Coverage Report

Created: 2026-10-17 07:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/modules/demux/mkv/virtual_segment.hpp
Line
Count
Source
1
/*****************************************************************************
2
 * virtual_segment.hpp : virtual segment implementation in the MKV demuxer
3
 *****************************************************************************
4
 * Copyright © 2003-2011 VideoLAN and VLC authors
5
 *
6
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7
 *          Steve Lhomme <steve.lhomme@free.fr>
8
 *          Denis Charmet <typx@dinauz.org>
9
 *
10
 * This program is free software; you can redistribute it and/or modify it
11
 * under the terms of the GNU Lesser General Public License as published by
12
 * the Free Software Foundation; either version 2.1 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public License
21
 * along with this program; if not, write to the Free Software Foundation,
22
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23
 *****************************************************************************/
24
25
#ifndef VLC_MKV_VIRTUAL_SEGMENT_HPP_
26
#define VLC_MKV_VIRTUAL_SEGMENT_HPP_
27
28
#include "mkv.hpp"
29
30
#include "matroska_segment.hpp"
31
#include "chapters.hpp"
32
33
namespace mkv {
34
35
/* virtual classes don't own anything but virtual elements so they shouldn't have to delete anything */
36
37
class virtual_chapter_c
38
{
39
public:
40
    virtual_chapter_c( matroska_segment_c &seg, chapter_item_c *p_chap, vlc_tick_t start, vlc_tick_t stop, std::vector<virtual_chapter_c *> & sub_chaps ):
41
3.56k
        segment(seg), p_chapter(p_chap),
42
3.56k
        i_mk_virtual_start_time(start), i_mk_virtual_stop_time(stop),
43
3.56k
        sub_vchapters(sub_chaps)
44
3.56k
    {}
45
    ~virtual_chapter_c();
46
47
    static virtual_chapter_c * CreateVirtualChapter( chapter_item_c * p_chap,
48
                                                     matroska_segment_c & main_segment,
49
                                                     const std::vector<matroska_segment_c*> & opened_segments,
50
                                                     vlc_tick_t & usertime_offset, bool b_ordered );
51
52
    virtual_chapter_c* getSubChapterbyTimecode( vlc_tick_t time );
53
    bool Leave( );
54
    bool EnterAndLeave( virtual_chapter_c *p_leaving_vchapter, bool b_enter = true );
55
    virtual_chapter_c * FindChapter( chapter_uid i_find_uid );
56
    int PublishChapters( input_title_t & title, int & i_user_chapters, int i_level, bool allow_no_name );
57
58
    virtual_chapter_c * BrowseCodecPrivate( chapter_codec_id codec_id,
59
                                            chapter_cmd_match match );
60
    bool Enter( bool b_do_subs );
61
    bool Leave( bool b_do_subs );
62
63
    static bool CompareTimecode( const virtual_chapter_c * itemA, const virtual_chapter_c * itemB )
64
0
    {
65
0
        return ( itemA->i_mk_virtual_start_time < itemB->i_mk_virtual_start_time );
66
0
    }
67
68
    bool ContainsTimestamp( vlc_tick_t i_pts );
69
70
    matroska_segment_c  &segment;
71
    chapter_item_c      *p_chapter;
72
    vlc_tick_t          i_mk_virtual_start_time;
73
    vlc_tick_t          i_mk_virtual_stop_time;
74
    int                 i_seekpoint_num;
75
    std::vector<virtual_chapter_c *> sub_vchapters;
76
#ifdef MKV_DEBUG
77
    void print();
78
#endif
79
};
80
81
class virtual_edition_c
82
{
83
public:
84
    virtual_edition_c( chapter_edition_c * p_edition, matroska_segment_c & main_segment, const std::vector<matroska_segment_c*> & opened_segments );
85
    ~virtual_edition_c();
86
    std::vector<virtual_chapter_c*> vchapters;
87
88
    virtual_chapter_c* getChapterbyTimecode( vlc_tick_t time );
89
    std::string GetMainName();
90
    int PublishChapters( input_title_t & title, int & i_user_chapters, int i_level );
91
    virtual_chapter_c * BrowseCodecPrivate( chapter_codec_id codec_id,
92
                                            chapter_cmd_match match );
93
94
    bool                b_ordered;
95
    vlc_tick_t          i_duration;
96
    chapter_edition_c   *p_edition;
97
    int                 i_seekpoint_num;
98
99
private:
100
    void retimeChapters();
101
    void retimeSubChapters( virtual_chapter_c * p_vchap );
102
#ifdef MKV_DEBUG
103
    void print(){ for( size_t i = 0; i<vchapters.size(); i++ ) vchapters[i]->print(); }
104
#endif
105
106
};
107
108
// class holding hard-linked segment together in the playback order
109
class virtual_segment_c
110
{
111
public:
112
    virtual_segment_c( matroska_segment_c & segment, std::vector<matroska_segment_c*> & opened_segments );
113
    ~virtual_segment_c();
114
    std::vector<virtual_edition_c*> veditions;
115
    std::vector<virtual_edition_c*>::size_type i_current_edition;
116
    bool                            b_current_vchapter_entered = false;
117
    int                             i_sys_title = 0;
118
119
120
    inline virtual_edition_c * CurrentEdition()
121
210k
    {
122
210k
        if( i_current_edition < veditions.size() )
123
210k
            return veditions[i_current_edition];
124
8
        return NULL;
125
210k
    }
126
127
    virtual_chapter_c * CurrentChapter() const
128
16.0k
    {
129
16.0k
        return p_current_vchapter;
130
16.0k
    }
131
132
    matroska_segment_c * CurrentSegment() const
133
907k
    {
134
907k
        if ( !p_current_vchapter )
135
76
            return NULL;
136
907k
        return &p_current_vchapter->segment;
137
907k
    }
138
139
    inline vlc_tick_t Duration()
140
2.06k
    {
141
2.06k
        return veditions[i_current_edition]->i_duration;
142
2.06k
    }
143
144
8.28k
    inline std::vector<virtual_edition_c*>* Editions() { return &veditions; }
145
146
    virtual_chapter_c *BrowseCodecPrivate( chapter_codec_id codec_id,
147
                                           chapter_cmd_match match );
148
149
    virtual_chapter_c * FindChapter( chapter_uid i_find_uid );
150
151
    bool UpdateCurrentToChapter( demux_t & demux );
152
    bool Seek( demux_t & demuxer, vlc_tick_t i_mk_date, virtual_chapter_c *p_vchapter, bool b_precise = true );
153
private:
154
    void KeepTrackSelection( const matroska_segment_c & old, const matroska_segment_c & next );
155
156
    virtual_chapter_c               *p_current_vchapter = nullptr;
157
};
158
159
} // namespace
160
161
#endif