1/*
2Copyright (c) 2012, Broadcom Europe Ltd
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of the copyright holder nor the
13 names of its contributors may be used to endorse or promote products
14 derived from this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27#include <stdlib.h>
28#include <string.h>
29
30//#define ENABLE_MKV_EXTRA_LOGGING
31#define CONTAINER_IS_BIG_ENDIAN
32#define CONTAINER_HELPER_LOG_INDENT(a) (a)->priv->module->element_level
33#include "containers/core/containers_private.h"
34#include "containers/core/containers_io_helpers.h"
35#include "containers/core/containers_utils.h"
36#include "containers/core/containers_logging.h"
37
38/******************************************************************************
39Defines.
40******************************************************************************/
41#define MKV_TRACKS_MAX 16
42#define MKV_CODECID_MAX 32
43#define MKV_MAX_LACING_NUM 64
44
45#define MKV_MAX_ENCODINGS 1
46#define MKV_MAX_ENCODING_DATA 256
47
48#define MKV_MAX_ELEMENT_LEVEL 8
49#define MKV_MAX_CONSECUTIVE_UNKNOWN_ELEMENTS 5
50#define MKV_MAX_ELEMENT_SIZE (1<<29) /* Does not apply to the data element */
51#define MKV_MAX_STRING_SIZE 256
52#define MKV_ELEMENT_MIN_HEADER_SIZE 2
53
54#define MKV_MAX_READER_STATE_LEVEL 4
55
56#define MKV_SKIP_U8(ctx,n) (size -= 1, SKIP_U8(ctx,n))
57#define MKV_SKIP_U16(ctx,n) (size -= 2, SKIP_U16(ctx,n))
58#define MKV_SKIP_U24(ctx,n) (size -= 3, SKIP_U24(ctx,n))
59#define MKV_SKIP_U32(ctx,n) (size -= 4, SKIP_U32(ctx,n))
60#define MKV_SKIP_U64(ctx,n) (size -= 8, SKIP_U64(ctx,n))
61#define MKV_READ_U8(ctx,n) (size -= 1, READ_U8(ctx,n))
62#define MKV_READ_U16(ctx,n) (size -= 2, READ_U16(ctx,n))
63#define MKV_READ_U24(ctx,n) (size -= 3, READ_U24(ctx,n))
64#define MKV_READ_U32(ctx,n) (size -= 4, READ_U32(ctx,n))
65#define MKV_READ_U64(ctx,n) (size -= 8, READ_U64(ctx,n))
66#define MKV_READ_BYTES(ctx,buffer,sz) (size -= sz, READ_BYTES(ctx,buffer,sz))
67#define MKV_SKIP_BYTES(ctx,sz) (size -= sz, SKIP_BYTES(ctx,sz))
68
69#define CHECK_POINT(a) do { \
70 /*if(size < 0 && size != INT64_C(-1)) return VC_CONTAINER_ERROR_CORRUPTED;*/ \
71 if(STREAM_STATUS(p_ctx)) return STREAM_STATUS(p_ctx); } while(0)
72
73static uint32_t mkv_io_read_id(VC_CONTAINER_IO_T *io, int64_t *size)
74{
75 uint32_t value, mask;
76
77 value = vc_container_io_read_uint8(io); (*size)--;
78 for(mask = 0x80; mask; mask <<= 7)
79 {
80 if(value & mask) return value;
81 value = (value << 8) | vc_container_io_read_uint8(io); (*size)--;
82 }
83 return 0;
84}
85
86static int64_t mkv_io_read_uint(VC_CONTAINER_IO_T *io, int64_t *size)
87{
88 uint64_t value, mask;
89
90 value = vc_container_io_read_uint8(io); (*size)--;
91 if(value == 0xFF) return -1;
92
93 for(mask = 0x80; mask; mask <<= 7)
94 {
95 if(value & mask) return value & ~mask;
96 value = (value << 8) | vc_container_io_read_uint8(io); (*size)--;
97 }
98 return 0;
99}
100
101static int64_t mkv_io_read_sint(VC_CONTAINER_IO_T *io, int64_t *size)
102{
103 int64_t value, count = io->offset;
104 value = mkv_io_read_uint(io, size);
105 count = io->offset - count;
106
107 switch(count)
108 {
109 case 1: value -= 0x3F; break;
110 case 2: value -= 0x1FFF; break;
111 case 3: value -= 0xFFFFF; break;
112 case 4: value -= 0x7FFFFFF; break;
113 default: break;
114 }
115 return value;
116}
117
118#define MKV_READ_ID(ctx, n) mkv_io_read_id((ctx)->priv->io, &size)
119#define MKV_READ_UINT(ctx, n) mkv_io_read_uint((ctx)->priv->io, &size)
120#define MKV_READ_SINT(ctx, n) mkv_io_read_sint((ctx)->priv->io, &size)
121
122/******************************************************************************
123Type definitions.
124******************************************************************************/
125
126typedef enum
127{
128 MKV_ELEMENT_ID_UNKNOWN = 0,
129
130 /* EBML Basics */
131 MKV_ELEMENT_ID_EBML = 0x1A45DFA3,
132 MKV_ELEMENT_ID_EBML_VERSION = 0x4286,
133 MKV_ELEMENT_ID_EBML_READ_VERSION = 0x42F7,
134 MKV_ELEMENT_ID_EBML_MAX_ID_LENGTH = 0x42F2,
135 MKV_ELEMENT_ID_EBML_MAX_SIZE_LENGTH = 0x42F3,
136 MKV_ELEMENT_ID_DOCTYPE = 0x4282,
137 MKV_ELEMENT_ID_DOCTYPE_VERSION = 0x4287,
138 MKV_ELEMENT_ID_DOCTYPE_READ_VERSION = 0x4285,
139
140 /* Global Elements */
141 MKV_ELEMENT_ID_CRC32 = 0xBF,
142 MKV_ELEMENT_ID_VOID = 0xEC,
143
144 /* Segment */
145 MKV_ELEMENT_ID_SEGMENT = 0x18538067,
146
147 /* Meta Seek Information */
148 MKV_ELEMENT_ID_SEEK_HEAD = 0x114D9B74,
149 MKV_ELEMENT_ID_SEEK = 0x4DBB,
150 MKV_ELEMENT_ID_SEEK_ID = 0x53AB,
151 MKV_ELEMENT_ID_SEEK_POSITION = 0x53AC,
152
153 /* Segment Information */
154 MKV_ELEMENT_ID_INFO = 0x1549A966,
155 MKV_ELEMENT_ID_SEGMENT_UID = 0x73A4,
156 MKV_ELEMENT_ID_SEGMENT_FILENAME = 0x7384,
157 MKV_ELEMENT_ID_PREV_UID = 0x3CB923,
158 MKV_ELEMENT_ID_PREV_FILENAME = 0x3C83AB,
159 MKV_ELEMENT_ID_NEXT_UID = 0x3EB923,
160 MKV_ELEMENT_ID_NEXT_FILENAME = 0x3E83BB,
161 MKV_ELEMENT_ID_SEGMENT_FAMILY = 0x4444,
162 MKV_ELEMENT_ID_CHAPTER_TRANSLATE = 0x6924,
163 MKV_ELEMENT_ID_CHAPTER_TRANSLATE_EDITION_UID = 0x69FC,
164 MKV_ELEMENT_ID_CHAPTER_TRANSLATE_CODEC = 0x69BF,
165 MKV_ELEMENT_ID_CHAPTER_TRANSLATE_ID = 0x69A5,
166 MKV_ELEMENT_ID_TIMECODE_SCALE = 0x2AD7B1,
167 MKV_ELEMENT_ID_DURATION = 0x4489,
168 MKV_ELEMENT_ID_DATE_UTC = 0x4461,
169 MKV_ELEMENT_ID_TITLE = 0x7BA9,
170 MKV_ELEMENT_ID_MUXING_APP = 0x4D80,
171 MKV_ELEMENT_ID_WRITING_APP = 0x5741,
172
173 /* Cluster */
174 MKV_ELEMENT_ID_CLUSTER = 0x1F43B675,
175 MKV_ELEMENT_ID_TIMECODE = 0xE7,
176 MKV_ELEMENT_ID_SILENT_TRACKS = 0x5854,
177 MKV_ELEMENT_ID_SILENT_TRACK_NUMBER = 0x58D7,
178 MKV_ELEMENT_ID_POSITION = 0xA7,
179 MKV_ELEMENT_ID_PREV_SIZE = 0xAB,
180 MKV_ELEMENT_ID_BLOCKGROUP = 0xA0,
181 MKV_ELEMENT_ID_BLOCK = 0xA1,
182 MKV_ELEMENT_ID_BLOCK_ADDITIONS = 0x75A1,
183 MKV_ELEMENT_ID_BLOCK_MORE = 0xA6,
184 MKV_ELEMENT_ID_BLOCK_ADD_ID = 0xEE,
185 MKV_ELEMENT_ID_BLOCK_ADDITIONAL = 0xA5,
186 MKV_ELEMENT_ID_BLOCK_DURATION = 0x9B,
187 MKV_ELEMENT_ID_REFERENCE_PRIORITY = 0xFA,
188 MKV_ELEMENT_ID_REFERENCE_BLOCK = 0xFB,
189 MKV_ELEMENT_ID_CODEC_STATE = 0xA4,
190 MKV_ELEMENT_ID_SLICES = 0x8E,
191 MKV_ELEMENT_ID_TIME_SLICE = 0xE8,
192 MKV_ELEMENT_ID_LACE_NUMBER = 0xCC,
193 MKV_ELEMENT_ID_SIMPLE_BLOCK = 0xA3,
194
195 /* Track */
196 MKV_ELEMENT_ID_TRACKS = 0x1654AE6B,
197 MKV_ELEMENT_ID_TRACK_ENTRY = 0xAE,
198 MKV_ELEMENT_ID_TRACK_NUMBER = 0xD7,
199 MKV_ELEMENT_ID_TRACK_UID = 0x73C5,
200 MKV_ELEMENT_ID_TRACK_TYPE = 0x83,
201 MKV_ELEMENT_ID_FLAG_ENABLED = 0xB9,
202 MKV_ELEMENT_ID_FLAG_DEFAULT = 0x88,
203 MKV_ELEMENT_ID_FLAG_FORCED = 0x55AA,
204 MKV_ELEMENT_ID_FLAG_LACING = 0x9C,
205 MKV_ELEMENT_ID_MIN_CACHE = 0x6DE7,
206 MKV_ELEMENT_ID_MAX_CACHE = 0x6DF8,
207 MKV_ELEMENT_ID_DEFAULT_DURATION = 0x23E383,
208 MKV_ELEMENT_ID_TRACK_TIMECODE_SCALE = 0x23314F,
209 MKV_ELEMENT_ID_MAX_BLOCK_ADDITION_ID = 0x55EE,
210 MKV_ELEMENT_ID_NAME = 0x536E,
211 MKV_ELEMENT_ID_LANGUAGE = 0x22B59C,
212 MKV_ELEMENT_ID_TRACK_CODEC_ID = 0x86,
213 MKV_ELEMENT_ID_TRACK_CODEC_PRIVATE = 0x63A2,
214 MKV_ELEMENT_ID_TRACK_CODEC_NAME = 0x258688,
215 MKV_ELEMENT_ID_ATTACHMENT_LINK = 0x7446,
216 MKV_ELEMENT_ID_CODEC_DECODE_ALL = 0xAA,
217 MKV_ELEMENT_ID_TRACK_OVERLAY = 0x6FAB,
218 MKV_ELEMENT_ID_TRACK_TRANSLATE = 0x6624,
219 MKV_ELEMENT_ID_TRACK_TRANSLATE_EDITION_UID = 0x66FC,
220 MKV_ELEMENT_ID_TRACK_TRANSLATE_CODEC = 0x66BF,
221 MKV_ELEMENT_ID_TRACK_TRANSLATE_TRACK_ID = 0x66A5,
222
223 /* Video */
224 MKV_ELEMENT_ID_VIDEO = 0xE0,
225 MKV_ELEMENT_ID_FLAG_INTERLACED = 0x9A,
226 MKV_ELEMENT_ID_STEREO_MODE = 0x53B8,
227 MKV_ELEMENT_ID_PIXEL_WIDTH = 0xB0,
228 MKV_ELEMENT_ID_PIXEL_HEIGHT = 0xBA,
229 MKV_ELEMENT_ID_PIXEL_CROP_BOTTOM = 0x54AA,
230 MKV_ELEMENT_ID_PIXEL_CROP_TOP = 0x54BB,
231 MKV_ELEMENT_ID_PIXEL_CROP_LEFT = 0x54CC,
232 MKV_ELEMENT_ID_PIXEL_CROP_RIGHT = 0x54DD,
233 MKV_ELEMENT_ID_DISPLAY_WIDTH = 0x54B0,
234 MKV_ELEMENT_ID_DISPLAY_HEIGHT = 0x54BA,
235 MKV_ELEMENT_ID_DISPLAY_UNIT = 0x54B2,
236 MKV_ELEMENT_ID_ASPECT_RATIO_TYPE = 0x54B3,
237 MKV_ELEMENT_ID_COLOUR_SPACE = 0x2EB524,
238 MKV_ELEMENT_ID_FRAME_RATE = 0x2383E3,
239
240 /* Audio */
241 MKV_ELEMENT_ID_AUDIO = 0xE1,
242 MKV_ELEMENT_ID_SAMPLING_FREQUENCY = 0xB5,
243 MKV_ELEMENT_ID_OUTPUT_SAMPLING_FREQUENCY = 0x78B5,
244 MKV_ELEMENT_ID_CHANNELS = 0x9F,
245 MKV_ELEMENT_ID_BIT_DEPTH = 0x6264,
246
247 /* Content Encoding */
248 MKV_ELEMENT_ID_CONTENT_ENCODINGS = 0x6D80,
249 MKV_ELEMENT_ID_CONTENT_ENCODING = 0x6240,
250 MKV_ELEMENT_ID_CONTENT_ENCODING_ORDER = 0x5031,
251 MKV_ELEMENT_ID_CONTENT_ENCODING_SCOPE = 0x5032,
252 MKV_ELEMENT_ID_CONTENT_ENCODING_TYPE = 0x5033,
253 MKV_ELEMENT_ID_CONTENT_COMPRESSION = 0x5034,
254 MKV_ELEMENT_ID_CONTENT_COMPRESSION_ALGO = 0x4254,
255 MKV_ELEMENT_ID_CONTENT_COMPRESSION_SETTINGS = 0x4255,
256 MKV_ELEMENT_ID_CONTENT_ENCRYPTION = 0x5035,
257 MKV_ELEMENT_ID_CONTENT_ENCRYPTION_ALGO = 0x47E1,
258 MKV_ELEMENT_ID_CONTENT_ENCRYPTION_KEY_ID = 0x47E2,
259 MKV_ELEMENT_ID_CONTENT_SIGNATURE = 0x47E3,
260 MKV_ELEMENT_ID_CONTENT_SIGNATURE_KEY_ID = 0x47E4,
261 MKV_ELEMENT_ID_CONTENT_SIGNATURE_ALGO = 0x47E5,
262 MKV_ELEMENT_ID_CONTENT_SIGNATURE_HASH_ALGO = 0x47E6,
263
264 /* Cueing Data */
265 MKV_ELEMENT_ID_CUES = 0x1C53BB6B,
266 MKV_ELEMENT_ID_CUE_POINT = 0xBB,
267 MKV_ELEMENT_ID_CUE_TIME = 0xB3,
268 MKV_ELEMENT_ID_CUE_TRACK_POSITIONS = 0xB7,
269 MKV_ELEMENT_ID_CUE_TRACK = 0xF7,
270 MKV_ELEMENT_ID_CUE_CLUSTER_POSITION = 0xF1,
271 MKV_ELEMENT_ID_CUE_BLOCK_NUMBER = 0x5378,
272
273 /* Attachments */
274 MKV_ELEMENT_ID_ATTACHMENTS = 0x1941A469,
275
276 /* Chapters */
277 MKV_ELEMENT_ID_CHAPTERS = 0x1043A770,
278
279 /* Tagging */
280 MKV_ELEMENT_ID_TAGS = 0x1254C367,
281 MKV_ELEMENT_ID_TAG = 0x7373,
282 MKV_ELEMENT_ID_TAG_TARGETS = 0x63C0,
283 MKV_ELEMENT_ID_TAG_TARGET_TYPE_VALUE = 0x68CA,
284 MKV_ELEMENT_ID_TAG_TARGET_TYPE = 0x63CA,
285 MKV_ELEMENT_ID_TAG_TRACK_UID = 0x63C5,
286 MKV_ELEMENT_ID_TAG_EDITION_UID = 0x63C9,
287 MKV_ELEMENT_ID_TAG_CHAPTER_UID = 0x63C4,
288 MKV_ELEMENT_ID_TAG_ATTACHMENT_UID = 0x63C6,
289 MKV_ELEMENT_ID_TAG_SIMPLE_TAG = 0x67C8,
290 MKV_ELEMENT_ID_TAG_NAME = 0x45A3,
291 MKV_ELEMENT_ID_TAG_LANGUAGE = 0x447A,
292 MKV_ELEMENT_ID_TAG_DEFAULT = 0x4484,
293 MKV_ELEMENT_ID_TAG_STRING = 0x4487,
294 MKV_ELEMENT_ID_TAG_BINARY = 0x4485,
295
296 MKV_ELEMENT_ID_INVALID = 0xFFFFFFFF
297} MKV_ELEMENT_ID_T;
298
299/** Context for our reader
300 */
301
302typedef struct
303{
304 unsigned int track;
305 unsigned int flags;
306 int64_t pts;
307 int64_t cluster_timecode;
308 int64_t prev_cluster_size; /* Size of the previous cluster if available */
309 int64_t frame_duration;
310
311 int level;
312 struct {
313 int64_t offset;
314 int64_t data_start;
315 int64_t data_offset;
316 int64_t size;
317 MKV_ELEMENT_ID_T id;
318 } levels[MKV_MAX_READER_STATE_LEVEL];
319
320 bool eos;
321 bool corrupted;
322 bool seen_ref_block;
323
324 uint32_t lacing_num_frames;
325 uint32_t lacing_size;
326 uint16_t lacing_sizes[MKV_MAX_LACING_NUM];
327 uint32_t lacing_current_size;
328
329 /* For header stripping compression */
330 uint32_t header_size;
331 uint8_t *header_data;
332 uint32_t header_size_backup;
333} MKV_READER_STATE_T;
334
335typedef struct
336{
337 const MKV_ELEMENT_ID_T id;
338 const MKV_ELEMENT_ID_T parent_id;
339 const char *psz_name;
340 VC_CONTAINER_STATUS_T (*pf_func)(VC_CONTAINER_T *, MKV_ELEMENT_ID_T, int64_t);
341
342} MKV_ELEMENT_T;
343
344typedef struct VC_CONTAINER_TRACK_MODULE_T
345{
346 MKV_READER_STATE_T *state;
347 MKV_READER_STATE_T track_state;
348
349 /* Information extracted from the track entry */
350 uint32_t number;
351 uint32_t type;
352 int64_t timecode_scale;
353 uint32_t duration;
354 int64_t frame_duration;
355 char codecid[MKV_CODECID_MAX];
356
357 union {
358 /* video specific */
359 struct {
360 unsigned int interlaced:1;
361 unsigned int stereo_mode:2;
362 uint32_t pixel_width;
363 uint32_t pixel_height;
364 uint32_t pixel_crop_bottom;
365 uint32_t pixel_crop_top;
366 uint32_t pixel_crop_left;
367 uint32_t pixel_crop_right;
368 uint32_t display_width;
369 uint32_t display_height;
370 uint32_t display_unit;
371 uint32_t aspect_ratio_type;
372 float frame_rate;
373 } video;
374
375 /* audio specific */
376 struct {
377 uint32_t sampling_frequency;
378 uint32_t output_sampling_frequency;
379 uint32_t channels;
380 uint32_t bit_depth;
381 } audio;
382 } es_type;
383
384 /* content encoding (i.e. lossless compression and encryption) */
385 unsigned int encodings_num;
386 struct {
387 enum {
388 MKV_CONTENT_ENCODING_COMPRESSION_ZLIB,
389 MKV_CONTENT_ENCODING_COMPRESSION_HEADER,
390 MKV_CONTENT_ENCODING_ENCRYPTION,
391 MKV_CONTENT_ENCODING_UNKNOWN
392 } type;
393 unsigned int data_size;
394 uint8_t *data;
395 } encodings[MKV_MAX_ENCODINGS];
396
397} VC_CONTAINER_TRACK_MODULE_T;
398
399typedef struct VC_CONTAINER_MODULE_T
400{
401 MKV_ELEMENT_T *elements_list;
402 int element_level;
403 MKV_ELEMENT_ID_T parent_id;
404
405 uint64_t element_offset; /**< Offset to the start of the current element */
406
407 uint64_t segment_offset; /**< Offset to the start of the data packets */
408 int64_t segment_size;
409
410 int tracks_num;
411 VC_CONTAINER_TRACK_T *tracks[MKV_TRACKS_MAX];
412
413 MKV_READER_STATE_T state;
414 int64_t timecode_scale;
415 float duration;
416
417 uint64_t cluster_offset; /**< Offset to the first cluster */
418 uint64_t cues_offset; /**< Offset to the start of the seeking cues */
419 uint64_t tags_offset; /**< Offset to the start of the tags */
420
421 /*
422 * Variables only used during parsing of the header
423 */
424
425 VC_CONTAINER_TRACK_T *parsing; /**< Current track being parsed */
426 bool is_doctype_valid;
427
428 MKV_ELEMENT_ID_T seekhead_elem_id;
429 int64_t seekhead_elem_offset;
430
431 /* Cues */
432 unsigned int cue_track;
433 int64_t cue_timecode;
434 uint64_t cue_cluster_offset;
435 unsigned int cue_block;
436
437} VC_CONTAINER_MODULE_T;
438
439/******************************************************************************
440Function prototypes
441******************************************************************************/
442VC_CONTAINER_STATUS_T mkv_reader_open( VC_CONTAINER_T * );
443
444/******************************************************************************
445Prototypes for local functions
446******************************************************************************/
447static VC_CONTAINER_STATUS_T mkv_read_element( VC_CONTAINER_T *p_ctx, int64_t size, MKV_ELEMENT_ID_T parent_id );
448static VC_CONTAINER_STATUS_T mkv_read_elements( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size );
449static VC_CONTAINER_STATUS_T mkv_read_element_data_uint( VC_CONTAINER_T *p_ctx, int64_t size, uint64_t *value );
450static VC_CONTAINER_STATUS_T mkv_read_element_data_float( VC_CONTAINER_T *p_ctx, int64_t size, double *value );
451static VC_CONTAINER_STATUS_T mkv_read_element_ebml( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size );
452static VC_CONTAINER_STATUS_T mkv_read_subelements_ebml( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size );
453static VC_CONTAINER_STATUS_T mkv_read_element_segment( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size );
454static VC_CONTAINER_STATUS_T mkv_read_element_track_entry( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size );
455static VC_CONTAINER_STATUS_T mkv_read_subelements_track_entry( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size );
456static VC_CONTAINER_STATUS_T mkv_read_subelements_video( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size );
457static VC_CONTAINER_STATUS_T mkv_read_subelements_audio( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size );
458static VC_CONTAINER_STATUS_T mkv_read_subelements_info( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size );
459static VC_CONTAINER_STATUS_T mkv_read_element_encoding( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size );
460static VC_CONTAINER_STATUS_T mkv_read_subelements_encoding( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size );
461static VC_CONTAINER_STATUS_T mkv_read_subelements_compression( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size );
462static VC_CONTAINER_STATUS_T mkv_read_subelements_seek_head( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size );
463static VC_CONTAINER_STATUS_T mkv_read_element_cues( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size );
464static VC_CONTAINER_STATUS_T mkv_read_subelements_cue_point( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size );
465
466static VC_CONTAINER_STATUS_T mkv_read_subelements_cluster( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size );
467
468/******************************************************************************
469List of element IDs and their associated processing functions
470******************************************************************************/
471MKV_ELEMENT_T mkv_elements_list[] =
472{
473 /* EBML Basics */
474 {MKV_ELEMENT_ID_EBML, MKV_ELEMENT_ID_UNKNOWN, "EBML", mkv_read_element_ebml},
475 {MKV_ELEMENT_ID_EBML_VERSION, MKV_ELEMENT_ID_EBML, "EBMLVersion", mkv_read_subelements_ebml},
476 {MKV_ELEMENT_ID_EBML_READ_VERSION, MKV_ELEMENT_ID_EBML, "EBMLReadVersion", mkv_read_subelements_ebml},
477 {MKV_ELEMENT_ID_EBML_MAX_ID_LENGTH, MKV_ELEMENT_ID_EBML, "EBMLMaxIDLength", mkv_read_subelements_ebml},
478 {MKV_ELEMENT_ID_EBML_MAX_SIZE_LENGTH, MKV_ELEMENT_ID_EBML, "EBMLMaxSizeLength", mkv_read_subelements_ebml},
479 {MKV_ELEMENT_ID_DOCTYPE, MKV_ELEMENT_ID_EBML, "DocType", mkv_read_subelements_ebml},
480 {MKV_ELEMENT_ID_DOCTYPE_VERSION, MKV_ELEMENT_ID_EBML, "DocTypeVersion", mkv_read_subelements_ebml},
481 {MKV_ELEMENT_ID_DOCTYPE_READ_VERSION, MKV_ELEMENT_ID_EBML, "DocTypeReadVersion", mkv_read_subelements_ebml},
482
483 /* Global Elements */
484 {MKV_ELEMENT_ID_CRC32, MKV_ELEMENT_ID_INVALID, "CRC-32", 0},
485 {MKV_ELEMENT_ID_VOID, MKV_ELEMENT_ID_INVALID, "Void", 0},
486
487 /* Segment */
488 {MKV_ELEMENT_ID_SEGMENT, MKV_ELEMENT_ID_UNKNOWN, "Segment", mkv_read_element_segment},
489
490 /* Meta Seek Information */
491 {MKV_ELEMENT_ID_SEEK_HEAD, MKV_ELEMENT_ID_SEGMENT, "SeekHead", mkv_read_elements},
492 {MKV_ELEMENT_ID_SEEK, MKV_ELEMENT_ID_SEEK_HEAD, "Seek", mkv_read_subelements_seek_head},
493 {MKV_ELEMENT_ID_SEEK_ID, MKV_ELEMENT_ID_SEEK, "SeekID", mkv_read_subelements_seek_head},
494 {MKV_ELEMENT_ID_SEEK_POSITION, MKV_ELEMENT_ID_SEEK, "SeekPosition", mkv_read_subelements_seek_head},
495
496 /* Segment Information */
497 {MKV_ELEMENT_ID_INFO, MKV_ELEMENT_ID_SEGMENT, "Info", mkv_read_elements},
498 {MKV_ELEMENT_ID_SEGMENT_UID, MKV_ELEMENT_ID_INFO, "SegmentUID", 0},
499 {MKV_ELEMENT_ID_SEGMENT_FILENAME, MKV_ELEMENT_ID_INFO, "SegmentFilename", 0},
500 {MKV_ELEMENT_ID_PREV_UID, MKV_ELEMENT_ID_INFO, "PrevUID", 0},
501 {MKV_ELEMENT_ID_PREV_FILENAME, MKV_ELEMENT_ID_INFO, "PrevFilename", 0},
502 {MKV_ELEMENT_ID_NEXT_UID, MKV_ELEMENT_ID_INFO, "NextUID", 0},
503 {MKV_ELEMENT_ID_NEXT_FILENAME, MKV_ELEMENT_ID_INFO, "NextFilename", 0},
504 {MKV_ELEMENT_ID_SEGMENT_FAMILY, MKV_ELEMENT_ID_INFO, "SegmentFamily", 0},
505 {MKV_ELEMENT_ID_CHAPTER_TRANSLATE, MKV_ELEMENT_ID_INFO, "ChapterTranslate", 0},
506 {MKV_ELEMENT_ID_CHAPTER_TRANSLATE_EDITION_UID, MKV_ELEMENT_ID_INFO, "ChapterTranslateEditionUID", 0},
507 {MKV_ELEMENT_ID_CHAPTER_TRANSLATE_CODEC, MKV_ELEMENT_ID_INFO, "ChapterTranslateCodec", 0},
508 {MKV_ELEMENT_ID_CHAPTER_TRANSLATE_ID, MKV_ELEMENT_ID_INFO, "ChapterTranslateID", 0},
509 {MKV_ELEMENT_ID_TIMECODE_SCALE, MKV_ELEMENT_ID_INFO, "TimecodeScale", mkv_read_subelements_info},
510 {MKV_ELEMENT_ID_DURATION, MKV_ELEMENT_ID_INFO, "Duration", mkv_read_subelements_info},
511 {MKV_ELEMENT_ID_DATE_UTC, MKV_ELEMENT_ID_INFO, "DateUTC", 0},
512 {MKV_ELEMENT_ID_TITLE, MKV_ELEMENT_ID_INFO, "Title", mkv_read_subelements_info},
513 {MKV_ELEMENT_ID_MUXING_APP, MKV_ELEMENT_ID_INFO, "MuxingApp", mkv_read_subelements_info},
514 {MKV_ELEMENT_ID_WRITING_APP, MKV_ELEMENT_ID_INFO, "WritingApp", mkv_read_subelements_info},
515
516 /* Cluster */
517 {MKV_ELEMENT_ID_CLUSTER, MKV_ELEMENT_ID_SEGMENT, "Cluster", 0},
518 {MKV_ELEMENT_ID_TIMECODE, MKV_ELEMENT_ID_CLUSTER, "Timecode", 0},
519 {MKV_ELEMENT_ID_SILENT_TRACKS, MKV_ELEMENT_ID_CLUSTER, "SilentTracks", 0},
520 {MKV_ELEMENT_ID_SILENT_TRACK_NUMBER, MKV_ELEMENT_ID_CLUSTER, "SilentTrackNumber", 0},
521 {MKV_ELEMENT_ID_POSITION, MKV_ELEMENT_ID_CLUSTER, "Position", 0},
522 {MKV_ELEMENT_ID_PREV_SIZE, MKV_ELEMENT_ID_CLUSTER, "PrevSize", 0},
523 {MKV_ELEMENT_ID_BLOCKGROUP, MKV_ELEMENT_ID_CLUSTER, "BlockGroup", 0},
524 {MKV_ELEMENT_ID_BLOCK, MKV_ELEMENT_ID_BLOCKGROUP, "Block", 0},
525 {MKV_ELEMENT_ID_BLOCK_ADDITIONS, MKV_ELEMENT_ID_BLOCKGROUP, "BlockAdditions", 0},
526 {MKV_ELEMENT_ID_BLOCK_MORE, MKV_ELEMENT_ID_BLOCK_ADDITIONS, "BlockMore", 0},
527 {MKV_ELEMENT_ID_BLOCK_ADD_ID, MKV_ELEMENT_ID_BLOCK_MORE, "BlockAddId", 0},
528 {MKV_ELEMENT_ID_BLOCK_ADDITIONAL, MKV_ELEMENT_ID_BLOCK_MORE, "BlockAdditional", 0},
529 {MKV_ELEMENT_ID_BLOCK_DURATION, MKV_ELEMENT_ID_BLOCKGROUP, "BlockDuration", 0},
530 {MKV_ELEMENT_ID_REFERENCE_PRIORITY, MKV_ELEMENT_ID_BLOCKGROUP, "ReferencePriority", 0},
531 {MKV_ELEMENT_ID_REFERENCE_BLOCK, MKV_ELEMENT_ID_BLOCKGROUP, "ReferenceBlock", 0},
532 {MKV_ELEMENT_ID_CODEC_STATE, MKV_ELEMENT_ID_BLOCKGROUP, "CodecState", 0},
533 {MKV_ELEMENT_ID_SLICES, MKV_ELEMENT_ID_BLOCKGROUP, "Slices", 0},
534 {MKV_ELEMENT_ID_TIME_SLICE, MKV_ELEMENT_ID_SLICES, "TimeSlice", 0},
535 {MKV_ELEMENT_ID_LACE_NUMBER, MKV_ELEMENT_ID_TIME_SLICE, "LaceNumber", 0},
536 {MKV_ELEMENT_ID_SIMPLE_BLOCK, MKV_ELEMENT_ID_CLUSTER, "SimpleBlock", 0},
537
538 /* Track */
539 {MKV_ELEMENT_ID_TRACKS, MKV_ELEMENT_ID_SEGMENT, "Tracks", mkv_read_elements},
540 {MKV_ELEMENT_ID_TRACK_ENTRY, MKV_ELEMENT_ID_TRACKS, "TrackEntry", mkv_read_element_track_entry},
541 {MKV_ELEMENT_ID_TRACK_NUMBER, MKV_ELEMENT_ID_TRACK_ENTRY, "TrackNumber", mkv_read_subelements_track_entry},
542 {MKV_ELEMENT_ID_TRACK_UID, MKV_ELEMENT_ID_TRACK_ENTRY, "TrackUID", mkv_read_subelements_track_entry},
543 {MKV_ELEMENT_ID_TRACK_TYPE, MKV_ELEMENT_ID_TRACK_ENTRY, "TrackType", mkv_read_subelements_track_entry},
544 {MKV_ELEMENT_ID_FLAG_ENABLED, MKV_ELEMENT_ID_TRACK_ENTRY, "FlagEnabled", mkv_read_subelements_track_entry},
545 {MKV_ELEMENT_ID_FLAG_DEFAULT, MKV_ELEMENT_ID_TRACK_ENTRY, "FlagDefault", mkv_read_subelements_track_entry},
546 {MKV_ELEMENT_ID_FLAG_FORCED, MKV_ELEMENT_ID_TRACK_ENTRY, "FlagForced", mkv_read_subelements_track_entry},
547 {MKV_ELEMENT_ID_FLAG_LACING, MKV_ELEMENT_ID_TRACK_ENTRY, "FlagLacing", mkv_read_subelements_track_entry},
548 {MKV_ELEMENT_ID_MIN_CACHE, MKV_ELEMENT_ID_TRACK_ENTRY, "MinCache", 0},
549 {MKV_ELEMENT_ID_MAX_CACHE, MKV_ELEMENT_ID_TRACK_ENTRY, "MaxCache", 0},
550 {MKV_ELEMENT_ID_DEFAULT_DURATION, MKV_ELEMENT_ID_TRACK_ENTRY, "DefaultDuration", mkv_read_subelements_track_entry},
551 {MKV_ELEMENT_ID_TRACK_TIMECODE_SCALE, MKV_ELEMENT_ID_TRACK_ENTRY, "TrackTimecodeScale", mkv_read_subelements_track_entry},
552 {MKV_ELEMENT_ID_MAX_BLOCK_ADDITION_ID, MKV_ELEMENT_ID_TRACK_ENTRY, "MaxBlockAdditionID", 0},
553 {MKV_ELEMENT_ID_NAME, MKV_ELEMENT_ID_TRACK_ENTRY, "Name", mkv_read_subelements_track_entry},
554 {MKV_ELEMENT_ID_LANGUAGE, MKV_ELEMENT_ID_TRACK_ENTRY, "Language", mkv_read_subelements_track_entry},
555 {MKV_ELEMENT_ID_TRACK_CODEC_ID, MKV_ELEMENT_ID_TRACK_ENTRY, "CodecID", mkv_read_subelements_track_entry},
556 {MKV_ELEMENT_ID_TRACK_CODEC_PRIVATE, MKV_ELEMENT_ID_TRACK_ENTRY, "CodecPrivate", mkv_read_subelements_track_entry},
557 {MKV_ELEMENT_ID_TRACK_CODEC_NAME, MKV_ELEMENT_ID_TRACK_ENTRY, "CodecName", mkv_read_subelements_track_entry},
558 {MKV_ELEMENT_ID_ATTACHMENT_LINK, MKV_ELEMENT_ID_TRACK_ENTRY, "AttachmentLink", 0},
559 {MKV_ELEMENT_ID_CODEC_DECODE_ALL, MKV_ELEMENT_ID_TRACK_ENTRY, "DecodeAll", 0},
560 {MKV_ELEMENT_ID_TRACK_OVERLAY, MKV_ELEMENT_ID_TRACK_ENTRY, "TrackOverlay", 0},
561 {MKV_ELEMENT_ID_TRACK_TRANSLATE, MKV_ELEMENT_ID_TRACK_ENTRY, "TrackTranslate", 0},
562 {MKV_ELEMENT_ID_TRACK_TRANSLATE_EDITION_UID, MKV_ELEMENT_ID_TRACK_TRANSLATE, "TrackTranslateEditionUID", 0},
563 {MKV_ELEMENT_ID_TRACK_TRANSLATE_CODEC, MKV_ELEMENT_ID_TRACK_TRANSLATE, "TrackTranslateCodec", 0},
564 {MKV_ELEMENT_ID_TRACK_TRANSLATE_TRACK_ID, MKV_ELEMENT_ID_TRACK_TRANSLATE, "TrackTranslateTrackID", 0},
565
566 /* Video */
567 {MKV_ELEMENT_ID_VIDEO, MKV_ELEMENT_ID_TRACK_ENTRY, "Video", mkv_read_elements},
568 {MKV_ELEMENT_ID_FLAG_INTERLACED, MKV_ELEMENT_ID_VIDEO, "FlagInterlaced", mkv_read_subelements_video},
569 {MKV_ELEMENT_ID_STEREO_MODE, MKV_ELEMENT_ID_VIDEO, "StereoMode", mkv_read_subelements_video},
570 {MKV_ELEMENT_ID_PIXEL_WIDTH, MKV_ELEMENT_ID_VIDEO, "PixelWidth", mkv_read_subelements_video},
571 {MKV_ELEMENT_ID_PIXEL_HEIGHT, MKV_ELEMENT_ID_VIDEO, "PixelHeight", mkv_read_subelements_video},
572 {MKV_ELEMENT_ID_PIXEL_CROP_BOTTOM, MKV_ELEMENT_ID_VIDEO, "PixelCropBottom", mkv_read_subelements_video},
573 {MKV_ELEMENT_ID_PIXEL_CROP_TOP, MKV_ELEMENT_ID_VIDEO, "PixelCropTop", mkv_read_subelements_video},
574 {MKV_ELEMENT_ID_PIXEL_CROP_LEFT, MKV_ELEMENT_ID_VIDEO, "PixelCropLeft", mkv_read_subelements_video},
575 {MKV_ELEMENT_ID_PIXEL_CROP_RIGHT, MKV_ELEMENT_ID_VIDEO, "PixelCropRight", mkv_read_subelements_video},
576 {MKV_ELEMENT_ID_DISPLAY_WIDTH, MKV_ELEMENT_ID_VIDEO, "DisplayWidth", mkv_read_subelements_video},
577 {MKV_ELEMENT_ID_DISPLAY_HEIGHT, MKV_ELEMENT_ID_VIDEO, "DisplayHeight", mkv_read_subelements_video},
578 {MKV_ELEMENT_ID_DISPLAY_UNIT, MKV_ELEMENT_ID_VIDEO, "DisplayUnit", mkv_read_subelements_video},
579 {MKV_ELEMENT_ID_ASPECT_RATIO_TYPE, MKV_ELEMENT_ID_VIDEO, "AspectRatioType", mkv_read_subelements_video},
580 {MKV_ELEMENT_ID_COLOUR_SPACE, MKV_ELEMENT_ID_VIDEO, "ColourSpace", mkv_read_subelements_video},
581 {MKV_ELEMENT_ID_FRAME_RATE, MKV_ELEMENT_ID_VIDEO, "FrameRate", mkv_read_subelements_video},
582
583 /* Audio */
584 {MKV_ELEMENT_ID_AUDIO, MKV_ELEMENT_ID_TRACK_ENTRY, "Audio", mkv_read_elements},
585 {MKV_ELEMENT_ID_SAMPLING_FREQUENCY, MKV_ELEMENT_ID_AUDIO, "SamplingFrequency", mkv_read_subelements_audio},
586 {MKV_ELEMENT_ID_OUTPUT_SAMPLING_FREQUENCY, MKV_ELEMENT_ID_AUDIO, "OutputSamplingFrequency", mkv_read_subelements_audio},
587 {MKV_ELEMENT_ID_CHANNELS, MKV_ELEMENT_ID_AUDIO, "Channels", mkv_read_subelements_audio},
588 {MKV_ELEMENT_ID_BIT_DEPTH, MKV_ELEMENT_ID_AUDIO, "BitDepth", mkv_read_subelements_audio},
589
590 /* Content Encoding */
591 {MKV_ELEMENT_ID_CONTENT_ENCODINGS, MKV_ELEMENT_ID_TRACK_ENTRY, "ContentEncodings", mkv_read_elements},
592 {MKV_ELEMENT_ID_CONTENT_ENCODING, MKV_ELEMENT_ID_CONTENT_ENCODINGS, "ContentEncoding", mkv_read_element_encoding},
593 {MKV_ELEMENT_ID_CONTENT_ENCODING_ORDER, MKV_ELEMENT_ID_CONTENT_ENCODING, "ContentEncodingOrder", mkv_read_subelements_encoding},
594 {MKV_ELEMENT_ID_CONTENT_ENCODING_SCOPE, MKV_ELEMENT_ID_CONTENT_ENCODING, "ContentEncodingScope", mkv_read_subelements_encoding},
595 {MKV_ELEMENT_ID_CONTENT_ENCODING_TYPE, MKV_ELEMENT_ID_CONTENT_ENCODING, "ContentEncodingType", mkv_read_subelements_encoding},
596 {MKV_ELEMENT_ID_CONTENT_COMPRESSION, MKV_ELEMENT_ID_CONTENT_ENCODING, "ContentCompression", mkv_read_elements},
597 {MKV_ELEMENT_ID_CONTENT_COMPRESSION_ALGO, MKV_ELEMENT_ID_CONTENT_COMPRESSION, "ContentCompAlgo", mkv_read_subelements_compression},
598 {MKV_ELEMENT_ID_CONTENT_COMPRESSION_SETTINGS, MKV_ELEMENT_ID_CONTENT_COMPRESSION, "ContentCompSettings", mkv_read_subelements_compression},
599 {MKV_ELEMENT_ID_CONTENT_ENCRYPTION, MKV_ELEMENT_ID_CONTENT_ENCODING, "ContentEncryption", mkv_read_elements},
600 {MKV_ELEMENT_ID_CONTENT_ENCRYPTION_ALGO, MKV_ELEMENT_ID_CONTENT_ENCRYPTION, "ContentEncAlgo", 0},
601 {MKV_ELEMENT_ID_CONTENT_ENCRYPTION_KEY_ID, MKV_ELEMENT_ID_CONTENT_ENCRYPTION, "ContentEncKeyID", 0},
602 {MKV_ELEMENT_ID_CONTENT_SIGNATURE, MKV_ELEMENT_ID_CONTENT_ENCRYPTION, "ContentSignature", 0},
603 {MKV_ELEMENT_ID_CONTENT_SIGNATURE_KEY_ID, MKV_ELEMENT_ID_CONTENT_ENCRYPTION, "ContentSigKeyID", 0},
604 {MKV_ELEMENT_ID_CONTENT_SIGNATURE_ALGO, MKV_ELEMENT_ID_CONTENT_ENCRYPTION, "ContentSigAlgo", 0},
605 {MKV_ELEMENT_ID_CONTENT_SIGNATURE_HASH_ALGO, MKV_ELEMENT_ID_CONTENT_ENCRYPTION, "ContentSigHashAlgo", 0},
606
607 /* Cueing data */
608 {MKV_ELEMENT_ID_CUES, MKV_ELEMENT_ID_SEGMENT, "Cues", mkv_read_element_cues},
609 {MKV_ELEMENT_ID_CUE_POINT, MKV_ELEMENT_ID_CUES, "Cue Point", mkv_read_elements},
610 {MKV_ELEMENT_ID_CUE_TIME, MKV_ELEMENT_ID_CUE_POINT, "Cue Time", 0},
611 {MKV_ELEMENT_ID_CUE_TRACK_POSITIONS, MKV_ELEMENT_ID_CUE_POINT, "Cue Track Positions", mkv_read_elements},
612 {MKV_ELEMENT_ID_CUE_TRACK, MKV_ELEMENT_ID_CUE_TRACK_POSITIONS, "Cue Track", 0},
613 {MKV_ELEMENT_ID_CUE_CLUSTER_POSITION, MKV_ELEMENT_ID_CUE_TRACK_POSITIONS, "Cue Cluster Position", 0},
614 {MKV_ELEMENT_ID_CUE_BLOCK_NUMBER, MKV_ELEMENT_ID_CUE_TRACK_POSITIONS, "Cue Block Number", 0},
615
616 /* Attachments */
617 {MKV_ELEMENT_ID_ATTACHMENTS, MKV_ELEMENT_ID_SEGMENT, "Attachments", 0},
618
619 /* Chapters */
620 {MKV_ELEMENT_ID_CHAPTERS, MKV_ELEMENT_ID_SEGMENT, "Chapters", 0},
621
622 /* Tagging */
623 {MKV_ELEMENT_ID_TAGS, MKV_ELEMENT_ID_SEGMENT, "Tags", mkv_read_elements},
624 {MKV_ELEMENT_ID_TAG, MKV_ELEMENT_ID_TAGS, "Tag", mkv_read_elements},
625 {MKV_ELEMENT_ID_TAG_TARGETS, MKV_ELEMENT_ID_TAG, "Tag Targets", mkv_read_elements},
626 {MKV_ELEMENT_ID_TAG_TARGET_TYPE_VALUE, MKV_ELEMENT_ID_TAG_TARGETS, "Tag Target Type Value", 0},
627 {MKV_ELEMENT_ID_TAG_TARGET_TYPE, MKV_ELEMENT_ID_TAG_TARGETS, "Tag Target Type", 0},
628 {MKV_ELEMENT_ID_TAG_TRACK_UID, MKV_ELEMENT_ID_TAG_TARGETS, "Tag Track UID", 0},
629 {MKV_ELEMENT_ID_TAG_EDITION_UID, MKV_ELEMENT_ID_TAG_TARGETS, "Tag Edition UID", 0},
630 {MKV_ELEMENT_ID_TAG_CHAPTER_UID, MKV_ELEMENT_ID_TAG_TARGETS, "Tag Chapter UID", 0},
631 {MKV_ELEMENT_ID_TAG_ATTACHMENT_UID, MKV_ELEMENT_ID_TAG_TARGETS, "Tag Attachment UID", 0},
632 {MKV_ELEMENT_ID_TAG_SIMPLE_TAG, MKV_ELEMENT_ID_TAG, "Simple Tag", mkv_read_elements},
633 {MKV_ELEMENT_ID_TAG_NAME, MKV_ELEMENT_ID_TAG_SIMPLE_TAG, "Tag Name", 0},
634 {MKV_ELEMENT_ID_TAG_LANGUAGE, MKV_ELEMENT_ID_TAG_SIMPLE_TAG, "Tag Language", 0},
635 {MKV_ELEMENT_ID_TAG_DEFAULT, MKV_ELEMENT_ID_TAG_SIMPLE_TAG, "Tag Default", 0},
636 {MKV_ELEMENT_ID_TAG_STRING, MKV_ELEMENT_ID_TAG_SIMPLE_TAG, "Tag String", 0},
637 {MKV_ELEMENT_ID_TAG_BINARY, MKV_ELEMENT_ID_TAG_SIMPLE_TAG, "Tag Binary", 0},
638
639 {MKV_ELEMENT_ID_UNKNOWN, MKV_ELEMENT_ID_INVALID, "unknown", 0}
640};
641
642MKV_ELEMENT_T mkv_cluster_elements_list[] =
643{
644 /* Cluster */
645 {MKV_ELEMENT_ID_CLUSTER, MKV_ELEMENT_ID_SEGMENT, "Cluster", 0},
646 {MKV_ELEMENT_ID_TIMECODE, MKV_ELEMENT_ID_CLUSTER, "Timecode", mkv_read_subelements_cluster},
647 {MKV_ELEMENT_ID_SILENT_TRACKS, MKV_ELEMENT_ID_CLUSTER, "SilentTracks", 0},
648 {MKV_ELEMENT_ID_SILENT_TRACK_NUMBER, MKV_ELEMENT_ID_CLUSTER, "SilentTrackNumber", 0},
649 {MKV_ELEMENT_ID_POSITION, MKV_ELEMENT_ID_CLUSTER, "Position", 0},
650 {MKV_ELEMENT_ID_PREV_SIZE, MKV_ELEMENT_ID_CLUSTER, "PrevSize", 0},
651 {MKV_ELEMENT_ID_BLOCKGROUP, MKV_ELEMENT_ID_CLUSTER, "BlockGroup", 0},
652 {MKV_ELEMENT_ID_BLOCK, MKV_ELEMENT_ID_BLOCKGROUP, "Block", 0},
653 {MKV_ELEMENT_ID_BLOCK_ADDITIONS, MKV_ELEMENT_ID_BLOCKGROUP, "BlockAdditions", 0},
654 {MKV_ELEMENT_ID_BLOCK_MORE, MKV_ELEMENT_ID_BLOCK_ADDITIONS, "BlockMore", 0},
655 {MKV_ELEMENT_ID_BLOCK_ADD_ID, MKV_ELEMENT_ID_BLOCK_MORE, "BlockAddId", 0},
656 {MKV_ELEMENT_ID_BLOCK_ADDITIONAL, MKV_ELEMENT_ID_BLOCK_MORE, "BlockAdditional", 0},
657 {MKV_ELEMENT_ID_BLOCK_DURATION, MKV_ELEMENT_ID_BLOCKGROUP, "BlockDuration", mkv_read_subelements_cluster},
658 {MKV_ELEMENT_ID_REFERENCE_PRIORITY, MKV_ELEMENT_ID_BLOCKGROUP, "ReferencePriority", 0},
659 {MKV_ELEMENT_ID_REFERENCE_BLOCK, MKV_ELEMENT_ID_BLOCKGROUP, "ReferenceBlock", 0},
660 {MKV_ELEMENT_ID_CODEC_STATE, MKV_ELEMENT_ID_BLOCKGROUP, "CodecState", 0},
661 {MKV_ELEMENT_ID_SLICES, MKV_ELEMENT_ID_BLOCKGROUP, "Slices", 0},
662 {MKV_ELEMENT_ID_TIME_SLICE, MKV_ELEMENT_ID_SLICES, "TimeSlice", 0},
663 {MKV_ELEMENT_ID_LACE_NUMBER, MKV_ELEMENT_ID_TIME_SLICE, "LaceNumber", 0},
664 {MKV_ELEMENT_ID_SIMPLE_BLOCK, MKV_ELEMENT_ID_CLUSTER, "SimpleBlock", 0},
665
666 /* Global Elements */
667 {MKV_ELEMENT_ID_CRC32, MKV_ELEMENT_ID_INVALID, "CRC-32", 0},
668 {MKV_ELEMENT_ID_VOID, MKV_ELEMENT_ID_INVALID, "Void", 0},
669
670 {MKV_ELEMENT_ID_UNKNOWN, MKV_ELEMENT_ID_INVALID, "unknown", 0}
671};
672
673MKV_ELEMENT_T mkv_cue_elements_list[] =
674{
675 /* Cueing data */
676 {MKV_ELEMENT_ID_CUES, MKV_ELEMENT_ID_SEGMENT, "Cues", 0},
677 {MKV_ELEMENT_ID_CUE_POINT, MKV_ELEMENT_ID_CUES, "Cue Point", mkv_read_elements},
678 {MKV_ELEMENT_ID_CUE_TIME, MKV_ELEMENT_ID_CUE_POINT, "Cue Time", mkv_read_subelements_cue_point},
679 {MKV_ELEMENT_ID_CUE_TRACK_POSITIONS, MKV_ELEMENT_ID_CUE_POINT, "Cue Track Positions", mkv_read_elements},
680 {MKV_ELEMENT_ID_CUE_TRACK, MKV_ELEMENT_ID_CUE_TRACK_POSITIONS, "Cue Track", mkv_read_subelements_cue_point},
681 {MKV_ELEMENT_ID_CUE_CLUSTER_POSITION, MKV_ELEMENT_ID_CUE_TRACK_POSITIONS, "Cue Cluster Position", mkv_read_subelements_cue_point},
682 {MKV_ELEMENT_ID_CUE_BLOCK_NUMBER, MKV_ELEMENT_ID_CUE_TRACK_POSITIONS, "Cue Block Number", mkv_read_subelements_cue_point},
683
684 /* Global Elements */
685 {MKV_ELEMENT_ID_CRC32, MKV_ELEMENT_ID_INVALID, "CRC-32", 0},
686 {MKV_ELEMENT_ID_VOID, MKV_ELEMENT_ID_INVALID, "Void", 0},
687
688 {MKV_ELEMENT_ID_UNKNOWN, MKV_ELEMENT_ID_INVALID, "unknown", 0}
689};
690
691/******************************************************************************
692List of codec mapping
693******************************************************************************/
694static const struct {
695 VC_CONTAINER_FOURCC_T fourcc;
696 const char *codecid;
697 VC_CONTAINER_FOURCC_T variant;
698} codecid_to_fourcc_table[] =
699{
700 /* Video */
701 {VC_CONTAINER_CODEC_MP1V, "V_MPEG1", 0},
702 {VC_CONTAINER_CODEC_MP2V, "V_MPEG2", 0},
703 {VC_CONTAINER_CODEC_MP4V, "V_MPEG4/ISO/ASP", 0},
704 {VC_CONTAINER_CODEC_MP4V, "V_MPEG4/ISO/SP", 0},
705 {VC_CONTAINER_CODEC_MP4V, "V_MPEG4/ISO/AP", 0},
706 {VC_CONTAINER_CODEC_DIV3, "V_MPEG4/MS/V3", 0},
707 {VC_CONTAINER_CODEC_H264, "V_MPEG4/ISO/AVC", VC_CONTAINER_VARIANT_H264_AVC1},
708 {VC_CONTAINER_CODEC_MJPEG, "V_MJPEG", 0},
709 {VC_CONTAINER_CODEC_RV10, "V_REAL/RV10", 0},
710 {VC_CONTAINER_CODEC_RV20, "V_REAL/RV20", 0},
711 {VC_CONTAINER_CODEC_RV30, "V_REAL/RV30", 0},
712 {VC_CONTAINER_CODEC_RV40, "V_REAL/RV40", 0},
713 {VC_CONTAINER_CODEC_THEORA, "V_THEORA", 0},
714 {VC_CONTAINER_CODEC_DIRAC, "V_DIRAC", 0},
715 {VC_CONTAINER_CODEC_VP8, "V_VP8", 0},
716
717 /* Audio */
718 {VC_CONTAINER_CODEC_MPGA, "A_MPEG/L3", VC_CONTAINER_VARIANT_MPGA_L3},
719 {VC_CONTAINER_CODEC_MPGA, "A_MPEG/L2", VC_CONTAINER_VARIANT_MPGA_L2},
720 {VC_CONTAINER_CODEC_MPGA, "A_MPEG/L1", VC_CONTAINER_VARIANT_MPGA_L1},
721 {VC_CONTAINER_CODEC_MP4A, "A_AAC", 0},
722 {VC_CONTAINER_CODEC_MP4A, "A_AAC/MPEG2/MAIN", 0},
723 {VC_CONTAINER_CODEC_MP4A, "A_AAC/MPEG2/LC", 0},
724 {VC_CONTAINER_CODEC_MP4A, "A_AAC/MPEG2/SSR", 0},
725 {VC_CONTAINER_CODEC_MP4A, "A_AAC/MPEG2/LC/SBR", 0},
726 {VC_CONTAINER_CODEC_MP4A, "A_AAC/MPEG4/MAIN", 0},
727 {VC_CONTAINER_CODEC_MP4A, "A_AAC/MPEG4/LC", 0},
728 {VC_CONTAINER_CODEC_MP4A, "A_AAC/MPEG4/SSR", 0},
729 {VC_CONTAINER_CODEC_MP4A, "A_AAC/MPEG4/LC/SBR", 0},
730 {VC_CONTAINER_CODEC_AC3, "A_AC3", 0},
731 {VC_CONTAINER_CODEC_EAC3, "A_EAC3", 0},
732 {VC_CONTAINER_CODEC_DTS, "A_DTS", 0},
733 {VC_CONTAINER_CODEC_MLP, "A_MLP", 0},
734 {0, "A_TRUEHD", 0},
735 {VC_CONTAINER_CODEC_VORBIS, "A_VORBIS", 0},
736 {VC_CONTAINER_CODEC_FLAC, "A_FLAC", 0},
737 {VC_CONTAINER_CODEC_PCM_SIGNED_LE, "A_PCM/INT/LIT", 0},
738 {VC_CONTAINER_CODEC_PCM_SIGNED_BE, "A_PCM/INT/BIG", 0},
739 {VC_CONTAINER_CODEC_PCM_FLOAT_LE, "A_PCM/FLOAT/IEEE", 0},
740 {0, "A_REAL/xyzt", 0},
741 {0, "A_REAL/14_4", 0},
742
743 /* Text */
744 {VC_CONTAINER_CODEC_TEXT, "S_TEXT/ASCII", 0},
745 {VC_CONTAINER_CODEC_TEXT, "S_TEXT/UTF8", 0},
746 {VC_CONTAINER_CODEC_SSA, "S_TEXT/ASS", 0},
747 {VC_CONTAINER_CODEC_SSA, "S_TEXT/SSA", 0},
748 {VC_CONTAINER_CODEC_SSA, "S_ASS", 0},
749 {VC_CONTAINER_CODEC_SSA, "S_SSA", 0},
750 {VC_CONTAINER_CODEC_USF, "S_TEXT/USF", 0},
751 {VC_CONTAINER_CODEC_VOBSUB, "S_VOBSUB", 0},
752
753 {0, 0}
754};
755
756/******************************************************************************
757Local Functions
758******************************************************************************/
759
760static VC_CONTAINER_FOURCC_T mkv_codecid_to_fourcc(const char *codecid,
761 VC_CONTAINER_FOURCC_T *variant)
762{
763 unsigned int i;
764 for(i = 0; codecid_to_fourcc_table[i].codecid; i++)
765 if(!strcmp(codecid_to_fourcc_table[i].codecid, codecid)) break;
766 if (variant) *variant = codecid_to_fourcc_table[i].variant;
767 return codecid_to_fourcc_table[i].fourcc;
768}
769
770#if 0
771/** Find the track associated with an MKV track number */
772static VC_CONTAINER_TRACK_T *mkv_reader_find_track( VC_CONTAINER_T *p_ctx, unsigned int mkv_track_num)
773{
774 VC_CONTAINER_TRACK_T *p_track = 0;
775 unsigned int i;
776
777 for(i = 0; i < p_ctx->tracks_num; i++)
778 if(p_ctx->tracks[i]->priv->module->number == mkv_track_num) break;
779
780 if(i < p_ctx->tracks_num) /* We found it */
781 p_track = p_ctx->tracks[i];
782
783 return p_track;
784}
785#endif
786
787/** Base function used to read an MKV/EBML element header.
788 * This will read the element header do lots of sanity checking and return the element id
789 * and the size of the data contained in the element */
790static VC_CONTAINER_STATUS_T mkv_read_element_header(VC_CONTAINER_T *p_ctx, int64_t size,
791 MKV_ELEMENT_ID_T *id, int64_t *element_size, MKV_ELEMENT_ID_T parent_id,
792 MKV_ELEMENT_T **elem)
793{
794 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
795 MKV_ELEMENT_T *element;
796
797 module->element_offset = STREAM_POSITION(p_ctx);
798
799 *id = MKV_READ_ID(p_ctx, "Element ID");
800 CHECK_POINT(p_ctx);
801 if(!*id)
802 {
803 LOG_DEBUG(p_ctx, "invalid element id %i", *id);
804 return VC_CONTAINER_ERROR_CORRUPTED;
805 }
806
807 if(elem) element = *elem;
808 else element = mkv_elements_list;
809
810 /* Find out which Element we are dealing with */
811 while(element->id && *id != element->id) element++;
812
813 *element_size = MKV_READ_UINT(p_ctx, "Element Size");
814 CHECK_POINT(p_ctx);
815 LOG_FORMAT(p_ctx, "- Element %s (ID 0x%x), Size: %"PRIi64", Offset: %"PRIi64,
816 element->psz_name, *id, *element_size, module->element_offset);
817
818 /* Sanity check the element size */
819 if(*element_size + 1 < 0 /* Shouldn't ever get that big */ ||
820 /* Only the segment / cluster elements can really be massive */
821 (*id != MKV_ELEMENT_ID_SEGMENT && *id != MKV_ELEMENT_ID_CLUSTER &&
822 *element_size > MKV_MAX_ELEMENT_SIZE))
823 {
824 LOG_DEBUG(p_ctx, "element %s has an invalid size (%"PRIi64")",
825 element->psz_name, *element_size);
826 return VC_CONTAINER_ERROR_CORRUPTED;
827 }
828 if(size >= 0 && *element_size > size)
829 {
830 LOG_DEBUG(p_ctx, "element %s is bigger than it should (%"PRIi64" > %"PRIi64")",
831 element->psz_name, *element_size, size);
832 return VC_CONTAINER_ERROR_CORRUPTED;
833 }
834
835 /* Sanity check that the element has the right parent */
836 if(element->id && element->parent_id != MKV_ELEMENT_ID_INVALID &&
837 parent_id != MKV_ELEMENT_ID_INVALID && parent_id != element->parent_id)
838 {
839 LOG_FORMAT(p_ctx, "Ignoring mis-placed element %s (ID 0x%x)", element->psz_name, *id);
840 while(element->id != MKV_ELEMENT_ID_UNKNOWN) element++;
841 }
842
843 /* Sanity check that the element isn't too deeply nested */
844 if(module->element_level >= MKV_MAX_ELEMENT_LEVEL)
845 {
846 LOG_DEBUG(p_ctx, "element %s is too deep. skipping", element->psz_name);
847 while(element->id != MKV_ELEMENT_ID_UNKNOWN) element++;
848 }
849
850 if(elem) *elem = element;
851 return STREAM_STATUS(p_ctx);
852}
853
854static VC_CONTAINER_STATUS_T mkv_read_element_data(VC_CONTAINER_T *p_ctx,
855 MKV_ELEMENT_T *element, int64_t element_size, int64_t size)
856{
857 VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
858 int64_t offset;
859
860 offset = STREAM_POSITION(p_ctx);
861 if (size < 0) size = element_size;
862 if (size < 0) size = INT64_C(1) << 62;
863
864 /* Call the element specific parsing function */
865 if(element->pf_func)
866 status = element->pf_func(p_ctx, element->id, element_size < 0 ? size : element_size);
867
868 if(status != VC_CONTAINER_SUCCESS)
869 LOG_DEBUG(p_ctx, "element %s appears to be corrupted (%i)", element->psz_name, status);
870
871 if(element_size < 0) return STREAM_STATUS(p_ctx); /* Unknown size */
872
873 /* Skip the rest of the element */
874 element_size -= (STREAM_POSITION(p_ctx) - offset);
875 if(element_size < 0) /* Check for overruns */
876 {
877 /* Things have gone really bad here and we ended up reading past the end of the
878 * element. We could maybe try to be clever and recover by seeking back to the end
879 * of the element. However if we get there, the file is clearly corrupted so there's
880 * no guarantee it would work anyway. */
881 LOG_DEBUG(p_ctx, "%"PRIi64" bytes overrun past the end of element %s",
882 -element_size, element->psz_name);
883 return VC_CONTAINER_ERROR_CORRUPTED;
884 }
885
886 if(element_size)
887 LOG_FORMAT(p_ctx, "%"PRIi64" bytes left unread in element %s", element_size, element->psz_name);
888
889 if(element_size < MKV_MAX_ELEMENT_SIZE) SKIP_BYTES(p_ctx, element_size);
890 else SEEK(p_ctx, STREAM_POSITION(p_ctx) + element_size);
891
892 return STREAM_STATUS(p_ctx);
893}
894
895/** Base function used to read an MKV/EBML element.
896 * This will read the element header do lots of sanity checking and pass on the rest
897 * of the reading to the element specific reading function */
898static VC_CONTAINER_STATUS_T mkv_read_element(VC_CONTAINER_T *p_ctx,
899 int64_t size, MKV_ELEMENT_ID_T parent_id)
900{
901 VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
902 MKV_ELEMENT_T *element = p_ctx->priv->module->elements_list;
903 int64_t element_size;
904 MKV_ELEMENT_ID_T id;
905
906 status = mkv_read_element_header(p_ctx, size, &id, &element_size, parent_id, &element);
907 if(status != VC_CONTAINER_SUCCESS) return status;
908 return mkv_read_element_data(p_ctx, element, element_size, size);
909}
910
911/** Reads an unsigned integer element */
912static VC_CONTAINER_STATUS_T mkv_read_element_data_uint(VC_CONTAINER_T *p_ctx,
913 int64_t size, uint64_t *value)
914{
915 switch(size)
916 {
917 case 1: *value = READ_U8(p_ctx, "u8-integer"); break;
918 case 2: *value = READ_U16(p_ctx, "u16-integer"); break;
919 case 3: *value = READ_U24(p_ctx, "u24-integer"); break;
920 case 4: *value = READ_U32(p_ctx, "u32-integer"); break;
921 case 5: *value = READ_U40(p_ctx, "u40-integer"); break;
922 case 6: *value = READ_U48(p_ctx, "u48-integer"); break;
923 case 7: *value = READ_U56(p_ctx, "u56-integer"); break;
924 case 8: *value = READ_U64(p_ctx, "u64-integer"); break;
925 default: return VC_CONTAINER_ERROR_CORRUPTED;
926 }
927 return STREAM_STATUS(p_ctx);
928}
929
930/** Reads a float element */
931static VC_CONTAINER_STATUS_T mkv_read_element_data_float(VC_CONTAINER_T *p_ctx,
932 int64_t size, double *value)
933{
934 union {
935 uint32_t u32;
936 uint64_t u64;
937 float f;
938 double d;
939 } u;
940
941 switch(size)
942 {
943 case 4: u.u32 = READ_U32(p_ctx, "f32-float"); *value = u.f; break;
944 case 8: u.u64 = READ_U64(p_ctx, "f64-float"); *value = u.d; break;
945 default: return VC_CONTAINER_ERROR_CORRUPTED;
946 }
947 LOG_FORMAT(p_ctx, "float: %f", *value);
948 return STREAM_STATUS(p_ctx);
949}
950
951/** Reads an MKV EBML element */
952static VC_CONTAINER_STATUS_T mkv_read_element_ebml(VC_CONTAINER_T *p_ctx,
953 MKV_ELEMENT_ID_T id, int64_t size)
954{
955 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
956 VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
957 int64_t offset = STREAM_POSITION(p_ctx);
958
959 /* Read contained elements */
960 module->element_level++;
961 while(status == VC_CONTAINER_SUCCESS && size >= MKV_ELEMENT_MIN_HEADER_SIZE)
962 {
963 offset = STREAM_POSITION(p_ctx);
964 status = mkv_read_element(p_ctx, size, id);
965 size -= (STREAM_POSITION(p_ctx) - offset);
966 }
967 module->element_level--;
968 return status;
969}
970
971/** Reads the MKV EBML sub-element */
972static VC_CONTAINER_STATUS_T mkv_read_subelements_ebml( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size )
973{
974 VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
975 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
976 uint64_t value;
977
978 /* Deal with DocType first since it's a special case */
979 if(id == MKV_ELEMENT_ID_DOCTYPE)
980 {
981 char doctype[] = "matroska doctype";
982
983 /* Check we've got the right doctype string for matroska */
984 if(size <= 0) goto unknown_doctype;
985 if(size > (int)sizeof(doctype)) goto unknown_doctype;
986 if((int)READ_STRING(p_ctx, doctype, size, "string") != size) return STREAM_STATUS(p_ctx);
987 if((size != sizeof("matroska")-1 || strncmp(doctype, "matroska", (int)size)) &&
988 (size != sizeof("webm")-1 || strncmp(doctype, "webm", (int)size)))
989 goto unknown_doctype;
990
991 module->is_doctype_valid = true;
992 return VC_CONTAINER_SUCCESS;
993
994 unknown_doctype:
995 LOG_DEBUG(p_ctx, "invalid doctype");
996 return VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED;
997 }
998
999 /* The rest are just unsigned integers */
1000 status = mkv_read_element_data_uint(p_ctx, size, &value);
1001 if(status != VC_CONTAINER_SUCCESS) return status;
1002
1003 switch(id)
1004 {
1005 case MKV_ELEMENT_ID_EBML_VERSION:
1006 case MKV_ELEMENT_ID_EBML_READ_VERSION:
1007 if(value != 1) return VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED;
1008 break;
1009 case MKV_ELEMENT_ID_EBML_MAX_ID_LENGTH:
1010 if(value > 4) return VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED;
1011 break;
1012 case MKV_ELEMENT_ID_EBML_MAX_SIZE_LENGTH:
1013 if(value > 8) return VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED;
1014 break;
1015 case MKV_ELEMENT_ID_DOCTYPE_VERSION:
1016 case MKV_ELEMENT_ID_DOCTYPE_READ_VERSION:
1017 default: break;
1018 }
1019
1020 return STREAM_STATUS(p_ctx);
1021}
1022
1023static VC_CONTAINER_STATUS_T mkv_read_elements( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size )
1024{
1025 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
1026 VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
1027 int64_t offset = STREAM_POSITION(p_ctx);
1028 bool unknown_size = size < 0;
1029
1030 /* Read contained elements */
1031 module->element_level++;
1032 while(status == VC_CONTAINER_SUCCESS &&
1033 (unknown_size || size >= MKV_ELEMENT_MIN_HEADER_SIZE))
1034 {
1035 offset = STREAM_POSITION(p_ctx);
1036 status = mkv_read_element(p_ctx, size, id);
1037 if(!unknown_size) size -= (STREAM_POSITION(p_ctx) - offset);
1038 }
1039 module->element_level--;
1040 return status;
1041}
1042
1043static VC_CONTAINER_STATUS_T mkv_read_element_segment( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size )
1044{
1045 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
1046 VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
1047 int64_t offset = STREAM_POSITION(p_ctx);
1048 bool unknown_size = size < 0;
1049
1050 /* Read contained elements */
1051 /* Initialise state used by reader */
1052 module->state.level = 0;
1053 module->state.levels[0].offset = STREAM_POSITION(p_ctx);
1054 module->state.levels[0].size = size;
1055 module->state.levels[0].id = MKV_ELEMENT_ID_SEGMENT;
1056 module->state.levels[0].data_start = 0;
1057 module->state.levels[0].data_offset = 0;
1058 module->timecode_scale = 1000000;
1059 module->duration = 0.0;
1060 module->segment_offset = STREAM_POSITION(p_ctx);
1061 module->segment_size = size;
1062
1063 /* Read contained elements until we have all the information we need to start
1064 * playing the stream */
1065 module->element_level++;
1066 while(status == VC_CONTAINER_SUCCESS &&
1067 (unknown_size || size >= MKV_ELEMENT_MIN_HEADER_SIZE))
1068 {
1069 MKV_ELEMENT_T *child = mkv_elements_list;
1070 MKV_ELEMENT_ID_T child_id;
1071 int64_t child_size;
1072
1073 offset = STREAM_POSITION(p_ctx);
1074
1075 status = mkv_read_element_header(p_ctx, size, &child_id, &child_size, id, &child);
1076 if(status != VC_CONTAINER_SUCCESS) break;
1077
1078 if(child_id == MKV_ELEMENT_ID_CLUSTER)
1079 {
1080 /* We found the start of the data */
1081 module->cluster_offset = module->element_offset;
1082 module->state.level = 1;
1083 module->state.levels[1].offset = STREAM_POSITION(p_ctx);
1084 module->state.levels[1].size = child_size;
1085 module->state.levels[1].id = MKV_ELEMENT_ID_CLUSTER;
1086 module->state.levels[1].data_start = 0;
1087 module->state.levels[1].data_offset = 0;
1088 break;
1089 }
1090
1091 status = mkv_read_element_data(p_ctx, child, child_size, size);
1092 if(!unknown_size) size -= (STREAM_POSITION(p_ctx) - offset);
1093 }
1094
1095 module->element_level--;
1096 return status;
1097}
1098
1099static VC_CONTAINER_STATUS_T mkv_read_element_track_entry( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size )
1100{
1101 VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
1102 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
1103 VC_CONTAINER_ES_TYPE_T es_type = VC_CONTAINER_ES_TYPE_UNKNOWN;
1104 VC_CONTAINER_TRACK_MODULE_T *track_module;
1105 VC_CONTAINER_TRACK_T *track;
1106 VC_CONTAINER_FOURCC_T fourcc = 0, variant = 0;
1107 unsigned int i, extra_size = 0, extra_offset = 0, is_wf = 0, is_bmih = 0;
1108
1109 /* Allocate and initialise track data */
1110 if(p_ctx->tracks_num >= MKV_TRACKS_MAX) return VC_CONTAINER_ERROR_OUT_OF_RESOURCES;
1111 p_ctx->tracks[p_ctx->tracks_num] = track =
1112 vc_container_allocate_track(p_ctx, sizeof(*p_ctx->tracks[0]->priv->module));
1113 if(!track) return VC_CONTAINER_ERROR_OUT_OF_MEMORY;
1114
1115 module->parsing = track;
1116 track_module = track->priv->module;
1117 track->is_enabled = true;
1118 track->format->flags |= VC_CONTAINER_ES_FORMAT_FLAG_FRAMED;
1119 track_module->timecode_scale = 1.0;
1120 track_module->es_type.video.frame_rate = 0;
1121
1122 status = mkv_read_elements( p_ctx, id, size );
1123 if(status != VC_CONTAINER_SUCCESS) goto error;
1124
1125 /* Sanity check the data we got from the track entry */
1126 if(!track_module->number || !track_module->type)
1127 { status = VC_CONTAINER_ERROR_FORMAT_INVALID; goto error; }
1128
1129 /* Check the encodings for the track are supported */
1130 if(track_module->encodings_num > MKV_MAX_ENCODINGS)
1131 { status = VC_CONTAINER_ERROR_TRACK_FORMAT_NOT_SUPPORTED; goto error; }
1132 for(i = 0; i < track_module->encodings_num; i++)
1133 {
1134 if(track_module->encodings[i].type != MKV_CONTENT_ENCODING_COMPRESSION_HEADER ||
1135 !track_module->encodings[i].data_size)
1136 { status = VC_CONTAINER_ERROR_TRACK_FORMAT_NOT_SUPPORTED; goto error; }
1137 }
1138
1139 /* Find out the track type */
1140 if(track_module->type == 0x1)
1141 es_type = VC_CONTAINER_ES_TYPE_VIDEO;
1142 else if(track_module->type == 0x2)
1143 es_type = VC_CONTAINER_ES_TYPE_AUDIO;
1144 else if(track_module->type == 0x11)
1145 es_type = VC_CONTAINER_ES_TYPE_SUBPICTURE;
1146
1147 if(es_type == VC_CONTAINER_ES_TYPE_UNKNOWN)
1148 { status = VC_CONTAINER_ERROR_TRACK_FORMAT_NOT_SUPPORTED; goto error; }
1149
1150 if(!strcmp(track_module->codecid, "V_MS/VFW/FOURCC"))
1151 {
1152 if(vc_container_bitmapinfoheader_to_es_format(track->format->extradata,
1153 track->format->extradata_size, &extra_offset, &extra_size,
1154 track->format) == VC_CONTAINER_SUCCESS)
1155 {
1156 fourcc = track->format->codec;
1157 is_bmih = 1;
1158 }
1159 track->format->extradata += extra_offset;
1160 track->format->extradata_size = extra_size;
1161 }
1162 else if(!strcmp(track_module->codecid, "A_MS/ACM"))
1163 {
1164 if(vc_container_waveformatex_to_es_format(track->format->extradata,
1165 track->format->extradata_size, &extra_offset, &extra_size,
1166 track->format) == VC_CONTAINER_SUCCESS)
1167 {
1168 fourcc = track->format->codec;
1169 is_wf = 1;
1170 }
1171 track->format->extradata += extra_offset;
1172 track->format->extradata_size = extra_size;
1173 }
1174 else if((!strncmp(track_module->codecid, "A_AAC/MPEG2/", sizeof("A_AAC/MPEG2/")-1) ||
1175 !strncmp(track_module->codecid, "A_AAC/MPEG4/", sizeof("A_AAC/MPEG4/")-1)) &&
1176 !track->format->extradata_size)
1177 {
1178 static const unsigned int sample_rates[16] =
1179 {96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350};
1180 unsigned int samplerate, samplerate_idx, profile, sbr = 0;
1181 uint8_t *extra;
1182
1183 fourcc = mkv_codecid_to_fourcc(track_module->codecid, &variant);
1184
1185 /* Create extra data */
1186 if( !strcmp( &track_module->codecid[12], "MAIN" ) ) profile = 0;
1187 else if( !strcmp( &track_module->codecid[12], "LC" ) ) profile = 1;
1188 else if( !strcmp( &track_module->codecid[12], "SSR" ) ) profile = 2;
1189 else if( !strcmp( &track_module->codecid[12], "LC/SBR" ) ) { profile = 1; sbr = 1; }
1190 else profile = 3;
1191
1192 samplerate = track_module->es_type.audio.sampling_frequency;
1193 for( samplerate_idx = 0; samplerate_idx < 13; samplerate_idx++ )
1194 if( sample_rates[samplerate_idx] == samplerate ) break;
1195
1196 status = vc_container_track_allocate_extradata(p_ctx, track, sbr ? 5 : 2);
1197 if(status != VC_CONTAINER_SUCCESS) goto error;
1198 track->format->extradata_size = sbr ? 5 : 2;
1199 extra = track->format->extradata;
1200
1201 extra[0] = ((profile + 1) << 3) | ((samplerate_idx & 0xe) >> 1);
1202 extra[1] = ((samplerate_idx & 0x1) << 7) | (track_module->es_type.audio.channels << 3);
1203
1204 if(sbr)
1205 {
1206 unsigned int sync_extension_type = 0x2B7;
1207 samplerate = track_module->es_type.audio.output_sampling_frequency;
1208 for(samplerate_idx = 0; samplerate_idx < 13; samplerate_idx++)
1209 if(sample_rates[samplerate_idx] == samplerate) break;
1210 extra[2] = (sync_extension_type >> 3) & 0xFF;
1211 extra[3] = ((sync_extension_type & 0x7) << 5) | 5;
1212 extra[4] = (1 << 7) | (samplerate_idx << 3);
1213 }
1214 }
1215 else fourcc = mkv_codecid_to_fourcc(track_module->codecid, &variant);
1216
1217 if(!fourcc)
1218 {
1219 LOG_DEBUG(p_ctx, "codec id %s is not supported", track_module->codecid);
1220 }
1221
1222 LOG_DEBUG(p_ctx, "found track %4.4s", (char *)&fourcc);
1223 track->format->codec = fourcc;
1224 track->format->codec_variant = variant;
1225 track->format->es_type = es_type;
1226
1227 switch(es_type)
1228 {
1229 case VC_CONTAINER_ES_TYPE_VIDEO:
1230 if(!is_bmih)
1231 {
1232 track->format->type->video.width = track_module->es_type.video.pixel_width;
1233 track->format->type->video.height = track_module->es_type.video.pixel_height;
1234 }
1235 track->format->type->video.visible_width = track->format->type->video.width;
1236 track->format->type->video.visible_height = track->format->type->video.height;
1237 if(track_module->es_type.video.pixel_crop_left < track->format->type->video.visible_width &&
1238 track_module->es_type.video.pixel_crop_top < track->format->type->video.visible_height)
1239 {
1240 track->format->type->video.x_offset = track_module->es_type.video.pixel_crop_left;
1241 track->format->type->video.y_offset = track_module->es_type.video.pixel_crop_right;
1242 track->format->type->video.visible_width -= track->format->type->video.x_offset;
1243 track->format->type->video.visible_height -= track->format->type->video.y_offset;
1244 }
1245 if(track_module->es_type.video.pixel_crop_right < track->format->type->video.visible_width &&
1246 track_module->es_type.video.pixel_crop_bottom < track->format->type->video.visible_height)
1247 {
1248 track->format->type->video.visible_width -= track_module->es_type.video.pixel_crop_right;
1249 track->format->type->video.visible_height -= track_module->es_type.video.pixel_crop_bottom;
1250 }
1251 if(track_module->es_type.video.frame_rate)
1252 {
1253 track->format->type->video.frame_rate_den = 100;
1254 track->format->type->video.frame_rate_num = 100 * track_module->es_type.video.frame_rate;
1255 }
1256 if(track_module->es_type.video.display_width && track_module->es_type.video.display_height)
1257 {
1258 track->format->type->video.par_num = track_module->es_type.video.display_width *
1259 track->format->type->video.visible_height;
1260 track->format->type->video.par_den = track_module->es_type.video.display_height *
1261 track->format->type->video.visible_width;
1262 vc_container_maths_rational_simplify(&track->format->type->video.par_num,
1263 &track->format->type->video.par_den);
1264 }
1265 break;
1266 case VC_CONTAINER_ES_TYPE_AUDIO:
1267 if(is_wf) break;
1268 track->format->type->audio.sample_rate = track_module->es_type.audio.sampling_frequency;
1269 if(track_module->es_type.audio.output_sampling_frequency)
1270 track->format->type->audio.sample_rate = track_module->es_type.audio.output_sampling_frequency;
1271 track->format->type->audio.channels = track_module->es_type.audio.channels;
1272 track->format->type->audio.bits_per_sample = track_module->es_type.audio.bit_depth;
1273 break;
1274 default:
1275 case VC_CONTAINER_ES_TYPE_SUBPICTURE:
1276 track->format->type->subpicture.encoding = VC_CONTAINER_CHAR_ENCODING_UTF8;
1277 if(!strcmp(track_module->codecid, "S_TEXT/ASCII"))
1278 track->format->type->subpicture.encoding = VC_CONTAINER_CHAR_ENCODING_UNKNOWN;
1279 }
1280
1281 track->is_enabled = true;
1282
1283 p_ctx->tracks_num++;
1284 return VC_CONTAINER_SUCCESS;
1285
1286 error:
1287 for(i = 0; i < MKV_MAX_ENCODINGS; i++) free(track_module->encodings[i].data);
1288 vc_container_free_track(p_ctx, track);
1289 return status;
1290}
1291
1292static VC_CONTAINER_STATUS_T mkv_read_subelements_track_entry( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size )
1293{
1294 VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
1295 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
1296 VC_CONTAINER_TRACK_T *track = module->parsing;
1297 VC_CONTAINER_TRACK_MODULE_T *track_module = track->priv->module;
1298 uint64_t value;
1299
1300 /* Deal with string elements */
1301 if( id == MKV_ELEMENT_ID_NAME ||
1302 id == MKV_ELEMENT_ID_LANGUAGE ||
1303 id == MKV_ELEMENT_ID_TRACK_CODEC_ID ||
1304 id == MKV_ELEMENT_ID_TRACK_CODEC_NAME )
1305 {
1306 char stringbuf[MKV_MAX_STRING_SIZE+1];
1307
1308 if(size > MKV_MAX_STRING_SIZE)
1309 {
1310 LOG_DEBUG(p_ctx, "string truncated (%i>%i)", (int)size, MKV_MAX_STRING_SIZE);
1311 size = MKV_MAX_STRING_SIZE;
1312 }
1313 if(READ_BYTES(p_ctx, stringbuf, size) != (size_t)size)
1314 {
1315 //XXX do sane thing
1316 return STREAM_STATUS(p_ctx);
1317 }
1318 stringbuf[size] = 0; /* null terminate */
1319
1320 LOG_FORMAT(p_ctx, "%s", stringbuf);
1321
1322 if(id == MKV_ELEMENT_ID_TRACK_CODEC_ID)
1323 strncpy(track_module->codecid, stringbuf, MKV_CODECID_MAX-1);
1324
1325 return VC_CONTAINER_SUCCESS;
1326 }
1327
1328 /* Deal with codec private data */
1329 if( id == MKV_ELEMENT_ID_TRACK_CODEC_PRIVATE )
1330 {
1331 status = vc_container_track_allocate_extradata(p_ctx, track, (unsigned int)size);
1332 if(status != VC_CONTAINER_SUCCESS) return status;
1333 track->format->extradata_size = READ_BYTES(p_ctx, track->format->extradata, size);
1334 return STREAM_STATUS(p_ctx);
1335 }
1336
1337 /* The rest are just unsigned integers */
1338 status = mkv_read_element_data_uint(p_ctx, size, &value);
1339 if(status != VC_CONTAINER_SUCCESS) return status;
1340
1341 switch(id)
1342 {
1343 case MKV_ELEMENT_ID_TRACK_NUMBER:
1344 track_module->number = value; break;
1345 case MKV_ELEMENT_ID_TRACK_TYPE:
1346 track_module->type = value; break;
1347 case MKV_ELEMENT_ID_DEFAULT_DURATION:
1348 track_module->frame_duration = value; break;
1349 default: break;
1350 }
1351
1352 return status;
1353}
1354
1355static VC_CONTAINER_STATUS_T mkv_read_subelements_video( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size )
1356{
1357 VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
1358 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
1359 VC_CONTAINER_TRACK_MODULE_T *track_module = module->parsing->priv->module;
1360 uint64_t value;
1361
1362 /* Deal with floating point values first */
1363 if(id == MKV_ELEMENT_ID_FRAME_RATE)
1364 {
1365 double fvalue;
1366 status = mkv_read_element_data_float(p_ctx, size, &fvalue);
1367 if(status != VC_CONTAINER_SUCCESS) return status;
1368 track_module->es_type.video.frame_rate = fvalue;
1369 return status;
1370 }
1371
1372 /* The rest are just unsigned integers */
1373 status = mkv_read_element_data_uint(p_ctx, size, &value);
1374 if(status != VC_CONTAINER_SUCCESS) return status;
1375
1376 switch(id)
1377 {
1378 case MKV_ELEMENT_ID_PIXEL_WIDTH: track_module->es_type.video.pixel_width = value; break;
1379 case MKV_ELEMENT_ID_PIXEL_HEIGHT: track_module->es_type.video.pixel_height = value; break;
1380 case MKV_ELEMENT_ID_PIXEL_CROP_BOTTOM: track_module->es_type.video.pixel_crop_bottom = value; break;
1381 case MKV_ELEMENT_ID_PIXEL_CROP_TOP: track_module->es_type.video.pixel_crop_top = value; break;
1382 case MKV_ELEMENT_ID_PIXEL_CROP_LEFT: track_module->es_type.video.pixel_crop_left = value; break;
1383 case MKV_ELEMENT_ID_PIXEL_CROP_RIGHT: track_module->es_type.video.pixel_crop_right = value; break;
1384 case MKV_ELEMENT_ID_DISPLAY_WIDTH: track_module->es_type.video.display_width = value; break;
1385 case MKV_ELEMENT_ID_DISPLAY_HEIGHT: track_module->es_type.video.display_height = value; break;
1386 case MKV_ELEMENT_ID_DISPLAY_UNIT: track_module->es_type.video.display_unit = value; break;
1387 case MKV_ELEMENT_ID_ASPECT_RATIO_TYPE: track_module->es_type.video.aspect_ratio_type = value; break;
1388 default: break;
1389 }
1390
1391 return status;
1392}
1393
1394static VC_CONTAINER_STATUS_T mkv_read_subelements_audio( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size )
1395{
1396 VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
1397 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
1398 VC_CONTAINER_TRACK_MODULE_T *track_module = module->parsing->priv->module;
1399 uint64_t value;
1400
1401 /* Deal with floating point values first */
1402 if(id == MKV_ELEMENT_ID_SAMPLING_FREQUENCY ||
1403 id == MKV_ELEMENT_ID_OUTPUT_SAMPLING_FREQUENCY)
1404 {
1405 double fvalue;
1406 status = mkv_read_element_data_float(p_ctx, size, &fvalue);
1407 if(status != VC_CONTAINER_SUCCESS) return status;
1408
1409 if(id == MKV_ELEMENT_ID_SAMPLING_FREQUENCY)
1410 track_module->es_type.audio.sampling_frequency = fvalue;
1411
1412 if(id == MKV_ELEMENT_ID_OUTPUT_SAMPLING_FREQUENCY)
1413 track_module->es_type.audio.output_sampling_frequency = fvalue;
1414
1415 return status;
1416 }
1417
1418 /* The rest are just unsigned integers */
1419 status = mkv_read_element_data_uint(p_ctx, size, &value);
1420 if(status != VC_CONTAINER_SUCCESS) return status;
1421
1422 switch(id)
1423 {
1424 case MKV_ELEMENT_ID_CHANNELS: track_module->es_type.audio.channels = value; break;
1425 case MKV_ELEMENT_ID_BIT_DEPTH: track_module->es_type.audio.bit_depth = value; break;
1426 default: break;
1427 }
1428
1429 return status;
1430}
1431
1432static VC_CONTAINER_STATUS_T mkv_read_element_encoding( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size )
1433{
1434 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
1435 VC_CONTAINER_TRACK_MODULE_T *track_module = module->parsing->priv->module;
1436 VC_CONTAINER_STATUS_T status;
1437 status = mkv_read_elements(p_ctx, id, size);
1438 track_module->encodings_num++;
1439 return status;
1440}
1441
1442static VC_CONTAINER_STATUS_T mkv_read_subelements_encoding( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size )
1443{
1444 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
1445 VC_CONTAINER_TRACK_MODULE_T *track_module = module->parsing->priv->module;
1446 VC_CONTAINER_STATUS_T status;
1447 uint64_t value;
1448
1449 /* These are just unsigned integers */
1450 status = mkv_read_element_data_uint(p_ctx, size, &value);
1451 if(status != VC_CONTAINER_SUCCESS) return status;
1452
1453 if(track_module->encodings_num >= MKV_MAX_ENCODINGS) return VC_CONTAINER_ERROR_OUT_OF_RESOURCES;
1454
1455 switch(id)
1456 {
1457 case MKV_ELEMENT_ID_CONTENT_ENCODING_TYPE:
1458 if(value == 0) track_module->encodings[track_module->encodings_num].type = MKV_CONTENT_ENCODING_COMPRESSION_ZLIB;
1459 if(value == 1) track_module->encodings[track_module->encodings_num].type = MKV_CONTENT_ENCODING_ENCRYPTION;
1460 else track_module->encodings[track_module->encodings_num].type = MKV_CONTENT_ENCODING_UNKNOWN;
1461 break;
1462 default: break;
1463 }
1464
1465 return status;
1466}
1467
1468static VC_CONTAINER_STATUS_T mkv_read_subelements_compression( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size )
1469{
1470 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
1471 VC_CONTAINER_TRACK_MODULE_T *track_module = module->parsing->priv->module;
1472 VC_CONTAINER_STATUS_T status;
1473 uint64_t value;
1474 uint8_t *data;
1475
1476 if(id == MKV_ELEMENT_ID_CONTENT_COMPRESSION_ALGO)
1477 {
1478 status = mkv_read_element_data_uint(p_ctx, size, &value);
1479 if(status != VC_CONTAINER_SUCCESS) return status;
1480
1481 if(value == 0) track_module->encodings[track_module->encodings_num].type = MKV_CONTENT_ENCODING_COMPRESSION_ZLIB;
1482 if(value == 3) track_module->encodings[track_module->encodings_num].type = MKV_CONTENT_ENCODING_COMPRESSION_HEADER;
1483 else track_module->encodings[track_module->encodings_num].type = MKV_CONTENT_ENCODING_UNKNOWN;
1484 return status;
1485 }
1486
1487 if(id == MKV_ELEMENT_ID_CONTENT_COMPRESSION_SETTINGS)
1488 {
1489 if(track_module->encodings[track_module->encodings_num].type == MKV_CONTENT_ENCODING_COMPRESSION_HEADER)
1490 {
1491 if(size > MKV_MAX_ENCODING_DATA) return VC_CONTAINER_ERROR_OUT_OF_RESOURCES;
1492
1493 data = malloc((int)size);
1494 if(!data) return VC_CONTAINER_ERROR_OUT_OF_MEMORY;
1495
1496 track_module->encodings[track_module->encodings_num].data = data;
1497 track_module->encodings[track_module->encodings_num].data_size = READ_BYTES(p_ctx, data, size);
1498 if(track_module->encodings[track_module->encodings_num].data_size != size)
1499 track_module->encodings[track_module->encodings_num].data_size = 0;
1500 return STREAM_STATUS(p_ctx);
1501 }
1502 else
1503 {
1504 SKIP_BYTES(p_ctx, size);
1505 }
1506 return STREAM_STATUS(p_ctx);
1507 }
1508
1509 return VC_CONTAINER_SUCCESS;
1510}
1511
1512static VC_CONTAINER_STATUS_T mkv_read_subelements_info( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size )
1513{
1514 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
1515 VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
1516 uint64_t value;
1517 double fvalue;
1518
1519 switch(id)
1520 {
1521 case MKV_ELEMENT_ID_TIMECODE_SCALE:
1522 status = mkv_read_element_data_uint(p_ctx, size, &value);
1523 if(status != VC_CONTAINER_SUCCESS) break;
1524 module->timecode_scale = value;
1525 break;
1526 case MKV_ELEMENT_ID_DURATION:
1527 status = mkv_read_element_data_float(p_ctx, size, &fvalue);
1528 if(status != VC_CONTAINER_SUCCESS) break;
1529 module->duration = fvalue;
1530 break;
1531 case MKV_ELEMENT_ID_TITLE:
1532 case MKV_ELEMENT_ID_MUXING_APP:
1533 case MKV_ELEMENT_ID_WRITING_APP:
1534 SKIP_STRING(p_ctx, size, "string");
1535 break;
1536
1537 default: break;
1538 }
1539
1540 return status;
1541}
1542
1543static VC_CONTAINER_STATUS_T mkv_read_subelements_seek_head( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size )
1544{
1545 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
1546 VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
1547 uint64_t value;
1548
1549 if(id == MKV_ELEMENT_ID_SEEK)
1550 {
1551 module->seekhead_elem_id = MKV_ELEMENT_ID_UNKNOWN;
1552 module->seekhead_elem_offset = -1;
1553 status = mkv_read_elements(p_ctx, id, size);
1554 if(status == VC_CONTAINER_SUCCESS && !module->cues_offset &&
1555 module->seekhead_elem_id == MKV_ELEMENT_ID_CUES && module->seekhead_elem_offset)
1556 module->cues_offset = module->seekhead_elem_offset;
1557 if(status == VC_CONTAINER_SUCCESS && !module->tags_offset &&
1558 module->seekhead_elem_id == MKV_ELEMENT_ID_TAGS && module->seekhead_elem_offset)
1559 module->tags_offset = module->seekhead_elem_offset;
1560 return status;
1561 }
1562
1563 if(id == MKV_ELEMENT_ID_SEEK_ID)
1564 {
1565 MKV_ELEMENT_T *element = mkv_elements_list;
1566 id = MKV_READ_ID(p_ctx, "Element ID");
1567 module->seekhead_elem_id = id;
1568
1569 /* Find out which Element we are dealing with */
1570 while(element->id && id != element->id) element++;
1571 LOG_FORMAT(p_ctx, "element: %s (ID 0x%x)", element->psz_name, id);
1572 }
1573 else if(id == MKV_ELEMENT_ID_SEEK_POSITION)
1574 {
1575 status = mkv_read_element_data_uint(p_ctx, size, &value);
1576 if(status != VC_CONTAINER_SUCCESS) return status;
1577 LOG_FORMAT(p_ctx, "offset: %"PRIi64, value + module->segment_offset);
1578 module->seekhead_elem_offset = value + module->segment_offset;
1579 }
1580
1581 return status;
1582}
1583
1584static VC_CONTAINER_STATUS_T mkv_read_element_cues( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size )
1585{
1586 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
1587 VC_CONTAINER_PARAM_UNUSED(id);
1588 VC_CONTAINER_PARAM_UNUSED(size);
1589 module->cues_offset = module->element_offset;
1590 return VC_CONTAINER_SUCCESS;
1591}
1592
1593static VC_CONTAINER_STATUS_T mkv_read_subelements_cue_point( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size )
1594{
1595 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
1596 VC_CONTAINER_STATUS_T status;
1597 uint64_t value;
1598
1599 /* All the values are unsigned integers */
1600 status = mkv_read_element_data_uint(p_ctx, size, &value);
1601 if(status != VC_CONTAINER_SUCCESS) return status;
1602
1603 switch(id)
1604 {
1605 case MKV_ELEMENT_ID_CUE_TIME:
1606 module->cue_timecode = value; break;
1607 case MKV_ELEMENT_ID_CUE_TRACK:
1608 module->cue_track = value; break;
1609 case MKV_ELEMENT_ID_CUE_CLUSTER_POSITION:
1610 module->cue_cluster_offset = value; break;
1611 case MKV_ELEMENT_ID_CUE_BLOCK_NUMBER:
1612 module->cue_block = value; break;
1613 default: break;
1614 }
1615
1616 return status;
1617}
1618
1619static VC_CONTAINER_STATUS_T mkv_read_subelements_cluster( VC_CONTAINER_T *p_ctx, MKV_ELEMENT_ID_T id, int64_t size )
1620{
1621 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
1622 VC_CONTAINER_STATUS_T status;
1623 uint64_t value;
1624
1625 /* The rest are just unsigned integers */
1626 status = mkv_read_element_data_uint(p_ctx, size, &value);
1627 if(status != VC_CONTAINER_SUCCESS) return status;
1628
1629 switch(id)
1630 {
1631 //XXX
1632 case MKV_ELEMENT_ID_TIMECODE: module->state.cluster_timecode = value; break;
1633 case MKV_ELEMENT_ID_BLOCK_DURATION: module->state.frame_duration = value; break;
1634 default: break;
1635 }
1636
1637 return status;
1638}
1639
1640/*******************************/
1641
1642static VC_CONTAINER_STATUS_T mkv_skip_element(VC_CONTAINER_T *p_ctx,
1643 MKV_READER_STATE_T *state)
1644{
1645 /* Skip any trailing data from the current element */
1646 int64_t skip = state->levels[state->level].offset +
1647 state->levels[state->level].size - STREAM_POSITION(p_ctx);
1648
1649 if(skip < 0) /* Check for overruns */
1650 {
1651 /* Things have gone really bad here and we ended up reading past the end of the
1652 * element. We could maybe try to be clever and recover by seeking back to the end
1653 * of the element. However if we get there, the file is clearly corrupted so there's
1654 * no guarantee it would work anyway. */
1655 LOG_DEBUG(p_ctx, "%"PRIi64" bytes overrun past the end of the element", -skip);
1656 return VC_CONTAINER_ERROR_CORRUPTED;
1657 }
1658
1659 if(skip)
1660 LOG_FORMAT(p_ctx, "%"PRIi64" bytes left unread at the end of element", skip);
1661
1662 state->level--;
1663
1664 if (skip >= MKV_MAX_ELEMENT_SIZE)
1665 return SEEK(p_ctx, STREAM_POSITION(p_ctx) + skip);
1666 SKIP_BYTES(p_ctx, skip);
1667 return STREAM_STATUS(p_ctx);
1668}
1669
1670static VC_CONTAINER_STATUS_T mkv_find_next_element(VC_CONTAINER_T *p_ctx,
1671 MKV_READER_STATE_T *state, MKV_ELEMENT_ID_T element_id)
1672{
1673 VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
1674 int64_t element_size, element_offset;
1675 MKV_ELEMENT_ID_T id;
1676
1677 /* Skip all elements until we find the next requested element */
1678 do
1679 {
1680 MKV_ELEMENT_T *element = mkv_cluster_elements_list;
1681
1682 /* Check whether we've reach the end of the parent element */
1683 if(STREAM_POSITION(p_ctx) >= state->levels[state->level].offset +
1684 state->levels[state->level].size)
1685 return VC_CONTAINER_ERROR_NOT_FOUND;
1686
1687 status = mkv_read_element_header(p_ctx, INT64_C(1) << 30, &id,
1688 &element_size, state->levels[state->level].id, &element);
1689 element_offset = STREAM_POSITION(p_ctx);
1690 if(status != VC_CONTAINER_SUCCESS) return status;
1691 if(id == element_id) break;
1692 if(element_id == MKV_ELEMENT_ID_BLOCKGROUP && id == MKV_ELEMENT_ID_SIMPLE_BLOCK) break;
1693
1694 if(element_id == MKV_ELEMENT_ID_BLOCK && id == MKV_ELEMENT_ID_REFERENCE_BLOCK)
1695 state->seen_ref_block = 1;
1696
1697 /* Check whether we've reached the end of the parent element */
1698 if(STREAM_POSITION(p_ctx) + element_size >= state->levels[state->level].offset +
1699 state->levels[state->level].size)
1700 return VC_CONTAINER_ERROR_NOT_FOUND;
1701
1702 status = mkv_read_element_data(p_ctx, element, element_size, INT64_C(1) << 30);
1703#if 0
1704 if(element_size < MKV_MAX_ELEMENT_SIZE) SKIP_BYTES(p_ctx, element_size);
1705 else SEEK(p_ctx, STREAM_POSITION(p_ctx) + element_size);
1706#endif
1707 } while (status == VC_CONTAINER_SUCCESS && STREAM_STATUS(p_ctx) == VC_CONTAINER_SUCCESS);
1708
1709 if(STREAM_STATUS(p_ctx) != VC_CONTAINER_SUCCESS)
1710 return STREAM_STATUS(p_ctx);
1711
1712 state->level++;
1713 state->levels[state->level].offset = element_offset;
1714 state->levels[state->level].size = element_size;
1715 state->levels[state->level].id = id;
1716 return VC_CONTAINER_SUCCESS;
1717}
1718
1719static VC_CONTAINER_STATUS_T mkv_find_next_segment(VC_CONTAINER_T *p_ctx,
1720 MKV_READER_STATE_T *state)
1721{
1722 VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
1723 int64_t element_size, element_offset;
1724 MKV_ELEMENT_ID_T id;
1725
1726 /* Skip all elements until we find the next segment */
1727 do
1728 {
1729 MKV_ELEMENT_T *element = mkv_cluster_elements_list;
1730
1731 status = mkv_read_element_header(p_ctx, INT64_C(-1), &id,
1732 &element_size, MKV_ELEMENT_ID_INVALID, &element);
1733
1734 element_offset = STREAM_POSITION(p_ctx);
1735 if(status != VC_CONTAINER_SUCCESS) return status;
1736 if(id == MKV_ELEMENT_ID_SEGMENT) break;
1737
1738 status = mkv_read_element_data(p_ctx, element, element_size, INT64_C(-1));
1739 } while (status == VC_CONTAINER_SUCCESS && STREAM_STATUS(p_ctx) == VC_CONTAINER_SUCCESS);
1740
1741 if(STREAM_STATUS(p_ctx) != VC_CONTAINER_SUCCESS)
1742 return STREAM_STATUS(p_ctx);
1743
1744 state->level++;
1745 state->levels[state->level].offset = element_offset;
1746 state->levels[state->level].size = element_size;
1747 state->levels[state->level].id = id;
1748 return VC_CONTAINER_SUCCESS;
1749}
1750
1751static VC_CONTAINER_STATUS_T mkv_find_next_block(VC_CONTAINER_T *p_ctx, MKV_READER_STATE_T *state)
1752{
1753 VC_CONTAINER_STATUS_T status = VC_CONTAINER_ERROR_NOT_FOUND;
1754
1755 do
1756 {
1757 if(state->level < 0)
1758 {
1759#ifdef ENABLE_MKV_EXTRA_LOGGING
1760 LOG_DEBUG(p_ctx, "find segment");
1761#endif
1762 status = mkv_find_next_segment(p_ctx, state);
1763 if(status == VC_CONTAINER_SUCCESS)
1764 {
1765 LOG_ERROR(p_ctx, "multi-segment files not supported");
1766 status = VC_CONTAINER_ERROR_EOS;
1767 break;
1768 }
1769 }
1770 if(state->levels[state->level].id == MKV_ELEMENT_ID_BLOCK ||
1771 state->levels[state->level].id == MKV_ELEMENT_ID_SIMPLE_BLOCK)
1772 {
1773 status = mkv_skip_element(p_ctx, state);
1774 }
1775 if(state->levels[state->level].id == MKV_ELEMENT_ID_BLOCKGROUP)
1776 {
1777#ifdef ENABLE_MKV_EXTRA_LOGGING
1778 LOG_DEBUG(p_ctx, "find block");
1779#endif
1780 state->seen_ref_block = 0;
1781 state->frame_duration = 0;
1782 status = mkv_find_next_element(p_ctx, state, MKV_ELEMENT_ID_BLOCK);
1783 if(status == VC_CONTAINER_SUCCESS) break;
1784
1785 if(status == VC_CONTAINER_ERROR_NOT_FOUND)
1786 status = mkv_skip_element(p_ctx, state);
1787 }
1788 if(state->levels[state->level].id == MKV_ELEMENT_ID_CLUSTER)
1789 {
1790#ifdef ENABLE_MKV_EXTRA_LOGGING
1791 LOG_DEBUG(p_ctx, "find blockgroup or simpleblock");
1792#endif
1793 state->frame_duration = 0;
1794 status = mkv_find_next_element(p_ctx, state, MKV_ELEMENT_ID_BLOCKGROUP);
1795 if(status == VC_CONTAINER_SUCCESS &&
1796 state->levels[state->level].id == MKV_ELEMENT_ID_SIMPLE_BLOCK) break;
1797 if(status == VC_CONTAINER_ERROR_NOT_FOUND)
1798 status = mkv_skip_element(p_ctx, state);
1799 }
1800 if(state->levels[state->level].id == MKV_ELEMENT_ID_SEGMENT)
1801 {
1802#ifdef ENABLE_MKV_EXTRA_LOGGING
1803 LOG_DEBUG(p_ctx, "find cluster");
1804#endif
1805 status = mkv_find_next_element(p_ctx, state, MKV_ELEMENT_ID_CLUSTER);
1806 if(status == VC_CONTAINER_ERROR_NOT_FOUND)
1807 status = mkv_skip_element(p_ctx, state);
1808 }
1809
1810 } while(status == VC_CONTAINER_SUCCESS && STREAM_STATUS(p_ctx) == VC_CONTAINER_SUCCESS);
1811
1812 return status == VC_CONTAINER_SUCCESS ? STREAM_STATUS(p_ctx) : status;
1813}
1814
1815static VC_CONTAINER_STATUS_T mkv_read_next_frame_header(VC_CONTAINER_T *p_ctx,
1816 MKV_READER_STATE_T *state, uint32_t *pi_track, uint32_t *pi_length)
1817{
1818 VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
1819 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
1820 VC_CONTAINER_TRACK_MODULE_T *track_module = 0;
1821 unsigned int i, track, flags, is_first_lace = 0;
1822 int64_t size, pts;
1823
1824 if ((state->levels[state->level].id == MKV_ELEMENT_ID_BLOCK ||
1825 state->levels[state->level].id == MKV_ELEMENT_ID_SIMPLE_BLOCK) &&
1826 state->levels[state->level].data_start + state->levels[state->level].data_offset <
1827 state->levels[state->level].size)
1828 goto end;
1829
1830 status = mkv_find_next_block(p_ctx, state);
1831 if (status != VC_CONTAINER_SUCCESS) return status;
1832
1833 /* We have a block */
1834 size = state->levels[state->level].size;
1835 track = MKV_READ_UINT(p_ctx, "Track Number"); LOG_FORMAT(p_ctx, "Track Number: %u", track);
1836 pts = (int16_t)MKV_READ_U16(p_ctx, "Timecode");
1837 flags = MKV_READ_U8(p_ctx, "Flags");
1838 if(state->levels[state->level].id == MKV_ELEMENT_ID_BLOCK) flags &= 0x0F;
1839
1840 //TODO improve sanity checking
1841 /* Sanity checking */
1842 if(size < 0) return VC_CONTAINER_ERROR_CORRUPTED;
1843 if(STREAM_STATUS(p_ctx)) return STREAM_STATUS(p_ctx);
1844
1845 for (i = 0; i < p_ctx->tracks_num; i++)
1846 if (p_ctx->tracks[i]->priv->module->number == track)
1847 { track_module = p_ctx->tracks[i]->priv->module; break; }
1848
1849 /* Finding out if we have a keyframe when dealing with an MKV_ELEMENT_ID_BLOCK is tricky */
1850 if(state->levels[state->level].id == MKV_ELEMENT_ID_BLOCK &&
1851 i < p_ctx->tracks_num && p_ctx->tracks[i]->format->es_type == VC_CONTAINER_ES_TYPE_VIDEO)
1852 {
1853 /* The absence of a ReferenceBlock element tells us if we are a keyframe or not.
1854 * The problem we have is that this element can appear before as well as after the block element.
1855 * To avoid seeking to look for this element, we do some guess work. */
1856 if(!state->seen_ref_block && state->level &&
1857 state->levels[state->level].offset + state->levels[state->level].size >=
1858 state->levels[state->level-1].offset + state->levels[state->level-1].size)
1859 flags |= 0x80;
1860 }
1861
1862 /* Take care of the lacing */
1863 state->lacing_num_frames = 0;
1864 if(i < p_ctx->tracks_num && (flags & 0x06))
1865 {
1866 unsigned int i, value = 0;
1867 int32_t fs = 0;
1868
1869 state->lacing_num_frames = MKV_READ_U8(p_ctx, "Lacing Head");
1870 state->lacing_size = 0;
1871 switch((flags & 0x06)>>1)
1872 {
1873 case 1: /* Xiph lacing */
1874 for(i = 0; i < state->lacing_num_frames; i++, fs = 0)
1875 {
1876 do {
1877 value = vc_container_io_read_uint8(p_ctx->priv->io);
1878 fs += value; size--;
1879 } while(value == 255);
1880 LOG_FORMAT(p_ctx, "Frame Size: %i", (int)fs);
1881 if(state->lacing_num_frames > MKV_MAX_LACING_NUM) continue;
1882 state->lacing_sizes[state->lacing_num_frames-(i+1)] = fs;
1883 }
1884 break;
1885 case 3: /* EBML lacing */
1886 for(i = 0; i < state->lacing_num_frames; i++)
1887 {
1888 if(!i) fs = MKV_READ_UINT(p_ctx, "Frame Size");
1889 else fs += MKV_READ_SINT(p_ctx, "Frame Size");
1890 LOG_FORMAT(p_ctx, "Frame Size: %i", (int)fs);
1891 if(state->lacing_num_frames > MKV_MAX_LACING_NUM) continue;
1892 state->lacing_sizes[state->lacing_num_frames-(i+1)] = fs;
1893 }
1894 break;
1895 default: /* Fixed-size lacing */
1896 state->lacing_size = size / (state->lacing_num_frames+1);
1897 break;
1898 }
1899
1900 /* There is a max number of laced frames we can support but after we can still give back
1901 * all the other frames in 1 packet */
1902 if(state->lacing_num_frames > MKV_MAX_LACING_NUM)
1903 state->lacing_num_frames = MKV_MAX_LACING_NUM;
1904
1905 /* Sanity check the size of the frames */
1906 if(size < 0) return VC_CONTAINER_ERROR_CORRUPTED;
1907 if(STREAM_STATUS(p_ctx)) return STREAM_STATUS(p_ctx);
1908 state->lacing_current_size = state->lacing_size;
1909 if(!state->lacing_size)
1910 {
1911 int64_t frames_size = 0;
1912 for(i = state->lacing_num_frames; i > 0; i--)
1913 {
1914 if(frames_size + state->lacing_sizes[i-1] > size) /* return error ? */
1915 state->lacing_sizes[i-1] = size - frames_size;
1916 frames_size += state->lacing_sizes[i-1];
1917 }
1918 }
1919 state->lacing_current_size = 0;
1920 state->lacing_num_frames++; /* Will be decremented further down */
1921 is_first_lace = 1;
1922 }
1923
1924 state->track = i;
1925 state->pts = (state->cluster_timecode + pts) * module->timecode_scale;
1926 if(track_module) state->pts *= track_module->timecode_scale;
1927 state->pts /= 1000;
1928 state->flags = flags;
1929
1930 state->frame_duration = state->frame_duration * module->timecode_scale / 1000;
1931 if(state->lacing_num_frames) state->frame_duration /= state->lacing_num_frames;
1932 if(!state->frame_duration && track_module)
1933 state->frame_duration = track_module->frame_duration / 1000;
1934
1935 state->levels[state->level].data_start = STREAM_POSITION(p_ctx) -
1936 state->levels[state->level].offset;
1937 state->levels[state->level].data_offset = 0;
1938
1939 /* Deal with header stripping compression */
1940 state->header_size = 0;
1941 if(track_module && track_module->encodings_num)
1942 {
1943 state->header_size = track_module->encodings[0].data_size;
1944 state->header_data = track_module->encodings[0].data;
1945 }
1946 state->header_size_backup = state->header_size;
1947
1948 end:
1949 *pi_length = state->levels[state->level].size - state->levels[state->level].data_start -
1950 state->levels[state->level].data_offset + state->header_size;
1951 *pi_track = state->track;
1952
1953 /* Special case for lacing */
1954 if(state->lacing_num_frames &&
1955 state->levels[state->level].data_offset >= state->lacing_current_size)
1956 {
1957 /* We need to switch to the next lace */
1958 if(--state->lacing_num_frames)
1959 {
1960 unsigned int lace_size = state->lacing_size;
1961 if(!state->lacing_size) lace_size = state->lacing_sizes[state->lacing_num_frames-1];
1962 state->lacing_current_size = lace_size;
1963 }
1964 state->levels[state->level].data_start += state->levels[state->level].data_offset;
1965 state->levels[state->level].data_offset = 0;
1966 if(!is_first_lace && state->frame_duration)
1967 state->pts += state->frame_duration;
1968 else if(!is_first_lace)
1969 state->pts = VC_CONTAINER_TIME_UNKNOWN;
1970
1971 /* Deal with header stripping compression */
1972 state->header_data -= (state->header_size_backup - state->header_size);
1973 state->header_size = state->header_size_backup;
1974 }
1975 if(state->lacing_num_frames)
1976 *pi_length = state->lacing_current_size - state->levels[state->level].data_offset + state->header_size;
1977
1978 return status == VC_CONTAINER_SUCCESS ? STREAM_STATUS(p_ctx) : status;
1979}
1980
1981static VC_CONTAINER_STATUS_T mkv_read_frame_data(VC_CONTAINER_T *p_ctx,
1982 MKV_READER_STATE_T *state, uint8_t *p_data, uint32_t *pi_length)
1983{
1984 uint64_t size;
1985 uint32_t header_size;
1986
1987 size = state->levels[state->level].size - state->levels[state->level].data_start -
1988 state->levels[state->level].data_offset;
1989
1990 /* Special case for lacing */
1991 if(state->lacing_num_frames)
1992 {
1993 size = state->lacing_current_size - state->levels[state->level].data_offset;
1994
1995 if(!p_data)
1996 {
1997 size = SKIP_BYTES(p_ctx, size);
1998 state->levels[state->level].data_offset += size;
1999 return STREAM_STATUS(p_ctx);
2000 }
2001 }
2002
2003 size += state->header_size;
2004
2005 if(!p_data) return mkv_skip_element(p_ctx, state);
2006 if(size > *pi_length) size = *pi_length;
2007
2008 header_size = state->header_size;
2009 if(header_size)
2010 {
2011 if(header_size > size) header_size = size;
2012 memcpy(p_data, state->header_data, header_size);
2013 state->header_size -= header_size;
2014 state->header_data += header_size;
2015 size -= header_size;
2016 }
2017
2018 size = READ_BYTES(p_ctx, p_data + header_size, size);
2019 state->levels[state->level].data_offset += size;
2020 *pi_length = size + header_size;
2021
2022 return STREAM_STATUS(p_ctx);
2023}
2024
2025/*****************************************************************************
2026 Functions exported as part of the Container Module API
2027 *****************************************************************************/
2028
2029static VC_CONTAINER_STATUS_T mkv_reader_read(VC_CONTAINER_T *p_ctx,
2030 VC_CONTAINER_PACKET_T *p_packet, uint32_t flags)
2031{
2032 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
2033 VC_CONTAINER_TRACK_T *p_track = 0;
2034 VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
2035 uint32_t buffer_size = 0, track = 0, data_size;
2036 MKV_READER_STATE_T *state = &module->state;
2037
2038 /* If a specific track has been selected, we need to use the track packet state */
2039 if(flags & VC_CONTAINER_READ_FLAG_FORCE_TRACK)
2040 {
2041 p_track = p_ctx->tracks[p_packet->track];
2042 state = p_track->priv->module->state;
2043 }
2044
2045 /**/
2046 if(state->eos) return VC_CONTAINER_ERROR_EOS;
2047 if(state->corrupted) return VC_CONTAINER_ERROR_CORRUPTED;
2048
2049 /* Look at the next frame header */
2050 status = mkv_read_next_frame_header(p_ctx, state, &track, &data_size);
2051 if(status == VC_CONTAINER_ERROR_EOS) state->eos = true;
2052 if(status == VC_CONTAINER_ERROR_CORRUPTED) state->corrupted = true;
2053 if(status != VC_CONTAINER_SUCCESS) return status;
2054
2055 if(track >= p_ctx->tracks_num || !p_ctx->tracks[track]->is_enabled)
2056 {
2057 /* Skip frame */
2058 status = mkv_read_frame_data(p_ctx, state, 0, &data_size);
2059 if (status != VC_CONTAINER_SUCCESS) return status;
2060 return VC_CONTAINER_ERROR_CONTINUE;
2061 }
2062
2063 if((flags & VC_CONTAINER_READ_FLAG_SKIP) && !(flags & VC_CONTAINER_READ_FLAG_INFO)) /* Skip packet */
2064 return mkv_read_frame_data(p_ctx, state, 0, &data_size);
2065
2066 p_packet->dts = p_packet->pts = state->pts;
2067 p_packet->flags = 0;
2068 if(state->flags & 0x80) p_packet->flags |= VC_CONTAINER_PACKET_FLAG_KEYFRAME;
2069 if(!state->levels[state->level].data_offset) p_packet->flags |= VC_CONTAINER_PACKET_FLAG_FRAME_START;
2070 p_packet->flags |= VC_CONTAINER_PACKET_FLAG_FRAME_END;
2071 p_packet->size = data_size;
2072 p_packet->track = track;
2073
2074 if(flags & VC_CONTAINER_READ_FLAG_SKIP)
2075 return mkv_read_frame_data(p_ctx, state, 0, &data_size );
2076 else if(flags & VC_CONTAINER_READ_FLAG_INFO)
2077 return VC_CONTAINER_SUCCESS;
2078
2079 /* Read the frame data */
2080 buffer_size = p_packet->buffer_size;
2081 status = mkv_read_frame_data(p_ctx, state, p_packet->data, &buffer_size);
2082 if(status != VC_CONTAINER_SUCCESS)
2083 {
2084 /* FIXME */
2085 return status;
2086 }
2087
2088 p_packet->size = buffer_size;
2089 if(buffer_size != data_size)
2090 p_packet->flags &= ~VC_CONTAINER_PACKET_FLAG_FRAME_END;
2091
2092 return status;
2093}
2094
2095/*****************************************************************************/
2096static VC_CONTAINER_STATUS_T mkv_reader_seek(VC_CONTAINER_T *p_ctx,
2097 int64_t *p_offset, VC_CONTAINER_SEEK_MODE_T mode, VC_CONTAINER_SEEK_FLAGS_T flags)
2098{
2099 VC_CONTAINER_STATUS_T status = VC_CONTAINER_SUCCESS;
2100 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
2101 MKV_READER_STATE_T *state = &module->state;
2102 uint64_t offset = 0, prev_offset = 0, position = STREAM_POSITION(p_ctx);
2103 int64_t time_offset = 0, prev_time_offset = 0;
2104 unsigned int i, video_track;
2105 MKV_ELEMENT_T *element = mkv_cue_elements_list;
2106 int64_t size, element_size;
2107 MKV_ELEMENT_ID_T id;
2108 VC_CONTAINER_PARAM_UNUSED(mode);
2109 VC_CONTAINER_PARAM_UNUSED(flags);
2110
2111 /* Find out if we have a video track */
2112 for(video_track = 0; video_track < p_ctx->tracks_num; video_track++)
2113 if(p_ctx->tracks[video_track]->is_enabled &&
2114 p_ctx->tracks[video_track]->format->es_type == VC_CONTAINER_ES_TYPE_VIDEO) break;
2115
2116 if(!*p_offset) goto end; /* Nothing much to do */
2117 if(!module->cues_offset) {status = VC_CONTAINER_ERROR_UNSUPPORTED_OPERATION; goto error;}
2118
2119 /* We need to do a search in the cue list */
2120 status = SEEK(p_ctx, module->cues_offset);
2121 if(status != VC_CONTAINER_SUCCESS) goto error;
2122
2123 /* First read the header of the cues element */
2124 status = mkv_read_element_header(p_ctx, INT64_C(-1) /* TODO */, &id, &element_size,
2125 MKV_ELEMENT_ID_SEGMENT, &element);
2126 if(status != VC_CONTAINER_SUCCESS || id != MKV_ELEMENT_ID_CUES) goto error;
2127 size = element_size;
2128
2129 module->elements_list = mkv_cue_elements_list;
2130 do
2131 {
2132 MKV_ELEMENT_T *element = mkv_cue_elements_list;
2133 int64_t element_offset = STREAM_POSITION(p_ctx);
2134
2135 /* Exit condition for when we've scanned the whole cues list */
2136 if(size <= 0)
2137 {
2138 if(!(flags & VC_CONTAINER_SEEK_FLAG_FORWARD))
2139 break; /* Just use the last valid entry in that case */
2140 status = VC_CONTAINER_ERROR_EOS;
2141 goto error;
2142 }
2143
2144 status = mkv_read_element_header(p_ctx, size, &id, &element_size,
2145 MKV_ELEMENT_ID_CUES, &element);
2146 size -= STREAM_POSITION(p_ctx) - element_offset;
2147 if(status == VC_CONTAINER_SUCCESS && element->id != MKV_ELEMENT_ID_UNKNOWN)
2148 status = mkv_read_element_data(p_ctx, element, element_size, size);
2149
2150 if(status != VC_CONTAINER_SUCCESS || element->id == MKV_ELEMENT_ID_UNKNOWN)
2151 {
2152 if(!(flags & VC_CONTAINER_SEEK_FLAG_FORWARD))
2153 break; /* Just use the last valid entry in that case */
2154 goto error;
2155 }
2156
2157 size -= element_size;
2158 if(id != MKV_ELEMENT_ID_CUE_POINT) continue;
2159
2160 /* Ignore cue points which don't belong to the track we want */
2161 if(video_track != p_ctx->tracks_num &&
2162 p_ctx->tracks[video_track]->priv->module->number != module->cue_track) continue;
2163
2164 time_offset = module->cue_timecode * module->timecode_scale / 1000;
2165 offset = module->cue_cluster_offset;
2166 LOG_DEBUG(p_ctx, "INDEX: %"PRIi64, time_offset);
2167 if( time_offset > *p_offset )
2168 {
2169 if(!(flags & VC_CONTAINER_SEEK_FLAG_FORWARD))
2170 {
2171 time_offset = prev_time_offset;
2172 offset = prev_offset;
2173 }
2174 break;
2175 }
2176 prev_time_offset = time_offset;
2177 prev_offset = offset;
2178 } while( 1 );
2179 module->elements_list = mkv_elements_list;
2180 *p_offset = time_offset;
2181
2182 end:
2183 /* Try seeking to the requested position */
2184 status = SEEK(p_ctx, module->segment_offset + offset);
2185 if(status != VC_CONTAINER_SUCCESS && status != VC_CONTAINER_ERROR_EOS) goto error;
2186
2187 /* Reinitialise the state */
2188 memset(state, 0, sizeof(*state));
2189 state->levels[0].offset = module->segment_offset;
2190 state->levels[0].size = module->segment_size;
2191 state->levels[0].id = MKV_ELEMENT_ID_SEGMENT;
2192 if(status == VC_CONTAINER_ERROR_EOS) state->eos = true;
2193 for(i = 0; i < p_ctx->tracks_num; i++)
2194 {
2195 VC_CONTAINER_TRACK_T *p_track = p_ctx->tracks[i];
2196 p_track->priv->module->state = state;
2197 }
2198
2199 /* If we have a video track, we skip frames until the next keyframe */
2200 for(i = 0; video_track != p_ctx->tracks_num && i < 200 /* limit search */; )
2201 {
2202 uint32_t track, data_size;
2203 status = mkv_read_next_frame_header(p_ctx, state, &track, &data_size);
2204 if(status != VC_CONTAINER_SUCCESS) break; //FIXME
2205 if(track == video_track) i++;
2206 if(track == video_track && (state->flags & 0x80) &&
2207 state->pts >= time_offset) break;
2208
2209 /* Skip frame */
2210 status = mkv_read_frame_data(p_ctx, state, 0, &data_size);
2211 }
2212
2213 return VC_CONTAINER_SUCCESS;
2214
2215 error:
2216 /* Reset everything as it was before the seek */
2217 SEEK(p_ctx, position);
2218 if(status == VC_CONTAINER_SUCCESS) status = VC_CONTAINER_ERROR_FAILED;
2219 return status;
2220}
2221
2222/*****************************************************************************/
2223static VC_CONTAINER_STATUS_T mkv_reader_close(VC_CONTAINER_T *p_ctx)
2224{
2225 VC_CONTAINER_MODULE_T *module = p_ctx->priv->module;
2226 unsigned int i, j;
2227
2228 for(i = 0; i < p_ctx->tracks_num; i++)
2229 {
2230 for(j = 0; j < MKV_MAX_ENCODINGS; j++)
2231 free(p_ctx->tracks[i]->priv->module->encodings[j].data);
2232 vc_container_free_track(p_ctx, p_ctx->tracks[i]);
2233 }
2234 free(module);
2235 return VC_CONTAINER_SUCCESS;
2236}
2237
2238/*****************************************************************************/
2239VC_CONTAINER_STATUS_T mkv_reader_open(VC_CONTAINER_T *p_ctx)
2240{
2241 VC_CONTAINER_MODULE_T *module = 0;
2242 VC_CONTAINER_STATUS_T status = VC_CONTAINER_ERROR_FORMAT_INVALID;
2243 uint8_t buffer[4];
2244
2245 // Can start with ASCII strings ????
2246
2247 /* Check for an EBML element */
2248 if(PEEK_BYTES(p_ctx, buffer, 4) < 4 ||
2249 buffer[0] != 0x1A || buffer[1] != 0x45 || buffer[2] != 0xDF || buffer[3] != 0xA3)
2250 return VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED;
2251
2252 /*
2253 * We are dealing with an MKV file
2254 */
2255
2256 /* Allocate our context */
2257 module = malloc(sizeof(*module));
2258 if(!module) {status = VC_CONTAINER_ERROR_OUT_OF_MEMORY; goto error;}
2259 memset(module, 0, sizeof(*module));
2260 p_ctx->priv->module = module;
2261 p_ctx->tracks = module->tracks;
2262 module->elements_list = mkv_elements_list;
2263
2264 /* Read and sanity check the EBML header */
2265 status = mkv_read_element(p_ctx, INT64_C(-1), MKV_ELEMENT_ID_UNKNOWN);
2266 if(status != VC_CONTAINER_SUCCESS) goto error;
2267 if(!module->is_doctype_valid) {status = VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED; goto error;}
2268
2269 /* Read the other elements until we find the start of the data */
2270 do
2271 {
2272 status = mkv_read_element(p_ctx, INT64_C(-1), MKV_ELEMENT_ID_UNKNOWN);
2273 if(status != VC_CONTAINER_SUCCESS) break;
2274
2275 if(module->cluster_offset) break;
2276 } while(1);
2277
2278 /* Bail out if we didn't find a track */
2279 if(!p_ctx->tracks_num)
2280 {
2281 status = VC_CONTAINER_ERROR_NO_TRACK_AVAILABLE;
2282 goto error;
2283 }
2284
2285 /*
2286 * We now have all the information we really need to start playing the stream
2287 */
2288
2289 p_ctx->priv->pf_close = mkv_reader_close;
2290 p_ctx->priv->pf_read = mkv_reader_read;
2291 p_ctx->priv->pf_seek = mkv_reader_seek;
2292 p_ctx->duration = module->duration / 1000 * module->timecode_scale;
2293
2294 /* Check if we're done */
2295 if(!STREAM_SEEKABLE(p_ctx))
2296 return VC_CONTAINER_SUCCESS;
2297
2298 if(module->cues_offset && (int64_t)module->cues_offset < p_ctx->size)
2299 p_ctx->capabilities |= VC_CONTAINER_CAPS_CAN_SEEK;
2300
2301 if(module->tags_offset)
2302 {
2303 status = SEEK(p_ctx, module->tags_offset);
2304 if(status == VC_CONTAINER_SUCCESS)
2305 status = mkv_read_element(p_ctx, INT64_C(-1) /*FIXME*/, MKV_ELEMENT_ID_SEGMENT);
2306 }
2307
2308 /* Seek back to the start of the data */
2309 return SEEK(p_ctx, module->state.levels[1].offset);
2310
2311 error:
2312 LOG_DEBUG(p_ctx, "mkv: error opening stream (%i)", status);
2313 if(module) mkv_reader_close(p_ctx);
2314 return status;
2315}
2316
2317/********************************************************************************
2318 Entrypoint function
2319 ********************************************************************************/
2320
2321#if !defined(ENABLE_CONTAINERS_STANDALONE) && defined(__HIGHC__)
2322# pragma weak reader_open mkv_reader_open
2323#endif
2324