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