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