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