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