1 /*****************************************************************************
2  * matroska_segment.hpp : matroska demuxer
3  *****************************************************************************
4  * Copyright (C) 2016 VLC authors and VideoLAN
5  * $Id: e2e1579354a90d0dad1a03c2574a1029f291fe90 $
6  *
7  * Authors: Filip Roséen <filip@videolabs.io>
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23 
24 #ifndef MKV_MATROSKA_SEGMENT_SEEKER_HPP_
25 #define MKV_MATROSKA_SEGMENT_SEEKER_HPP_
26 
27 #include "mkv.hpp"
28 
29 #include <algorithm>
30 #include <vector>
31 #include <map>
32 #include <limits>
33 
34 class matroska_segment_c;
35 
36 class SegmentSeeker
37 {
38     public:
39         typedef uint64_t fptr_t;
40         typedef mkv_track_t::track_id_t track_id_t;
41 
42         struct Range
43         {
RangeSegmentSeeker::Range44             Range (fptr_t start, fptr_t end)
45                 : start( start ), end( end )
46             { }
47 
48             fptr_t start, end;
49 
operator <SegmentSeeker::Range50             bool operator<( Range const& rhs ) const
51             {
52                 return start < rhs.start;
53             }
54         };
55 
56         struct Seekpoint
57         {
58             enum TrustLevel {
59                 TRUSTED = +3,
60                 QUESTIONABLE = +2,
61                 DISABLED = -1,
62             };
63 
SeekpointSegmentSeeker::Seekpoint64             Seekpoint( fptr_t fpos, mtime_t pts, TrustLevel trust_level = TRUSTED )
65                 : fpos( fpos ), pts( pts ), trust_level( trust_level )
66             { }
67 
SeekpointSegmentSeeker::Seekpoint68             Seekpoint()
69                 : Seekpoint( std::numeric_limits<fptr_t>::max(), -1, DISABLED )
70             { }
71 
operator <SegmentSeeker::Seekpoint72             bool operator<( Seekpoint const& rhs ) const
73             {
74                 return pts < rhs.pts;
75             }
76 
77             fptr_t fpos;
78             mtime_t pts;
79             TrustLevel trust_level;
80         };
81 
82         struct Cluster {
83             fptr_t  fpos;
84             mtime_t pts;
85             mtime_t duration;
86             fptr_t  size;
87         };
88 
89     public:
90         typedef std::vector<track_id_t> track_ids_t;
91         typedef std::vector<Range> ranges_t;
92         typedef std::vector<Seekpoint> seekpoints_t;
93         typedef std::vector<fptr_t> cluster_positions_t;
94 
95         typedef std::map<track_id_t, Seekpoint> tracks_seekpoint_t;
96         typedef std::map<track_id_t, seekpoints_t> tracks_seekpoints_t;
97         typedef std::map<mtime_t, Cluster> cluster_map_t;
98 
99         typedef std::pair<Seekpoint, Seekpoint> seekpoint_pair_t;
100 
101         void add_seekpoint( track_id_t, Seekpoint );
102 
103         seekpoint_pair_t get_seekpoints_around( mtime_t, seekpoints_t const& );
104         Seekpoint get_first_seekpoint_around( mtime_t, seekpoints_t const&, Seekpoint::TrustLevel = Seekpoint::TRUSTED );
105         seekpoint_pair_t get_seekpoints_around( mtime_t, track_ids_t const& );
106 
107         tracks_seekpoint_t get_seekpoints( matroska_segment_c&, mtime_t, track_ids_t const&, track_ids_t const& );
108         tracks_seekpoint_t find_greatest_seekpoints_in_range( fptr_t , mtime_t, track_ids_t const& filter_tracks );
109 
110         cluster_positions_t::iterator add_cluster_position( fptr_t pos );
111         cluster_map_t      ::iterator add_cluster( KaxCluster * const );
112 
113         void mkv_jump_to( matroska_segment_c&, fptr_t );
114 
115         void index_range( matroska_segment_c& matroska_segment, Range search_area, mtime_t max_pts );
116         void index_unsearched_range( matroska_segment_c& matroska_segment, Range search_area, mtime_t max_pts );
117 
118         void mark_range_as_searched( Range );
119         ranges_t get_search_areas( fptr_t start, fptr_t end ) const;
120 
121     public:
122         ranges_t            _ranges_searched;
123         tracks_seekpoints_t _tracks_seekpoints;
124         cluster_positions_t _cluster_positions;
125         cluster_map_t       _clusters;
126 };
127 
128 #endif /* include-guard */
129