/src/vlc/modules/demux/mkv/mkv.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | /***************************************************************************** |
2 | | * mkv.hpp : matroska demuxer |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2003-2005, 2008 VLC authors and VideoLAN |
5 | | * |
6 | | * Authors: Laurent Aimar <fenrir@via.ecp.fr> |
7 | | * Steve Lhomme <steve.lhomme@free.fr> |
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 VLC_MKV_MKV_HPP_ |
25 | | #define VLC_MKV_MKV_HPP_ |
26 | | |
27 | | /***************************************************************************** |
28 | | * Preamble |
29 | | *****************************************************************************/ |
30 | | |
31 | | #ifdef HAVE_CONFIG_H |
32 | | # include "config.h" |
33 | | #endif |
34 | | |
35 | | #include <vlc_common.h> |
36 | | #include <vlc_plugin.h> |
37 | | |
38 | | #include <vlc_meta.h> |
39 | | #include <vlc_input.h> |
40 | | #include <vlc_demux.h> |
41 | | #include <vlc_aout.h> /* For reordering */ |
42 | | |
43 | | #include <iostream> |
44 | | #include <cassert> |
45 | | #include <typeinfo> |
46 | | #include <string> |
47 | | #include <vector> |
48 | | #include <algorithm> |
49 | | #include <map> |
50 | | #include <stdexcept> |
51 | | #include <functional> |
52 | | |
53 | | /* libebml and matroska */ |
54 | | #include <ebml/EbmlVersion.h> |
55 | | #include <ebml/EbmlHead.h> |
56 | | #include <ebml/EbmlSubHead.h> |
57 | | #include <ebml/EbmlStream.h> |
58 | | #include <ebml/EbmlContexts.h> |
59 | | #include <ebml/EbmlVoid.h> |
60 | | |
61 | | #include <matroska/KaxVersion.h> |
62 | | #include <matroska/KaxAttachments.h> |
63 | | #include <matroska/KaxAttached.h> |
64 | | #include <matroska/KaxBlock.h> |
65 | | #include <matroska/KaxBlockData.h> |
66 | | #include <matroska/KaxChapters.h> |
67 | | #include <matroska/KaxCluster.h> |
68 | | #include <matroska/KaxClusterData.h> |
69 | | #include <matroska/KaxContexts.h> |
70 | | #include <matroska/KaxCues.h> |
71 | | #include <matroska/KaxCuesData.h> |
72 | | #include <matroska/KaxInfo.h> |
73 | | #include <matroska/KaxInfoData.h> |
74 | | #include <matroska/KaxSeekHead.h> |
75 | | #include <matroska/KaxSegment.h> |
76 | | #include <matroska/KaxTag.h> |
77 | | #include <matroska/KaxTags.h> |
78 | | #include <matroska/KaxTracks.h> |
79 | | #include <matroska/KaxTrackAudio.h> |
80 | | #include <matroska/KaxTrackVideo.h> |
81 | | #include <matroska/KaxTrackEntryData.h> |
82 | | #include <matroska/KaxContentEncoding.h> |
83 | | |
84 | 44 | #define GlobalTimestamp() GlobalTimecode() |
85 | 51 | #define InitTimestamp(t,s) InitTimecode(t,s) |
86 | | using KaxClusterTimestamp = libmatroska::KaxClusterTimecode; |
87 | | using KaxTimestampScale = libmatroska::KaxTimecodeScale; |
88 | | using KaxTrackTimestampScale = libmatroska::KaxTrackTimecodeScale; |
89 | | |
90 | | #include "stream_io_callback.hpp" |
91 | | |
92 | | #ifdef HAVE_ZLIB_H |
93 | | # include <zlib.h> |
94 | | #endif |
95 | | |
96 | | #ifndef NDEBUG |
97 | | //# define MKV_DEBUG 0 |
98 | | #endif |
99 | | |
100 | | namespace mkv { |
101 | | |
102 | 33 | #define MATROSKA_COMPRESSION_NONE -1 |
103 | 0 | #define MATROSKA_COMPRESSION_ZLIB 0 |
104 | | #define MATROSKA_COMPRESSION_BLIB 1 |
105 | | #define MATROSKA_COMPRESSION_LZOX 2 |
106 | 7.34k | #define MATROSKA_COMPRESSION_HEADER 3 |
107 | | |
108 | | enum |
109 | | { |
110 | | MATROSKA_ENCODING_SCOPE_ALL_FRAMES = 1, |
111 | | MATROSKA_ENCODING_SCOPE_PRIVATE = 2, |
112 | | MATROSKA_ENCODING_SCOPE_NEXT = 4 /* unsupported */ |
113 | | }; |
114 | | |
115 | | enum chapter_codec_id |
116 | | { |
117 | | MATROSKA_CHAPTER_CODEC_NATIVE = 0, |
118 | | MATROSKA_CHAPTER_CODEC_DVD = 1, |
119 | | }; |
120 | | |
121 | 17 | #define MKVD_TIMECODESCALE 1000000 |
122 | | |
123 | 963 | #define MKV_IS_ID( el, C ) ( el != NULL && (el->operator const EbmlId&()) == EBML_ID(C) && !el->IsDummy() ) |
124 | 1.36k | #define MKV_CHECKED_PTR_DECL( name, type, src ) type * name = MKV_IS_ID(src, type) ? static_cast<type*>(src) : NULL |
125 | 22 | #define MKV_CHECKED_PTR_DECL_CONST( name, type, src ) const type * name = MKV_IS_ID(src, type) ? static_cast<const type*>(src) : NULL |
126 | | |
127 | | class MissingMandatory : public std::runtime_error |
128 | | { |
129 | | public: |
130 | | MissingMandatory(const char * type_name) |
131 | 0 | :std::runtime_error(std::string("missing mandatory element without a default ") + type_name) |
132 | 0 | {} |
133 | | }; |
134 | | |
135 | | template <typename Type> |
136 | | Type & GetMandatoryChild(const EbmlMaster & Master) |
137 | 33 | { |
138 | 33 | auto p = static_cast<Type *>(Master.FindFirstElt(EBML_INFO(Type))); |
139 | 33 | if (p == nullptr) |
140 | 0 | { |
141 | 0 | throw MissingMandatory(EBML_INFO_NAME(EBML_INFO(Type))); |
142 | 0 | } |
143 | 33 | return *p; |
144 | 33 | } libmatroska::KaxTrackType& mkv::GetMandatoryChild<libmatroska::KaxTrackType>(libebml::EbmlMaster const&) Line | Count | Source | 137 | 33 | { | 138 | 33 | auto p = static_cast<Type *>(Master.FindFirstElt(EBML_INFO(Type))); | 139 | 33 | if (p == nullptr) | 140 | 0 | { | 141 | 0 | throw MissingMandatory(EBML_INFO_NAME(EBML_INFO(Type))); | 142 | 0 | } | 143 | 33 | return *p; | 144 | 33 | } |
Unexecuted instantiation: libmatroska::KaxFileData& mkv::GetMandatoryChild<libmatroska::KaxFileData>(libebml::EbmlMaster const&) Unexecuted instantiation: libmatroska::KaxFileName& mkv::GetMandatoryChild<libmatroska::KaxFileName>(libebml::EbmlMaster const&) Unexecuted instantiation: libmatroska::KaxMimeType& mkv::GetMandatoryChild<libmatroska::KaxMimeType>(libebml::EbmlMaster const&) |
145 | | #if LIBEBML_VERSION < 0x020000 |
146 | | template <typename Type> |
147 | | Type * FindChild(const EbmlMaster & Master) |
148 | 2.37k | { |
149 | 2.37k | return static_cast<Type *>(Master.FindFirstElt(EBML_INFO(Type))); |
150 | 2.37k | } libmatroska::KaxBlockMore const* mkv::FindChild<libmatroska::KaxBlockMore const>(libebml::EbmlMaster const&) Line | Count | Source | 148 | 791 | { | 149 | 791 | return static_cast<Type *>(Master.FindFirstElt(EBML_INFO(Type))); | 150 | 791 | } |
libmatroska::KaxBlockAdditional const* mkv::FindChild<libmatroska::KaxBlockAdditional const>(libebml::EbmlMaster const&) Line | Count | Source | 148 | 791 | { | 149 | 791 | return static_cast<Type *>(Master.FindFirstElt(EBML_INFO(Type))); | 150 | 791 | } |
libmatroska::KaxBlockAddID const* mkv::FindChild<libmatroska::KaxBlockAddID const>(libebml::EbmlMaster const&) Line | Count | Source | 148 | 791 | { | 149 | 791 | return static_cast<Type *>(Master.FindFirstElt(EBML_INFO(Type))); | 150 | 791 | } |
Unexecuted instantiation: libmatroska::KaxChapterProcessData* mkv::FindChild<libmatroska::KaxChapterProcessData>(libebml::EbmlMaster const&) Unexecuted instantiation: libmatroska::KaxChapterProcessTime* mkv::FindChild<libmatroska::KaxChapterProcessTime>(libebml::EbmlMaster const&) |
151 | | |
152 | | template <typename Type> |
153 | | Type * FindNextChild(const EbmlMaster & Master, const Type & PastElt) |
154 | | { |
155 | | return static_cast<Type *>(Master.FindNextElt(PastElt)); |
156 | | } |
157 | | #endif |
158 | | |
159 | | using namespace libmatroska; |
160 | | |
161 | | class matroska_segment_c; |
162 | | struct matroska_stream_c |
163 | | { |
164 | | matroska_stream_c(stream_t *s, bool owner); |
165 | 17 | ~matroska_stream_c() {} |
166 | | |
167 | | bool isUsed() const; |
168 | | |
169 | | vlc_stream_io_callback io_callback; |
170 | | matroska_iostream_c estream; |
171 | | |
172 | | std::vector<matroska_segment_c*> segments; |
173 | | }; |
174 | | |
175 | | class chapter_codec_cmds_c; |
176 | | using chapter_cmd_match = std::function<bool(const chapter_codec_cmds_c &)>; |
177 | | |
178 | | using chapter_uid = uint64_t; |
179 | | |
180 | | |
181 | | /***************************************************************************** |
182 | | * definitions of structures and functions used by this plugins |
183 | | *****************************************************************************/ |
184 | | class PrivateTrackData |
185 | | { |
186 | | public: |
187 | 0 | virtual ~PrivateTrackData() {} |
188 | 0 | virtual int32_t Init() { return 0; } |
189 | | }; |
190 | | |
191 | | class mkv_track_t |
192 | | { |
193 | | public: |
194 | | mkv_track_t(enum es_format_category_e es_cat); |
195 | | ~mkv_track_t(); |
196 | | |
197 | | typedef unsigned int track_id_t; |
198 | | |
199 | | bool b_default; |
200 | | bool b_enabled; |
201 | | bool b_forced; |
202 | | track_id_t i_number; |
203 | | |
204 | | size_t i_extra_data; |
205 | | uint8_t *p_extra_data; |
206 | | |
207 | | std::string codec; |
208 | | bool b_dts_only; |
209 | | bool b_pts_only; |
210 | | |
211 | | bool b_no_duration; |
212 | | vlc_tick_t i_default_duration; |
213 | | float f_timecodescale; |
214 | | vlc_tick_t i_last_dts; |
215 | | uint64_t i_skip_until_fpos; /*< any block before this fpos should be ignored */ |
216 | | |
217 | | /* video */ |
218 | | es_format_t fmt; |
219 | | float f_fps; |
220 | | es_out_id_t *p_es; |
221 | | |
222 | | /* audio */ |
223 | | unsigned int i_original_rate; |
224 | | uint8_t i_chans_to_reorder; /* do we need channel reordering */ |
225 | | uint8_t pi_chan_table[AOUT_CHAN_MAX]; |
226 | | |
227 | | |
228 | | /* Private track parameters */ |
229 | | PrivateTrackData *p_sys; |
230 | | |
231 | | bool b_discontinuity; |
232 | | bool b_has_alpha; |
233 | | |
234 | | /* informative */ |
235 | | std::string str_codec_name; |
236 | | |
237 | | /* encryption/compression */ |
238 | | int i_compression_type; |
239 | | uint32_t i_encoding_scope; |
240 | | KaxContentCompSettings *p_compression_data; |
241 | | |
242 | | /* Matroska 4 new elements used by Opus */ |
243 | | vlc_tick_t i_seek_preroll; |
244 | | vlc_tick_t i_codec_delay; |
245 | | }; |
246 | | |
247 | | } // namespace |
248 | | |
249 | | #endif /* _MKV_HPP_ */ |