1233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* 2233d2500723e5594f3e7c70896ffeeef32b9c950ywan * Copyright © 2010 Mozilla Foundation 3233d2500723e5594f3e7c70896ffeeef32b9c950ywan * 4233d2500723e5594f3e7c70896ffeeef32b9c950ywan * This program is made available under an ISC-style license. See the 5233d2500723e5594f3e7c70896ffeeef32b9c950ywan * accompanying file LICENSE for details. 6233d2500723e5594f3e7c70896ffeeef32b9c950ywan */ 7233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <assert.h> 8233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <stdlib.h> 9233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include <string.h> 10233d2500723e5594f3e7c70896ffeeef32b9c950ywan 11233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "third_party/nestegg/halloc/halloc.h" 12233d2500723e5594f3e7c70896ffeeef32b9c950ywan#include "third_party/nestegg/include/nestegg/nestegg.h" 13233d2500723e5594f3e7c70896ffeeef32b9c950ywan 14233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* EBML Elements */ 15233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_EBML 0x1a45dfa3 16233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_EBML_VERSION 0x4286 17233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_EBML_READ_VERSION 0x42f7 18233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_EBML_MAX_ID_LENGTH 0x42f2 19233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_EBML_MAX_SIZE_LENGTH 0x42f3 20233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_DOCTYPE 0x4282 21233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_DOCTYPE_VERSION 0x4287 22233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_DOCTYPE_READ_VERSION 0x4285 23233d2500723e5594f3e7c70896ffeeef32b9c950ywan 24233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Global Elements */ 25233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_VOID 0xec 26233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_CRC32 0xbf 27233d2500723e5594f3e7c70896ffeeef32b9c950ywan 28233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* WebM Elements */ 29233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_SEGMENT 0x18538067 30233d2500723e5594f3e7c70896ffeeef32b9c950ywan 31233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Seek Head Elements */ 32233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_SEEK_HEAD 0x114d9b74 33233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_SEEK 0x4dbb 34233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_SEEK_ID 0x53ab 35233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_SEEK_POSITION 0x53ac 36233d2500723e5594f3e7c70896ffeeef32b9c950ywan 37233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Info Elements */ 38233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_INFO 0x1549a966 39233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_TIMECODE_SCALE 0x2ad7b1 40233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_DURATION 0x4489 41233d2500723e5594f3e7c70896ffeeef32b9c950ywan 42233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Cluster Elements */ 43233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_CLUSTER 0x1f43b675 44233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_TIMECODE 0xe7 45233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_BLOCK_GROUP 0xa0 46233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_SIMPLE_BLOCK 0xa3 47233d2500723e5594f3e7c70896ffeeef32b9c950ywan 48233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* BlockGroup Elements */ 49233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_BLOCK 0xa1 50233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_BLOCK_DURATION 0x9b 51233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_REFERENCE_BLOCK 0xfb 52233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_DISCARD_PADDING 0x75a2 53233d2500723e5594f3e7c70896ffeeef32b9c950ywan 54233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Tracks Elements */ 55233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_TRACKS 0x1654ae6b 56233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_TRACK_ENTRY 0xae 57233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_TRACK_NUMBER 0xd7 58233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_TRACK_UID 0x73c5 59233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_TRACK_TYPE 0x83 60233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_FLAG_ENABLED 0xb9 61233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_FLAG_DEFAULT 0x88 62233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_FLAG_LACING 0x9c 63233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_TRACK_TIMECODE_SCALE 0x23314f 64233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_LANGUAGE 0x22b59c 65233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_CODEC_ID 0x86 66233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_CODEC_PRIVATE 0x63a2 67233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_CODEC_DELAY 0x56aa 68233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_SEEK_PREROLL 0x56bb 69233d2500723e5594f3e7c70896ffeeef32b9c950ywan 70233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Video Elements */ 71233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_VIDEO 0xe0 72233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_STEREO_MODE 0x53b8 73233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_PIXEL_WIDTH 0xb0 74233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_PIXEL_HEIGHT 0xba 75233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_PIXEL_CROP_BOTTOM 0x54aa 76233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_PIXEL_CROP_TOP 0x54bb 77233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_PIXEL_CROP_LEFT 0x54cc 78233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_PIXEL_CROP_RIGHT 0x54dd 79233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_DISPLAY_WIDTH 0x54b0 80233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_DISPLAY_HEIGHT 0x54ba 81233d2500723e5594f3e7c70896ffeeef32b9c950ywan 82233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Audio Elements */ 83233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_AUDIO 0xe1 84233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_SAMPLING_FREQUENCY 0xb5 85233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_CHANNELS 0x9f 86233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_BIT_DEPTH 0x6264 87233d2500723e5594f3e7c70896ffeeef32b9c950ywan 88233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Cues Elements */ 89233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_CUES 0x1c53bb6b 90233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_CUE_POINT 0xbb 91233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_CUE_TIME 0xb3 92233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_CUE_TRACK_POSITIONS 0xb7 93233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_CUE_TRACK 0xf7 94233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_CUE_CLUSTER_POSITION 0xf1 95233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define ID_CUE_BLOCK_NUMBER 0x5378 96233d2500723e5594f3e7c70896ffeeef32b9c950ywan 97233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* EBML Types */ 98233d2500723e5594f3e7c70896ffeeef32b9c950ywanenum ebml_type_enum { 99233d2500723e5594f3e7c70896ffeeef32b9c950ywan TYPE_UNKNOWN, 100233d2500723e5594f3e7c70896ffeeef32b9c950ywan TYPE_MASTER, 101233d2500723e5594f3e7c70896ffeeef32b9c950ywan TYPE_UINT, 102233d2500723e5594f3e7c70896ffeeef32b9c950ywan TYPE_FLOAT, 103233d2500723e5594f3e7c70896ffeeef32b9c950ywan TYPE_INT, 104233d2500723e5594f3e7c70896ffeeef32b9c950ywan TYPE_STRING, 105233d2500723e5594f3e7c70896ffeeef32b9c950ywan TYPE_BINARY 106233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 107233d2500723e5594f3e7c70896ffeeef32b9c950ywan 108233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define LIMIT_STRING (1 << 20) 109233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define LIMIT_BINARY (1 << 24) 110233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define LIMIT_BLOCK (1 << 30) 111233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define LIMIT_FRAME (1 << 28) 112233d2500723e5594f3e7c70896ffeeef32b9c950ywan 113233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Field Flags */ 114233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define DESC_FLAG_NONE 0 115233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define DESC_FLAG_MULTI (1 << 0) 116233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define DESC_FLAG_SUSPEND (1 << 1) 117233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define DESC_FLAG_OFFSET (1 << 2) 118233d2500723e5594f3e7c70896ffeeef32b9c950ywan 119233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Block Header Flags */ 120233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define BLOCK_FLAGS_LACING 6 121233d2500723e5594f3e7c70896ffeeef32b9c950ywan 122233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Lacing Constants */ 123233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define LACING_NONE 0 124233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define LACING_XIPH 1 125233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define LACING_FIXED 2 126233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define LACING_EBML 3 127233d2500723e5594f3e7c70896ffeeef32b9c950ywan 128233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Track Types */ 129233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define TRACK_TYPE_VIDEO 1 130233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define TRACK_TYPE_AUDIO 2 131233d2500723e5594f3e7c70896ffeeef32b9c950ywan 132233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Track IDs */ 133233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define TRACK_ID_VP8 "V_VP8" 134233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define TRACK_ID_VP9 "V_VP9" 135233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define TRACK_ID_VORBIS "A_VORBIS" 136233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define TRACK_ID_OPUS "A_OPUS" 137233d2500723e5594f3e7c70896ffeeef32b9c950ywan 138233d2500723e5594f3e7c70896ffeeef32b9c950ywanenum vint_mask { 139233d2500723e5594f3e7c70896ffeeef32b9c950ywan MASK_NONE, 140233d2500723e5594f3e7c70896ffeeef32b9c950ywan MASK_FIRST_BIT 141233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 142233d2500723e5594f3e7c70896ffeeef32b9c950ywan 143233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct ebml_binary { 144233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned char * data; 145233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t length; 146233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 147233d2500723e5594f3e7c70896ffeeef32b9c950ywan 148233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct ebml_list_node { 149233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list_node * next; 150233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t id; 151233d2500723e5594f3e7c70896ffeeef32b9c950ywan void * data; 152233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 153233d2500723e5594f3e7c70896ffeeef32b9c950ywan 154233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct ebml_list { 155233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list_node * head; 156233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list_node * tail; 157233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 158233d2500723e5594f3e7c70896ffeeef32b9c950ywan 159233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct ebml_type { 160233d2500723e5594f3e7c70896ffeeef32b9c950ywan union ebml_value { 161233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t u; 162233d2500723e5594f3e7c70896ffeeef32b9c950ywan double f; 163233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t i; 164233d2500723e5594f3e7c70896ffeeef32b9c950ywan char * s; 165233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_binary b; 166233d2500723e5594f3e7c70896ffeeef32b9c950ywan } v; 167233d2500723e5594f3e7c70896ffeeef32b9c950ywan enum ebml_type_enum type; 168233d2500723e5594f3e7c70896ffeeef32b9c950ywan int read; 169233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 170233d2500723e5594f3e7c70896ffeeef32b9c950ywan 171233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* EBML Definitions */ 172233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct ebml { 173233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type ebml_version; 174233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type ebml_read_version; 175233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type ebml_max_id_length; 176233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type ebml_max_size_length; 177233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type doctype; 178233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type doctype_version; 179233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type doctype_read_version; 180233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 181233d2500723e5594f3e7c70896ffeeef32b9c950ywan 182233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Matroksa Definitions */ 183233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct seek { 184233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type id; 185233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type position; 186233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 187233d2500723e5594f3e7c70896ffeeef32b9c950ywan 188233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct seek_head { 189233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list seek; 190233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 191233d2500723e5594f3e7c70896ffeeef32b9c950ywan 192233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct info { 193233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type timecode_scale; 194233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type duration; 195233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 196233d2500723e5594f3e7c70896ffeeef32b9c950ywan 197233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct block_group { 198233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type duration; 199233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type reference_block; 200233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type discard_padding; 201233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 202233d2500723e5594f3e7c70896ffeeef32b9c950ywan 203233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct cluster { 204233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type timecode; 205233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list block_group; 206233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 207233d2500723e5594f3e7c70896ffeeef32b9c950ywan 208233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct video { 209233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type stereo_mode; 210233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type pixel_width; 211233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type pixel_height; 212233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type pixel_crop_bottom; 213233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type pixel_crop_top; 214233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type pixel_crop_left; 215233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type pixel_crop_right; 216233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type display_width; 217233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type display_height; 218233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 219233d2500723e5594f3e7c70896ffeeef32b9c950ywan 220233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct audio { 221233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type sampling_frequency; 222233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type channels; 223233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type bit_depth; 224233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 225233d2500723e5594f3e7c70896ffeeef32b9c950ywan 226233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct track_entry { 227233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type number; 228233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type uid; 229233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type type; 230233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type flag_enabled; 231233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type flag_default; 232233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type flag_lacing; 233233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type track_timecode_scale; 234233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type language; 235233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type codec_id; 236233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type codec_private; 237233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type codec_delay; 238233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type seek_preroll; 239233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct video video; 240233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct audio audio; 241233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 242233d2500723e5594f3e7c70896ffeeef32b9c950ywan 243233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct tracks { 244233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list track_entry; 245233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 246233d2500723e5594f3e7c70896ffeeef32b9c950ywan 247233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct cue_track_positions { 248233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type track; 249233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type cluster_position; 250233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type block_number; 251233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 252233d2500723e5594f3e7c70896ffeeef32b9c950ywan 253233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct cue_point { 254233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type time; 255233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list cue_track_positions; 256233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 257233d2500723e5594f3e7c70896ffeeef32b9c950ywan 258233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct cues { 259233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list cue_point; 260233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 261233d2500723e5594f3e7c70896ffeeef32b9c950ywan 262233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct segment { 263233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list seek_head; 264233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct info info; 265233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list cluster; 266233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct tracks tracks; 267233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct cues cues; 268233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 269233d2500723e5594f3e7c70896ffeeef32b9c950ywan 270233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Misc. */ 271233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct pool_ctx { 272233d2500723e5594f3e7c70896ffeeef32b9c950ywan char dummy; 273233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 274233d2500723e5594f3e7c70896ffeeef32b9c950ywan 275233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct list_node { 276233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct list_node * previous; 277233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_element_desc * node; 278233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned char * data; 279233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 280233d2500723e5594f3e7c70896ffeeef32b9c950ywan 281233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct saved_state { 282233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t stream_offset; 283233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct list_node * ancestor; 284233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t last_id; 285233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t last_size; 286233d2500723e5594f3e7c70896ffeeef32b9c950ywan int last_valid; 287233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 288233d2500723e5594f3e7c70896ffeeef32b9c950ywan 289233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct frame { 290233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned char * data; 291233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t length; 292233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct frame * next; 293233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 294233d2500723e5594f3e7c70896ffeeef32b9c950ywan 295233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Public (opaque) Structures */ 296233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct nestegg { 297233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_io * io; 298233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_log log; 299233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct pool_ctx * alloc_pool; 300233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t last_id; 301233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t last_size; 302233d2500723e5594f3e7c70896ffeeef32b9c950ywan int last_valid; 303233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct list_node * ancestor; 304233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml ebml; 305233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct segment segment; 306233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t segment_offset; 307233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int track_count; 308233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 309233d2500723e5594f3e7c70896ffeeef32b9c950ywan 310233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct nestegg_packet { 311233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t track; 312233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t timecode; 313233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct frame * frame; 314233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t discard_padding; 315233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 316233d2500723e5594f3e7c70896ffeeef32b9c950ywan 317233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Element Descriptor */ 318233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct ebml_element_desc { 319233d2500723e5594f3e7c70896ffeeef32b9c950ywan char const * name; 320233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t id; 321233d2500723e5594f3e7c70896ffeeef32b9c950ywan enum ebml_type_enum type; 322233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t offset; 323233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int flags; 324233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_element_desc * children; 325233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t size; 326233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t data_offset; 327233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 328233d2500723e5594f3e7c70896ffeeef32b9c950ywan 329233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define E_FIELD(ID, TYPE, STRUCT, FIELD) \ 330233d2500723e5594f3e7c70896ffeeef32b9c950ywan { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_NONE, NULL, 0, 0 } 331233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define E_MASTER(ID, TYPE, STRUCT, FIELD) \ 332233d2500723e5594f3e7c70896ffeeef32b9c950ywan { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_MULTI, ne_ ## FIELD ## _elements, \ 333233d2500723e5594f3e7c70896ffeeef32b9c950ywan sizeof(struct FIELD), 0 } 334233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define E_SINGLE_MASTER_O(ID, TYPE, STRUCT, FIELD) \ 335233d2500723e5594f3e7c70896ffeeef32b9c950ywan { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_OFFSET, ne_ ## FIELD ## _elements, 0, \ 336233d2500723e5594f3e7c70896ffeeef32b9c950ywan offsetof(STRUCT, FIELD ## _offset) } 337233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define E_SINGLE_MASTER(ID, TYPE, STRUCT, FIELD) \ 338233d2500723e5594f3e7c70896ffeeef32b9c950ywan { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_NONE, ne_ ## FIELD ## _elements, 0, 0 } 339233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define E_SUSPEND(ID, TYPE) \ 340233d2500723e5594f3e7c70896ffeeef32b9c950ywan { #ID, ID, TYPE, 0, DESC_FLAG_SUSPEND, NULL, 0, 0 } 341233d2500723e5594f3e7c70896ffeeef32b9c950ywan#define E_LAST \ 342233d2500723e5594f3e7c70896ffeeef32b9c950ywan { NULL, 0, 0, 0, DESC_FLAG_NONE, NULL, 0, 0 } 343233d2500723e5594f3e7c70896ffeeef32b9c950ywan 344233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* EBML Element Lists */ 345233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct ebml_element_desc ne_ebml_elements[] = { 346233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_EBML_VERSION, TYPE_UINT, struct ebml, ebml_version), 347233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_EBML_READ_VERSION, TYPE_UINT, struct ebml, ebml_read_version), 348233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_EBML_MAX_ID_LENGTH, TYPE_UINT, struct ebml, ebml_max_id_length), 349233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_EBML_MAX_SIZE_LENGTH, TYPE_UINT, struct ebml, ebml_max_size_length), 350233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_DOCTYPE, TYPE_STRING, struct ebml, doctype), 351233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_DOCTYPE_VERSION, TYPE_UINT, struct ebml, doctype_version), 352233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_DOCTYPE_READ_VERSION, TYPE_UINT, struct ebml, doctype_read_version), 353233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_LAST 354233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 355233d2500723e5594f3e7c70896ffeeef32b9c950ywan 356233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* WebM Element Lists */ 357233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct ebml_element_desc ne_seek_elements[] = { 358233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_SEEK_ID, TYPE_BINARY, struct seek, id), 359233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_SEEK_POSITION, TYPE_UINT, struct seek, position), 360233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_LAST 361233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 362233d2500723e5594f3e7c70896ffeeef32b9c950ywan 363233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct ebml_element_desc ne_seek_head_elements[] = { 364233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_MASTER(ID_SEEK, TYPE_MASTER, struct seek_head, seek), 365233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_LAST 366233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 367233d2500723e5594f3e7c70896ffeeef32b9c950ywan 368233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct ebml_element_desc ne_info_elements[] = { 369233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_TIMECODE_SCALE, TYPE_UINT, struct info, timecode_scale), 370233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_DURATION, TYPE_FLOAT, struct info, duration), 371233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_LAST 372233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 373233d2500723e5594f3e7c70896ffeeef32b9c950ywan 374233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct ebml_element_desc ne_block_group_elements[] = { 375233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_SUSPEND(ID_BLOCK, TYPE_BINARY), 376233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_BLOCK_DURATION, TYPE_UINT, struct block_group, duration), 377233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_REFERENCE_BLOCK, TYPE_INT, struct block_group, reference_block), 378233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_DISCARD_PADDING, TYPE_INT, struct block_group, discard_padding), 379233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_LAST 380233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 381233d2500723e5594f3e7c70896ffeeef32b9c950ywan 382233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct ebml_element_desc ne_cluster_elements[] = { 383233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_TIMECODE, TYPE_UINT, struct cluster, timecode), 384233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_MASTER(ID_BLOCK_GROUP, TYPE_MASTER, struct cluster, block_group), 385233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_SUSPEND(ID_SIMPLE_BLOCK, TYPE_BINARY), 386233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_LAST 387233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 388233d2500723e5594f3e7c70896ffeeef32b9c950ywan 389233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct ebml_element_desc ne_video_elements[] = { 390233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_STEREO_MODE, TYPE_UINT, struct video, stereo_mode), 391233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_PIXEL_WIDTH, TYPE_UINT, struct video, pixel_width), 392233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_PIXEL_HEIGHT, TYPE_UINT, struct video, pixel_height), 393233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_PIXEL_CROP_BOTTOM, TYPE_UINT, struct video, pixel_crop_bottom), 394233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_PIXEL_CROP_TOP, TYPE_UINT, struct video, pixel_crop_top), 395233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_PIXEL_CROP_LEFT, TYPE_UINT, struct video, pixel_crop_left), 396233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_PIXEL_CROP_RIGHT, TYPE_UINT, struct video, pixel_crop_right), 397233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_DISPLAY_WIDTH, TYPE_UINT, struct video, display_width), 398233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_DISPLAY_HEIGHT, TYPE_UINT, struct video, display_height), 399233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_LAST 400233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 401233d2500723e5594f3e7c70896ffeeef32b9c950ywan 402233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct ebml_element_desc ne_audio_elements[] = { 403233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_SAMPLING_FREQUENCY, TYPE_FLOAT, struct audio, sampling_frequency), 404233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_CHANNELS, TYPE_UINT, struct audio, channels), 405233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_BIT_DEPTH, TYPE_UINT, struct audio, bit_depth), 406233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_LAST 407233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 408233d2500723e5594f3e7c70896ffeeef32b9c950ywan 409233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct ebml_element_desc ne_track_entry_elements[] = { 410233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_TRACK_NUMBER, TYPE_UINT, struct track_entry, number), 411233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_TRACK_UID, TYPE_UINT, struct track_entry, uid), 412233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_TRACK_TYPE, TYPE_UINT, struct track_entry, type), 413233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_FLAG_ENABLED, TYPE_UINT, struct track_entry, flag_enabled), 414233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_FLAG_DEFAULT, TYPE_UINT, struct track_entry, flag_default), 415233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_FLAG_LACING, TYPE_UINT, struct track_entry, flag_lacing), 416233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_TRACK_TIMECODE_SCALE, TYPE_FLOAT, struct track_entry, track_timecode_scale), 417233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_LANGUAGE, TYPE_STRING, struct track_entry, language), 418233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_CODEC_ID, TYPE_STRING, struct track_entry, codec_id), 419233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_CODEC_PRIVATE, TYPE_BINARY, struct track_entry, codec_private), 420233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_CODEC_DELAY, TYPE_UINT, struct track_entry, codec_delay), 421233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_SEEK_PREROLL, TYPE_UINT, struct track_entry, seek_preroll), 422233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_SINGLE_MASTER(ID_VIDEO, TYPE_MASTER, struct track_entry, video), 423233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_SINGLE_MASTER(ID_AUDIO, TYPE_MASTER, struct track_entry, audio), 424233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_LAST 425233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 426233d2500723e5594f3e7c70896ffeeef32b9c950ywan 427233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct ebml_element_desc ne_tracks_elements[] = { 428233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_MASTER(ID_TRACK_ENTRY, TYPE_MASTER, struct tracks, track_entry), 429233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_LAST 430233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 431233d2500723e5594f3e7c70896ffeeef32b9c950ywan 432233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct ebml_element_desc ne_cue_track_positions_elements[] = { 433233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_CUE_TRACK, TYPE_UINT, struct cue_track_positions, track), 434233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_CUE_CLUSTER_POSITION, TYPE_UINT, struct cue_track_positions, cluster_position), 435233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_CUE_BLOCK_NUMBER, TYPE_UINT, struct cue_track_positions, block_number), 436233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_LAST 437233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 438233d2500723e5594f3e7c70896ffeeef32b9c950ywan 439233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct ebml_element_desc ne_cue_point_elements[] = { 440233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_FIELD(ID_CUE_TIME, TYPE_UINT, struct cue_point, time), 441233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_MASTER(ID_CUE_TRACK_POSITIONS, TYPE_MASTER, struct cue_point, cue_track_positions), 442233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_LAST 443233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 444233d2500723e5594f3e7c70896ffeeef32b9c950ywan 445233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct ebml_element_desc ne_cues_elements[] = { 446233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_MASTER(ID_CUE_POINT, TYPE_MASTER, struct cues, cue_point), 447233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_LAST 448233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 449233d2500723e5594f3e7c70896ffeeef32b9c950ywan 450233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct ebml_element_desc ne_segment_elements[] = { 451233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_MASTER(ID_SEEK_HEAD, TYPE_MASTER, struct segment, seek_head), 452233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_SINGLE_MASTER(ID_INFO, TYPE_MASTER, struct segment, info), 453233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_MASTER(ID_CLUSTER, TYPE_MASTER, struct segment, cluster), 454233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_SINGLE_MASTER(ID_TRACKS, TYPE_MASTER, struct segment, tracks), 455233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_SINGLE_MASTER(ID_CUES, TYPE_MASTER, struct segment, cues), 456233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_LAST 457233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 458233d2500723e5594f3e7c70896ffeeef32b9c950ywan 459233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct ebml_element_desc ne_top_level_elements[] = { 460233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_SINGLE_MASTER(ID_EBML, TYPE_MASTER, nestegg, ebml), 461233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_SINGLE_MASTER_O(ID_SEGMENT, TYPE_MASTER, nestegg, segment), 462233d2500723e5594f3e7c70896ffeeef32b9c950ywan E_LAST 463233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 464233d2500723e5594f3e7c70896ffeeef32b9c950ywan 465233d2500723e5594f3e7c70896ffeeef32b9c950ywan#undef E_FIELD 466233d2500723e5594f3e7c70896ffeeef32b9c950ywan#undef E_MASTER 467233d2500723e5594f3e7c70896ffeeef32b9c950ywan#undef E_SINGLE_MASTER_O 468233d2500723e5594f3e7c70896ffeeef32b9c950ywan#undef E_SINGLE_MASTER 469233d2500723e5594f3e7c70896ffeeef32b9c950ywan#undef E_SUSPEND 470233d2500723e5594f3e7c70896ffeeef32b9c950ywan#undef E_LAST 471233d2500723e5594f3e7c70896ffeeef32b9c950ywan 472233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct pool_ctx * 473233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_pool_init(void) 474233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 475233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct pool_ctx * pool; 476233d2500723e5594f3e7c70896ffeeef32b9c950ywan 477233d2500723e5594f3e7c70896ffeeef32b9c950ywan pool = h_malloc(sizeof(*pool)); 478233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!pool) 479233d2500723e5594f3e7c70896ffeeef32b9c950ywan abort(); 480233d2500723e5594f3e7c70896ffeeef32b9c950ywan return pool; 481233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 482233d2500723e5594f3e7c70896ffeeef32b9c950ywan 483233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void 484233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_pool_destroy(struct pool_ctx * pool) 485233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 486233d2500723e5594f3e7c70896ffeeef32b9c950ywan h_free(pool); 487233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 488233d2500723e5594f3e7c70896ffeeef32b9c950ywan 489233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void * 490233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_pool_alloc(size_t size, struct pool_ctx * pool) 491233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 492233d2500723e5594f3e7c70896ffeeef32b9c950ywan void * p; 493233d2500723e5594f3e7c70896ffeeef32b9c950ywan 494233d2500723e5594f3e7c70896ffeeef32b9c950ywan p = h_malloc(size); 495233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!p) 496233d2500723e5594f3e7c70896ffeeef32b9c950ywan abort(); 497233d2500723e5594f3e7c70896ffeeef32b9c950ywan hattach(p, pool); 498233d2500723e5594f3e7c70896ffeeef32b9c950ywan memset(p, 0, size); 499233d2500723e5594f3e7c70896ffeeef32b9c950ywan return p; 500233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 501233d2500723e5594f3e7c70896ffeeef32b9c950ywan 502233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void * 503233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_alloc(size_t size) 504233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 505233d2500723e5594f3e7c70896ffeeef32b9c950ywan void * p; 506233d2500723e5594f3e7c70896ffeeef32b9c950ywan 507233d2500723e5594f3e7c70896ffeeef32b9c950ywan p = calloc(1, size); 508233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!p) 509233d2500723e5594f3e7c70896ffeeef32b9c950ywan abort(); 510233d2500723e5594f3e7c70896ffeeef32b9c950ywan return p; 511233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 512233d2500723e5594f3e7c70896ffeeef32b9c950ywan 513233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 514233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_io_read(nestegg_io * io, void * buffer, size_t length) 515233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 516233d2500723e5594f3e7c70896ffeeef32b9c950ywan return io->read(buffer, length, io->userdata); 517233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 518233d2500723e5594f3e7c70896ffeeef32b9c950ywan 519233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 520233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_io_seek(nestegg_io * io, int64_t offset, int whence) 521233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 522233d2500723e5594f3e7c70896ffeeef32b9c950ywan return io->seek(offset, whence, io->userdata); 523233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 524233d2500723e5594f3e7c70896ffeeef32b9c950ywan 525233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 526233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_io_read_skip(nestegg_io * io, size_t length) 527233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 528233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t get; 529233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned char buf[8192]; 530233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r = 1; 531233d2500723e5594f3e7c70896ffeeef32b9c950ywan 532233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (length > 0) { 533233d2500723e5594f3e7c70896ffeeef32b9c950ywan get = length < sizeof(buf) ? length : sizeof(buf); 534233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_io_read(io, buf, get); 535233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 536233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 537233d2500723e5594f3e7c70896ffeeef32b9c950ywan length -= get; 538233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 539233d2500723e5594f3e7c70896ffeeef32b9c950ywan 540233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 541233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 542233d2500723e5594f3e7c70896ffeeef32b9c950ywan 543233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int64_t 544233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_io_tell(nestegg_io * io) 545233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 546233d2500723e5594f3e7c70896ffeeef32b9c950ywan return io->tell(io->userdata); 547233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 548233d2500723e5594f3e7c70896ffeeef32b9c950ywan 549233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 550233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_bare_read_vint(nestegg_io * io, uint64_t * value, uint64_t * length, enum vint_mask maskflag) 551233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 552233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 553233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned char b; 554233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t maxlen = 8; 555233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int count = 1, mask = 1 << 7; 556233d2500723e5594f3e7c70896ffeeef32b9c950ywan 557233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_io_read(io, &b, 1); 558233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 559233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 560233d2500723e5594f3e7c70896ffeeef32b9c950ywan 561233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (count < maxlen) { 562233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((b & mask) != 0) 563233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 564233d2500723e5594f3e7c70896ffeeef32b9c950ywan mask >>= 1; 565233d2500723e5594f3e7c70896ffeeef32b9c950ywan count += 1; 566233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 567233d2500723e5594f3e7c70896ffeeef32b9c950ywan 568233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (length) 569233d2500723e5594f3e7c70896ffeeef32b9c950ywan *length = count; 570233d2500723e5594f3e7c70896ffeeef32b9c950ywan *value = b; 571233d2500723e5594f3e7c70896ffeeef32b9c950ywan 572233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (maskflag == MASK_FIRST_BIT) 573233d2500723e5594f3e7c70896ffeeef32b9c950ywan *value = b & ~mask; 574233d2500723e5594f3e7c70896ffeeef32b9c950ywan 575233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (--count) { 576233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_io_read(io, &b, 1); 577233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 578233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 579233d2500723e5594f3e7c70896ffeeef32b9c950ywan *value <<= 8; 580233d2500723e5594f3e7c70896ffeeef32b9c950ywan *value |= b; 581233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 582233d2500723e5594f3e7c70896ffeeef32b9c950ywan 583233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 584233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 585233d2500723e5594f3e7c70896ffeeef32b9c950ywan 586233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 587233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_read_id(nestegg_io * io, uint64_t * value, uint64_t * length) 588233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 589233d2500723e5594f3e7c70896ffeeef32b9c950ywan return ne_bare_read_vint(io, value, length, MASK_NONE); 590233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 591233d2500723e5594f3e7c70896ffeeef32b9c950ywan 592233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 593233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_read_vint(nestegg_io * io, uint64_t * value, uint64_t * length) 594233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 595233d2500723e5594f3e7c70896ffeeef32b9c950ywan return ne_bare_read_vint(io, value, length, MASK_FIRST_BIT); 596233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 597233d2500723e5594f3e7c70896ffeeef32b9c950ywan 598233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 599233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_read_svint(nestegg_io * io, int64_t * value, uint64_t * length) 600233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 601233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 602233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t uvalue; 603233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t ulength; 604233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t svint_subtr[] = { 605233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0x3f, 0x1fff, 606233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0xfffff, 0x7ffffff, 607233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0x3ffffffffLL, 0x1ffffffffffLL, 608233d2500723e5594f3e7c70896ffeeef32b9c950ywan 0xffffffffffffLL, 0x7fffffffffffffLL 609233d2500723e5594f3e7c70896ffeeef32b9c950ywan }; 610233d2500723e5594f3e7c70896ffeeef32b9c950ywan 611233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_bare_read_vint(io, &uvalue, &ulength, MASK_FIRST_BIT); 612233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 613233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 614233d2500723e5594f3e7c70896ffeeef32b9c950ywan *value = uvalue - svint_subtr[ulength - 1]; 615233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (length) 616233d2500723e5594f3e7c70896ffeeef32b9c950ywan *length = ulength; 617233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 618233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 619233d2500723e5594f3e7c70896ffeeef32b9c950ywan 620233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 621233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_read_uint(nestegg_io * io, uint64_t * val, uint64_t length) 622233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 623233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned char b; 624233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 625233d2500723e5594f3e7c70896ffeeef32b9c950ywan 626233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (length == 0 || length > 8) 627233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 628233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_io_read(io, &b, 1); 629233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 630233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 631233d2500723e5594f3e7c70896ffeeef32b9c950ywan *val = b; 632233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (--length) { 633233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_io_read(io, &b, 1); 634233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 635233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 636233d2500723e5594f3e7c70896ffeeef32b9c950ywan *val <<= 8; 637233d2500723e5594f3e7c70896ffeeef32b9c950ywan *val |= b; 638233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 639233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 640233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 641233d2500723e5594f3e7c70896ffeeef32b9c950ywan 642233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 643233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_read_int(nestegg_io * io, int64_t * val, uint64_t length) 644233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 645233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 646233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t uval, base; 647233d2500723e5594f3e7c70896ffeeef32b9c950ywan 648233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_uint(io, &uval, length); 649233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 650233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 651233d2500723e5594f3e7c70896ffeeef32b9c950ywan 652233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (length < sizeof(int64_t)) { 653233d2500723e5594f3e7c70896ffeeef32b9c950ywan base = 1; 654233d2500723e5594f3e7c70896ffeeef32b9c950ywan base <<= length * 8 - 1; 655233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (uval >= base) { 656233d2500723e5594f3e7c70896ffeeef32b9c950ywan base = 1; 657233d2500723e5594f3e7c70896ffeeef32b9c950ywan base <<= length * 8; 658233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 659233d2500723e5594f3e7c70896ffeeef32b9c950ywan base = 0; 660233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 661233d2500723e5594f3e7c70896ffeeef32b9c950ywan *val = uval - base; 662233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 663233d2500723e5594f3e7c70896ffeeef32b9c950ywan *val = (int64_t) uval; 664233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 665233d2500723e5594f3e7c70896ffeeef32b9c950ywan 666233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 667233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 668233d2500723e5594f3e7c70896ffeeef32b9c950ywan 669233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 670233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_read_float(nestegg_io * io, double * val, uint64_t length) 671233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 672233d2500723e5594f3e7c70896ffeeef32b9c950ywan union { 673233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t u; 674233d2500723e5594f3e7c70896ffeeef32b9c950ywan float f; 675233d2500723e5594f3e7c70896ffeeef32b9c950ywan double d; 676233d2500723e5594f3e7c70896ffeeef32b9c950ywan } value; 677233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 678233d2500723e5594f3e7c70896ffeeef32b9c950ywan 679233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Length == 10 not implemented. */ 680233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (length != 4 && length != 8) 681233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 682233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_uint(io, &value.u, length); 683233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 684233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 685233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (length == 4) 686233d2500723e5594f3e7c70896ffeeef32b9c950ywan *val = value.f; 687233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 688233d2500723e5594f3e7c70896ffeeef32b9c950ywan *val = value.d; 689233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 690233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 691233d2500723e5594f3e7c70896ffeeef32b9c950ywan 692233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 693233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_read_string(nestegg * ctx, char ** val, uint64_t length) 694233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 695233d2500723e5594f3e7c70896ffeeef32b9c950ywan char * str; 696233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 697233d2500723e5594f3e7c70896ffeeef32b9c950ywan const size_t alloc_size = (size_t)length + 1; 698233d2500723e5594f3e7c70896ffeeef32b9c950ywan 699233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (length == 0 || length > LIMIT_STRING) 700233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 701233d2500723e5594f3e7c70896ffeeef32b9c950ywan str = ne_pool_alloc(alloc_size, ctx->alloc_pool); 702233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_io_read(ctx->io, (unsigned char *) str, alloc_size - 1); 703233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 704233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 705233d2500723e5594f3e7c70896ffeeef32b9c950ywan str[alloc_size - 1] = '\0'; 706233d2500723e5594f3e7c70896ffeeef32b9c950ywan *val = str; 707233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 708233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 709233d2500723e5594f3e7c70896ffeeef32b9c950ywan 710233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 711233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_read_binary(nestegg * ctx, struct ebml_binary * val, uint64_t length) 712233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 713233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (length == 0 || length > LIMIT_BINARY) 714233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 715233d2500723e5594f3e7c70896ffeeef32b9c950ywan val->length = (size_t)length; 716233d2500723e5594f3e7c70896ffeeef32b9c950ywan val->data = ne_pool_alloc(val->length, ctx->alloc_pool); 717233d2500723e5594f3e7c70896ffeeef32b9c950ywan return ne_io_read(ctx->io, val->data, val->length); 718233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 719233d2500723e5594f3e7c70896ffeeef32b9c950ywan 720233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 721233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_get_uint(struct ebml_type type, uint64_t * value) 722233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 723233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!type.read) 724233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 725233d2500723e5594f3e7c70896ffeeef32b9c950ywan 726233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(type.type == TYPE_UINT); 727233d2500723e5594f3e7c70896ffeeef32b9c950ywan 728233d2500723e5594f3e7c70896ffeeef32b9c950ywan *value = type.v.u; 729233d2500723e5594f3e7c70896ffeeef32b9c950ywan 730233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 731233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 732233d2500723e5594f3e7c70896ffeeef32b9c950ywan 733233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 734233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_get_uint32(struct ebml_type type, unsigned int * value) 735233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 736233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t v; 737233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_uint(type, &v)) 738233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 739233d2500723e5594f3e7c70896ffeeef32b9c950ywan 740233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert((unsigned int)v == v); 741233d2500723e5594f3e7c70896ffeeef32b9c950ywan 742233d2500723e5594f3e7c70896ffeeef32b9c950ywan *value = (unsigned int)v; 743233d2500723e5594f3e7c70896ffeeef32b9c950ywan 744233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 745233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 746233d2500723e5594f3e7c70896ffeeef32b9c950ywan 747233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 748233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_get_float(struct ebml_type type, double * value) 749233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 750233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!type.read) 751233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 752233d2500723e5594f3e7c70896ffeeef32b9c950ywan 753233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(type.type == TYPE_FLOAT); 754233d2500723e5594f3e7c70896ffeeef32b9c950ywan 755233d2500723e5594f3e7c70896ffeeef32b9c950ywan *value = type.v.f; 756233d2500723e5594f3e7c70896ffeeef32b9c950ywan 757233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 758233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 759233d2500723e5594f3e7c70896ffeeef32b9c950ywan 760233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 761233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_get_string(struct ebml_type type, char ** value) 762233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 763233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!type.read) 764233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 765233d2500723e5594f3e7c70896ffeeef32b9c950ywan 766233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(type.type == TYPE_STRING); 767233d2500723e5594f3e7c70896ffeeef32b9c950ywan 768233d2500723e5594f3e7c70896ffeeef32b9c950ywan *value = type.v.s; 769233d2500723e5594f3e7c70896ffeeef32b9c950ywan 770233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 771233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 772233d2500723e5594f3e7c70896ffeeef32b9c950ywan 773233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 774233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_get_binary(struct ebml_type type, struct ebml_binary * value) 775233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 776233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!type.read) 777233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 778233d2500723e5594f3e7c70896ffeeef32b9c950ywan 779233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(type.type == TYPE_BINARY); 780233d2500723e5594f3e7c70896ffeeef32b9c950ywan 781233d2500723e5594f3e7c70896ffeeef32b9c950ywan *value = type.v.b; 782233d2500723e5594f3e7c70896ffeeef32b9c950ywan 783233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 784233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 785233d2500723e5594f3e7c70896ffeeef32b9c950ywan 786233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 787233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_is_ancestor_element(uint64_t id, struct list_node * ancestor) 788233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 789233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_element_desc * element; 790233d2500723e5594f3e7c70896ffeeef32b9c950ywan 791233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (; ancestor; ancestor = ancestor->previous) 792233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (element = ancestor->node; element->id; ++element) 793233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (element->id == id) 794233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 795233d2500723e5594f3e7c70896ffeeef32b9c950ywan 796233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 797233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 798233d2500723e5594f3e7c70896ffeeef32b9c950ywan 799233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct ebml_element_desc * 800233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_find_element(uint64_t id, struct ebml_element_desc * elements) 801233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 802233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_element_desc * element; 803233d2500723e5594f3e7c70896ffeeef32b9c950ywan 804233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (element = elements; element->id; ++element) 805233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (element->id == id) 806233d2500723e5594f3e7c70896ffeeef32b9c950ywan return element; 807233d2500723e5594f3e7c70896ffeeef32b9c950ywan 808233d2500723e5594f3e7c70896ffeeef32b9c950ywan return NULL; 809233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 810233d2500723e5594f3e7c70896ffeeef32b9c950ywan 811233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void 812233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_ctx_push(nestegg * ctx, struct ebml_element_desc * ancestor, void * data) 813233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 814233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct list_node * item; 815233d2500723e5594f3e7c70896ffeeef32b9c950ywan 816233d2500723e5594f3e7c70896ffeeef32b9c950ywan item = ne_alloc(sizeof(*item)); 817233d2500723e5594f3e7c70896ffeeef32b9c950ywan item->previous = ctx->ancestor; 818233d2500723e5594f3e7c70896ffeeef32b9c950ywan item->node = ancestor; 819233d2500723e5594f3e7c70896ffeeef32b9c950ywan item->data = data; 820233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->ancestor = item; 821233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 822233d2500723e5594f3e7c70896ffeeef32b9c950ywan 823233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void 824233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_ctx_pop(nestegg * ctx) 825233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 826233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct list_node * item; 827233d2500723e5594f3e7c70896ffeeef32b9c950ywan 828233d2500723e5594f3e7c70896ffeeef32b9c950ywan item = ctx->ancestor; 829233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->ancestor = item->previous; 830233d2500723e5594f3e7c70896ffeeef32b9c950ywan free(item); 831233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 832233d2500723e5594f3e7c70896ffeeef32b9c950ywan 833233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 834233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_ctx_save(nestegg * ctx, struct saved_state * s) 835233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 836233d2500723e5594f3e7c70896ffeeef32b9c950ywan s->stream_offset = ne_io_tell(ctx->io); 837233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (s->stream_offset < 0) 838233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 839233d2500723e5594f3e7c70896ffeeef32b9c950ywan s->ancestor = ctx->ancestor; 840233d2500723e5594f3e7c70896ffeeef32b9c950ywan s->last_id = ctx->last_id; 841233d2500723e5594f3e7c70896ffeeef32b9c950ywan s->last_size = ctx->last_size; 842233d2500723e5594f3e7c70896ffeeef32b9c950ywan s->last_valid = ctx->last_valid; 843233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 844233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 845233d2500723e5594f3e7c70896ffeeef32b9c950ywan 846233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 847233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_ctx_restore(nestegg * ctx, struct saved_state * s) 848233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 849233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 850233d2500723e5594f3e7c70896ffeeef32b9c950ywan 851233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_io_seek(ctx->io, s->stream_offset, NESTEGG_SEEK_SET); 852233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 0) 853233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 854233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->ancestor = s->ancestor; 855233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->last_id = s->last_id; 856233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->last_size = s->last_size; 857233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->last_valid = s->last_valid; 858233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 859233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 860233d2500723e5594f3e7c70896ffeeef32b9c950ywan 861233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 862233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_peek_element(nestegg * ctx, uint64_t * id, uint64_t * size) 863233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 864233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 865233d2500723e5594f3e7c70896ffeeef32b9c950ywan 866233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ctx->last_valid) { 867233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (id) 868233d2500723e5594f3e7c70896ffeeef32b9c950ywan *id = ctx->last_id; 869233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (size) 870233d2500723e5594f3e7c70896ffeeef32b9c950ywan *size = ctx->last_size; 871233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 872233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 873233d2500723e5594f3e7c70896ffeeef32b9c950ywan 874233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_id(ctx->io, &ctx->last_id, NULL); 875233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 876233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 877233d2500723e5594f3e7c70896ffeeef32b9c950ywan 878233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_vint(ctx->io, &ctx->last_size, NULL); 879233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 880233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 881233d2500723e5594f3e7c70896ffeeef32b9c950ywan 882233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (id) 883233d2500723e5594f3e7c70896ffeeef32b9c950ywan *id = ctx->last_id; 884233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (size) 885233d2500723e5594f3e7c70896ffeeef32b9c950ywan *size = ctx->last_size; 886233d2500723e5594f3e7c70896ffeeef32b9c950ywan 887233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->last_valid = 1; 888233d2500723e5594f3e7c70896ffeeef32b9c950ywan 889233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 890233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 891233d2500723e5594f3e7c70896ffeeef32b9c950ywan 892233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 893233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_read_element(nestegg * ctx, uint64_t * id, uint64_t * size) 894233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 895233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 896233d2500723e5594f3e7c70896ffeeef32b9c950ywan 897233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_peek_element(ctx, id, size); 898233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 899233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 900233d2500723e5594f3e7c70896ffeeef32b9c950ywan 901233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->last_valid = 0; 902233d2500723e5594f3e7c70896ffeeef32b9c950ywan 903233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 904233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 905233d2500723e5594f3e7c70896ffeeef32b9c950ywan 906233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void 907233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_read_master(nestegg * ctx, struct ebml_element_desc * desc) 908233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 909233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list * list; 910233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list_node * node, * oldtail; 911233d2500723e5594f3e7c70896ffeeef32b9c950ywan 912233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(desc->type == TYPE_MASTER && desc->flags & DESC_FLAG_MULTI); 913233d2500723e5594f3e7c70896ffeeef32b9c950ywan 914233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->log(ctx, NESTEGG_LOG_DEBUG, "multi master element %llx (%s)", 915233d2500723e5594f3e7c70896ffeeef32b9c950ywan desc->id, desc->name); 916233d2500723e5594f3e7c70896ffeeef32b9c950ywan 917233d2500723e5594f3e7c70896ffeeef32b9c950ywan list = (struct ebml_list *) (ctx->ancestor->data + desc->offset); 918233d2500723e5594f3e7c70896ffeeef32b9c950ywan 919233d2500723e5594f3e7c70896ffeeef32b9c950ywan node = ne_pool_alloc(sizeof(*node), ctx->alloc_pool); 920233d2500723e5594f3e7c70896ffeeef32b9c950ywan node->id = desc->id; 921233d2500723e5594f3e7c70896ffeeef32b9c950ywan node->data = ne_pool_alloc(desc->size, ctx->alloc_pool); 922233d2500723e5594f3e7c70896ffeeef32b9c950ywan 923233d2500723e5594f3e7c70896ffeeef32b9c950ywan oldtail = list->tail; 924233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (oldtail) 925233d2500723e5594f3e7c70896ffeeef32b9c950ywan oldtail->next = node; 926233d2500723e5594f3e7c70896ffeeef32b9c950ywan list->tail = node; 927233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!list->head) 928233d2500723e5594f3e7c70896ffeeef32b9c950ywan list->head = node; 929233d2500723e5594f3e7c70896ffeeef32b9c950ywan 930233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->log(ctx, NESTEGG_LOG_DEBUG, " -> using data %p", node->data); 931233d2500723e5594f3e7c70896ffeeef32b9c950ywan 932233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_ctx_push(ctx, desc->children, node->data); 933233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 934233d2500723e5594f3e7c70896ffeeef32b9c950ywan 935233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void 936233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_read_single_master(nestegg * ctx, struct ebml_element_desc * desc) 937233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 938233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(desc->type == TYPE_MASTER && !(desc->flags & DESC_FLAG_MULTI)); 939233d2500723e5594f3e7c70896ffeeef32b9c950ywan 940233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->log(ctx, NESTEGG_LOG_DEBUG, "single master element %llx (%s)", 941233d2500723e5594f3e7c70896ffeeef32b9c950ywan desc->id, desc->name); 942233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->log(ctx, NESTEGG_LOG_DEBUG, " -> using data %p (%u)", 943233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->ancestor->data + desc->offset, desc->offset); 944233d2500723e5594f3e7c70896ffeeef32b9c950ywan 945233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_ctx_push(ctx, desc->children, ctx->ancestor->data + desc->offset); 946233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 947233d2500723e5594f3e7c70896ffeeef32b9c950ywan 948233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 949233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_read_simple(nestegg * ctx, struct ebml_element_desc * desc, size_t length) 950233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 951233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type * storage; 952233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r = 0; 953233d2500723e5594f3e7c70896ffeeef32b9c950ywan 954233d2500723e5594f3e7c70896ffeeef32b9c950ywan storage = (struct ebml_type *) (ctx->ancestor->data + desc->offset); 955233d2500723e5594f3e7c70896ffeeef32b9c950ywan 956233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (storage->read) { 957233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->log(ctx, NESTEGG_LOG_DEBUG, "element %llx (%s) already read, skipping", 958233d2500723e5594f3e7c70896ffeeef32b9c950ywan desc->id, desc->name); 959233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 960233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 961233d2500723e5594f3e7c70896ffeeef32b9c950ywan 962233d2500723e5594f3e7c70896ffeeef32b9c950ywan storage->type = desc->type; 963233d2500723e5594f3e7c70896ffeeef32b9c950ywan 964233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->log(ctx, NESTEGG_LOG_DEBUG, "element %llx (%s) -> %p (%u)", 965233d2500723e5594f3e7c70896ffeeef32b9c950ywan desc->id, desc->name, storage, desc->offset); 966233d2500723e5594f3e7c70896ffeeef32b9c950ywan 967233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (desc->type) { 968233d2500723e5594f3e7c70896ffeeef32b9c950ywan case TYPE_UINT: 969233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_uint(ctx->io, &storage->v.u, length); 970233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 971233d2500723e5594f3e7c70896ffeeef32b9c950ywan case TYPE_FLOAT: 972233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_float(ctx->io, &storage->v.f, length); 973233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 974233d2500723e5594f3e7c70896ffeeef32b9c950ywan case TYPE_INT: 975233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_int(ctx->io, &storage->v.i, length); 976233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 977233d2500723e5594f3e7c70896ffeeef32b9c950ywan case TYPE_STRING: 978233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_string(ctx, &storage->v.s, length); 979233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 980233d2500723e5594f3e7c70896ffeeef32b9c950ywan case TYPE_BINARY: 981233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_binary(ctx, &storage->v.b, length); 982233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 983233d2500723e5594f3e7c70896ffeeef32b9c950ywan case TYPE_MASTER: 984233d2500723e5594f3e7c70896ffeeef32b9c950ywan case TYPE_UNKNOWN: 985233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(0); 986233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 987233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 988233d2500723e5594f3e7c70896ffeeef32b9c950ywan 989233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r == 1) 990233d2500723e5594f3e7c70896ffeeef32b9c950ywan storage->read = 1; 991233d2500723e5594f3e7c70896ffeeef32b9c950ywan 992233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 993233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 994233d2500723e5594f3e7c70896ffeeef32b9c950ywan 995233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 996233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_parse(nestegg * ctx, struct ebml_element_desc * top_level, int64_t max_offset) 997233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 998233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 999233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t * data_offset; 1000233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t id, size, peeked_id; 1001233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_element_desc * element; 1002233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1003233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!ctx->ancestor) 1004233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1005233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1006233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (;;) { 1007233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (max_offset > 0 && ne_io_tell(ctx->io) >= max_offset) { 1008233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Reached end of offset allowed for parsing - return gracefully */ 1009233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = 1; 1010233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1011233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1012233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_peek_element(ctx, &id, &size); 1013233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1014233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1015233d2500723e5594f3e7c70896ffeeef32b9c950ywan peeked_id = id; 1016233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1017233d2500723e5594f3e7c70896ffeeef32b9c950ywan element = ne_find_element(id, ctx->ancestor->node); 1018233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (element) { 1019233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (element->flags & DESC_FLAG_SUSPEND) { 1020233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(element->type == TYPE_BINARY); 1021233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->log(ctx, NESTEGG_LOG_DEBUG, "suspend parse at %llx", id); 1022233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = 1; 1023233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1024233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1025233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1026233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_element(ctx, &id, &size); 1027233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1028233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1029233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(id == peeked_id); 1030233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1031233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (element->flags & DESC_FLAG_OFFSET) { 1032233d2500723e5594f3e7c70896ffeeef32b9c950ywan data_offset = (int64_t *) (ctx->ancestor->data + element->data_offset); 1033233d2500723e5594f3e7c70896ffeeef32b9c950ywan *data_offset = ne_io_tell(ctx->io); 1034233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (*data_offset < 0) { 1035233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = -1; 1036233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1037233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1038233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1039233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1040233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (element->type == TYPE_MASTER) { 1041233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (element->flags & DESC_FLAG_MULTI) 1042233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_read_master(ctx, element); 1043233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 1044233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_read_single_master(ctx, element); 1045233d2500723e5594f3e7c70896ffeeef32b9c950ywan continue; 1046233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 1047233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_simple(ctx, element, (size_t)size); 1048233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r < 0) 1049233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1050233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1051233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (ne_is_ancestor_element(id, ctx->ancestor->previous)) { 1052233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->log(ctx, NESTEGG_LOG_DEBUG, "parent element %llx", id); 1053233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (top_level && ctx->ancestor->node == top_level) { 1054233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->log(ctx, NESTEGG_LOG_DEBUG, "*** parse about to back up past top_level"); 1055233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = 1; 1056233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1057233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1058233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_ctx_pop(ctx); 1059233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 1060233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_element(ctx, &id, &size); 1061233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1062233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1063233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1064233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (id != ID_VOID && id != ID_CRC32) 1065233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->log(ctx, NESTEGG_LOG_DEBUG, "unknown element %llx", id); 1066233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_io_read_skip(ctx->io, (size_t)size); 1067233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1068233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1069233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1070233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1071233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1072233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1073233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (ctx->ancestor) 1074233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_ctx_pop(ctx); 1075233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1076233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 1077233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1078233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1079233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic uint64_t 1080233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_xiph_lace_value(unsigned char ** np) 1081233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1082233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t lace; 1083233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t value; 1084233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned char * p = *np; 1085233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1086233d2500723e5594f3e7c70896ffeeef32b9c950ywan lace = *p++; 1087233d2500723e5594f3e7c70896ffeeef32b9c950ywan value = lace; 1088233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (lace == 255) { 1089233d2500723e5594f3e7c70896ffeeef32b9c950ywan lace = *p++; 1090233d2500723e5594f3e7c70896ffeeef32b9c950ywan value += lace; 1091233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1092233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1093233d2500723e5594f3e7c70896ffeeef32b9c950ywan *np = p; 1094233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1095233d2500723e5594f3e7c70896ffeeef32b9c950ywan return value; 1096233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1097233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1098233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 1099233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_read_xiph_lace_value(nestegg_io * io, uint64_t * value, size_t * consumed) 1100233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1101233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 1102233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t lace; 1103233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1104233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_uint(io, &lace, 1); 1105233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1106233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 1107233d2500723e5594f3e7c70896ffeeef32b9c950ywan *consumed += 1; 1108233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1109233d2500723e5594f3e7c70896ffeeef32b9c950ywan *value = lace; 1110233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (lace == 255) { 1111233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_uint(io, &lace, 1); 1112233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1113233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 1114233d2500723e5594f3e7c70896ffeeef32b9c950ywan *consumed += 1; 1115233d2500723e5594f3e7c70896ffeeef32b9c950ywan *value += lace; 1116233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1117233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1118233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 1119233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1120233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1121233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 1122233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_read_xiph_lacing(nestegg_io * io, size_t block, size_t * read, uint64_t n, uint64_t * sizes) 1123233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1124233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 1125233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t i = 0; 1126233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t sum = 0; 1127233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1128233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (--n) { 1129233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_xiph_lace_value(io, &sizes[i], read); 1130233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1131233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 1132233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum += sizes[i]; 1133233d2500723e5594f3e7c70896ffeeef32b9c950ywan i += 1; 1134233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1135233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1136233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (*read + sum > block) 1137233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1138233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1139233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Last frame is the remainder of the block. */ 1140233d2500723e5594f3e7c70896ffeeef32b9c950ywan sizes[i] = block - *read - sum; 1141233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 1142233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1143233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1144233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 1145233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_read_ebml_lacing(nestegg_io * io, size_t block, size_t * read, uint64_t n, uint64_t * sizes) 1146233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1147233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 1148233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t lace, sum, length; 1149233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t slace; 1150233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t i = 0; 1151233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1152233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_vint(io, &lace, &length); 1153233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1154233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 1155233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(length <= 8); 1156233d2500723e5594f3e7c70896ffeeef32b9c950ywan *read += (size_t)length; 1157233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1158233d2500723e5594f3e7c70896ffeeef32b9c950ywan sizes[i] = lace; 1159233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum = sizes[i]; 1160233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1161233d2500723e5594f3e7c70896ffeeef32b9c950ywan i += 1; 1162233d2500723e5594f3e7c70896ffeeef32b9c950ywan n -= 1; 1163233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1164233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (--n) { 1165233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_svint(io, &slace, &length); 1166233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1167233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 1168233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(length <= 8); 1169233d2500723e5594f3e7c70896ffeeef32b9c950ywan *read += (size_t)length; 1170233d2500723e5594f3e7c70896ffeeef32b9c950ywan sizes[i] = sizes[i - 1] + slace; 1171233d2500723e5594f3e7c70896ffeeef32b9c950ywan sum += sizes[i]; 1172233d2500723e5594f3e7c70896ffeeef32b9c950ywan i += 1; 1173233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1174233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1175233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (*read + sum > block) 1176233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1177233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1178233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Last frame is the remainder of the block. */ 1179233d2500723e5594f3e7c70896ffeeef32b9c950ywan sizes[i] = block - *read - sum; 1180233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 1181233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1182233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1183233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic uint64_t 1184233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_get_timecode_scale(nestegg * ctx) 1185233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1186233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t scale; 1187233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1188233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_uint(ctx->segment.info.timecode_scale, &scale) != 0) 1189233d2500723e5594f3e7c70896ffeeef32b9c950ywan scale = 1000000; 1190233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1191233d2500723e5594f3e7c70896ffeeef32b9c950ywan return scale; 1192233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1193233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1194233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 1195233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_map_track_number_to_index(nestegg * ctx, 1196233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int track_number, 1197233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int * track_index) 1198233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1199233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list_node * node; 1200233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct track_entry * t_entry; 1201233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t t_number = 0; 1202233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1203233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!track_index) 1204233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1205233d2500723e5594f3e7c70896ffeeef32b9c950ywan *track_index = 0; 1206233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1207233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (track_number == 0) 1208233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1209233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1210233d2500723e5594f3e7c70896ffeeef32b9c950ywan node = ctx->segment.tracks.track_entry.head; 1211233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (node) { 1212233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(node->id == ID_TRACK_ENTRY); 1213233d2500723e5594f3e7c70896ffeeef32b9c950ywan t_entry = node->data; 1214233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_uint(t_entry->number, &t_number) != 0) 1215233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1216233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (t_number == track_number) 1217233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 1218233d2500723e5594f3e7c70896ffeeef32b9c950ywan *track_index += 1; 1219233d2500723e5594f3e7c70896ffeeef32b9c950ywan node = node->next; 1220233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1221233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1222233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1223233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1224233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1225233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct track_entry * 1226233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_find_track_entry(nestegg * ctx, unsigned int track) 1227233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1228233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list_node * node; 1229233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int tracks = 0; 1230233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1231233d2500723e5594f3e7c70896ffeeef32b9c950ywan node = ctx->segment.tracks.track_entry.head; 1232233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (node) { 1233233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(node->id == ID_TRACK_ENTRY); 1234233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (track == tracks) 1235233d2500723e5594f3e7c70896ffeeef32b9c950ywan return node->data; 1236233d2500723e5594f3e7c70896ffeeef32b9c950ywan tracks += 1; 1237233d2500723e5594f3e7c70896ffeeef32b9c950ywan node = node->next; 1238233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1239233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1240233d2500723e5594f3e7c70896ffeeef32b9c950ywan return NULL; 1241233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1242233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1243233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 1244233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_read_block(nestegg * ctx, uint64_t block_id, uint64_t block_size, nestegg_packet ** data) 1245233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1246233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 1247233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t timecode, abs_timecode; 1248233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_packet * pkt; 1249233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct cluster * cluster; 1250233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct frame * f, * last; 1251233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct track_entry * entry; 1252233d2500723e5594f3e7c70896ffeeef32b9c950ywan const int track_scale = 1; 1253233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t track_number, length, frame_sizes[256], cluster_tc, flags, frames, tc_scale, total; 1254233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int i, lacing, track; 1255233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t consumed = 0; 1256233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1257233d2500723e5594f3e7c70896ffeeef32b9c950ywan *data = NULL; 1258233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1259233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (block_size > LIMIT_BLOCK) 1260233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1261233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1262233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_vint(ctx->io, &track_number, &length); 1263233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1264233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 1265233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1266233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (track_number == 0 || (unsigned int)track_number != track_number) 1267233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1268233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1269233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(length <= 8); 1270233d2500723e5594f3e7c70896ffeeef32b9c950ywan consumed += (size_t)length; 1271233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1272233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_int(ctx->io, &timecode, 2); 1273233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1274233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 1275233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1276233d2500723e5594f3e7c70896ffeeef32b9c950ywan consumed += 2; 1277233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1278233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_uint(ctx->io, &flags, 1); 1279233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1280233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 1281233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1282233d2500723e5594f3e7c70896ffeeef32b9c950ywan consumed += 1; 1283233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1284233d2500723e5594f3e7c70896ffeeef32b9c950ywan frames = 0; 1285233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1286233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Flags are different between Block and SimpleBlock, but lacing is 1287233d2500723e5594f3e7c70896ffeeef32b9c950ywan encoded the same way. */ 1288233d2500723e5594f3e7c70896ffeeef32b9c950ywan lacing = (flags & BLOCK_FLAGS_LACING) >> 1; 1289233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1290233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (lacing) { 1291233d2500723e5594f3e7c70896ffeeef32b9c950ywan case LACING_NONE: 1292233d2500723e5594f3e7c70896ffeeef32b9c950ywan frames = 1; 1293233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1294233d2500723e5594f3e7c70896ffeeef32b9c950ywan case LACING_XIPH: 1295233d2500723e5594f3e7c70896ffeeef32b9c950ywan case LACING_FIXED: 1296233d2500723e5594f3e7c70896ffeeef32b9c950ywan case LACING_EBML: 1297233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_uint(ctx->io, &frames, 1); 1298233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1299233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 1300233d2500723e5594f3e7c70896ffeeef32b9c950ywan consumed += 1; 1301233d2500723e5594f3e7c70896ffeeef32b9c950ywan frames += 1; 1302233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1303233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1304233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (frames > 256) 1305233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1306233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1307233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch (lacing) { 1308233d2500723e5594f3e7c70896ffeeef32b9c950ywan case LACING_NONE: 1309233d2500723e5594f3e7c70896ffeeef32b9c950ywan frame_sizes[0] = block_size - consumed; 1310233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1311233d2500723e5594f3e7c70896ffeeef32b9c950ywan case LACING_XIPH: 1312233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (frames == 1) 1313233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1314233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_xiph_lacing(ctx->io, (size_t)block_size, &consumed, frames, frame_sizes); 1315233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1316233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 1317233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1318233d2500723e5594f3e7c70896ffeeef32b9c950ywan case LACING_FIXED: 1319233d2500723e5594f3e7c70896ffeeef32b9c950ywan if ((block_size - consumed) % frames) 1320233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1321233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < frames; ++i) 1322233d2500723e5594f3e7c70896ffeeef32b9c950ywan frame_sizes[i] = (block_size - consumed) / frames; 1323233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1324233d2500723e5594f3e7c70896ffeeef32b9c950ywan case LACING_EBML: 1325233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (frames == 1) 1326233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1327233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_ebml_lacing(ctx->io, (size_t)block_size, &consumed, frames, frame_sizes); 1328233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1329233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 1330233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1331233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1332233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1333233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Sanity check unlaced frame sizes against total block size. */ 1334233d2500723e5594f3e7c70896ffeeef32b9c950ywan total = consumed; 1335233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < frames; ++i) 1336233d2500723e5594f3e7c70896ffeeef32b9c950ywan total += frame_sizes[i]; 1337233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (total > block_size) 1338233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1339233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1340233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_map_track_number_to_index(ctx, (unsigned int)track_number, &track) != 0) 1341233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1342233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1343233d2500723e5594f3e7c70896ffeeef32b9c950ywan entry = ne_find_track_entry(ctx, track); 1344233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!entry) 1345233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1346233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1347233d2500723e5594f3e7c70896ffeeef32b9c950ywan tc_scale = ne_get_timecode_scale(ctx); 1348233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1349233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(ctx->segment.cluster.tail->id == ID_CLUSTER); 1350233d2500723e5594f3e7c70896ffeeef32b9c950ywan cluster = ctx->segment.cluster.tail->data; 1351233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_uint(cluster->timecode, &cluster_tc) != 0) 1352233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1353233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1354233d2500723e5594f3e7c70896ffeeef32b9c950ywan abs_timecode = timecode + cluster_tc; 1355233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (abs_timecode < 0) 1356233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1357233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1358233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt = ne_alloc(sizeof(*pkt)); 1359233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt->track = track; 1360233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt->timecode = abs_timecode * tc_scale * track_scale; 1361233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1362233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->log(ctx, NESTEGG_LOG_DEBUG, "%sblock t %lld pts %f f %llx frames: %llu", 1363233d2500723e5594f3e7c70896ffeeef32b9c950ywan block_id == ID_BLOCK ? "" : "simple", pkt->track, pkt->timecode / 1e9, flags, frames); 1364233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1365233d2500723e5594f3e7c70896ffeeef32b9c950ywan last = NULL; 1366233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < frames; ++i) { 1367233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (frame_sizes[i] > LIMIT_FRAME) { 1368233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_free_packet(pkt); 1369233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1370233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1371233d2500723e5594f3e7c70896ffeeef32b9c950ywan f = ne_alloc(sizeof(*f)); 1372233d2500723e5594f3e7c70896ffeeef32b9c950ywan f->length = (size_t)frame_sizes[i]; 1373233d2500723e5594f3e7c70896ffeeef32b9c950ywan f->data = ne_alloc(f->length); 1374233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_io_read(ctx->io, f->data, f->length); 1375233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) { 1376233d2500723e5594f3e7c70896ffeeef32b9c950ywan free(f->data); 1377233d2500723e5594f3e7c70896ffeeef32b9c950ywan free(f); 1378233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_free_packet(pkt); 1379233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1380233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1381233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1382233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!last) 1383233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt->frame = f; 1384233d2500723e5594f3e7c70896ffeeef32b9c950ywan else 1385233d2500723e5594f3e7c70896ffeeef32b9c950ywan last->next = f; 1386233d2500723e5594f3e7c70896ffeeef32b9c950ywan last = f; 1387233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1388233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1389233d2500723e5594f3e7c70896ffeeef32b9c950ywan *data = pkt; 1390233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1391233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 1392233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1393233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1394233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 1395233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_read_discard_padding(nestegg * ctx, nestegg_packet * pkt) 1396233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1397233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 1398233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t id, size; 1399233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_element_desc * element; 1400233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_type * storage; 1401233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1402233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_peek_element(ctx, &id, &size); 1403233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1404233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 1405233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1406233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (id != ID_DISCARD_PADDING) 1407233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 1408233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1409233d2500723e5594f3e7c70896ffeeef32b9c950ywan element = ne_find_element(id, ctx->ancestor->node); 1410233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!element) 1411233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 1412233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1413233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert((size_t)size == size); 1414233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_simple(ctx, element, (size_t)size); 1415233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1416233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 1417233d2500723e5594f3e7c70896ffeeef32b9c950ywan storage = (struct ebml_type *) (ctx->ancestor->data + element->offset); 1418233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt->discard_padding = storage->v.i; 1419233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1420233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 1421233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1422233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1423233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1424233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic uint64_t 1425233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_buf_read_id(unsigned char const * p, size_t length) 1426233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1427233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t id = 0; 1428233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1429233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (length--) { 1430233d2500723e5594f3e7c70896ffeeef32b9c950ywan id <<= 8; 1431233d2500723e5594f3e7c70896ffeeef32b9c950ywan id |= *p++; 1432233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1433233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1434233d2500723e5594f3e7c70896ffeeef32b9c950ywan return id; 1435233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1436233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1437233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct seek * 1438233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_find_seek_for_id(struct ebml_list_node * seek_head, uint64_t id) 1439233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1440233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list * head; 1441233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list_node * seek; 1442233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_binary binary_id; 1443233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct seek * s; 1444233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1445233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (seek_head) { 1446233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(seek_head->id == ID_SEEK_HEAD); 1447233d2500723e5594f3e7c70896ffeeef32b9c950ywan head = seek_head->data; 1448233d2500723e5594f3e7c70896ffeeef32b9c950ywan seek = head->head; 1449233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1450233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (seek) { 1451233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(seek->id == ID_SEEK); 1452233d2500723e5594f3e7c70896ffeeef32b9c950ywan s = seek->data; 1453233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1454233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_binary(s->id, &binary_id) == 0 && 1455233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_buf_read_id(binary_id.data, binary_id.length) == id) 1456233d2500723e5594f3e7c70896ffeeef32b9c950ywan return s; 1457233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1458233d2500723e5594f3e7c70896ffeeef32b9c950ywan seek = seek->next; 1459233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1460233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1461233d2500723e5594f3e7c70896ffeeef32b9c950ywan seek_head = seek_head->next; 1462233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1463233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1464233d2500723e5594f3e7c70896ffeeef32b9c950ywan return NULL; 1465233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1466233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1467233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct cue_track_positions * 1468233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_find_cue_position_for_track(nestegg * ctx, struct ebml_list_node * node, unsigned int track) 1469233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1470233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct cue_track_positions * pos = NULL; 1471233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int track_number; 1472233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int t; 1473233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1474233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (node) { 1475233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(node->id == ID_CUE_TRACK_POSITIONS); 1476233d2500723e5594f3e7c70896ffeeef32b9c950ywan pos = node->data; 1477233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_uint32(pos->track, &track_number) != 0) 1478233d2500723e5594f3e7c70896ffeeef32b9c950ywan return NULL; 1479233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1480233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_map_track_number_to_index(ctx, track_number, &t) != 0) 1481233d2500723e5594f3e7c70896ffeeef32b9c950ywan return NULL; 1482233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1483233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (t == track) 1484233d2500723e5594f3e7c70896ffeeef32b9c950ywan return pos; 1485233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1486233d2500723e5594f3e7c70896ffeeef32b9c950ywan node = node->next; 1487233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1488233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1489233d2500723e5594f3e7c70896ffeeef32b9c950ywan return NULL; 1490233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1491233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1492233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic struct cue_point * 1493233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_find_cue_point_for_tstamp(nestegg * ctx, struct ebml_list_node * cue_point, unsigned int track, uint64_t scale, uint64_t tstamp) 1494233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1495233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t time; 1496233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct cue_point * c, * prev = NULL; 1497233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1498233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (cue_point) { 1499233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(cue_point->id == ID_CUE_POINT); 1500233d2500723e5594f3e7c70896ffeeef32b9c950ywan c = cue_point->data; 1501233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1502233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!prev) 1503233d2500723e5594f3e7c70896ffeeef32b9c950ywan prev = c; 1504233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1505233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_uint(c->time, &time) == 0 && time * scale > tstamp) 1506233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1507233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1508233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_find_cue_position_for_track(ctx, c->cue_track_positions.head, track) != NULL) 1509233d2500723e5594f3e7c70896ffeeef32b9c950ywan prev = c; 1510233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1511233d2500723e5594f3e7c70896ffeeef32b9c950ywan cue_point = cue_point->next; 1512233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1513233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1514233d2500723e5594f3e7c70896ffeeef32b9c950ywan return prev; 1515233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1516233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1517233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 1518233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_is_suspend_element(uint64_t id) 1519233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1520233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (id == ID_SIMPLE_BLOCK || id == ID_BLOCK) 1521233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 1522233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 1523233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1524233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1525233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic void 1526233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_null_log_callback(nestegg * ctx, unsigned int severity, char const * fmt, ...) 1527233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1528233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ctx && severity && fmt) 1529233d2500723e5594f3e7c70896ffeeef32b9c950ywan return; 1530233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1531233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1532233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 1533233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_init_cue_points(nestegg * ctx, int64_t max_offset) 1534233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1535233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 1536233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list_node * node = ctx->segment.cues.cue_point.head; 1537233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct seek * found; 1538233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t seek_pos, id; 1539233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct saved_state state; 1540233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1541233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* If there are no cues loaded, check for cues element in the seek head 1542233d2500723e5594f3e7c70896ffeeef32b9c950ywan and load it. */ 1543233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!node) { 1544233d2500723e5594f3e7c70896ffeeef32b9c950ywan found = ne_find_seek_for_id(ctx->segment.seek_head.head, ID_CUES); 1545233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!found) 1546233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1547233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1548233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_uint(found->position, &seek_pos) != 0) 1549233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1550233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1551233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Save old parser state. */ 1552233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_ctx_save(ctx, &state); 1553233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 0) 1554233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1555233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1556233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Seek and set up parser state for segment-level element (Cues). */ 1557233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_io_seek(ctx->io, ctx->segment_offset + seek_pos, NESTEGG_SEEK_SET); 1558233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 0) 1559233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1560233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->last_valid = 0; 1561233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1562233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_element(ctx, &id, NULL); 1563233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1564233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1565233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1566233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (id != ID_CUES) 1567233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1568233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1569233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->ancestor = NULL; 1570233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_ctx_push(ctx, ne_top_level_elements, ctx); 1571233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_ctx_push(ctx, ne_segment_elements, &ctx->segment); 1572233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_ctx_push(ctx, ne_cues_elements, &ctx->segment.cues); 1573233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* parser will run until end of cues element. */ 1574233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->log(ctx, NESTEGG_LOG_DEBUG, "seek: parsing cue elements"); 1575233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_parse(ctx, ne_cues_elements, max_offset); 1576233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (ctx->ancestor) 1577233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_ctx_pop(ctx); 1578233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1579233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Reset parser state to original state and seek back to old position. */ 1580233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_ctx_restore(ctx, &state) != 0) 1581233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1582233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1583233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r < 0) 1584233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1585233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1586233d2500723e5594f3e7c70896ffeeef32b9c950ywan node = ctx->segment.cues.cue_point.head; 1587233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!node) 1588233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1589233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1590233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1591233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 1592233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1593233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1594233d2500723e5594f3e7c70896ffeeef32b9c950ywan/* Three functions that implement the nestegg_io interface, operating on a 1595233d2500723e5594f3e7c70896ffeeef32b9c950ywan * sniff_buffer. */ 1596233d2500723e5594f3e7c70896ffeeef32b9c950ywanstruct sniff_buffer { 1597233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned char const * buffer; 1598233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t length; 1599233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t offset; 1600233d2500723e5594f3e7c70896ffeeef32b9c950ywan}; 1601233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1602233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 1603233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_buffer_read(void * buffer, size_t length, void * user_data) 1604233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1605233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct sniff_buffer * sb = user_data; 1606233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1607233d2500723e5594f3e7c70896ffeeef32b9c950ywan int rv = 1; 1608233d2500723e5594f3e7c70896ffeeef32b9c950ywan size_t available = sb->length - (size_t)sb->offset; 1609233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1610233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (available < length) 1611233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 1612233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1613233d2500723e5594f3e7c70896ffeeef32b9c950ywan memcpy(buffer, sb->buffer + sb->offset, length); 1614233d2500723e5594f3e7c70896ffeeef32b9c950ywan sb->offset += length; 1615233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1616233d2500723e5594f3e7c70896ffeeef32b9c950ywan return rv; 1617233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1618233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1619233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 1620233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_buffer_seek(int64_t offset, int whence, void * user_data) 1621233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1622233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct sniff_buffer * sb = user_data; 1623233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t o = sb->offset; 1624233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1625233d2500723e5594f3e7c70896ffeeef32b9c950ywan switch(whence) { 1626233d2500723e5594f3e7c70896ffeeef32b9c950ywan case NESTEGG_SEEK_SET: 1627233d2500723e5594f3e7c70896ffeeef32b9c950ywan o = offset; 1628233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1629233d2500723e5594f3e7c70896ffeeef32b9c950ywan case NESTEGG_SEEK_CUR: 1630233d2500723e5594f3e7c70896ffeeef32b9c950ywan o += offset; 1631233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1632233d2500723e5594f3e7c70896ffeeef32b9c950ywan case NESTEGG_SEEK_END: 1633233d2500723e5594f3e7c70896ffeeef32b9c950ywan o = sb->length + offset; 1634233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1635233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1636233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1637233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (o < 0 || o > (int64_t) sb->length) 1638233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1639233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1640233d2500723e5594f3e7c70896ffeeef32b9c950ywan sb->offset = o; 1641233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 1642233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1643233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1644233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int64_t 1645233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_buffer_tell(void * user_data) 1646233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1647233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct sniff_buffer * sb = user_data; 1648233d2500723e5594f3e7c70896ffeeef32b9c950ywan return sb->offset; 1649233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1650233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1651233d2500723e5594f3e7c70896ffeeef32b9c950ywanstatic int 1652233d2500723e5594f3e7c70896ffeeef32b9c950ywanne_match_webm(nestegg_io io, int64_t max_offset) 1653233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1654233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 1655233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t id; 1656233d2500723e5594f3e7c70896ffeeef32b9c950ywan char * doctype; 1657233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg * ctx; 1658233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1659233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!(io.read && io.seek && io.tell)) 1660233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1661233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1662233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx = ne_alloc(sizeof(*ctx)); 1663233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1664233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->io = ne_alloc(sizeof(*ctx->io)); 1665233d2500723e5594f3e7c70896ffeeef32b9c950ywan *ctx->io = io; 1666233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->alloc_pool = ne_pool_init(); 1667233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->log = ne_null_log_callback; 1668233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1669233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_peek_element(ctx, &id, NULL); 1670233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) { 1671233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_destroy(ctx); 1672233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 1673233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1674233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1675233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (id != ID_EBML) { 1676233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_destroy(ctx); 1677233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 1678233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1679233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1680233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_ctx_push(ctx, ne_top_level_elements, ctx); 1681233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1682233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* we don't check the return value of ne_parse, that might fail because 1683233d2500723e5594f3e7c70896ffeeef32b9c950ywan * max_offset is not on a valid element end point. We only want to check 1684233d2500723e5594f3e7c70896ffeeef32b9c950ywan * the EBML ID and that the doctype is "webm". */ 1685233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_parse(ctx, NULL, max_offset); 1686233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1687233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_string(ctx->ebml.doctype, &doctype) != 0 || 1688233d2500723e5594f3e7c70896ffeeef32b9c950ywan strcmp(doctype, "webm") != 0) { 1689233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_destroy(ctx); 1690233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 1691233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1692233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1693233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_destroy(ctx); 1694233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1695233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 1696233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1697233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1698233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 1699233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_init(nestegg ** context, nestegg_io io, nestegg_log callback, int64_t max_offset) 1700233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1701233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 1702233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t id, version, docversion; 1703233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list_node * track; 1704233d2500723e5594f3e7c70896ffeeef32b9c950ywan char * doctype; 1705233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg * ctx; 1706233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1707233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!(io.read && io.seek && io.tell)) 1708233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1709233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1710233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx = ne_alloc(sizeof(*ctx)); 1711233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1712233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->io = ne_alloc(sizeof(*ctx->io)); 1713233d2500723e5594f3e7c70896ffeeef32b9c950ywan *ctx->io = io; 1714233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->log = callback; 1715233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->alloc_pool = ne_pool_init(); 1716233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1717233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!ctx->log) 1718233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->log = ne_null_log_callback; 1719233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1720233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_peek_element(ctx, &id, NULL); 1721233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) { 1722233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_destroy(ctx); 1723233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1724233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1725233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1726233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (id != ID_EBML) { 1727233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_destroy(ctx); 1728233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1729233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1730233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1731233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->log(ctx, NESTEGG_LOG_DEBUG, "ctx %p", ctx); 1732233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1733233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_ctx_push(ctx, ne_top_level_elements, ctx); 1734233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1735233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_parse(ctx, NULL, max_offset); 1736233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1737233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) { 1738233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_destroy(ctx); 1739233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1740233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1741233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1742233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_uint(ctx->ebml.ebml_read_version, &version) != 0) 1743233d2500723e5594f3e7c70896ffeeef32b9c950ywan version = 1; 1744233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (version != 1) { 1745233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_destroy(ctx); 1746233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1747233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1748233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1749233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_string(ctx->ebml.doctype, &doctype) != 0) 1750233d2500723e5594f3e7c70896ffeeef32b9c950ywan doctype = "matroska"; 1751233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (strcmp(doctype, "webm") != 0) { 1752233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_destroy(ctx); 1753233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1754233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1755233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1756233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_uint(ctx->ebml.doctype_read_version, &docversion) != 0) 1757233d2500723e5594f3e7c70896ffeeef32b9c950ywan docversion = 1; 1758233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (docversion < 1 || docversion > 2) { 1759233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_destroy(ctx); 1760233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1761233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1762233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1763233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!ctx->segment.tracks.track_entry.head) { 1764233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_destroy(ctx); 1765233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1766233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1767233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1768233d2500723e5594f3e7c70896ffeeef32b9c950ywan track = ctx->segment.tracks.track_entry.head; 1769233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->track_count = 0; 1770233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1771233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (track) { 1772233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->track_count += 1; 1773233d2500723e5594f3e7c70896ffeeef32b9c950ywan track = track->next; 1774233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1775233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1776233d2500723e5594f3e7c70896ffeeef32b9c950ywan *context = ctx; 1777233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1778233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 1779233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1780233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1781233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid 1782233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_destroy(nestegg * ctx) 1783233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1784233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (ctx->ancestor) 1785233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_ctx_pop(ctx); 1786233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_pool_destroy(ctx->alloc_pool); 1787233d2500723e5594f3e7c70896ffeeef32b9c950ywan free(ctx->io); 1788233d2500723e5594f3e7c70896ffeeef32b9c950ywan free(ctx); 1789233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1790233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1791233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 1792233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_duration(nestegg * ctx, uint64_t * duration) 1793233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1794233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t tc_scale; 1795233d2500723e5594f3e7c70896ffeeef32b9c950ywan double unscaled_duration; 1796233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1797233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_float(ctx->segment.info.duration, &unscaled_duration) != 0) 1798233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1799233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1800233d2500723e5594f3e7c70896ffeeef32b9c950ywan tc_scale = ne_get_timecode_scale(ctx); 1801233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1802233d2500723e5594f3e7c70896ffeeef32b9c950ywan *duration = (uint64_t) (unscaled_duration * tc_scale); 1803233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 1804233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1805233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1806233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 1807233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_tstamp_scale(nestegg * ctx, uint64_t * scale) 1808233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1809233d2500723e5594f3e7c70896ffeeef32b9c950ywan *scale = ne_get_timecode_scale(ctx); 1810233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 1811233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1812233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1813233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 1814233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_track_count(nestegg * ctx, unsigned int * tracks) 1815233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1816233d2500723e5594f3e7c70896ffeeef32b9c950ywan *tracks = ctx->track_count; 1817233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 1818233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1819233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1820233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 1821233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_get_cue_point(nestegg * ctx, unsigned int cluster_num, int64_t max_offset, 1822233d2500723e5594f3e7c70896ffeeef32b9c950ywan int64_t * start_pos, int64_t * end_pos, uint64_t * tstamp) 1823233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1824233d2500723e5594f3e7c70896ffeeef32b9c950ywan int range_obtained = 0; 1825233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int cluster_count = 0; 1826233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct cue_point * cue_point; 1827233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct cue_track_positions * pos; 1828233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t seek_pos, track_number, tc_scale, time; 1829233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list_node * cues_node = ctx->segment.cues.cue_point.head; 1830233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_list_node * cue_pos_node = NULL; 1831233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int track = 0, track_count = 0, track_index; 1832233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1833233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!start_pos || !end_pos || !tstamp) 1834233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1835233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1836233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Initialise return values */ 1837233d2500723e5594f3e7c70896ffeeef32b9c950ywan *start_pos = -1; 1838233d2500723e5594f3e7c70896ffeeef32b9c950ywan *end_pos = -1; 1839233d2500723e5594f3e7c70896ffeeef32b9c950ywan *tstamp = 0; 1840233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1841233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!cues_node) { 1842233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_init_cue_points(ctx, max_offset); 1843233d2500723e5594f3e7c70896ffeeef32b9c950ywan cues_node = ctx->segment.cues.cue_point.head; 1844233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Verify cues have been added to context. */ 1845233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!cues_node) 1846233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1847233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1848233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1849233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_track_count(ctx, &track_count); 1850233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1851233d2500723e5594f3e7c70896ffeeef32b9c950ywan tc_scale = ne_get_timecode_scale(ctx); 1852233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1853233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (cues_node && !range_obtained) { 1854233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(cues_node->id == ID_CUE_POINT); 1855233d2500723e5594f3e7c70896ffeeef32b9c950ywan cue_point = cues_node->data; 1856233d2500723e5594f3e7c70896ffeeef32b9c950ywan cue_pos_node = cue_point->cue_track_positions.head; 1857233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (cue_pos_node) { 1858233d2500723e5594f3e7c70896ffeeef32b9c950ywan assert(cue_pos_node->id == ID_CUE_TRACK_POSITIONS); 1859233d2500723e5594f3e7c70896ffeeef32b9c950ywan pos = cue_pos_node->data; 1860233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (track = 0; track < track_count; track++) { 1861233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_uint(pos->track, &track_number) != 0) 1862233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1863233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1864233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_map_track_number_to_index(ctx, (unsigned int)track_number, &track_index) != 0) 1865233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1866233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1867233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (track_index == track) { 1868233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_uint(pos->cluster_position, &seek_pos) != 0) 1869233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1870233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (cluster_count == cluster_num) { 1871233d2500723e5594f3e7c70896ffeeef32b9c950ywan *start_pos = ctx->segment_offset+seek_pos; 1872233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_uint(cue_point->time, &time) != 0) 1873233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1874233d2500723e5594f3e7c70896ffeeef32b9c950ywan *tstamp = time * tc_scale; 1875233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else if (cluster_count == cluster_num+1) { 1876233d2500723e5594f3e7c70896ffeeef32b9c950ywan *end_pos = (ctx->segment_offset+seek_pos)-1; 1877233d2500723e5594f3e7c70896ffeeef32b9c950ywan range_obtained = 1; 1878233d2500723e5594f3e7c70896ffeeef32b9c950ywan break; 1879233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1880233d2500723e5594f3e7c70896ffeeef32b9c950ywan cluster_count++; 1881233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1882233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1883233d2500723e5594f3e7c70896ffeeef32b9c950ywan cue_pos_node = cue_pos_node->next; 1884233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1885233d2500723e5594f3e7c70896ffeeef32b9c950ywan cues_node = cues_node->next; 1886233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1887233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1888233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 1889233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1890233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1891233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 1892233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_offset_seek(nestegg * ctx, uint64_t offset) 1893233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1894233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 1895233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1896233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Seek and set up parser state for segment-level element (Cluster). */ 1897233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_io_seek(ctx->io, offset, NESTEGG_SEEK_SET); 1898233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 0) 1899233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1900233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->last_valid = 0; 1901233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1902233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (ctx->ancestor) 1903233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_ctx_pop(ctx); 1904233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1905233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_ctx_push(ctx, ne_top_level_elements, ctx); 1906233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_ctx_push(ctx, ne_segment_elements, &ctx->segment); 1907233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1908233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 1909233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1910233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1911233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 1912233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_track_seek(nestegg * ctx, unsigned int track, uint64_t tstamp) 1913233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1914233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 1915233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct cue_point * cue_point; 1916233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct cue_track_positions * pos; 1917233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t seek_pos, tc_scale; 1918233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1919233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* If there are no cues loaded, check for cues element in the seek head 1920233d2500723e5594f3e7c70896ffeeef32b9c950ywan and load it. */ 1921233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!ctx->segment.cues.cue_point.head) { 1922233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_init_cue_points(ctx, -1); 1923233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 0) 1924233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1925233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 1926233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1927233d2500723e5594f3e7c70896ffeeef32b9c950ywan tc_scale = ne_get_timecode_scale(ctx); 1928233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1929233d2500723e5594f3e7c70896ffeeef32b9c950ywan cue_point = ne_find_cue_point_for_tstamp(ctx, ctx->segment.cues.cue_point.head, 1930233d2500723e5594f3e7c70896ffeeef32b9c950ywan track, tc_scale, tstamp); 1931233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!cue_point) 1932233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1933233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1934233d2500723e5594f3e7c70896ffeeef32b9c950ywan pos = ne_find_cue_position_for_track(ctx, cue_point->cue_track_positions.head, track); 1935233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (pos == NULL) 1936233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1937233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1938233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_uint(pos->cluster_position, &seek_pos) != 0) 1939233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1940233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1941233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Seek and set up parser state for segment-level element (Cluster). */ 1942233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = nestegg_offset_seek(ctx, ctx->segment_offset + seek_pos); 1943233d2500723e5594f3e7c70896ffeeef32b9c950ywan ctx->log(ctx, NESTEGG_LOG_DEBUG, "seek: parsing cluster elements"); 1944233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_parse(ctx, NULL, -1); 1945233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 1946233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1947233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1948233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!ne_is_suspend_element(ctx->last_id)) 1949233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1950233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1951233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 1952233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1953233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1954233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 1955233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_track_type(nestegg * ctx, unsigned int track) 1956233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1957233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct track_entry * entry; 1958233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t type; 1959233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1960233d2500723e5594f3e7c70896ffeeef32b9c950ywan entry = ne_find_track_entry(ctx, track); 1961233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!entry) 1962233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1963233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1964233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_uint(entry->type, &type) != 0) 1965233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1966233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1967233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (type & TRACK_TYPE_VIDEO) 1968233d2500723e5594f3e7c70896ffeeef32b9c950ywan return NESTEGG_TRACK_VIDEO; 1969233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1970233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (type & TRACK_TYPE_AUDIO) 1971233d2500723e5594f3e7c70896ffeeef32b9c950ywan return NESTEGG_TRACK_AUDIO; 1972233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1973233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1974233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 1975233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1976233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 1977233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_track_codec_id(nestegg * ctx, unsigned int track) 1978233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 1979233d2500723e5594f3e7c70896ffeeef32b9c950ywan char * codec_id; 1980233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct track_entry * entry; 1981233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1982233d2500723e5594f3e7c70896ffeeef32b9c950ywan entry = ne_find_track_entry(ctx, track); 1983233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!entry) 1984233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1985233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1986233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_string(entry->codec_id, &codec_id) != 0) 1987233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 1988233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1989233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (strcmp(codec_id, TRACK_ID_VP8) == 0) 1990233d2500723e5594f3e7c70896ffeeef32b9c950ywan return NESTEGG_CODEC_VP8; 1991233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1992233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (strcmp(codec_id, TRACK_ID_VP9) == 0) 1993233d2500723e5594f3e7c70896ffeeef32b9c950ywan return NESTEGG_CODEC_VP9; 1994233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1995233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (strcmp(codec_id, TRACK_ID_VORBIS) == 0) 1996233d2500723e5594f3e7c70896ffeeef32b9c950ywan return NESTEGG_CODEC_VORBIS; 1997233d2500723e5594f3e7c70896ffeeef32b9c950ywan 1998233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (strcmp(codec_id, TRACK_ID_OPUS) == 0) 1999233d2500723e5594f3e7c70896ffeeef32b9c950ywan return NESTEGG_CODEC_OPUS; 2000233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2001233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 2002233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2003233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2004233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 2005233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_track_codec_data_count(nestegg * ctx, unsigned int track, 2006233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int * count) 2007233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 2008233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct track_entry * entry; 2009233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_binary codec_private; 2010233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned char * p; 2011233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2012233d2500723e5594f3e7c70896ffeeef32b9c950ywan *count = 0; 2013233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2014233d2500723e5594f3e7c70896ffeeef32b9c950ywan entry = ne_find_track_entry(ctx, track); 2015233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!entry) 2016233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 2017233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2018233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_VORBIS) 2019233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 2020233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2021233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_binary(entry->codec_private, &codec_private) != 0) 2022233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 2023233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2024233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (codec_private.length < 1) 2025233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 2026233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2027233d2500723e5594f3e7c70896ffeeef32b9c950ywan p = codec_private.data; 2028233d2500723e5594f3e7c70896ffeeef32b9c950ywan *count = *p + 1; 2029233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2030233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (*count > 3) 2031233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 2032233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2033233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 2034233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2035233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2036233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 2037233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_track_codec_data(nestegg * ctx, unsigned int track, unsigned int item, 2038233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned char ** data, size_t * length) 2039233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 2040233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct track_entry * entry; 2041233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct ebml_binary codec_private; 2042233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t sizes[3], total; 2043233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned char * p; 2044233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int count, i; 2045233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2046233d2500723e5594f3e7c70896ffeeef32b9c950ywan *data = NULL; 2047233d2500723e5594f3e7c70896ffeeef32b9c950ywan *length = 0; 2048233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2049233d2500723e5594f3e7c70896ffeeef32b9c950ywan entry = ne_find_track_entry(ctx, track); 2050233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!entry) 2051233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 2052233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2053233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_VORBIS 2054233d2500723e5594f3e7c70896ffeeef32b9c950ywan && nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_OPUS) 2055233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 2056233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2057233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_binary(entry->codec_private, &codec_private) != 0) 2058233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 2059233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2060233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (nestegg_track_codec_id(ctx, track) == NESTEGG_CODEC_VORBIS) { 2061233d2500723e5594f3e7c70896ffeeef32b9c950ywan p = codec_private.data; 2062233d2500723e5594f3e7c70896ffeeef32b9c950ywan count = *p++ + 1; 2063233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2064233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (count > 3) 2065233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 2066233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2067233d2500723e5594f3e7c70896ffeeef32b9c950ywan i = 0; 2068233d2500723e5594f3e7c70896ffeeef32b9c950ywan total = 0; 2069233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (--count) { 2070233d2500723e5594f3e7c70896ffeeef32b9c950ywan sizes[i] = ne_xiph_lace_value(&p); 2071233d2500723e5594f3e7c70896ffeeef32b9c950ywan total += sizes[i]; 2072233d2500723e5594f3e7c70896ffeeef32b9c950ywan i += 1; 2073233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2074233d2500723e5594f3e7c70896ffeeef32b9c950ywan sizes[i] = codec_private.length - total - (p - codec_private.data); 2075233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2076233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (i = 0; i < item; ++i) { 2077233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (sizes[i] > LIMIT_FRAME) 2078233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 2079233d2500723e5594f3e7c70896ffeeef32b9c950ywan p += sizes[i]; 2080233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2081233d2500723e5594f3e7c70896ffeeef32b9c950ywan *data = p; 2082233d2500723e5594f3e7c70896ffeeef32b9c950ywan *length = (size_t)sizes[item]; 2083233d2500723e5594f3e7c70896ffeeef32b9c950ywan } else { 2084233d2500723e5594f3e7c70896ffeeef32b9c950ywan *data = codec_private.data; 2085233d2500723e5594f3e7c70896ffeeef32b9c950ywan *length = codec_private.length; 2086233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2087233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2088233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 2089233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2090233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2091233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 2092233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_track_video_params(nestegg * ctx, unsigned int track, 2093233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_video_params * params) 2094233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 2095233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct track_entry * entry; 2096233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int value; 2097233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2098233d2500723e5594f3e7c70896ffeeef32b9c950ywan memset(params, 0, sizeof(*params)); 2099233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2100233d2500723e5594f3e7c70896ffeeef32b9c950ywan entry = ne_find_track_entry(ctx, track); 2101233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!entry) 2102233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 2103233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2104233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (nestegg_track_type(ctx, track) != NESTEGG_TRACK_VIDEO) 2105233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 2106233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2107233d2500723e5594f3e7c70896ffeeef32b9c950ywan value = 0; 2108233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_get_uint32(entry->video.stereo_mode, &value); 2109233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (value <= NESTEGG_VIDEO_STEREO_TOP_BOTTOM || 2110233d2500723e5594f3e7c70896ffeeef32b9c950ywan value == NESTEGG_VIDEO_STEREO_RIGHT_LEFT) 2111233d2500723e5594f3e7c70896ffeeef32b9c950ywan params->stereo_mode = value; 2112233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2113233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_uint32(entry->video.pixel_width, &value) != 0) 2114233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 2115233d2500723e5594f3e7c70896ffeeef32b9c950ywan params->width = value; 2116233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2117233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_get_uint32(entry->video.pixel_height, &value) != 0) 2118233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 2119233d2500723e5594f3e7c70896ffeeef32b9c950ywan params->height = value; 2120233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2121233d2500723e5594f3e7c70896ffeeef32b9c950ywan value = 0; 2122233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_get_uint32(entry->video.pixel_crop_bottom, &value); 2123233d2500723e5594f3e7c70896ffeeef32b9c950ywan params->crop_bottom = value; 2124233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2125233d2500723e5594f3e7c70896ffeeef32b9c950ywan value = 0; 2126233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_get_uint32(entry->video.pixel_crop_top, &value); 2127233d2500723e5594f3e7c70896ffeeef32b9c950ywan params->crop_top = value; 2128233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2129233d2500723e5594f3e7c70896ffeeef32b9c950ywan value = 0; 2130233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_get_uint32(entry->video.pixel_crop_left, &value); 2131233d2500723e5594f3e7c70896ffeeef32b9c950ywan params->crop_left = value; 2132233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2133233d2500723e5594f3e7c70896ffeeef32b9c950ywan value = 0; 2134233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_get_uint32(entry->video.pixel_crop_right, &value); 2135233d2500723e5594f3e7c70896ffeeef32b9c950ywan params->crop_right = value; 2136233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2137233d2500723e5594f3e7c70896ffeeef32b9c950ywan value = params->width; 2138233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_get_uint32(entry->video.display_width, &value); 2139233d2500723e5594f3e7c70896ffeeef32b9c950ywan params->display_width = value; 2140233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2141233d2500723e5594f3e7c70896ffeeef32b9c950ywan value = params->height; 2142233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_get_uint32(entry->video.display_height, &value); 2143233d2500723e5594f3e7c70896ffeeef32b9c950ywan params->display_height = value; 2144233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2145233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 2146233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2147233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2148233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 2149233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_track_audio_params(nestegg * ctx, unsigned int track, 2150233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_audio_params * params) 2151233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 2152233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct track_entry * entry; 2153233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int value; 2154233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2155233d2500723e5594f3e7c70896ffeeef32b9c950ywan memset(params, 0, sizeof(*params)); 2156233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2157233d2500723e5594f3e7c70896ffeeef32b9c950ywan entry = ne_find_track_entry(ctx, track); 2158233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (!entry) 2159233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 2160233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2161233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (nestegg_track_type(ctx, track) != NESTEGG_TRACK_AUDIO) 2162233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 2163233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2164233d2500723e5594f3e7c70896ffeeef32b9c950ywan params->rate = 8000; 2165233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_get_float(entry->audio.sampling_frequency, ¶ms->rate); 2166233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2167233d2500723e5594f3e7c70896ffeeef32b9c950ywan value = 1; 2168233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_get_uint32(entry->audio.channels, &value); 2169233d2500723e5594f3e7c70896ffeeef32b9c950ywan params->channels = value; 2170233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2171233d2500723e5594f3e7c70896ffeeef32b9c950ywan value = 16; 2172233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_get_uint32(entry->audio.bit_depth, &value); 2173233d2500723e5594f3e7c70896ffeeef32b9c950ywan params->depth = value; 2174233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2175233d2500723e5594f3e7c70896ffeeef32b9c950ywan value = 0; 2176233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_get_uint32(entry->codec_delay, &value); 2177233d2500723e5594f3e7c70896ffeeef32b9c950ywan params->codec_delay = value; 2178233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2179233d2500723e5594f3e7c70896ffeeef32b9c950ywan value = 0; 2180233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_get_uint32(entry->seek_preroll, &value); 2181233d2500723e5594f3e7c70896ffeeef32b9c950ywan params->seek_preroll = value; 2182233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2183233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 2184233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2185233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2186233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 2187233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_read_packet(nestegg * ctx, nestegg_packet ** pkt) 2188233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 2189233d2500723e5594f3e7c70896ffeeef32b9c950ywan int r; 2190233d2500723e5594f3e7c70896ffeeef32b9c950ywan uint64_t id, size; 2191233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2192233d2500723e5594f3e7c70896ffeeef32b9c950ywan *pkt = NULL; 2193233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2194233d2500723e5594f3e7c70896ffeeef32b9c950ywan for (;;) { 2195233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_peek_element(ctx, &id, &size); 2196233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 2197233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 2198233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2199233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* Any DESC_FLAG_SUSPEND fields must be handled here. */ 2200233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (ne_is_suspend_element(id)) { 2201233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_element(ctx, &id, &size); 2202233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 2203233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 2204233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2205233d2500723e5594f3e7c70896ffeeef32b9c950ywan /* The only DESC_FLAG_SUSPEND fields are Blocks and SimpleBlocks, which we 2206233d2500723e5594f3e7c70896ffeeef32b9c950ywan handle directly. */ 2207233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_block(ctx, id, size, pkt); 2208233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 2209233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 2210233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2211233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_read_discard_padding(ctx, *pkt); 2212233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 2213233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 2214233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2215233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 2216233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2217233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2218233d2500723e5594f3e7c70896ffeeef32b9c950ywan r = ne_parse(ctx, NULL, -1); 2219233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (r != 1) 2220233d2500723e5594f3e7c70896ffeeef32b9c950ywan return r; 2221233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2222233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2223233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 1; 2224233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2225233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2226233d2500723e5594f3e7c70896ffeeef32b9c950ywanvoid 2227233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_free_packet(nestegg_packet * pkt) 2228233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 2229233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct frame * frame; 2230233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2231233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (pkt->frame) { 2232233d2500723e5594f3e7c70896ffeeef32b9c950ywan frame = pkt->frame; 2233233d2500723e5594f3e7c70896ffeeef32b9c950ywan pkt->frame = frame->next; 2234233d2500723e5594f3e7c70896ffeeef32b9c950ywan free(frame->data); 2235233d2500723e5594f3e7c70896ffeeef32b9c950ywan free(frame); 2236233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2237233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2238233d2500723e5594f3e7c70896ffeeef32b9c950ywan free(pkt); 2239233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2240233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2241233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 2242233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_packet_track(nestegg_packet * pkt, unsigned int * track) 2243233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 2244233d2500723e5594f3e7c70896ffeeef32b9c950ywan *track = (unsigned int)pkt->track; 2245233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 2246233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2247233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2248233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 2249233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_packet_tstamp(nestegg_packet * pkt, uint64_t * tstamp) 2250233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 2251233d2500723e5594f3e7c70896ffeeef32b9c950ywan *tstamp = pkt->timecode; 2252233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 2253233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2254233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2255233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 2256233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_packet_discard_padding(nestegg_packet * pkt, int64_t * discard_padding) 2257233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 2258233d2500723e5594f3e7c70896ffeeef32b9c950ywan *discard_padding = pkt->discard_padding; 2259233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 2260233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2261233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2262233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 2263233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_packet_count(nestegg_packet * pkt, unsigned int * count) 2264233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 2265233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct frame * f = pkt->frame; 2266233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2267233d2500723e5594f3e7c70896ffeeef32b9c950ywan *count = 0; 2268233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2269233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (f) { 2270233d2500723e5594f3e7c70896ffeeef32b9c950ywan *count += 1; 2271233d2500723e5594f3e7c70896ffeeef32b9c950ywan f = f->next; 2272233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2273233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2274233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 2275233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2276233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2277233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 2278233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_packet_data(nestegg_packet * pkt, unsigned int item, 2279233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned char ** data, size_t * length) 2280233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 2281233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct frame * f = pkt->frame; 2282233d2500723e5594f3e7c70896ffeeef32b9c950ywan unsigned int count = 0; 2283233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2284233d2500723e5594f3e7c70896ffeeef32b9c950ywan *data = NULL; 2285233d2500723e5594f3e7c70896ffeeef32b9c950ywan *length = 0; 2286233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2287233d2500723e5594f3e7c70896ffeeef32b9c950ywan while (f) { 2288233d2500723e5594f3e7c70896ffeeef32b9c950ywan if (count == item) { 2289233d2500723e5594f3e7c70896ffeeef32b9c950ywan *data = f->data; 2290233d2500723e5594f3e7c70896ffeeef32b9c950ywan *length = f->length; 2291233d2500723e5594f3e7c70896ffeeef32b9c950ywan return 0; 2292233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2293233d2500723e5594f3e7c70896ffeeef32b9c950ywan count += 1; 2294233d2500723e5594f3e7c70896ffeeef32b9c950ywan f = f->next; 2295233d2500723e5594f3e7c70896ffeeef32b9c950ywan } 2296233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2297233d2500723e5594f3e7c70896ffeeef32b9c950ywan return -1; 2298233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2299233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2300233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 2301233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_has_cues(nestegg * ctx) 2302233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 2303233d2500723e5594f3e7c70896ffeeef32b9c950ywan return ctx->segment.cues.cue_point.head || 2304233d2500723e5594f3e7c70896ffeeef32b9c950ywan ne_find_seek_for_id(ctx->segment.seek_head.head, ID_CUES); 2305233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2306233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2307233d2500723e5594f3e7c70896ffeeef32b9c950ywanint 2308233d2500723e5594f3e7c70896ffeeef32b9c950ywannestegg_sniff(unsigned char const * buffer, size_t length) 2309233d2500723e5594f3e7c70896ffeeef32b9c950ywan{ 2310233d2500723e5594f3e7c70896ffeeef32b9c950ywan nestegg_io io; 2311233d2500723e5594f3e7c70896ffeeef32b9c950ywan struct sniff_buffer user_data; 2312233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2313233d2500723e5594f3e7c70896ffeeef32b9c950ywan user_data.buffer = buffer; 2314233d2500723e5594f3e7c70896ffeeef32b9c950ywan user_data.length = length; 2315233d2500723e5594f3e7c70896ffeeef32b9c950ywan user_data.offset = 0; 2316233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2317233d2500723e5594f3e7c70896ffeeef32b9c950ywan io.read = ne_buffer_read; 2318233d2500723e5594f3e7c70896ffeeef32b9c950ywan io.seek = ne_buffer_seek; 2319233d2500723e5594f3e7c70896ffeeef32b9c950ywan io.tell = ne_buffer_tell; 2320233d2500723e5594f3e7c70896ffeeef32b9c950ywan io.userdata = &user_data; 2321233d2500723e5594f3e7c70896ffeeef32b9c950ywan return ne_match_webm(io, length); 2322233d2500723e5594f3e7c70896ffeeef32b9c950ywan} 2323233d2500723e5594f3e7c70896ffeeef32b9c950ywan 2324