2 * Copyright © 2010 Mozilla Foundation
4 * This program is made available under an ISC-style license. See the
5 * accompanying file LICENSE for details.
11 #include "nestegg/halloc/halloc.h"
12 #include "nestegg/include/nestegg/nestegg.h"
15 #define ID_EBML 0x1a45dfa3
16 #define ID_EBML_VERSION 0x4286
17 #define ID_EBML_READ_VERSION 0x42f7
18 #define ID_EBML_MAX_ID_LENGTH 0x42f2
19 #define ID_EBML_MAX_SIZE_LENGTH 0x42f3
20 #define ID_DOCTYPE 0x4282
21 #define ID_DOCTYPE_VERSION 0x4287
22 #define ID_DOCTYPE_READ_VERSION 0x4285
28 /* WebMedia Elements */
29 #define ID_SEGMENT 0x18538067
31 /* Seek Head Elements */
32 #define ID_SEEK_HEAD 0x114d9b74
33 #define ID_SEEK 0x4dbb
34 #define ID_SEEK_ID 0x53ab
35 #define ID_SEEK_POSITION 0x53ac
38 #define ID_INFO 0x1549a966
39 #define ID_TIMECODE_SCALE 0x2ad7b1
40 #define ID_DURATION 0x4489
42 /* Cluster Elements */
43 #define ID_CLUSTER 0x1f43b675
44 #define ID_TIMECODE 0xe7
45 #define ID_BLOCK_GROUP 0xa0
46 #define ID_SIMPLE_BLOCK 0xa3
48 /* BlockGroup Elements */
50 #define ID_BLOCK_DURATION 0x9b
51 #define ID_REFERENCE_BLOCK 0xfb
54 #define ID_TRACKS 0x1654ae6b
55 #define ID_TRACK_ENTRY 0xae
56 #define ID_TRACK_NUMBER 0xd7
57 #define ID_TRACK_UID 0x73c5
58 #define ID_TRACK_TYPE 0x83
59 #define ID_FLAG_ENABLED 0xb9
60 #define ID_FLAG_DEFAULT 0x88
61 #define ID_FLAG_LACING 0x9c
62 #define ID_TRACK_TIMECODE_SCALE 0x23314f
63 #define ID_LANGUAGE 0x22b59c
64 #define ID_CODEC_ID 0x86
65 #define ID_CODEC_PRIVATE 0x63a2
69 #define ID_PIXEL_WIDTH 0xb0
70 #define ID_PIXEL_HEIGHT 0xba
71 #define ID_PIXEL_CROP_BOTTOM 0x54aa
72 #define ID_PIXEL_CROP_TOP 0x54bb
73 #define ID_PIXEL_CROP_LEFT 0x54cc
74 #define ID_PIXEL_CROP_RIGHT 0x54dd
75 #define ID_DISPLAY_WIDTH 0x54b0
76 #define ID_DISPLAY_HEIGHT 0x54ba
80 #define ID_SAMPLING_FREQUENCY 0xb5
81 #define ID_CHANNELS 0x9f
82 #define ID_BIT_DEPTH 0x6264
85 #define ID_CUES 0x1c53bb6b
86 #define ID_CUE_POINT 0xbb
87 #define ID_CUE_TIME 0xb3
88 #define ID_CUE_TRACK_POSITIONS 0xb7
89 #define ID_CUE_TRACK 0xf7
90 #define ID_CUE_CLUSTER_POSITION 0xf1
91 #define ID_CUE_BLOCK_NUMBER 0x5378
104 #define LIMIT_STRING (1 << 20)
105 #define LIMIT_BINARY (1 << 24)
106 #define LIMIT_BLOCK (1 << 30)
107 #define LIMIT_FRAME (1 << 28)
110 #define DESC_FLAG_NONE 0
111 #define DESC_FLAG_MULTI (1 << 0)
112 #define DESC_FLAG_SUSPEND (1 << 1)
113 #define DESC_FLAG_OFFSET (1 << 2)
115 /* Block Header Flags */
116 #define BLOCK_FLAGS_LACING 6
118 /* Lacing Constants */
119 #define LACING_NONE 0
120 #define LACING_XIPH 1
121 #define LACING_FIXED 2
122 #define LACING_EBML 3
125 #define TRACK_TYPE_VIDEO 1
126 #define TRACK_TYPE_AUDIO 2
129 #define TRACK_ID_VP8 "V_VP8"
130 #define TRACK_ID_VORBIS "A_VORBIS"
138 unsigned char * data
;
142 struct ebml_list_node
{
143 struct ebml_list_node
* next
;
149 struct ebml_list_node
* head
;
150 struct ebml_list_node
* tail
;
159 struct ebml_binary b
;
161 enum ebml_type_enum type
;
165 /* EBML Definitions */
167 struct ebml_type ebml_version
;
168 struct ebml_type ebml_read_version
;
169 struct ebml_type ebml_max_id_length
;
170 struct ebml_type ebml_max_size_length
;
171 struct ebml_type doctype
;
172 struct ebml_type doctype_version
;
173 struct ebml_type doctype_read_version
;
176 /* Matroksa Definitions */
179 struct ebml_type position
;
183 struct ebml_list seek
;
187 struct ebml_type timecode_scale
;
188 struct ebml_type duration
;
192 struct ebml_type duration
;
193 struct ebml_type reference_block
;
197 struct ebml_type timecode
;
198 struct ebml_list block_group
;
202 struct ebml_type pixel_width
;
203 struct ebml_type pixel_height
;
204 struct ebml_type pixel_crop_bottom
;
205 struct ebml_type pixel_crop_top
;
206 struct ebml_type pixel_crop_left
;
207 struct ebml_type pixel_crop_right
;
208 struct ebml_type display_width
;
209 struct ebml_type display_height
;
213 struct ebml_type sampling_frequency
;
214 struct ebml_type channels
;
215 struct ebml_type bit_depth
;
219 struct ebml_type number
;
220 struct ebml_type uid
;
221 struct ebml_type type
;
222 struct ebml_type flag_enabled
;
223 struct ebml_type flag_default
;
224 struct ebml_type flag_lacing
;
225 struct ebml_type track_timecode_scale
;
226 struct ebml_type language
;
227 struct ebml_type codec_id
;
228 struct ebml_type codec_private
;
234 struct ebml_list track_entry
;
237 struct cue_track_positions
{
238 struct ebml_type track
;
239 struct ebml_type cluster_position
;
240 struct ebml_type block_number
;
244 struct ebml_type time
;
245 struct ebml_list cue_track_positions
;
249 struct ebml_list cue_point
;
253 struct ebml_list seek_head
;
255 struct ebml_list cluster
;
256 struct tracks tracks
;
266 struct list_node
* previous
;
267 struct ebml_element_desc
* node
;
268 unsigned char * data
;
272 int64_t stream_offset
;
273 struct list_node
* ancestor
;
279 unsigned char * data
;
284 /* Public (opaque) Structures */
288 struct pool_ctx
* alloc_pool
;
291 struct list_node
* ancestor
;
293 struct segment segment
;
294 int64_t segment_offset
;
295 unsigned int track_count
;
298 struct nestegg_packet
{
301 struct frame
* frame
;
304 /* Element Descriptor */
305 struct ebml_element_desc
{
308 enum ebml_type_enum type
;
311 struct ebml_element_desc
* children
;
316 #define E_FIELD(ID, TYPE, STRUCT, FIELD) \
317 { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_NONE, NULL, 0, 0 }
318 #define E_MASTER(ID, TYPE, STRUCT, FIELD) \
319 { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_MULTI, ne_ ## FIELD ## _elements, \
320 sizeof(struct FIELD), 0 }
321 #define E_SINGLE_MASTER_O(ID, TYPE, STRUCT, FIELD) \
322 { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_OFFSET, ne_ ## FIELD ## _elements, 0, \
323 offsetof(STRUCT, FIELD ## _offset) }
324 #define E_SINGLE_MASTER(ID, TYPE, STRUCT, FIELD) \
325 { #ID, ID, TYPE, offsetof(STRUCT, FIELD), DESC_FLAG_NONE, ne_ ## FIELD ## _elements, 0, 0 }
326 #define E_SUSPEND(ID, TYPE) \
327 { #ID, ID, TYPE, 0, DESC_FLAG_SUSPEND, NULL, 0, 0 }
329 { NULL, 0, 0, 0, DESC_FLAG_NONE, NULL, 0, 0 }
331 /* EBML Element Lists */
332 static struct ebml_element_desc ne_ebml_elements
[] = {
333 E_FIELD(ID_EBML_VERSION
, TYPE_UINT
, struct ebml
, ebml_version
),
334 E_FIELD(ID_EBML_READ_VERSION
, TYPE_UINT
, struct ebml
, ebml_read_version
),
335 E_FIELD(ID_EBML_MAX_ID_LENGTH
, TYPE_UINT
, struct ebml
, ebml_max_id_length
),
336 E_FIELD(ID_EBML_MAX_SIZE_LENGTH
, TYPE_UINT
, struct ebml
, ebml_max_size_length
),
337 E_FIELD(ID_DOCTYPE
, TYPE_STRING
, struct ebml
, doctype
),
338 E_FIELD(ID_DOCTYPE_VERSION
, TYPE_UINT
, struct ebml
, doctype_version
),
339 E_FIELD(ID_DOCTYPE_READ_VERSION
, TYPE_UINT
, struct ebml
, doctype_read_version
),
343 /* WebMedia Element Lists */
344 static struct ebml_element_desc ne_seek_elements
[] = {
345 E_FIELD(ID_SEEK_ID
, TYPE_BINARY
, struct seek
, id
),
346 E_FIELD(ID_SEEK_POSITION
, TYPE_UINT
, struct seek
, position
),
350 static struct ebml_element_desc ne_seek_head_elements
[] = {
351 E_MASTER(ID_SEEK
, TYPE_MASTER
, struct seek_head
, seek
),
355 static struct ebml_element_desc ne_info_elements
[] = {
356 E_FIELD(ID_TIMECODE_SCALE
, TYPE_UINT
, struct info
, timecode_scale
),
357 E_FIELD(ID_DURATION
, TYPE_FLOAT
, struct info
, duration
),
361 static struct ebml_element_desc ne_block_group_elements
[] = {
362 E_SUSPEND(ID_BLOCK
, TYPE_BINARY
),
363 E_FIELD(ID_BLOCK_DURATION
, TYPE_UINT
, struct block_group
, duration
),
364 E_FIELD(ID_REFERENCE_BLOCK
, TYPE_INT
, struct block_group
, reference_block
),
368 static struct ebml_element_desc ne_cluster_elements
[] = {
369 E_FIELD(ID_TIMECODE
, TYPE_UINT
, struct cluster
, timecode
),
370 E_MASTER(ID_BLOCK_GROUP
, TYPE_MASTER
, struct cluster
, block_group
),
371 E_SUSPEND(ID_SIMPLE_BLOCK
, TYPE_BINARY
),
375 static struct ebml_element_desc ne_video_elements
[] = {
376 E_FIELD(ID_PIXEL_WIDTH
, TYPE_UINT
, struct video
, pixel_width
),
377 E_FIELD(ID_PIXEL_HEIGHT
, TYPE_UINT
, struct video
, pixel_height
),
378 E_FIELD(ID_PIXEL_CROP_BOTTOM
, TYPE_UINT
, struct video
, pixel_crop_bottom
),
379 E_FIELD(ID_PIXEL_CROP_TOP
, TYPE_UINT
, struct video
, pixel_crop_top
),
380 E_FIELD(ID_PIXEL_CROP_LEFT
, TYPE_UINT
, struct video
, pixel_crop_left
),
381 E_FIELD(ID_PIXEL_CROP_RIGHT
, TYPE_UINT
, struct video
, pixel_crop_right
),
382 E_FIELD(ID_DISPLAY_WIDTH
, TYPE_UINT
, struct video
, display_width
),
383 E_FIELD(ID_DISPLAY_HEIGHT
, TYPE_UINT
, struct video
, display_height
),
387 static struct ebml_element_desc ne_audio_elements
[] = {
388 E_FIELD(ID_SAMPLING_FREQUENCY
, TYPE_FLOAT
, struct audio
, sampling_frequency
),
389 E_FIELD(ID_CHANNELS
, TYPE_UINT
, struct audio
, channels
),
390 E_FIELD(ID_BIT_DEPTH
, TYPE_UINT
, struct audio
, bit_depth
),
394 static struct ebml_element_desc ne_track_entry_elements
[] = {
395 E_FIELD(ID_TRACK_NUMBER
, TYPE_UINT
, struct track_entry
, number
),
396 E_FIELD(ID_TRACK_UID
, TYPE_UINT
, struct track_entry
, uid
),
397 E_FIELD(ID_TRACK_TYPE
, TYPE_UINT
, struct track_entry
, type
),
398 E_FIELD(ID_FLAG_ENABLED
, TYPE_UINT
, struct track_entry
, flag_enabled
),
399 E_FIELD(ID_FLAG_DEFAULT
, TYPE_UINT
, struct track_entry
, flag_default
),
400 E_FIELD(ID_FLAG_LACING
, TYPE_UINT
, struct track_entry
, flag_lacing
),
401 E_FIELD(ID_TRACK_TIMECODE_SCALE
, TYPE_FLOAT
, struct track_entry
, track_timecode_scale
),
402 E_FIELD(ID_LANGUAGE
, TYPE_STRING
, struct track_entry
, language
),
403 E_FIELD(ID_CODEC_ID
, TYPE_STRING
, struct track_entry
, codec_id
),
404 E_FIELD(ID_CODEC_PRIVATE
, TYPE_BINARY
, struct track_entry
, codec_private
),
405 E_SINGLE_MASTER(ID_VIDEO
, TYPE_MASTER
, struct track_entry
, video
),
406 E_SINGLE_MASTER(ID_AUDIO
, TYPE_MASTER
, struct track_entry
, audio
),
410 static struct ebml_element_desc ne_tracks_elements
[] = {
411 E_MASTER(ID_TRACK_ENTRY
, TYPE_MASTER
, struct tracks
, track_entry
),
415 static struct ebml_element_desc ne_cue_track_positions_elements
[] = {
416 E_FIELD(ID_CUE_TRACK
, TYPE_UINT
, struct cue_track_positions
, track
),
417 E_FIELD(ID_CUE_CLUSTER_POSITION
, TYPE_UINT
, struct cue_track_positions
, cluster_position
),
418 E_FIELD(ID_CUE_BLOCK_NUMBER
, TYPE_UINT
, struct cue_track_positions
, block_number
),
422 static struct ebml_element_desc ne_cue_point_elements
[] = {
423 E_FIELD(ID_CUE_TIME
, TYPE_UINT
, struct cue_point
, time
),
424 E_MASTER(ID_CUE_TRACK_POSITIONS
, TYPE_MASTER
, struct cue_point
, cue_track_positions
),
428 static struct ebml_element_desc ne_cues_elements
[] = {
429 E_MASTER(ID_CUE_POINT
, TYPE_MASTER
, struct cues
, cue_point
),
433 static struct ebml_element_desc ne_segment_elements
[] = {
434 E_MASTER(ID_SEEK_HEAD
, TYPE_MASTER
, struct segment
, seek_head
),
435 E_SINGLE_MASTER(ID_INFO
, TYPE_MASTER
, struct segment
, info
),
436 E_MASTER(ID_CLUSTER
, TYPE_MASTER
, struct segment
, cluster
),
437 E_SINGLE_MASTER(ID_TRACKS
, TYPE_MASTER
, struct segment
, tracks
),
438 E_SINGLE_MASTER(ID_CUES
, TYPE_MASTER
, struct segment
, cues
),
442 static struct ebml_element_desc ne_top_level_elements
[] = {
443 E_SINGLE_MASTER(ID_EBML
, TYPE_MASTER
, nestegg
, ebml
),
444 E_SINGLE_MASTER_O(ID_SEGMENT
, TYPE_MASTER
, nestegg
, segment
),
450 #undef E_SINGLE_MASTER_O
451 #undef E_SINGLE_MASTER
455 static struct pool_ctx
*
458 struct pool_ctx
* pool
;
460 pool
= h_malloc(sizeof(*pool
));
467 ne_pool_destroy(struct pool_ctx
* pool
)
473 ne_pool_alloc(size_t size
, struct pool_ctx
* pool
)
486 ne_alloc(size_t size
)
497 ne_io_read(nestegg_io
* io
, void * buffer
, size_t length
)
499 return io
->read(buffer
, length
, io
->userdata
);
503 ne_io_seek(nestegg_io
* io
, int64_t offset
, int whence
)
505 return io
->seek(offset
, whence
, io
->userdata
);
509 ne_io_read_skip(nestegg_io
* io
, size_t length
)
512 unsigned char buf
[8192];
516 get
= length
< sizeof(buf
) ? length
: sizeof(buf
);
517 r
= ne_io_read(io
, buf
, get
);
527 ne_io_tell(nestegg_io
* io
)
529 return io
->tell(io
->userdata
);
533 ne_bare_read_vint(nestegg_io
* io
, uint64_t * value
, uint64_t * length
, enum vint_mask maskflag
)
538 unsigned int count
= 1, mask
= 1 << 7;
540 r
= ne_io_read(io
, &b
, 1);
544 while (count
< maxlen
) {
555 if (maskflag
== MASK_FIRST_BIT
)
559 r
= ne_io_read(io
, &b
, 1);
570 ne_read_id(nestegg_io
* io
, uint64_t * value
, uint64_t * length
)
572 return ne_bare_read_vint(io
, value
, length
, MASK_NONE
);
576 ne_read_vint(nestegg_io
* io
, uint64_t * value
, uint64_t * length
)
578 return ne_bare_read_vint(io
, value
, length
, MASK_FIRST_BIT
);
582 ne_read_svint(nestegg_io
* io
, int64_t * value
, uint64_t * length
)
587 int64_t svint_subtr
[] = {
590 0x3ffffffffLL
, 0x1ffffffffffLL
,
591 0xffffffffffffLL
, 0x7fffffffffffffLL
594 r
= ne_bare_read_vint(io
, &uvalue
, &ulength
, MASK_FIRST_BIT
);
597 *value
= uvalue
- svint_subtr
[ulength
- 1];
604 ne_read_uint(nestegg_io
* io
, uint64_t * val
, uint64_t length
)
609 if (length
== 0 || length
> 8)
611 r
= ne_io_read(io
, &b
, 1);
616 r
= ne_io_read(io
, &b
, 1);
626 ne_read_int(nestegg_io
* io
, int64_t * val
, uint64_t length
)
631 r
= ne_read_uint(io
, &uval
, length
);
635 if (length
< sizeof(int64_t)) {
637 base
<<= length
* 8 - 1;
646 *val
= (int64_t) uval
;
653 ne_read_float(nestegg_io
* io
, double * val
, uint64_t length
)
662 /* length == 10 not implemented */
663 if (length
!= 4 && length
!= 8)
665 r
= ne_read_uint(io
, &value
.u
, length
);
676 ne_read_string(nestegg
* ctx
, char ** val
, uint64_t length
)
681 if (length
== 0 || length
> LIMIT_STRING
)
683 str
= ne_pool_alloc(length
+ 1, ctx
->alloc_pool
);
684 r
= ne_io_read(ctx
->io
, (unsigned char *) str
, length
);
693 ne_read_binary(nestegg
* ctx
, struct ebml_binary
* val
, uint64_t length
)
695 if (length
== 0 || length
> LIMIT_BINARY
)
697 val
->data
= ne_pool_alloc(length
, ctx
->alloc_pool
);
698 val
->length
= length
;
699 return ne_io_read(ctx
->io
, val
->data
, length
);
703 ne_get_uint(struct ebml_type type
, uint64_t * value
)
708 assert(type
.type
== TYPE_UINT
);
716 ne_get_float(struct ebml_type type
, double * value
)
721 assert(type
.type
== TYPE_FLOAT
);
729 ne_get_string(struct ebml_type type
, char ** value
)
734 assert(type
.type
== TYPE_STRING
);
742 ne_get_binary(struct ebml_type type
, struct ebml_binary
* value
)
747 assert(type
.type
== TYPE_BINARY
);
755 ne_is_ancestor_element(uint64_t id
, struct list_node
* ancestor
)
757 struct ebml_element_desc
* element
;
759 for (; ancestor
; ancestor
= ancestor
->previous
)
760 for (element
= ancestor
->node
; element
->id
; ++element
)
761 if (element
->id
== id
)
767 static struct ebml_element_desc
*
768 ne_find_element(uint64_t id
, struct ebml_element_desc
* elements
)
770 struct ebml_element_desc
* element
;
772 for (element
= elements
; element
->id
; ++element
)
773 if (element
->id
== id
)
780 ne_ctx_push(nestegg
* ctx
, struct ebml_element_desc
* ancestor
, void * data
)
782 struct list_node
* item
;
784 item
= ne_alloc(sizeof(*item
));
785 item
->previous
= ctx
->ancestor
;
786 item
->node
= ancestor
;
788 ctx
->ancestor
= item
;
792 ne_ctx_pop(nestegg
* ctx
)
794 struct list_node
* item
;
796 item
= ctx
->ancestor
;
797 ctx
->ancestor
= item
->previous
;
802 ne_ctx_save(nestegg
* ctx
, struct saved_state
* s
)
804 s
->stream_offset
= ne_io_tell(ctx
->io
);
805 if (s
->stream_offset
< 0)
807 s
->ancestor
= ctx
->ancestor
;
808 s
->last_id
= ctx
->last_id
;
809 s
->last_size
= ctx
->last_size
;
814 ne_ctx_restore(nestegg
* ctx
, struct saved_state
* s
)
818 r
= ne_io_seek(ctx
->io
, s
->stream_offset
, NESTEGG_SEEK_SET
);
821 ctx
->ancestor
= s
->ancestor
;
822 ctx
->last_id
= s
->last_id
;
823 ctx
->last_size
= s
->last_size
;
828 ne_peek_element(nestegg
* ctx
, uint64_t * id
, uint64_t * size
)
832 if (ctx
->last_id
&& ctx
->last_size
) {
836 *size
= ctx
->last_size
;
840 r
= ne_read_id(ctx
->io
, &ctx
->last_id
, NULL
);
844 r
= ne_read_vint(ctx
->io
, &ctx
->last_size
, NULL
);
851 *size
= ctx
->last_size
;
857 ne_read_element(nestegg
* ctx
, uint64_t * id
, uint64_t * size
)
861 r
= ne_peek_element(ctx
, id
, size
);
872 ne_read_master(nestegg
* ctx
, struct ebml_element_desc
* desc
)
874 struct ebml_list
* list
;
875 struct ebml_list_node
* node
, * oldtail
;
877 assert(desc
->type
== TYPE_MASTER
&& desc
->flags
& DESC_FLAG_MULTI
);
879 ctx
->log(ctx
, NESTEGG_LOG_DEBUG
, "multi master element %llx (%s)",
880 desc
->id
, desc
->name
);
882 list
= (struct ebml_list
*) (ctx
->ancestor
->data
+ desc
->offset
);
884 node
= ne_pool_alloc(sizeof(*node
), ctx
->alloc_pool
);
886 node
->data
= ne_pool_alloc(desc
->size
, ctx
->alloc_pool
);
888 oldtail
= list
->tail
;
890 oldtail
->next
= node
;
895 ctx
->log(ctx
, NESTEGG_LOG_DEBUG
, " -> using data %p", node
->data
);
897 ne_ctx_push(ctx
, desc
->children
, node
->data
);
901 ne_read_single_master(nestegg
* ctx
, struct ebml_element_desc
* desc
)
903 assert(desc
->type
== TYPE_MASTER
&& !(desc
->flags
& DESC_FLAG_MULTI
));
905 ctx
->log(ctx
, NESTEGG_LOG_DEBUG
, "single master element %llx (%s)",
906 desc
->id
, desc
->name
);
907 ctx
->log(ctx
, NESTEGG_LOG_DEBUG
, " -> using data %p (%u)",
908 ctx
->ancestor
->data
+ desc
->offset
, desc
->offset
);
910 ne_ctx_push(ctx
, desc
->children
, ctx
->ancestor
->data
+ desc
->offset
);
914 ne_read_simple(nestegg
* ctx
, struct ebml_element_desc
* desc
, size_t length
)
916 struct ebml_type
* storage
;
919 storage
= (struct ebml_type
*) (ctx
->ancestor
->data
+ desc
->offset
);
922 ctx
->log(ctx
, NESTEGG_LOG_DEBUG
, "element %llx (%s) already read, skipping",
923 desc
->id
, desc
->name
);
927 storage
->type
= desc
->type
;
929 ctx
->log(ctx
, NESTEGG_LOG_DEBUG
, "element %llx (%s) -> %p (%u)",
930 desc
->id
, desc
->name
, storage
, desc
->offset
);
934 switch (desc
->type
) {
936 r
= ne_read_uint(ctx
->io
, &storage
->v
.u
, length
);
939 r
= ne_read_float(ctx
->io
, &storage
->v
.f
, length
);
942 r
= ne_read_int(ctx
->io
, &storage
->v
.i
, length
);
945 r
= ne_read_string(ctx
, &storage
->v
.s
, length
);
948 r
= ne_read_binary(ctx
, &storage
->v
.b
, length
);
963 ne_parse(nestegg
* ctx
, struct ebml_element_desc
* top_level
)
966 int64_t * data_offset
;
968 struct ebml_element_desc
* element
;
970 /* loop until we need to return:
975 /* loop over elements at current level reading them if sublevel found,
976 push ctx onto stack and continue if sublevel ended, pop ctx off stack
983 r
= ne_peek_element(ctx
, &id
, &size
);
987 element
= ne_find_element(id
, ctx
->ancestor
->node
);
989 if (element
->flags
& DESC_FLAG_SUSPEND
) {
990 assert(element
->type
== TYPE_BINARY
);
991 ctx
->log(ctx
, NESTEGG_LOG_DEBUG
, "suspend parse at %llx", id
);
996 r
= ne_read_element(ctx
, &id
, &size
);
1000 if (element
->flags
& DESC_FLAG_OFFSET
) {
1001 data_offset
= (int64_t *) (ctx
->ancestor
->data
+ element
->data_offset
);
1002 *data_offset
= ne_io_tell(ctx
->io
);
1003 if (*data_offset
< 0) {
1009 if (element
->type
== TYPE_MASTER
) {
1010 if (element
->flags
& DESC_FLAG_MULTI
)
1011 ne_read_master(ctx
, element
);
1013 ne_read_single_master(ctx
, element
);
1016 r
= ne_read_simple(ctx
, element
, size
);
1020 } else if (ne_is_ancestor_element(id
, ctx
->ancestor
->previous
)) {
1021 ctx
->log(ctx
, NESTEGG_LOG_DEBUG
, "parent element %llx", id
);
1022 if (top_level
&& ctx
->ancestor
->node
== top_level
) {
1023 ctx
->log(ctx
, NESTEGG_LOG_DEBUG
, "*** parse about to back up past top_level");
1029 r
= ne_read_element(ctx
, &id
, &size
);
1033 if (id
!= ID_VOID
&& id
!= ID_CRC32
)
1034 ctx
->log(ctx
, NESTEGG_LOG_DEBUG
, "unknown element %llx", id
);
1035 r
= ne_io_read_skip(ctx
->io
, size
);
1042 while (ctx
->ancestor
)
1049 ne_xiph_lace_value(unsigned char ** np
)
1053 unsigned char * p
= *np
;
1057 while (lace
== 255) {
1068 ne_read_xiph_lace_value(nestegg_io
* io
, uint64_t * value
, size_t * consumed
)
1073 r
= ne_read_uint(io
, &lace
, 1);
1079 while (lace
== 255) {
1080 r
= ne_read_uint(io
, &lace
, 1);
1091 ne_read_xiph_lacing(nestegg_io
* io
, size_t block
, size_t * read
, uint64_t n
, uint64_t * sizes
)
1098 r
= ne_read_xiph_lace_value(io
, &sizes
[i
], read
);
1105 if (*read
+ sum
> block
)
1108 /* last frame is the remainder of the block */
1109 sizes
[i
] = block
- *read
- sum
;
1114 ne_read_ebml_lacing(nestegg_io
* io
, size_t block
, size_t * read
, uint64_t n
, uint64_t * sizes
)
1117 uint64_t lace
, sum
, length
;
1121 r
= ne_read_vint(io
, &lace
, &length
);
1133 r
= ne_read_svint(io
, &slace
, &length
);
1137 sizes
[i
] = sizes
[i
- 1] + slace
;
1142 if (*read
+ sum
> block
)
1145 /* last frame is the remainder of the block */
1146 sizes
[i
] = block
- *read
- sum
;
1151 ne_get_timecode_scale(nestegg
* ctx
)
1155 if (ne_get_uint(ctx
->segment
.info
.timecode_scale
, &scale
) != 0)
1161 static struct track_entry
*
1162 ne_find_track_entry(nestegg
* ctx
, unsigned int track
)
1164 struct ebml_list_node
* node
;
1165 unsigned int tracks
= 0;
1167 node
= ctx
->segment
.tracks
.track_entry
.head
;
1169 assert(node
->id
== ID_TRACK_ENTRY
);
1170 if (track
== tracks
)
1180 ne_read_block(nestegg
* ctx
, uint64_t block_id
, uint64_t block_size
, nestegg_packet
** data
)
1183 int64_t timecode
, abs_timecode
;
1184 nestegg_packet
* pkt
;
1185 struct cluster
* cluster
;
1186 struct frame
* f
, * last
;
1187 struct track_entry
* entry
;
1189 uint64_t track
, length
, frame_sizes
[256], cluster_tc
, flags
, frames
, tc_scale
, total
;
1190 unsigned int i
, lacing
;
1191 size_t consumed
= 0;
1195 if (block_size
> LIMIT_BLOCK
)
1198 r
= ne_read_vint(ctx
->io
, &track
, &length
);
1202 if (track
== 0 || track
> ctx
->track_count
)
1207 r
= ne_read_int(ctx
->io
, &timecode
, 2);
1213 r
= ne_read_uint(ctx
->io
, &flags
, 1);
1221 /* flags are different between block and simpleblock, but lacing is
1222 encoded the same way */
1223 lacing
= (flags
& BLOCK_FLAGS_LACING
) >> 1;
1232 r
= ne_read_uint(ctx
->io
, &frames
, 1);
1244 frame_sizes
[0] = block_size
- consumed
;
1249 r
= ne_read_xiph_lacing(ctx
->io
, block_size
, &consumed
, frames
, frame_sizes
);
1254 if ((block_size
- consumed
) % frames
)
1256 for (i
= 0; i
< frames
; ++i
)
1257 frame_sizes
[i
] = (block_size
- consumed
) / frames
;
1262 r
= ne_read_ebml_lacing(ctx
->io
, block_size
, &consumed
, frames
, frame_sizes
);
1268 /* sanity check unlaced frame sizes against total block size. */
1270 for (i
= 0; i
< frames
; ++i
)
1271 total
+= frame_sizes
[i
];
1272 if (total
> block_size
)
1275 entry
= ne_find_track_entry(ctx
, track
- 1);
1281 tc_scale
= ne_get_timecode_scale(ctx
);
1283 assert(ctx
->segment
.cluster
.tail
->id
== ID_CLUSTER
);
1284 cluster
= ctx
->segment
.cluster
.tail
->data
;
1285 if (ne_get_uint(cluster
->timecode
, &cluster_tc
) != 0)
1288 abs_timecode
= timecode
+ cluster_tc
;
1289 if (abs_timecode
< 0)
1292 pkt
= ne_alloc(sizeof(*pkt
));
1293 pkt
->track
= track
- 1;
1294 pkt
->timecode
= abs_timecode
* tc_scale
* track_scale
;
1296 ctx
->log(ctx
, NESTEGG_LOG_DEBUG
, "%sblock t %lld pts %f f %llx frames: %llu",
1297 block_id
== ID_BLOCK
? "" : "simple", pkt
->track
, pkt
->timecode
/ 1e9
, flags
, frames
);
1300 for (i
= 0; i
< frames
; ++i
) {
1301 if (frame_sizes
[i
] > LIMIT_FRAME
) {
1302 nestegg_free_packet(pkt
);
1305 f
= ne_alloc(sizeof(*f
));
1306 f
->data
= ne_alloc(frame_sizes
[i
]);
1307 f
->length
= frame_sizes
[i
];
1308 r
= ne_io_read(ctx
->io
, f
->data
, frame_sizes
[i
]);
1312 nestegg_free_packet(pkt
);
1329 ne_buf_read_id(unsigned char const * p
, size_t length
)
1341 static struct seek
*
1342 ne_find_seek_for_id(struct ebml_list_node
* seek_head
, uint64_t id
)
1344 struct ebml_list
* head
;
1345 struct ebml_list_node
* seek
;
1346 struct ebml_binary binary_id
;
1350 assert(seek_head
->id
== ID_SEEK_HEAD
);
1351 head
= seek_head
->data
;
1355 assert(seek
->id
== ID_SEEK
);
1358 if (ne_get_binary(s
->id
, &binary_id
) == 0 &&
1359 ne_buf_read_id(binary_id
.data
, binary_id
.length
) == id
)
1365 seek_head
= seek_head
->next
;
1371 static struct cue_point
*
1372 ne_find_cue_point_for_tstamp(struct ebml_list_node
* cue_point
, uint64_t scale
, uint64_t tstamp
)
1375 struct cue_point
* c
, * prev
= NULL
;
1378 assert(cue_point
->id
== ID_CUE_POINT
);
1379 c
= cue_point
->data
;
1384 if (ne_get_uint(c
->time
, &time
) == 0 && time
* scale
> tstamp
)
1387 prev
= cue_point
->data
;
1388 cue_point
= cue_point
->next
;
1395 ne_is_suspend_element(uint64_t id
)
1397 /* this could search the tree of elements for DESC_FLAG_SUSPEND */
1398 if (id
== ID_SIMPLE_BLOCK
|| id
== ID_BLOCK
)
1404 ne_null_log_callback(nestegg
* ctx
, unsigned int severity
, char const * fmt
, ...)
1406 if (ctx
&& severity
&& fmt
)
1411 nestegg_init(nestegg
** context
, nestegg_io io
, nestegg_log callback
)
1414 uint64_t id
, version
, docversion
;
1415 struct ebml_list_node
* track
;
1417 nestegg
* ctx
= NULL
;
1419 if (!(io
.read
&& io
.seek
&& io
.tell
))
1422 ctx
= ne_alloc(sizeof(*ctx
));
1424 ctx
->io
= ne_alloc(sizeof(*ctx
->io
));
1426 ctx
->log
= callback
;
1427 ctx
->alloc_pool
= ne_pool_init();
1430 ctx
->log
= ne_null_log_callback
;
1432 r
= ne_peek_element(ctx
, &id
, NULL
);
1434 nestegg_destroy(ctx
);
1438 if (id
!= ID_EBML
) {
1439 nestegg_destroy(ctx
);
1443 ctx
->log(ctx
, NESTEGG_LOG_DEBUG
, "ctx %p", ctx
);
1445 ne_ctx_push(ctx
, ne_top_level_elements
, ctx
);
1447 r
= ne_parse(ctx
, NULL
);
1450 nestegg_destroy(ctx
);
1454 if (ne_get_uint(ctx
->ebml
.ebml_read_version
, &version
) != 0)
1457 nestegg_destroy(ctx
);
1461 if (ne_get_string(ctx
->ebml
.doctype
, &doctype
) != 0)
1462 doctype
= "matroska";
1463 if (strcmp(doctype
, "webm") != 0) {
1464 nestegg_destroy(ctx
);
1468 if (ne_get_uint(ctx
->ebml
.doctype_read_version
, &docversion
) != 0)
1470 if (docversion
< 1 || docversion
> 2) {
1471 nestegg_destroy(ctx
);
1475 if (!ctx
->segment
.tracks
.track_entry
.head
) {
1476 nestegg_destroy(ctx
);
1480 track
= ctx
->segment
.tracks
.track_entry
.head
;
1481 ctx
->track_count
= 0;
1484 ctx
->track_count
+= 1;
1485 track
= track
->next
;
1494 nestegg_destroy(nestegg
* ctx
)
1496 while (ctx
->ancestor
)
1498 ne_pool_destroy(ctx
->alloc_pool
);
1504 nestegg_duration(nestegg
* ctx
, uint64_t * duration
)
1507 double unscaled_duration
;
1509 if (ne_get_float(ctx
->segment
.info
.duration
, &unscaled_duration
) != 0)
1512 tc_scale
= ne_get_timecode_scale(ctx
);
1514 *duration
= (uint64_t) (unscaled_duration
* tc_scale
);
1519 nestegg_tstamp_scale(nestegg
* ctx
, uint64_t * scale
)
1521 *scale
= ne_get_timecode_scale(ctx
);
1526 nestegg_track_count(nestegg
* ctx
, unsigned int * tracks
)
1528 *tracks
= ctx
->track_count
;
1533 nestegg_track_seek(nestegg
* ctx
, unsigned int track
, uint64_t tstamp
)
1536 struct cue_point
* cue_point
;
1537 struct cue_track_positions
* pos
;
1538 struct saved_state state
;
1539 struct seek
* found
;
1540 uint64_t seek_pos
, tc_scale
, t
, id
;
1541 struct ebml_list_node
* node
= ctx
->segment
.cues
.cue_point
.head
;
1543 /* If there are no cues loaded, check for cues element in the seek head
1546 found
= ne_find_seek_for_id(ctx
->segment
.seek_head
.head
, ID_CUES
);
1550 if (ne_get_uint(found
->position
, &seek_pos
) != 0)
1553 /* Save old parser state. */
1554 r
= ne_ctx_save(ctx
, &state
);
1558 /* Seek and set up parser state for segment-level element (Cues). */
1559 r
= ne_io_seek(ctx
->io
, ctx
->segment_offset
+ seek_pos
, NESTEGG_SEEK_SET
);
1565 r
= ne_read_element(ctx
, &id
, NULL
);
1572 ctx
->ancestor
= NULL
;
1573 ne_ctx_push(ctx
, ne_top_level_elements
, ctx
);
1574 ne_ctx_push(ctx
, ne_segment_elements
, &ctx
->segment
);
1575 ne_ctx_push(ctx
, ne_cues_elements
, &ctx
->segment
.cues
);
1576 /* parser will run until end of cues element. */
1577 ctx
->log(ctx
, NESTEGG_LOG_DEBUG
, "seek: parsing cue elements");
1578 r
= ne_parse(ctx
, ne_cues_elements
);
1579 while (ctx
->ancestor
)
1582 /* Reset parser state to original state and seek back to old position. */
1583 if (ne_ctx_restore(ctx
, &state
) != 0)
1590 tc_scale
= ne_get_timecode_scale(ctx
);
1592 cue_point
= ne_find_cue_point_for_tstamp(ctx
->segment
.cues
.cue_point
.head
, tc_scale
, tstamp
);
1596 node
= cue_point
->cue_track_positions
.head
;
1601 assert(node
->id
== ID_CUE_TRACK_POSITIONS
);
1603 if (ne_get_uint(pos
->track
, &t
) == 0 && t
- 1 == track
) {
1604 if (ne_get_uint(pos
->cluster_position
, &seek_pos
) != 0)
1611 /* Seek and set up parser state for segment-level element (Cluster). */
1612 r
= ne_io_seek(ctx
->io
, ctx
->segment_offset
+ seek_pos
, NESTEGG_SEEK_SET
);
1618 while (ctx
->ancestor
)
1621 ne_ctx_push(ctx
, ne_top_level_elements
, ctx
);
1622 ne_ctx_push(ctx
, ne_segment_elements
, &ctx
->segment
);
1623 ctx
->log(ctx
, NESTEGG_LOG_DEBUG
, "seek: parsing cluster elements");
1624 r
= ne_parse(ctx
, NULL
);
1628 if (!ne_is_suspend_element(ctx
->last_id
))
1635 nestegg_track_type(nestegg
* ctx
, unsigned int track
)
1637 struct track_entry
* entry
;
1640 entry
= ne_find_track_entry(ctx
, track
);
1644 if (ne_get_uint(entry
->type
, &type
) != 0)
1647 if (type
& TRACK_TYPE_VIDEO
)
1648 return NESTEGG_TRACK_VIDEO
;
1650 if (type
& TRACK_TYPE_AUDIO
)
1651 return NESTEGG_TRACK_AUDIO
;
1657 nestegg_track_codec_id(nestegg
* ctx
, unsigned int track
)
1660 struct track_entry
* entry
;
1662 entry
= ne_find_track_entry(ctx
, track
);
1666 if (ne_get_string(entry
->codec_id
, &codec_id
) != 0)
1669 if (strcmp(codec_id
, TRACK_ID_VP8
) == 0)
1670 return NESTEGG_CODEC_VP8
;
1672 if (strcmp(codec_id
, TRACK_ID_VORBIS
) == 0)
1673 return NESTEGG_CODEC_VORBIS
;
1679 nestegg_track_codec_data_count(nestegg
* ctx
, unsigned int track
,
1680 unsigned int * count
)
1682 struct track_entry
* entry
;
1683 struct ebml_binary codec_private
;
1688 entry
= ne_find_track_entry(ctx
, track
);
1692 if (nestegg_track_codec_id(ctx
, track
) != NESTEGG_CODEC_VORBIS
)
1695 if (ne_get_binary(entry
->codec_private
, &codec_private
) != 0)
1698 if (codec_private
.length
< 1)
1701 p
= codec_private
.data
;
1711 nestegg_track_codec_data(nestegg
* ctx
, unsigned int track
, unsigned int item
,
1712 unsigned char ** data
, size_t * length
)
1714 struct track_entry
* entry
;
1715 struct ebml_binary codec_private
;
1716 uint64_t sizes
[3], total
;
1718 unsigned int count
, i
;
1723 entry
= ne_find_track_entry(ctx
, track
);
1727 if (nestegg_track_codec_id(ctx
, track
) != NESTEGG_CODEC_VORBIS
)
1730 if (ne_get_binary(entry
->codec_private
, &codec_private
) != 0)
1733 p
= codec_private
.data
;
1742 sizes
[i
] = ne_xiph_lace_value(&p
);
1746 sizes
[i
] = codec_private
.length
- total
- (p
- codec_private
.data
);
1748 for (i
= 0; i
< item
; ++i
) {
1749 if (sizes
[i
] > LIMIT_FRAME
)
1754 *length
= sizes
[item
];
1760 nestegg_track_video_params(nestegg
* ctx
, unsigned int track
,
1761 nestegg_video_params
* params
)
1763 struct track_entry
* entry
;
1766 memset(params
, 0, sizeof(*params
));
1768 entry
= ne_find_track_entry(ctx
, track
);
1772 if (nestegg_track_type(ctx
, track
) != NESTEGG_TRACK_VIDEO
)
1775 if (ne_get_uint(entry
->video
.pixel_width
, &value
) != 0)
1777 params
->width
= value
;
1779 if (ne_get_uint(entry
->video
.pixel_height
, &value
) != 0)
1781 params
->height
= value
;
1784 ne_get_uint(entry
->video
.pixel_crop_bottom
, &value
);
1785 params
->crop_bottom
= value
;
1788 ne_get_uint(entry
->video
.pixel_crop_top
, &value
);
1789 params
->crop_top
= value
;
1792 ne_get_uint(entry
->video
.pixel_crop_left
, &value
);
1793 params
->crop_left
= value
;
1796 ne_get_uint(entry
->video
.pixel_crop_right
, &value
);
1797 params
->crop_right
= value
;
1799 value
= params
->width
;
1800 ne_get_uint(entry
->video
.display_width
, &value
);
1801 params
->display_width
= value
;
1803 value
= params
->height
;
1804 ne_get_uint(entry
->video
.display_height
, &value
);
1805 params
->display_height
= value
;
1811 nestegg_track_audio_params(nestegg
* ctx
, unsigned int track
,
1812 nestegg_audio_params
* params
)
1814 struct track_entry
* entry
;
1817 memset(params
, 0, sizeof(*params
));
1819 entry
= ne_find_track_entry(ctx
, track
);
1823 if (nestegg_track_type(ctx
, track
) != NESTEGG_TRACK_AUDIO
)
1826 params
->rate
= 8000;
1827 ne_get_float(entry
->audio
.sampling_frequency
, ¶ms
->rate
);
1830 ne_get_uint(entry
->audio
.channels
, &value
);
1831 params
->channels
= value
;
1834 ne_get_uint(entry
->audio
.bit_depth
, &value
);
1835 params
->depth
= value
;
1841 nestegg_read_packet(nestegg
* ctx
, nestegg_packet
** pkt
)
1849 r
= ne_peek_element(ctx
, &id
, &size
);
1853 /* any suspend fields must be handled here */
1854 if (ne_is_suspend_element(id
)) {
1855 r
= ne_read_element(ctx
, &id
, &size
);
1859 /* the only suspend fields are blocks and simple blocks, which we
1861 r
= ne_read_block(ctx
, id
, size
, pkt
);
1865 r
= ne_parse(ctx
, NULL
);
1874 nestegg_free_packet(nestegg_packet
* pkt
)
1876 struct frame
* frame
;
1878 while (pkt
->frame
) {
1880 pkt
->frame
= frame
->next
;
1889 nestegg_packet_track(nestegg_packet
* pkt
, unsigned int * track
)
1891 *track
= pkt
->track
;
1896 nestegg_packet_tstamp(nestegg_packet
* pkt
, uint64_t * tstamp
)
1898 *tstamp
= pkt
->timecode
;
1903 nestegg_packet_count(nestegg_packet
* pkt
, unsigned int * count
)
1905 struct frame
* f
= pkt
->frame
;
1918 nestegg_packet_data(nestegg_packet
* pkt
, unsigned int item
,
1919 unsigned char ** data
, size_t * length
)
1921 struct frame
* f
= pkt
->frame
;
1922 unsigned int count
= 0;
1928 if (count
== item
) {
1930 *length
= f
->length
;