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 11538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include "nestegg/halloc/halloc.h" 12538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#include "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 28538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* WebMedia 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 52538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 53538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Tracks Elements */ 54538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_TRACKS 0x1654ae6b 55538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_TRACK_ENTRY 0xae 56538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_TRACK_NUMBER 0xd7 57538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_TRACK_UID 0x73c5 58538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_TRACK_TYPE 0x83 59538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_FLAG_ENABLED 0xb9 60538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_FLAG_DEFAULT 0x88 61538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_FLAG_LACING 0x9c 62538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_TRACK_TIMECODE_SCALE 0x23314f 63538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_LANGUAGE 0x22b59c 64538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CODEC_ID 0x86 65538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CODEC_PRIVATE 0x63a2 66538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 67538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Video Elements */ 68538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_VIDEO 0xe0 69538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_PIXEL_WIDTH 0xb0 70538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_PIXEL_HEIGHT 0xba 71538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_PIXEL_CROP_BOTTOM 0x54aa 72538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_PIXEL_CROP_TOP 0x54bb 73538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_PIXEL_CROP_LEFT 0x54cc 74538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_PIXEL_CROP_RIGHT 0x54dd 75538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_DISPLAY_WIDTH 0x54b0 76538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_DISPLAY_HEIGHT 0x54ba 77538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 78538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Audio Elements */ 79538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_AUDIO 0xe1 80538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_SAMPLING_FREQUENCY 0xb5 81538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CHANNELS 0x9f 82538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_BIT_DEPTH 0x6264 83538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 84538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Cues Elements */ 85538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CUES 0x1c53bb6b 86538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CUE_POINT 0xbb 87538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CUE_TIME 0xb3 88538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CUE_TRACK_POSITIONS 0xb7 89538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CUE_TRACK 0xf7 90538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CUE_CLUSTER_POSITION 0xf1 91538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define ID_CUE_BLOCK_NUMBER 0x5378 92538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 93538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* EBML Types */ 94538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberenum ebml_type_enum { 95538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber TYPE_UNKNOWN, 96538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber TYPE_MASTER, 97538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber TYPE_UINT, 98538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber TYPE_FLOAT, 99538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber TYPE_INT, 100538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber TYPE_STRING, 101538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber TYPE_BINARY 102538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 103538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 104538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define LIMIT_STRING (1 << 20) 105538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define LIMIT_BINARY (1 << 24) 106538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define LIMIT_BLOCK (1 << 30) 107538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define LIMIT_FRAME (1 << 28) 108538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 109538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Field Flags */ 110538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define DESC_FLAG_NONE 0 111538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define DESC_FLAG_MULTI (1 << 0) 112538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define DESC_FLAG_SUSPEND (1 << 1) 113538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define DESC_FLAG_OFFSET (1 << 2) 114538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 115538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Block Header Flags */ 116538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define BLOCK_FLAGS_LACING 6 117538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 118538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Lacing Constants */ 119538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define LACING_NONE 0 120538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define LACING_XIPH 1 121538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define LACING_FIXED 2 122538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define LACING_EBML 3 123538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 124538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Track Types */ 125538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define TRACK_TYPE_VIDEO 1 126538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define TRACK_TYPE_AUDIO 2 127538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 128538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Track IDs */ 129538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define TRACK_ID_VP8 "V_VP8" 130538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define TRACK_ID_VORBIS "A_VORBIS" 131538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 132538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberenum vint_mask { 133538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber MASK_NONE, 134538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber MASK_FIRST_BIT 135538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 136538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 137538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct ebml_binary { 138538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char * data; 139538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t length; 140538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 141538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 142538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct ebml_list_node { 143538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list_node * next; 144538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t id; 145538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber void * data; 146538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 147538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 148538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct ebml_list { 149538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list_node * head; 150538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list_node * tail; 151538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 152538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 153538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct ebml_type { 154538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber union ebml_value { 155538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t u; 156538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber double f; 157538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int64_t i; 158538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber char * s; 159538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_binary b; 160538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } v; 161538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber enum ebml_type_enum type; 162538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int read; 163538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 164538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 165538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* EBML Definitions */ 166538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct ebml { 167538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type ebml_version; 168538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type ebml_read_version; 169538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type ebml_max_id_length; 170538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type ebml_max_size_length; 171538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type doctype; 172538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type doctype_version; 173538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type doctype_read_version; 174538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 175538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 176538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Matroksa Definitions */ 177538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct seek { 178538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type id; 179538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type position; 180538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 181538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 182538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct seek_head { 183538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list seek; 184538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 185538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 186538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct info { 187538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type timecode_scale; 188538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type duration; 189538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 190538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 191538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct block_group { 192538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type duration; 193538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type reference_block; 194538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 195538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 196538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct cluster { 197538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type timecode; 198538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list block_group; 199538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 200538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 201538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct video { 202538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type pixel_width; 203538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type pixel_height; 204538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type pixel_crop_bottom; 205538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type pixel_crop_top; 206538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type pixel_crop_left; 207538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type pixel_crop_right; 208538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type display_width; 209538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type display_height; 210538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 211538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 212538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct audio { 213538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type sampling_frequency; 214538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type channels; 215538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type bit_depth; 216538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 217538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 218538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct track_entry { 219538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type number; 220538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type uid; 221538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type type; 222538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type flag_enabled; 223538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type flag_default; 224538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type flag_lacing; 225538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type track_timecode_scale; 226538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type language; 227538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type codec_id; 228538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type codec_private; 229538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct video video; 230538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct audio audio; 231538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 232538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 233538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct tracks { 234538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list track_entry; 235538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 236538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 237538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct cue_track_positions { 238538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type track; 239538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type cluster_position; 240538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type block_number; 241538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 242538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 243538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct cue_point { 244538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type time; 245538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list cue_track_positions; 246538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 247538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 248538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct cues { 249538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list cue_point; 250538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 251538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 252538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct segment { 253538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list seek_head; 254538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct info info; 255538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list cluster; 256538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct tracks tracks; 257538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct cues cues; 258538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 259538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 260538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Misc. */ 261538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct pool_ctx { 262538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber char dummy; 263538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 264538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 265538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct list_node { 266538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct list_node * previous; 267538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_element_desc * node; 268538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char * data; 269538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 270538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 271538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct saved_state { 272538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int64_t stream_offset; 273538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct list_node * ancestor; 274538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t last_id; 275538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t last_size; 276538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 277538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 278538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct frame { 279538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char * data; 280538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t length; 281538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct frame * next; 282538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 283538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 284538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Public (opaque) Structures */ 285538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct nestegg { 286538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_io * io; 287538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_log log; 288538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct pool_ctx * alloc_pool; 289538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t last_id; 290538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t last_size; 291538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct list_node * ancestor; 292538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml ebml; 293538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct segment segment; 294538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int64_t segment_offset; 295538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned int track_count; 296538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 297538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 298538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct nestegg_packet { 299538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t track; 300538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t timecode; 301538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct frame * frame; 302538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 303538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 304538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* Element Descriptor */ 305538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstruct ebml_element_desc { 306538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber char const * name; 307538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t id; 308538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber enum ebml_type_enum type; 309538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t offset; 310538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned int flags; 311538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_element_desc * children; 312538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t size; 313538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t data_offset; 314538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 315538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 316538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define E_FIELD(ID, TYPE, STRUCT, FIELD) \ 317538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_NONE, NULL, 0, 0 } 318538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define E_MASTER(ID, TYPE, STRUCT, FIELD) \ 319538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_MULTI, ne_ ## FIELD ## _elements, \ 320538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber sizeof(struct FIELD), 0 } 321538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define E_SINGLE_MASTER_O(ID, TYPE, STRUCT, FIELD) \ 322538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_OFFSET, ne_ ## FIELD ## _elements, 0, \ 323538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber offsetof(STRUCT, FIELD ## _offset) } 324538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define E_SINGLE_MASTER(ID, TYPE, STRUCT, FIELD) \ 325538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_NONE, ne_ ## FIELD ## _elements, 0, 0 } 326538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define E_SUSPEND(ID, TYPE) \ 327538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber { #ID, ID, TYPE, 0, DESC_FLAG_SUSPEND, NULL, 0, 0 } 328538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#define E_LAST \ 329538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber { NULL, 0, 0, 0, DESC_FLAG_NONE, NULL, 0, 0 } 330538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 331538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* EBML Element Lists */ 332538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_ebml_elements[] = { 333538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_EBML_VERSION, TYPE_UINT, struct ebml, ebml_version), 334538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_EBML_READ_VERSION, TYPE_UINT, struct ebml, ebml_read_version), 335538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_EBML_MAX_ID_LENGTH, TYPE_UINT, struct ebml, ebml_max_id_length), 336538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_EBML_MAX_SIZE_LENGTH, TYPE_UINT, struct ebml, ebml_max_size_length), 337538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_DOCTYPE, TYPE_STRING, struct ebml, doctype), 338538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_DOCTYPE_VERSION, TYPE_UINT, struct ebml, doctype_version), 339538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_DOCTYPE_READ_VERSION, TYPE_UINT, struct ebml, doctype_read_version), 340538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 341538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 342538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 343538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber/* WebMedia Element Lists */ 344538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_seek_elements[] = { 345538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_SEEK_ID, TYPE_BINARY, struct seek, id), 346538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_SEEK_POSITION, TYPE_UINT, struct seek, position), 347538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 348538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 349538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 350538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_seek_head_elements[] = { 351538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_MASTER(ID_SEEK, TYPE_MASTER, struct seek_head, seek), 352538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 353538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 354538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 355538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_info_elements[] = { 356538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_TIMECODE_SCALE, TYPE_UINT, struct info, timecode_scale), 357538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_DURATION, TYPE_FLOAT, struct info, duration), 358538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 359538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 360538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 361538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_block_group_elements[] = { 362538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_SUSPEND(ID_BLOCK, TYPE_BINARY), 363538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_BLOCK_DURATION, TYPE_UINT, struct block_group, duration), 364538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_REFERENCE_BLOCK, TYPE_INT, struct block_group, reference_block), 365538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 366538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 367538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 368538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_cluster_elements[] = { 369538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_TIMECODE, TYPE_UINT, struct cluster, timecode), 370538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_MASTER(ID_BLOCK_GROUP, TYPE_MASTER, struct cluster, block_group), 371538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_SUSPEND(ID_SIMPLE_BLOCK, TYPE_BINARY), 372538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 373538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 374538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 375538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_video_elements[] = { 376538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_PIXEL_WIDTH, TYPE_UINT, struct video, pixel_width), 377538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_PIXEL_HEIGHT, TYPE_UINT, struct video, pixel_height), 378538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_PIXEL_CROP_BOTTOM, TYPE_UINT, struct video, pixel_crop_bottom), 379538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_PIXEL_CROP_TOP, TYPE_UINT, struct video, pixel_crop_top), 380538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_PIXEL_CROP_LEFT, TYPE_UINT, struct video, pixel_crop_left), 381538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_PIXEL_CROP_RIGHT, TYPE_UINT, struct video, pixel_crop_right), 382538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_DISPLAY_WIDTH, TYPE_UINT, struct video, display_width), 383538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_DISPLAY_HEIGHT, TYPE_UINT, struct video, display_height), 384538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 385538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 386538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 387538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_audio_elements[] = { 388538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_SAMPLING_FREQUENCY, TYPE_FLOAT, struct audio, sampling_frequency), 389538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_CHANNELS, TYPE_UINT, struct audio, channels), 390538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_BIT_DEPTH, TYPE_UINT, struct audio, bit_depth), 391538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 392538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 393538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 394538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_track_entry_elements[] = { 395538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_TRACK_NUMBER, TYPE_UINT, struct track_entry, number), 396538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_TRACK_UID, TYPE_UINT, struct track_entry, uid), 397538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_TRACK_TYPE, TYPE_UINT, struct track_entry, type), 398538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_FLAG_ENABLED, TYPE_UINT, struct track_entry, flag_enabled), 399538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_FLAG_DEFAULT, TYPE_UINT, struct track_entry, flag_default), 400538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_FLAG_LACING, TYPE_UINT, struct track_entry, flag_lacing), 401538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_TRACK_TIMECODE_SCALE, TYPE_FLOAT, struct track_entry, track_timecode_scale), 402538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_LANGUAGE, TYPE_STRING, struct track_entry, language), 403538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_CODEC_ID, TYPE_STRING, struct track_entry, codec_id), 404538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_CODEC_PRIVATE, TYPE_BINARY, struct track_entry, codec_private), 405538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_SINGLE_MASTER(ID_VIDEO, TYPE_MASTER, struct track_entry, video), 406538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_SINGLE_MASTER(ID_AUDIO, TYPE_MASTER, struct track_entry, audio), 407538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 408538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 409538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 410538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_tracks_elements[] = { 411538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_MASTER(ID_TRACK_ENTRY, TYPE_MASTER, struct tracks, track_entry), 412538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 413538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 414538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 415538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_cue_track_positions_elements[] = { 416538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_CUE_TRACK, TYPE_UINT, struct cue_track_positions, track), 417538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_CUE_CLUSTER_POSITION, TYPE_UINT, struct cue_track_positions, cluster_position), 418538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_CUE_BLOCK_NUMBER, TYPE_UINT, struct cue_track_positions, block_number), 419538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 420538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 421538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 422538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_cue_point_elements[] = { 423538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_FIELD(ID_CUE_TIME, TYPE_UINT, struct cue_point, time), 424538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_MASTER(ID_CUE_TRACK_POSITIONS, TYPE_MASTER, struct cue_point, cue_track_positions), 425538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 426538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 427538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 428538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_cues_elements[] = { 429538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_MASTER(ID_CUE_POINT, TYPE_MASTER, struct cues, cue_point), 430538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 431538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 432538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 433538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_segment_elements[] = { 434538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_MASTER(ID_SEEK_HEAD, TYPE_MASTER, struct segment, seek_head), 435538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_SINGLE_MASTER(ID_INFO, TYPE_MASTER, struct segment, info), 436538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_MASTER(ID_CLUSTER, TYPE_MASTER, struct segment, cluster), 437538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_SINGLE_MASTER(ID_TRACKS, TYPE_MASTER, struct segment, tracks), 438538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_SINGLE_MASTER(ID_CUES, TYPE_MASTER, struct segment, cues), 439538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 440538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 441538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 442538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc ne_top_level_elements[] = { 443538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_SINGLE_MASTER(ID_EBML, TYPE_MASTER, nestegg, ebml), 444538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_SINGLE_MASTER_O(ID_SEGMENT, TYPE_MASTER, nestegg, segment), 445538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber E_LAST 446538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber}; 447538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 448538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#undef E_FIELD 449538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#undef E_MASTER 450538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#undef E_SINGLE_MASTER_O 451538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#undef E_SINGLE_MASTER 452538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#undef E_SUSPEND 453538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber#undef E_LAST 454538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 455538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct pool_ctx * 456538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_pool_init(void) 457538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 458538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct pool_ctx * pool; 459538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 460538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber pool = h_malloc(sizeof(*pool)); 461538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!pool) 462538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber abort(); 463538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return pool; 464538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 465538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 466538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic void 467538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_pool_destroy(struct pool_ctx * pool) 468538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 469538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber h_free(pool); 470538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 471538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 472538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic void * 473538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_pool_alloc(size_t size, struct pool_ctx * pool) 474538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 475538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber void * p; 476538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 477538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber p = h_malloc(size); 478538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!p) 479538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber abort(); 480538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber hattach(p, pool); 481538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber memset(p, 0, size); 482538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return p; 483538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 484538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 485538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic void * 486538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_alloc(size_t size) 487538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 488538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber void * p; 489538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 490538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber p = calloc(1, size); 491538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!p) 492538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber abort(); 493538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return p; 494538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 495538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 496538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 497538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_io_read(nestegg_io * io, void * buffer, size_t length) 498538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 499538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return io->read(buffer, length, io->userdata); 500538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 501538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 502538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 503538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_io_seek(nestegg_io * io, int64_t offset, int whence) 504538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 505538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return io->seek(offset, whence, io->userdata); 506538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 507538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 508538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 509538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_io_read_skip(nestegg_io * io, size_t length) 510538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 511538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t get; 512538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char buf[8192]; 513538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r = 1; 514538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 515538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (length > 0) { 516538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber get = length < sizeof(buf) ? length : sizeof(buf); 517538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_io_read(io, buf, get); 518538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 519538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 520538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber length -= get; 521538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 522538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 523538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 524538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 525538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 526538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int64_t 527538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_io_tell(nestegg_io * io) 528538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 529538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return io->tell(io->userdata); 530538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 531538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 532538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 533538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_bare_read_vint(nestegg_io * io, uint64_t * value, uint64_t * length, enum vint_mask maskflag) 534538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 535538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 536538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char b; 537538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t maxlen = 8; 538538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned int count = 1, mask = 1 << 7; 539538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 540538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_io_read(io, &b, 1); 541538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 542538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 543538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 544538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (count < maxlen) { 545538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if ((b & mask) != 0) 546538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 547538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber mask >>= 1; 548538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber count += 1; 549538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 550538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 551538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (length) 552538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *length = count; 553538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value = b; 554538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 555538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (maskflag == MASK_FIRST_BIT) 556538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value = b & ~mask; 557538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 558538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (--count) { 559538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_io_read(io, &b, 1); 560538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 561538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 562538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value <<= 8; 563538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value |= b; 564538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 565538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 566538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 567538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 568538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 569538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 570538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_id(nestegg_io * io, uint64_t * value, uint64_t * length) 571538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 572538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return ne_bare_read_vint(io, value, length, MASK_NONE); 573538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 574538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 575538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 576538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_vint(nestegg_io * io, uint64_t * value, uint64_t * length) 577538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 578538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return ne_bare_read_vint(io, value, length, MASK_FIRST_BIT); 579538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 580538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 581538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 582538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_svint(nestegg_io * io, int64_t * value, uint64_t * length) 583538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 584538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 585538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t uvalue; 586538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t ulength; 587538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int64_t svint_subtr[] = { 588538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 0x3f, 0x1fff, 589538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 0xfffff, 0x7ffffff, 590538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 0x3ffffffffLL, 0x1ffffffffffLL, 591538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 0xffffffffffffLL, 0x7fffffffffffffLL 592538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber }; 593538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 594538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_bare_read_vint(io, &uvalue, &ulength, MASK_FIRST_BIT); 595538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 596538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 597538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value = uvalue - svint_subtr[ulength - 1]; 598538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (length) 599538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *length = ulength; 600538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 601538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 602538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 603538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 604538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_uint(nestegg_io * io, uint64_t * val, uint64_t length) 605538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 606538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char b; 607538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 608538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 609538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (length == 0 || length > 8) 610538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 611538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_io_read(io, &b, 1); 612538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 613538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 614538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *val = b; 615538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (--length) { 616538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_io_read(io, &b, 1); 617538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 618538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 619538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *val <<= 8; 620538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *val |= b; 621538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 622538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 623538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 624538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 625538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 626538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_int(nestegg_io * io, int64_t * val, uint64_t length) 627538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 628538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 629538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t uval, base; 630538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 631538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_uint(io, &uval, length); 632538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 633538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 634538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 635538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (length < sizeof(int64_t)) { 636538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber base = 1; 637538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber base <<= length * 8 - 1; 638538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (uval >= base) { 639538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber base = 1; 640538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber base <<= length * 8; 641538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } else { 642538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber base = 0; 643538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 644538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *val = uval - base; 645538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } else { 646538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *val = (int64_t) uval; 647538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 648538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 649538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 650538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 651538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 652538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 653538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_float(nestegg_io * io, double * val, uint64_t length) 654538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 655538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber union { 656538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t u; 657538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber float f; 658538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber double d; 659538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } value; 660538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 661538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 662538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber /* length == 10 not implemented */ 663538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (length != 4 && length != 8) 664538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 665538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_uint(io, &value.u, length); 666538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 667538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 668538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (length == 4) 669538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *val = value.f; 670538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber else 671538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *val = value.d; 672538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 673538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 674538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 675538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 676538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_string(nestegg * ctx, char ** val, uint64_t length) 677538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 678538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber char * str; 679538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 680538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 681538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (length == 0 || length > LIMIT_STRING) 682538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 683538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber str = ne_pool_alloc(length + 1, ctx->alloc_pool); 684538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_io_read(ctx->io, (unsigned char *) str, length); 685538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 686538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 687538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber str[length] = '\0'; 688538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *val = str; 689538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 690538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 691538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 692538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 693538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_binary(nestegg * ctx, struct ebml_binary * val, uint64_t length) 694538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 695538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (length == 0 || length > LIMIT_BINARY) 696538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 697538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber val->data = ne_pool_alloc(length, ctx->alloc_pool); 698538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber val->length = length; 699538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return ne_io_read(ctx->io, val->data, length); 700538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 701538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 702538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 703538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_get_uint(struct ebml_type type, uint64_t * value) 704538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 705538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!type.read) 706538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 707538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 708538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(type.type == TYPE_UINT); 709538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 710538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value = type.v.u; 711538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 712538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 713538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 714538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 715538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 716538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_get_float(struct ebml_type type, double * value) 717538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 718538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!type.read) 719538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 720538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 721538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(type.type == TYPE_FLOAT); 722538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 723538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value = type.v.f; 724538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 725538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 726538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 727538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 728538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 729538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_get_string(struct ebml_type type, char ** value) 730538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 731538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!type.read) 732538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 733538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 734538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(type.type == TYPE_STRING); 735538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 736538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value = type.v.s; 737538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 738538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 739538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 740538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 741538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 742538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_get_binary(struct ebml_type type, struct ebml_binary * value) 743538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 744538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!type.read) 745538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 746538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 747538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(type.type == TYPE_BINARY); 748538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 749538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value = type.v.b; 750538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 751538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 752538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 753538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 754538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 755538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_is_ancestor_element(uint64_t id, struct list_node * ancestor) 756538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 757538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_element_desc * element; 758538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 759538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber for (; ancestor; ancestor = ancestor->previous) 760538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber for (element = ancestor->node; element->id; ++element) 761538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (element->id == id) 762538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 763538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 764538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 765538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 766538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 767538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct ebml_element_desc * 768538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_find_element(uint64_t id, struct ebml_element_desc * elements) 769538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 770538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_element_desc * element; 771538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 772538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber for (element = elements; element->id; ++element) 773538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (element->id == id) 774538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return element; 775538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 776538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return NULL; 777538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 778538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 779538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic void 780538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_ctx_push(nestegg * ctx, struct ebml_element_desc * ancestor, void * data) 781538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 782538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct list_node * item; 783538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 784538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber item = ne_alloc(sizeof(*item)); 785538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber item->previous = ctx->ancestor; 786538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber item->node = ancestor; 787538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber item->data = data; 788538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->ancestor = item; 789538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 790538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 791538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic void 792538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_ctx_pop(nestegg * ctx) 793538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 794538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct list_node * item; 795538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 796538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber item = ctx->ancestor; 797538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->ancestor = item->previous; 798538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber free(item); 799538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 800538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 801538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 802538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_ctx_save(nestegg * ctx, struct saved_state * s) 803538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 804538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber s->stream_offset = ne_io_tell(ctx->io); 805538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (s->stream_offset < 0) 806538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 807538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber s->ancestor = ctx->ancestor; 808538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber s->last_id = ctx->last_id; 809538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber s->last_size = ctx->last_size; 810538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 811538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 812538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 813538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 814538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_ctx_restore(nestegg * ctx, struct saved_state * s) 815538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 816538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 817538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 818538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_io_seek(ctx->io, s->stream_offset, NESTEGG_SEEK_SET); 819538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 0) 820538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 821538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->ancestor = s->ancestor; 822538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->last_id = s->last_id; 823538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->last_size = s->last_size; 824538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 825538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 826538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 827538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 828538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_peek_element(nestegg * ctx, uint64_t * id, uint64_t * size) 829538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 830538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 831538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 832538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ctx->last_id && ctx->last_size) { 833538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (id) 834538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *id = ctx->last_id; 835538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (size) 836538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *size = ctx->last_size; 837538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 838538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 839538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 840538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_id(ctx->io, &ctx->last_id, NULL); 841538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 842538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 843538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 844538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_vint(ctx->io, &ctx->last_size, NULL); 845538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 846538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 847538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 848538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (id) 849538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *id = ctx->last_id; 850538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (size) 851538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *size = ctx->last_size; 852538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 853538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 854538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 855538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 856538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 857538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_element(nestegg * ctx, uint64_t * id, uint64_t * size) 858538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 859538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 860538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 861538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_peek_element(ctx, id, size); 862538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 863538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 864538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 865538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->last_id = 0; 866538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->last_size = 0; 867538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 868538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 869538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 870538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 871538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic void 872538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_master(nestegg * ctx, struct ebml_element_desc * desc) 873538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 874538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list * list; 875538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list_node * node, * oldtail; 876538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 877538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(desc->type == TYPE_MASTER && desc->flags & DESC_FLAG_MULTI); 878538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 879538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "multi master element %llx (%s)", 880538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber desc->id, desc->name); 881538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 882538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber list = (struct ebml_list *) (ctx->ancestor->data + desc->offset); 883538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 884538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber node = ne_pool_alloc(sizeof(*node), ctx->alloc_pool); 885538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber node->id = desc->id; 886538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber node->data = ne_pool_alloc(desc->size, ctx->alloc_pool); 887538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 888538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber oldtail = list->tail; 889538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (oldtail) 890538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber oldtail->next = node; 891538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber list->tail = node; 892538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!list->head) 893538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber list->head = node; 894538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 895538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, " -> using data %p", node->data); 896538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 897538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_ctx_push(ctx, desc->children, node->data); 898538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 899538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 900538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic void 901538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_single_master(nestegg * ctx, struct ebml_element_desc * desc) 902538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 903538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(desc->type == TYPE_MASTER && !(desc->flags & DESC_FLAG_MULTI)); 904538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 905538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "single master element %llx (%s)", 906538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber desc->id, desc->name); 907538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, " -> using data %p (%u)", 908538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->ancestor->data + desc->offset, desc->offset); 909538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 910538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_ctx_push(ctx, desc->children, ctx->ancestor->data + desc->offset); 911538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 912538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 913538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 914538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_simple(nestegg * ctx, struct ebml_element_desc * desc, size_t length) 915538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 916538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_type * storage; 917538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 918538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 919538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber storage = (struct ebml_type *) (ctx->ancestor->data + desc->offset); 920538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 921538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (storage->read) { 922538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "element %llx (%s) already read, skipping", 923538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber desc->id, desc->name); 924538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 925538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 926538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 927538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber storage->type = desc->type; 928538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 929538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "element %llx (%s) -> %p (%u)", 930538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber desc->id, desc->name, storage, desc->offset); 931538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 932538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = -1; 933538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 934538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber switch (desc->type) { 935538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case TYPE_UINT: 936538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_uint(ctx->io, &storage->v.u, length); 937538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 938538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case TYPE_FLOAT: 939538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_float(ctx->io, &storage->v.f, length); 940538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 941538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case TYPE_INT: 942538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_int(ctx->io, &storage->v.i, length); 943538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 944538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case TYPE_STRING: 945538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_string(ctx, &storage->v.s, length); 946538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 947538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case TYPE_BINARY: 948538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_binary(ctx, &storage->v.b, length); 949538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 950538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case TYPE_MASTER: 951538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case TYPE_UNKNOWN: 952538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(0); 953538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 954538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 955538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 956538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r == 1) 957538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber storage->read = 1; 958538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 959538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 960538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 961538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 962538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 963538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_parse(nestegg * ctx, struct ebml_element_desc * top_level) 964538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 965538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 966538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int64_t * data_offset; 967538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t id, size; 968538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_element_desc * element; 969538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 970538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber /* loop until we need to return: 971538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber - hit suspend point 972538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber - parse complete 973538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber - error occurred */ 974538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 975538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber /* loop over elements at current level reading them if sublevel found, 976538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber push ctx onto stack and continue if sublevel ended, pop ctx off stack 977538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber and continue */ 978538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 979538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!ctx->ancestor) 980538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 981538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 982538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber for (;;) { 983538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_peek_element(ctx, &id, &size); 984538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 985538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 986538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 987538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber element = ne_find_element(id, ctx->ancestor->node); 988538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (element) { 989538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (element->flags & DESC_FLAG_SUSPEND) { 990538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(element->type == TYPE_BINARY); 991538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "suspend parse at %llx", id); 992538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = 1; 993538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 994538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 995538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 996538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_element(ctx, &id, &size); 997538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 998538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 999538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1000538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (element->flags & DESC_FLAG_OFFSET) { 1001538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber data_offset = (int64_t *) (ctx->ancestor->data + element->data_offset); 1002538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *data_offset = ne_io_tell(ctx->io); 1003538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (*data_offset < 0) { 1004538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = -1; 1005538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1006538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1007538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1008538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1009538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (element->type == TYPE_MASTER) { 1010538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (element->flags & DESC_FLAG_MULTI) 1011538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_read_master(ctx, element); 1012538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber else 1013538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_read_single_master(ctx, element); 1014538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber continue; 1015538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } else { 1016538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_simple(ctx, element, size); 1017538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r < 0) 1018538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1019538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1020538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } else if (ne_is_ancestor_element(id, ctx->ancestor->previous)) { 1021538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "parent element %llx", id); 1022538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (top_level && ctx->ancestor->node == top_level) { 1023538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "*** parse about to back up past top_level"); 1024538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = 1; 1025538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1026538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1027538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_ctx_pop(ctx); 1028538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } else { 1029538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_element(ctx, &id, &size); 1030538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1031538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1032538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1033538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (id != ID_VOID && id != ID_CRC32) 1034538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "unknown element %llx", id); 1035538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_io_read_skip(ctx->io, size); 1036538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1037538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1038538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1039538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1040538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1041538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1042538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (ctx->ancestor) 1043538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_ctx_pop(ctx); 1044538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1045538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1046538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1047538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1048538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic uint64_t 1049538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_xiph_lace_value(unsigned char ** np) 1050538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1051538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t lace; 1052538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t value; 1053538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char * p = *np; 1054538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1055538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber lace = *p++; 1056538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value = lace; 1057538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (lace == 255) { 1058538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber lace = *p++; 1059538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value += lace; 1060538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1061538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1062538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *np = p; 1063538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1064538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return value; 1065538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1066538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1067538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 1068538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_xiph_lace_value(nestegg_io * io, uint64_t * value, size_t * consumed) 1069538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1070538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 1071538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t lace; 1072538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1073538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_uint(io, &lace, 1); 1074538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1075538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1076538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *consumed += 1; 1077538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1078538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value = lace; 1079538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (lace == 255) { 1080538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_uint(io, &lace, 1); 1081538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1082538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1083538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *consumed += 1; 1084538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *value += lace; 1085538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1086538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1087538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 1088538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1089538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1090538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 1091538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_xiph_lacing(nestegg_io * io, size_t block, size_t * read, uint64_t n, uint64_t * sizes) 1092538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1093538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 1094538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t i = 0; 1095538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t sum = 0; 1096538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1097538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (--n) { 1098538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_xiph_lace_value(io, &sizes[i], read); 1099538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1100538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1101538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber sum += sizes[i]; 1102538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber i += 1; 1103538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1104538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1105538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (*read + sum > block) 1106538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1107538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1108538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber /* last frame is the remainder of the block */ 1109538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber sizes[i] = block - *read - sum; 1110538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 1111538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1112538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1113538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 1114538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_ebml_lacing(nestegg_io * io, size_t block, size_t * read, uint64_t n, uint64_t * sizes) 1115538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1116538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 1117538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t lace, sum, length; 1118538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int64_t slace; 1119538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t i = 0; 1120538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1121538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_vint(io, &lace, &length); 1122538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1123538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1124538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *read += length; 1125538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1126538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber sizes[i] = lace; 1127538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber sum = sizes[i]; 1128538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1129538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber i += 1; 1130538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber n -= 1; 1131538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1132538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (--n) { 1133538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_svint(io, &slace, &length); 1134538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1135538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1136538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *read += length; 1137538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber sizes[i] = sizes[i - 1] + slace; 1138538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber sum += sizes[i]; 1139538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber i += 1; 1140538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1141538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1142538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (*read + sum > block) 1143538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1144538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1145538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber /* last frame is the remainder of the block */ 1146538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber sizes[i] = block - *read - sum; 1147538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 1148538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1149538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1150538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic uint64_t 1151538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_get_timecode_scale(nestegg * ctx) 1152538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1153538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t scale; 1154538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1155538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_uint(ctx->segment.info.timecode_scale, &scale) != 0) 1156538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber scale = 1000000; 1157538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1158538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return scale; 1159538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1160538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1161538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct track_entry * 1162538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_find_track_entry(nestegg * ctx, unsigned int track) 1163538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1164538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list_node * node; 1165538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned int tracks = 0; 1166538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1167538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber node = ctx->segment.tracks.track_entry.head; 1168538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (node) { 1169538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(node->id == ID_TRACK_ENTRY); 1170538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (track == tracks) 1171538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return node->data; 1172538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber tracks += 1; 1173538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber node = node->next; 1174538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1175538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1176538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return NULL; 1177538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1178538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1179538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 1180538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_read_block(nestegg * ctx, uint64_t block_id, uint64_t block_size, nestegg_packet ** data) 1181538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1182538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 1183538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int64_t timecode, abs_timecode; 1184538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_packet * pkt; 1185538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct cluster * cluster; 1186538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct frame * f, * last; 1187538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct track_entry * entry; 1188538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber double track_scale; 1189538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t track, length, frame_sizes[256], cluster_tc, flags, frames, tc_scale, total; 1190538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned int i, lacing; 1191538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber size_t consumed = 0; 1192538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1193538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *data = NULL; 1194538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1195538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (block_size > LIMIT_BLOCK) 1196538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1197538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1198538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_vint(ctx->io, &track, &length); 1199538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1200538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1201538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1202538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (track == 0 || track > ctx->track_count) 1203538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1204538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1205538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber consumed += length; 1206538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1207538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_int(ctx->io, &timecode, 2); 1208538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1209538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1210538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1211538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber consumed += 2; 1212538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1213538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_uint(ctx->io, &flags, 1); 1214538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1215538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1216538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1217538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber consumed += 1; 1218538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1219538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber frames = 0; 1220538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1221538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber /* flags are different between block and simpleblock, but lacing is 1222538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber encoded the same way */ 1223538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber lacing = (flags & BLOCK_FLAGS_LACING) >> 1; 1224538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1225538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber switch (lacing) { 1226538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case LACING_NONE: 1227538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber frames = 1; 1228538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1229538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case LACING_XIPH: 1230538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case LACING_FIXED: 1231538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case LACING_EBML: 1232538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_uint(ctx->io, &frames, 1); 1233538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1234538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1235538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber consumed += 1; 1236538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber frames += 1; 1237538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1238538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1239538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (frames > 256) 1240538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1241538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1242538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber switch (lacing) { 1243538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case LACING_NONE: 1244538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber frame_sizes[0] = block_size - consumed; 1245538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1246538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case LACING_XIPH: 1247538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (frames == 1) 1248538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1249538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_xiph_lacing(ctx->io, block_size, &consumed, frames, frame_sizes); 1250538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1251538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1252538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1253538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case LACING_FIXED: 1254538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if ((block_size - consumed) % frames) 1255538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1256538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber for (i = 0; i < frames; ++i) 1257538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber frame_sizes[i] = (block_size - consumed) / frames; 1258538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1259538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber case LACING_EBML: 1260538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (frames == 1) 1261538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1262538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_ebml_lacing(ctx->io, block_size, &consumed, frames, frame_sizes); 1263538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1264538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1265538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1266538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1267538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1268538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber /* sanity check unlaced frame sizes against total block size. */ 1269538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber total = consumed; 1270538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber for (i = 0; i < frames; ++i) 1271538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber total += frame_sizes[i]; 1272538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (total > block_size) 1273538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1274538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1275538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber entry = ne_find_track_entry(ctx, track - 1); 1276538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!entry) 1277538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1278538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1279538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber track_scale = 1.0; 1280538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1281538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber tc_scale = ne_get_timecode_scale(ctx); 1282538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1283538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(ctx->segment.cluster.tail->id == ID_CLUSTER); 1284538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber cluster = ctx->segment.cluster.tail->data; 1285538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_uint(cluster->timecode, &cluster_tc) != 0) 1286538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1287538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1288538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber abs_timecode = timecode + cluster_tc; 1289538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (abs_timecode < 0) 1290538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1291538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1292538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber pkt = ne_alloc(sizeof(*pkt)); 1293538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber pkt->track = track - 1; 1294538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber pkt->timecode = abs_timecode * tc_scale * track_scale; 1295538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1296538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "%sblock t %lld pts %f f %llx frames: %llu", 1297538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber block_id == ID_BLOCK ? "" : "simple", pkt->track, pkt->timecode / 1e9, flags, frames); 1298538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1299538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber last = NULL; 1300538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber for (i = 0; i < frames; ++i) { 1301538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (frame_sizes[i] > LIMIT_FRAME) { 1302538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_free_packet(pkt); 1303538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1304538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1305538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber f = ne_alloc(sizeof(*f)); 1306538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber f->data = ne_alloc(frame_sizes[i]); 1307538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber f->length = frame_sizes[i]; 1308538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_io_read(ctx->io, f->data, frame_sizes[i]); 1309538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) { 1310538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber free(f->data); 1311538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber free(f); 1312538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_free_packet(pkt); 1313538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1314538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1315538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1316538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!last) 1317538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber pkt->frame = f; 1318538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber else 1319538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber last->next = f; 1320538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber last = f; 1321538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1322538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1323538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *data = pkt; 1324538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1325538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 1326538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1327538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1328538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic uint64_t 1329538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_buf_read_id(unsigned char const * p, size_t length) 1330538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1331538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t id = 0; 1332538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1333538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (length--) { 1334538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber id <<= 8; 1335538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber id |= *p++; 1336538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1337538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1338538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return id; 1339538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1340538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1341538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct seek * 1342538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_find_seek_for_id(struct ebml_list_node * seek_head, uint64_t id) 1343538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1344538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list * head; 1345538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list_node * seek; 1346538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_binary binary_id; 1347538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct seek * s; 1348538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1349538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (seek_head) { 1350538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(seek_head->id == ID_SEEK_HEAD); 1351538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber head = seek_head->data; 1352538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber seek = head->head; 1353538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1354538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (seek) { 1355538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(seek->id == ID_SEEK); 1356538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber s = seek->data; 1357538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1358538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_binary(s->id, &binary_id) == 0 && 1359538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_buf_read_id(binary_id.data, binary_id.length) == id) 1360538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return s; 1361538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1362538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber seek = seek->next; 1363538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1364538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1365538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber seek_head = seek_head->next; 1366538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1367538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1368538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return NULL; 1369538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1370538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1371538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic struct cue_point * 1372538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_find_cue_point_for_tstamp(struct ebml_list_node * cue_point, uint64_t scale, uint64_t tstamp) 1373538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1374538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t time; 1375538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct cue_point * c, * prev = NULL; 1376538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1377538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (cue_point) { 1378538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(cue_point->id == ID_CUE_POINT); 1379538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber c = cue_point->data; 1380538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1381538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!prev) 1382538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber prev = c; 1383538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1384538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_uint(c->time, &time) == 0 && time * scale > tstamp) 1385538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1386538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1387538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber prev = cue_point->data; 1388538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber cue_point = cue_point->next; 1389538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1390538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1391538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return prev; 1392538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1393538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1394538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic int 1395538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_is_suspend_element(uint64_t id) 1396538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1397538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber /* this could search the tree of elements for DESC_FLAG_SUSPEND */ 1398538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (id == ID_SIMPLE_BLOCK || id == ID_BLOCK) 1399538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 1400538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1401538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1402538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1403538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic void 1404538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberne_null_log_callback(nestegg * ctx, unsigned int severity, char const * fmt, ...) 1405538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1406538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ctx && severity && fmt) 1407538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return; 1408538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1409538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1410538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1411538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_init(nestegg ** context, nestegg_io io, nestegg_log callback) 1412538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1413538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 1414538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t id, version, docversion; 1415538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list_node * track; 1416538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber char * doctype; 1417538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg * ctx = NULL; 1418538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1419538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!(io.read && io.seek && io.tell)) 1420538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1421538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1422538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx = ne_alloc(sizeof(*ctx)); 1423538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1424538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->io = ne_alloc(sizeof(*ctx->io)); 1425538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *ctx->io = io; 1426538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log = callback; 1427538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->alloc_pool = ne_pool_init(); 1428538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1429538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!ctx->log) 1430538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log = ne_null_log_callback; 1431538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1432538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_peek_element(ctx, &id, NULL); 1433538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) { 1434538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_destroy(ctx); 1435538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1436538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1437538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1438538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (id != ID_EBML) { 1439538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_destroy(ctx); 1440538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1441538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1442538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1443538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "ctx %p", ctx); 1444538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1445538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_ctx_push(ctx, ne_top_level_elements, ctx); 1446538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1447538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_parse(ctx, NULL); 1448538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1449538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) { 1450538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_destroy(ctx); 1451538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1452538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1453538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1454538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_uint(ctx->ebml.ebml_read_version, &version) != 0) 1455538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber version = 1; 1456538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (version != 1) { 1457538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_destroy(ctx); 1458538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1459538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1460538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1461538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_string(ctx->ebml.doctype, &doctype) != 0) 1462538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber doctype = "matroska"; 1463538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (strcmp(doctype, "webm") != 0) { 1464538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_destroy(ctx); 1465538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1466538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1467538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1468538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_uint(ctx->ebml.doctype_read_version, &docversion) != 0) 1469538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber docversion = 1; 1470538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (docversion < 1 || docversion > 2) { 1471538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_destroy(ctx); 1472538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1473538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1474538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1475538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!ctx->segment.tracks.track_entry.head) { 1476538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_destroy(ctx); 1477538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1478538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1479538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1480538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber track = ctx->segment.tracks.track_entry.head; 1481538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->track_count = 0; 1482538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1483538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (track) { 1484538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->track_count += 1; 1485538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber track = track->next; 1486538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1487538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1488538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *context = ctx; 1489538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1490538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1491538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1492538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1493538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubervoid 1494538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_destroy(nestegg * ctx) 1495538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1496538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (ctx->ancestor) 1497538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_ctx_pop(ctx); 1498538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_pool_destroy(ctx->alloc_pool); 1499538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber free(ctx->io); 1500538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber free(ctx); 1501538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1502538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1503538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1504538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_duration(nestegg * ctx, uint64_t * duration) 1505538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1506538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t tc_scale; 1507538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber double unscaled_duration; 1508538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1509538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_float(ctx->segment.info.duration, &unscaled_duration) != 0) 1510538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1511538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1512538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber tc_scale = ne_get_timecode_scale(ctx); 1513538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1514538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *duration = (uint64_t) (unscaled_duration * tc_scale); 1515538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1516538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1517538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1518538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1519538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_tstamp_scale(nestegg * ctx, uint64_t * scale) 1520538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1521538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *scale = ne_get_timecode_scale(ctx); 1522538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1523538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1524538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1525538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1526538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_track_count(nestegg * ctx, unsigned int * tracks) 1527538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1528538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *tracks = ctx->track_count; 1529538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1530538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1531538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1532538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1533538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_track_seek(nestegg * ctx, unsigned int track, uint64_t tstamp) 1534538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1535538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 1536538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct cue_point * cue_point; 1537538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct cue_track_positions * pos; 1538538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct saved_state state; 1539538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct seek * found; 1540538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t seek_pos, tc_scale, t, id; 1541538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_list_node * node = ctx->segment.cues.cue_point.head; 1542538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1543538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber /* If there are no cues loaded, check for cues element in the seek head 1544538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber and load it. */ 1545538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!node) { 1546538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber found = ne_find_seek_for_id(ctx->segment.seek_head.head, ID_CUES); 1547538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!found) 1548538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1549538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1550538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_uint(found->position, &seek_pos) != 0) 1551538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1552538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1553538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber /* Save old parser state. */ 1554538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_ctx_save(ctx, &state); 1555538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 0) 1556538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1557538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1558538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber /* Seek and set up parser state for segment-level element (Cues). */ 1559538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_io_seek(ctx->io, ctx->segment_offset + seek_pos, NESTEGG_SEEK_SET); 1560538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 0) 1561538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1562538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->last_id = 0; 1563538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->last_size = 0; 1564538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1565538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_element(ctx, &id, NULL); 1566538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1567538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1568538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1569538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (id != ID_CUES) 1570538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1571538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1572538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->ancestor = NULL; 1573538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_ctx_push(ctx, ne_top_level_elements, ctx); 1574538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_ctx_push(ctx, ne_segment_elements, &ctx->segment); 1575538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_ctx_push(ctx, ne_cues_elements, &ctx->segment.cues); 1576538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber /* parser will run until end of cues element. */ 1577538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "seek: parsing cue elements"); 1578538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_parse(ctx, ne_cues_elements); 1579538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (ctx->ancestor) 1580538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_ctx_pop(ctx); 1581538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1582538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber /* Reset parser state to original state and seek back to old position. */ 1583538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_ctx_restore(ctx, &state) != 0) 1584538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1585538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1586538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r < 0) 1587538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1588538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1589538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1590538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber tc_scale = ne_get_timecode_scale(ctx); 1591538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1592538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber cue_point = ne_find_cue_point_for_tstamp(ctx->segment.cues.cue_point.head, tc_scale, tstamp); 1593538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!cue_point) 1594538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1595538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1596538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber node = cue_point->cue_track_positions.head; 1597538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1598538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber seek_pos = 0; 1599538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1600538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (node) { 1601538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber assert(node->id == ID_CUE_TRACK_POSITIONS); 1602538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber pos = node->data; 1603538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_uint(pos->track, &t) == 0 && t - 1 == track) { 1604538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_uint(pos->cluster_position, &seek_pos) != 0) 1605538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1606538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber break; 1607538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1608538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber node = node->next; 1609538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1610538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1611538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber /* Seek and set up parser state for segment-level element (Cluster). */ 1612538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_io_seek(ctx->io, ctx->segment_offset + seek_pos, NESTEGG_SEEK_SET); 1613538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 0) 1614538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1615538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->last_id = 0; 1616538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->last_size = 0; 1617538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1618538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (ctx->ancestor) 1619538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_ctx_pop(ctx); 1620538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1621538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_ctx_push(ctx, ne_top_level_elements, ctx); 1622538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_ctx_push(ctx, ne_segment_elements, &ctx->segment); 1623538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ctx->log(ctx, NESTEGG_LOG_DEBUG, "seek: parsing cluster elements"); 1624538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_parse(ctx, NULL); 1625538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1626538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1627538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1628538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!ne_is_suspend_element(ctx->last_id)) 1629538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1630538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1631538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1632538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1633538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1634538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1635538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_track_type(nestegg * ctx, unsigned int track) 1636538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1637538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct track_entry * entry; 1638538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t type; 1639538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1640538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber entry = ne_find_track_entry(ctx, track); 1641538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!entry) 1642538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1643538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1644538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_uint(entry->type, &type) != 0) 1645538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1646538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1647538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (type & TRACK_TYPE_VIDEO) 1648538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return NESTEGG_TRACK_VIDEO; 1649538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1650538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (type & TRACK_TYPE_AUDIO) 1651538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return NESTEGG_TRACK_AUDIO; 1652538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1653538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1654538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1655538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1656538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1657538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_track_codec_id(nestegg * ctx, unsigned int track) 1658538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1659538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber char * codec_id; 1660538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct track_entry * entry; 1661538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1662538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber entry = ne_find_track_entry(ctx, track); 1663538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!entry) 1664538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1665538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1666538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_string(entry->codec_id, &codec_id) != 0) 1667538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1668538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1669538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (strcmp(codec_id, TRACK_ID_VP8) == 0) 1670538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return NESTEGG_CODEC_VP8; 1671538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1672538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (strcmp(codec_id, TRACK_ID_VORBIS) == 0) 1673538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return NESTEGG_CODEC_VORBIS; 1674538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1675538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1676538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1677538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1678538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1679538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_track_codec_data_count(nestegg * ctx, unsigned int track, 1680538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned int * count) 1681538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1682538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct track_entry * entry; 1683538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_binary codec_private; 1684538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char * p; 1685538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1686538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *count = 0; 1687538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1688538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber entry = ne_find_track_entry(ctx, track); 1689538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!entry) 1690538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1691538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1692538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_VORBIS) 1693538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1694538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1695538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_binary(entry->codec_private, &codec_private) != 0) 1696538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1697538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1698538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (codec_private.length < 1) 1699538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1700538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1701538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber p = codec_private.data; 1702538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *count = *p + 1; 1703538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1704538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (*count > 3) 1705538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1706538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1707538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1708538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1709538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1710538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1711538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_track_codec_data(nestegg * ctx, unsigned int track, unsigned int item, 1712538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char ** data, size_t * length) 1713538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1714538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct track_entry * entry; 1715538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct ebml_binary codec_private; 1716538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t sizes[3], total; 1717538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char * p; 1718538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned int count, i; 1719538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1720538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *data = NULL; 1721538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *length = 0; 1722538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1723538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber entry = ne_find_track_entry(ctx, track); 1724538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!entry) 1725538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1726538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1727538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (nestegg_track_codec_id(ctx, track) != NESTEGG_CODEC_VORBIS) 1728538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1729538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1730538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_binary(entry->codec_private, &codec_private) != 0) 1731538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1732538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1733538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber p = codec_private.data; 1734538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber count = *p++ + 1; 1735538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1736538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (count > 3) 1737538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1738538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1739538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber i = 0; 1740538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber total = 0; 1741538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (--count) { 1742538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber sizes[i] = ne_xiph_lace_value(&p); 1743538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber total += sizes[i]; 1744538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber i += 1; 1745538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1746538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber sizes[i] = codec_private.length - total - (p - codec_private.data); 1747538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1748538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber for (i = 0; i < item; ++i) { 1749538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (sizes[i] > LIMIT_FRAME) 1750538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1751538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber p += sizes[i]; 1752538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1753538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *data = p; 1754538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *length = sizes[item]; 1755538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1756538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1757538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1758538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1759538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1760538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_track_video_params(nestegg * ctx, unsigned int track, 1761538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_video_params * params) 1762538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1763538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct track_entry * entry; 1764538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t value; 1765538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1766538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber memset(params, 0, sizeof(*params)); 1767538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1768538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber entry = ne_find_track_entry(ctx, track); 1769538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!entry) 1770538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1771538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1772538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (nestegg_track_type(ctx, track) != NESTEGG_TRACK_VIDEO) 1773538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1774538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1775538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_uint(entry->video.pixel_width, &value) != 0) 1776538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1777538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber params->width = value; 1778538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1779538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_get_uint(entry->video.pixel_height, &value) != 0) 1780538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1781538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber params->height = value; 1782538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1783538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value = 0; 1784538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_get_uint(entry->video.pixel_crop_bottom, &value); 1785538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber params->crop_bottom = value; 1786538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1787538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value = 0; 1788538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_get_uint(entry->video.pixel_crop_top, &value); 1789538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber params->crop_top = value; 1790538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1791538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value = 0; 1792538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_get_uint(entry->video.pixel_crop_left, &value); 1793538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber params->crop_left = value; 1794538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1795538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value = 0; 1796538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_get_uint(entry->video.pixel_crop_right, &value); 1797538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber params->crop_right = value; 1798538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1799538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value = params->width; 1800538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_get_uint(entry->video.display_width, &value); 1801538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber params->display_width = value; 1802538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1803538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value = params->height; 1804538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_get_uint(entry->video.display_height, &value); 1805538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber params->display_height = value; 1806538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1807538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1808538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1809538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1810538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1811538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_track_audio_params(nestegg * ctx, unsigned int track, 1812538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber nestegg_audio_params * params) 1813538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1814538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct track_entry * entry; 1815538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t value; 1816538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1817538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber memset(params, 0, sizeof(*params)); 1818538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1819538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber entry = ne_find_track_entry(ctx, track); 1820538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (!entry) 1821538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1822538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1823538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (nestegg_track_type(ctx, track) != NESTEGG_TRACK_AUDIO) 1824538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1825538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1826538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber params->rate = 8000; 1827538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_get_float(entry->audio.sampling_frequency, ¶ms->rate); 1828538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1829538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value = 1; 1830538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_get_uint(entry->audio.channels, &value); 1831538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber params->channels = value; 1832538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1833538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber value = 16; 1834538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber ne_get_uint(entry->audio.bit_depth, &value); 1835538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber params->depth = value; 1836538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1837538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1838538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1839538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1840538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1841538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_read_packet(nestegg * ctx, nestegg_packet ** pkt) 1842538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1843538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber int r; 1844538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber uint64_t id, size; 1845538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1846538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *pkt = NULL; 1847538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1848538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber for (;;) { 1849538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_peek_element(ctx, &id, &size); 1850538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1851538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1852538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1853538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber /* any suspend fields must be handled here */ 1854538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (ne_is_suspend_element(id)) { 1855538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_element(ctx, &id, &size); 1856538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1857538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1858538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1859538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber /* the only suspend fields are blocks and simple blocks, which we 1860538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber handle directly. */ 1861538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_read_block(ctx, id, size, pkt); 1862538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1863538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1864538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1865538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber r = ne_parse(ctx, NULL); 1866538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (r != 1) 1867538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return r; 1868538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1869538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1870538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 1; 1871538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1872538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1873538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubervoid 1874538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_free_packet(nestegg_packet * pkt) 1875538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1876538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct frame * frame; 1877538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1878538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (pkt->frame) { 1879538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber frame = pkt->frame; 1880538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber pkt->frame = frame->next; 1881538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber free(frame->data); 1882538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber free(frame); 1883538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1884538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1885538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber free(pkt); 1886538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1887538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1888538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1889538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_packet_track(nestegg_packet * pkt, unsigned int * track) 1890538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1891538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *track = pkt->track; 1892538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1893538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1894538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1895538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1896538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_packet_tstamp(nestegg_packet * pkt, uint64_t * tstamp) 1897538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1898538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *tstamp = pkt->timecode; 1899538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1900538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1901538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1902538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1903538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_packet_count(nestegg_packet * pkt, unsigned int * count) 1904538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1905538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct frame * f = pkt->frame; 1906538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1907538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *count = 0; 1908538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1909538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (f) { 1910538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *count += 1; 1911538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber f = f->next; 1912538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1913538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1914538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1915538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1916538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1917538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberint 1918538f6170b788de7408b06efc6613dc98579aa6a6Andreas Hubernestegg_packet_data(nestegg_packet * pkt, unsigned int item, 1919538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned char ** data, size_t * length) 1920538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{ 1921538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber struct frame * f = pkt->frame; 1922538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber unsigned int count = 0; 1923538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1924538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *data = NULL; 1925538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *length = 0; 1926538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1927538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber while (f) { 1928538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber if (count == item) { 1929538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *data = f->data; 1930538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber *length = f->length; 1931538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return 0; 1932538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1933538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber count += 1; 1934538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber f = f->next; 1935538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 1936538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 1937538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber return -1; 1938538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} 1939