1538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* 2538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber * Copyright © 2010 Mozilla Foundation 3538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber * 4538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber * This program is made available under an ISC-style license. See the 5538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber * accompanying file LICENSE for details. 6538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber */ 7538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include <assert.h> 8538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include <stdlib.h> 9538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include <string.h> 10538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 11b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "third_party/nestegg/halloc/halloc.h" 12b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#include "third_party/nestegg/include/nestegg/nestegg.h" 13538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 14538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* EBML Elements */ 15538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_EBML 0x1a45dfa3 16538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_EBML_VERSION 0x4286 17538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_EBML_READ_VERSION 0x42f7 18538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_EBML_MAX_ID_LENGTH 0x42f2 19538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_EBML_MAX_SIZE_LENGTH 0x42f3 20538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_DOCTYPE 0x4282 21538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_DOCTYPE_VERSION 0x4287 22538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_DOCTYPE_READ_VERSION 0x4285 23538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 24538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Global Elements */ 25538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_VOID 0xec 26538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CRC32 0xbf 27538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 28b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian/* WebM Elements */ 29538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_SEGMENT 0x18538067 30538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 31538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Seek Head Elements */ 32538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_SEEK_HEAD 0x114d9b74 33538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_SEEK 0x4dbb 34538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_SEEK_ID 0x53ab 35538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_SEEK_POSITION 0x53ac 36538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 37538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Info Elements */ 38538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_INFO 0x1549a966 39538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_TIMECODE_SCALE 0x2ad7b1 40538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_DURATION 0x4489 41538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 42538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Cluster Elements */ 43538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CLUSTER 0x1f43b675 44538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_TIMECODE 0xe7 45538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_BLOCK_GROUP 0xa0 46538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_SIMPLE_BLOCK 0xa3 47538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 48538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* BlockGroup Elements */ 49538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_BLOCK 0xa1 50538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_BLOCK_DURATION 0x9b 51538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_REFERENCE_BLOCK 0xfb 52b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#define ID_DISCARD_PADDING 0x75a2 53538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 54538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Tracks Elements */ 55538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_TRACKS 0x1654ae6b 56538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_TRACK_ENTRY 0xae 57538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_TRACK_NUMBER 0xd7 58538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_TRACK_UID 0x73c5 59538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_TRACK_TYPE 0x83 60538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_FLAG_ENABLED 0xb9 61538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_FLAG_DEFAULT 0x88 62538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_FLAG_LACING 0x9c 63538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_TRACK_TIMECODE_SCALE 0x23314f 64538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_LANGUAGE 0x22b59c 65538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CODEC_ID 0x86 66538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CODEC_PRIVATE 0x63a2 67b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#define ID_CODEC_DELAY 0x56aa 68b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#define ID_SEEK_PREROLL 0x56bb 69538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 70538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Video Elements */ 71538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_VIDEO 0xe0 72b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#define ID_STEREO_MODE 0x53b8 73538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_PIXEL_WIDTH 0xb0 74538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_PIXEL_HEIGHT 0xba 75538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_PIXEL_CROP_BOTTOM 0x54aa 76538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_PIXEL_CROP_TOP 0x54bb 77538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_PIXEL_CROP_LEFT 0x54cc 78538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_PIXEL_CROP_RIGHT 0x54dd 79538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_DISPLAY_WIDTH 0x54b0 80538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_DISPLAY_HEIGHT 0x54ba 81538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 82538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Audio Elements */ 83538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_AUDIO 0xe1 84538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_SAMPLING_FREQUENCY 0xb5 85538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CHANNELS 0x9f 86538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_BIT_DEPTH 0x6264 87538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 88538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Cues Elements */ 89538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CUES 0x1c53bb6b 90538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CUE_POINT 0xbb 91538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CUE_TIME 0xb3 92538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CUE_TRACK_POSITIONS 0xb7 93538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CUE_TRACK 0xf7 94538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CUE_CLUSTER_POSITION 0xf1 95538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CUE_BLOCK_NUMBER 0x5378 96538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 97538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* EBML Types */ 98538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberenum ebml_type_enum { 99538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber TYPE_UNKNOWN, 100538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber TYPE_MASTER, 101538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber TYPE_UINT, 102538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber TYPE_FLOAT, 103538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber TYPE_INT, 104538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber TYPE_STRING, 105538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber TYPE_BINARY 106538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 107538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 108538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define LIMIT_STRING (1 << 20) 109538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define LIMIT_BINARY (1 << 24) 110538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define LIMIT_BLOCK (1 << 30) 111538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define LIMIT_FRAME (1 << 28) 112538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 113538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Field Flags */ 114538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define DESC_FLAG_NONE 0 115538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define DESC_FLAG_MULTI (1 << 0) 116538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define DESC_FLAG_SUSPEND (1 << 1) 117538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define DESC_FLAG_OFFSET (1 << 2) 118538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 119538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Block Header Flags */ 120538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define BLOCK_FLAGS_LACING 6 121538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 122538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Lacing Constants */ 123538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define LACING_NONE 0 124538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define LACING_XIPH 1 125538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define LACING_FIXED 2 126538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define LACING_EBML 3 127538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 128538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Track Types */ 129538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define TRACK_TYPE_VIDEO 1 130538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define TRACK_TYPE_AUDIO 2 131538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 132538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Track IDs */ 133538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define TRACK_ID_VP8 "V_VP8" 134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#define TRACK_ID_VP9 "V_VP9" 135538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define TRACK_ID_VORBIS "A_VORBIS" 136b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian#define TRACK_ID_OPUS "A_OPUS" 137538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 138538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberenum vint_mask { 139538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber MASK_NONE, 140538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber MASK_FIRST_BIT 141538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 142538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 143538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct ebml_binary { 144538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char * data; 145538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t length; 146538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 147538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 148538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct ebml_list_node { 149538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list_node * next; 150538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t id; 151538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber void * data; 152538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 153538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 154538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct ebml_list { 155538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list_node * head; 156538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list_node * tail; 157538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 158538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 159538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct ebml_type { 160538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber union ebml_value { 161538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t u; 162538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber double f; 163538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int64_t i; 164538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber char * s; 165538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_binary b; 166538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } v; 167538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber enum ebml_type_enum type; 168538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int read; 169538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 170538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 171538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* EBML Definitions */ 172538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct ebml { 173538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type ebml_version; 174538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type ebml_read_version; 175538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type ebml_max_id_length; 176538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type ebml_max_size_length; 177538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type doctype; 178538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type doctype_version; 179538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type doctype_read_version; 180538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 181538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 182538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Matroksa Definitions */ 183538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct seek { 184538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type id; 185538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type position; 186538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 187538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 188538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct seek_head { 189538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list seek; 190538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 191538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 192538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct info { 193538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type timecode_scale; 194538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type duration; 195538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 196538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 197538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct block_group { 198538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type duration; 199538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type reference_block; 200b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct ebml_type discard_padding; 201538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 202538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 203538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct cluster { 204538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type timecode; 205538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list block_group; 206538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 207538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 208538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct video { 209b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct ebml_type stereo_mode; 210538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type pixel_width; 211538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type pixel_height; 212538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type pixel_crop_bottom; 213538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type pixel_crop_top; 214538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type pixel_crop_left; 215538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type pixel_crop_right; 216538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type display_width; 217538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type display_height; 218538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 219538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 220538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct audio { 221538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type sampling_frequency; 222538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type channels; 223538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type bit_depth; 224538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 225538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 226538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct track_entry { 227538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type number; 228538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type uid; 229538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type type; 230538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type flag_enabled; 231538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type flag_default; 232538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type flag_lacing; 233538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type track_timecode_scale; 234538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type language; 235538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type codec_id; 236538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type codec_private; 237b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct ebml_type codec_delay; 238b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct ebml_type seek_preroll; 239538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct video video; 240538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct audio audio; 241538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 242538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 243538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct tracks { 244538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list track_entry; 245538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 246538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 247538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct cue_track_positions { 248538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type track; 249538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type cluster_position; 250538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type block_number; 251538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 252538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 253538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct cue_point { 254538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type time; 255538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list cue_track_positions; 256538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 257538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 258538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct cues { 259538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list cue_point; 260538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 261538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 262538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct segment { 263538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list seek_head; 264538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct info info; 265538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list cluster; 266538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct tracks tracks; 267538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct cues cues; 268538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 269538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 270538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Misc. */ 271538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct pool_ctx { 272538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber char dummy; 273538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 274538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 275538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct list_node { 276538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct list_node * previous; 277538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_element_desc * node; 278538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char * data; 279538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 280538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 281538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct saved_state { 282538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int64_t stream_offset; 283538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct list_node * ancestor; 284538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t last_id; 285538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t last_size; 286b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int last_valid; 287538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 288538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 289538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct frame { 290538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char * data; 291538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t length; 292538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct frame * next; 293538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 294538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 295538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Public (opaque) Structures */ 296538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct nestegg { 297538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_io * io; 298538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_log log; 299538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct pool_ctx * alloc_pool; 300538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t last_id; 301538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t last_size; 302b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int last_valid; 303538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct list_node * ancestor; 304538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml ebml; 305538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct segment segment; 306538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int64_t segment_offset; 307538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned int track_count; 308538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 309538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 310538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct nestegg_packet { 311538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t track; 312538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t timecode; 313538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct frame * frame; 314b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int64_t discard_padding; 315538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 316538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 317538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Element Descriptor */ 318538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct ebml_element_desc { 319538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber char const * name; 320538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t id; 321538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber enum ebml_type_enum type; 322538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t offset; 323538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned int flags; 324538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_element_desc * children; 325538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t size; 326538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t data_offset; 327538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 328538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 329538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define E_FIELD(ID, TYPE, STRUCT, FIELD) \ 330538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_NONE, NULL, 0, 0 } 331538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define E_MASTER(ID, TYPE, STRUCT, FIELD) \ 332538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_MULTI, ne_ ## FIELD ## _elements, \ 333538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber sizeof(struct FIELD), 0 } 334538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define E_SINGLE_MASTER_O(ID, TYPE, STRUCT, FIELD) \ 335538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_OFFSET, ne_ ## FIELD ## _elements, 0, \ 336538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber offsetof(STRUCT, FIELD ## _offset) } 337538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define E_SINGLE_MASTER(ID, TYPE, STRUCT, FIELD) \ 338538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_NONE, ne_ ## FIELD ## _elements, 0, 0 } 339538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define E_SUSPEND(ID, TYPE) \ 340538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber { #ID, ID, TYPE, 0, DESC_FLAG_SUSPEND, NULL, 0, 0 } 341538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define E_LAST \ 342538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber { NULL, 0, 0, 0, DESC_FLAG_NONE, NULL, 0, 0 } 343538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 344538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* EBML Element Lists */ 345538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_ebml_elements[] = { 346538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_EBML_VERSION, TYPE_UINT, struct ebml, ebml_version), 347538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_EBML_READ_VERSION, TYPE_UINT, struct ebml, ebml_read_version), 348538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_EBML_MAX_ID_LENGTH, TYPE_UINT, struct ebml, ebml_max_id_length), 349538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_EBML_MAX_SIZE_LENGTH, TYPE_UINT, struct ebml, ebml_max_size_length), 350538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_DOCTYPE, TYPE_STRING, struct ebml, doctype), 351538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_DOCTYPE_VERSION, TYPE_UINT, struct ebml, doctype_version), 352538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_DOCTYPE_READ_VERSION, TYPE_UINT, struct ebml, doctype_read_version), 353538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 354538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 355538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 356b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian/* WebM Element Lists */ 357538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_seek_elements[] = { 358538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_SEEK_ID, TYPE_BINARY, struct seek, id), 359538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_SEEK_POSITION, TYPE_UINT, struct seek, position), 360538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 361538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 362538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 363538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_seek_head_elements[] = { 364538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_MASTER(ID_SEEK, TYPE_MASTER, struct seek_head, seek), 365538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 366538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 367538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 368538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_info_elements[] = { 369538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_TIMECODE_SCALE, TYPE_UINT, struct info, timecode_scale), 370538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_DURATION, TYPE_FLOAT, struct info, duration), 371538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 372538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 373538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 374538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_block_group_elements[] = { 375538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_SUSPEND(ID_BLOCK, TYPE_BINARY), 376538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_BLOCK_DURATION, TYPE_UINT, struct block_group, duration), 377538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_REFERENCE_BLOCK, TYPE_INT, struct block_group, reference_block), 378b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian E_FIELD(ID_DISCARD_PADDING, TYPE_INT, struct block_group, discard_padding), 379538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 380538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 381538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 382538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_cluster_elements[] = { 383538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_TIMECODE, TYPE_UINT, struct cluster, timecode), 384538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_MASTER(ID_BLOCK_GROUP, TYPE_MASTER, struct cluster, block_group), 385538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_SUSPEND(ID_SIMPLE_BLOCK, TYPE_BINARY), 386538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 387538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 388538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 389538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_video_elements[] = { 390b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian E_FIELD(ID_STEREO_MODE, TYPE_UINT, struct video, stereo_mode), 391538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_PIXEL_WIDTH, TYPE_UINT, struct video, pixel_width), 392538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_PIXEL_HEIGHT, TYPE_UINT, struct video, pixel_height), 393538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_PIXEL_CROP_BOTTOM, TYPE_UINT, struct video, pixel_crop_bottom), 394538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_PIXEL_CROP_TOP, TYPE_UINT, struct video, pixel_crop_top), 395538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_PIXEL_CROP_LEFT, TYPE_UINT, struct video, pixel_crop_left), 396538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_PIXEL_CROP_RIGHT, TYPE_UINT, struct video, pixel_crop_right), 397538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_DISPLAY_WIDTH, TYPE_UINT, struct video, display_width), 398538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_DISPLAY_HEIGHT, TYPE_UINT, struct video, display_height), 399538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 400538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 401538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 402538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_audio_elements[] = { 403538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_SAMPLING_FREQUENCY, TYPE_FLOAT, struct audio, sampling_frequency), 404538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_CHANNELS, TYPE_UINT, struct audio, channels), 405538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_BIT_DEPTH, TYPE_UINT, struct audio, bit_depth), 406538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 407538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 408538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 409538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_track_entry_elements[] = { 410538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_TRACK_NUMBER, TYPE_UINT, struct track_entry, number), 411538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_TRACK_UID, TYPE_UINT, struct track_entry, uid), 412538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_TRACK_TYPE, TYPE_UINT, struct track_entry, type), 413538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_FLAG_ENABLED, TYPE_UINT, struct track_entry, flag_enabled), 414538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_FLAG_DEFAULT, TYPE_UINT, struct track_entry, flag_default), 415538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_FLAG_LACING, TYPE_UINT, struct track_entry, flag_lacing), 416538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_TRACK_TIMECODE_SCALE, TYPE_FLOAT, struct track_entry, track_timecode_scale), 417538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_LANGUAGE, TYPE_STRING, struct track_entry, language), 418538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_CODEC_ID, TYPE_STRING, struct track_entry, codec_id), 419538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_CODEC_PRIVATE, TYPE_BINARY, struct track_entry, codec_private), 420b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian E_FIELD(ID_CODEC_DELAY, TYPE_UINT, struct track_entry, codec_delay), 421b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian E_FIELD(ID_SEEK_PREROLL, TYPE_UINT, struct track_entry, seek_preroll), 422538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_SINGLE_MASTER(ID_VIDEO, TYPE_MASTER, struct track_entry, video), 423538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_SINGLE_MASTER(ID_AUDIO, TYPE_MASTER, struct track_entry, audio), 424538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 425538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 426538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 427538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_tracks_elements[] = { 428538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_MASTER(ID_TRACK_ENTRY, TYPE_MASTER, struct tracks, track_entry), 429538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 430538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 431538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 432538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_cue_track_positions_elements[] = { 433538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_CUE_TRACK, TYPE_UINT, struct cue_track_positions, track), 434538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_CUE_CLUSTER_POSITION, TYPE_UINT, struct cue_track_positions, cluster_position), 435538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_CUE_BLOCK_NUMBER, TYPE_UINT, struct cue_track_positions, block_number), 436538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 437538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 438538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 439538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_cue_point_elements[] = { 440538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_CUE_TIME, TYPE_UINT, struct cue_point, time), 441538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_MASTER(ID_CUE_TRACK_POSITIONS, TYPE_MASTER, struct cue_point, cue_track_positions), 442538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 443538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 444538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 445538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_cues_elements[] = { 446538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_MASTER(ID_CUE_POINT, TYPE_MASTER, struct cues, cue_point), 447538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 448538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 449538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 450538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_segment_elements[] = { 451538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_MASTER(ID_SEEK_HEAD, TYPE_MASTER, struct segment, seek_head), 452538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_SINGLE_MASTER(ID_INFO, TYPE_MASTER, struct segment, info), 453538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_MASTER(ID_CLUSTER, TYPE_MASTER, struct segment, cluster), 454538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_SINGLE_MASTER(ID_TRACKS, TYPE_MASTER, struct segment, tracks), 455538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_SINGLE_MASTER(ID_CUES, TYPE_MASTER, struct segment, cues), 456538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 457538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 458538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 459538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_top_level_elements[] = { 460538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_SINGLE_MASTER(ID_EBML, TYPE_MASTER, nestegg, ebml), 461538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_SINGLE_MASTER_O(ID_SEGMENT, TYPE_MASTER, nestegg, segment), 462538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 463538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 464538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 465538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#undef E_FIELD 466538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#undef E_MASTER 467538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#undef E_SINGLE_MASTER_O 468538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#undef E_SINGLE_MASTER 469538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#undef E_SUSPEND 470538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#undef E_LAST 471538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 472538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct pool_ctx * 473538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_pool_init(void) 474538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 475538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct pool_ctx * pool; 476538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 477538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber pool = h_malloc(sizeof(*pool)); 478538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!pool) 479538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber abort(); 480538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return pool; 481538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 482538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 483538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic void 484538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_pool_destroy(struct pool_ctx * pool) 485538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 486538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber h_free(pool); 487538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 488538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 489538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic void * 490538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_pool_alloc(size_t size, struct pool_ctx * pool) 491538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 492538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber void * p; 493538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 494538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber p = h_malloc(size); 495538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!p) 496538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber abort(); 497538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber hattach(p, pool); 498538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber memset(p, 0, size); 499538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return p; 500538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 501538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 502538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic void * 503538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_alloc(size_t size) 504538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 505538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber void * p; 506538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 507538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber p = calloc(1, size); 508538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!p) 509538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber abort(); 510538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return p; 511538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 512538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 513538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 514538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_io_read(nestegg_io * io, void * buffer, size_t length) 515538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 516538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return io->read(buffer, length, io->userdata); 517538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 518538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 519538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 520538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_io_seek(nestegg_io * io, int64_t offset, int whence) 521538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 522538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return io->seek(offset, whence, io->userdata); 523538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 524538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 525538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 526538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_io_read_skip(nestegg_io * io, size_t length) 527538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 528538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t get; 529538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char buf[8192]; 530538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r = 1; 531538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 532538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (length > 0) { 533538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber get = length < sizeof(buf) ? length : sizeof(buf); 534538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_io_read(io, buf, get); 535538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 536538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 537538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber length -= get; 538538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 539538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 540538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 541538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 542538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 543538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int64_t 544538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_io_tell(nestegg_io * io) 545538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 546538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return io->tell(io->userdata); 547538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 548538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 549538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 550538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_bare_read_vint(nestegg_io * io, uint64_t * value, uint64_t * length, enum vint_mask maskflag) 551538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 552538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 553538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char b; 554538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t maxlen = 8; 555538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned int count = 1, mask = 1 << 7; 556538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 557538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_io_read(io, &b, 1); 558538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 559538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 560538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 561538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (count < maxlen) { 562538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if ((b & mask) != 0) 563538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 564538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber mask >>= 1; 565538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber count += 1; 566538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 567538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 568538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (length) 569538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *length = count; 570538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value = b; 571538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 572538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (maskflag == MASK_FIRST_BIT) 573538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value = b & ~mask; 574538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 575538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (--count) { 576538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_io_read(io, &b, 1); 577538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 578538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 579538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value <<= 8; 580538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value |= b; 581538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 582538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 583538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 584538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 585538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 586538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 587538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_id(nestegg_io * io, uint64_t * value, uint64_t * length) 588538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 589538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return ne_bare_read_vint(io, value, length, MASK_NONE); 590538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 591538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 592538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 593538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_vint(nestegg_io * io, uint64_t * value, uint64_t * length) 594538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 595538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return ne_bare_read_vint(io, value, length, MASK_FIRST_BIT); 596538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 597538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 598538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 599538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_svint(nestegg_io * io, int64_t * value, uint64_t * length) 600538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 601538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 602538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t uvalue; 603538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t ulength; 604538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int64_t svint_subtr[] = { 605538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 0x3f, 0x1fff, 606538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 0xfffff, 0x7ffffff, 607538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 0x3ffffffffLL, 0x1ffffffffffLL, 608538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 0xffffffffffffLL, 0x7fffffffffffffLL 609538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber }; 610538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 611538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_bare_read_vint(io, &uvalue, &ulength, MASK_FIRST_BIT); 612538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 613538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 614538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value = uvalue - svint_subtr[ulength - 1]; 615538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (length) 616538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *length = ulength; 617538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 618538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 619538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 620538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 621538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_uint(nestegg_io * io, uint64_t * val, uint64_t length) 622538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 623538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char b; 624538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 625538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 626538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (length == 0 || length > 8) 627538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 628538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_io_read(io, &b, 1); 629538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 630538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 631538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *val = b; 632538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (--length) { 633538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_io_read(io, &b, 1); 634538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 635538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 636538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *val <<= 8; 637538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *val |= b; 638538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 639538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 640538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 641538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 642538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 643538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_int(nestegg_io * io, int64_t * val, uint64_t length) 644538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 645538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 646538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t uval, base; 647538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 648538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_uint(io, &uval, length); 649538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 650538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 651538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 652538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (length < sizeof(int64_t)) { 653538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber base = 1; 654538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber base <<= length * 8 - 1; 655538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (uval >= base) { 656538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber base = 1; 657538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber base <<= length * 8; 658538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } else { 659538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber base = 0; 660538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 661538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *val = uval - base; 662538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } else { 663538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *val = (int64_t) uval; 664538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 665538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 666538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 667538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 668538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 669538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 670538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_float(nestegg_io * io, double * val, uint64_t length) 671538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 672538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber union { 673538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t u; 674538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber float f; 675538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber double d; 676538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } value; 677538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 678538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 679b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Length == 10 not implemented. */ 680538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (length != 4 && length != 8) 681538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 682538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_uint(io, &value.u, length); 683538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 684538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 685538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (length == 4) 686538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *val = value.f; 687538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber else 688538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *val = value.d; 689538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 690538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 691538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 692538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 693538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_string(nestegg * ctx, char ** val, uint64_t length) 694538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 695538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber char * str; 696538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 697b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const size_t alloc_size = (size_t)length + 1; 698538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 699538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (length == 0 || length > LIMIT_STRING) 700538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 701b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian str = ne_pool_alloc(alloc_size, ctx->alloc_pool); 702b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_io_read(ctx->io, (unsigned char *) str, alloc_size - 1); 703538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 704538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 705b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian str[alloc_size - 1] = '\0'; 706538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *val = str; 707538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 708538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 709538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 710538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 711538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_binary(nestegg * ctx, struct ebml_binary * val, uint64_t length) 712538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 713538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (length == 0 || length > LIMIT_BINARY) 714538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 715b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian val->length = (size_t)length; 716b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian val->data = ne_pool_alloc(val->length, ctx->alloc_pool); 717b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return ne_io_read(ctx->io, val->data, val->length); 718538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 719538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 720538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 721538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_get_uint(struct ebml_type type, uint64_t * value) 722538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 723538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!type.read) 724538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 725538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 726538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(type.type == TYPE_UINT); 727538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 728538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value = type.v.u; 729538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 730538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 731538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 732538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 733538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 734b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianne_get_uint32(struct ebml_type type, unsigned int * value) 735b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 736b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian uint64_t v; 737b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (ne_get_uint(type, &v)) 738b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 739b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 740b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian assert((unsigned int)v == v); 741b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 742b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *value = (unsigned int)v; 743b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 744b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 0; 745b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 746b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 747b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic int 748538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_get_float(struct ebml_type type, double * value) 749538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 750538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!type.read) 751538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 752538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 753538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(type.type == TYPE_FLOAT); 754538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 755538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value = type.v.f; 756538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 757538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 758538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 759538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 760538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 761538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_get_string(struct ebml_type type, char ** value) 762538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 763538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!type.read) 764538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 765538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 766538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(type.type == TYPE_STRING); 767538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 768538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value = type.v.s; 769538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 770538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 771538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 772538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 773538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 774538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_get_binary(struct ebml_type type, struct ebml_binary * value) 775538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 776538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!type.read) 777538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 778538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 779538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(type.type == TYPE_BINARY); 780538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 781538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value = type.v.b; 782538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 783538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 784538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 785538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 786538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 787538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_is_ancestor_element(uint64_t id, struct list_node * ancestor) 788538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 789538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_element_desc * element; 790538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 791538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber for (; ancestor; ancestor = ancestor->previous) 792538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber for (element = ancestor->node; element->id; ++element) 793538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (element->id == id) 794538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 795538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 796538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 797538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 798538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 799538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc * 800538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_find_element(uint64_t id, struct ebml_element_desc * elements) 801538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 802538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_element_desc * element; 803538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 804538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber for (element = elements; element->id; ++element) 805538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (element->id == id) 806538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return element; 807538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 808538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return NULL; 809538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 810538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 811538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic void 812538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_ctx_push(nestegg * ctx, struct ebml_element_desc * ancestor, void * data) 813538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 814538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct list_node * item; 815538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 816538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber item = ne_alloc(sizeof(*item)); 817538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber item->previous = ctx->ancestor; 818538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber item->node = ancestor; 819538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber item->data = data; 820538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->ancestor = item; 821538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 822538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 823538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic void 824538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_ctx_pop(nestegg * ctx) 825538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 826538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct list_node * item; 827538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 828538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber item = ctx->ancestor; 829538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->ancestor = item->previous; 830538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber free(item); 831538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 832538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 833538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 834538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_ctx_save(nestegg * ctx, struct saved_state * s) 835538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 836538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber s->stream_offset = ne_io_tell(ctx->io); 837538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (s->stream_offset < 0) 838538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 839538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber s->ancestor = ctx->ancestor; 840538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber s->last_id = ctx->last_id; 841538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber s->last_size = ctx->last_size; 842b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian s->last_valid = ctx->last_valid; 843538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 844538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 845538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 846538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 847538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_ctx_restore(nestegg * ctx, struct saved_state * s) 848538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 849538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 850538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 851538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_io_seek(ctx->io, s->stream_offset, NESTEGG_SEEK_SET); 852538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 0) 853538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 854538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->ancestor = s->ancestor; 855538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->last_id = s->last_id; 856538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->last_size = s->last_size; 857b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ctx->last_valid = s->last_valid; 858538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 859538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 860538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 861538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 862538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_peek_element(nestegg * ctx, uint64_t * id, uint64_t * size) 863538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 864538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 865538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 866b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (ctx->last_valid) { 867538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (id) 868538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *id = ctx->last_id; 869538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (size) 870538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *size = ctx->last_size; 871538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 872538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 873538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 874538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_id(ctx->io, &ctx->last_id, NULL); 875538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 876538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 877538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 878538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_vint(ctx->io, &ctx->last_size, NULL); 879538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 880538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 881538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 882538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (id) 883538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *id = ctx->last_id; 884538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (size) 885538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *size = ctx->last_size; 886538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 887b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ctx->last_valid = 1; 888b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 889538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 890538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 891538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 892538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 893538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_element(nestegg * ctx, uint64_t * id, uint64_t * size) 894538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 895538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 896538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 897538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_peek_element(ctx, id, size); 898538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 899538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 900538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 901b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ctx->last_valid = 0; 902538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 903538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 904538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 905538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 906538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic void 907538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_master(nestegg * ctx, struct ebml_element_desc * desc) 908538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 909538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list * list; 910538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list_node * node, * oldtail; 911538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 912538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(desc->type == TYPE_MASTER && desc->flags & DESC_FLAG_MULTI); 913538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 914538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "multi master element %llx (%s)", 915538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber desc->id, desc->name); 916538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 917538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber list = (struct ebml_list *) (ctx->ancestor->data + desc->offset); 918538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 919538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber node = ne_pool_alloc(sizeof(*node), ctx->alloc_pool); 920538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber node->id = desc->id; 921538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber node->data = ne_pool_alloc(desc->size, ctx->alloc_pool); 922538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 923538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber oldtail = list->tail; 924538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (oldtail) 925538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber oldtail->next = node; 926538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber list->tail = node; 927538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!list->head) 928538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber list->head = node; 929538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 930538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, " -> using data %p", node->data); 931538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 932538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_ctx_push(ctx, desc->children, node->data); 933538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 934538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 935538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic void 936538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_single_master(nestegg * ctx, struct ebml_element_desc * desc) 937538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 938538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(desc->type == TYPE_MASTER && !(desc->flags & DESC_FLAG_MULTI)); 939538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 940538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "single master element %llx (%s)", 941538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber desc->id, desc->name); 942538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, " -> using data %p (%u)", 943538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->ancestor->data + desc->offset, desc->offset); 944538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 945538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_ctx_push(ctx, desc->children, ctx->ancestor->data + desc->offset); 946538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 947538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 948538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 949538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_simple(nestegg * ctx, struct ebml_element_desc * desc, size_t length) 950538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 951538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type * storage; 952b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int r = 0; 953538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 954538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber storage = (struct ebml_type *) (ctx->ancestor->data + desc->offset); 955538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 956538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (storage->read) { 957538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "element %llx (%s) already read, skipping", 958538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber desc->id, desc->name); 959538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 960538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 961538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 962538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber storage->type = desc->type; 963538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 964538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "element %llx (%s) -> %p (%u)", 965538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber desc->id, desc->name, storage, desc->offset); 966538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 967538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber switch (desc->type) { 968538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case TYPE_UINT: 969538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_uint(ctx->io, &storage->v.u, length); 970538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 971538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case TYPE_FLOAT: 972538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_float(ctx->io, &storage->v.f, length); 973538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 974538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case TYPE_INT: 975538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_int(ctx->io, &storage->v.i, length); 976538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 977538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case TYPE_STRING: 978538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_string(ctx, &storage->v.s, length); 979538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 980538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case TYPE_BINARY: 981538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_binary(ctx, &storage->v.b, length); 982538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 983538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case TYPE_MASTER: 984538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case TYPE_UNKNOWN: 985538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(0); 986538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 987538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 988538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 989538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r == 1) 990538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber storage->read = 1; 991538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 992538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 993538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 994538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 995538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 996b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianne_parse(nestegg * ctx, struct ebml_element_desc * top_level, int64_t max_offset) 997538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 998538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 999538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int64_t * data_offset; 1000b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian uint64_t id, size, peeked_id; 1001538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_element_desc * element; 1002538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1003538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!ctx->ancestor) 1004538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1005538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1006538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber for (;;) { 1007b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (max_offset > 0 && ne_io_tell(ctx->io) >= max_offset) { 1008b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Reached end of offset allowed for parsing - return gracefully */ 1009b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = 1; 1010b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 1011b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 1012538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_peek_element(ctx, &id, &size); 1013538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1014538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1015b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian peeked_id = id; 1016538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1017538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber element = ne_find_element(id, ctx->ancestor->node); 1018538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (element) { 1019538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (element->flags & DESC_FLAG_SUSPEND) { 1020538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(element->type == TYPE_BINARY); 1021538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "suspend parse at %llx", id); 1022538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = 1; 1023538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1024538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1025538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1026538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_element(ctx, &id, &size); 1027538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1028538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1029b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian assert(id == peeked_id); 1030538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1031538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (element->flags & DESC_FLAG_OFFSET) { 1032538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber data_offset = (int64_t *) (ctx->ancestor->data + element->data_offset); 1033538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *data_offset = ne_io_tell(ctx->io); 1034538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (*data_offset < 0) { 1035538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = -1; 1036538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1037538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1038538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1039538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1040538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (element->type == TYPE_MASTER) { 1041538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (element->flags & DESC_FLAG_MULTI) 1042538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_read_master(ctx, element); 1043538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber else 1044538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_read_single_master(ctx, element); 1045538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber continue; 1046538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } else { 1047b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_read_simple(ctx, element, (size_t)size); 1048538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r < 0) 1049538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1050538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1051538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } else if (ne_is_ancestor_element(id, ctx->ancestor->previous)) { 1052538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "parent element %llx", id); 1053538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (top_level && ctx->ancestor->node == top_level) { 1054538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "*** parse about to back up past top_level"); 1055538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = 1; 1056538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1057538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1058538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_ctx_pop(ctx); 1059538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } else { 1060538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_element(ctx, &id, &size); 1061538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1062538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1063538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1064538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (id != ID_VOID && id != ID_CRC32) 1065538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "unknown element %llx", id); 1066b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_io_read_skip(ctx->io, (size_t)size); 1067538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1068538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1069538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1070538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1071538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1072538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1073538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (ctx->ancestor) 1074538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_ctx_pop(ctx); 1075538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1076538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1077538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1078538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1079538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic uint64_t 1080538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_xiph_lace_value(unsigned char ** np) 1081538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1082538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t lace; 1083538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t value; 1084538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char * p = *np; 1085538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1086538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber lace = *p++; 1087538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value = lace; 1088538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (lace == 255) { 1089538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber lace = *p++; 1090538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value += lace; 1091538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1092538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1093538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *np = p; 1094538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1095538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return value; 1096538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1097538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1098538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 1099538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_xiph_lace_value(nestegg_io * io, uint64_t * value, size_t * consumed) 1100538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1101538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 1102538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t lace; 1103538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1104538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_uint(io, &lace, 1); 1105538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1106538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1107538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *consumed += 1; 1108538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1109538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value = lace; 1110538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (lace == 255) { 1111538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_uint(io, &lace, 1); 1112538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1113538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1114538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *consumed += 1; 1115538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value += lace; 1116538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1117538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1118538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 1119538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1120538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1121538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 1122538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_xiph_lacing(nestegg_io * io, size_t block, size_t * read, uint64_t n, uint64_t * sizes) 1123538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1124538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 1125538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t i = 0; 1126538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t sum = 0; 1127538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1128538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (--n) { 1129538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_xiph_lace_value(io, &sizes[i], read); 1130538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1131538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1132538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber sum += sizes[i]; 1133538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber i += 1; 1134538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1135538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1136538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (*read + sum > block) 1137538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1138538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1139b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Last frame is the remainder of the block. */ 1140538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber sizes[i] = block - *read - sum; 1141538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 1142538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1143538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1144538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 1145538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_ebml_lacing(nestegg_io * io, size_t block, size_t * read, uint64_t n, uint64_t * sizes) 1146538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1147538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 1148538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t lace, sum, length; 1149538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int64_t slace; 1150538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t i = 0; 1151538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1152538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_vint(io, &lace, &length); 1153538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1154538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1155b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian assert(length <= 8); 1156b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *read += (size_t)length; 1157538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1158538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber sizes[i] = lace; 1159538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber sum = sizes[i]; 1160538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1161538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber i += 1; 1162538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber n -= 1; 1163538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1164538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (--n) { 1165538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_svint(io, &slace, &length); 1166538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1167538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1168b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian assert(length <= 8); 1169b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *read += (size_t)length; 1170538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber sizes[i] = sizes[i - 1] + slace; 1171538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber sum += sizes[i]; 1172538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber i += 1; 1173538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1174538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1175538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (*read + sum > block) 1176538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1177538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1178b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Last frame is the remainder of the block. */ 1179538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber sizes[i] = block - *read - sum; 1180538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 1181538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1182538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1183538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic uint64_t 1184538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_get_timecode_scale(nestegg * ctx) 1185538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1186538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t scale; 1187538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1188538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_uint(ctx->segment.info.timecode_scale, &scale) != 0) 1189538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber scale = 1000000; 1190538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1191538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return scale; 1192538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1193538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1194b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic int 1195b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianne_map_track_number_to_index(nestegg * ctx, 1196b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int track_number, 1197b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int * track_index) 1198b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 1199b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct ebml_list_node * node; 1200b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct track_entry * t_entry; 1201b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian uint64_t t_number = 0; 1202b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1203b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!track_index) 1204b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1205b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *track_index = 0; 1206b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1207b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (track_number == 0) 1208b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1209b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1210b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian node = ctx->segment.tracks.track_entry.head; 1211b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while (node) { 1212b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian assert(node->id == ID_TRACK_ENTRY); 1213b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian t_entry = node->data; 1214b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (ne_get_uint(t_entry->number, &t_number) != 0) 1215b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1216b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (t_number == track_number) 1217b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 0; 1218b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *track_index += 1; 1219b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian node = node->next; 1220b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 1221b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1222b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1223b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 1224b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1225538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct track_entry * 1226538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_find_track_entry(nestegg * ctx, unsigned int track) 1227538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1228538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list_node * node; 1229538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned int tracks = 0; 1230538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1231538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber node = ctx->segment.tracks.track_entry.head; 1232538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (node) { 1233538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(node->id == ID_TRACK_ENTRY); 1234538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (track == tracks) 1235538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return node->data; 1236538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber tracks += 1; 1237538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber node = node->next; 1238538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1239538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1240538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return NULL; 1241538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1242538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1243538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 1244538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_block(nestegg * ctx, uint64_t block_id, uint64_t block_size, nestegg_packet ** data) 1245538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1246538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 1247538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int64_t timecode, abs_timecode; 1248538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_packet * pkt; 1249538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct cluster * cluster; 1250538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct frame * f, * last; 1251538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct track_entry * entry; 1252b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian const int track_scale = 1; 1253b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian uint64_t track_number, length, frame_sizes[256], cluster_tc, flags, frames, tc_scale, total; 1254b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int i, lacing, track; 1255538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t consumed = 0; 1256538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1257538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *data = NULL; 1258538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1259538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (block_size > LIMIT_BLOCK) 1260538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1261538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1262b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_read_vint(ctx->io, &track_number, &length); 1263538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1264538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1265538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1266b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (track_number == 0 || (unsigned int)track_number != track_number) 1267538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1268538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1269b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian assert(length <= 8); 1270b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian consumed += (size_t)length; 1271538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1272538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_int(ctx->io, &timecode, 2); 1273538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1274538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1275538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1276538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber consumed += 2; 1277538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1278538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_uint(ctx->io, &flags, 1); 1279538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1280538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1281538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1282538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber consumed += 1; 1283538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1284538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber frames = 0; 1285538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1286b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Flags are different between Block and SimpleBlock, but lacing is 1287b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian encoded the same way. */ 1288538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber lacing = (flags & BLOCK_FLAGS_LACING) >> 1; 1289538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1290538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber switch (lacing) { 1291538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case LACING_NONE: 1292538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber frames = 1; 1293538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1294538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case LACING_XIPH: 1295538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case LACING_FIXED: 1296538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case LACING_EBML: 1297538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_uint(ctx->io, &frames, 1); 1298538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1299538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1300538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber consumed += 1; 1301538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber frames += 1; 1302538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1303538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1304538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (frames > 256) 1305538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1306538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1307538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber switch (lacing) { 1308538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case LACING_NONE: 1309538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber frame_sizes[0] = block_size - consumed; 1310538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1311538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case LACING_XIPH: 1312538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (frames == 1) 1313538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1314b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_read_xiph_lacing(ctx->io, (size_t)block_size, &consumed, frames, frame_sizes); 1315538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1316538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1317538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1318538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case LACING_FIXED: 1319538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if ((block_size - consumed) % frames) 1320538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1321538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber for (i = 0; i < frames; ++i) 1322538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber frame_sizes[i] = (block_size - consumed) / frames; 1323538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1324538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case LACING_EBML: 1325538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (frames == 1) 1326538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1327b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_read_ebml_lacing(ctx->io, (size_t)block_size, &consumed, frames, frame_sizes); 1328538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1329538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1330538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1331538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1332538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1333b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Sanity check unlaced frame sizes against total block size. */ 1334538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber total = consumed; 1335538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber for (i = 0; i < frames; ++i) 1336538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber total += frame_sizes[i]; 1337538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (total > block_size) 1338538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1339538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1340b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (ne_map_track_number_to_index(ctx, (unsigned int)track_number, &track) != 0) 1341538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1342538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1343b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian entry = ne_find_track_entry(ctx, track); 1344b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!entry) 1345b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1346538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1347538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber tc_scale = ne_get_timecode_scale(ctx); 1348538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1349538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(ctx->segment.cluster.tail->id == ID_CLUSTER); 1350538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber cluster = ctx->segment.cluster.tail->data; 1351538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_uint(cluster->timecode, &cluster_tc) != 0) 1352538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1353538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1354538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber abs_timecode = timecode + cluster_tc; 1355538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (abs_timecode < 0) 1356538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1357538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1358538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber pkt = ne_alloc(sizeof(*pkt)); 1359b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian pkt->track = track; 1360b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian pkt->timecode = abs_timecode * tc_scale * track_scale; 1361538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1362538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "%sblock t %lld pts %f f %llx frames: %llu", 1363538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber block_id == ID_BLOCK ? "" : "simple", pkt->track, pkt->timecode / 1e9, flags, frames); 1364538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1365538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber last = NULL; 1366538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber for (i = 0; i < frames; ++i) { 1367538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (frame_sizes[i] > LIMIT_FRAME) { 1368538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_free_packet(pkt); 1369538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1370538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1371538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber f = ne_alloc(sizeof(*f)); 1372b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian f->length = (size_t)frame_sizes[i]; 1373b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian f->data = ne_alloc(f->length); 1374b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_io_read(ctx->io, f->data, f->length); 1375538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) { 1376538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber free(f->data); 1377538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber free(f); 1378538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_free_packet(pkt); 1379538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1380538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1381538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1382538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!last) 1383538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber pkt->frame = f; 1384538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber else 1385538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber last->next = f; 1386538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber last = f; 1387538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1388538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1389538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *data = pkt; 1390538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1391538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 1392538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1393538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1394b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic int 1395b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianne_read_discard_padding(nestegg * ctx, nestegg_packet * pkt) 1396b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 1397b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int r; 1398b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian uint64_t id, size; 1399b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct ebml_element_desc * element; 1400b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct ebml_type * storage; 1401b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1402b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_peek_element(ctx, &id, &size); 1403b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (r != 1) 1404b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return r; 1405b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1406b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (id != ID_DISCARD_PADDING) 1407b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 1; 1408b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1409b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian element = ne_find_element(id, ctx->ancestor->node); 1410b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!element) 1411b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 1; 1412b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1413b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian assert((size_t)size == size); 1414b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_read_simple(ctx, element, (size_t)size); 1415b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (r != 1) 1416b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return r; 1417b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian storage = (struct ebml_type *) (ctx->ancestor->data + element->offset); 1418b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian pkt->discard_padding = storage->v.i; 1419b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1420b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 1; 1421b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 1422b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1423b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1424538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic uint64_t 1425538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_buf_read_id(unsigned char const * p, size_t length) 1426538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1427538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t id = 0; 1428538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1429538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (length--) { 1430538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber id <<= 8; 1431538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber id |= *p++; 1432538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1433538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1434538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return id; 1435538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1436538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1437538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct seek * 1438538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_find_seek_for_id(struct ebml_list_node * seek_head, uint64_t id) 1439538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1440538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list * head; 1441538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list_node * seek; 1442538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_binary binary_id; 1443538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct seek * s; 1444538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1445538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (seek_head) { 1446538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(seek_head->id == ID_SEEK_HEAD); 1447538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber head = seek_head->data; 1448538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber seek = head->head; 1449538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1450538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (seek) { 1451538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(seek->id == ID_SEEK); 1452538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber s = seek->data; 1453538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1454538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_binary(s->id, &binary_id) == 0 && 1455538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_buf_read_id(binary_id.data, binary_id.length) == id) 1456538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return s; 1457538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1458538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber seek = seek->next; 1459538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1460538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1461538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber seek_head = seek_head->next; 1462538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1463538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1464538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return NULL; 1465538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1466538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1467b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic struct cue_track_positions * 1468b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianne_find_cue_position_for_track(nestegg * ctx, struct ebml_list_node * node, unsigned int track) 1469b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 1470b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct cue_track_positions * pos = NULL; 1471b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int track_number; 1472b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int t; 1473b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1474b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while (node) { 1475b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian assert(node->id == ID_CUE_TRACK_POSITIONS); 1476b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian pos = node->data; 1477b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (ne_get_uint32(pos->track, &track_number) != 0) 1478b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return NULL; 1479b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1480b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (ne_map_track_number_to_index(ctx, track_number, &t) != 0) 1481b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return NULL; 1482b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1483b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (t == track) 1484b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return pos; 1485b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1486b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian node = node->next; 1487b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 1488b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1489b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return NULL; 1490b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 1491b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1492538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct cue_point * 1493b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianne_find_cue_point_for_tstamp(nestegg * ctx, struct ebml_list_node * cue_point, unsigned int track, uint64_t scale, uint64_t tstamp) 1494538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1495538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t time; 1496538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct cue_point * c, * prev = NULL; 1497538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1498538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (cue_point) { 1499538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(cue_point->id == ID_CUE_POINT); 1500538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber c = cue_point->data; 1501538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1502538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!prev) 1503538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber prev = c; 1504538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1505538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_uint(c->time, &time) == 0 && time * scale > tstamp) 1506538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1507538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1508b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (ne_find_cue_position_for_track(ctx, c->cue_track_positions.head, track) != NULL) 1509b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian prev = c; 1510b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1511538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber cue_point = cue_point->next; 1512538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1513538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1514538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return prev; 1515538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1516538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1517538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 1518538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_is_suspend_element(uint64_t id) 1519538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1520538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (id == ID_SIMPLE_BLOCK || id == ID_BLOCK) 1521538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 1522538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1523538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1524538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1525538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic void 1526538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_null_log_callback(nestegg * ctx, unsigned int severity, char const * fmt, ...) 1527538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1528538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ctx && severity && fmt) 1529538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return; 1530538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1531538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1532b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic int 1533b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianne_init_cue_points(nestegg * ctx, int64_t max_offset) 1534b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 1535b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int r; 1536b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct ebml_list_node * node = ctx->segment.cues.cue_point.head; 1537b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct seek * found; 1538b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian uint64_t seek_pos, id; 1539b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct saved_state state; 1540b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1541b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* If there are no cues loaded, check for cues element in the seek head 1542b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian and load it. */ 1543b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!node) { 1544b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian found = ne_find_seek_for_id(ctx->segment.seek_head.head, ID_CUES); 1545b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!found) 1546b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1547b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1548b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (ne_get_uint(found->position, &seek_pos) != 0) 1549b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1550b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1551b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Save old parser state. */ 1552b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_ctx_save(ctx, &state); 1553b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (r != 0) 1554b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1555b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1556b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Seek and set up parser state for segment-level element (Cues). */ 1557b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_io_seek(ctx->io, ctx->segment_offset + seek_pos, NESTEGG_SEEK_SET); 1558b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (r != 0) 1559b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1560b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ctx->last_valid = 0; 1561b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1562b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_read_element(ctx, &id, NULL); 1563b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (r != 1) 1564b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1565b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1566b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (id != ID_CUES) 1567b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1568b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1569b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ctx->ancestor = NULL; 1570b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_ctx_push(ctx, ne_top_level_elements, ctx); 1571b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_ctx_push(ctx, ne_segment_elements, &ctx->segment); 1572b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_ctx_push(ctx, ne_cues_elements, &ctx->segment.cues); 1573b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* parser will run until end of cues element. */ 1574b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ctx->log(ctx, NESTEGG_LOG_DEBUG, "seek: parsing cue elements"); 1575b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_parse(ctx, ne_cues_elements, max_offset); 1576b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while (ctx->ancestor) 1577b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_ctx_pop(ctx); 1578b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1579b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Reset parser state to original state and seek back to old position. */ 1580b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (ne_ctx_restore(ctx, &state) != 0) 1581b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1582b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1583b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (r < 0) 1584b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1585b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1586b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian node = ctx->segment.cues.cue_point.head; 1587b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!node) 1588b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1589b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 1590b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1591b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 0; 1592b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 1593b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1594b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian/* Three functions that implement the nestegg_io interface, operating on a 1595b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * sniff_buffer. */ 1596b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstruct sniff_buffer { 1597b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned char const * buffer; 1598b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian size_t length; 1599b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int64_t offset; 1600b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian}; 1601b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1602b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic int 1603b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianne_buffer_read(void * buffer, size_t length, void * user_data) 1604b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 1605b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct sniff_buffer * sb = user_data; 1606b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1607b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int rv = 1; 1608b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian size_t available = sb->length - (size_t)sb->offset; 1609b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1610b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (available < length) 1611b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 0; 1612b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1613b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian memcpy(buffer, sb->buffer + sb->offset, length); 1614b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian sb->offset += length; 1615b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1616b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return rv; 1617b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 1618b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1619b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic int 1620b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianne_buffer_seek(int64_t offset, int whence, void * user_data) 1621b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 1622b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct sniff_buffer * sb = user_data; 1623b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int64_t o = sb->offset; 1624b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1625b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian switch(whence) { 1626b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case NESTEGG_SEEK_SET: 1627b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian o = offset; 1628b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 1629b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case NESTEGG_SEEK_CUR: 1630b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian o += offset; 1631b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 1632b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian case NESTEGG_SEEK_END: 1633b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian o = sb->length + offset; 1634b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 1635b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 1636b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1637b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (o < 0 || o > (int64_t) sb->length) 1638b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1639b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1640b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian sb->offset = o; 1641b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 0; 1642b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 1643b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1644b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic int64_t 1645b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianne_buffer_tell(void * user_data) 1646b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 1647b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct sniff_buffer * sb = user_data; 1648b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return sb->offset; 1649b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 1650b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1651b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianstatic int 1652b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianne_match_webm(nestegg_io io, int64_t max_offset) 1653b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 1654b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int r; 1655b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian uint64_t id; 1656b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian char * doctype; 1657b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian nestegg * ctx; 1658b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1659b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!(io.read && io.seek && io.tell)) 1660b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1661b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1662b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ctx = ne_alloc(sizeof(*ctx)); 1663b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1664b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ctx->io = ne_alloc(sizeof(*ctx->io)); 1665b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *ctx->io = io; 1666b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ctx->alloc_pool = ne_pool_init(); 1667b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ctx->log = ne_null_log_callback; 1668b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1669b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_peek_element(ctx, &id, NULL); 1670b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (r != 1) { 1671b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian nestegg_destroy(ctx); 1672b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 0; 1673b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 1674b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1675b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (id != ID_EBML) { 1676b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian nestegg_destroy(ctx); 1677b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 0; 1678b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 1679b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1680b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_ctx_push(ctx, ne_top_level_elements, ctx); 1681b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1682b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* we don't check the return value of ne_parse, that might fail because 1683b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * max_offset is not on a valid element end point. We only want to check 1684b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian * the EBML ID and that the doctype is "webm". */ 1685b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_parse(ctx, NULL, max_offset); 1686b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1687b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (ne_get_string(ctx->ebml.doctype, &doctype) != 0 || 1688b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian strcmp(doctype, "webm") != 0) { 1689b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian nestegg_destroy(ctx); 1690b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 0; 1691b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 1692b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1693b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian nestegg_destroy(ctx); 1694b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1695b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 1; 1696b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 1697b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1698538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1699b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniannestegg_init(nestegg ** context, nestegg_io io, nestegg_log callback, int64_t max_offset) 1700538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1701538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 1702538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t id, version, docversion; 1703538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list_node * track; 1704538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber char * doctype; 1705b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian nestegg * ctx; 1706538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1707538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!(io.read && io.seek && io.tell)) 1708538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1709538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1710538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx = ne_alloc(sizeof(*ctx)); 1711538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1712538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->io = ne_alloc(sizeof(*ctx->io)); 1713538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *ctx->io = io; 1714538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log = callback; 1715538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->alloc_pool = ne_pool_init(); 1716538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1717538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!ctx->log) 1718538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log = ne_null_log_callback; 1719538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1720538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_peek_element(ctx, &id, NULL); 1721538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) { 1722538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_destroy(ctx); 1723538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1724538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1725538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1726538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (id != ID_EBML) { 1727538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_destroy(ctx); 1728538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1729538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1730538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1731538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "ctx %p", ctx); 1732538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1733538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_ctx_push(ctx, ne_top_level_elements, ctx); 1734538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1735b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_parse(ctx, NULL, max_offset); 1736538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1737538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) { 1738538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_destroy(ctx); 1739538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1740538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1741538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1742538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_uint(ctx->ebml.ebml_read_version, &version) != 0) 1743538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber version = 1; 1744538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (version != 1) { 1745538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_destroy(ctx); 1746538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1747538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1748538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1749538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_string(ctx->ebml.doctype, &doctype) != 0) 1750538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber doctype = "matroska"; 1751538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (strcmp(doctype, "webm") != 0) { 1752538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_destroy(ctx); 1753538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1754538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1755538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1756538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_uint(ctx->ebml.doctype_read_version, &docversion) != 0) 1757538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber docversion = 1; 1758538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (docversion < 1 || docversion > 2) { 1759538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_destroy(ctx); 1760538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1761538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1762538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1763538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!ctx->segment.tracks.track_entry.head) { 1764538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_destroy(ctx); 1765538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1766538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1767538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1768538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber track = ctx->segment.tracks.track_entry.head; 1769538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->track_count = 0; 1770538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1771538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (track) { 1772538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->track_count += 1; 1773538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber track = track->next; 1774538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1775538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1776538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *context = ctx; 1777538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1778538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1779538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1780538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1781538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubervoid 1782538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_destroy(nestegg * ctx) 1783538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1784538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (ctx->ancestor) 1785538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_ctx_pop(ctx); 1786538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_pool_destroy(ctx->alloc_pool); 1787538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber free(ctx->io); 1788538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber free(ctx); 1789538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1790538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1791538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1792538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_duration(nestegg * ctx, uint64_t * duration) 1793538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1794538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t tc_scale; 1795538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber double unscaled_duration; 1796538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1797538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_float(ctx->segment.info.duration, &unscaled_duration) != 0) 1798538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1799538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1800538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber tc_scale = ne_get_timecode_scale(ctx); 1801538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1802538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *duration = (uint64_t) (unscaled_duration * tc_scale); 1803538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1804538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1805538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1806538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1807538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_tstamp_scale(nestegg * ctx, uint64_t * scale) 1808538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1809538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *scale = ne_get_timecode_scale(ctx); 1810538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1811538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1812538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1813538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1814538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_track_count(nestegg * ctx, unsigned int * tracks) 1815538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1816538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *tracks = ctx->track_count; 1817538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1818538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1819538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1820538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1821b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniannestegg_get_cue_point(nestegg * ctx, unsigned int cluster_num, int64_t max_offset, 1822b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int64_t * start_pos, int64_t * end_pos, uint64_t * tstamp) 1823538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1824b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int range_obtained = 0; 1825b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int cluster_count = 0; 1826538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct cue_point * cue_point; 1827538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct cue_track_positions * pos; 1828b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian uint64_t seek_pos, track_number, tc_scale, time; 1829b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct ebml_list_node * cues_node = ctx->segment.cues.cue_point.head; 1830b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct ebml_list_node * cue_pos_node = NULL; 1831b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int track = 0, track_count = 0, track_index; 1832538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1833b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!start_pos || !end_pos || !tstamp) 1834b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1835538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1836b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Initialise return values */ 1837b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *start_pos = -1; 1838b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *end_pos = -1; 1839b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *tstamp = 0; 1840538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1841b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!cues_node) { 1842b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_init_cue_points(ctx, max_offset); 1843b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cues_node = ctx->segment.cues.cue_point.head; 1844b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Verify cues have been added to context. */ 1845b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!cues_node) 1846538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1847b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 1848538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1849b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian nestegg_track_count(ctx, &track_count); 1850538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1851b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian tc_scale = ne_get_timecode_scale(ctx); 1852538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1853b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while (cues_node && !range_obtained) { 1854b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian assert(cues_node->id == ID_CUE_POINT); 1855b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cue_point = cues_node->data; 1856b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cue_pos_node = cue_point->cue_track_positions.head; 1857b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while (cue_pos_node) { 1858b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian assert(cue_pos_node->id == ID_CUE_TRACK_POSITIONS); 1859b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian pos = cue_pos_node->data; 1860b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for (track = 0; track < track_count; track++) { 1861b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (ne_get_uint(pos->track, &track_number) != 0) 1862b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1863b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1864b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (ne_map_track_number_to_index(ctx, (unsigned int)track_number, &track_index) != 0) 1865b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1866b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1867b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (track_index == track) { 1868b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (ne_get_uint(pos->cluster_position, &seek_pos) != 0) 1869b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1870b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (cluster_count == cluster_num) { 1871b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *start_pos = ctx->segment_offset+seek_pos; 1872b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (ne_get_uint(cue_point->time, &time) != 0) 1873b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1874b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *tstamp = time * tc_scale; 1875b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } else if (cluster_count == cluster_num+1) { 1876b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *end_pos = (ctx->segment_offset+seek_pos)-1; 1877b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian range_obtained = 1; 1878b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian break; 1879b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 1880b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cluster_count++; 1881b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 1882b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 1883b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cue_pos_node = cue_pos_node->next; 1884b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 1885b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cues_node = cues_node->next; 1886b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 1887538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1888b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 0; 1889b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 1890538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1891b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint 1892b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniannestegg_offset_seek(nestegg * ctx, uint64_t offset) 1893b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 1894b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int r; 1895538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1896b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Seek and set up parser state for segment-level element (Cluster). */ 1897b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_io_seek(ctx->io, offset, NESTEGG_SEEK_SET); 1898b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (r != 0) 1899b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1900b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ctx->last_valid = 0; 1901b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1902b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while (ctx->ancestor) 1903b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_ctx_pop(ctx); 1904b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1905b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_ctx_push(ctx, ne_top_level_elements, ctx); 1906b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_ctx_push(ctx, ne_segment_elements, &ctx->segment); 1907b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1908b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 0; 1909b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 1910b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1911b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint 1912b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniannestegg_track_seek(nestegg * ctx, unsigned int track, uint64_t tstamp) 1913b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 1914b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian int r; 1915b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct cue_point * cue_point; 1916b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct cue_track_positions * pos; 1917b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian uint64_t seek_pos, tc_scale; 1918b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 1919b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* If there are no cues loaded, check for cues element in the seek head 1920b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian and load it. */ 1921b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (!ctx->segment.cues.cue_point.head) { 1922b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_init_cue_points(ctx, -1); 1923b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (r != 0) 1924538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1925538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1926538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1927538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber tc_scale = ne_get_timecode_scale(ctx); 1928538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1929b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian cue_point = ne_find_cue_point_for_tstamp(ctx, ctx->segment.cues.cue_point.head, 1930b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian track, tc_scale, tstamp); 1931538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!cue_point) 1932538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1933538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1934b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian pos = ne_find_cue_position_for_track(ctx, cue_point->cue_track_positions.head, track); 1935b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (pos == NULL) 1936538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1937538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1938b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (ne_get_uint(pos->cluster_position, &seek_pos) != 0) 1939b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 1940538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1941b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Seek and set up parser state for segment-level element (Cluster). */ 1942b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = nestegg_offset_seek(ctx, ctx->segment_offset + seek_pos); 1943538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "seek: parsing cluster elements"); 1944b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_parse(ctx, NULL, -1); 1945538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1946538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1947538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1948538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!ne_is_suspend_element(ctx->last_id)) 1949538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1950538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1951538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1952538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1953538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1954538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1955538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_track_type(nestegg * ctx, unsigned int track) 1956538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1957538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct track_entry * entry; 1958538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t type; 1959538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1960538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber entry = ne_find_track_entry(ctx, track); 1961538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!entry) 1962538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1963538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1964538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_uint(entry->type, &type) != 0) 1965538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1966538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1967538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (type & TRACK_TYPE_VIDEO) 1968538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return NESTEGG_TRACK_VIDEO; 1969538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1970538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (type & TRACK_TYPE_AUDIO) 1971538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return NESTEGG_TRACK_AUDIO; 1972538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1973538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1974538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1975538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1976538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1977538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_track_codec_id(nestegg * ctx, unsigned int track) 1978538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1979538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber char * codec_id; 1980538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct track_entry * entry; 1981538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1982538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber entry = ne_find_track_entry(ctx, track); 1983538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!entry) 1984538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1985538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1986538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_string(entry->codec_id, &codec_id) != 0) 1987538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1988538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1989538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (strcmp(codec_id, TRACK_ID_VP8) == 0) 1990538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return NESTEGG_CODEC_VP8; 1991538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1992ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang if (strcmp(codec_id, TRACK_ID_VP9) == 0) 1993ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang return NESTEGG_CODEC_VP9; 1994ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang 1995538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (strcmp(codec_id, TRACK_ID_VORBIS) == 0) 1996538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return NESTEGG_CODEC_VORBIS; 1997538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1998b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (strcmp(codec_id, TRACK_ID_OPUS) == 0) 1999b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return NESTEGG_CODEC_OPUS; 2000b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 2001538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 2002538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 2003538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2004538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 2005538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_track_codec_data_count(nestegg * ctx, unsigned int track, 2006538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned int * count) 2007538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 2008538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct track_entry * entry; 2009538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_binary codec_private; 2010538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char * p; 2011538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2012538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *count = 0; 2013538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2014538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber entry = ne_find_track_entry(ctx, track); 2015538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!entry) 2016538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 2017538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2018538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_VORBIS) 2019538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 2020538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2021538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_binary(entry->codec_private, &codec_private) != 0) 2022538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 2023538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2024538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (codec_private.length < 1) 2025538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 2026538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2027538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber p = codec_private.data; 2028538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *count = *p + 1; 2029538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2030538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (*count > 3) 2031538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 2032538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2033538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 2034538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 2035538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2036538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 2037538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_track_codec_data(nestegg * ctx, unsigned int track, unsigned int item, 2038538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char ** data, size_t * length) 2039538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 2040538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct track_entry * entry; 2041538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_binary codec_private; 2042538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t sizes[3], total; 2043538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char * p; 2044538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned int count, i; 2045538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2046538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *data = NULL; 2047538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *length = 0; 2048538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2049538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber entry = ne_find_track_entry(ctx, track); 2050538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!entry) 2051538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 2052538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2053b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_VORBIS 2054b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian && nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_OPUS) 2055538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 2056538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2057538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_binary(entry->codec_private, &codec_private) != 0) 2058538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 2059538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2060b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (nestegg_track_codec_id(ctx, track) == NESTEGG_CODEC_VORBIS) { 2061b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian p = codec_private.data; 2062b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian count = *p++ + 1; 2063538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2064b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (count > 3) 2065b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 2066538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2067b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian i = 0; 2068b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian total = 0; 2069b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian while (--count) { 2070b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian sizes[i] = ne_xiph_lace_value(&p); 2071b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian total += sizes[i]; 2072b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian i += 1; 2073b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 2074b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian sizes[i] = codec_private.length - total - (p - codec_private.data); 2075538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2076b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian for (i = 0; i < item; ++i) { 2077b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (sizes[i] > LIMIT_FRAME) 2078b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return -1; 2079b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian p += sizes[i]; 2080b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } 2081b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *data = p; 2082b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *length = (size_t)sizes[item]; 2083b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian } else { 2084b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *data = codec_private.data; 2085b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *length = codec_private.length; 2086538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 2087538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2088538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 2089538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 2090538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2091538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 2092538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_track_video_params(nestegg * ctx, unsigned int track, 2093538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_video_params * params) 2094538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 2095538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct track_entry * entry; 2096b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int value; 2097538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2098538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber memset(params, 0, sizeof(*params)); 2099538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2100538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber entry = ne_find_track_entry(ctx, track); 2101538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!entry) 2102538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 2103538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2104538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (nestegg_track_type(ctx, track) != NESTEGG_TRACK_VIDEO) 2105538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 2106538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2107b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian value = 0; 2108b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_get_uint32(entry->video.stereo_mode, &value); 2109b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (value <= NESTEGG_VIDEO_STEREO_TOP_BOTTOM || 2110b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian value == NESTEGG_VIDEO_STEREO_RIGHT_LEFT) 2111b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian params->stereo_mode = value; 2112b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 2113b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (ne_get_uint32(entry->video.pixel_width, &value) != 0) 2114538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 2115b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian params->width = value; 2116538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2117b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (ne_get_uint32(entry->video.pixel_height, &value) != 0) 2118538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 2119b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian params->height = value; 2120538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2121538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value = 0; 2122b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_get_uint32(entry->video.pixel_crop_bottom, &value); 2123b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian params->crop_bottom = value; 2124538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2125538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value = 0; 2126b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_get_uint32(entry->video.pixel_crop_top, &value); 2127b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian params->crop_top = value; 2128538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2129538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value = 0; 2130b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_get_uint32(entry->video.pixel_crop_left, &value); 2131b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian params->crop_left = value; 2132538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2133538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value = 0; 2134b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_get_uint32(entry->video.pixel_crop_right, &value); 2135b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian params->crop_right = value; 2136538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2137538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value = params->width; 2138b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_get_uint32(entry->video.display_width, &value); 2139b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian params->display_width = value; 2140538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2141538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value = params->height; 2142b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_get_uint32(entry->video.display_height, &value); 2143b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian params->display_height = value; 2144538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2145538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 2146538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 2147538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2148538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 2149538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_track_audio_params(nestegg * ctx, unsigned int track, 2150538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_audio_params * params) 2151538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 2152538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct track_entry * entry; 2153b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian unsigned int value; 2154538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2155538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber memset(params, 0, sizeof(*params)); 2156538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2157538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber entry = ne_find_track_entry(ctx, track); 2158538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!entry) 2159538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 2160538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2161538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (nestegg_track_type(ctx, track) != NESTEGG_TRACK_AUDIO) 2162538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 2163538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2164538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber params->rate = 8000; 2165538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_get_float(entry->audio.sampling_frequency, ¶ms->rate); 2166538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2167538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value = 1; 2168b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_get_uint32(entry->audio.channels, &value); 2169b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian params->channels = value; 2170538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2171538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value = 16; 2172b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_get_uint32(entry->audio.bit_depth, &value); 2173b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian params->depth = value; 2174b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 2175b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian value = 0; 2176b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_get_uint32(entry->codec_delay, &value); 2177b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian params->codec_delay = value; 2178b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 2179b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian value = 0; 2180b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_get_uint32(entry->seek_preroll, &value); 2181b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian params->seek_preroll = value; 2182538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2183538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 2184538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 2185538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2186538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 2187538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_read_packet(nestegg * ctx, nestegg_packet ** pkt) 2188538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 2189538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 2190538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t id, size; 2191538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2192538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *pkt = NULL; 2193538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2194538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber for (;;) { 2195538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_peek_element(ctx, &id, &size); 2196538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 2197538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 2198538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2199b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* Any DESC_FLAG_SUSPEND fields must be handled here. */ 2200538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_is_suspend_element(id)) { 2201538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_element(ctx, &id, &size); 2202538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 2203538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 2204538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2205b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian /* The only DESC_FLAG_SUSPEND fields are Blocks and SimpleBlocks, which we 2206538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber handle directly. */ 2207538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_block(ctx, id, size, pkt); 2208b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (r != 1) 2209b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return r; 2210b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 2211b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_read_discard_padding(ctx, *pkt); 2212b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian if (r != 1) 2213b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return r; 2214b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 2215538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 2216538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 2217538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2218b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian r = ne_parse(ctx, NULL, -1); 2219538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 2220538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 2221538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 2222538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2223538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 2224538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 2225538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2226538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubervoid 2227538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_free_packet(nestegg_packet * pkt) 2228538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 2229538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct frame * frame; 2230538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2231538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (pkt->frame) { 2232538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber frame = pkt->frame; 2233538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber pkt->frame = frame->next; 2234538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber free(frame->data); 2235538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber free(frame); 2236538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 2237538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2238538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber free(pkt); 2239538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 2240538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2241538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 2242538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_packet_track(nestegg_packet * pkt, unsigned int * track) 2243538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 22441b362b15af34006e6a11974088a46d42b903418eJohann *track = (unsigned int)pkt->track; 2245538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 2246538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 2247538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2248538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 2249538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_packet_tstamp(nestegg_packet * pkt, uint64_t * tstamp) 2250538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 2251538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *tstamp = pkt->timecode; 2252538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 2253538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 2254538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2255538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 2256b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniannestegg_packet_discard_padding(nestegg_packet * pkt, int64_t * discard_padding) 2257b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 2258b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian *discard_padding = pkt->discard_padding; 2259b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return 0; 2260b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 2261b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 2262b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint 2263538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_packet_count(nestegg_packet * pkt, unsigned int * count) 2264538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 2265538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct frame * f = pkt->frame; 2266538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2267538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *count = 0; 2268538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2269538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (f) { 2270538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *count += 1; 2271538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber f = f->next; 2272538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 2273538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2274538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 2275538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 2276538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2277538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 2278538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_packet_data(nestegg_packet * pkt, unsigned int item, 2279538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char ** data, size_t * length) 2280538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 2281538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct frame * f = pkt->frame; 2282538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned int count = 0; 2283538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2284538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *data = NULL; 2285538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *length = 0; 2286538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2287538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (f) { 2288538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (count == item) { 2289538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *data = f->data; 2290538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *length = f->length; 2291538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 2292538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 2293538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber count += 1; 2294538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber f = f->next; 2295538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 2296538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 2297538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 2298538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 2299b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 2300b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint 2301b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniannestegg_has_cues(nestegg * ctx) 2302b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 2303b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return ctx->segment.cues.cue_point.head || 2304b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian ne_find_seek_for_id(ctx->segment.seek_head.head, ID_CUES); 2305b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 2306b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 2307b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanianint 2308b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramaniannestegg_sniff(unsigned char const * buffer, size_t length) 2309b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian{ 2310b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian nestegg_io io; 2311b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian struct sniff_buffer user_data; 2312b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 2313b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian user_data.buffer = buffer; 2314b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian user_data.length = length; 2315b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian user_data.offset = 0; 2316b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 2317b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian io.read = ne_buffer_read; 2318b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian io.seek = ne_buffer_seek; 2319b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian io.tell = ne_buffer_tell; 2320b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian io.userdata = &user_data; 2321b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian return ne_match_webm(io, length); 2322b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian} 2323b08e2e23eec181e9951df33cd704ac294c5407b6Vignesh Venkatasubramanian 2324