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