Line data Source code
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 <stddef.h>
9 : #include <stdlib.h>
10 : #include <string.h>
11 :
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 : /* WebM Elements */
29 : #define ID_SEGMENT 0x18538067
30 :
31 : /* Seek Head Elements */
32 : #define ID_SEEK_HEAD 0x114d9b74
33 : #define ID_SEEK 0x4dbb
34 : #define ID_SEEK_ID 0x53ab
35 : #define ID_SEEK_POSITION 0x53ac
36 :
37 : /* Info Elements */
38 : #define ID_INFO 0x1549a966
39 : #define ID_TIMECODE_SCALE 0x2ad7b1
40 : #define ID_DURATION 0x4489
41 :
42 : /* Cluster Elements */
43 : #define ID_CLUSTER 0x1f43b675
44 : #define ID_TIMECODE 0xe7
45 : #define ID_BLOCK_GROUP 0xa0
46 : #define ID_SIMPLE_BLOCK 0xa3
47 :
48 : /* BlockGroup Elements */
49 : #define ID_BLOCK 0xa1
50 : #define ID_BLOCK_ADDITIONS 0x75a1
51 : #define ID_BLOCK_DURATION 0x9b
52 : #define ID_REFERENCE_BLOCK 0xfb
53 : #define ID_DISCARD_PADDING 0x75a2
54 :
55 : /* BlockAdditions Elements */
56 : #define ID_BLOCK_MORE 0xa6
57 :
58 : /* BlockMore Elements */
59 : #define ID_BLOCK_ADD_ID 0xee
60 : #define ID_BLOCK_ADDITIONAL 0xa5
61 :
62 : /* Tracks Elements */
63 : #define ID_TRACKS 0x1654ae6b
64 : #define ID_TRACK_ENTRY 0xae
65 : #define ID_TRACK_NUMBER 0xd7
66 : #define ID_TRACK_UID 0x73c5
67 : #define ID_TRACK_TYPE 0x83
68 : #define ID_FLAG_ENABLED 0xb9
69 : #define ID_FLAG_DEFAULT 0x88
70 : #define ID_FLAG_LACING 0x9c
71 : #define ID_TRACK_TIMECODE_SCALE 0x23314f
72 : #define ID_LANGUAGE 0x22b59c
73 : #define ID_CODEC_ID 0x86
74 : #define ID_CODEC_PRIVATE 0x63a2
75 : #define ID_CODEC_DELAY 0x56aa
76 : #define ID_SEEK_PREROLL 0x56bb
77 : #define ID_DEFAULT_DURATION 0x23e383
78 :
79 : /* Video Elements */
80 : #define ID_VIDEO 0xe0
81 : #define ID_STEREO_MODE 0x53b8
82 : #define ID_ALPHA_MODE 0x53c0
83 : #define ID_PIXEL_WIDTH 0xb0
84 : #define ID_PIXEL_HEIGHT 0xba
85 : #define ID_PIXEL_CROP_BOTTOM 0x54aa
86 : #define ID_PIXEL_CROP_TOP 0x54bb
87 : #define ID_PIXEL_CROP_LEFT 0x54cc
88 : #define ID_PIXEL_CROP_RIGHT 0x54dd
89 : #define ID_DISPLAY_WIDTH 0x54b0
90 : #define ID_DISPLAY_HEIGHT 0x54ba
91 :
92 : /* Audio Elements */
93 : #define ID_AUDIO 0xe1
94 : #define ID_SAMPLING_FREQUENCY 0xb5
95 : #define ID_CHANNELS 0x9f
96 : #define ID_BIT_DEPTH 0x6264
97 :
98 : /* Cues Elements */
99 : #define ID_CUES 0x1c53bb6b
100 : #define ID_CUE_POINT 0xbb
101 : #define ID_CUE_TIME 0xb3
102 : #define ID_CUE_TRACK_POSITIONS 0xb7
103 : #define ID_CUE_TRACK 0xf7
104 : #define ID_CUE_CLUSTER_POSITION 0xf1
105 : #define ID_CUE_BLOCK_NUMBER 0x5378
106 :
107 : /* Encoding Elements */
108 : #define ID_CONTENT_ENCODINGS 0x6d80
109 : #define ID_CONTENT_ENCODING 0x6240
110 : #define ID_CONTENT_ENCODING_TYPE 0x5033
111 :
112 : /* Encryption Elements */
113 : #define ID_CONTENT_ENCRYPTION 0x5035
114 : #define ID_CONTENT_ENC_ALGO 0x47e1
115 : #define ID_CONTENT_ENC_KEY_ID 0x47e2
116 : #define ID_CONTENT_ENC_AES_SETTINGS 0x47e7
117 : #define ID_AES_SETTINGS_CIPHER_MODE 0x47e8
118 :
119 : /* EBML Types */
120 : enum ebml_type_enum {
121 : TYPE_UNKNOWN,
122 : TYPE_MASTER,
123 : TYPE_UINT,
124 : TYPE_FLOAT,
125 : TYPE_STRING,
126 : TYPE_BINARY
127 : };
128 :
129 : #define LIMIT_STRING (1 << 20)
130 : #define LIMIT_BINARY (1 << 24)
131 : #define LIMIT_BLOCK (1 << 30)
132 : #define LIMIT_FRAME (1 << 28)
133 :
134 : /* Field Flags */
135 : #define DESC_FLAG_NONE 0
136 : #define DESC_FLAG_MULTI (1 << 0)
137 : #define DESC_FLAG_SUSPEND (1 << 1)
138 : #define DESC_FLAG_OFFSET (1 << 2)
139 :
140 : /* Block Header Flags */
141 : #define SIMPLE_BLOCK_FLAGS_KEYFRAME (1 << 7)
142 : #define BLOCK_FLAGS_LACING 6
143 :
144 : /* Lacing Constants */
145 : #define LACING_NONE 0
146 : #define LACING_XIPH 1
147 : #define LACING_FIXED 2
148 : #define LACING_EBML 3
149 :
150 : /* Track Types */
151 : #define TRACK_TYPE_VIDEO 1
152 : #define TRACK_TYPE_AUDIO 2
153 :
154 : /* Track IDs */
155 : #define TRACK_ID_VP8 "V_VP8"
156 : #define TRACK_ID_VP9 "V_VP9"
157 : #define TRACK_ID_AV1 "V_AV1"
158 : #define TRACK_ID_VORBIS "A_VORBIS"
159 : #define TRACK_ID_OPUS "A_OPUS"
160 :
161 : /* Track Encryption */
162 : #define CONTENT_ENC_ALGO_AES 5
163 : #define AES_SETTINGS_CIPHER_CTR 1
164 :
165 : /* Packet Encryption */
166 : #define SIGNAL_BYTE_SIZE 1
167 : #define IV_SIZE 8
168 : #define NUM_PACKETS_SIZE 1
169 : #define PACKET_OFFSET_SIZE 4
170 :
171 : /* Signal Byte */
172 : #define PACKET_ENCRYPTED 1
173 : #define ENCRYPTED_BIT_MASK (1 << 0)
174 :
175 : #define PACKET_PARTITIONED 2
176 : #define PARTITIONED_BIT_MASK (1 << 1)
177 :
178 : enum vint_mask {
179 : MASK_NONE,
180 : MASK_FIRST_BIT
181 : };
182 :
183 : struct ebml_binary {
184 : unsigned char * data;
185 : size_t length;
186 : };
187 :
188 : struct ebml_list_node {
189 : struct ebml_list_node * next;
190 : uint64_t id;
191 : void * data;
192 : };
193 :
194 : struct ebml_list {
195 : struct ebml_list_node * head;
196 : struct ebml_list_node * tail;
197 : };
198 :
199 : struct ebml_type {
200 : union ebml_value {
201 : uint64_t u;
202 : double f;
203 : int64_t i;
204 : char * s;
205 : struct ebml_binary b;
206 : } v;
207 : enum ebml_type_enum type;
208 : int read;
209 : };
210 :
211 : /* EBML Definitions */
212 : struct ebml {
213 : struct ebml_type ebml_version;
214 : struct ebml_type ebml_read_version;
215 : struct ebml_type ebml_max_id_length;
216 : struct ebml_type ebml_max_size_length;
217 : struct ebml_type doctype;
218 : struct ebml_type doctype_version;
219 : struct ebml_type doctype_read_version;
220 : };
221 :
222 : /* Matroksa Definitions */
223 : struct seek {
224 : struct ebml_type id;
225 : struct ebml_type position;
226 : };
227 :
228 : struct seek_head {
229 : struct ebml_list seek;
230 : };
231 :
232 : struct info {
233 : struct ebml_type timecode_scale;
234 : struct ebml_type duration;
235 : };
236 :
237 : struct video {
238 : struct ebml_type stereo_mode;
239 : struct ebml_type alpha_mode;
240 : struct ebml_type pixel_width;
241 : struct ebml_type pixel_height;
242 : struct ebml_type pixel_crop_bottom;
243 : struct ebml_type pixel_crop_top;
244 : struct ebml_type pixel_crop_left;
245 : struct ebml_type pixel_crop_right;
246 : struct ebml_type display_width;
247 : struct ebml_type display_height;
248 : };
249 :
250 : struct audio {
251 : struct ebml_type sampling_frequency;
252 : struct ebml_type channels;
253 : struct ebml_type bit_depth;
254 : };
255 :
256 : struct content_enc_aes_settings {
257 : struct ebml_type aes_settings_cipher_mode;
258 : };
259 :
260 : struct content_encryption {
261 : struct ebml_type content_enc_algo;
262 : struct ebml_type content_enc_key_id;
263 : struct ebml_list content_enc_aes_settings;
264 : };
265 :
266 : struct content_encoding {
267 : struct ebml_type content_encoding_type;
268 : struct ebml_list content_encryption;
269 : };
270 :
271 : struct content_encodings {
272 : struct ebml_list content_encoding;
273 : };
274 :
275 : struct track_entry {
276 : struct ebml_type number;
277 : struct ebml_type uid;
278 : struct ebml_type type;
279 : struct ebml_type flag_enabled;
280 : struct ebml_type flag_default;
281 : struct ebml_type flag_lacing;
282 : struct ebml_type track_timecode_scale;
283 : struct ebml_type language;
284 : struct ebml_type codec_id;
285 : struct ebml_type codec_private;
286 : struct ebml_type codec_delay;
287 : struct ebml_type seek_preroll;
288 : struct ebml_type default_duration;
289 : struct video video;
290 : struct audio audio;
291 : struct content_encodings content_encodings;
292 : };
293 :
294 : struct tracks {
295 : struct ebml_list track_entry;
296 : };
297 :
298 : struct cue_track_positions {
299 : struct ebml_type track;
300 : struct ebml_type cluster_position;
301 : struct ebml_type block_number;
302 : };
303 :
304 : struct cue_point {
305 : struct ebml_type time;
306 : struct ebml_list cue_track_positions;
307 : };
308 :
309 : struct cues {
310 : struct ebml_list cue_point;
311 : };
312 :
313 : struct segment {
314 : struct ebml_list seek_head;
315 : struct info info;
316 : struct tracks tracks;
317 : struct cues cues;
318 : };
319 :
320 : /* Misc. */
321 : struct pool_node {
322 : struct pool_node * next;
323 : void * data;
324 : };
325 :
326 : struct pool_ctx {
327 : struct pool_node * head;
328 : };
329 :
330 : struct list_node {
331 : struct list_node * previous;
332 : struct ebml_element_desc * node;
333 : unsigned char * data;
334 : };
335 :
336 : struct saved_state {
337 : int64_t stream_offset;
338 : uint64_t last_id;
339 : uint64_t last_size;
340 : int last_valid;
341 : };
342 :
343 : struct frame_encryption {
344 : unsigned char * iv;
345 : size_t length;
346 : uint8_t signal_byte;
347 : uint8_t num_partitions;
348 : uint32_t * partition_offsets;
349 : };
350 :
351 : struct frame {
352 : unsigned char * data;
353 : size_t length;
354 : struct frame_encryption * frame_encryption;
355 : struct frame * next;
356 : };
357 :
358 : struct block_additional {
359 : unsigned int id;
360 : unsigned char * data;
361 : size_t length;
362 : struct block_additional * next;
363 : };
364 :
365 : /* Public (opaque) Structures */
366 : struct nestegg {
367 : nestegg_io * io;
368 : nestegg_log log;
369 : struct pool_ctx * alloc_pool;
370 : uint64_t last_id;
371 : uint64_t last_size;
372 : int last_valid;
373 : struct list_node * ancestor;
374 : struct ebml ebml;
375 : struct segment segment;
376 : int64_t segment_offset;
377 : unsigned int track_count;
378 : /* Last read cluster. */
379 : uint64_t cluster_timecode;
380 : int read_cluster_timecode;
381 : struct saved_state saved;
382 : };
383 :
384 : struct nestegg_packet {
385 : uint64_t track;
386 : uint64_t timecode;
387 : uint64_t duration;
388 : int read_duration;
389 : struct frame * frame;
390 : struct block_additional * block_additional;
391 : int64_t discard_padding;
392 : int read_discard_padding;
393 : int64_t reference_block;
394 : int read_reference_block;
395 : uint8_t keyframe;
396 : };
397 :
398 : /* Element Descriptor */
399 : struct ebml_element_desc {
400 : char const * name;
401 : uint64_t id;
402 : enum ebml_type_enum type;
403 : size_t offset;
404 : unsigned int flags;
405 : struct ebml_element_desc * children;
406 : size_t size;
407 : size_t data_offset;
408 : };
409 :
410 : #define E_FIELD(ID, TYPE, STRUCT, FIELD) \
411 : { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_NONE, NULL, 0, 0 }
412 : #define E_MASTER(ID, TYPE, STRUCT, FIELD) \
413 : { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_MULTI, ne_ ## FIELD ## _elements, \
414 : sizeof(struct FIELD), 0 }
415 : #define E_SINGLE_MASTER_O(ID, TYPE, STRUCT, FIELD) \
416 : { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_OFFSET, ne_ ## FIELD ## _elements, 0, \
417 : offsetof(STRUCT, FIELD ## _offset) }
418 : #define E_SINGLE_MASTER(ID, TYPE, STRUCT, FIELD) \
419 : { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_NONE, ne_ ## FIELD ## _elements, 0, 0 }
420 : #define E_SUSPEND(ID, TYPE) \
421 : { #ID, ID, TYPE, 0, DESC_FLAG_SUSPEND, NULL, 0, 0 }
422 : #define E_LAST \
423 : { NULL, 0, 0, 0, DESC_FLAG_NONE, NULL, 0, 0 }
424 :
425 : /* EBML Element Lists */
426 : static struct ebml_element_desc ne_ebml_elements[] = {
427 : E_FIELD(ID_EBML_VERSION, TYPE_UINT, struct ebml, ebml_version),
428 : E_FIELD(ID_EBML_READ_VERSION, TYPE_UINT, struct ebml, ebml_read_version),
429 : E_FIELD(ID_EBML_MAX_ID_LENGTH, TYPE_UINT, struct ebml, ebml_max_id_length),
430 : E_FIELD(ID_EBML_MAX_SIZE_LENGTH, TYPE_UINT, struct ebml, ebml_max_size_length),
431 : E_FIELD(ID_DOCTYPE, TYPE_STRING, struct ebml, doctype),
432 : E_FIELD(ID_DOCTYPE_VERSION, TYPE_UINT, struct ebml, doctype_version),
433 : E_FIELD(ID_DOCTYPE_READ_VERSION, TYPE_UINT, struct ebml, doctype_read_version),
434 : E_LAST
435 : };
436 :
437 : /* WebM Element Lists */
438 : static struct ebml_element_desc ne_seek_elements[] = {
439 : E_FIELD(ID_SEEK_ID, TYPE_BINARY, struct seek, id),
440 : E_FIELD(ID_SEEK_POSITION, TYPE_UINT, struct seek, position),
441 : E_LAST
442 : };
443 :
444 : static struct ebml_element_desc ne_seek_head_elements[] = {
445 : E_MASTER(ID_SEEK, TYPE_MASTER, struct seek_head, seek),
446 : E_LAST
447 : };
448 :
449 : static struct ebml_element_desc ne_info_elements[] = {
450 : E_FIELD(ID_TIMECODE_SCALE, TYPE_UINT, struct info, timecode_scale),
451 : E_FIELD(ID_DURATION, TYPE_FLOAT, struct info, duration),
452 : E_LAST
453 : };
454 :
455 : static struct ebml_element_desc ne_video_elements[] = {
456 : E_FIELD(ID_STEREO_MODE, TYPE_UINT, struct video, stereo_mode),
457 : E_FIELD(ID_ALPHA_MODE, TYPE_UINT, struct video, alpha_mode),
458 : E_FIELD(ID_PIXEL_WIDTH, TYPE_UINT, struct video, pixel_width),
459 : E_FIELD(ID_PIXEL_HEIGHT, TYPE_UINT, struct video, pixel_height),
460 : E_FIELD(ID_PIXEL_CROP_BOTTOM, TYPE_UINT, struct video, pixel_crop_bottom),
461 : E_FIELD(ID_PIXEL_CROP_TOP, TYPE_UINT, struct video, pixel_crop_top),
462 : E_FIELD(ID_PIXEL_CROP_LEFT, TYPE_UINT, struct video, pixel_crop_left),
463 : E_FIELD(ID_PIXEL_CROP_RIGHT, TYPE_UINT, struct video, pixel_crop_right),
464 : E_FIELD(ID_DISPLAY_WIDTH, TYPE_UINT, struct video, display_width),
465 : E_FIELD(ID_DISPLAY_HEIGHT, TYPE_UINT, struct video, display_height),
466 : E_LAST
467 : };
468 :
469 : static struct ebml_element_desc ne_audio_elements[] = {
470 : E_FIELD(ID_SAMPLING_FREQUENCY, TYPE_FLOAT, struct audio, sampling_frequency),
471 : E_FIELD(ID_CHANNELS, TYPE_UINT, struct audio, channels),
472 : E_FIELD(ID_BIT_DEPTH, TYPE_UINT, struct audio, bit_depth),
473 : E_LAST
474 : };
475 :
476 : static struct ebml_element_desc ne_content_enc_aes_settings_elements[] = {
477 : E_FIELD(ID_AES_SETTINGS_CIPHER_MODE, TYPE_UINT, struct content_enc_aes_settings, aes_settings_cipher_mode),
478 : E_LAST
479 : };
480 :
481 : static struct ebml_element_desc ne_content_encryption_elements[] = {
482 : E_FIELD(ID_CONTENT_ENC_ALGO, TYPE_UINT, struct content_encryption, content_enc_algo),
483 : E_FIELD(ID_CONTENT_ENC_KEY_ID, TYPE_BINARY, struct content_encryption, content_enc_key_id),
484 : E_MASTER(ID_CONTENT_ENC_AES_SETTINGS, TYPE_MASTER, struct content_encryption, content_enc_aes_settings),
485 : E_LAST
486 : };
487 :
488 : static struct ebml_element_desc ne_content_encoding_elements[] = {
489 : E_FIELD(ID_CONTENT_ENCODING_TYPE, TYPE_UINT, struct content_encoding, content_encoding_type),
490 : E_MASTER(ID_CONTENT_ENCRYPTION, TYPE_MASTER, struct content_encoding, content_encryption),
491 : E_LAST
492 : };
493 :
494 : static struct ebml_element_desc ne_content_encodings_elements[] = {
495 : E_MASTER(ID_CONTENT_ENCODING, TYPE_MASTER, struct content_encodings, content_encoding),
496 : E_LAST
497 : };
498 :
499 : static struct ebml_element_desc ne_track_entry_elements[] = {
500 : E_FIELD(ID_TRACK_NUMBER, TYPE_UINT, struct track_entry, number),
501 : E_FIELD(ID_TRACK_UID, TYPE_UINT, struct track_entry, uid),
502 : E_FIELD(ID_TRACK_TYPE, TYPE_UINT, struct track_entry, type),
503 : E_FIELD(ID_FLAG_ENABLED, TYPE_UINT, struct track_entry, flag_enabled),
504 : E_FIELD(ID_FLAG_DEFAULT, TYPE_UINT, struct track_entry, flag_default),
505 : E_FIELD(ID_FLAG_LACING, TYPE_UINT, struct track_entry, flag_lacing),
506 : E_FIELD(ID_TRACK_TIMECODE_SCALE, TYPE_FLOAT, struct track_entry, track_timecode_scale),
507 : E_FIELD(ID_LANGUAGE, TYPE_STRING, struct track_entry, language),
508 : E_FIELD(ID_CODEC_ID, TYPE_STRING, struct track_entry, codec_id),
509 : E_FIELD(ID_CODEC_PRIVATE, TYPE_BINARY, struct track_entry, codec_private),
510 : E_FIELD(ID_CODEC_DELAY, TYPE_UINT, struct track_entry, codec_delay),
511 : E_FIELD(ID_SEEK_PREROLL, TYPE_UINT, struct track_entry, seek_preroll),
512 : E_FIELD(ID_DEFAULT_DURATION, TYPE_UINT, struct track_entry, default_duration),
513 : E_SINGLE_MASTER(ID_VIDEO, TYPE_MASTER, struct track_entry, video),
514 : E_SINGLE_MASTER(ID_AUDIO, TYPE_MASTER, struct track_entry, audio),
515 : E_SINGLE_MASTER(ID_CONTENT_ENCODINGS, TYPE_MASTER, struct track_entry, content_encodings),
516 : E_LAST
517 : };
518 :
519 : static struct ebml_element_desc ne_tracks_elements[] = {
520 : E_MASTER(ID_TRACK_ENTRY, TYPE_MASTER, struct tracks, track_entry),
521 : E_LAST
522 : };
523 :
524 : static struct ebml_element_desc ne_cue_track_positions_elements[] = {
525 : E_FIELD(ID_CUE_TRACK, TYPE_UINT, struct cue_track_positions, track),
526 : E_FIELD(ID_CUE_CLUSTER_POSITION, TYPE_UINT, struct cue_track_positions, cluster_position),
527 : E_FIELD(ID_CUE_BLOCK_NUMBER, TYPE_UINT, struct cue_track_positions, block_number),
528 : E_LAST
529 : };
530 :
531 : static struct ebml_element_desc ne_cue_point_elements[] = {
532 : E_FIELD(ID_CUE_TIME, TYPE_UINT, struct cue_point, time),
533 : E_MASTER(ID_CUE_TRACK_POSITIONS, TYPE_MASTER, struct cue_point, cue_track_positions),
534 : E_LAST
535 : };
536 :
537 : static struct ebml_element_desc ne_cues_elements[] = {
538 : E_MASTER(ID_CUE_POINT, TYPE_MASTER, struct cues, cue_point),
539 : E_LAST
540 : };
541 :
542 : static struct ebml_element_desc ne_segment_elements[] = {
543 : E_MASTER(ID_SEEK_HEAD, TYPE_MASTER, struct segment, seek_head),
544 : E_SINGLE_MASTER(ID_INFO, TYPE_MASTER, struct segment, info),
545 : E_SUSPEND(ID_CLUSTER, TYPE_MASTER),
546 : E_SINGLE_MASTER(ID_TRACKS, TYPE_MASTER, struct segment, tracks),
547 : E_SINGLE_MASTER(ID_CUES, TYPE_MASTER, struct segment, cues),
548 : E_LAST
549 : };
550 :
551 : static struct ebml_element_desc ne_top_level_elements[] = {
552 : E_SINGLE_MASTER(ID_EBML, TYPE_MASTER, nestegg, ebml),
553 : E_SINGLE_MASTER_O(ID_SEGMENT, TYPE_MASTER, nestegg, segment),
554 : E_LAST
555 : };
556 :
557 : #undef E_FIELD
558 : #undef E_MASTER
559 : #undef E_SINGLE_MASTER_O
560 : #undef E_SINGLE_MASTER
561 : #undef E_SUSPEND
562 : #undef E_LAST
563 :
564 : static struct pool_ctx *
565 0 : ne_pool_init(void)
566 : {
567 0 : return calloc(1, sizeof(struct pool_ctx));
568 : }
569 :
570 : static void
571 0 : ne_pool_destroy(struct pool_ctx * pool)
572 : {
573 0 : struct pool_node * node = pool->head;
574 0 : while (node) {
575 0 : struct pool_node * old = node;
576 0 : node = node->next;
577 0 : free(old->data);
578 0 : free(old);
579 : }
580 0 : free(pool);
581 0 : }
582 :
583 : static void *
584 0 : ne_pool_alloc(size_t size, struct pool_ctx * pool)
585 : {
586 : struct pool_node * node;
587 :
588 0 : node = calloc(1, sizeof(*node));
589 0 : if (!node)
590 0 : return NULL;
591 :
592 0 : node->data = calloc(1, size);
593 0 : if (!node->data) {
594 0 : free(node);
595 0 : return NULL;
596 : }
597 :
598 0 : node->next = pool->head;
599 0 : pool->head = node;
600 :
601 0 : return node->data;
602 : }
603 :
604 : static void *
605 0 : ne_alloc(size_t size)
606 : {
607 0 : return calloc(1, size);
608 : }
609 :
610 : static int
611 0 : ne_io_read(nestegg_io * io, void * buffer, size_t length)
612 : {
613 0 : return io->read(buffer, length, io->userdata);
614 : }
615 :
616 : static int
617 0 : ne_io_seek(nestegg_io * io, int64_t offset, int whence)
618 : {
619 0 : return io->seek(offset, whence, io->userdata);
620 : }
621 :
622 : static int
623 0 : ne_io_read_skip(nestegg_io * io, size_t length)
624 : {
625 : size_t get;
626 : unsigned char buf[8192];
627 0 : int r = 1;
628 :
629 0 : while (length > 0) {
630 0 : get = length < sizeof(buf) ? length : sizeof(buf);
631 0 : r = ne_io_read(io, buf, get);
632 0 : if (r != 1)
633 0 : break;
634 0 : length -= get;
635 : }
636 :
637 0 : return r;
638 : }
639 :
640 : static int64_t
641 0 : ne_io_tell(nestegg_io * io)
642 : {
643 0 : return io->tell(io->userdata);
644 : }
645 :
646 : static int
647 0 : ne_bare_read_vint(nestegg_io * io, uint64_t * value, uint64_t * length, enum vint_mask maskflag)
648 : {
649 : int r;
650 : unsigned char b;
651 0 : size_t maxlen = 8;
652 0 : unsigned int count = 1, mask = 1 << 7;
653 :
654 0 : r = ne_io_read(io, &b, 1);
655 0 : if (r != 1)
656 0 : return r;
657 :
658 0 : while (count < maxlen) {
659 0 : if ((b & mask) != 0)
660 0 : break;
661 0 : mask >>= 1;
662 0 : count += 1;
663 : }
664 :
665 0 : if (length)
666 0 : *length = count;
667 0 : *value = b;
668 :
669 0 : if (maskflag == MASK_FIRST_BIT)
670 0 : *value = b & ~mask;
671 :
672 0 : while (--count) {
673 0 : r = ne_io_read(io, &b, 1);
674 0 : if (r != 1)
675 0 : return r;
676 0 : *value <<= 8;
677 0 : *value |= b;
678 : }
679 :
680 0 : return 1;
681 : }
682 :
683 : static int
684 0 : ne_read_id(nestegg_io * io, uint64_t * value, uint64_t * length)
685 : {
686 0 : return ne_bare_read_vint(io, value, length, MASK_NONE);
687 : }
688 :
689 : static int
690 0 : ne_read_vint(nestegg_io * io, uint64_t * value, uint64_t * length)
691 : {
692 0 : return ne_bare_read_vint(io, value, length, MASK_FIRST_BIT);
693 : }
694 :
695 : static int
696 0 : ne_read_svint(nestegg_io * io, int64_t * value, uint64_t * length)
697 : {
698 : int r;
699 : uint64_t uvalue;
700 : uint64_t ulength;
701 0 : int64_t svint_subtr[] = {
702 : 0x3f, 0x1fff,
703 : 0xfffff, 0x7ffffff,
704 : 0x3ffffffffLL, 0x1ffffffffffLL,
705 : 0xffffffffffffLL, 0x7fffffffffffffLL
706 : };
707 :
708 0 : r = ne_bare_read_vint(io, &uvalue, &ulength, MASK_FIRST_BIT);
709 0 : if (r != 1)
710 0 : return r;
711 0 : *value = uvalue - svint_subtr[ulength - 1];
712 0 : if (length)
713 0 : *length = ulength;
714 0 : return r;
715 : }
716 :
717 : static int
718 0 : ne_read_uint(nestegg_io * io, uint64_t * val, uint64_t length)
719 : {
720 : unsigned char b;
721 : int r;
722 :
723 0 : if (length == 0 || length > 8)
724 0 : return -1;
725 0 : r = ne_io_read(io, &b, 1);
726 0 : if (r != 1)
727 0 : return r;
728 0 : *val = b;
729 0 : while (--length) {
730 0 : r = ne_io_read(io, &b, 1);
731 0 : if (r != 1)
732 0 : return r;
733 0 : *val <<= 8;
734 0 : *val |= b;
735 : }
736 0 : return 1;
737 : }
738 :
739 : static int
740 0 : ne_read_int(nestegg_io * io, int64_t * val, uint64_t length)
741 : {
742 : int r;
743 : uint64_t uval, base;
744 :
745 0 : r = ne_read_uint(io, &uval, length);
746 0 : if (r != 1)
747 0 : return r;
748 :
749 0 : if (length < sizeof(int64_t)) {
750 0 : base = 1;
751 0 : base <<= length * 8 - 1;
752 0 : if (uval >= base) {
753 0 : base = 1;
754 0 : base <<= length * 8;
755 : } else {
756 0 : base = 0;
757 : }
758 0 : *val = uval - base;
759 : } else {
760 0 : *val = (int64_t) uval;
761 : }
762 :
763 0 : return 1;
764 : }
765 :
766 : static int
767 0 : ne_read_float(nestegg_io * io, double * val, uint64_t length)
768 : {
769 : union {
770 : uint64_t u;
771 : float f;
772 : double d;
773 : } value;
774 : int r;
775 :
776 : /* Length == 10 not implemented. */
777 0 : if (length != 4 && length != 8)
778 0 : return -1;
779 0 : r = ne_read_uint(io, &value.u, length);
780 0 : if (r != 1)
781 0 : return r;
782 0 : if (length == 4)
783 0 : *val = value.f;
784 : else
785 0 : *val = value.d;
786 0 : return 1;
787 : }
788 :
789 : static int
790 0 : ne_read_string(nestegg * ctx, char ** val, uint64_t length)
791 : {
792 : char * str;
793 : int r;
794 :
795 0 : if (length > LIMIT_STRING)
796 0 : return -1;
797 0 : str = ne_pool_alloc(length + 1, ctx->alloc_pool);
798 0 : if (!str)
799 0 : return -1;
800 0 : if (length) {
801 0 : r = ne_io_read(ctx->io, (unsigned char *) str, length);
802 0 : if (r != 1)
803 0 : return r;
804 : }
805 0 : str[length] = '\0';
806 0 : *val = str;
807 0 : return 1;
808 : }
809 :
810 : static int
811 0 : ne_read_binary(nestegg * ctx, struct ebml_binary * val, uint64_t length)
812 : {
813 0 : if (length == 0 || length > LIMIT_BINARY)
814 0 : return -1;
815 0 : val->data = ne_pool_alloc(length, ctx->alloc_pool);
816 0 : if (!val->data)
817 0 : return -1;
818 0 : val->length = length;
819 0 : return ne_io_read(ctx->io, val->data, length);
820 : }
821 :
822 : static int
823 0 : ne_get_uint(struct ebml_type type, uint64_t * value)
824 : {
825 0 : if (!type.read)
826 0 : return -1;
827 :
828 0 : assert(type.type == TYPE_UINT);
829 :
830 0 : *value = type.v.u;
831 :
832 0 : return 0;
833 : }
834 :
835 : static int
836 0 : ne_get_float(struct ebml_type type, double * value)
837 : {
838 0 : if (!type.read)
839 0 : return -1;
840 :
841 0 : assert(type.type == TYPE_FLOAT);
842 :
843 0 : *value = type.v.f;
844 :
845 0 : return 0;
846 : }
847 :
848 : static int
849 0 : ne_get_string(struct ebml_type type, char ** value)
850 : {
851 0 : if (!type.read)
852 0 : return -1;
853 :
854 0 : assert(type.type == TYPE_STRING);
855 :
856 0 : *value = type.v.s;
857 :
858 0 : return 0;
859 : }
860 :
861 : static int
862 0 : ne_get_binary(struct ebml_type type, struct ebml_binary * value)
863 : {
864 0 : if (!type.read)
865 0 : return -1;
866 :
867 0 : assert(type.type == TYPE_BINARY);
868 :
869 0 : *value = type.v.b;
870 :
871 0 : return 0;
872 : }
873 :
874 : static int
875 0 : ne_is_ancestor_element(uint64_t id, struct list_node * ancestor)
876 : {
877 : struct ebml_element_desc * element;
878 :
879 0 : for (; ancestor; ancestor = ancestor->previous)
880 0 : for (element = ancestor->node; element->id; ++element)
881 0 : if (element->id == id)
882 0 : return 1;
883 :
884 0 : return 0;
885 : }
886 :
887 : static struct ebml_element_desc *
888 0 : ne_find_element(uint64_t id, struct ebml_element_desc * elements)
889 : {
890 : struct ebml_element_desc * element;
891 :
892 0 : for (element = elements; element->id; ++element)
893 0 : if (element->id == id)
894 0 : return element;
895 :
896 0 : return NULL;
897 : }
898 :
899 : static int
900 0 : ne_ctx_push(nestegg * ctx, struct ebml_element_desc * ancestor, void * data)
901 : {
902 : struct list_node * item;
903 :
904 0 : item = ne_alloc(sizeof(*item));
905 0 : if (!item)
906 0 : return -1;
907 0 : item->previous = ctx->ancestor;
908 0 : item->node = ancestor;
909 0 : item->data = data;
910 0 : ctx->ancestor = item;
911 0 : return 0;
912 : }
913 :
914 : static void
915 0 : ne_ctx_pop(nestegg * ctx)
916 : {
917 : struct list_node * item;
918 :
919 0 : item = ctx->ancestor;
920 0 : ctx->ancestor = item->previous;
921 0 : free(item);
922 0 : }
923 :
924 : static int
925 0 : ne_ctx_save(nestegg * ctx, struct saved_state * s)
926 : {
927 0 : s->stream_offset = ne_io_tell(ctx->io);
928 0 : if (s->stream_offset < 0)
929 0 : return -1;
930 0 : s->last_id = ctx->last_id;
931 0 : s->last_size = ctx->last_size;
932 0 : s->last_valid = ctx->last_valid;
933 0 : return 0;
934 : }
935 :
936 : static int
937 0 : ne_ctx_restore(nestegg * ctx, struct saved_state * s)
938 : {
939 : int r;
940 :
941 0 : if (s->stream_offset < 0)
942 0 : return -1;
943 0 : r = ne_io_seek(ctx->io, s->stream_offset, NESTEGG_SEEK_SET);
944 0 : if (r != 0)
945 0 : return -1;
946 0 : ctx->last_id = s->last_id;
947 0 : ctx->last_size = s->last_size;
948 0 : ctx->last_valid = s->last_valid;
949 0 : return 0;
950 : }
951 :
952 : static int
953 0 : ne_peek_element(nestegg * ctx, uint64_t * id, uint64_t * size)
954 : {
955 : int r;
956 :
957 0 : if (ctx->last_valid) {
958 0 : if (id)
959 0 : *id = ctx->last_id;
960 0 : if (size)
961 0 : *size = ctx->last_size;
962 0 : return 1;
963 : }
964 :
965 0 : r = ne_read_id(ctx->io, &ctx->last_id, NULL);
966 0 : if (r != 1)
967 0 : return r;
968 :
969 0 : r = ne_read_vint(ctx->io, &ctx->last_size, NULL);
970 0 : if (r != 1)
971 0 : return r;
972 :
973 0 : if (id)
974 0 : *id = ctx->last_id;
975 0 : if (size)
976 0 : *size = ctx->last_size;
977 :
978 0 : ctx->last_valid = 1;
979 :
980 0 : return 1;
981 : }
982 :
983 : static int
984 0 : ne_read_element(nestegg * ctx, uint64_t * id, uint64_t * size)
985 : {
986 : int r;
987 :
988 0 : r = ne_peek_element(ctx, id, size);
989 0 : if (r != 1)
990 0 : return r;
991 :
992 0 : ctx->last_valid = 0;
993 :
994 0 : return 1;
995 : }
996 :
997 : static int
998 0 : ne_read_master(nestegg * ctx, struct ebml_element_desc * desc)
999 : {
1000 : struct ebml_list * list;
1001 : struct ebml_list_node * node, * oldtail;
1002 :
1003 0 : assert(desc->type == TYPE_MASTER && desc->flags & DESC_FLAG_MULTI);
1004 :
1005 0 : ctx->log(ctx, NESTEGG_LOG_DEBUG, "multi master element %llx (%s)",
1006 : desc->id, desc->name);
1007 :
1008 0 : list = (struct ebml_list *) (ctx->ancestor->data + desc->offset);
1009 :
1010 0 : node = ne_pool_alloc(sizeof(*node), ctx->alloc_pool);
1011 0 : if (!node)
1012 0 : return -1;
1013 0 : node->id = desc->id;
1014 0 : node->data = ne_pool_alloc(desc->size, ctx->alloc_pool);
1015 0 : if (!node->data)
1016 0 : return -1;
1017 :
1018 0 : oldtail = list->tail;
1019 0 : if (oldtail)
1020 0 : oldtail->next = node;
1021 0 : list->tail = node;
1022 0 : if (!list->head)
1023 0 : list->head = node;
1024 :
1025 0 : ctx->log(ctx, NESTEGG_LOG_DEBUG, " -> using data %p", node->data);
1026 :
1027 0 : if (ne_ctx_push(ctx, desc->children, node->data) < 0)
1028 0 : return -1;
1029 :
1030 0 : return 0;
1031 : }
1032 :
1033 : static int
1034 0 : ne_read_single_master(nestegg * ctx, struct ebml_element_desc * desc)
1035 : {
1036 0 : assert(desc->type == TYPE_MASTER && !(desc->flags & DESC_FLAG_MULTI));
1037 :
1038 0 : ctx->log(ctx, NESTEGG_LOG_DEBUG, "single master element %llx (%s)",
1039 : desc->id, desc->name);
1040 0 : ctx->log(ctx, NESTEGG_LOG_DEBUG, " -> using data %p (%u)",
1041 0 : ctx->ancestor->data + desc->offset, desc->offset);
1042 :
1043 0 : return ne_ctx_push(ctx, desc->children, ctx->ancestor->data + desc->offset);
1044 : }
1045 :
1046 : static int
1047 0 : ne_read_simple(nestegg * ctx, struct ebml_element_desc * desc, size_t length)
1048 : {
1049 : struct ebml_type * storage;
1050 0 : int r = -1;
1051 :
1052 0 : storage = (struct ebml_type *) (ctx->ancestor->data + desc->offset);
1053 :
1054 0 : if (storage->read) {
1055 0 : ctx->log(ctx, NESTEGG_LOG_DEBUG, "element %llx (%s) already read, skipping",
1056 : desc->id, desc->name);
1057 0 : return 0;
1058 : }
1059 :
1060 0 : storage->type = desc->type;
1061 :
1062 0 : ctx->log(ctx, NESTEGG_LOG_DEBUG, "element %llx (%s) -> %p (%u)",
1063 : desc->id, desc->name, storage, desc->offset);
1064 :
1065 0 : switch (desc->type) {
1066 : case TYPE_UINT:
1067 0 : r = ne_read_uint(ctx->io, &storage->v.u, length);
1068 0 : break;
1069 : case TYPE_FLOAT:
1070 0 : r = ne_read_float(ctx->io, &storage->v.f, length);
1071 0 : break;
1072 : case TYPE_STRING:
1073 0 : r = ne_read_string(ctx, &storage->v.s, length);
1074 0 : break;
1075 : case TYPE_BINARY:
1076 0 : r = ne_read_binary(ctx, &storage->v.b, length);
1077 0 : break;
1078 : case TYPE_MASTER:
1079 : case TYPE_UNKNOWN:
1080 : default:
1081 0 : assert(0);
1082 : break;
1083 : }
1084 :
1085 0 : if (r == 1)
1086 0 : storage->read = 1;
1087 :
1088 0 : return r;
1089 : }
1090 :
1091 : static int
1092 0 : ne_parse(nestegg * ctx, struct ebml_element_desc * top_level, int64_t max_offset)
1093 : {
1094 : int r;
1095 : int64_t * data_offset;
1096 : uint64_t id, size, peeked_id;
1097 : struct ebml_element_desc * element;
1098 :
1099 0 : assert(ctx->ancestor);
1100 :
1101 : for (;;) {
1102 0 : if (max_offset > 0 && ne_io_tell(ctx->io) >= max_offset) {
1103 : /* Reached end of offset allowed for parsing - return gracefully */
1104 0 : r = 1;
1105 0 : break;
1106 : }
1107 0 : r = ne_peek_element(ctx, &id, &size);
1108 0 : if (r != 1)
1109 0 : break;
1110 0 : peeked_id = id;
1111 :
1112 0 : element = ne_find_element(id, ctx->ancestor->node);
1113 0 : if (element) {
1114 0 : if (element->flags & DESC_FLAG_SUSPEND) {
1115 0 : assert(element->id == ID_CLUSTER && element->type == TYPE_MASTER);
1116 0 : ctx->log(ctx, NESTEGG_LOG_DEBUG, "suspend parse at %llx", id);
1117 0 : r = 1;
1118 0 : break;
1119 : }
1120 :
1121 0 : r = ne_read_element(ctx, &id, &size);
1122 0 : if (r != 1)
1123 0 : break;
1124 0 : assert(id == peeked_id);
1125 :
1126 0 : if (element->flags & DESC_FLAG_OFFSET) {
1127 0 : data_offset = (int64_t *) (ctx->ancestor->data + element->data_offset);
1128 0 : *data_offset = ne_io_tell(ctx->io);
1129 0 : if (*data_offset < 0) {
1130 0 : r = -1;
1131 0 : break;
1132 : }
1133 : }
1134 :
1135 0 : if (element->type == TYPE_MASTER) {
1136 0 : if (element->flags & DESC_FLAG_MULTI) {
1137 0 : if (ne_read_master(ctx, element) < 0)
1138 0 : break;
1139 : } else {
1140 0 : if (ne_read_single_master(ctx, element) < 0)
1141 0 : break;
1142 : }
1143 0 : continue;
1144 : } else {
1145 0 : r = ne_read_simple(ctx, element, size);
1146 0 : if (r < 0)
1147 0 : break;
1148 : }
1149 0 : } else if (ne_is_ancestor_element(id, ctx->ancestor->previous)) {
1150 0 : ctx->log(ctx, NESTEGG_LOG_DEBUG, "parent element %llx", id);
1151 0 : if (top_level && ctx->ancestor->node == top_level) {
1152 0 : ctx->log(ctx, NESTEGG_LOG_DEBUG, "*** parse about to back up past top_level");
1153 0 : r = 1;
1154 0 : break;
1155 : }
1156 0 : ne_ctx_pop(ctx);
1157 : } else {
1158 0 : r = ne_read_element(ctx, &id, &size);
1159 0 : if (r != 1)
1160 0 : break;
1161 :
1162 0 : if (id != ID_VOID && id != ID_CRC32)
1163 0 : ctx->log(ctx, NESTEGG_LOG_DEBUG, "unknown element %llx", id);
1164 0 : r = ne_io_read_skip(ctx->io, size);
1165 0 : if (r != 1)
1166 0 : break;
1167 : }
1168 : }
1169 :
1170 0 : if (r != 1)
1171 0 : while (ctx->ancestor)
1172 0 : ne_ctx_pop(ctx);
1173 :
1174 0 : return r;
1175 : }
1176 :
1177 : static int
1178 0 : ne_read_block_encryption(nestegg * ctx, struct track_entry const * entry,
1179 : uint64_t * encoding_type, uint64_t * encryption_algo,
1180 : uint64_t * encryption_mode)
1181 : {
1182 : struct content_encoding * encoding;
1183 : struct content_encryption * encryption;
1184 : struct content_enc_aes_settings * aes_settings;
1185 :
1186 0 : *encoding_type = 0;
1187 0 : if (entry->content_encodings.content_encoding.head) {
1188 0 : encoding = entry->content_encodings.content_encoding.head->data;
1189 0 : if (ne_get_uint(encoding->content_encoding_type, encoding_type) != 0)
1190 0 : return -1;
1191 :
1192 0 : if (*encoding_type == NESTEGG_ENCODING_ENCRYPTION) {
1193 : /* Metadata states content is encrypted */
1194 0 : if (!encoding->content_encryption.head)
1195 0 : return -1;
1196 :
1197 0 : encryption = encoding->content_encryption.head->data;
1198 0 : if (ne_get_uint(encryption->content_enc_algo, encryption_algo) != 0) {
1199 0 : ctx->log(ctx, NESTEGG_LOG_ERROR, "No ContentEncAlgo element found");
1200 0 : return -1;
1201 : }
1202 :
1203 0 : if (*encryption_algo != CONTENT_ENC_ALGO_AES) {
1204 0 : ctx->log(ctx, NESTEGG_LOG_ERROR, "Disallowed ContentEncAlgo used");
1205 0 : return -1;
1206 : }
1207 :
1208 0 : if (!encryption->content_enc_aes_settings.head) {
1209 0 : ctx->log(ctx, NESTEGG_LOG_ERROR, "No ContentEncAESSettings element found");
1210 0 : return -1;
1211 : }
1212 :
1213 0 : aes_settings = encryption->content_enc_aes_settings.head->data;
1214 0 : *encryption_mode = AES_SETTINGS_CIPHER_CTR;
1215 0 : ne_get_uint(aes_settings->aes_settings_cipher_mode, encryption_mode);
1216 :
1217 0 : if (*encryption_mode != AES_SETTINGS_CIPHER_CTR) {
1218 0 : ctx->log(ctx, NESTEGG_LOG_ERROR, "Disallowed AESSettingsCipherMode used");
1219 0 : return -1;
1220 : }
1221 : }
1222 : }
1223 0 : return 1;
1224 : }
1225 :
1226 : static int
1227 0 : ne_read_xiph_lace_value(nestegg_io * io, uint64_t * value, size_t * consumed)
1228 : {
1229 : int r;
1230 : uint64_t lace;
1231 :
1232 0 : r = ne_read_uint(io, &lace, 1);
1233 0 : if (r != 1)
1234 0 : return r;
1235 0 : *consumed += 1;
1236 :
1237 0 : *value = lace;
1238 0 : while (lace == 255) {
1239 0 : r = ne_read_uint(io, &lace, 1);
1240 0 : if (r != 1)
1241 0 : return r;
1242 0 : *consumed += 1;
1243 0 : *value += lace;
1244 : }
1245 :
1246 0 : return 1;
1247 : }
1248 :
1249 : static int
1250 0 : ne_read_xiph_lacing(nestegg_io * io, size_t block, size_t * read, uint64_t n, uint64_t * sizes)
1251 : {
1252 : int r;
1253 0 : size_t i = 0;
1254 0 : uint64_t sum = 0;
1255 :
1256 0 : while (--n) {
1257 0 : r = ne_read_xiph_lace_value(io, &sizes[i], read);
1258 0 : if (r != 1)
1259 0 : return r;
1260 0 : sum += sizes[i];
1261 0 : i += 1;
1262 : }
1263 :
1264 0 : if (*read + sum > block)
1265 0 : return -1;
1266 :
1267 : /* Last frame is the remainder of the block. */
1268 0 : sizes[i] = block - *read - sum;
1269 0 : return 1;
1270 : }
1271 :
1272 : static int
1273 0 : ne_read_ebml_lacing(nestegg_io * io, size_t block, size_t * read, uint64_t n, uint64_t * sizes)
1274 : {
1275 : int r;
1276 : uint64_t lace, sum, length;
1277 : int64_t slace;
1278 0 : size_t i = 0;
1279 :
1280 0 : r = ne_read_vint(io, &lace, &length);
1281 0 : if (r != 1)
1282 0 : return r;
1283 0 : *read += length;
1284 :
1285 0 : sizes[i] = lace;
1286 0 : sum = sizes[i];
1287 :
1288 0 : i += 1;
1289 0 : n -= 1;
1290 :
1291 0 : while (--n) {
1292 0 : r = ne_read_svint(io, &slace, &length);
1293 0 : if (r != 1)
1294 0 : return r;
1295 0 : *read += length;
1296 0 : sizes[i] = sizes[i - 1] + slace;
1297 0 : sum += sizes[i];
1298 0 : i += 1;
1299 : }
1300 :
1301 0 : if (*read + sum > block)
1302 0 : return -1;
1303 :
1304 : /* Last frame is the remainder of the block. */
1305 0 : sizes[i] = block - *read - sum;
1306 0 : return 1;
1307 : }
1308 :
1309 : static uint64_t
1310 0 : ne_get_timecode_scale(nestegg * ctx)
1311 : {
1312 : uint64_t scale;
1313 :
1314 0 : if (ne_get_uint(ctx->segment.info.timecode_scale, &scale) != 0)
1315 0 : scale = 1000000;
1316 :
1317 0 : return scale;
1318 : }
1319 :
1320 : static int
1321 0 : ne_map_track_number_to_index(nestegg * ctx,
1322 : unsigned int track_number,
1323 : unsigned int * track_index)
1324 : {
1325 : struct ebml_list_node * node;
1326 : struct track_entry * t_entry;
1327 0 : uint64_t t_number = 0;
1328 :
1329 0 : if (!track_index)
1330 0 : return -1;
1331 0 : *track_index = 0;
1332 :
1333 0 : if (track_number == 0)
1334 0 : return -1;
1335 :
1336 0 : node = ctx->segment.tracks.track_entry.head;
1337 0 : while (node) {
1338 0 : assert(node->id == ID_TRACK_ENTRY);
1339 0 : t_entry = node->data;
1340 0 : if (ne_get_uint(t_entry->number, &t_number) != 0)
1341 0 : return -1;
1342 0 : if (t_number == track_number)
1343 0 : return 0;
1344 0 : *track_index += 1;
1345 0 : node = node->next;
1346 : }
1347 :
1348 0 : return -1;
1349 : }
1350 :
1351 : static struct track_entry *
1352 0 : ne_find_track_entry(nestegg * ctx, unsigned int track)
1353 : {
1354 : struct ebml_list_node * node;
1355 0 : unsigned int tracks = 0;
1356 :
1357 0 : node = ctx->segment.tracks.track_entry.head;
1358 0 : while (node) {
1359 0 : assert(node->id == ID_TRACK_ENTRY);
1360 0 : if (track == tracks)
1361 0 : return node->data;
1362 0 : tracks += 1;
1363 0 : node = node->next;
1364 : }
1365 :
1366 0 : return NULL;
1367 : }
1368 :
1369 : static struct frame *
1370 0 : ne_alloc_frame(void)
1371 : {
1372 0 : struct frame * f = ne_alloc(sizeof(*f));
1373 :
1374 0 : if (!f)
1375 0 : return NULL;
1376 :
1377 0 : f->data = NULL;
1378 0 : f->length = 0;
1379 0 : f->frame_encryption = NULL;
1380 0 : f->next = NULL;
1381 :
1382 0 : return f;
1383 : }
1384 :
1385 : static struct frame_encryption *
1386 0 : ne_alloc_frame_encryption(void)
1387 : {
1388 0 : struct frame_encryption * f = ne_alloc(sizeof(*f));
1389 :
1390 0 : if (!f)
1391 0 : return NULL;
1392 :
1393 0 : f->iv = NULL;
1394 0 : f->length = 0;
1395 0 : f->signal_byte = 0;
1396 0 : f->num_partitions = 0;
1397 0 : f->partition_offsets = NULL;
1398 :
1399 0 : return f;
1400 : }
1401 :
1402 : static void
1403 0 : ne_free_frame(struct frame * f)
1404 : {
1405 0 : if (f->frame_encryption) {
1406 0 : free(f->frame_encryption->iv);
1407 0 : free(f->frame_encryption->partition_offsets);
1408 : }
1409 :
1410 0 : free(f->frame_encryption);
1411 0 : free(f->data);
1412 0 : free(f);
1413 0 : }
1414 :
1415 : static int
1416 0 : ne_read_block(nestegg * ctx, uint64_t block_id, uint64_t block_size, nestegg_packet ** data)
1417 : {
1418 : int r;
1419 : int64_t timecode, abs_timecode;
1420 : nestegg_packet * pkt;
1421 : struct frame * f, * last;
1422 : struct track_entry * entry;
1423 : double track_scale;
1424 : uint64_t track_number, length, frame_sizes[256], cluster_tc, flags, frames, tc_scale, total,
1425 : encoding_type, encryption_algo, encryption_mode;
1426 : unsigned int i, lacing, track;
1427 0 : uint8_t signal_byte, keyframe = NESTEGG_PACKET_HAS_KEYFRAME_UNKNOWN, j = 0;
1428 0 : size_t consumed = 0, data_size, encryption_size;
1429 :
1430 0 : *data = NULL;
1431 :
1432 0 : if (block_size > LIMIT_BLOCK)
1433 0 : return -1;
1434 :
1435 0 : r = ne_read_vint(ctx->io, &track_number, &length);
1436 0 : if (r != 1)
1437 0 : return r;
1438 :
1439 0 : if (track_number == 0)
1440 0 : return -1;
1441 :
1442 0 : consumed += length;
1443 :
1444 0 : r = ne_read_int(ctx->io, &timecode, 2);
1445 0 : if (r != 1)
1446 0 : return r;
1447 :
1448 0 : consumed += 2;
1449 :
1450 0 : r = ne_read_uint(ctx->io, &flags, 1);
1451 0 : if (r != 1)
1452 0 : return r;
1453 :
1454 0 : consumed += 1;
1455 :
1456 0 : frames = 0;
1457 :
1458 : /* Simple blocks have an explicit flag for if the contents a keyframes*/
1459 0 : if (block_id == ID_SIMPLE_BLOCK)
1460 0 : keyframe = (flags & SIMPLE_BLOCK_FLAGS_KEYFRAME) == SIMPLE_BLOCK_FLAGS_KEYFRAME ?
1461 0 : NESTEGG_PACKET_HAS_KEYFRAME_TRUE :
1462 : NESTEGG_PACKET_HAS_KEYFRAME_FALSE;
1463 :
1464 : /* Flags are different between Block and SimpleBlock, but lacing is
1465 : encoded the same way. */
1466 0 : lacing = (flags & BLOCK_FLAGS_LACING) >> 1;
1467 :
1468 0 : switch (lacing) {
1469 : case LACING_NONE:
1470 0 : frames = 1;
1471 0 : break;
1472 : case LACING_XIPH:
1473 : case LACING_FIXED:
1474 : case LACING_EBML:
1475 0 : r = ne_read_uint(ctx->io, &frames, 1);
1476 0 : if (r != 1)
1477 0 : return r;
1478 0 : consumed += 1;
1479 0 : frames += 1;
1480 0 : break;
1481 : default:
1482 0 : assert(0);
1483 : return -1;
1484 : }
1485 :
1486 0 : if (frames > 256)
1487 0 : return -1;
1488 :
1489 0 : switch (lacing) {
1490 : case LACING_NONE:
1491 0 : frame_sizes[0] = block_size - consumed;
1492 0 : break;
1493 : case LACING_XIPH:
1494 0 : if (frames == 1)
1495 0 : return -1;
1496 0 : r = ne_read_xiph_lacing(ctx->io, block_size, &consumed, frames, frame_sizes);
1497 0 : if (r != 1)
1498 0 : return r;
1499 0 : break;
1500 : case LACING_FIXED:
1501 0 : if ((block_size - consumed) % frames)
1502 0 : return -1;
1503 0 : for (i = 0; i < frames; ++i)
1504 0 : frame_sizes[i] = (block_size - consumed) / frames;
1505 0 : break;
1506 : case LACING_EBML:
1507 0 : if (frames == 1)
1508 0 : return -1;
1509 0 : r = ne_read_ebml_lacing(ctx->io, block_size, &consumed, frames, frame_sizes);
1510 0 : if (r != 1)
1511 0 : return r;
1512 0 : break;
1513 : default:
1514 0 : assert(0);
1515 : return -1;
1516 : }
1517 :
1518 : /* Sanity check unlaced frame sizes against total block size. */
1519 0 : total = consumed;
1520 0 : for (i = 0; i < frames; ++i)
1521 0 : total += frame_sizes[i];
1522 0 : if (total > block_size)
1523 0 : return -1;
1524 :
1525 0 : if (ne_map_track_number_to_index(ctx, track_number, &track) != 0)
1526 0 : return -1;
1527 :
1528 0 : entry = ne_find_track_entry(ctx, track);
1529 0 : if (!entry)
1530 0 : return -1;
1531 :
1532 0 : r = ne_read_block_encryption(ctx, entry, &encoding_type, &encryption_algo, &encryption_mode);
1533 0 : if (r != 1)
1534 0 : return r;
1535 :
1536 : /* Encryption does not support lacing */
1537 0 : if (lacing != LACING_NONE && encoding_type == NESTEGG_ENCODING_ENCRYPTION) {
1538 0 : ctx->log(ctx, NESTEGG_LOG_ERROR, "Encrypted blocks may not also be laced");
1539 0 : return -1;
1540 : }
1541 :
1542 0 : track_scale = 1.0;
1543 :
1544 0 : tc_scale = ne_get_timecode_scale(ctx);
1545 0 : if (tc_scale == 0)
1546 0 : return -1;
1547 :
1548 0 : if (!ctx->read_cluster_timecode)
1549 0 : return -1;
1550 0 : cluster_tc = ctx->cluster_timecode;
1551 :
1552 0 : abs_timecode = timecode + cluster_tc;
1553 0 : if (abs_timecode < 0)
1554 0 : return -1;
1555 :
1556 0 : pkt = ne_alloc(sizeof(*pkt));
1557 0 : if (!pkt)
1558 0 : return -1;
1559 0 : pkt->track = track;
1560 0 : pkt->timecode = abs_timecode * tc_scale * track_scale;
1561 0 : pkt->keyframe = keyframe;
1562 :
1563 0 : ctx->log(ctx, NESTEGG_LOG_DEBUG, "%sblock t %lld pts %f f %llx frames: %llu",
1564 0 : block_id == ID_BLOCK ? "" : "simple", pkt->track, pkt->timecode / 1e9, flags, frames);
1565 :
1566 0 : last = NULL;
1567 0 : for (i = 0; i < frames; ++i) {
1568 0 : if (frame_sizes[i] > LIMIT_FRAME) {
1569 0 : nestegg_free_packet(pkt);
1570 0 : return -1;
1571 : }
1572 0 : f = ne_alloc_frame();
1573 0 : if (!f) {
1574 0 : nestegg_free_packet(pkt);
1575 0 : return -1;
1576 : }
1577 : /* Parse encryption */
1578 0 : if (encoding_type == NESTEGG_ENCODING_ENCRYPTION) {
1579 0 : r = ne_io_read(ctx->io, &signal_byte, SIGNAL_BYTE_SIZE);
1580 0 : if (r != 1) {
1581 0 : ne_free_frame(f);
1582 0 : nestegg_free_packet(pkt);
1583 0 : return r;
1584 : }
1585 0 : f->frame_encryption = ne_alloc_frame_encryption();
1586 0 : if (!f->frame_encryption) {
1587 0 : ne_free_frame(f);
1588 0 : nestegg_free_packet(pkt);
1589 0 : return -1;
1590 : }
1591 0 : f->frame_encryption->signal_byte = signal_byte;
1592 0 : if ((signal_byte & ENCRYPTED_BIT_MASK) == PACKET_ENCRYPTED) {
1593 0 : f->frame_encryption->iv = ne_alloc(IV_SIZE);
1594 0 : if (!f->frame_encryption->iv) {
1595 0 : ne_free_frame(f);
1596 0 : nestegg_free_packet(pkt);
1597 0 : return -1;
1598 : }
1599 0 : r = ne_io_read(ctx->io, f->frame_encryption->iv, IV_SIZE);
1600 0 : if (r != 1) {
1601 0 : ne_free_frame(f);
1602 0 : nestegg_free_packet(pkt);
1603 0 : return r;
1604 : }
1605 0 : f->frame_encryption->length = IV_SIZE;
1606 0 : encryption_size = SIGNAL_BYTE_SIZE + IV_SIZE;
1607 :
1608 0 : if ((signal_byte & PARTITIONED_BIT_MASK) == PACKET_PARTITIONED) {
1609 0 : r = ne_io_read(ctx->io, &f->frame_encryption->num_partitions, NUM_PACKETS_SIZE);
1610 0 : if (r != 1) {
1611 0 : ne_free_frame(f);
1612 0 : nestegg_free_packet(pkt);
1613 0 : return r;
1614 : }
1615 :
1616 0 : encryption_size += NUM_PACKETS_SIZE + f->frame_encryption->num_partitions * PACKET_OFFSET_SIZE;
1617 0 : f->frame_encryption->partition_offsets = ne_alloc(f->frame_encryption->num_partitions * PACKET_OFFSET_SIZE);
1618 :
1619 0 : for (j = 0; j < f->frame_encryption->num_partitions; ++j) {
1620 0 : uint64_t value = 0;
1621 0 : r = ne_read_uint(ctx->io, &value, PACKET_OFFSET_SIZE);
1622 0 : if (r != 1) {
1623 0 : break;
1624 : }
1625 :
1626 0 : f->frame_encryption->partition_offsets[j] = (uint32_t) value;
1627 : }
1628 :
1629 : /* If any of the partition offsets did not return 1, then fail. */
1630 0 : if (j != f->frame_encryption->num_partitions) {
1631 0 : ne_free_frame(f);
1632 0 : nestegg_free_packet(pkt);
1633 0 : return r;
1634 : }
1635 : }
1636 : } else {
1637 0 : encryption_size = SIGNAL_BYTE_SIZE;
1638 : }
1639 : } else {
1640 0 : encryption_size = 0;
1641 : }
1642 0 : data_size = frame_sizes[i] - encryption_size;
1643 : /* Encryption parsed */
1644 0 : f->data = ne_alloc(data_size);
1645 0 : if (!f->data) {
1646 0 : ne_free_frame(f);
1647 0 : nestegg_free_packet(pkt);
1648 0 : return -1;
1649 : }
1650 0 : f->length = data_size;
1651 0 : r = ne_io_read(ctx->io, f->data, data_size);
1652 0 : if (r != 1) {
1653 0 : ne_free_frame(f);
1654 0 : nestegg_free_packet(pkt);
1655 0 : return r;
1656 : }
1657 :
1658 0 : if (!last)
1659 0 : pkt->frame = f;
1660 : else
1661 0 : last->next = f;
1662 0 : last = f;
1663 : }
1664 :
1665 0 : *data = pkt;
1666 :
1667 0 : return 1;
1668 : }
1669 :
1670 : static int
1671 0 : ne_read_block_additions(nestegg * ctx, uint64_t block_size, struct block_additional ** pkt_block_additional)
1672 : {
1673 : int r;
1674 : uint64_t id, size, data_size;
1675 : int64_t block_additions_end, block_more_end;
1676 : void * data;
1677 : int has_data;
1678 : struct block_additional * block_additional;
1679 : uint64_t add_id;
1680 :
1681 0 : assert(*pkt_block_additional == NULL);
1682 :
1683 0 : block_additions_end = ne_io_tell(ctx->io) + block_size;
1684 :
1685 0 : while (ne_io_tell(ctx->io) < block_additions_end) {
1686 0 : add_id = 1;
1687 0 : data = NULL;
1688 0 : has_data = 0;
1689 0 : r = ne_read_element(ctx, &id, &size);
1690 0 : if (r != 1)
1691 0 : return r;
1692 :
1693 0 : if (id != ID_BLOCK_MORE) {
1694 : /* We don't know what this element is, so skip over it */
1695 0 : if (id != ID_VOID && id != ID_CRC32)
1696 0 : ctx->log(ctx, NESTEGG_LOG_DEBUG,
1697 : "unknown element %llx in BlockAdditions", id);
1698 0 : r = ne_io_read_skip(ctx->io, size);
1699 0 : if (r != 1)
1700 0 : return r;
1701 0 : continue;
1702 : }
1703 :
1704 0 : block_more_end = ne_io_tell(ctx->io) + size;
1705 :
1706 0 : while (ne_io_tell(ctx->io) < block_more_end) {
1707 0 : r = ne_read_element(ctx, &id, &size);
1708 0 : if (r != 1) {
1709 0 : free(data);
1710 0 : return r;
1711 : }
1712 :
1713 0 : if (id == ID_BLOCK_ADD_ID) {
1714 0 : r = ne_read_uint(ctx->io, &add_id, size);
1715 0 : if (r != 1) {
1716 0 : free(data);
1717 0 : return r;
1718 : }
1719 :
1720 0 : if (add_id == 0) {
1721 0 : ctx->log(ctx, NESTEGG_LOG_ERROR, "Disallowed BlockAddId 0 used");
1722 0 : free(data);
1723 0 : return -1;
1724 : }
1725 0 : } else if (id == ID_BLOCK_ADDITIONAL) {
1726 0 : if (has_data) {
1727 : /* BlockAdditional is supposed to only occur once in a
1728 : BlockMore. */
1729 0 : ctx->log(ctx, NESTEGG_LOG_ERROR,
1730 : "Multiple BlockAdditional elements in a BlockMore");
1731 0 : free(data);
1732 0 : return -1;
1733 : }
1734 :
1735 0 : has_data = 1;
1736 0 : data_size = size;
1737 0 : if (data_size != 0 && data_size < LIMIT_FRAME) {
1738 0 : data = ne_alloc(data_size);
1739 0 : if (!data)
1740 0 : return -1;
1741 0 : r = ne_io_read(ctx->io, data, data_size);
1742 0 : if (r != 1) {
1743 0 : free(data);
1744 0 : return r;
1745 : }
1746 : }
1747 : } else {
1748 : /* We don't know what this element is, so skip over it */
1749 0 : if (id != ID_VOID && id != ID_CRC32)
1750 0 : ctx->log(ctx, NESTEGG_LOG_DEBUG,
1751 : "unknown element %llx in BlockMore", id);
1752 0 : r = ne_io_read_skip(ctx->io, size);
1753 0 : if (r != 1) {
1754 0 : free(data);
1755 0 : return r;
1756 : }
1757 : }
1758 : }
1759 :
1760 0 : if (has_data == 0) {
1761 0 : ctx->log(ctx, NESTEGG_LOG_ERROR,
1762 : "No BlockAdditional element in a BlockMore");
1763 0 : return -1;
1764 : }
1765 :
1766 0 : block_additional = ne_alloc(sizeof(*block_additional));
1767 0 : block_additional->next = *pkt_block_additional;
1768 0 : block_additional->id = add_id;
1769 0 : block_additional->data = data;
1770 0 : block_additional->length = data_size;
1771 0 : *pkt_block_additional = block_additional;
1772 : }
1773 :
1774 0 : return 1;
1775 : }
1776 :
1777 : static uint64_t
1778 0 : ne_buf_read_id(unsigned char const * p, size_t length)
1779 : {
1780 0 : uint64_t id = 0;
1781 :
1782 0 : while (length--) {
1783 0 : id <<= 8;
1784 0 : id |= *p++;
1785 : }
1786 :
1787 0 : return id;
1788 : }
1789 :
1790 : static struct seek *
1791 0 : ne_find_seek_for_id(struct ebml_list_node * seek_head, uint64_t id)
1792 : {
1793 : struct ebml_list * head;
1794 : struct ebml_list_node * seek;
1795 : struct ebml_binary binary_id;
1796 : struct seek * s;
1797 :
1798 0 : while (seek_head) {
1799 0 : assert(seek_head->id == ID_SEEK_HEAD);
1800 0 : head = seek_head->data;
1801 0 : seek = head->head;
1802 :
1803 0 : while (seek) {
1804 0 : assert(seek->id == ID_SEEK);
1805 0 : s = seek->data;
1806 :
1807 0 : if (ne_get_binary(s->id, &binary_id) == 0 &&
1808 0 : ne_buf_read_id(binary_id.data, binary_id.length) == id)
1809 0 : return s;
1810 :
1811 0 : seek = seek->next;
1812 : }
1813 :
1814 0 : seek_head = seek_head->next;
1815 : }
1816 :
1817 0 : return NULL;
1818 : }
1819 :
1820 : static struct cue_track_positions *
1821 0 : ne_find_cue_position_for_track(nestegg * ctx, struct ebml_list_node * node, unsigned int track)
1822 : {
1823 0 : struct cue_track_positions * pos = NULL;
1824 : uint64_t track_number;
1825 : unsigned int t;
1826 :
1827 0 : while (node) {
1828 0 : assert(node->id == ID_CUE_TRACK_POSITIONS);
1829 0 : pos = node->data;
1830 0 : if (ne_get_uint(pos->track, &track_number) != 0)
1831 0 : return NULL;
1832 :
1833 0 : if (ne_map_track_number_to_index(ctx, track_number, &t) != 0)
1834 0 : return NULL;
1835 :
1836 0 : if (t == track)
1837 0 : return pos;
1838 :
1839 0 : node = node->next;
1840 : }
1841 :
1842 0 : return NULL;
1843 : }
1844 :
1845 : static struct cue_point *
1846 0 : ne_find_cue_point_for_tstamp(nestegg * ctx, struct ebml_list_node * cue_point, unsigned int track, uint64_t scale, uint64_t tstamp)
1847 : {
1848 : uint64_t time;
1849 0 : struct cue_point * c, * prev = NULL;
1850 :
1851 0 : while (cue_point) {
1852 0 : assert(cue_point->id == ID_CUE_POINT);
1853 0 : c = cue_point->data;
1854 :
1855 0 : if (!prev)
1856 0 : prev = c;
1857 :
1858 0 : if (ne_get_uint(c->time, &time) == 0 && time * scale > tstamp)
1859 0 : break;
1860 :
1861 0 : if (ne_find_cue_position_for_track(ctx, c->cue_track_positions.head, track) != NULL)
1862 0 : prev = c;
1863 :
1864 0 : cue_point = cue_point->next;
1865 : }
1866 :
1867 0 : return prev;
1868 : }
1869 :
1870 : static void
1871 0 : ne_null_log_callback(nestegg * ctx, unsigned int severity, char const * fmt, ...)
1872 : {
1873 0 : if (ctx && severity && fmt)
1874 0 : return;
1875 : }
1876 :
1877 : static int
1878 0 : ne_init_cue_points(nestegg * ctx, int64_t max_offset)
1879 : {
1880 : int r;
1881 0 : struct ebml_list_node * node = ctx->segment.cues.cue_point.head;
1882 : struct seek * found;
1883 : uint64_t seek_pos, id;
1884 : struct saved_state state;
1885 :
1886 : /* If there are no cues loaded, check for cues element in the seek head
1887 : and load it. */
1888 0 : if (!node) {
1889 0 : found = ne_find_seek_for_id(ctx->segment.seek_head.head, ID_CUES);
1890 0 : if (!found)
1891 0 : return -1;
1892 :
1893 0 : if (ne_get_uint(found->position, &seek_pos) != 0)
1894 0 : return -1;
1895 :
1896 : /* Save old parser state. */
1897 0 : r = ne_ctx_save(ctx, &state);
1898 0 : if (r != 0)
1899 0 : return -1;
1900 :
1901 : /* Seek and set up parser state for segment-level element (Cues). */
1902 0 : r = ne_io_seek(ctx->io, ctx->segment_offset + seek_pos, NESTEGG_SEEK_SET);
1903 0 : if (r != 0)
1904 0 : return -1;
1905 0 : ctx->last_valid = 0;
1906 :
1907 0 : r = ne_read_element(ctx, &id, NULL);
1908 0 : if (r != 1)
1909 0 : return -1;
1910 :
1911 0 : if (id != ID_CUES)
1912 0 : return -1;
1913 :
1914 0 : assert(ctx->ancestor == NULL);
1915 0 : if (ne_ctx_push(ctx, ne_top_level_elements, ctx) < 0)
1916 0 : return -1;
1917 0 : if (ne_ctx_push(ctx, ne_segment_elements, &ctx->segment) < 0)
1918 0 : return -1;
1919 0 : if (ne_ctx_push(ctx, ne_cues_elements, &ctx->segment.cues) < 0)
1920 0 : return -1;
1921 : /* parser will run until end of cues element. */
1922 0 : ctx->log(ctx, NESTEGG_LOG_DEBUG, "seek: parsing cue elements");
1923 0 : r = ne_parse(ctx, ne_cues_elements, max_offset);
1924 0 : while (ctx->ancestor)
1925 0 : ne_ctx_pop(ctx);
1926 :
1927 : /* Reset parser state to original state and seek back to old position. */
1928 0 : if (ne_ctx_restore(ctx, &state) != 0)
1929 0 : return -1;
1930 :
1931 0 : if (r < 0)
1932 0 : return -1;
1933 :
1934 0 : node = ctx->segment.cues.cue_point.head;
1935 0 : if (!node)
1936 0 : return -1;
1937 : }
1938 :
1939 0 : return 0;
1940 : }
1941 :
1942 : /* Three functions that implement the nestegg_io interface, operating on a
1943 : io_buffer. */
1944 : struct io_buffer {
1945 : unsigned char const * buffer;
1946 : size_t length;
1947 : int64_t offset;
1948 : };
1949 :
1950 : static int
1951 0 : ne_buffer_read(void * buffer, size_t length, void * userdata)
1952 : {
1953 0 : struct io_buffer * iob = userdata;
1954 :
1955 0 : int rv = 1;
1956 0 : size_t available = iob->length - iob->offset;
1957 :
1958 0 : if (available < length)
1959 0 : return 0;
1960 :
1961 0 : memcpy(buffer, iob->buffer + iob->offset, length);
1962 0 : iob->offset += length;
1963 :
1964 0 : return rv;
1965 : }
1966 :
1967 : static int
1968 0 : ne_buffer_seek(int64_t offset, int whence, void * userdata)
1969 : {
1970 0 : struct io_buffer * iob = userdata;
1971 0 : int64_t o = iob->offset;
1972 :
1973 0 : switch(whence) {
1974 : case NESTEGG_SEEK_SET:
1975 0 : o = offset;
1976 0 : break;
1977 : case NESTEGG_SEEK_CUR:
1978 0 : o += offset;
1979 0 : break;
1980 : case NESTEGG_SEEK_END:
1981 0 : o = iob->length + offset;
1982 0 : break;
1983 : }
1984 :
1985 0 : if (o < 0 || o > (int64_t) iob->length)
1986 0 : return -1;
1987 :
1988 0 : iob->offset = o;
1989 0 : return 0;
1990 : }
1991 :
1992 : static int64_t
1993 0 : ne_buffer_tell(void * userdata)
1994 : {
1995 0 : struct io_buffer * iob = userdata;
1996 0 : return iob->offset;
1997 : }
1998 :
1999 : static int
2000 0 : ne_context_new(nestegg ** context, nestegg_io io, nestegg_log callback)
2001 : {
2002 : nestegg * ctx;
2003 :
2004 0 : if (!(io.read && io.seek && io.tell))
2005 0 : return -1;
2006 :
2007 0 : ctx = ne_alloc(sizeof(*ctx));
2008 0 : if (!ctx)
2009 0 : return -1;
2010 :
2011 0 : ctx->io = ne_alloc(sizeof(*ctx->io));
2012 0 : if (!ctx->io) {
2013 0 : nestegg_destroy(ctx);
2014 0 : return -1;
2015 : }
2016 0 : *ctx->io = io;
2017 0 : ctx->log = callback;
2018 0 : ctx->alloc_pool = ne_pool_init();
2019 0 : if (!ctx->alloc_pool) {
2020 0 : nestegg_destroy(ctx);
2021 0 : return -1;
2022 : }
2023 :
2024 0 : if (!ctx->log)
2025 0 : ctx->log = ne_null_log_callback;
2026 :
2027 0 : *context = ctx;
2028 0 : return 0;
2029 : }
2030 :
2031 : static int
2032 0 : ne_match_webm(nestegg_io io, int64_t max_offset)
2033 : {
2034 : int r;
2035 : uint64_t id;
2036 : char * doctype;
2037 : nestegg * ctx;
2038 :
2039 0 : if (ne_context_new(&ctx, io, NULL) != 0)
2040 0 : return -1;
2041 :
2042 0 : r = ne_peek_element(ctx, &id, NULL);
2043 0 : if (r != 1) {
2044 0 : nestegg_destroy(ctx);
2045 0 : return 0;
2046 : }
2047 :
2048 0 : if (id != ID_EBML) {
2049 0 : nestegg_destroy(ctx);
2050 0 : return 0;
2051 : }
2052 :
2053 0 : ne_ctx_push(ctx, ne_top_level_elements, ctx);
2054 :
2055 : /* we don't check the return value of ne_parse, that might fail because
2056 : max_offset is not on a valid element end point. We only want to check
2057 : the EBML ID and that the doctype is "webm". */
2058 0 : ne_parse(ctx, NULL, max_offset);
2059 0 : while (ctx->ancestor)
2060 0 : ne_ctx_pop(ctx);
2061 :
2062 0 : if (ne_get_string(ctx->ebml.doctype, &doctype) != 0 ||
2063 0 : strcmp(doctype, "webm") != 0) {
2064 0 : nestegg_destroy(ctx);
2065 0 : return 0;
2066 : }
2067 :
2068 0 : nestegg_destroy(ctx);
2069 :
2070 0 : return 1;
2071 : }
2072 :
2073 : int
2074 0 : nestegg_init(nestegg ** context, nestegg_io io, nestegg_log callback, int64_t max_offset)
2075 : {
2076 : int r;
2077 : uint64_t id, version, docversion;
2078 : struct ebml_list_node * track;
2079 : char * doctype;
2080 : nestegg * ctx;
2081 :
2082 0 : if (ne_context_new(&ctx, io, callback) != 0)
2083 0 : return -1;
2084 :
2085 0 : r = ne_peek_element(ctx, &id, NULL);
2086 0 : if (r != 1) {
2087 0 : nestegg_destroy(ctx);
2088 0 : return -1;
2089 : }
2090 :
2091 0 : if (id != ID_EBML) {
2092 0 : nestegg_destroy(ctx);
2093 0 : return -1;
2094 : }
2095 :
2096 0 : ctx->log(ctx, NESTEGG_LOG_DEBUG, "ctx %p", ctx);
2097 :
2098 0 : ne_ctx_push(ctx, ne_top_level_elements, ctx);
2099 :
2100 0 : r = ne_parse(ctx, NULL, max_offset);
2101 0 : while (ctx->ancestor)
2102 0 : ne_ctx_pop(ctx);
2103 :
2104 0 : if (r != 1) {
2105 0 : nestegg_destroy(ctx);
2106 0 : return -1;
2107 : }
2108 :
2109 0 : if (ne_get_uint(ctx->ebml.ebml_read_version, &version) != 0)
2110 0 : version = 1;
2111 0 : if (version != 1) {
2112 0 : nestegg_destroy(ctx);
2113 0 : return -1;
2114 : }
2115 :
2116 0 : if (ne_get_string(ctx->ebml.doctype, &doctype) != 0)
2117 0 : doctype = "matroska";
2118 0 : if (strcmp(doctype, "webm") != 0) {
2119 0 : nestegg_destroy(ctx);
2120 0 : return -1;
2121 : }
2122 :
2123 0 : if (ne_get_uint(ctx->ebml.doctype_read_version, &docversion) != 0)
2124 0 : docversion = 1;
2125 0 : if (docversion < 1 || docversion > 2) {
2126 0 : nestegg_destroy(ctx);
2127 0 : return -1;
2128 : }
2129 :
2130 0 : if (!ctx->segment.tracks.track_entry.head) {
2131 0 : nestegg_destroy(ctx);
2132 0 : return -1;
2133 : }
2134 :
2135 0 : track = ctx->segment.tracks.track_entry.head;
2136 0 : ctx->track_count = 0;
2137 :
2138 0 : while (track) {
2139 0 : ctx->track_count += 1;
2140 0 : track = track->next;
2141 : }
2142 :
2143 0 : r = ne_ctx_save(ctx, &ctx->saved);
2144 0 : if (r != 0) {
2145 0 : nestegg_destroy(ctx);
2146 0 : return -1;
2147 : }
2148 :
2149 0 : *context = ctx;
2150 :
2151 0 : return 0;
2152 : }
2153 :
2154 : void
2155 0 : nestegg_destroy(nestegg * ctx)
2156 : {
2157 0 : assert(ctx->ancestor == NULL);
2158 0 : ne_pool_destroy(ctx->alloc_pool);
2159 0 : free(ctx->io);
2160 0 : free(ctx);
2161 0 : }
2162 :
2163 : int
2164 0 : nestegg_duration(nestegg * ctx, uint64_t * duration)
2165 : {
2166 : uint64_t tc_scale;
2167 : double unscaled_duration;
2168 :
2169 0 : if (ne_get_float(ctx->segment.info.duration, &unscaled_duration) != 0)
2170 0 : return -1;
2171 :
2172 0 : tc_scale = ne_get_timecode_scale(ctx);
2173 0 : if (tc_scale == 0)
2174 0 : return -1;
2175 :
2176 0 : if (unscaled_duration != unscaled_duration ||
2177 0 : unscaled_duration < 0 || unscaled_duration > (double) UINT64_MAX ||
2178 0 : (uint64_t) unscaled_duration > UINT64_MAX / tc_scale)
2179 0 : return -1;
2180 :
2181 0 : *duration = (uint64_t) (unscaled_duration * tc_scale);
2182 0 : return 0;
2183 : }
2184 :
2185 : int
2186 0 : nestegg_tstamp_scale(nestegg * ctx, uint64_t * scale)
2187 : {
2188 0 : *scale = ne_get_timecode_scale(ctx);
2189 0 : if (*scale == 0)
2190 0 : return -1;
2191 0 : return 0;
2192 : }
2193 :
2194 : int
2195 0 : nestegg_track_count(nestegg * ctx, unsigned int * tracks)
2196 : {
2197 0 : *tracks = ctx->track_count;
2198 0 : return 0;
2199 : }
2200 :
2201 : int
2202 0 : nestegg_get_cue_point(nestegg * ctx, unsigned int cluster_num, int64_t max_offset,
2203 : int64_t * start_pos, int64_t * end_pos, uint64_t * tstamp)
2204 : {
2205 0 : int range_obtained = 0;
2206 0 : unsigned int cluster_count = 0;
2207 : struct cue_point * cue_point;
2208 : struct cue_track_positions * pos;
2209 : uint64_t seek_pos, track_number, tc_scale, time;
2210 0 : struct ebml_list_node * cues_node = ctx->segment.cues.cue_point.head;
2211 0 : struct ebml_list_node * cue_pos_node = NULL;
2212 0 : unsigned int track = 0, track_count = 0, track_index;
2213 :
2214 0 : if (!start_pos || !end_pos || !tstamp)
2215 0 : return -1;
2216 :
2217 : /* Initialise return values */
2218 0 : *start_pos = -1;
2219 0 : *end_pos = -1;
2220 0 : *tstamp = 0;
2221 :
2222 0 : if (!cues_node) {
2223 0 : ne_init_cue_points(ctx, max_offset);
2224 0 : cues_node = ctx->segment.cues.cue_point.head;
2225 : /* Verify cues have been added to context. */
2226 0 : if (!cues_node)
2227 0 : return -1;
2228 : }
2229 :
2230 0 : nestegg_track_count(ctx, &track_count);
2231 :
2232 0 : tc_scale = ne_get_timecode_scale(ctx);
2233 0 : if (tc_scale == 0)
2234 0 : return -1;
2235 :
2236 0 : while (cues_node && !range_obtained) {
2237 0 : assert(cues_node->id == ID_CUE_POINT);
2238 0 : cue_point = cues_node->data;
2239 0 : cue_pos_node = cue_point->cue_track_positions.head;
2240 0 : while (cue_pos_node) {
2241 0 : assert(cue_pos_node->id == ID_CUE_TRACK_POSITIONS);
2242 0 : pos = cue_pos_node->data;
2243 0 : for (track = 0; track < track_count; ++track) {
2244 0 : if (ne_get_uint(pos->track, &track_number) != 0)
2245 0 : return -1;
2246 :
2247 0 : if (ne_map_track_number_to_index(ctx, track_number, &track_index) != 0)
2248 0 : return -1;
2249 :
2250 0 : if (track_index == track) {
2251 0 : if (ne_get_uint(pos->cluster_position, &seek_pos) != 0)
2252 0 : return -1;
2253 0 : if (cluster_count == cluster_num) {
2254 0 : *start_pos = ctx->segment_offset + seek_pos;
2255 0 : if (ne_get_uint(cue_point->time, &time) != 0)
2256 0 : return -1;
2257 0 : *tstamp = time * tc_scale;
2258 0 : } else if (cluster_count == cluster_num + 1) {
2259 0 : *end_pos = ctx->segment_offset + seek_pos - 1;
2260 0 : range_obtained = 1;
2261 0 : break;
2262 : }
2263 0 : cluster_count++;
2264 : }
2265 : }
2266 0 : cue_pos_node = cue_pos_node->next;
2267 : }
2268 0 : cues_node = cues_node->next;
2269 : }
2270 :
2271 0 : return 0;
2272 : }
2273 :
2274 : int
2275 0 : nestegg_offset_seek(nestegg * ctx, uint64_t offset)
2276 : {
2277 : int r;
2278 :
2279 0 : if (offset > INT64_MAX)
2280 0 : return -1;
2281 :
2282 : /* Seek and set up parser state for segment-level element (Cluster). */
2283 0 : r = ne_io_seek(ctx->io, offset, NESTEGG_SEEK_SET);
2284 0 : if (r != 0)
2285 0 : return -1;
2286 0 : ctx->last_valid = 0;
2287 :
2288 0 : assert(ctx->ancestor == NULL);
2289 :
2290 0 : return 0;
2291 : }
2292 :
2293 : int
2294 0 : nestegg_track_seek(nestegg * ctx, unsigned int track, uint64_t tstamp)
2295 : {
2296 : int r;
2297 : struct cue_point * cue_point;
2298 : struct cue_track_positions * pos;
2299 : uint64_t seek_pos, tc_scale;
2300 :
2301 : /* If there are no cues loaded, check for cues element in the seek head
2302 : and load it. */
2303 0 : if (!ctx->segment.cues.cue_point.head) {
2304 0 : r = ne_init_cue_points(ctx, -1);
2305 0 : if (r != 0)
2306 0 : return -1;
2307 : }
2308 :
2309 0 : tc_scale = ne_get_timecode_scale(ctx);
2310 0 : if (tc_scale == 0)
2311 0 : return -1;
2312 :
2313 0 : cue_point = ne_find_cue_point_for_tstamp(ctx, ctx->segment.cues.cue_point.head,
2314 : track, tc_scale, tstamp);
2315 0 : if (!cue_point)
2316 0 : return -1;
2317 :
2318 0 : pos = ne_find_cue_position_for_track(ctx, cue_point->cue_track_positions.head, track);
2319 0 : if (pos == NULL)
2320 0 : return -1;
2321 :
2322 0 : if (ne_get_uint(pos->cluster_position, &seek_pos) != 0)
2323 0 : return -1;
2324 :
2325 : /* Seek to (we assume) the start of a Cluster element. */
2326 0 : r = nestegg_offset_seek(ctx, ctx->segment_offset + seek_pos);
2327 0 : if (r != 0)
2328 0 : return -1;
2329 :
2330 0 : return 0;
2331 : }
2332 :
2333 : int
2334 0 : nestegg_track_type(nestegg * ctx, unsigned int track)
2335 : {
2336 : struct track_entry * entry;
2337 : uint64_t type;
2338 :
2339 0 : entry = ne_find_track_entry(ctx, track);
2340 0 : if (!entry)
2341 0 : return -1;
2342 :
2343 0 : if (ne_get_uint(entry->type, &type) != 0)
2344 0 : return -1;
2345 :
2346 0 : if (type & TRACK_TYPE_VIDEO)
2347 0 : return NESTEGG_TRACK_VIDEO;
2348 :
2349 0 : if (type & TRACK_TYPE_AUDIO)
2350 0 : return NESTEGG_TRACK_AUDIO;
2351 :
2352 0 : return NESTEGG_TRACK_UNKNOWN;
2353 : }
2354 :
2355 : int
2356 0 : nestegg_track_codec_id(nestegg * ctx, unsigned int track)
2357 : {
2358 : char * codec_id;
2359 : struct track_entry * entry;
2360 :
2361 0 : entry = ne_find_track_entry(ctx, track);
2362 0 : if (!entry)
2363 0 : return -1;
2364 :
2365 0 : if (ne_get_string(entry->codec_id, &codec_id) != 0)
2366 0 : return -1;
2367 :
2368 0 : if (strcmp(codec_id, TRACK_ID_VP8) == 0)
2369 0 : return NESTEGG_CODEC_VP8;
2370 :
2371 0 : if (strcmp(codec_id, TRACK_ID_VP9) == 0)
2372 0 : return NESTEGG_CODEC_VP9;
2373 :
2374 0 : if (strcmp(codec_id, TRACK_ID_AV1) == 0)
2375 0 : return NESTEGG_CODEC_AV1;
2376 :
2377 0 : if (strcmp(codec_id, TRACK_ID_VORBIS) == 0)
2378 0 : return NESTEGG_CODEC_VORBIS;
2379 :
2380 0 : if (strcmp(codec_id, TRACK_ID_OPUS) == 0)
2381 0 : return NESTEGG_CODEC_OPUS;
2382 :
2383 0 : return NESTEGG_CODEC_UNKNOWN;
2384 : }
2385 :
2386 : int
2387 0 : nestegg_track_codec_data_count(nestegg * ctx, unsigned int track,
2388 : unsigned int * count)
2389 : {
2390 : struct track_entry * entry;
2391 : struct ebml_binary codec_private;
2392 : int codec_id;
2393 : unsigned char * p;
2394 :
2395 0 : *count = 0;
2396 :
2397 0 : entry = ne_find_track_entry(ctx, track);
2398 0 : if (!entry)
2399 0 : return -1;
2400 :
2401 0 : codec_id = nestegg_track_codec_id(ctx, track);
2402 :
2403 0 : if (codec_id == NESTEGG_CODEC_OPUS) {
2404 0 : *count = 1;
2405 0 : return 0;
2406 : }
2407 :
2408 0 : if (codec_id != NESTEGG_CODEC_VORBIS)
2409 0 : return -1;
2410 :
2411 0 : if (ne_get_binary(entry->codec_private, &codec_private) != 0)
2412 0 : return -1;
2413 :
2414 0 : if (codec_private.length < 1)
2415 0 : return -1;
2416 :
2417 0 : p = codec_private.data;
2418 0 : *count = *p + 1;
2419 :
2420 0 : if (*count > 3)
2421 0 : return -1;
2422 :
2423 0 : return 0;
2424 : }
2425 :
2426 : int
2427 0 : nestegg_track_codec_data(nestegg * ctx, unsigned int track, unsigned int item,
2428 : unsigned char ** data, size_t * length)
2429 : {
2430 : struct track_entry * entry;
2431 : struct ebml_binary codec_private;
2432 :
2433 0 : *data = NULL;
2434 0 : *length = 0;
2435 :
2436 0 : entry = ne_find_track_entry(ctx, track);
2437 0 : if (!entry)
2438 0 : return -1;
2439 :
2440 0 : if (nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_VORBIS &&
2441 0 : nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_OPUS)
2442 0 : return -1;
2443 :
2444 0 : if (ne_get_binary(entry->codec_private, &codec_private) != 0)
2445 0 : return -1;
2446 :
2447 0 : if (nestegg_track_codec_id(ctx, track) == NESTEGG_CODEC_VORBIS) {
2448 : uint64_t count;
2449 : uint64_t sizes[3];
2450 : size_t total;
2451 : unsigned char * p;
2452 : unsigned int i;
2453 : int r;
2454 :
2455 : nestegg_io io;
2456 : struct io_buffer userdata;
2457 0 : userdata.buffer = codec_private.data;
2458 0 : userdata.length = codec_private.length;
2459 0 : userdata.offset = 0;
2460 :
2461 0 : io.read = ne_buffer_read;
2462 0 : io.seek = ne_buffer_seek;
2463 0 : io.tell = ne_buffer_tell;
2464 0 : io.userdata = &userdata;
2465 :
2466 0 : total = 0;
2467 :
2468 0 : r = ne_read_uint(&io, &count, 1);
2469 0 : if (r != 1)
2470 0 : return r;
2471 0 : total += 1;
2472 0 : count += 1;
2473 :
2474 0 : if (count > 3)
2475 0 : return -1;
2476 0 : r = ne_read_xiph_lacing(&io, codec_private.length, &total, count, sizes);
2477 0 : if (r != 1)
2478 0 : return r;
2479 :
2480 0 : if (item >= count)
2481 0 : return -1;
2482 :
2483 0 : p = codec_private.data + total;
2484 0 : for (i = 0; i < item; ++i) {
2485 0 : p += sizes[i];
2486 : }
2487 0 : assert((size_t) (p - codec_private.data) <= codec_private.length &&
2488 : codec_private.length - (p - codec_private.data) >= sizes[item]);
2489 0 : *data = p;
2490 0 : *length = sizes[item];
2491 : } else {
2492 0 : if (item >= 1)
2493 0 : return -1;
2494 :
2495 0 : *data = codec_private.data;
2496 0 : *length = codec_private.length;
2497 : }
2498 :
2499 0 : return 0;
2500 : }
2501 :
2502 : int
2503 0 : nestegg_track_video_params(nestegg * ctx, unsigned int track,
2504 : nestegg_video_params * params)
2505 : {
2506 : struct track_entry * entry;
2507 : uint64_t value;
2508 :
2509 0 : memset(params, 0, sizeof(*params));
2510 :
2511 0 : entry = ne_find_track_entry(ctx, track);
2512 0 : if (!entry)
2513 0 : return -1;
2514 :
2515 0 : if (nestegg_track_type(ctx, track) != NESTEGG_TRACK_VIDEO)
2516 0 : return -1;
2517 :
2518 0 : value = 0;
2519 0 : ne_get_uint(entry->video.stereo_mode, &value);
2520 0 : if (value <= NESTEGG_VIDEO_STEREO_TOP_BOTTOM ||
2521 0 : value == NESTEGG_VIDEO_STEREO_RIGHT_LEFT)
2522 0 : params->stereo_mode = value;
2523 :
2524 0 : value = 0;
2525 0 : ne_get_uint(entry->video.alpha_mode, &value);
2526 0 : params->alpha_mode = value;
2527 :
2528 0 : if (ne_get_uint(entry->video.pixel_width, &value) != 0)
2529 0 : return -1;
2530 0 : params->width = value;
2531 :
2532 0 : if (ne_get_uint(entry->video.pixel_height, &value) != 0)
2533 0 : return -1;
2534 0 : params->height = value;
2535 :
2536 0 : value = 0;
2537 0 : ne_get_uint(entry->video.pixel_crop_bottom, &value);
2538 0 : params->crop_bottom = value;
2539 :
2540 0 : value = 0;
2541 0 : ne_get_uint(entry->video.pixel_crop_top, &value);
2542 0 : params->crop_top = value;
2543 :
2544 0 : value = 0;
2545 0 : ne_get_uint(entry->video.pixel_crop_left, &value);
2546 0 : params->crop_left = value;
2547 :
2548 0 : value = 0;
2549 0 : ne_get_uint(entry->video.pixel_crop_right, &value);
2550 0 : params->crop_right = value;
2551 :
2552 0 : value = params->width;
2553 0 : ne_get_uint(entry->video.display_width, &value);
2554 0 : params->display_width = value;
2555 :
2556 0 : value = params->height;
2557 0 : ne_get_uint(entry->video.display_height, &value);
2558 0 : params->display_height = value;
2559 :
2560 0 : return 0;
2561 : }
2562 :
2563 : int
2564 0 : nestegg_track_audio_params(nestegg * ctx, unsigned int track,
2565 : nestegg_audio_params * params)
2566 : {
2567 : struct track_entry * entry;
2568 : uint64_t value;
2569 :
2570 0 : memset(params, 0, sizeof(*params));
2571 :
2572 0 : entry = ne_find_track_entry(ctx, track);
2573 0 : if (!entry)
2574 0 : return -1;
2575 :
2576 0 : if (nestegg_track_type(ctx, track) != NESTEGG_TRACK_AUDIO)
2577 0 : return -1;
2578 :
2579 0 : params->rate = 8000;
2580 0 : ne_get_float(entry->audio.sampling_frequency, ¶ms->rate);
2581 :
2582 0 : value = 1;
2583 0 : ne_get_uint(entry->audio.channels, &value);
2584 0 : params->channels = value;
2585 :
2586 0 : value = 16;
2587 0 : ne_get_uint(entry->audio.bit_depth, &value);
2588 0 : params->depth = value;
2589 :
2590 0 : value = 0;
2591 0 : ne_get_uint(entry->codec_delay, &value);
2592 0 : params->codec_delay = value;
2593 :
2594 0 : value = 0;
2595 0 : ne_get_uint(entry->seek_preroll, &value);
2596 0 : params->seek_preroll = value;
2597 :
2598 0 : return 0;
2599 : }
2600 :
2601 : int
2602 0 : nestegg_track_encoding(nestegg * ctx, unsigned int track)
2603 : {
2604 : struct track_entry * entry;
2605 : struct content_encoding * encoding;
2606 : uint64_t encoding_value;
2607 :
2608 0 : entry = ne_find_track_entry(ctx, track);
2609 0 : if (!entry) {
2610 0 : ctx->log(ctx, NESTEGG_LOG_ERROR, "No track entry found");
2611 0 : return -1;
2612 : }
2613 :
2614 0 : if (!entry->content_encodings.content_encoding.head) {
2615 : /* Default encoding is compression */
2616 0 : return NESTEGG_ENCODING_COMPRESSION;
2617 : }
2618 :
2619 0 : encoding = entry->content_encodings.content_encoding.head->data;
2620 :
2621 0 : encoding_value = NESTEGG_ENCODING_COMPRESSION;
2622 0 : ne_get_uint(encoding->content_encoding_type, &encoding_value);
2623 0 : if (encoding_value != NESTEGG_ENCODING_COMPRESSION && encoding_value != NESTEGG_ENCODING_ENCRYPTION) {
2624 0 : ctx->log(ctx, NESTEGG_LOG_ERROR, "Invalid ContentEncoding element found");
2625 0 : return -1;
2626 : }
2627 :
2628 0 : return encoding_value;
2629 : }
2630 :
2631 : int
2632 0 : nestegg_track_content_enc_key_id(nestegg * ctx, unsigned int track, unsigned char const ** content_enc_key_id,
2633 : size_t * content_enc_key_id_length)
2634 : {
2635 : struct track_entry * entry;
2636 : struct content_encoding * encoding;
2637 : struct content_encryption * encryption;
2638 : struct content_enc_aes_settings * aes_settings;
2639 : struct nestegg_encryption_params;
2640 : uint64_t value;
2641 : struct ebml_binary enc_key_id;
2642 :
2643 0 : entry = ne_find_track_entry(ctx, track);
2644 0 : if (!entry) {
2645 0 : ctx->log(ctx, NESTEGG_LOG_ERROR, "No track entry found");
2646 0 : return -1;
2647 : }
2648 :
2649 0 : if (!entry->content_encodings.content_encoding.head) {
2650 0 : ctx->log(ctx, NESTEGG_LOG_ERROR, "No ContentEncoding element found");
2651 0 : return -1;
2652 : }
2653 :
2654 0 : encoding = entry->content_encodings.content_encoding.head->data;
2655 :
2656 0 : value = 0;
2657 0 : ne_get_uint(encoding->content_encoding_type, &value);
2658 0 : if (value != NESTEGG_ENCODING_ENCRYPTION) {
2659 0 : ctx->log(ctx, NESTEGG_LOG_ERROR, "Disallowed ContentEncodingType found");
2660 0 : return -1;
2661 : }
2662 :
2663 0 : if (!encoding->content_encryption.head) {
2664 0 : ctx->log(ctx, NESTEGG_LOG_ERROR, "No ContentEncryption element found");
2665 0 : return -1;
2666 : }
2667 :
2668 0 : encryption = encoding->content_encryption.head->data;
2669 :
2670 0 : value = 0;
2671 0 : ne_get_uint(encryption->content_enc_algo, &value);
2672 :
2673 0 : if (value != CONTENT_ENC_ALGO_AES) {
2674 0 : ctx->log(ctx, NESTEGG_LOG_ERROR, "Disallowed ContentEncAlgo found");
2675 0 : return -1;
2676 : }
2677 :
2678 0 : if (!encryption->content_enc_aes_settings.head) {
2679 0 : ctx->log(ctx, NESTEGG_LOG_ERROR, "No ContentEncAesSettings element found");
2680 0 : return -1;
2681 : }
2682 :
2683 0 : aes_settings = encryption->content_enc_aes_settings.head->data;
2684 0 : value = AES_SETTINGS_CIPHER_CTR;
2685 0 : ne_get_uint(aes_settings->aes_settings_cipher_mode, &value);
2686 :
2687 0 : if (value != AES_SETTINGS_CIPHER_CTR) {
2688 0 : ctx->log(ctx, NESTEGG_LOG_ERROR, "Disallowed AESSettingCipherMode used");
2689 0 : return -1;
2690 : }
2691 :
2692 0 : if (ne_get_binary(encryption->content_enc_key_id, &enc_key_id) != 0) {
2693 0 : ctx->log(ctx, NESTEGG_LOG_ERROR, "Could not retrieve track ContentEncKeyId");
2694 0 : return -1;
2695 : }
2696 :
2697 0 : *content_enc_key_id = enc_key_id.data;
2698 0 : *content_enc_key_id_length = enc_key_id.length;
2699 :
2700 0 : return 0;
2701 : }
2702 :
2703 : int
2704 0 : nestegg_track_default_duration(nestegg * ctx, unsigned int track,
2705 : uint64_t * duration)
2706 : {
2707 : struct track_entry * entry;
2708 : uint64_t value;
2709 :
2710 0 : entry = ne_find_track_entry(ctx, track);
2711 0 : if (!entry)
2712 0 : return -1;
2713 :
2714 0 : if (ne_get_uint(entry->default_duration, &value) != 0)
2715 0 : return -1;
2716 0 : *duration = value;
2717 :
2718 0 : return 0;
2719 : }
2720 :
2721 : int
2722 0 : nestegg_read_reset(nestegg * ctx)
2723 : {
2724 0 : assert(ctx->ancestor == NULL);
2725 0 : return ne_ctx_restore(ctx, &ctx->saved);
2726 : }
2727 :
2728 : int
2729 0 : nestegg_read_packet(nestegg * ctx, nestegg_packet ** pkt)
2730 : {
2731 0 : int r, read_block = 0;
2732 : uint64_t id, size;
2733 :
2734 0 : *pkt = NULL;
2735 :
2736 0 : assert(ctx->ancestor == NULL);
2737 :
2738 : /* Prepare for read_reset to resume parsing from this point upon error. */
2739 0 : r = ne_ctx_save(ctx, &ctx->saved);
2740 0 : if (r != 0)
2741 0 : return -1;
2742 :
2743 0 : while (!read_block) {
2744 0 : r = ne_read_element(ctx, &id, &size);
2745 0 : if (r != 1)
2746 0 : return r;
2747 :
2748 0 : switch (id) {
2749 : case ID_CLUSTER: {
2750 0 : r = ne_read_element(ctx, &id, &size);
2751 0 : if (r != 1)
2752 0 : return r;
2753 :
2754 : /* Timecode must be the first element in a Cluster, per spec. */
2755 0 : if (id != ID_TIMECODE)
2756 0 : return -1;
2757 :
2758 0 : r = ne_read_uint(ctx->io, &ctx->cluster_timecode, size);
2759 0 : if (r != 1)
2760 0 : return r;
2761 0 : ctx->read_cluster_timecode = 1;
2762 0 : break;
2763 : }
2764 : case ID_SIMPLE_BLOCK:
2765 0 : r = ne_read_block(ctx, id, size, pkt);
2766 0 : if (r != 1)
2767 0 : return r;
2768 :
2769 0 : read_block = 1;
2770 0 : break;
2771 : case ID_BLOCK_GROUP: {
2772 : int64_t block_group_end;
2773 0 : uint64_t block_duration = 0;
2774 0 : int read_block_duration = 0;
2775 0 : int64_t discard_padding = 0;
2776 0 : int read_discard_padding = 0;
2777 0 : int64_t reference_block = 0;
2778 0 : int read_reference_block = 0;
2779 0 : struct block_additional * block_additional = NULL;
2780 : uint64_t tc_scale;
2781 :
2782 0 : block_group_end = ne_io_tell(ctx->io) + size;
2783 :
2784 : /* Read the entire BlockGroup manually. */
2785 0 : while (ne_io_tell(ctx->io) < block_group_end) {
2786 0 : r = ne_read_element(ctx, &id, &size);
2787 0 : if (r != 1) {
2788 0 : free(block_additional);
2789 0 : if (*pkt) {
2790 0 : nestegg_free_packet(*pkt);
2791 0 : *pkt = NULL;
2792 : }
2793 0 : return r;
2794 : }
2795 :
2796 0 : switch (id) {
2797 : case ID_BLOCK: {
2798 0 : r = ne_read_block(ctx, id, size, pkt);
2799 0 : if (r != 1) {
2800 0 : free(block_additional);
2801 0 : if (*pkt) {
2802 0 : nestegg_free_packet(*pkt);
2803 0 : *pkt = NULL;
2804 : }
2805 0 : return r;
2806 : }
2807 :
2808 0 : read_block = 1;
2809 0 : break;
2810 : }
2811 : case ID_BLOCK_DURATION: {
2812 0 : r = ne_read_uint(ctx->io, &block_duration, size);
2813 0 : if (r != 1) {
2814 0 : free(block_additional);
2815 0 : if (*pkt) {
2816 0 : nestegg_free_packet(*pkt);
2817 0 : *pkt = NULL;
2818 : }
2819 0 : return r;
2820 : }
2821 0 : tc_scale = ne_get_timecode_scale(ctx);
2822 0 : if (tc_scale == 0) {
2823 0 : free(block_additional);
2824 0 : if (*pkt) {
2825 0 : nestegg_free_packet(*pkt);
2826 0 : *pkt = NULL;
2827 : }
2828 0 : return -1;
2829 : }
2830 0 : block_duration *= tc_scale;
2831 0 : read_block_duration = 1;
2832 0 : break;
2833 : }
2834 : case ID_DISCARD_PADDING: {
2835 0 : r = ne_read_int(ctx->io, &discard_padding, size);
2836 0 : if (r != 1) {
2837 0 : free(block_additional);
2838 0 : if (*pkt) {
2839 0 : nestegg_free_packet(*pkt);
2840 0 : *pkt = NULL;
2841 : }
2842 0 : return r;
2843 : }
2844 0 : read_discard_padding = 1;
2845 0 : break;
2846 : }
2847 : case ID_BLOCK_ADDITIONS: {
2848 : /* There should only be one BlockAdditions; treat multiple as an error. */
2849 0 : if (block_additional) {
2850 0 : free(block_additional);
2851 0 : if (*pkt) {
2852 0 : nestegg_free_packet(*pkt);
2853 0 : *pkt = NULL;
2854 : }
2855 0 : return -1;
2856 : }
2857 0 : r = ne_read_block_additions(ctx, size, &block_additional);
2858 0 : if (r != 1) {
2859 0 : free(block_additional);
2860 0 : if (*pkt) {
2861 0 : nestegg_free_packet(*pkt);
2862 0 : *pkt = NULL;
2863 : }
2864 0 : return r;
2865 : }
2866 0 : break;
2867 : }
2868 : case ID_REFERENCE_BLOCK: {
2869 0 : r = ne_read_int(ctx->io, &reference_block, size);
2870 0 : if (r != 1) {
2871 0 : free(block_additional);
2872 0 : if (*pkt) {
2873 0 : nestegg_free_packet(*pkt);
2874 0 : *pkt = NULL;
2875 : }
2876 0 : return r;
2877 : }
2878 0 : read_reference_block = 1;
2879 0 : break;
2880 : }
2881 : default:
2882 : /* We don't know what this element is, so skip over it */
2883 0 : if (id != ID_VOID && id != ID_CRC32)
2884 0 : ctx->log(ctx, NESTEGG_LOG_DEBUG,
2885 : "read_packet: unknown element %llx in BlockGroup", id);
2886 0 : r = ne_io_read_skip(ctx->io, size);
2887 0 : if (r != 1) {
2888 0 : free(block_additional);
2889 0 : if (*pkt) {
2890 0 : nestegg_free_packet(*pkt);
2891 0 : *pkt = NULL;
2892 : }
2893 0 : return r;
2894 : }
2895 : }
2896 : }
2897 :
2898 0 : assert(read_block == (*pkt != NULL));
2899 0 : if (*pkt) {
2900 0 : (*pkt)->duration = block_duration;
2901 0 : (*pkt)->read_duration = read_block_duration;
2902 0 : (*pkt)->discard_padding = discard_padding;
2903 0 : (*pkt)->read_discard_padding = read_discard_padding;
2904 0 : (*pkt)->reference_block = reference_block;
2905 0 : (*pkt)->read_reference_block = read_reference_block;
2906 0 : (*pkt)->block_additional = block_additional;
2907 0 : if ((*pkt)->read_reference_block)
2908 : /* If a packet has a reference block it contains
2909 : predictive frames and no keyframes */
2910 0 : (*pkt)->keyframe = NESTEGG_PACKET_HAS_KEYFRAME_FALSE;
2911 : } else {
2912 0 : free(block_additional);
2913 : }
2914 0 : break;
2915 : }
2916 : default:
2917 0 : ctx->log(ctx, NESTEGG_LOG_DEBUG, "read_packet: unknown element %llx", id);
2918 0 : r = ne_io_read_skip(ctx->io, size);
2919 0 : if (r != 1)
2920 0 : return r;
2921 : }
2922 : }
2923 :
2924 0 : return 1;
2925 : }
2926 :
2927 : void
2928 0 : nestegg_free_packet(nestegg_packet * pkt)
2929 : {
2930 : struct frame * frame;
2931 : struct block_additional * block_additional;
2932 :
2933 0 : while (pkt->frame) {
2934 0 : frame = pkt->frame;
2935 0 : pkt->frame = frame->next;
2936 :
2937 0 : ne_free_frame(frame);
2938 : }
2939 :
2940 0 : while (pkt->block_additional) {
2941 0 : block_additional = pkt->block_additional;
2942 0 : pkt->block_additional = block_additional->next;
2943 0 : free(block_additional->data);
2944 0 : free(block_additional);
2945 : }
2946 :
2947 0 : free(pkt);
2948 0 : }
2949 :
2950 : int
2951 0 : nestegg_packet_has_keyframe(nestegg_packet * pkt)
2952 : {
2953 0 : return pkt->keyframe;
2954 : }
2955 :
2956 : int
2957 0 : nestegg_packet_track(nestegg_packet * pkt, unsigned int * track)
2958 : {
2959 0 : *track = pkt->track;
2960 0 : return 0;
2961 : }
2962 :
2963 : int
2964 0 : nestegg_packet_tstamp(nestegg_packet * pkt, uint64_t * tstamp)
2965 : {
2966 0 : *tstamp = pkt->timecode;
2967 0 : return 0;
2968 : }
2969 :
2970 : int
2971 0 : nestegg_packet_duration(nestegg_packet * pkt, uint64_t * duration)
2972 : {
2973 0 : if (!pkt->read_duration)
2974 0 : return -1;
2975 0 : *duration = pkt->duration;
2976 0 : return 0;
2977 : }
2978 :
2979 : int
2980 0 : nestegg_packet_discard_padding(nestegg_packet * pkt, int64_t * discard_padding)
2981 : {
2982 0 : if (!pkt->read_discard_padding)
2983 0 : return -1;
2984 0 : *discard_padding = pkt->discard_padding;
2985 0 : return 0;
2986 : }
2987 :
2988 : int
2989 0 : nestegg_packet_reference_block(nestegg_packet * pkt, int64_t * reference_block)
2990 : {
2991 0 : if (!pkt->read_reference_block)
2992 0 : return -1;
2993 0 : *reference_block = pkt->reference_block;
2994 0 : return 0;
2995 : }
2996 :
2997 : int
2998 0 : nestegg_packet_count(nestegg_packet * pkt, unsigned int * count)
2999 : {
3000 0 : struct frame * f = pkt->frame;
3001 :
3002 0 : *count = 0;
3003 :
3004 0 : while (f) {
3005 0 : *count += 1;
3006 0 : f = f->next;
3007 : }
3008 :
3009 0 : return 0;
3010 : }
3011 :
3012 : int
3013 0 : nestegg_packet_data(nestegg_packet * pkt, unsigned int item,
3014 : unsigned char ** data, size_t * length)
3015 : {
3016 0 : struct frame * f = pkt->frame;
3017 0 : unsigned int count = 0;
3018 :
3019 0 : *data = NULL;
3020 0 : *length = 0;
3021 :
3022 0 : while (f) {
3023 0 : if (count == item) {
3024 0 : *data = f->data;
3025 0 : *length = f->length;
3026 0 : return 0;
3027 : }
3028 0 : count += 1;
3029 0 : f = f->next;
3030 : }
3031 :
3032 0 : return -1;
3033 : }
3034 :
3035 : int
3036 0 : nestegg_packet_additional_data(nestegg_packet * pkt, unsigned int id,
3037 : unsigned char ** data, size_t * length)
3038 : {
3039 0 : struct block_additional * a = pkt->block_additional;
3040 :
3041 0 : *data = NULL;
3042 0 : *length = 0;
3043 :
3044 0 : while (a) {
3045 0 : if (a->id == id) {
3046 0 : *data = a->data;
3047 0 : *length = a->length;
3048 0 : return 0;
3049 : }
3050 0 : a = a->next;
3051 : }
3052 :
3053 0 : return -1;
3054 : }
3055 :
3056 : int
3057 0 : nestegg_packet_encryption(nestegg_packet * pkt)
3058 : {
3059 0 : struct frame * f = pkt->frame;
3060 : unsigned char encrypted_bit;
3061 : unsigned char partitioned_bit;
3062 :
3063 0 : if (!f->frame_encryption)
3064 0 : return NESTEGG_PACKET_HAS_SIGNAL_BYTE_FALSE;
3065 :
3066 : /* Should never have parsed blocks with both encryption and lacing */
3067 0 : assert(f->next == NULL);
3068 :
3069 0 : encrypted_bit = f->frame_encryption->signal_byte & ENCRYPTED_BIT_MASK;
3070 0 : partitioned_bit = f->frame_encryption->signal_byte & PARTITIONED_BIT_MASK;
3071 :
3072 0 : if (encrypted_bit != PACKET_ENCRYPTED)
3073 0 : return NESTEGG_PACKET_HAS_SIGNAL_BYTE_UNENCRYPTED;
3074 :
3075 0 : if (partitioned_bit == PACKET_PARTITIONED)
3076 0 : return NESTEGG_PACKET_HAS_SIGNAL_BYTE_PARTITIONED;
3077 :
3078 0 : return NESTEGG_PACKET_HAS_SIGNAL_BYTE_ENCRYPTED;
3079 : }
3080 :
3081 : int
3082 0 : nestegg_packet_iv(nestegg_packet * pkt, unsigned char const ** iv, size_t * length)
3083 : {
3084 0 : struct frame * f = pkt->frame;
3085 : unsigned char encrypted_bit;
3086 :
3087 0 : *iv = NULL;
3088 0 : *length = 0;
3089 0 : if (!f->frame_encryption)
3090 0 : return -1;
3091 :
3092 : /* Should never have parsed blocks with both encryption and lacing */
3093 0 : assert(f->next == NULL);
3094 :
3095 0 : encrypted_bit = f->frame_encryption->signal_byte & ENCRYPTED_BIT_MASK;
3096 :
3097 0 : if (encrypted_bit != PACKET_ENCRYPTED)
3098 0 : return 0;
3099 :
3100 0 : *iv = f->frame_encryption->iv;
3101 0 : *length = f->frame_encryption->length;
3102 0 : return 0;
3103 : }
3104 :
3105 : int
3106 0 : nestegg_packet_offsets(nestegg_packet * pkt,
3107 : uint32_t const ** partition_offsets,
3108 : uint8_t * num_partitions)
3109 : {
3110 0 : struct frame * f = pkt->frame;
3111 : unsigned char encrypted_bit;
3112 : unsigned char partitioned_bit;
3113 :
3114 0 : *partition_offsets = NULL;
3115 0 : *num_partitions = 0;
3116 :
3117 0 : if (!f->frame_encryption)
3118 0 : return -1;
3119 :
3120 : /* Should never have parsed blocks with both encryption and lacing */
3121 0 : assert(f->next == NULL);
3122 :
3123 0 : encrypted_bit = f->frame_encryption->signal_byte & ENCRYPTED_BIT_MASK;
3124 0 : partitioned_bit = f->frame_encryption->signal_byte & PARTITIONED_BIT_MASK;
3125 :
3126 0 : if (encrypted_bit != PACKET_ENCRYPTED || partitioned_bit != PACKET_PARTITIONED)
3127 0 : return -1;
3128 :
3129 0 : *num_partitions = f->frame_encryption->num_partitions;
3130 0 : *partition_offsets = f->frame_encryption->partition_offsets;
3131 0 : return 0;
3132 : }
3133 :
3134 : int
3135 0 : nestegg_has_cues(nestegg * ctx)
3136 : {
3137 0 : return ctx->segment.cues.cue_point.head ||
3138 0 : ne_find_seek_for_id(ctx->segment.seek_head.head, ID_CUES);
3139 : }
3140 :
3141 : int
3142 0 : nestegg_sniff(unsigned char const * buffer, size_t length)
3143 : {
3144 : nestegg_io io;
3145 : struct io_buffer userdata;
3146 :
3147 0 : userdata.buffer = buffer;
3148 0 : userdata.length = length;
3149 0 : userdata.offset = 0;
3150 :
3151 0 : io.read = ne_buffer_read;
3152 0 : io.seek = ne_buffer_seek;
3153 0 : io.tell = ne_buffer_tell;
3154 0 : io.userdata = &userdata;
3155 0 : return ne_match_webm(io, length);
3156 : }
|