1 /*
2 * Copyright © 2010 Mozilla Foundation
3 *
4 * This program is made available under an ISC-style license. See the
5 * accompanying file LICENSE for details.
6 */
7 #include <assert.h>
8 #include <stdlib.h>
9 #include <string.h>
10
11 #include "nestegg/halloc/halloc.h"
12 #include "nestegg/include/nestegg/nestegg.h"
13
14 /* EBML Elements */
15 #define ID_EBML 0x1a45dfa3
16 #define ID_EBML_VERSION 0x4286
17 #define ID_EBML_READ_VERSION 0x42f7
18 #define ID_EBML_MAX_ID_LENGTH 0x42f2
19 #define ID_EBML_MAX_SIZE_LENGTH 0x42f3
20 #define ID_DOCTYPE 0x4282
21 #define ID_DOCTYPE_VERSION 0x4287
22 #define ID_DOCTYPE_READ_VERSION 0x4285
23
24 /* Global Elements */
25 #define ID_VOID 0xec
26 #define ID_CRC32 0xbf
27
28 /* WebMedia Elements */
29 #define ID_SEGMENT 0x18538067
30
31 /* Seek Head Elements */
32 #define ID_SEEK_HEAD 0x114d9b74
33 #define ID_SEEK 0x4dbb
34 #define ID_SEEK_ID 0x53ab
35 #define ID_SEEK_POSITION 0x53ac
36
37 /* Info Elements */
38 #define ID_INFO 0x1549a966
39 #define ID_TIMECODE_SCALE 0x2ad7b1
40 #define ID_DURATION 0x4489
41
42 /* Cluster Elements */
43 #define ID_CLUSTER 0x1f43b675
44 #define ID_TIMECODE 0xe7
45 #define ID_BLOCK_GROUP 0xa0
46 #define ID_SIMPLE_BLOCK 0xa3
47
48 /* BlockGroup Elements */
49 #define ID_BLOCK 0xa1
50 #define ID_BLOCK_DURATION 0x9b
51 #define ID_REFERENCE_BLOCK 0xfb
52
53 /* Tracks Elements */
54 #define ID_TRACKS 0x1654ae6b
55 #define ID_TRACK_ENTRY 0xae
56 #define ID_TRACK_NUMBER 0xd7
57 #define ID_TRACK_UID 0x73c5
58 #define ID_TRACK_TYPE 0x83
59 #define ID_FLAG_ENABLED 0xb9
60 #define ID_FLAG_DEFAULT 0x88
61 #define ID_FLAG_LACING 0x9c
62 #define ID_TRACK_TIMECODE_SCALE 0x23314f
63 #define ID_LANGUAGE 0x22b59c
64 #define ID_CODEC_ID 0x86
65 #define ID_CODEC_PRIVATE 0x63a2
66
67 /* Video Elements */
68 #define ID_VIDEO 0xe0
69 #define ID_PIXEL_WIDTH 0xb0
70 #define ID_PIXEL_HEIGHT 0xba
71 #define ID_PIXEL_CROP_BOTTOM 0x54aa
72 #define ID_PIXEL_CROP_TOP 0x54bb
73 #define ID_PIXEL_CROP_LEFT 0x54cc
74 #define ID_PIXEL_CROP_RIGHT 0x54dd
75 #define ID_DISPLAY_WIDTH 0x54b0
76 #define ID_DISPLAY_HEIGHT 0x54ba
77
78 /* Audio Elements */
79 #define ID_AUDIO 0xe1
80 #define ID_SAMPLING_FREQUENCY 0xb5
81 #define ID_CHANNELS 0x9f
82 #define ID_BIT_DEPTH 0x6264
83
84 /* Cues Elements */
85 #define ID_CUES 0x1c53bb6b
86 #define ID_CUE_POINT 0xbb
87 #define ID_CUE_TIME 0xb3
88 #define ID_CUE_TRACK_POSITIONS 0xb7
89 #define ID_CUE_TRACK 0xf7
90 #define ID_CUE_CLUSTER_POSITION 0xf1
91 #define ID_CUE_BLOCK_NUMBER 0x5378
92
93 /* EBML Types */
94 enum ebml_type_enum {
95 TYPE_UNKNOWN,
96 TYPE_MASTER,
97 TYPE_UINT,
98 TYPE_FLOAT,
99 TYPE_INT,
100 TYPE_STRING,
101 TYPE_BINARY
102 };
103
104 #define LIMIT_STRING (1 << 20)
105 #define LIMIT_BINARY (1 << 24)
106 #define LIMIT_BLOCK (1 << 30)
107 #define LIMIT_FRAME (1 << 28)
108
109 /* Field Flags */
110 #define DESC_FLAG_NONE 0
111 #define DESC_FLAG_MULTI (1 << 0)
112 #define DESC_FLAG_SUSPEND (1 << 1)
113 #define DESC_FLAG_OFFSET (1 << 2)
114
115 /* Block Header Flags */
116 #define BLOCK_FLAGS_LACING 6
117
118 /* Lacing Constants */
119 #define LACING_NONE 0
120 #define LACING_XIPH 1
121 #define LACING_FIXED 2
122 #define LACING_EBML 3
123
124 /* Track Types */
125 #define TRACK_TYPE_VIDEO 1
126 #define TRACK_TYPE_AUDIO 2
127
128 /* Track IDs */
129 #define TRACK_ID_VP8 "V_VP8"
130 #define TRACK_ID_VORBIS "A_VORBIS"
131
132 enum vint_mask {
133 MASK_NONE,
134 MASK_FIRST_BIT
135 };
136
137 struct ebml_binary {
138 unsigned char * data;
139 size_t length;
140 };
141
142 struct ebml_list_node {
143 struct ebml_list_node * next;
144 uint64_t id;
145 void * data;
146 };
147
148 struct ebml_list {
149 struct ebml_list_node * head;
150 struct ebml_list_node * tail;
151 };
152
153 struct ebml_type {
154 union ebml_value {
155 uint64_t u;
156 double f;
157 int64_t i;
158 char * s;
159 struct ebml_binary b;
160 } v;
161 enum ebml_type_enum type;
162 int read;
163 };
164
165 /* EBML Definitions */
166 struct ebml {
167 struct ebml_type ebml_version;
168 struct ebml_type ebml_read_version;
169 struct ebml_type ebml_max_id_length;
170 struct ebml_type ebml_max_size_length;
171 struct ebml_type doctype;
172 struct ebml_type doctype_version;
173 struct ebml_type doctype_read_version;
174 };
175
176 /* Matroksa Definitions */
177 struct seek {
178 struct ebml_type id;
179 struct ebml_type position;
180 };
181
182 struct seek_head {
183 struct ebml_list seek;
184 };
185
186 struct info {
187 struct ebml_type timecode_scale;
188 struct ebml_type duration;
189 };
190
191 struct block_group {
192 struct ebml_type duration;
193 struct ebml_type reference_block;
194 };
195
196 struct cluster {
197 struct ebml_type timecode;
198 struct ebml_list block_group;
199 };
200
201 struct video {
202 struct ebml_type pixel_width;
203 struct ebml_type pixel_height;
204 struct ebml_type pixel_crop_bottom;
205 struct ebml_type pixel_crop_top;
206 struct ebml_type pixel_crop_left;
207 struct ebml_type pixel_crop_right;
208 struct ebml_type display_width;
209 struct ebml_type display_height;
210 };
211
212 struct audio {
213 struct ebml_type sampling_frequency;
214 struct ebml_type channels;
215 struct ebml_type bit_depth;
216 };
217
218 struct track_entry {
219 struct ebml_type number;
220 struct ebml_type uid;
221 struct ebml_type type;
222 struct ebml_type flag_enabled;
223 struct ebml_type flag_default;
224 struct ebml_type flag_lacing;
225 struct ebml_type track_timecode_scale;
226 struct ebml_type language;
227 struct ebml_type codec_id;
228 struct ebml_type codec_private;
229 struct video video;
230 struct audio audio;
231 };
232
233 struct tracks {
234 struct ebml_list track_entry;
235 };
236
237 struct cue_track_positions {
238 struct ebml_type track;
239 struct ebml_type cluster_position;
240 struct ebml_type block_number;
241 };
242
243 struct cue_point {
244 struct ebml_type time;
245 struct ebml_list cue_track_positions;
246 };
247
248 struct cues {
249 struct ebml_list cue_point;
250 };
251
252 struct segment {
253 struct ebml_list seek_head;
254 struct info info;
255 struct ebml_list cluster;
256 struct tracks tracks;
257 struct cues cues;
258 };
259
260 /* Misc. */
261 struct pool_ctx {
262 char dummy;
263 };
264
265 struct list_node {
266 struct list_node * previous;
267 struct ebml_element_desc * node;
268 unsigned char * data;
269 };
270
271 struct saved_state {
272 int64_t stream_offset;
273 struct list_node * ancestor;
274 uint64_t last_id;
275 uint64_t last_size;
276 };
277
278 struct frame {
279 unsigned char * data;
280 size_t length;
281 struct frame * next;
282 };
283
284 /* Public (opaque) Structures */
285 struct nestegg {
286 nestegg_io * io;
287 nestegg_log log;
288 struct pool_ctx * alloc_pool;
289 uint64_t last_id;
290 uint64_t last_size;
291 struct list_node * ancestor;
292 struct ebml ebml;
293 struct segment segment;
294 int64_t segment_offset;
295 unsigned int track_count;
296 };
297
298 struct nestegg_packet {
299 uint64_t track;
300 uint64_t timecode;
301 struct frame * frame;
302 };
303
304 /* Element Descriptor */
305 struct ebml_element_desc {
306 char const * name;
307 uint64_t id;
308 enum ebml_type_enum type;
309 size_t offset;
310 unsigned int flags;
311 struct ebml_element_desc * children;
312 size_t size;
313 size_t data_offset;
314 };
315
316 #define E_FIELD(ID, TYPE, STRUCT, FIELD) \
317 { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_NONE, NULL, 0, 0 }
318 #define E_MASTER(ID, TYPE, STRUCT, FIELD) \
319 { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_MULTI, ne_ ## FIELD ## _elements, \
320 sizeof(struct FIELD), 0 }
321 #define E_SINGLE_MASTER_O(ID, TYPE, STRUCT, FIELD) \
322 { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_OFFSET, ne_ ## FIELD ## _elements, 0, \
323 offsetof(STRUCT, FIELD ## _offset) }
324 #define E_SINGLE_MASTER(ID, TYPE, STRUCT, FIELD) \
325 { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_NONE, ne_ ## FIELD ## _elements, 0, 0 }
326 #define E_SUSPEND(ID, TYPE) \
327 { #ID, ID, TYPE, 0, DESC_FLAG_SUSPEND, NULL, 0, 0 }
328 #define E_LAST \
329 { NULL, 0, 0, 0, DESC_FLAG_NONE, NULL, 0, 0 }
330
331 /* EBML Element Lists */
332 static struct ebml_element_desc ne_ebml_elements[] = {
333 E_FIELD(ID_EBML_VERSION, TYPE_UINT, struct ebml, ebml_version),
334 E_FIELD(ID_EBML_READ_VERSION, TYPE_UINT, struct ebml, ebml_read_version),
335 E_FIELD(ID_EBML_MAX_ID_LENGTH, TYPE_UINT, struct ebml, ebml_max_id_length),
336 E_FIELD(ID_EBML_MAX_SIZE_LENGTH, TYPE_UINT, struct ebml, ebml_max_size_length),
337 E_FIELD(ID_DOCTYPE, TYPE_STRING, struct ebml, doctype),
338 E_FIELD(ID_DOCTYPE_VERSION, TYPE_UINT, struct ebml, doctype_version),
339 E_FIELD(ID_DOCTYPE_READ_VERSION, TYPE_UINT, struct ebml, doctype_read_version),
340 E_LAST
341 };
342
343 /* WebMedia Element Lists */
344 static struct ebml_element_desc ne_seek_elements[] = {
345 E_FIELD(ID_SEEK_ID, TYPE_BINARY, struct seek, id),
346 E_FIELD(ID_SEEK_POSITION, TYPE_UINT, struct seek, position),
347 E_LAST
348 };
349
350 static struct ebml_element_desc ne_seek_head_elements[] = {
351 E_MASTER(ID_SEEK, TYPE_MASTER, struct seek_head, seek),
352 E_LAST
353 };
354
355 static struct ebml_element_desc ne_info_elements[] = {
356 E_FIELD(ID_TIMECODE_SCALE, TYPE_UINT, struct info, timecode_scale),
357 E_FIELD(ID_DURATION, TYPE_FLOAT, struct info, duration),
358 E_LAST
359 };
360
361 static struct ebml_element_desc ne_block_group_elements[] = {
362 E_SUSPEND(ID_BLOCK, TYPE_BINARY),
363 E_FIELD(ID_BLOCK_DURATION, TYPE_UINT, struct block_group, duration),
364 E_FIELD(ID_REFERENCE_BLOCK, TYPE_INT, struct block_group, reference_block),
365 E_LAST
366 };
367
368 static struct ebml_element_desc ne_cluster_elements[] = {
369 E_FIELD(ID_TIMECODE, TYPE_UINT, struct cluster, timecode),
370 E_MASTER(ID_BLOCK_GROUP, TYPE_MASTER, struct cluster, block_group),
371 E_SUSPEND(ID_SIMPLE_BLOCK, TYPE_BINARY),
372 E_LAST
373 };
374
375 static struct ebml_element_desc ne_video_elements[] = {
376 E_FIELD(ID_PIXEL_WIDTH, TYPE_UINT, struct video, pixel_width),
377 E_FIELD(ID_PIXEL_HEIGHT, TYPE_UINT, struct video, pixel_height),
378 E_FIELD(ID_PIXEL_CROP_BOTTOM, TYPE_UINT, struct video, pixel_crop_bottom),
379 E_FIELD(ID_PIXEL_CROP_TOP, TYPE_UINT, struct video, pixel_crop_top),
380 E_FIELD(ID_PIXEL_CROP_LEFT, TYPE_UINT, struct video, pixel_crop_left),
381 E_FIELD(ID_PIXEL_CROP_RIGHT, TYPE_UINT, struct video, pixel_crop_right),
382 E_FIELD(ID_DISPLAY_WIDTH, TYPE_UINT, struct video, display_width),
383 E_FIELD(ID_DISPLAY_HEIGHT, TYPE_UINT, struct video, display_height),
384 E_LAST
385 };
386
387 static struct ebml_element_desc ne_audio_elements[] = {
388 E_FIELD(ID_SAMPLING_FREQUENCY, TYPE_FLOAT, struct audio, sampling_frequency),
389 E_FIELD(ID_CHANNELS, TYPE_UINT, struct audio, channels),
390 E_FIELD(ID_BIT_DEPTH, TYPE_UINT, struct audio, bit_depth),
391 E_LAST
392 };
393
394 static struct ebml_element_desc ne_track_entry_elements[] = {
395 E_FIELD(ID_TRACK_NUMBER, TYPE_UINT, struct track_entry, number),
396 E_FIELD(ID_TRACK_UID, TYPE_UINT, struct track_entry, uid),
397 E_FIELD(ID_TRACK_TYPE, TYPE_UINT, struct track_entry, type),
398 E_FIELD(ID_FLAG_ENABLED, TYPE_UINT, struct track_entry, flag_enabled),
399 E_FIELD(ID_FLAG_DEFAULT, TYPE_UINT, struct track_entry, flag_default),
400 E_FIELD(ID_FLAG_LACING, TYPE_UINT, struct track_entry, flag_lacing),
401 E_FIELD(ID_TRACK_TIMECODE_SCALE, TYPE_FLOAT, struct track_entry, track_timecode_scale),
402 E_FIELD(ID_LANGUAGE, TYPE_STRING, struct track_entry, language),
403 E_FIELD(ID_CODEC_ID, TYPE_STRING, struct track_entry, codec_id),
404 E_FIELD(ID_CODEC_PRIVATE, TYPE_BINARY, struct track_entry, codec_private),
405 E_SINGLE_MASTER(ID_VIDEO, TYPE_MASTER, struct track_entry, video),
406 E_SINGLE_MASTER(ID_AUDIO, TYPE_MASTER, struct track_entry, audio),
407 E_LAST
408 };
409
410 static struct ebml_element_desc ne_tracks_elements[] = {
411 E_MASTER(ID_TRACK_ENTRY, TYPE_MASTER, struct tracks, track_entry),
412 E_LAST
413 };
414
415 static struct ebml_element_desc ne_cue_track_positions_elements[] = {
416 E_FIELD(ID_CUE_TRACK, TYPE_UINT, struct cue_track_positions, track),
417 E_FIELD(ID_CUE_CLUSTER_POSITION, TYPE_UINT, struct cue_track_positions, cluster_position),
418 E_FIELD(ID_CUE_BLOCK_NUMBER, TYPE_UINT, struct cue_track_positions, block_number),
419 E_LAST
420 };
421
422 static struct ebml_element_desc ne_cue_point_elements[] = {
423 E_FIELD(ID_CUE_TIME, TYPE_UINT, struct cue_point, time),
424 E_MASTER(ID_CUE_TRACK_POSITIONS, TYPE_MASTER, struct cue_point, cue_track_positions),
425 E_LAST
426 };
427
428 static struct ebml_element_desc ne_cues_elements[] = {
429 E_MASTER(ID_CUE_POINT, TYPE_MASTER, struct cues, cue_point),
430 E_LAST
431 };
432
433 static struct ebml_element_desc ne_segment_elements[] = {
434 E_MASTER(ID_SEEK_HEAD, TYPE_MASTER, struct segment, seek_head),
435 E_SINGLE_MASTER(ID_INFO, TYPE_MASTER, struct segment, info),
436 E_MASTER(ID_CLUSTER, TYPE_MASTER, struct segment, cluster),
437 E_SINGLE_MASTER(ID_TRACKS, TYPE_MASTER, struct segment, tracks),
438 E_SINGLE_MASTER(ID_CUES, TYPE_MASTER, struct segment, cues),
439 E_LAST
440 };
441
442 static struct ebml_element_desc ne_top_level_elements[] = {
443 E_SINGLE_MASTER(ID_EBML, TYPE_MASTER, nestegg, ebml),
444 E_SINGLE_MASTER_O(ID_SEGMENT, TYPE_MASTER, nestegg, segment),
445 E_LAST
446 };
447
448 #undef E_FIELD
449 #undef E_MASTER
450 #undef E_SINGLE_MASTER_O
451 #undef E_SINGLE_MASTER
452 #undef E_SUSPEND
453 #undef E_LAST
454
455 static struct pool_ctx *
ne_pool_init(void)456 ne_pool_init(void)
457 {
458 struct pool_ctx * pool;
459
460 pool = h_malloc(sizeof(*pool));
461 if (!pool)
462 abort();
463 return pool;
464 }
465
466 static void
ne_pool_destroy(struct pool_ctx * pool)467 ne_pool_destroy(struct pool_ctx * pool)
468 {
469 h_free(pool);
470 }
471
472 static void *
ne_pool_alloc(size_t size,struct pool_ctx * pool)473 ne_pool_alloc(size_t size, struct pool_ctx * pool)
474 {
475 void * p;
476
477 p = h_malloc(size);
478 if (!p)
479 abort();
480 hattach(p, pool);
481 memset(p, 0, size);
482 return p;
483 }
484
485 static void *
ne_alloc(size_t size)486 ne_alloc(size_t size)
487 {
488 void * p;
489
490 p = calloc(1, size);
491 if (!p)
492 abort();
493 return p;
494 }
495
496 static int
ne_io_read(nestegg_io * io,void * buffer,size_t length)497 ne_io_read(nestegg_io * io, void * buffer, size_t length)
498 {
499 return io->read(buffer, length, io->userdata);
500 }
501
502 static int
ne_io_seek(nestegg_io * io,int64_t offset,int whence)503 ne_io_seek(nestegg_io * io, int64_t offset, int whence)
504 {
505 return io->seek(offset, whence, io->userdata);
506 }
507
508 static int
ne_io_read_skip(nestegg_io * io,size_t length)509 ne_io_read_skip(nestegg_io * io, size_t length)
510 {
511 size_t get;
512 unsigned char buf[8192];
513 int r = 1;
514
515 while (length > 0) {
516 get = length < sizeof(buf) ? length : sizeof(buf);
517 r = ne_io_read(io, buf, get);
518 if (r != 1)
519 break;
520 length -= get;
521 }
522
523 return r;
524 }
525
526 static int64_t
ne_io_tell(nestegg_io * io)527 ne_io_tell(nestegg_io * io)
528 {
529 return io->tell(io->userdata);
530 }
531
532 static int
ne_bare_read_vint(nestegg_io * io,uint64_t * value,uint64_t * length,enum vint_mask maskflag)533 ne_bare_read_vint(nestegg_io * io, uint64_t * value, uint64_t * length, enum vint_mask maskflag)
534 {
535 int r;
536 unsigned char b;
537 size_t maxlen = 8;
538 unsigned int count = 1, mask = 1 << 7;
539
540 r = ne_io_read(io, &b, 1);
541 if (r != 1)
542 return r;
543
544 while (count < maxlen) {
545 if ((b & mask) != 0)
546 break;
547 mask >>= 1;
548 count += 1;
549 }
550
551 if (length)
552 *length = count;
553 *value = b;
554
555 if (maskflag == MASK_FIRST_BIT)
556 *value = b & ~mask;
557
558 while (--count) {
559 r = ne_io_read(io, &b, 1);
560 if (r != 1)
561 return r;
562 *value <<= 8;
563 *value |= b;
564 }
565
566 return 1;
567 }
568
569 static int
ne_read_id(nestegg_io * io,uint64_t * value,uint64_t * length)570 ne_read_id(nestegg_io * io, uint64_t * value, uint64_t * length)
571 {
572 return ne_bare_read_vint(io, value, length, MASK_NONE);
573 }
574
575 static int
ne_read_vint(nestegg_io * io,uint64_t * value,uint64_t * length)576 ne_read_vint(nestegg_io * io, uint64_t * value, uint64_t * length)
577 {
578 return ne_bare_read_vint(io, value, length, MASK_FIRST_BIT);
579 }
580
581 static int
ne_read_svint(nestegg_io * io,int64_t * value,uint64_t * length)582 ne_read_svint(nestegg_io * io, int64_t * value, uint64_t * length)
583 {
584 int r;
585 uint64_t uvalue;
586 uint64_t ulength;
587 int64_t svint_subtr[] = {
588 0x3f, 0x1fff,
589 0xfffff, 0x7ffffff,
590 0x3ffffffffLL, 0x1ffffffffffLL,
591 0xffffffffffffLL, 0x7fffffffffffffLL
592 };
593
594 r = ne_bare_read_vint(io, &uvalue, &ulength, MASK_FIRST_BIT);
595 if (r != 1)
596 return r;
597 *value = uvalue - svint_subtr[ulength - 1];
598 if (length)
599 *length = ulength;
600 return r;
601 }
602
603 static int
ne_read_uint(nestegg_io * io,uint64_t * val,uint64_t length)604 ne_read_uint(nestegg_io * io, uint64_t * val, uint64_t length)
605 {
606 unsigned char b;
607 int r;
608
609 if (length == 0 || length > 8)
610 return -1;
611 r = ne_io_read(io, &b, 1);
612 if (r != 1)
613 return r;
614 *val = b;
615 while (--length) {
616 r = ne_io_read(io, &b, 1);
617 if (r != 1)
618 return r;
619 *val <<= 8;
620 *val |= b;
621 }
622 return 1;
623 }
624
625 static int
ne_read_int(nestegg_io * io,int64_t * val,uint64_t length)626 ne_read_int(nestegg_io * io, int64_t * val, uint64_t length)
627 {
628 int r;
629 uint64_t uval, base;
630
631 r = ne_read_uint(io, &uval, length);
632 if (r != 1)
633 return r;
634
635 if (length < sizeof(int64_t)) {
636 base = 1;
637 base <<= length * 8 - 1;
638 if (uval >= base) {
639 base = 1;
640 base <<= length * 8;
641 } else {
642 base = 0;
643 }
644 *val = uval - base;
645 } else {
646 *val = (int64_t) uval;
647 }
648
649 return 1;
650 }
651
652 static int
ne_read_float(nestegg_io * io,double * val,uint64_t length)653 ne_read_float(nestegg_io * io, double * val, uint64_t length)
654 {
655 union {
656 uint64_t u;
657 float f;
658 double d;
659 } value;
660 int r;
661
662 /* length == 10 not implemented */
663 if (length != 4 && length != 8)
664 return -1;
665 r = ne_read_uint(io, &value.u, length);
666 if (r != 1)
667 return r;
668 if (length == 4)
669 *val = value.f;
670 else
671 *val = value.d;
672 return 1;
673 }
674
675 static int
ne_read_string(nestegg * ctx,char ** val,uint64_t length)676 ne_read_string(nestegg * ctx, char ** val, uint64_t length)
677 {
678 char * str;
679 int r;
680
681 if (length == 0 || length > LIMIT_STRING)
682 return -1;
683 str = ne_pool_alloc(length + 1, ctx->alloc_pool);
684 r = ne_io_read(ctx->io, (unsigned char *) str, length);
685 if (r != 1)
686 return r;
687 str[length] = '\0';
688 *val = str;
689 return 1;
690 }
691
692 static int
ne_read_binary(nestegg * ctx,struct ebml_binary * val,uint64_t length)693 ne_read_binary(nestegg * ctx, struct ebml_binary * val, uint64_t length)
694 {
695 if (length == 0 || length > LIMIT_BINARY)
696 return -1;
697 val->data = ne_pool_alloc(length, ctx->alloc_pool);
698 val->length = length;
699 return ne_io_read(ctx->io, val->data, length);
700 }
701
702 static int
ne_get_uint(struct ebml_type type,uint64_t * value)703 ne_get_uint(struct ebml_type type, uint64_t * value)
704 {
705 if (!type.read)
706 return -1;
707
708 assert(type.type == TYPE_UINT);
709
710 *value = type.v.u;
711
712 return 0;
713 }
714
715 static int
ne_get_float(struct ebml_type type,double * value)716 ne_get_float(struct ebml_type type, double * value)
717 {
718 if (!type.read)
719 return -1;
720
721 assert(type.type == TYPE_FLOAT);
722
723 *value = type.v.f;
724
725 return 0;
726 }
727
728 static int
ne_get_string(struct ebml_type type,char ** value)729 ne_get_string(struct ebml_type type, char ** value)
730 {
731 if (!type.read)
732 return -1;
733
734 assert(type.type == TYPE_STRING);
735
736 *value = type.v.s;
737
738 return 0;
739 }
740
741 static int
ne_get_binary(struct ebml_type type,struct ebml_binary * value)742 ne_get_binary(struct ebml_type type, struct ebml_binary * value)
743 {
744 if (!type.read)
745 return -1;
746
747 assert(type.type == TYPE_BINARY);
748
749 *value = type.v.b;
750
751 return 0;
752 }
753
754 static int
ne_is_ancestor_element(uint64_t id,struct list_node * ancestor)755 ne_is_ancestor_element(uint64_t id, struct list_node * ancestor)
756 {
757 struct ebml_element_desc * element;
758
759 for (; ancestor; ancestor = ancestor->previous)
760 for (element = ancestor->node; element->id; ++element)
761 if (element->id == id)
762 return 1;
763
764 return 0;
765 }
766
767 static struct ebml_element_desc *
ne_find_element(uint64_t id,struct ebml_element_desc * elements)768 ne_find_element(uint64_t id, struct ebml_element_desc * elements)
769 {
770 struct ebml_element_desc * element;
771
772 for (element = elements; element->id; ++element)
773 if (element->id == id)
774 return element;
775
776 return NULL;
777 }
778
779 static void
ne_ctx_push(nestegg * ctx,struct ebml_element_desc * ancestor,void * data)780 ne_ctx_push(nestegg * ctx, struct ebml_element_desc * ancestor, void * data)
781 {
782 struct list_node * item;
783
784 item = ne_alloc(sizeof(*item));
785 item->previous = ctx->ancestor;
786 item->node = ancestor;
787 item->data = data;
788 ctx->ancestor = item;
789 }
790
791 static void
ne_ctx_pop(nestegg * ctx)792 ne_ctx_pop(nestegg * ctx)
793 {
794 struct list_node * item;
795
796 item = ctx->ancestor;
797 ctx->ancestor = item->previous;
798 free(item);
799 }
800
801 static int
ne_ctx_save(nestegg * ctx,struct saved_state * s)802 ne_ctx_save(nestegg * ctx, struct saved_state * s)
803 {
804 s->stream_offset = ne_io_tell(ctx->io);
805 if (s->stream_offset < 0)
806 return -1;
807 s->ancestor = ctx->ancestor;
808 s->last_id = ctx->last_id;
809 s->last_size = ctx->last_size;
810 return 0;
811 }
812
813 static int
ne_ctx_restore(nestegg * ctx,struct saved_state * s)814 ne_ctx_restore(nestegg * ctx, struct saved_state * s)
815 {
816 int r;
817
818 r = ne_io_seek(ctx->io, s->stream_offset, NESTEGG_SEEK_SET);
819 if (r != 0)
820 return -1;
821 ctx->ancestor = s->ancestor;
822 ctx->last_id = s->last_id;
823 ctx->last_size = s->last_size;
824 return 0;
825 }
826
827 static int
ne_peek_element(nestegg * ctx,uint64_t * id,uint64_t * size)828 ne_peek_element(nestegg * ctx, uint64_t * id, uint64_t * size)
829 {
830 int r;
831
832 if (ctx->last_id && ctx->last_size) {
833 if (id)
834 *id = ctx->last_id;
835 if (size)
836 *size = ctx->last_size;
837 return 1;
838 }
839
840 r = ne_read_id(ctx->io, &ctx->last_id, NULL);
841 if (r != 1)
842 return r;
843
844 r = ne_read_vint(ctx->io, &ctx->last_size, NULL);
845 if (r != 1)
846 return r;
847
848 if (id)
849 *id = ctx->last_id;
850 if (size)
851 *size = ctx->last_size;
852
853 return 1;
854 }
855
856 static int
ne_read_element(nestegg * ctx,uint64_t * id,uint64_t * size)857 ne_read_element(nestegg * ctx, uint64_t * id, uint64_t * size)
858 {
859 int r;
860
861 r = ne_peek_element(ctx, id, size);
862 if (r != 1)
863 return r;
864
865 ctx->last_id = 0;
866 ctx->last_size = 0;
867
868 return 1;
869 }
870
871 static void
ne_read_master(nestegg * ctx,struct ebml_element_desc * desc)872 ne_read_master(nestegg * ctx, struct ebml_element_desc * desc)
873 {
874 struct ebml_list * list;
875 struct ebml_list_node * node, * oldtail;
876
877 assert(desc->type == TYPE_MASTER && desc->flags & DESC_FLAG_MULTI);
878
879 ctx->log(ctx, NESTEGG_LOG_DEBUG, "multi master element %llx (%s)",
880 desc->id, desc->name);
881
882 list = (struct ebml_list *) (ctx->ancestor->data + desc->offset);
883
884 node = ne_pool_alloc(sizeof(*node), ctx->alloc_pool);
885 node->id = desc->id;
886 node->data = ne_pool_alloc(desc->size, ctx->alloc_pool);
887
888 oldtail = list->tail;
889 if (oldtail)
890 oldtail->next = node;
891 list->tail = node;
892 if (!list->head)
893 list->head = node;
894
895 ctx->log(ctx, NESTEGG_LOG_DEBUG, " -> using data %p", node->data);
896
897 ne_ctx_push(ctx, desc->children, node->data);
898 }
899
900 static void
ne_read_single_master(nestegg * ctx,struct ebml_element_desc * desc)901 ne_read_single_master(nestegg * ctx, struct ebml_element_desc * desc)
902 {
903 assert(desc->type == TYPE_MASTER && !(desc->flags & DESC_FLAG_MULTI));
904
905 ctx->log(ctx, NESTEGG_LOG_DEBUG, "single master element %llx (%s)",
906 desc->id, desc->name);
907 ctx->log(ctx, NESTEGG_LOG_DEBUG, " -> using data %p (%u)",
908 ctx->ancestor->data + desc->offset, desc->offset);
909
910 ne_ctx_push(ctx, desc->children, ctx->ancestor->data + desc->offset);
911 }
912
913 static int
ne_read_simple(nestegg * ctx,struct ebml_element_desc * desc,size_t length)914 ne_read_simple(nestegg * ctx, struct ebml_element_desc * desc, size_t length)
915 {
916 struct ebml_type * storage;
917 int r;
918
919 storage = (struct ebml_type *) (ctx->ancestor->data + desc->offset);
920
921 if (storage->read) {
922 ctx->log(ctx, NESTEGG_LOG_DEBUG, "element %llx (%s) already read, skipping",
923 desc->id, desc->name);
924 return 0;
925 }
926
927 storage->type = desc->type;
928
929 ctx->log(ctx, NESTEGG_LOG_DEBUG, "element %llx (%s) -> %p (%u)",
930 desc->id, desc->name, storage, desc->offset);
931
932 r = -1;
933
934 switch (desc->type) {
935 case TYPE_UINT:
936 r = ne_read_uint(ctx->io, &storage->v.u, length);
937 break;
938 case TYPE_FLOAT:
939 r = ne_read_float(ctx->io, &storage->v.f, length);
940 break;
941 case TYPE_INT:
942 r = ne_read_int(ctx->io, &storage->v.i, length);
943 break;
944 case TYPE_STRING:
945 r = ne_read_string(ctx, &storage->v.s, length);
946 break;
947 case TYPE_BINARY:
948 r = ne_read_binary(ctx, &storage->v.b, length);
949 break;
950 case TYPE_MASTER:
951 case TYPE_UNKNOWN:
952 assert(0);
953 break;
954 }
955
956 if (r == 1)
957 storage->read = 1;
958
959 return r;
960 }
961
962 static int
ne_parse(nestegg * ctx,struct ebml_element_desc * top_level)963 ne_parse(nestegg * ctx, struct ebml_element_desc * top_level)
964 {
965 int r;
966 int64_t * data_offset;
967 uint64_t id, size;
968 struct ebml_element_desc * element;
969
970 /* loop until we need to return:
971 - hit suspend point
972 - parse complete
973 - error occurred */
974
975 /* loop over elements at current level reading them if sublevel found,
976 push ctx onto stack and continue if sublevel ended, pop ctx off stack
977 and continue */
978
979 if (!ctx->ancestor)
980 return -1;
981
982 for (;;) {
983 r = ne_peek_element(ctx, &id, &size);
984 if (r != 1)
985 break;
986
987 element = ne_find_element(id, ctx->ancestor->node);
988 if (element) {
989 if (element->flags & DESC_FLAG_SUSPEND) {
990 assert(element->type == TYPE_BINARY);
991 ctx->log(ctx, NESTEGG_LOG_DEBUG, "suspend parse at %llx", id);
992 r = 1;
993 break;
994 }
995
996 r = ne_read_element(ctx, &id, &size);
997 if (r != 1)
998 break;
999
1000 if (element->flags & DESC_FLAG_OFFSET) {
1001 data_offset = (int64_t *) (ctx->ancestor->data + element->data_offset);
1002 *data_offset = ne_io_tell(ctx->io);
1003 if (*data_offset < 0) {
1004 r = -1;
1005 break;
1006 }
1007 }
1008
1009 if (element->type == TYPE_MASTER) {
1010 if (element->flags & DESC_FLAG_MULTI)
1011 ne_read_master(ctx, element);
1012 else
1013 ne_read_single_master(ctx, element);
1014 continue;
1015 } else {
1016 r = ne_read_simple(ctx, element, size);
1017 if (r < 0)
1018 break;
1019 }
1020 } else if (ne_is_ancestor_element(id, ctx->ancestor->previous)) {
1021 ctx->log(ctx, NESTEGG_LOG_DEBUG, "parent element %llx", id);
1022 if (top_level && ctx->ancestor->node == top_level) {
1023 ctx->log(ctx, NESTEGG_LOG_DEBUG, "*** parse about to back up past top_level");
1024 r = 1;
1025 break;
1026 }
1027 ne_ctx_pop(ctx);
1028 } else {
1029 r = ne_read_element(ctx, &id, &size);
1030 if (r != 1)
1031 break;
1032
1033 if (id != ID_VOID && id != ID_CRC32)
1034 ctx->log(ctx, NESTEGG_LOG_DEBUG, "unknown element %llx", id);
1035 r = ne_io_read_skip(ctx->io, size);
1036 if (r != 1)
1037 break;
1038 }
1039 }
1040
1041 if (r != 1)
1042 while (ctx->ancestor)
1043 ne_ctx_pop(ctx);
1044
1045 return r;
1046 }
1047
1048 static uint64_t
ne_xiph_lace_value(unsigned char ** np)1049 ne_xiph_lace_value(unsigned char ** np)
1050 {
1051 uint64_t lace;
1052 uint64_t value;
1053 unsigned char * p = *np;
1054
1055 lace = *p++;
1056 value = lace;
1057 while (lace == 255) {
1058 lace = *p++;
1059 value += lace;
1060 }
1061
1062 *np = p;
1063
1064 return value;
1065 }
1066
1067 static int
ne_read_xiph_lace_value(nestegg_io * io,uint64_t * value,size_t * consumed)1068 ne_read_xiph_lace_value(nestegg_io * io, uint64_t * value, size_t * consumed)
1069 {
1070 int r;
1071 uint64_t lace;
1072
1073 r = ne_read_uint(io, &lace, 1);
1074 if (r != 1)
1075 return r;
1076 *consumed += 1;
1077
1078 *value = lace;
1079 while (lace == 255) {
1080 r = ne_read_uint(io, &lace, 1);
1081 if (r != 1)
1082 return r;
1083 *consumed += 1;
1084 *value += lace;
1085 }
1086
1087 return 1;
1088 }
1089
1090 static int
ne_read_xiph_lacing(nestegg_io * io,size_t block,size_t * read,uint64_t n,uint64_t * sizes)1091 ne_read_xiph_lacing(nestegg_io * io, size_t block, size_t * read, uint64_t n, uint64_t * sizes)
1092 {
1093 int r;
1094 size_t i = 0;
1095 uint64_t sum = 0;
1096
1097 while (--n) {
1098 r = ne_read_xiph_lace_value(io, &sizes[i], read);
1099 if (r != 1)
1100 return r;
1101 sum += sizes[i];
1102 i += 1;
1103 }
1104
1105 if (*read + sum > block)
1106 return -1;
1107
1108 /* last frame is the remainder of the block */
1109 sizes[i] = block - *read - sum;
1110 return 1;
1111 }
1112
1113 static int
ne_read_ebml_lacing(nestegg_io * io,size_t block,size_t * read,uint64_t n,uint64_t * sizes)1114 ne_read_ebml_lacing(nestegg_io * io, size_t block, size_t * read, uint64_t n, uint64_t * sizes)
1115 {
1116 int r;
1117 uint64_t lace, sum, length;
1118 int64_t slace;
1119 size_t i = 0;
1120
1121 r = ne_read_vint(io, &lace, &length);
1122 if (r != 1)
1123 return r;
1124 *read += length;
1125
1126 sizes[i] = lace;
1127 sum = sizes[i];
1128
1129 i += 1;
1130 n -= 1;
1131
1132 while (--n) {
1133 r = ne_read_svint(io, &slace, &length);
1134 if (r != 1)
1135 return r;
1136 *read += length;
1137 sizes[i] = sizes[i - 1] + slace;
1138 sum += sizes[i];
1139 i += 1;
1140 }
1141
1142 if (*read + sum > block)
1143 return -1;
1144
1145 /* last frame is the remainder of the block */
1146 sizes[i] = block - *read - sum;
1147 return 1;
1148 }
1149
1150 static uint64_t
ne_get_timecode_scale(nestegg * ctx)1151 ne_get_timecode_scale(nestegg * ctx)
1152 {
1153 uint64_t scale;
1154
1155 if (ne_get_uint(ctx->segment.info.timecode_scale, &scale) != 0)
1156 scale = 1000000;
1157
1158 return scale;
1159 }
1160
1161 static struct track_entry *
ne_find_track_entry(nestegg * ctx,unsigned int track)1162 ne_find_track_entry(nestegg * ctx, unsigned int track)
1163 {
1164 struct ebml_list_node * node;
1165 unsigned int tracks = 0;
1166
1167 node = ctx->segment.tracks.track_entry.head;
1168 while (node) {
1169 assert(node->id == ID_TRACK_ENTRY);
1170 if (track == tracks)
1171 return node->data;
1172 tracks += 1;
1173 node = node->next;
1174 }
1175
1176 return NULL;
1177 }
1178
1179 static int
ne_read_block(nestegg * ctx,uint64_t block_id,uint64_t block_size,nestegg_packet ** data)1180 ne_read_block(nestegg * ctx, uint64_t block_id, uint64_t block_size, nestegg_packet ** data)
1181 {
1182 int r;
1183 int64_t timecode, abs_timecode;
1184 nestegg_packet * pkt;
1185 struct cluster * cluster;
1186 struct frame * f, * last;
1187 struct track_entry * entry;
1188 double track_scale;
1189 uint64_t track, length, frame_sizes[256], cluster_tc, flags, frames, tc_scale, total;
1190 unsigned int i, lacing;
1191 size_t consumed = 0;
1192
1193 *data = NULL;
1194
1195 if (block_size > LIMIT_BLOCK)
1196 return -1;
1197
1198 r = ne_read_vint(ctx->io, &track, &length);
1199 if (r != 1)
1200 return r;
1201
1202 if (track == 0 || track > ctx->track_count)
1203 return -1;
1204
1205 consumed += length;
1206
1207 r = ne_read_int(ctx->io, &timecode, 2);
1208 if (r != 1)
1209 return r;
1210
1211 consumed += 2;
1212
1213 r = ne_read_uint(ctx->io, &flags, 1);
1214 if (r != 1)
1215 return r;
1216
1217 consumed += 1;
1218
1219 frames = 0;
1220
1221 /* flags are different between block and simpleblock, but lacing is
1222 encoded the same way */
1223 lacing = (flags & BLOCK_FLAGS_LACING) >> 1;
1224
1225 switch (lacing) {
1226 case LACING_NONE:
1227 frames = 1;
1228 break;
1229 case LACING_XIPH:
1230 case LACING_FIXED:
1231 case LACING_EBML:
1232 r = ne_read_uint(ctx->io, &frames, 1);
1233 if (r != 1)
1234 return r;
1235 consumed += 1;
1236 frames += 1;
1237 }
1238
1239 if (frames > 256)
1240 return -1;
1241
1242 switch (lacing) {
1243 case LACING_NONE:
1244 frame_sizes[0] = block_size - consumed;
1245 break;
1246 case LACING_XIPH:
1247 if (frames == 1)
1248 return -1;
1249 r = ne_read_xiph_lacing(ctx->io, block_size, &consumed, frames, frame_sizes);
1250 if (r != 1)
1251 return r;
1252 break;
1253 case LACING_FIXED:
1254 if ((block_size - consumed) % frames)
1255 return -1;
1256 for (i = 0; i < frames; ++i)
1257 frame_sizes[i] = (block_size - consumed) / frames;
1258 break;
1259 case LACING_EBML:
1260 if (frames == 1)
1261 return -1;
1262 r = ne_read_ebml_lacing(ctx->io, block_size, &consumed, frames, frame_sizes);
1263 if (r != 1)
1264 return r;
1265 break;
1266 }
1267
1268 /* sanity check unlaced frame sizes against total block size. */
1269 total = consumed;
1270 for (i = 0; i < frames; ++i)
1271 total += frame_sizes[i];
1272 if (total > block_size)
1273 return -1;
1274
1275 entry = ne_find_track_entry(ctx, track - 1);
1276 if (!entry)
1277 return -1;
1278
1279 track_scale = 1.0;
1280
1281 tc_scale = ne_get_timecode_scale(ctx);
1282
1283 assert(ctx->segment.cluster.tail->id == ID_CLUSTER);
1284 cluster = ctx->segment.cluster.tail->data;
1285 if (ne_get_uint(cluster->timecode, &cluster_tc) != 0)
1286 return -1;
1287
1288 abs_timecode = timecode + cluster_tc;
1289 if (abs_timecode < 0)
1290 return -1;
1291
1292 pkt = ne_alloc(sizeof(*pkt));
1293 pkt->track = track - 1;
1294 pkt->timecode = abs_timecode * tc_scale * track_scale;
1295
1296 ctx->log(ctx, NESTEGG_LOG_DEBUG, "%sblock t %lld pts %f f %llx frames: %llu",
1297 block_id == ID_BLOCK ? "" : "simple", pkt->track, pkt->timecode / 1e9, flags, frames);
1298
1299 last = NULL;
1300 for (i = 0; i < frames; ++i) {
1301 if (frame_sizes[i] > LIMIT_FRAME) {
1302 nestegg_free_packet(pkt);
1303 return -1;
1304 }
1305 f = ne_alloc(sizeof(*f));
1306 f->data = ne_alloc(frame_sizes[i]);
1307 f->length = frame_sizes[i];
1308 r = ne_io_read(ctx->io, f->data, frame_sizes[i]);
1309 if (r != 1) {
1310 free(f->data);
1311 free(f);
1312 nestegg_free_packet(pkt);
1313 return -1;
1314 }
1315
1316 if (!last)
1317 pkt->frame = f;
1318 else
1319 last->next = f;
1320 last = f;
1321 }
1322
1323 *data = pkt;
1324
1325 return 1;
1326 }
1327
1328 static uint64_t
ne_buf_read_id(unsigned char const * p,size_t length)1329 ne_buf_read_id(unsigned char const * p, size_t length)
1330 {
1331 uint64_t id = 0;
1332
1333 while (length--) {
1334 id <<= 8;
1335 id |= *p++;
1336 }
1337
1338 return id;
1339 }
1340
1341 static struct seek *
ne_find_seek_for_id(struct ebml_list_node * seek_head,uint64_t id)1342 ne_find_seek_for_id(struct ebml_list_node * seek_head, uint64_t id)
1343 {
1344 struct ebml_list * head;
1345 struct ebml_list_node * seek;
1346 struct ebml_binary binary_id;
1347 struct seek * s;
1348
1349 while (seek_head) {
1350 assert(seek_head->id == ID_SEEK_HEAD);
1351 head = seek_head->data;
1352 seek = head->head;
1353
1354 while (seek) {
1355 assert(seek->id == ID_SEEK);
1356 s = seek->data;
1357
1358 if (ne_get_binary(s->id, &binary_id) == 0 &&
1359 ne_buf_read_id(binary_id.data, binary_id.length) == id)
1360 return s;
1361
1362 seek = seek->next;
1363 }
1364
1365 seek_head = seek_head->next;
1366 }
1367
1368 return NULL;
1369 }
1370
1371 static struct cue_point *
ne_find_cue_point_for_tstamp(struct ebml_list_node * cue_point,uint64_t scale,uint64_t tstamp)1372 ne_find_cue_point_for_tstamp(struct ebml_list_node * cue_point, uint64_t scale, uint64_t tstamp)
1373 {
1374 uint64_t time;
1375 struct cue_point * c, * prev = NULL;
1376
1377 while (cue_point) {
1378 assert(cue_point->id == ID_CUE_POINT);
1379 c = cue_point->data;
1380
1381 if (!prev)
1382 prev = c;
1383
1384 if (ne_get_uint(c->time, &time) == 0 && time * scale > tstamp)
1385 break;
1386
1387 prev = cue_point->data;
1388 cue_point = cue_point->next;
1389 }
1390
1391 return prev;
1392 }
1393
1394 static int
ne_is_suspend_element(uint64_t id)1395 ne_is_suspend_element(uint64_t id)
1396 {
1397 /* this could search the tree of elements for DESC_FLAG_SUSPEND */
1398 if (id == ID_SIMPLE_BLOCK || id == ID_BLOCK)
1399 return 1;
1400 return 0;
1401 }
1402
1403 static void
ne_null_log_callback(nestegg * ctx,unsigned int severity,char const * fmt,...)1404 ne_null_log_callback(nestegg * ctx, unsigned int severity, char const * fmt, ...)
1405 {
1406 if (ctx && severity && fmt)
1407 return;
1408 }
1409
1410 int
nestegg_init(nestegg ** context,nestegg_io io,nestegg_log callback)1411 nestegg_init(nestegg ** context, nestegg_io io, nestegg_log callback)
1412 {
1413 int r;
1414 uint64_t id, version, docversion;
1415 struct ebml_list_node * track;
1416 char * doctype;
1417 nestegg * ctx = NULL;
1418
1419 if (!(io.read && io.seek && io.tell))
1420 return -1;
1421
1422 ctx = ne_alloc(sizeof(*ctx));
1423
1424 ctx->io = ne_alloc(sizeof(*ctx->io));
1425 *ctx->io = io;
1426 ctx->log = callback;
1427 ctx->alloc_pool = ne_pool_init();
1428
1429 if (!ctx->log)
1430 ctx->log = ne_null_log_callback;
1431
1432 r = ne_peek_element(ctx, &id, NULL);
1433 if (r != 1) {
1434 nestegg_destroy(ctx);
1435 return -1;
1436 }
1437
1438 if (id != ID_EBML) {
1439 nestegg_destroy(ctx);
1440 return -1;
1441 }
1442
1443 ctx->log(ctx, NESTEGG_LOG_DEBUG, "ctx %p", ctx);
1444
1445 ne_ctx_push(ctx, ne_top_level_elements, ctx);
1446
1447 r = ne_parse(ctx, NULL);
1448
1449 if (r != 1) {
1450 nestegg_destroy(ctx);
1451 return -1;
1452 }
1453
1454 if (ne_get_uint(ctx->ebml.ebml_read_version, &version) != 0)
1455 version = 1;
1456 if (version != 1) {
1457 nestegg_destroy(ctx);
1458 return -1;
1459 }
1460
1461 if (ne_get_string(ctx->ebml.doctype, &doctype) != 0)
1462 doctype = "matroska";
1463 if (strcmp(doctype, "webm") != 0) {
1464 nestegg_destroy(ctx);
1465 return -1;
1466 }
1467
1468 if (ne_get_uint(ctx->ebml.doctype_read_version, &docversion) != 0)
1469 docversion = 1;
1470 if (docversion < 1 || docversion > 2) {
1471 nestegg_destroy(ctx);
1472 return -1;
1473 }
1474
1475 if (!ctx->segment.tracks.track_entry.head) {
1476 nestegg_destroy(ctx);
1477 return -1;
1478 }
1479
1480 track = ctx->segment.tracks.track_entry.head;
1481 ctx->track_count = 0;
1482
1483 while (track) {
1484 ctx->track_count += 1;
1485 track = track->next;
1486 }
1487
1488 *context = ctx;
1489
1490 return 0;
1491 }
1492
1493 void
nestegg_destroy(nestegg * ctx)1494 nestegg_destroy(nestegg * ctx)
1495 {
1496 while (ctx->ancestor)
1497 ne_ctx_pop(ctx);
1498 ne_pool_destroy(ctx->alloc_pool);
1499 free(ctx->io);
1500 free(ctx);
1501 }
1502
1503 int
nestegg_duration(nestegg * ctx,uint64_t * duration)1504 nestegg_duration(nestegg * ctx, uint64_t * duration)
1505 {
1506 uint64_t tc_scale;
1507 double unscaled_duration;
1508
1509 if (ne_get_float(ctx->segment.info.duration, &unscaled_duration) != 0)
1510 return -1;
1511
1512 tc_scale = ne_get_timecode_scale(ctx);
1513
1514 *duration = (uint64_t) (unscaled_duration * tc_scale);
1515 return 0;
1516 }
1517
1518 int
nestegg_tstamp_scale(nestegg * ctx,uint64_t * scale)1519 nestegg_tstamp_scale(nestegg * ctx, uint64_t * scale)
1520 {
1521 *scale = ne_get_timecode_scale(ctx);
1522 return 0;
1523 }
1524
1525 int
nestegg_track_count(nestegg * ctx,unsigned int * tracks)1526 nestegg_track_count(nestegg * ctx, unsigned int * tracks)
1527 {
1528 *tracks = ctx->track_count;
1529 return 0;
1530 }
1531
1532 int
nestegg_track_seek(nestegg * ctx,unsigned int track,uint64_t tstamp)1533 nestegg_track_seek(nestegg * ctx, unsigned int track, uint64_t tstamp)
1534 {
1535 int r;
1536 struct cue_point * cue_point;
1537 struct cue_track_positions * pos;
1538 struct saved_state state;
1539 struct seek * found;
1540 uint64_t seek_pos, tc_scale, t, id;
1541 struct ebml_list_node * node = ctx->segment.cues.cue_point.head;
1542
1543 /* If there are no cues loaded, check for cues element in the seek head
1544 and load it. */
1545 if (!node) {
1546 found = ne_find_seek_for_id(ctx->segment.seek_head.head, ID_CUES);
1547 if (!found)
1548 return -1;
1549
1550 if (ne_get_uint(found->position, &seek_pos) != 0)
1551 return -1;
1552
1553 /* Save old parser state. */
1554 r = ne_ctx_save(ctx, &state);
1555 if (r != 0)
1556 return -1;
1557
1558 /* Seek and set up parser state for segment-level element (Cues). */
1559 r = ne_io_seek(ctx->io, ctx->segment_offset + seek_pos, NESTEGG_SEEK_SET);
1560 if (r != 0)
1561 return -1;
1562 ctx->last_id = 0;
1563 ctx->last_size = 0;
1564
1565 r = ne_read_element(ctx, &id, NULL);
1566 if (r != 1)
1567 return -1;
1568
1569 if (id != ID_CUES)
1570 return -1;
1571
1572 ctx->ancestor = NULL;
1573 ne_ctx_push(ctx, ne_top_level_elements, ctx);
1574 ne_ctx_push(ctx, ne_segment_elements, &ctx->segment);
1575 ne_ctx_push(ctx, ne_cues_elements, &ctx->segment.cues);
1576 /* parser will run until end of cues element. */
1577 ctx->log(ctx, NESTEGG_LOG_DEBUG, "seek: parsing cue elements");
1578 r = ne_parse(ctx, ne_cues_elements);
1579 while (ctx->ancestor)
1580 ne_ctx_pop(ctx);
1581
1582 /* Reset parser state to original state and seek back to old position. */
1583 if (ne_ctx_restore(ctx, &state) != 0)
1584 return -1;
1585
1586 if (r < 0)
1587 return -1;
1588 }
1589
1590 tc_scale = ne_get_timecode_scale(ctx);
1591
1592 cue_point = ne_find_cue_point_for_tstamp(ctx->segment.cues.cue_point.head, tc_scale, tstamp);
1593 if (!cue_point)
1594 return -1;
1595
1596 node = cue_point->cue_track_positions.head;
1597
1598 seek_pos = 0;
1599
1600 while (node) {
1601 assert(node->id == ID_CUE_TRACK_POSITIONS);
1602 pos = node->data;
1603 if (ne_get_uint(pos->track, &t) == 0 && t - 1 == track) {
1604 if (ne_get_uint(pos->cluster_position, &seek_pos) != 0)
1605 return -1;
1606 break;
1607 }
1608 node = node->next;
1609 }
1610
1611 /* Seek and set up parser state for segment-level element (Cluster). */
1612 r = ne_io_seek(ctx->io, ctx->segment_offset + seek_pos, NESTEGG_SEEK_SET);
1613 if (r != 0)
1614 return -1;
1615 ctx->last_id = 0;
1616 ctx->last_size = 0;
1617
1618 while (ctx->ancestor)
1619 ne_ctx_pop(ctx);
1620
1621 ne_ctx_push(ctx, ne_top_level_elements, ctx);
1622 ne_ctx_push(ctx, ne_segment_elements, &ctx->segment);
1623 ctx->log(ctx, NESTEGG_LOG_DEBUG, "seek: parsing cluster elements");
1624 r = ne_parse(ctx, NULL);
1625 if (r != 1)
1626 return -1;
1627
1628 if (!ne_is_suspend_element(ctx->last_id))
1629 return -1;
1630
1631 return 0;
1632 }
1633
1634 int
nestegg_track_type(nestegg * ctx,unsigned int track)1635 nestegg_track_type(nestegg * ctx, unsigned int track)
1636 {
1637 struct track_entry * entry;
1638 uint64_t type;
1639
1640 entry = ne_find_track_entry(ctx, track);
1641 if (!entry)
1642 return -1;
1643
1644 if (ne_get_uint(entry->type, &type) != 0)
1645 return -1;
1646
1647 if (type & TRACK_TYPE_VIDEO)
1648 return NESTEGG_TRACK_VIDEO;
1649
1650 if (type & TRACK_TYPE_AUDIO)
1651 return NESTEGG_TRACK_AUDIO;
1652
1653 return -1;
1654 }
1655
1656 int
nestegg_track_codec_id(nestegg * ctx,unsigned int track)1657 nestegg_track_codec_id(nestegg * ctx, unsigned int track)
1658 {
1659 char * codec_id;
1660 struct track_entry * entry;
1661
1662 entry = ne_find_track_entry(ctx, track);
1663 if (!entry)
1664 return -1;
1665
1666 if (ne_get_string(entry->codec_id, &codec_id) != 0)
1667 return -1;
1668
1669 if (strcmp(codec_id, TRACK_ID_VP8) == 0)
1670 return NESTEGG_CODEC_VP8;
1671
1672 if (strcmp(codec_id, TRACK_ID_VORBIS) == 0)
1673 return NESTEGG_CODEC_VORBIS;
1674
1675 return -1;
1676 }
1677
1678 int
nestegg_track_codec_data_count(nestegg * ctx,unsigned int track,unsigned int * count)1679 nestegg_track_codec_data_count(nestegg * ctx, unsigned int track,
1680 unsigned int * count)
1681 {
1682 struct track_entry * entry;
1683 struct ebml_binary codec_private;
1684 unsigned char * p;
1685
1686 *count = 0;
1687
1688 entry = ne_find_track_entry(ctx, track);
1689 if (!entry)
1690 return -1;
1691
1692 if (nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_VORBIS)
1693 return -1;
1694
1695 if (ne_get_binary(entry->codec_private, &codec_private) != 0)
1696 return -1;
1697
1698 if (codec_private.length < 1)
1699 return -1;
1700
1701 p = codec_private.data;
1702 *count = *p + 1;
1703
1704 if (*count > 3)
1705 return -1;
1706
1707 return 0;
1708 }
1709
1710 int
nestegg_track_codec_data(nestegg * ctx,unsigned int track,unsigned int item,unsigned char ** data,size_t * length)1711 nestegg_track_codec_data(nestegg * ctx, unsigned int track, unsigned int item,
1712 unsigned char ** data, size_t * length)
1713 {
1714 struct track_entry * entry;
1715 struct ebml_binary codec_private;
1716 uint64_t sizes[3], total;
1717 unsigned char * p;
1718 unsigned int count, i;
1719
1720 *data = NULL;
1721 *length = 0;
1722
1723 entry = ne_find_track_entry(ctx, track);
1724 if (!entry)
1725 return -1;
1726
1727 if (nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_VORBIS)
1728 return -1;
1729
1730 if (ne_get_binary(entry->codec_private, &codec_private) != 0)
1731 return -1;
1732
1733 p = codec_private.data;
1734 count = *p++ + 1;
1735
1736 if (count > 3)
1737 return -1;
1738
1739 i = 0;
1740 total = 0;
1741 while (--count) {
1742 sizes[i] = ne_xiph_lace_value(&p);
1743 total += sizes[i];
1744 i += 1;
1745 }
1746 sizes[i] = codec_private.length - total - (p - codec_private.data);
1747
1748 for (i = 0; i < item; ++i) {
1749 if (sizes[i] > LIMIT_FRAME)
1750 return -1;
1751 p += sizes[i];
1752 }
1753 *data = p;
1754 *length = sizes[item];
1755
1756 return 0;
1757 }
1758
1759 int
nestegg_track_video_params(nestegg * ctx,unsigned int track,nestegg_video_params * params)1760 nestegg_track_video_params(nestegg * ctx, unsigned int track,
1761 nestegg_video_params * params)
1762 {
1763 struct track_entry * entry;
1764 uint64_t value;
1765
1766 memset(params, 0, sizeof(*params));
1767
1768 entry = ne_find_track_entry(ctx, track);
1769 if (!entry)
1770 return -1;
1771
1772 if (nestegg_track_type(ctx, track) != NESTEGG_TRACK_VIDEO)
1773 return -1;
1774
1775 if (ne_get_uint(entry->video.pixel_width, &value) != 0)
1776 return -1;
1777 params->width = value;
1778
1779 if (ne_get_uint(entry->video.pixel_height, &value) != 0)
1780 return -1;
1781 params->height = value;
1782
1783 value = 0;
1784 ne_get_uint(entry->video.pixel_crop_bottom, &value);
1785 params->crop_bottom = value;
1786
1787 value = 0;
1788 ne_get_uint(entry->video.pixel_crop_top, &value);
1789 params->crop_top = value;
1790
1791 value = 0;
1792 ne_get_uint(entry->video.pixel_crop_left, &value);
1793 params->crop_left = value;
1794
1795 value = 0;
1796 ne_get_uint(entry->video.pixel_crop_right, &value);
1797 params->crop_right = value;
1798
1799 value = params->width;
1800 ne_get_uint(entry->video.display_width, &value);
1801 params->display_width = value;
1802
1803 value = params->height;
1804 ne_get_uint(entry->video.display_height, &value);
1805 params->display_height = value;
1806
1807 return 0;
1808 }
1809
1810 int
nestegg_track_audio_params(nestegg * ctx,unsigned int track,nestegg_audio_params * params)1811 nestegg_track_audio_params(nestegg * ctx, unsigned int track,
1812 nestegg_audio_params * params)
1813 {
1814 struct track_entry * entry;
1815 uint64_t value;
1816
1817 memset(params, 0, sizeof(*params));
1818
1819 entry = ne_find_track_entry(ctx, track);
1820 if (!entry)
1821 return -1;
1822
1823 if (nestegg_track_type(ctx, track) != NESTEGG_TRACK_AUDIO)
1824 return -1;
1825
1826 params->rate = 8000;
1827 ne_get_float(entry->audio.sampling_frequency, ¶ms->rate);
1828
1829 value = 1;
1830 ne_get_uint(entry->audio.channels, &value);
1831 params->channels = value;
1832
1833 value = 16;
1834 ne_get_uint(entry->audio.bit_depth, &value);
1835 params->depth = value;
1836
1837 return 0;
1838 }
1839
1840 int
nestegg_read_packet(nestegg * ctx,nestegg_packet ** pkt)1841 nestegg_read_packet(nestegg * ctx, nestegg_packet ** pkt)
1842 {
1843 int r;
1844 uint64_t id, size;
1845
1846 *pkt = NULL;
1847
1848 for (;;) {
1849 r = ne_peek_element(ctx, &id, &size);
1850 if (r != 1)
1851 return r;
1852
1853 /* any suspend fields must be handled here */
1854 if (ne_is_suspend_element(id)) {
1855 r = ne_read_element(ctx, &id, &size);
1856 if (r != 1)
1857 return r;
1858
1859 /* the only suspend fields are blocks and simple blocks, which we
1860 handle directly. */
1861 r = ne_read_block(ctx, id, size, pkt);
1862 return r;
1863 }
1864
1865 r = ne_parse(ctx, NULL);
1866 if (r != 1)
1867 return r;
1868 }
1869
1870 return 1;
1871 }
1872
1873 void
nestegg_free_packet(nestegg_packet * pkt)1874 nestegg_free_packet(nestegg_packet * pkt)
1875 {
1876 struct frame * frame;
1877
1878 while (pkt->frame) {
1879 frame = pkt->frame;
1880 pkt->frame = frame->next;
1881 free(frame->data);
1882 free(frame);
1883 }
1884
1885 free(pkt);
1886 }
1887
1888 int
nestegg_packet_track(nestegg_packet * pkt,unsigned int * track)1889 nestegg_packet_track(nestegg_packet * pkt, unsigned int * track)
1890 {
1891 *track = pkt->track;
1892 return 0;
1893 }
1894
1895 int
nestegg_packet_tstamp(nestegg_packet * pkt,uint64_t * tstamp)1896 nestegg_packet_tstamp(nestegg_packet * pkt, uint64_t * tstamp)
1897 {
1898 *tstamp = pkt->timecode;
1899 return 0;
1900 }
1901
1902 int
nestegg_packet_count(nestegg_packet * pkt,unsigned int * count)1903 nestegg_packet_count(nestegg_packet * pkt, unsigned int * count)
1904 {
1905 struct frame * f = pkt->frame;
1906
1907 *count = 0;
1908
1909 while (f) {
1910 *count += 1;
1911 f = f->next;
1912 }
1913
1914 return 0;
1915 }
1916
1917 int
nestegg_packet_data(nestegg_packet * pkt,unsigned int item,unsigned char ** data,size_t * length)1918 nestegg_packet_data(nestegg_packet * pkt, unsigned int item,
1919 unsigned char ** data, size_t * length)
1920 {
1921 struct frame * f = pkt->frame;
1922 unsigned int count = 0;
1923
1924 *data = NULL;
1925 *length = 0;
1926
1927 while (f) {
1928 if (count == item) {
1929 *data = f->data;
1930 *length = f->length;
1931 return 0;
1932 }
1933 count += 1;
1934 f = f->next;
1935 }
1936
1937 return -1;
1938 }
1939