1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2010-2015 L-SMASH project
6 * Authors: Yusuke Nakamura <muken.the.vfrmaniac@gmail.com>
8 * Permission to use, copy, modify, and/or distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 *****************************************************************************/
21 /* This file is available under an ISC license. */
23 #include "common/internal.h" /* must be placed first */
35 #include "codecs/mp4a.h"
36 #include "codecs/mp4sys.h"
37 #include "codecs/description.h"
39 static int isom_bs_read_box_common( lsmash_bs_t
*bs
, isom_box_t
*box
)
41 assert( bs
&& box
&& box
->file
);
42 /* Reset the counter so that we can use it to get position within the box. */
43 lsmash_bs_reset_counter( bs
);
44 /* Read the common fields of box. */
45 box
->pos
= lsmash_bs_get_stream_pos( bs
);
49 /* Read size and type. */
50 box
->size
= lsmash_bs_get_be32( bs
);
51 box
->type
.fourcc
= lsmash_bs_get_be32( bs
);
52 /* If size is set to 1, the actual size is repersented in the next 8 bytes.
53 * If size is set to 0, this box ends at the end of the stream. */
55 box
->size
= lsmash_bs_get_be64( bs
);
58 /* This box is the last box in the stream. */
59 box
->manager
|= LSMASH_LAST_BOX
;
61 box
->size
= bs
->written
- (lsmash_bs_get_stream_pos( bs
) - lsmash_bs_count( bs
));
63 /* We haven't known the box size yet.
64 * To get the box size, read the stream until the end of the stream. */
67 int ret
= lsmash_bs_read( bs
, 1 );
68 if( bs
->eof
|| ret
< 0 )
70 /* OK, now we know the box size. */
71 box
->size
= lsmash_bs_count( bs
) + lsmash_bs_get_remaining_buffer_size( bs
);
73 /* This box may end incompletely at the end of the stream. */
74 box
->manager
|= LSMASH_INCOMPLETE_BOX
;
79 /* Here, we don't set up extended box type fields if this box is not a UUID Box. */
80 if( box
->type
.fourcc
== ISOM_BOX_TYPE_UUID
.fourcc
81 && box
->size
>= lsmash_bs_count( bs
) + 16 )
84 lsmash_box_type_t
*type
= &box
->type
;
85 uint64_t temp64
= lsmash_bs_get_be64( bs
);
86 type
->user
.fourcc
= (temp64
>> 32) & 0xffffffff;
87 LSMASH_SET_BE32( &type
->user
.id
[0], temp64
);
88 temp64
= lsmash_bs_get_be64( bs
);
89 LSMASH_SET_BE64( &type
->user
.id
[4], temp64
);
94 static int isom_read_fullbox_common_extension( lsmash_bs_t
*bs
, isom_box_t
*box
)
96 if( !isom_is_fullbox( box
) )
98 /* Get version and flags. */
99 box
->version
= lsmash_bs_get_byte( bs
);
100 box
->flags
= lsmash_bs_get_be24( bs
);
101 box
->manager
|= LSMASH_FULLBOX
;
105 /* Don't copy destructor since a destructor is defined as box specific. */
106 static void isom_basebox_common_copy( isom_box_t
*dst
, isom_box_t
*src
)
108 dst
->root
= src
->root
;
109 dst
->file
= src
->file
;
110 dst
->parent
= src
->parent
;
111 dst
->manager
= src
->manager
;
113 dst
->size
= src
->size
;
114 dst
->type
= src
->type
;
117 static void isom_fullbox_common_copy( isom_box_t
*dst
, isom_box_t
*src
)
119 dst
->root
= src
->root
;
120 dst
->file
= src
->file
;
121 dst
->parent
= src
->parent
;
122 dst
->manager
= src
->manager
;
124 dst
->size
= src
->size
;
125 dst
->type
= src
->type
;
126 dst
->version
= src
->version
;
127 dst
->flags
= src
->flags
;
130 static void isom_box_common_copy( void *dst
, void *src
)
132 if( src
&& lsmash_check_box_type_identical( ((isom_box_t
*)src
)->type
, ISOM_BOX_TYPE_STSD
) )
134 isom_basebox_common_copy( (isom_box_t
*)dst
, (isom_box_t
*)src
);
137 if( isom_is_fullbox( src
) )
138 isom_fullbox_common_copy( (isom_box_t
*)dst
, (isom_box_t
*)src
);
140 isom_basebox_common_copy( (isom_box_t
*)dst
, (isom_box_t
*)src
);
143 static void isom_skip_box_rest( lsmash_bs_t
*bs
, isom_box_t
*box
)
145 if( box
->manager
& LSMASH_LAST_BOX
)
147 box
->size
= (box
->manager
& LSMASH_FULLBOX
) ? ISOM_FULLBOX_COMMON_SIZE
: ISOM_BASEBOX_COMMON_SIZE
;
148 uint64_t start
= lsmash_bs_get_stream_pos( bs
);
149 if( !bs
->unseekable
)
150 lsmash_bs_read_seek( bs
, 0, SEEK_END
);
153 lsmash_bs_skip_bytes( bs
, UINT32_MAX
);
154 uint64_t end
= lsmash_bs_get_stream_pos( bs
);
155 box
->size
+= end
- start
;
158 uint64_t skip_bytes
= box
->size
- lsmash_bs_count( bs
);
159 if( !bs
->unseekable
)
161 /* The stream is seekable. So, skip by seeking the stream. */
162 uint64_t start
= lsmash_bs_get_stream_pos( bs
);
163 lsmash_bs_read_seek( bs
, skip_bytes
, SEEK_CUR
);
164 uint64_t end
= lsmash_bs_get_stream_pos( bs
);
165 if( end
- start
!= skip_bytes
)
167 box
->manager
|= LSMASH_INCOMPLETE_BOX
;
170 /* The stream is unseekable. So, skip by reading the stream. */
171 lsmash_bs_skip_bytes_64( bs
, skip_bytes
);
172 if( box
->size
> lsmash_bs_count( bs
) )
173 box
->manager
|= LSMASH_INCOMPLETE_BOX
;
176 static void isom_validate_box_size( lsmash_bs_t
*bs
, isom_box_t
*box
)
178 uint64_t pos
= lsmash_bs_count( bs
);
179 if( box
->manager
& LSMASH_LAST_BOX
)
184 if( box
->size
< pos
)
186 printf( "[%s] box has less bytes than expected: %"PRId64
"\n", isom_4cc2str( box
->type
.fourcc
), pos
- box
->size
);
189 else if( box
->size
> pos
)
191 /* The box probably has extra padding bytes at the end. */
192 printf( "[%s] box has more bytes than expected: %"PRId64
"\n", isom_4cc2str( box
->type
.fourcc
), box
->size
- pos
);
193 isom_skip_box_rest( bs
, box
);
197 static int isom_read_children( lsmash_file_t
*file
, isom_box_t
*box
, void *parent
, int level
)
200 lsmash_bs_t
*bs
= file
->bs
;
201 isom_box_t
*parent_box
= (isom_box_t
*)parent
;
202 uint64_t parent_pos
= lsmash_bs_count( bs
);
203 while( !(ret
= isom_read_box( file
, box
, parent_box
, parent_pos
, level
)) )
205 parent_pos
+= box
->size
;
206 if( parent_box
->size
<= parent_pos
|| bs
->eob
|| bs
->error
)
209 box
->size
= parent_pos
; /* for file size */
213 static int isom_read_leaf_box_common_last_process( lsmash_file_t
*file
, isom_box_t
*box
, int level
, void *instance
)
215 isom_validate_box_size( file
->bs
, box
);
216 isom_box_common_copy( instance
, box
);
217 return isom_add_print_func( file
, instance
, level
);
220 static int isom_read_unknown_box( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
222 lsmash_bs_t
*bs
= file
->bs
;
223 uint64_t read_size
= box
->size
- lsmash_bs_count( bs
);
224 if( box
->manager
& LSMASH_INCOMPLETE_BOX
)
225 return LSMASH_ERR_INVALID_DATA
;
226 isom_unknown_box_t
*unknown
= lsmash_malloc_zero( sizeof(isom_unknown_box_t
) );
228 return LSMASH_ERR_MEMORY_ALLOC
;
229 if( lsmash_add_entry( &parent
->extensions
, unknown
) < 0 )
231 lsmash_free( unknown
);
232 return LSMASH_ERR_MEMORY_ALLOC
;
234 isom_box_common_copy( unknown
, box
);
235 unknown
->manager
|= LSMASH_UNKNOWN_BOX
;
236 unknown
->destruct
= (isom_extension_destructor_t
)isom_remove_unknown_box
;
237 isom_set_box_writer( (isom_box_t
*)unknown
);
240 unknown
->unknown_field
= lsmash_bs_get_bytes( bs
, read_size
);
241 if( unknown
->unknown_field
)
242 unknown
->unknown_size
= read_size
;
244 unknown
->manager
|= LSMASH_INCOMPLETE_BOX
;
246 if( !(file
->flags
& LSMASH_FILE_MODE_DUMP
) )
248 /* Create a dummy for dump. */
249 isom_box_t
*dummy
= lsmash_malloc_zero( sizeof(isom_box_t
) );
251 return LSMASH_ERR_MEMORY_ALLOC
;
252 box
->manager
|= LSMASH_ABSENT_IN_FILE
| LSMASH_UNKNOWN_BOX
;
253 isom_box_common_copy( dummy
, box
);
254 int ret
= isom_add_print_func( file
, dummy
, level
);
257 lsmash_free( dummy
);
263 #define ADD_BOX( box_name, parent_type ) \
264 isom_##box_name##_t *box_name = isom_add_##box_name( (parent_type *)parent ); \
266 return LSMASH_ERR_NAMELESS
268 static int isom_read_ftyp( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
270 if( !lsmash_check_box_type_identical( parent
->type
, LSMASH_BOX_TYPE_UNSPECIFIED
) || ((lsmash_file_t
*)parent
)->ftyp
)
271 return isom_read_unknown_box( file
, box
, parent
, level
);
272 ADD_BOX( ftyp
, lsmash_file_t
);
273 lsmash_bs_t
*bs
= file
->bs
;
274 ftyp
->major_brand
= lsmash_bs_get_be32( bs
);
275 ftyp
->minor_version
= lsmash_bs_get_be32( bs
);
276 uint64_t pos
= lsmash_bs_count( bs
);
277 ftyp
->brand_count
= box
->size
> pos
? (box
->size
- pos
) / sizeof(uint32_t) : 0;
278 size_t alloc_size
= ftyp
->brand_count
* sizeof(uint32_t);
279 ftyp
->compatible_brands
= ftyp
->brand_count
? lsmash_malloc( alloc_size
) : NULL
;
280 if( ftyp
->brand_count
&& !ftyp
->compatible_brands
)
281 return LSMASH_ERR_MEMORY_ALLOC
;
282 for( uint32_t i
= 0; i
< ftyp
->brand_count
; i
++ )
283 ftyp
->compatible_brands
[i
] = lsmash_bs_get_be32( bs
);
284 if( !file
->compatible_brands
&& ftyp
->compatible_brands
)
286 file
->compatible_brands
= lsmash_memdup( ftyp
->compatible_brands
, alloc_size
);
287 if( !file
->compatible_brands
)
288 return LSMASH_ERR_MEMORY_ALLOC
;
289 file
->brand_count
= ftyp
->brand_count
;
291 return isom_read_leaf_box_common_last_process( file
, box
, level
, ftyp
);
294 static int isom_read_styp( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
296 if( !lsmash_check_box_type_identical( parent
->type
, LSMASH_BOX_TYPE_UNSPECIFIED
) )
297 return isom_read_unknown_box( file
, box
, parent
, level
);
298 ADD_BOX( styp
, lsmash_file_t
);
299 lsmash_bs_t
*bs
= file
->bs
;
300 styp
->major_brand
= lsmash_bs_get_be32( bs
);
301 styp
->minor_version
= lsmash_bs_get_be32( bs
);
302 uint64_t pos
= lsmash_bs_count( bs
);
303 styp
->brand_count
= box
->size
> pos
? (box
->size
- pos
) / sizeof(uint32_t) : 0;
304 size_t alloc_size
= styp
->brand_count
* sizeof(uint32_t);
305 styp
->compatible_brands
= styp
->brand_count
? lsmash_malloc( alloc_size
) : NULL
;
306 if( styp
->brand_count
&& !styp
->compatible_brands
)
307 return LSMASH_ERR_MEMORY_ALLOC
;
308 for( uint32_t i
= 0; i
< styp
->brand_count
; i
++ )
309 styp
->compatible_brands
[i
] = lsmash_bs_get_be32( bs
);
310 if( !file
->compatible_brands
&& styp
->compatible_brands
)
312 file
->compatible_brands
= lsmash_memdup( styp
->compatible_brands
, alloc_size
);
313 if( !file
->compatible_brands
)
314 return LSMASH_ERR_MEMORY_ALLOC
;
315 file
->brand_count
= styp
->brand_count
;
317 file
->flags
|= LSMASH_FILE_MODE_SEGMENT
;
318 return isom_read_leaf_box_common_last_process( file
, box
, level
, styp
);
321 static int isom_read_sidx( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
323 if( !lsmash_check_box_type_identical( parent
->type
, LSMASH_BOX_TYPE_UNSPECIFIED
) )
324 return isom_read_unknown_box( file
, box
, parent
, level
);
325 ADD_BOX( sidx
, lsmash_file_t
);
326 lsmash_bs_t
*bs
= file
->bs
;
327 sidx
->reference_ID
= lsmash_bs_get_be32( bs
);
328 sidx
->timescale
= lsmash_bs_get_be32( bs
);
329 if( box
->version
== 0 )
331 sidx
->earliest_presentation_time
= lsmash_bs_get_be32( bs
);
332 sidx
->first_offset
= lsmash_bs_get_be32( bs
);
336 sidx
->earliest_presentation_time
= lsmash_bs_get_be64( bs
);
337 sidx
->first_offset
= lsmash_bs_get_be64( bs
);
339 sidx
->reserved
= lsmash_bs_get_be16( bs
);
340 sidx
->reference_count
= lsmash_bs_get_be16( bs
);
341 for( uint64_t pos
= lsmash_bs_count( bs
);
342 pos
< box
->size
&& sidx
->list
->entry_count
< sidx
->reference_count
;
343 pos
= lsmash_bs_count( bs
) )
345 isom_sidx_referenced_item_t
*data
= lsmash_malloc( sizeof(isom_sidx_referenced_item_t
) );
347 return LSMASH_ERR_MEMORY_ALLOC
;
348 if( lsmash_add_entry( sidx
->list
, data
) < 0 )
351 return LSMASH_ERR_MEMORY_ALLOC
;
354 temp32
= lsmash_bs_get_be32( bs
);
355 data
->reference_type
= (temp32
>> 31) & 0x00000001;
356 data
->reference_size
= temp32
& 0x7FFFFFFF;
357 data
->subsegment_duration
= lsmash_bs_get_be32( bs
);
358 temp32
= lsmash_bs_get_be32( bs
);
359 data
->starts_with_SAP
= (temp32
>> 31) & 0x00000001;
360 data
->SAP_type
= (temp32
>> 28) & 0x00000007;
361 data
->SAP_delta_time
= temp32
& 0x0FFFFFFF;
363 file
->flags
|= LSMASH_FILE_MODE_INDEX
;
364 return isom_read_leaf_box_common_last_process( file
, box
, level
, sidx
);
367 static int isom_read_moov( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
369 if( !lsmash_check_box_type_identical( parent
->type
, LSMASH_BOX_TYPE_UNSPECIFIED
) || ((lsmash_file_t
*)parent
)->moov
)
370 return isom_read_unknown_box( file
, box
, parent
, level
);
371 ADD_BOX( moov
, lsmash_file_t
);
372 file
->flags
|= LSMASH_FILE_MODE_INITIALIZATION
;
373 file
->initializer
= file
;
374 isom_box_common_copy( moov
, box
);
375 int ret
= isom_add_print_func( file
, moov
, level
);
378 return isom_read_children( file
, box
, moov
, level
);
381 static int isom_read_mvhd( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
383 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MOOV
) || ((isom_moov_t
*)parent
)->mvhd
)
384 return isom_read_unknown_box( file
, box
, parent
, level
);
385 ADD_BOX( mvhd
, isom_moov_t
);
386 lsmash_bs_t
*bs
= file
->bs
;
389 mvhd
->creation_time
= lsmash_bs_get_be64( bs
);
390 mvhd
->modification_time
= lsmash_bs_get_be64( bs
);
391 mvhd
->timescale
= lsmash_bs_get_be32( bs
);
392 mvhd
->duration
= lsmash_bs_get_be64( bs
);
396 mvhd
->creation_time
= lsmash_bs_get_be32( bs
);
397 mvhd
->modification_time
= lsmash_bs_get_be32( bs
);
398 mvhd
->timescale
= lsmash_bs_get_be32( bs
);
399 mvhd
->duration
= lsmash_bs_get_be32( bs
);
401 mvhd
->rate
= lsmash_bs_get_be32( bs
);
402 mvhd
->volume
= lsmash_bs_get_be16( bs
);
403 mvhd
->reserved
= lsmash_bs_get_be16( bs
);
404 mvhd
->preferredLong
[0] = lsmash_bs_get_be32( bs
);
405 mvhd
->preferredLong
[1] = lsmash_bs_get_be32( bs
);
406 for( int i
= 0; i
< 9; i
++ )
407 mvhd
->matrix
[i
] = lsmash_bs_get_be32( bs
);
408 mvhd
->previewTime
= lsmash_bs_get_be32( bs
);
409 mvhd
->previewDuration
= lsmash_bs_get_be32( bs
);
410 mvhd
->posterTime
= lsmash_bs_get_be32( bs
);
411 mvhd
->selectionTime
= lsmash_bs_get_be32( bs
);
412 mvhd
->selectionDuration
= lsmash_bs_get_be32( bs
);
413 mvhd
->currentTime
= lsmash_bs_get_be32( bs
);
414 mvhd
->next_track_ID
= lsmash_bs_get_be32( bs
);
415 return isom_read_leaf_box_common_last_process( file
, box
, level
, mvhd
);
418 static int isom_read_iods( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
420 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MOOV
) )
421 return isom_read_unknown_box( file
, box
, parent
, level
);
422 ADD_BOX( iods
, isom_moov_t
);
423 lsmash_bs_t
*bs
= file
->bs
;
424 iods
->OD
= mp4sys_get_descriptor( bs
, NULL
);
426 return LSMASH_ERR_INVALID_DATA
;
427 return isom_read_leaf_box_common_last_process( file
, box
, level
, iods
);
430 static int isom_read_qt_color_table( lsmash_bs_t
*bs
, isom_qt_color_table_t
*color_table
)
432 color_table
->seed
= lsmash_bs_get_be32( bs
);
433 color_table
->flags
= lsmash_bs_get_be16( bs
);
434 color_table
->size
= lsmash_bs_get_be16( bs
);
436 return LSMASH_ERR_INVALID_DATA
;
437 isom_qt_color_array_t
*array
= lsmash_malloc_zero( (color_table
->size
+ 1) * sizeof(isom_qt_color_array_t
) );
439 return LSMASH_ERR_MEMORY_ALLOC
;
440 color_table
->array
= array
;
441 for( uint16_t i
= 0; i
<= color_table
->size
; i
++ )
443 uint64_t color
= lsmash_bs_get_be64( bs
);
444 array
[i
].value
= (color
>> 48) & 0xffff;
445 array
[i
].r
= (color
>> 32) & 0xffff;
446 array
[i
].g
= (color
>> 16) & 0xffff;
447 array
[i
].b
= color
& 0xffff;
452 static int isom_read_ctab( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
454 ADD_BOX( ctab
, isom_moov_t
);
455 lsmash_bs_t
*bs
= file
->bs
;
456 int ret
= isom_read_qt_color_table( bs
, &ctab
->color_table
);
459 return isom_read_leaf_box_common_last_process( file
, box
, level
, ctab
);
462 static int isom_read_trak( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
464 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MOOV
) )
465 return isom_read_unknown_box( file
, box
, parent
, level
);
466 ADD_BOX( trak
, isom_moov_t
);
467 box
->parent
= parent
;
468 box
->root
= file
->root
;
470 isom_box_common_copy( trak
, box
);
471 int ret
= isom_add_print_func( file
, trak
, level
);
474 return isom_read_children( file
, box
, trak
, level
);
477 static int isom_read_tkhd( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
479 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TRAK
) || ((isom_trak_t
*)parent
)->tkhd
)
480 return isom_read_unknown_box( file
, box
, parent
, level
);
481 ADD_BOX( tkhd
, isom_trak_t
);
482 lsmash_bs_t
*bs
= file
->bs
;
485 tkhd
->creation_time
= lsmash_bs_get_be64( bs
);
486 tkhd
->modification_time
= lsmash_bs_get_be64( bs
);
487 tkhd
->track_ID
= lsmash_bs_get_be32( bs
);
488 tkhd
->reserved1
= lsmash_bs_get_be32( bs
);
489 tkhd
->duration
= lsmash_bs_get_be64( bs
);
493 tkhd
->creation_time
= lsmash_bs_get_be32( bs
);
494 tkhd
->modification_time
= lsmash_bs_get_be32( bs
);
495 tkhd
->track_ID
= lsmash_bs_get_be32( bs
);
496 tkhd
->reserved1
= lsmash_bs_get_be32( bs
);
497 tkhd
->duration
= lsmash_bs_get_be32( bs
);
499 tkhd
->reserved2
[0] = lsmash_bs_get_be32( bs
);
500 tkhd
->reserved2
[1] = lsmash_bs_get_be32( bs
);
501 tkhd
->layer
= lsmash_bs_get_be16( bs
);
502 tkhd
->alternate_group
= lsmash_bs_get_be16( bs
);
503 tkhd
->volume
= lsmash_bs_get_be16( bs
);
504 tkhd
->reserved3
= lsmash_bs_get_be16( bs
);
505 for( int i
= 0; i
< 9; i
++ )
506 tkhd
->matrix
[i
] = lsmash_bs_get_be32( bs
);
507 tkhd
->width
= lsmash_bs_get_be32( bs
);
508 tkhd
->height
= lsmash_bs_get_be32( bs
);
509 return isom_read_leaf_box_common_last_process( file
, box
, level
, tkhd
);
512 static int isom_read_tapt( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
514 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TRAK
) || ((isom_trak_t
*)parent
)->tapt
)
515 return isom_read_unknown_box( file
, box
, parent
, level
);
516 ADD_BOX( tapt
, isom_trak_t
);
517 isom_box_common_copy( tapt
, box
);
518 int ret
= isom_add_print_func( file
, tapt
, level
);
521 return isom_read_children( file
, box
, tapt
, level
);
524 static int isom_read_clef( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
526 if( !lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_TAPT
) || ((isom_tapt_t
*)parent
)->clef
)
527 return isom_read_unknown_box( file
, box
, parent
, level
);
528 ADD_BOX( clef
, isom_tapt_t
);
529 lsmash_bs_t
*bs
= file
->bs
;
530 clef
->width
= lsmash_bs_get_be32( bs
);
531 clef
->height
= lsmash_bs_get_be32( bs
);
532 return isom_read_leaf_box_common_last_process( file
, box
, level
, clef
);
535 static int isom_read_prof( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
537 if( !lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_TAPT
) || ((isom_tapt_t
*)parent
)->prof
)
538 return isom_read_unknown_box( file
, box
, parent
, level
);
539 ADD_BOX( prof
, isom_tapt_t
);
540 lsmash_bs_t
*bs
= file
->bs
;
541 prof
->width
= lsmash_bs_get_be32( bs
);
542 prof
->height
= lsmash_bs_get_be32( bs
);
543 return isom_read_leaf_box_common_last_process( file
, box
, level
, prof
);
546 static int isom_read_enof( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
548 if( !lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_TAPT
) || ((isom_tapt_t
*)parent
)->enof
)
549 return isom_read_unknown_box( file
, box
, parent
, level
);
550 ADD_BOX( enof
, isom_tapt_t
);
551 lsmash_bs_t
*bs
= file
->bs
;
552 enof
->width
= lsmash_bs_get_be32( bs
);
553 enof
->height
= lsmash_bs_get_be32( bs
);
554 return isom_read_leaf_box_common_last_process( file
, box
, level
, enof
);
557 static int isom_read_edts( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
559 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TRAK
) || ((isom_trak_t
*)parent
)->edts
)
560 return isom_read_unknown_box( file
, box
, parent
, level
);
561 ADD_BOX( edts
, isom_trak_t
);
562 isom_box_common_copy( edts
, box
);
563 if( isom_add_print_func( file
, edts
, level
) < 0 )
565 return isom_read_children( file
, box
, edts
, level
);
568 static int isom_read_elst( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
570 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_EDTS
) || ((isom_edts_t
*)parent
)->elst
)
571 return isom_read_unknown_box( file
, box
, parent
, level
);
572 ADD_BOX( elst
, isom_edts_t
);
573 lsmash_bs_t
*bs
= file
->bs
;
574 uint32_t entry_count
= lsmash_bs_get_be32( bs
);
575 for( uint64_t pos
= lsmash_bs_count( bs
); pos
< box
->size
&& elst
->list
->entry_count
< entry_count
; pos
= lsmash_bs_count( bs
) )
577 isom_elst_entry_t
*data
= lsmash_malloc( sizeof(isom_elst_entry_t
) );
579 return LSMASH_ERR_MEMORY_ALLOC
;
580 if( lsmash_add_entry( elst
->list
, data
) < 0 )
583 return LSMASH_ERR_MEMORY_ALLOC
;
585 if( box
->version
== 1 )
587 data
->segment_duration
= lsmash_bs_get_be64( bs
);
588 data
->media_time
= (int64_t)lsmash_bs_get_be64( bs
);
592 data
->segment_duration
= lsmash_bs_get_be32( bs
);
593 data
->media_time
= (int32_t)lsmash_bs_get_be32( bs
);
595 data
->media_rate
= lsmash_bs_get_be32( bs
);
597 return isom_read_leaf_box_common_last_process( file
, box
, level
, elst
);
600 static int isom_read_tref( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
602 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TRAK
) || ((isom_trak_t
*)parent
)->tref
)
603 return isom_read_unknown_box( file
, box
, parent
, level
);
604 ADD_BOX( tref
, isom_trak_t
);
605 isom_box_common_copy( tref
, box
);
606 int ret
= isom_add_print_func( file
, tref
, level
);
609 return isom_read_children( file
, box
, tref
, level
);
612 static int isom_read_track_reference_type( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
614 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TREF
) )
615 return isom_read_unknown_box( file
, box
, parent
, level
);
616 isom_tref_type_t
*ref
= isom_add_track_reference_type( (isom_tref_t
*)parent
, box
->type
.fourcc
);
618 return LSMASH_ERR_NAMELESS
;
619 lsmash_bs_t
*bs
= file
->bs
;
620 ref
->ref_count
= (box
->size
- lsmash_bs_count( bs
) ) / sizeof(uint32_t);
623 ref
->track_ID
= lsmash_malloc( ref
->ref_count
* sizeof(uint32_t) );
627 return LSMASH_ERR_MEMORY_ALLOC
;
629 for( uint32_t i
= 0; i
< ref
->ref_count
; i
++ )
630 ref
->track_ID
[i
] = lsmash_bs_get_be32( bs
);
632 return isom_read_leaf_box_common_last_process( file
, box
, level
, ref
);
635 static int isom_read_mdia( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
637 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TRAK
) || ((isom_trak_t
*)parent
)->mdia
)
638 return isom_read_unknown_box( file
, box
, parent
, level
);
639 ADD_BOX( mdia
, isom_trak_t
);
640 isom_box_common_copy( mdia
, box
);
641 int ret
= isom_add_print_func( file
, mdia
, level
);
644 return isom_read_children( file
, box
, mdia
, level
);
647 static int isom_read_mdhd( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
649 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MDIA
) || ((isom_mdia_t
*)parent
)->mdhd
)
650 return isom_read_unknown_box( file
, box
, parent
, level
);
651 ADD_BOX( mdhd
, isom_mdia_t
);
652 lsmash_bs_t
*bs
= file
->bs
;
655 mdhd
->creation_time
= lsmash_bs_get_be64( bs
);
656 mdhd
->modification_time
= lsmash_bs_get_be64( bs
);
657 mdhd
->timescale
= lsmash_bs_get_be32( bs
);
658 mdhd
->duration
= lsmash_bs_get_be64( bs
);
662 mdhd
->creation_time
= lsmash_bs_get_be32( bs
);
663 mdhd
->modification_time
= lsmash_bs_get_be32( bs
);
664 mdhd
->timescale
= lsmash_bs_get_be32( bs
);
665 mdhd
->duration
= lsmash_bs_get_be32( bs
);
667 mdhd
->language
= lsmash_bs_get_be16( bs
);
668 mdhd
->quality
= lsmash_bs_get_be16( bs
);
669 return isom_read_leaf_box_common_last_process( file
, box
, level
, mdhd
);
672 static int isom_read_hdlr( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
674 if( (!lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MDIA
)
675 && !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_META
)
676 && !lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_META
)
677 && !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MINF
))
678 || (lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MDIA
) && ((isom_mdia_t
*)parent
)->hdlr
)
679 || (lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_META
) && ((isom_meta_t
*)parent
)->hdlr
)
680 || (lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_META
) && ((isom_meta_t
*)parent
)->hdlr
)
681 || (lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MINF
) && ((isom_minf_t
*)parent
)->hdlr
) )
682 return isom_read_unknown_box( file
, box
, parent
, level
);
683 ADD_BOX( hdlr
, void );
684 lsmash_bs_t
*bs
= file
->bs
;
685 hdlr
->componentType
= lsmash_bs_get_be32( bs
);
686 hdlr
->componentSubtype
= lsmash_bs_get_be32( bs
);
687 hdlr
->componentManufacturer
= lsmash_bs_get_be32( bs
);
688 hdlr
->componentFlags
= lsmash_bs_get_be32( bs
);
689 hdlr
->componentFlagsMask
= lsmash_bs_get_be32( bs
);
690 uint64_t pos
= lsmash_bs_count( bs
);
691 hdlr
->componentName_length
= box
->size
- pos
;
692 if( hdlr
->componentName_length
)
694 hdlr
->componentName
= lsmash_malloc( hdlr
->componentName_length
);
695 if( !hdlr
->componentName
)
696 return LSMASH_ERR_MEMORY_ALLOC
;
697 for( uint32_t i
= 0; pos
< box
->size
; pos
= lsmash_bs_count( bs
) )
698 hdlr
->componentName
[i
++] = lsmash_bs_get_byte( bs
);
700 return isom_read_leaf_box_common_last_process( file
, box
, level
, hdlr
);
703 static int isom_read_minf( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
705 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MDIA
) || ((isom_mdia_t
*)parent
)->minf
)
706 return isom_read_unknown_box( file
, box
, parent
, level
);
707 ADD_BOX( minf
, isom_mdia_t
);
708 isom_box_common_copy( minf
, box
);
709 int ret
= isom_add_print_func( file
, minf
, level
);
712 return isom_read_children( file
, box
, minf
, level
);
715 static int isom_read_vmhd( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
717 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MINF
) || ((isom_minf_t
*)parent
)->vmhd
)
718 return isom_read_unknown_box( file
, box
, parent
, level
);
719 ADD_BOX( vmhd
, isom_minf_t
);
720 lsmash_bs_t
*bs
= file
->bs
;
721 vmhd
->graphicsmode
= lsmash_bs_get_be16( bs
);
722 for( int i
= 0; i
< 3; i
++ )
723 vmhd
->opcolor
[i
] = lsmash_bs_get_be16( bs
);
724 return isom_read_leaf_box_common_last_process( file
, box
, level
, vmhd
);
727 static int isom_read_smhd( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
729 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MINF
) || ((isom_minf_t
*)parent
)->smhd
)
730 return isom_read_unknown_box( file
, box
, parent
, level
);
731 ADD_BOX( smhd
, isom_minf_t
);
732 lsmash_bs_t
*bs
= file
->bs
;
733 smhd
->balance
= lsmash_bs_get_be16( bs
);
734 smhd
->reserved
= lsmash_bs_get_be16( bs
);
735 return isom_read_leaf_box_common_last_process( file
, box
, level
, smhd
);
738 static int isom_read_hmhd( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
740 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MINF
) || ((isom_minf_t
*)parent
)->hmhd
)
741 return isom_read_unknown_box( file
, box
, parent
, level
);
742 ADD_BOX( hmhd
, isom_minf_t
);
743 lsmash_bs_t
*bs
= file
->bs
;
744 hmhd
->maxPDUsize
= lsmash_bs_get_be16( bs
);
745 hmhd
->avgPDUsize
= lsmash_bs_get_be16( bs
);
746 hmhd
->maxbitrate
= lsmash_bs_get_be32( bs
);
747 hmhd
->avgbitrate
= lsmash_bs_get_be32( bs
);
748 hmhd
->reserved
= lsmash_bs_get_be32( bs
);
749 return isom_read_leaf_box_common_last_process( file
, box
, level
, hmhd
);
752 static int isom_read_nmhd( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
754 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MINF
) || ((isom_minf_t
*)parent
)->nmhd
)
755 return isom_read_unknown_box( file
, box
, parent
, level
);
756 ADD_BOX( nmhd
, isom_minf_t
);
757 return isom_read_leaf_box_common_last_process( file
, box
, level
, nmhd
);
760 static int isom_read_gmhd( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
762 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MINF
) || ((isom_minf_t
*)parent
)->gmhd
)
763 return isom_read_unknown_box( file
, box
, parent
, level
);
764 ADD_BOX( gmhd
, isom_minf_t
);
765 isom_box_common_copy( gmhd
, box
);
766 int ret
= isom_add_print_func( file
, gmhd
, level
);
769 return isom_read_children( file
, box
, gmhd
, level
);
772 static int isom_read_gmin( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
774 if( !lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_GMHD
) || ((isom_gmhd_t
*)parent
)->gmin
)
775 return isom_read_unknown_box( file
, box
, parent
, level
);
776 ADD_BOX( gmin
, isom_gmhd_t
);
777 lsmash_bs_t
*bs
= file
->bs
;
778 gmin
->graphicsmode
= lsmash_bs_get_be16( bs
);
779 for( int i
= 0; i
< 3; i
++ )
780 gmin
->opcolor
[i
] = lsmash_bs_get_be16( bs
);
781 gmin
->balance
= lsmash_bs_get_be16( bs
);
782 gmin
->reserved
= lsmash_bs_get_be16( bs
);
783 return isom_read_leaf_box_common_last_process( file
, box
, level
, gmin
);
786 static int isom_read_text( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
788 if( !lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_GMHD
) || ((isom_gmhd_t
*)parent
)->text
)
789 return isom_read_unknown_box( file
, box
, parent
, level
);
790 ADD_BOX( text
, isom_gmhd_t
);
791 lsmash_bs_t
*bs
= file
->bs
;
792 for( int i
= 0; i
< 9; i
++ )
793 text
->matrix
[i
] = lsmash_bs_get_be32( bs
);
794 return isom_read_leaf_box_common_last_process( file
, box
, level
, text
);
797 static int isom_read_dinf( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
799 if( (!lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MINF
)
800 && !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_META
)
801 && !lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_META
))
802 || (lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MINF
) && ((isom_minf_t
*)parent
)->dinf
)
803 || (lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_META
) && ((isom_meta_t
*)parent
)->dinf
)
804 || (lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_META
) && ((isom_meta_t
*)parent
)->dinf
) )
805 return isom_read_unknown_box( file
, box
, parent
, level
);
806 ADD_BOX( dinf
, void );
807 isom_box_common_copy( dinf
, box
);
808 int ret
= isom_add_print_func( file
, dinf
, level
);
811 return isom_read_children( file
, box
, dinf
, level
);
814 static int isom_read_dref( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
816 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_DINF
) || ((isom_dinf_t
*)parent
)->dref
)
817 return isom_read_unknown_box( file
, box
, parent
, level
);
818 ADD_BOX( dref
, isom_dinf_t
);
819 lsmash_bs_t
*bs
= file
->bs
;
820 dref
->list
.entry_count
= lsmash_bs_get_be32( bs
);
821 isom_box_common_copy( dref
, box
);
822 int ret
= isom_add_print_func( file
, dref
, level
);
825 return isom_read_children( file
, box
, dref
, level
);
828 static int isom_read_dref_entry( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
830 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_DREF
) )
831 return isom_read_unknown_box( file
, box
, parent
, level
);
832 isom_dref_t
*dref
= (isom_dref_t
*)parent
;
833 if( !dref
->list
.head
)
834 dref
->list
.entry_count
= 0; /* discard entry_count gotten from the file */
835 isom_dref_entry_t
*ref
= isom_add_dref_entry( dref
, box
->type
);
837 return LSMASH_ERR_NAMELESS
;
838 lsmash_bs_t
*bs
= file
->bs
;
839 if( lsmash_check_box_type_identical( ref
->type
, ISOM_BOX_TYPE_URL
) )
841 uint64_t pos
= lsmash_bs_count( bs
);
842 ref
->location_length
= box
->size
- pos
;
843 if( ref
->location_length
)
845 ref
->location
= lsmash_malloc( ref
->location_length
);
847 return LSMASH_ERR_MEMORY_ALLOC
;
848 for( uint32_t i
= 0; pos
< box
->size
; pos
= lsmash_bs_count( bs
) )
849 ref
->location
[i
++] = lsmash_bs_get_byte( bs
);
852 if( box
->flags
& 0x000001 )
853 ref
->ref_file
= ref
->file
;
854 box
->parent
= parent
;
855 return isom_read_leaf_box_common_last_process( file
, box
, level
, ref
);
858 static int isom_read_stbl( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
860 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MINF
) || ((isom_minf_t
*)parent
)->stbl
)
861 return isom_read_unknown_box( file
, box
, parent
, level
);
862 ADD_BOX( stbl
, isom_minf_t
);
863 isom_box_common_copy( stbl
, box
);
864 int ret
= isom_add_print_func( file
, stbl
, level
);
867 return isom_read_children( file
, box
, stbl
, level
);
870 static int isom_read_stsd( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
872 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STBL
) || ((isom_stbl_t
*)parent
)->stsd
)
873 return isom_read_unknown_box( file
, box
, parent
, level
);
874 ADD_BOX( stsd
, isom_stbl_t
);
875 lsmash_bs_t
*bs
= file
->bs
;
876 stsd
->entry_count
= lsmash_bs_get_be32( bs
);
877 isom_box_common_copy( stsd
, box
);
878 int ret
= isom_add_print_func( file
, stsd
, level
);
881 uint64_t stsd_pos
= lsmash_bs_count( bs
);
882 for( uint32_t i
= 0; i
< stsd
->entry_count
|| (stsd_pos
+ ISOM_BASEBOX_COMMON_SIZE
) <= stsd
->size
; i
++ )
884 if( (ret
= isom_read_box( file
, box
, (isom_box_t
*)stsd
, stsd_pos
, level
)) != 0 )
886 stsd_pos
+= box
->size
;
887 if( stsd
->size
<= stsd_pos
|| bs
->eob
|| bs
->error
)
890 if( stsd
->size
< stsd_pos
)
892 printf( "[stsd] box has extra bytes: %"PRId64
"\n", stsd_pos
- stsd
->size
);
893 stsd
->size
= stsd_pos
;
895 box
->size
= stsd
->size
;
899 static int isom_read_codec_specific( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
901 lsmash_bs_t
*bs
= file
->bs
;
902 uint64_t opaque_pos
= lsmash_bs_count( bs
);
903 uint64_t exdata_length
= box
->size
- opaque_pos
;
904 if( exdata_length
> UINT32_MAX
)
905 return LSMASH_ERR_MEMORY_ALLOC
;
906 uint8_t *exdata
= lsmash_malloc( box
->size
);
908 return LSMASH_ERR_MEMORY_ALLOC
;
909 int ret
= lsmash_bs_get_bytes_ex( bs
, exdata_length
, exdata
+ (uintptr_t)opaque_pos
);
912 LSMASH_SET_BE32( &exdata
[0], box
->size
);
913 LSMASH_SET_BE32( &exdata
[4], box
->type
.fourcc
);
915 if( box
->type
.fourcc
== ISOM_BOX_TYPE_UUID
.fourcc
)
917 LSMASH_SET_BE32( &exdata
[8], box
->type
.user
.fourcc
);
918 memcpy( &exdata
[12], box
->type
.user
.id
, 12 );
921 if( box
->manager
& LSMASH_FULLBOX
)
923 LSMASH_SET_BYTE( &exdata
[i
], box
->version
);
925 LSMASH_SET_BE24( &exdata
[i
], box
->flags
);
928 if( i
!= opaque_pos
)
930 ret
= LSMASH_ERR_INVALID_DATA
;
933 if( (ret
= isom_add_extension_binary( parent
, box
->type
, LSMASH_BOX_PRECEDENCE_N
, exdata
, box
->size
)) < 0 )
935 isom_box_t
*ext
= (isom_box_t
*)parent
->extensions
.tail
->data
;
936 box
->manager
|= ext
->manager
;
937 isom_validate_box_size( file
->bs
, box
);
938 isom_basebox_common_copy( ext
, box
);
939 return isom_add_print_func( file
, ext
, level
);
941 lsmash_free( exdata
);
945 static void *isom_sample_description_alloc( lsmash_codec_type_t sample_type
, isom_stsd_t
*stsd
)
947 assert( isom_check_media_hdlr_from_stsd( stsd
) );
948 /* Determine suitable allocation size. */
949 size_t alloc_size
= 0;
950 lsmash_media_type media_type
= ((isom_mdia_t
*)stsd
->parent
->parent
->parent
)->hdlr
->componentSubtype
;
951 if( media_type
== ISOM_MEDIA_HANDLER_TYPE_VIDEO_TRACK
)
952 alloc_size
= sizeof(isom_visual_entry_t
);
953 else if( media_type
== ISOM_MEDIA_HANDLER_TYPE_AUDIO_TRACK
)
954 alloc_size
= sizeof(isom_audio_entry_t
);
955 else if( media_type
== ISOM_MEDIA_HANDLER_TYPE_TEXT_TRACK
)
957 if( lsmash_check_codec_type_identical( sample_type
, ISOM_CODEC_TYPE_TX3G_TEXT
) )
958 alloc_size
= sizeof(isom_tx3g_entry_t
);
959 else if( lsmash_check_codec_type_identical( sample_type
, QT_CODEC_TYPE_TEXT_TEXT
) )
960 alloc_size
= sizeof(isom_qt_text_entry_t
);
962 else if( lsmash_check_codec_type_identical( sample_type
, ISOM_CODEC_TYPE_MP4S_SYSTEM
) )
963 alloc_size
= sizeof(isom_mp4s_entry_t
);
964 /* Return allocated memory block if the allocation size is non-zero. */
965 if( alloc_size
== 0 )
967 return lsmash_malloc_zero( alloc_size
);
970 static void *isom_add_description( lsmash_codec_type_t sample_type
, isom_stsd_t
*stsd
)
972 void *sample
= isom_sample_description_alloc( sample_type
, stsd
);
975 if( lsmash_add_entry( &stsd
->list
, sample
) < 0 )
977 lsmash_free( sample
);
980 if( lsmash_add_entry( &stsd
->extensions
, sample
) < 0 )
982 lsmash_remove_entry_tail( &stsd
->list
, lsmash_free
);
985 ((isom_box_t
*)sample
)->destruct
= (isom_extension_destructor_t
)isom_remove_sample_description
;
989 static int isom_read_visual_description( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
991 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STSD
) )
992 return isom_read_unknown_box( file
, box
, parent
, level
);
993 isom_visual_entry_t
*visual
= (isom_visual_entry_t
*)isom_add_description( box
->type
, (isom_stsd_t
*)parent
);
995 return LSMASH_ERR_MEMORY_ALLOC
;
996 lsmash_bs_t
*bs
= file
->bs
;
997 for( int i
= 0; i
< 6; i
++ )
998 visual
->reserved
[i
] = lsmash_bs_get_byte( bs
);
999 visual
->data_reference_index
= lsmash_bs_get_be16( bs
);
1000 visual
->version
= lsmash_bs_get_be16( bs
);
1001 visual
->revision_level
= lsmash_bs_get_be16( bs
);
1002 visual
->vendor
= lsmash_bs_get_be32( bs
);
1003 visual
->temporalQuality
= lsmash_bs_get_be32( bs
);
1004 visual
->spatialQuality
= lsmash_bs_get_be32( bs
);
1005 visual
->width
= lsmash_bs_get_be16( bs
);
1006 visual
->height
= lsmash_bs_get_be16( bs
);
1007 visual
->horizresolution
= lsmash_bs_get_be32( bs
);
1008 visual
->vertresolution
= lsmash_bs_get_be32( bs
);
1009 visual
->dataSize
= lsmash_bs_get_be32( bs
);
1010 visual
->frame_count
= lsmash_bs_get_be16( bs
);
1011 for( int i
= 0; i
< 32; i
++ )
1012 visual
->compressorname
[i
] = lsmash_bs_get_byte( bs
);
1013 visual
->depth
= lsmash_bs_get_be16( bs
);
1014 visual
->color_table_ID
= lsmash_bs_get_be16( bs
);
1016 if( visual
->color_table_ID
== 0
1017 && lsmash_bs_get_pos( bs
) < box
->size
1018 && (ret
= isom_read_qt_color_table( bs
, &visual
->color_table
)) < 0 )
1020 box
->parent
= parent
;
1021 box
->manager
|= LSMASH_VIDEO_DESCRIPTION
;
1022 isom_box_common_copy( visual
, box
);
1023 if( (ret
= isom_add_print_func( file
, visual
, level
)) < 0 )
1025 return isom_read_children( file
, box
, visual
, level
);
1028 static int isom_read_esds( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1030 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_CODEC_TYPE_MP4V_VIDEO
)
1031 && !lsmash_check_box_type_identical( parent
->type
, ISOM_CODEC_TYPE_MP4A_AUDIO
)
1032 && !lsmash_check_box_type_identical( parent
->type
, ISOM_CODEC_TYPE_ENCA_AUDIO
)
1033 && !lsmash_check_box_type_identical( parent
->type
, ISOM_CODEC_TYPE_M4AE_AUDIO
)
1034 && !lsmash_check_box_type_identical( parent
->type
, ISOM_CODEC_TYPE_MP4S_SYSTEM
)
1035 && !lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_WAVE
) )
1036 return isom_read_unknown_box( file
, box
, parent
, level
);
1037 if( lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_WAVE
) )
1039 box
->type
= QT_BOX_TYPE_ESDS
;
1040 if( parent
->parent
&& lsmash_check_box_type_identical( parent
->parent
->type
, ISOM_CODEC_TYPE_MP4A_AUDIO
) )
1041 parent
->parent
->type
= QT_CODEC_TYPE_MP4A_AUDIO
;
1044 box
->type
= ISOM_BOX_TYPE_ESDS
;
1045 ADD_BOX( esds
, void );
1046 lsmash_bs_t
*bs
= file
->bs
;
1047 esds
->ES
= mp4sys_get_descriptor( bs
, NULL
);
1049 return LSMASH_ERR_INVALID_DATA
;
1050 return isom_read_leaf_box_common_last_process( file
, box
, level
, esds
);
1053 static int isom_read_btrt( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1055 ADD_BOX( btrt
, isom_visual_entry_t
);
1056 lsmash_bs_t
*bs
= file
->bs
;
1057 btrt
->bufferSizeDB
= lsmash_bs_get_be32( bs
);
1058 btrt
->maxBitrate
= lsmash_bs_get_be32( bs
);
1059 btrt
->avgBitrate
= lsmash_bs_get_be32( bs
);
1060 return isom_read_leaf_box_common_last_process( file
, box
, level
, btrt
);
1063 static int isom_read_glbl( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1065 ADD_BOX( glbl
, isom_visual_entry_t
);
1066 lsmash_bs_t
*bs
= file
->bs
;
1067 uint32_t header_size
= box
->size
- ISOM_BASEBOX_COMMON_SIZE
;
1070 glbl
->header_data
= lsmash_malloc( header_size
);
1071 if( !glbl
->header_data
)
1072 return LSMASH_ERR_MEMORY_ALLOC
;
1073 for( uint32_t i
= 0; i
< header_size
; i
++ )
1074 glbl
->header_data
[i
] = lsmash_bs_get_byte( bs
);
1076 glbl
->header_size
= header_size
;
1077 return isom_read_leaf_box_common_last_process( file
, box
, level
, glbl
);
1080 static int isom_read_clap( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1082 ADD_BOX( clap
, isom_visual_entry_t
);
1083 lsmash_bs_t
*bs
= file
->bs
;
1084 clap
->cleanApertureWidthN
= lsmash_bs_get_be32( bs
);
1085 clap
->cleanApertureWidthD
= lsmash_bs_get_be32( bs
);
1086 clap
->cleanApertureHeightN
= lsmash_bs_get_be32( bs
);
1087 clap
->cleanApertureHeightD
= lsmash_bs_get_be32( bs
);
1088 clap
->horizOffN
= lsmash_bs_get_be32( bs
);
1089 clap
->horizOffD
= lsmash_bs_get_be32( bs
);
1090 clap
->vertOffN
= lsmash_bs_get_be32( bs
);
1091 clap
->vertOffD
= lsmash_bs_get_be32( bs
);
1092 return isom_read_leaf_box_common_last_process( file
, box
, level
, clap
);
1095 static int isom_read_pasp( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1097 ADD_BOX( pasp
, isom_visual_entry_t
);
1098 lsmash_bs_t
*bs
= file
->bs
;
1099 pasp
->hSpacing
= lsmash_bs_get_be32( bs
);
1100 pasp
->vSpacing
= lsmash_bs_get_be32( bs
);
1101 return isom_read_leaf_box_common_last_process( file
, box
, level
, pasp
);
1104 static int isom_read_colr( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1106 ADD_BOX( colr
, isom_visual_entry_t
);
1107 lsmash_bs_t
*bs
= file
->bs
;
1108 colr
->color_parameter_type
= lsmash_bs_get_be32( bs
);
1109 if( colr
->color_parameter_type
== QT_COLOR_PARAMETER_TYPE_NCLC
1110 || colr
->color_parameter_type
== ISOM_COLOR_PARAMETER_TYPE_NCLX
)
1112 colr
->primaries_index
= lsmash_bs_get_be16( bs
);
1113 colr
->transfer_function_index
= lsmash_bs_get_be16( bs
);
1114 colr
->matrix_index
= lsmash_bs_get_be16( bs
);
1115 if( colr
->color_parameter_type
== ISOM_COLOR_PARAMETER_TYPE_NCLX
)
1117 if( lsmash_bs_count( bs
) < box
->size
)
1119 uint8_t temp8
= lsmash_bs_get_byte( bs
);
1120 colr
->full_range_flag
= (temp8
>> 7) & 0x01;
1121 colr
->reserved
= temp8
& 0x7f;
1125 /* It seems this box is broken or incomplete. */
1126 box
->manager
|= LSMASH_INCOMPLETE_BOX
;
1127 colr
->full_range_flag
= 0;
1132 box
->manager
|= LSMASH_QTFF_BASE
;
1134 box
->type
= (box
->manager
& LSMASH_QTFF_BASE
) ? QT_BOX_TYPE_COLR
: ISOM_BOX_TYPE_COLR
;
1135 return isom_read_leaf_box_common_last_process( file
, box
, level
, colr
);
1138 static int isom_read_gama( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1140 ADD_BOX( gama
, isom_visual_entry_t
);
1141 lsmash_bs_t
*bs
= file
->bs
;
1142 gama
->level
= lsmash_bs_get_be32( bs
);
1143 return isom_read_leaf_box_common_last_process( file
, box
, level
, gama
);
1146 static int isom_read_fiel( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1148 ADD_BOX( fiel
, isom_visual_entry_t
);
1149 lsmash_bs_t
*bs
= file
->bs
;
1150 fiel
->fields
= lsmash_bs_get_byte( bs
);
1151 fiel
->detail
= lsmash_bs_get_byte( bs
);
1152 return isom_read_leaf_box_common_last_process( file
, box
, level
, fiel
);
1155 static int isom_read_cspc( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1157 ADD_BOX( cspc
, isom_visual_entry_t
);
1158 lsmash_bs_t
*bs
= file
->bs
;
1159 cspc
->pixel_format
= lsmash_bs_get_be32( bs
);
1160 return isom_read_leaf_box_common_last_process( file
, box
, level
, cspc
);
1163 static int isom_read_sgbt( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1165 ADD_BOX( sgbt
, isom_visual_entry_t
);
1166 lsmash_bs_t
*bs
= file
->bs
;
1167 sgbt
->significantBits
= lsmash_bs_get_byte( bs
);
1168 return isom_read_leaf_box_common_last_process( file
, box
, level
, sgbt
);
1171 static int isom_read_stsl( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1173 ADD_BOX( stsl
, isom_visual_entry_t
);
1174 lsmash_bs_t
*bs
= file
->bs
;
1175 stsl
->constraint_flag
= lsmash_bs_get_byte( bs
);
1176 stsl
->scale_method
= lsmash_bs_get_byte( bs
);
1177 stsl
->display_center_x
= lsmash_bs_get_be16( bs
);
1178 stsl
->display_center_y
= lsmash_bs_get_be16( bs
);
1179 return isom_read_leaf_box_common_last_process( file
, box
, level
, stsl
);
1182 static int isom_read_audio_description( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1184 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STSD
) )
1185 return isom_read_unknown_box( file
, box
, parent
, level
);
1186 isom_audio_entry_t
*audio
= (isom_audio_entry_t
*)isom_add_description( box
->type
, (isom_stsd_t
*)parent
);
1188 return LSMASH_ERR_MEMORY_ALLOC
;
1189 lsmash_bs_t
*bs
= file
->bs
;
1190 for( int i
= 0; i
< 6; i
++ )
1191 audio
->reserved
[i
] = lsmash_bs_get_byte( bs
);
1192 audio
->data_reference_index
= lsmash_bs_get_be16( bs
);
1193 audio
->version
= lsmash_bs_get_be16( bs
);
1194 audio
->revision_level
= lsmash_bs_get_be16( bs
);
1195 audio
->vendor
= lsmash_bs_get_be32( bs
);
1196 audio
->channelcount
= lsmash_bs_get_be16( bs
);
1197 audio
->samplesize
= lsmash_bs_get_be16( bs
);
1198 audio
->compression_ID
= lsmash_bs_get_be16( bs
);
1199 audio
->packet_size
= lsmash_bs_get_be16( bs
);
1200 audio
->samplerate
= lsmash_bs_get_be32( bs
);
1201 if( audio
->version
== 0 && isom_is_qt_audio( box
->type
) )
1203 /* Skip weird extra bytes.
1204 * About QTFF, extensions were first added with Sound Sample Description v1. */
1205 while( lsmash_bs_count( bs
) + ISOM_BASEBOX_COMMON_SIZE
<= box
->size
)
1207 uint32_t size
= lsmash_bs_show_be32( bs
, 0 );
1208 if( size
== 0 || lsmash_bs_count( bs
) + size
> box
->size
)
1209 lsmash_bs_skip_bytes( bs
, 1 );
1214 else if( audio
->version
== 1 )
1216 if( ((isom_stsd_t
*)parent
)->version
== 0 )
1218 audio
->samplesPerPacket
= lsmash_bs_get_be32( bs
);
1219 audio
->bytesPerPacket
= lsmash_bs_get_be32( bs
);
1220 audio
->bytesPerFrame
= lsmash_bs_get_be32( bs
);
1221 audio
->bytesPerSample
= lsmash_bs_get_be32( bs
);
1222 box
->manager
|= LSMASH_QTFF_BASE
;
1225 /* AudioSampleEntryV1 has no additional fields. */
1226 box
->manager
&= ~LSMASH_QTFF_BASE
;
1228 else if( audio
->version
== 2 )
1230 audio
->sizeOfStructOnly
= lsmash_bs_get_be32( bs
);
1231 audio
->audioSampleRate
= lsmash_bs_get_be64( bs
);
1232 audio
->numAudioChannels
= lsmash_bs_get_be32( bs
);
1233 audio
->always7F000000
= lsmash_bs_get_be32( bs
);
1234 audio
->constBitsPerChannel
= lsmash_bs_get_be32( bs
);
1235 audio
->formatSpecificFlags
= lsmash_bs_get_be32( bs
);
1236 audio
->constBytesPerAudioPacket
= lsmash_bs_get_be32( bs
);
1237 audio
->constLPCMFramesPerAudioPacket
= lsmash_bs_get_be32( bs
);
1238 box
->manager
|= LSMASH_QTFF_BASE
;
1240 box
->parent
= parent
;
1241 box
->manager
|= LSMASH_AUDIO_DESCRIPTION
;
1242 isom_box_common_copy( audio
, box
);
1243 int ret
= isom_add_print_func( file
, audio
, level
);
1246 return isom_read_children( file
, box
, audio
, level
);
1249 static int isom_read_wave( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1251 ADD_BOX( wave
, isom_audio_entry_t
);
1252 isom_box_common_copy( wave
, box
);
1253 int ret
= isom_add_print_func( file
, wave
, level
);
1256 return isom_read_children( file
, box
, wave
, level
);
1259 static int isom_read_frma( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1261 if( !lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_WAVE
) || ((isom_wave_t
*)parent
)->frma
)
1262 return isom_read_unknown_box( file
, box
, parent
, level
);
1263 ADD_BOX( frma
, isom_wave_t
);
1264 lsmash_bs_t
*bs
= file
->bs
;
1265 frma
->data_format
= lsmash_bs_get_be32( bs
);
1266 return isom_read_leaf_box_common_last_process( file
, box
, level
, frma
);
1269 static int isom_read_enda( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1271 if( !lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_WAVE
) || ((isom_wave_t
*)parent
)->enda
)
1272 return isom_read_unknown_box( file
, box
, parent
, level
);
1273 ADD_BOX( enda
, isom_wave_t
);
1274 lsmash_bs_t
*bs
= file
->bs
;
1275 enda
->littleEndian
= lsmash_bs_get_be16( bs
);
1276 return isom_read_leaf_box_common_last_process( file
, box
, level
, enda
);
1279 static int isom_read_terminator( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1281 if( !lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_WAVE
) || ((isom_wave_t
*)parent
)->terminator
)
1282 return isom_read_unknown_box( file
, box
, parent
, level
);
1283 ADD_BOX( terminator
, isom_wave_t
);
1284 return isom_read_leaf_box_common_last_process( file
, box
, level
, terminator
);
1287 static int isom_read_chan( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1289 ADD_BOX( chan
, isom_audio_entry_t
);
1290 lsmash_bs_t
*bs
= file
->bs
;
1291 chan
->channelLayoutTag
= lsmash_bs_get_be32( bs
);
1292 chan
->channelBitmap
= lsmash_bs_get_be32( bs
);
1293 chan
->numberChannelDescriptions
= lsmash_bs_get_be32( bs
);
1294 if( chan
->numberChannelDescriptions
)
1296 isom_channel_description_t
*desc
= lsmash_malloc( chan
->numberChannelDescriptions
* sizeof(isom_channel_description_t
) );
1298 return LSMASH_ERR_MEMORY_ALLOC
;
1299 chan
->channelDescriptions
= desc
;
1300 for( uint32_t i
= 0; i
< chan
->numberChannelDescriptions
; i
++ )
1302 desc
->channelLabel
= lsmash_bs_get_be32( bs
);
1303 desc
->channelFlags
= lsmash_bs_get_be32( bs
);
1304 for( int j
= 0; j
< 3; j
++ )
1305 desc
->coordinates
[j
] = lsmash_bs_get_be32( bs
);
1308 return isom_read_leaf_box_common_last_process( file
, box
, level
, chan
);
1311 static int isom_read_srat( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1313 ADD_BOX( srat
, isom_audio_entry_t
);
1314 lsmash_bs_t
*bs
= file
->bs
;
1315 srat
->sampling_rate
= lsmash_bs_get_be32( bs
);
1316 return isom_read_leaf_box_common_last_process( file
, box
, level
, srat
);
1319 static int isom_read_qt_text_description( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1321 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STSD
) )
1322 return isom_read_unknown_box( file
, box
, parent
, level
);
1323 isom_qt_text_entry_t
*text
= (isom_qt_text_entry_t
*)isom_add_description( box
->type
, (isom_stsd_t
*)parent
);
1325 return LSMASH_ERR_MEMORY_ALLOC
;
1326 lsmash_bs_t
*bs
= file
->bs
;
1327 for( int i
= 0; i
< 6; i
++ )
1328 text
->reserved
[i
] = lsmash_bs_get_byte( bs
);
1329 text
->data_reference_index
= lsmash_bs_get_be16( bs
);
1330 text
->displayFlags
= lsmash_bs_get_be32( bs
);
1331 text
->textJustification
= lsmash_bs_get_be32( bs
);
1332 for( int i
= 0; i
< 3; i
++ )
1333 text
->bgColor
[i
] = lsmash_bs_get_be16( bs
);
1334 text
->top
= lsmash_bs_get_be16( bs
);
1335 text
->left
= lsmash_bs_get_be16( bs
);
1336 text
->bottom
= lsmash_bs_get_be16( bs
);
1337 text
->right
= lsmash_bs_get_be16( bs
);
1338 text
->scrpStartChar
= lsmash_bs_get_be32( bs
);
1339 text
->scrpHeight
= lsmash_bs_get_be16( bs
);
1340 text
->scrpAscent
= lsmash_bs_get_be16( bs
);
1341 text
->scrpFont
= lsmash_bs_get_be16( bs
);
1342 text
->scrpFace
= lsmash_bs_get_be16( bs
);
1343 text
->scrpSize
= lsmash_bs_get_be16( bs
);
1344 for( int i
= 0; i
< 3; i
++ )
1345 text
->scrpColor
[i
] = lsmash_bs_get_be16( bs
);
1346 text
->font_name_length
= lsmash_bs_get_byte( bs
);
1347 if( text
->font_name_length
)
1349 text
->font_name
= lsmash_malloc( text
->font_name_length
+ 1 );
1350 if( !text
->font_name
)
1351 return LSMASH_ERR_MEMORY_ALLOC
;
1352 for( uint8_t i
= 0; i
< text
->font_name_length
; i
++ )
1353 text
->font_name
[i
] = lsmash_bs_get_byte( bs
);
1354 text
->font_name
[text
->font_name_length
] = '\0';
1356 box
->parent
= parent
;
1357 isom_box_common_copy( text
, box
);
1358 int ret
= isom_add_print_func( file
, text
, level
);
1361 return isom_read_children( file
, box
, text
, level
);
1364 static int isom_read_tx3g_description( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1366 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STSD
) )
1367 return isom_read_unknown_box( file
, box
, parent
, level
);
1368 isom_tx3g_entry_t
*tx3g
= (isom_tx3g_entry_t
*)isom_add_description( box
->type
, (isom_stsd_t
*)parent
);
1370 return LSMASH_ERR_MEMORY_ALLOC
;
1371 lsmash_bs_t
*bs
= file
->bs
;
1372 for( int i
= 0; i
< 6; i
++ )
1373 tx3g
->reserved
[i
] = lsmash_bs_get_byte( bs
);
1374 tx3g
->data_reference_index
= lsmash_bs_get_be16( bs
);
1375 tx3g
->displayFlags
= lsmash_bs_get_be32( bs
);
1376 tx3g
->horizontal_justification
= lsmash_bs_get_byte( bs
);
1377 tx3g
->vertical_justification
= lsmash_bs_get_byte( bs
);
1378 for( int i
= 0; i
< 4; i
++ )
1379 tx3g
->background_color_rgba
[i
] = lsmash_bs_get_byte( bs
);
1380 tx3g
->top
= lsmash_bs_get_be16( bs
);
1381 tx3g
->left
= lsmash_bs_get_be16( bs
);
1382 tx3g
->bottom
= lsmash_bs_get_be16( bs
);
1383 tx3g
->right
= lsmash_bs_get_be16( bs
);
1384 tx3g
->startChar
= lsmash_bs_get_be16( bs
);
1385 tx3g
->endChar
= lsmash_bs_get_be16( bs
);
1386 tx3g
->font_ID
= lsmash_bs_get_be16( bs
);
1387 tx3g
->face_style_flags
= lsmash_bs_get_byte( bs
);
1388 tx3g
->font_size
= lsmash_bs_get_byte( bs
);
1389 for( int i
= 0; i
< 4; i
++ )
1390 tx3g
->text_color_rgba
[i
] = lsmash_bs_get_byte( bs
);
1391 box
->parent
= parent
;
1392 isom_box_common_copy( tx3g
, box
);
1393 int ret
= isom_add_print_func( file
, tx3g
, level
);
1396 return isom_read_children( file
, box
, tx3g
, level
);
1399 static int isom_read_text_description( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1401 if( lsmash_check_codec_type_identical( box
->type
, QT_CODEC_TYPE_TEXT_TEXT
) )
1402 return isom_read_qt_text_description( file
, box
, parent
, level
);
1403 else if( lsmash_check_codec_type_identical( box
->type
, ISOM_CODEC_TYPE_TX3G_TEXT
) )
1404 return isom_read_tx3g_description( file
, box
, parent
, level
);
1406 return isom_read_unknown_box( file
, box
, parent
, level
);
1409 static int isom_read_ftab( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1411 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_CODEC_TYPE_TX3G_TEXT
)
1412 || ((isom_tx3g_entry_t
*)parent
)->ftab
)
1413 return isom_read_unknown_box( file
, box
, parent
, level
);
1414 ADD_BOX( ftab
, isom_tx3g_entry_t
);
1415 lsmash_bs_t
*bs
= file
->bs
;
1416 uint32_t entry_count
= lsmash_bs_get_be16( bs
);
1417 for( uint64_t pos
= lsmash_bs_count( bs
); pos
< box
->size
&& ftab
->list
->entry_count
< entry_count
; pos
= lsmash_bs_count( bs
) )
1419 isom_font_record_t
*data
= lsmash_malloc_zero( sizeof(isom_font_record_t
) );
1421 return LSMASH_ERR_MEMORY_ALLOC
;
1422 if( lsmash_add_entry( ftab
->list
, data
) < 0 )
1424 lsmash_free( data
);
1425 return LSMASH_ERR_MEMORY_ALLOC
;
1427 data
->font_ID
= lsmash_bs_get_be16( bs
);
1428 data
->font_name_length
= lsmash_bs_get_byte( bs
);
1429 if( data
->font_name_length
)
1431 data
->font_name
= lsmash_malloc( data
->font_name_length
+ 1 );
1432 if( !data
->font_name
)
1433 return LSMASH_ERR_MEMORY_ALLOC
;
1434 for( uint8_t i
= 0; i
< data
->font_name_length
; i
++ )
1435 data
->font_name
[i
] = lsmash_bs_get_byte( bs
);
1436 data
->font_name
[data
->font_name_length
] = '\0';
1439 return isom_read_leaf_box_common_last_process( file
, box
, level
, ftab
);
1442 static int isom_read_mp4s_description( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1444 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STSD
) )
1445 return isom_read_unknown_box( file
, box
, parent
, level
);
1446 isom_mp4s_entry_t
*mp4s
= (isom_mp4s_entry_t
*)isom_add_description( box
->type
, (isom_stsd_t
*)parent
);
1448 return LSMASH_ERR_MEMORY_ALLOC
;
1449 lsmash_bs_t
*bs
= file
->bs
;
1450 for( int i
= 0; i
< 6; i
++ )
1451 mp4s
->reserved
[i
] = lsmash_bs_get_byte( bs
);
1452 mp4s
->data_reference_index
= lsmash_bs_get_be16( bs
);
1453 box
->parent
= parent
;
1454 isom_box_common_copy( mp4s
, box
);
1455 int ret
= isom_add_print_func( file
, mp4s
, level
);
1458 return isom_read_children( file
, box
, mp4s
, level
);
1461 static int isom_read_other_description( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1463 if( lsmash_check_codec_type_identical( box
->type
, ISOM_CODEC_TYPE_MP4S_SYSTEM
) )
1464 return isom_read_mp4s_description( file
, box
, parent
, level
);
1465 return isom_read_unknown_box( file
, box
, parent
, level
);
1468 static int isom_read_stts( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1470 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STBL
) || ((isom_stbl_t
*)parent
)->stts
)
1471 return isom_read_unknown_box( file
, box
, parent
, level
);
1472 ADD_BOX( stts
, isom_stbl_t
);
1473 lsmash_bs_t
*bs
= file
->bs
;
1474 uint32_t entry_count
= lsmash_bs_get_be32( bs
);
1475 for( uint64_t pos
= lsmash_bs_count( bs
); pos
< box
->size
&& stts
->list
->entry_count
< entry_count
; pos
= lsmash_bs_count( bs
) )
1477 isom_stts_entry_t
*data
= lsmash_malloc( sizeof(isom_stts_entry_t
) );
1479 return LSMASH_ERR_MEMORY_ALLOC
;
1480 if( lsmash_add_entry( stts
->list
, data
) < 0 )
1482 lsmash_free( data
);
1483 return LSMASH_ERR_MEMORY_ALLOC
;
1485 data
->sample_count
= lsmash_bs_get_be32( bs
);
1486 data
->sample_delta
= lsmash_bs_get_be32( bs
);
1488 return isom_read_leaf_box_common_last_process( file
, box
, level
, stts
);
1491 static int isom_read_ctts( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1493 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STBL
) || ((isom_stbl_t
*)parent
)->ctts
)
1494 return isom_read_unknown_box( file
, box
, parent
, level
);
1495 ADD_BOX( ctts
, isom_stbl_t
);
1496 lsmash_bs_t
*bs
= file
->bs
;
1497 uint32_t entry_count
= lsmash_bs_get_be32( bs
);
1498 for( uint64_t pos
= lsmash_bs_count( bs
); pos
< box
->size
&& ctts
->list
->entry_count
< entry_count
; pos
= lsmash_bs_count( bs
) )
1500 isom_ctts_entry_t
*data
= lsmash_malloc( sizeof(isom_ctts_entry_t
) );
1502 return LSMASH_ERR_MEMORY_ALLOC
;
1503 if( lsmash_add_entry( ctts
->list
, data
) < 0 )
1505 lsmash_free( data
);
1506 return LSMASH_ERR_MEMORY_ALLOC
;
1508 data
->sample_count
= lsmash_bs_get_be32( bs
);
1509 data
->sample_offset
= lsmash_bs_get_be32( bs
);
1511 return isom_read_leaf_box_common_last_process( file
, box
, level
, ctts
);
1514 static int isom_read_cslg( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1516 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STBL
) || ((isom_stbl_t
*)parent
)->cslg
)
1517 return isom_read_unknown_box( file
, box
, parent
, level
);
1518 ADD_BOX( cslg
, isom_stbl_t
);
1519 lsmash_bs_t
*bs
= file
->bs
;
1520 cslg
->compositionToDTSShift
= lsmash_bs_get_be32( bs
);
1521 cslg
->leastDecodeToDisplayDelta
= lsmash_bs_get_be32( bs
);
1522 cslg
->greatestDecodeToDisplayDelta
= lsmash_bs_get_be32( bs
);
1523 cslg
->compositionStartTime
= lsmash_bs_get_be32( bs
);
1524 cslg
->compositionEndTime
= lsmash_bs_get_be32( bs
);
1525 return isom_read_leaf_box_common_last_process( file
, box
, level
, cslg
);
1528 static int isom_read_stss( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1530 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STBL
) || ((isom_stbl_t
*)parent
)->stss
)
1531 return isom_read_unknown_box( file
, box
, parent
, level
);
1532 ADD_BOX( stss
, isom_stbl_t
);
1533 lsmash_bs_t
*bs
= file
->bs
;
1534 uint32_t entry_count
= lsmash_bs_get_be32( bs
);
1535 for( uint64_t pos
= lsmash_bs_count( bs
); pos
< box
->size
&& stss
->list
->entry_count
< entry_count
; pos
= lsmash_bs_count( bs
) )
1537 isom_stss_entry_t
*data
= lsmash_malloc( sizeof(isom_stss_entry_t
) );
1539 return LSMASH_ERR_MEMORY_ALLOC
;
1540 if( lsmash_add_entry( stss
->list
, data
) < 0 )
1542 lsmash_free( data
);
1543 return LSMASH_ERR_MEMORY_ALLOC
;
1545 data
->sample_number
= lsmash_bs_get_be32( bs
);
1547 return isom_read_leaf_box_common_last_process( file
, box
, level
, stss
);
1550 static int isom_read_stps( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1552 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STBL
) || ((isom_stbl_t
*)parent
)->stps
)
1553 return isom_read_unknown_box( file
, box
, parent
, level
);
1554 ADD_BOX( stps
, isom_stbl_t
);
1555 lsmash_bs_t
*bs
= file
->bs
;
1556 uint32_t entry_count
= lsmash_bs_get_be32( bs
);
1557 for( uint64_t pos
= lsmash_bs_count( bs
); pos
< box
->size
&& stps
->list
->entry_count
< entry_count
; pos
= lsmash_bs_count( bs
) )
1559 isom_stps_entry_t
*data
= lsmash_malloc( sizeof(isom_stps_entry_t
) );
1561 return LSMASH_ERR_MEMORY_ALLOC
;
1562 if( lsmash_add_entry( stps
->list
, data
) < 0 )
1564 lsmash_free( data
);
1565 return LSMASH_ERR_MEMORY_ALLOC
;
1567 data
->sample_number
= lsmash_bs_get_be32( bs
);
1569 return isom_read_leaf_box_common_last_process( file
, box
, level
, stps
);
1572 static int isom_read_sdtp( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1574 if( (!lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STBL
)
1575 && !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TRAF
))
1576 || (lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STBL
) && ((isom_stbl_t
*)parent
)->sdtp
)
1577 || (lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TRAF
) && ((isom_traf_t
*)parent
)->sdtp
))
1578 return isom_read_unknown_box( file
, box
, parent
, level
);
1579 ADD_BOX( sdtp
, isom_box_t
);
1580 lsmash_bs_t
*bs
= file
->bs
;
1581 for( uint64_t pos
= lsmash_bs_count( bs
); pos
< box
->size
; pos
= lsmash_bs_count( bs
) )
1583 isom_sdtp_entry_t
*data
= lsmash_malloc( sizeof(isom_sdtp_entry_t
) );
1585 return LSMASH_ERR_MEMORY_ALLOC
;
1586 if( lsmash_add_entry( sdtp
->list
, data
) < 0 )
1588 lsmash_free( data
);
1589 return LSMASH_ERR_MEMORY_ALLOC
;
1591 uint8_t temp
= lsmash_bs_get_byte( bs
);
1592 data
->is_leading
= (temp
>> 6) & 0x3;
1593 data
->sample_depends_on
= (temp
>> 4) & 0x3;
1594 data
->sample_is_depended_on
= (temp
>> 2) & 0x3;
1595 data
->sample_has_redundancy
= temp
& 0x3;
1597 return isom_read_leaf_box_common_last_process( file
, box
, level
, sdtp
);
1600 static int isom_read_stsc( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1602 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STBL
) || ((isom_stbl_t
*)parent
)->stsc
)
1603 return isom_read_unknown_box( file
, box
, parent
, level
);
1604 ADD_BOX( stsc
, isom_stbl_t
);
1605 lsmash_bs_t
*bs
= file
->bs
;
1606 uint32_t entry_count
= lsmash_bs_get_be32( bs
);
1607 for( uint64_t pos
= lsmash_bs_count( bs
); pos
< box
->size
&& stsc
->list
->entry_count
< entry_count
; pos
= lsmash_bs_count( bs
) )
1609 isom_stsc_entry_t
*data
= lsmash_malloc( sizeof(isom_stsc_entry_t
) );
1611 return LSMASH_ERR_MEMORY_ALLOC
;
1612 if( lsmash_add_entry( stsc
->list
, data
) < 0 )
1614 lsmash_free( data
);
1615 return LSMASH_ERR_MEMORY_ALLOC
;
1617 data
->first_chunk
= lsmash_bs_get_be32( bs
);
1618 data
->samples_per_chunk
= lsmash_bs_get_be32( bs
);
1619 data
->sample_description_index
= lsmash_bs_get_be32( bs
);
1621 return isom_read_leaf_box_common_last_process( file
, box
, level
, stsc
);
1624 static int isom_read_stsz( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1626 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STBL
) || ((isom_stbl_t
*)parent
)->stsz
)
1627 return isom_read_unknown_box( file
, box
, parent
, level
);
1628 ADD_BOX( stsz
, isom_stbl_t
);
1629 lsmash_bs_t
*bs
= file
->bs
;
1630 stsz
->sample_size
= lsmash_bs_get_be32( bs
);
1631 stsz
->sample_count
= lsmash_bs_get_be32( bs
);
1632 uint64_t pos
= lsmash_bs_count( bs
);
1633 if( pos
< box
->size
)
1635 stsz
->list
= lsmash_create_entry_list();
1637 return LSMASH_ERR_MEMORY_ALLOC
;
1638 for( ; pos
< box
->size
&& stsz
->list
->entry_count
< stsz
->sample_count
; pos
= lsmash_bs_count( bs
) )
1640 isom_stsz_entry_t
*data
= lsmash_malloc( sizeof(isom_stsz_entry_t
) );
1642 return LSMASH_ERR_MEMORY_ALLOC
;
1643 if( lsmash_add_entry( stsz
->list
, data
) < 0 )
1645 lsmash_free( data
);
1646 return LSMASH_ERR_MEMORY_ALLOC
;
1648 data
->entry_size
= lsmash_bs_get_be32( bs
);
1651 return isom_read_leaf_box_common_last_process( file
, box
, level
, stsz
);
1654 static int isom_read_stz2( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1656 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STBL
) || ((isom_stbl_t
*)parent
)->stz2
)
1657 return isom_read_unknown_box( file
, box
, parent
, level
);
1658 ADD_BOX( stz2
, isom_stbl_t
);
1659 lsmash_bs_t
*bs
= file
->bs
;
1660 uint32_t temp32
= lsmash_bs_get_be32( bs
);
1661 stz2
->reserved
= temp32
>> 24;
1662 stz2
->field_size
= temp32
& 0xff;
1663 stz2
->sample_count
= lsmash_bs_get_be32( bs
);
1664 uint64_t pos
= lsmash_bs_count( bs
);
1665 if( pos
< box
->size
)
1667 if( stz2
->field_size
== 16 || stz2
->field_size
== 8 )
1669 uint64_t (*bs_get_funcs
[2])( lsmash_bs_t
* ) =
1671 lsmash_bs_get_byte_to_64
,
1672 lsmash_bs_get_be16_to_64
1674 uint64_t (*bs_get_entry_size
)( lsmash_bs_t
* ) = bs_get_funcs
[ stz2
->field_size
== 16 ? 1 : 0 ];
1675 for( ; pos
< box
->size
&& stz2
->list
->entry_count
< stz2
->sample_count
; pos
= lsmash_bs_count( bs
) )
1677 isom_stsz_entry_t
*data
= lsmash_malloc( sizeof(isom_stsz_entry_t
) );
1679 return LSMASH_ERR_MEMORY_ALLOC
;
1680 if( lsmash_add_entry( stz2
->list
, data
) < 0 )
1682 lsmash_free( data
);
1683 return LSMASH_ERR_MEMORY_ALLOC
;
1685 data
->entry_size
= bs_get_entry_size( bs
);
1688 else if( stz2
->field_size
== 4 )
1692 while( pos
< box
->size
&& stz2
->list
->entry_count
< stz2
->sample_count
)
1694 isom_stsz_entry_t
*data
= lsmash_malloc( sizeof(isom_stsz_entry_t
) );
1696 return LSMASH_ERR_MEMORY_ALLOC
;
1697 if( lsmash_add_entry( stz2
->list
, data
) < 0 )
1699 lsmash_free( data
);
1700 return LSMASH_ERR_MEMORY_ALLOC
;
1702 /* Read a byte by two entries. */
1705 temp8
= lsmash_bs_get_byte( bs
);
1706 data
->entry_size
= (temp8
>> 4) & 0xf;
1710 pos
= lsmash_bs_count( bs
);
1711 data
->entry_size
= temp8
& 0xf;
1717 return LSMASH_ERR_INVALID_DATA
;
1719 return isom_read_leaf_box_common_last_process( file
, box
, level
, stz2
);
1722 static int isom_read_stco( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1724 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STBL
) || ((isom_stbl_t
*)parent
)->stco
)
1725 return isom_read_unknown_box( file
, box
, parent
, level
);
1726 box
->type
= lsmash_form_iso_box_type( box
->type
.fourcc
);
1727 int is_stco
= lsmash_check_box_type_identical( box
->type
, ISOM_BOX_TYPE_STCO
);
1728 isom_stco_t
*stco
= is_stco
1729 ? isom_add_stco( (isom_stbl_t
*)parent
)
1730 : isom_add_co64( (isom_stbl_t
*)parent
);
1732 return LSMASH_ERR_NAMELESS
;
1733 lsmash_bs_t
*bs
= file
->bs
;
1734 uint32_t entry_count
= lsmash_bs_get_be32( bs
);
1736 for( uint64_t pos
= lsmash_bs_count( bs
); pos
< box
->size
&& stco
->list
->entry_count
< entry_count
; pos
= lsmash_bs_count( bs
) )
1738 isom_stco_entry_t
*data
= lsmash_malloc( sizeof(isom_stco_entry_t
) );
1740 return LSMASH_ERR_MEMORY_ALLOC
;
1741 if( lsmash_add_entry( stco
->list
, data
) < 0 )
1743 lsmash_free( data
);
1744 return LSMASH_ERR_MEMORY_ALLOC
;
1746 data
->chunk_offset
= lsmash_bs_get_be32( bs
);
1750 for( uint64_t pos
= lsmash_bs_count( bs
); pos
< box
->size
&& stco
->list
->entry_count
< entry_count
; pos
= lsmash_bs_count( bs
) )
1752 isom_co64_entry_t
*data
= lsmash_malloc( sizeof(isom_co64_entry_t
) );
1754 return LSMASH_ERR_MEMORY_ALLOC
;
1755 if( lsmash_add_entry( stco
->list
, data
) < 0 )
1757 lsmash_free( data
);
1758 return LSMASH_ERR_MEMORY_ALLOC
;
1760 data
->chunk_offset
= lsmash_bs_get_be64( bs
);
1763 return isom_read_leaf_box_common_last_process( file
, box
, level
, stco
);
1766 static int isom_read_sgpd( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1768 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STBL
)
1769 && !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TRAF
) )
1770 return isom_read_unknown_box( file
, box
, parent
, level
);
1771 ADD_BOX( sgpd
, void );
1772 lsmash_bs_t
*bs
= file
->bs
;
1773 sgpd
->grouping_type
= lsmash_bs_get_be32( bs
);
1774 if( box
->version
== 1 )
1775 sgpd
->default_length
= lsmash_bs_get_be32( bs
);
1776 uint32_t entry_count
= lsmash_bs_get_be32( bs
);
1777 switch( sgpd
->grouping_type
)
1779 case ISOM_GROUP_TYPE_RAP
:
1781 for( uint64_t pos
= lsmash_bs_count( bs
); pos
< box
->size
&& sgpd
->list
->entry_count
< entry_count
; pos
= lsmash_bs_count( bs
) )
1783 isom_rap_entry_t
*data
= lsmash_malloc( sizeof(isom_rap_entry_t
) );
1785 return LSMASH_ERR_MEMORY_ALLOC
;
1786 if( lsmash_add_entry( sgpd
->list
, data
) < 0 )
1788 lsmash_free( data
);
1789 return LSMASH_ERR_MEMORY_ALLOC
;
1791 memset( data
, 0, sizeof(isom_rap_entry_t
) );
1792 /* We don't know groups decided by variable description length. If encountering, skip getting of bytes of it. */
1793 if( box
->version
== 1 && !sgpd
->default_length
)
1794 data
->description_length
= lsmash_bs_get_be32( bs
);
1797 uint8_t temp
= lsmash_bs_get_byte( bs
);
1798 data
->num_leading_samples_known
= (temp
>> 7) & 0x01;
1799 data
->num_leading_samples
= temp
& 0x7f;
1804 case ISOM_GROUP_TYPE_ROLL
:
1805 case ISOM_GROUP_TYPE_PROL
:
1807 for( uint64_t pos
= lsmash_bs_count( bs
); pos
< box
->size
&& sgpd
->list
->entry_count
< entry_count
; pos
= lsmash_bs_count( bs
) )
1809 isom_roll_entry_t
*data
= lsmash_malloc( sizeof(isom_roll_entry_t
) );
1811 return LSMASH_ERR_MEMORY_ALLOC
;
1812 if( lsmash_add_entry( sgpd
->list
, data
) < 0 )
1814 lsmash_free( data
);
1815 return LSMASH_ERR_MEMORY_ALLOC
;
1817 memset( data
, 0, sizeof(isom_roll_entry_t
) );
1818 /* We don't know groups decided by variable description length. If encountering, skip getting of bytes of it. */
1819 if( box
->version
== 1 && !sgpd
->default_length
)
1820 data
->description_length
= lsmash_bs_get_be32( bs
);
1822 data
->roll_distance
= lsmash_bs_get_be16( bs
);
1829 return isom_read_leaf_box_common_last_process( file
, box
, level
, sgpd
);
1832 static int isom_read_sbgp( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1834 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STBL
)
1835 && !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TRAF
) )
1836 return isom_read_unknown_box( file
, box
, parent
, level
);
1837 ADD_BOX( sbgp
, void );
1838 lsmash_bs_t
*bs
= file
->bs
;
1839 sbgp
->grouping_type
= lsmash_bs_get_be32( bs
);
1840 if( box
->version
== 1 )
1841 sbgp
->grouping_type_parameter
= lsmash_bs_get_be32( bs
);
1842 uint32_t entry_count
= lsmash_bs_get_be32( bs
);
1843 for( uint64_t pos
= lsmash_bs_count( bs
); pos
< box
->size
&& sbgp
->list
->entry_count
< entry_count
; pos
= lsmash_bs_count( bs
) )
1845 isom_group_assignment_entry_t
*data
= lsmash_malloc( sizeof(isom_group_assignment_entry_t
) );
1847 return LSMASH_ERR_MEMORY_ALLOC
;
1848 if( lsmash_add_entry( sbgp
->list
, data
) < 0 )
1850 lsmash_free( data
);
1851 return LSMASH_ERR_MEMORY_ALLOC
;
1853 data
->sample_count
= lsmash_bs_get_be32( bs
);
1854 data
->group_description_index
= lsmash_bs_get_be32( bs
);
1856 return isom_read_leaf_box_common_last_process( file
, box
, level
,sbgp
);
1859 static int isom_read_udta( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1861 if( (!lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MOOV
)
1862 && !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TRAK
))
1863 || (lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MOOV
) && ((isom_moov_t
*)parent
)->udta
)
1864 || (lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TRAK
) && ((isom_trak_t
*)parent
)->udta
) )
1865 return isom_read_unknown_box( file
, box
, parent
, level
);
1866 ADD_BOX( udta
, void );
1867 isom_box_common_copy( udta
, box
);
1868 int ret
= isom_add_print_func( file
, udta
, level
);
1871 return isom_read_children( file
, box
, udta
, level
);
1874 static int isom_read_chpl( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1876 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_UDTA
) || ((isom_udta_t
*)parent
)->chpl
)
1877 return isom_read_unknown_box( file
, box
, parent
, level
);
1878 ADD_BOX( chpl
, isom_udta_t
);
1879 lsmash_bs_t
*bs
= file
->bs
;
1880 uint32_t entry_count
;
1881 if( box
->version
== 1 )
1883 chpl
->unknown
= lsmash_bs_get_byte( bs
);
1884 entry_count
= lsmash_bs_get_be32( bs
);
1887 entry_count
= lsmash_bs_get_byte( bs
);
1888 for( uint64_t pos
= lsmash_bs_count( bs
); pos
< box
->size
&& chpl
->list
->entry_count
< entry_count
; pos
= lsmash_bs_count( bs
) )
1890 isom_chpl_entry_t
*data
= lsmash_malloc( sizeof(isom_chpl_entry_t
) );
1892 return LSMASH_ERR_MEMORY_ALLOC
;
1893 if( lsmash_add_entry( chpl
->list
, data
) < 0 )
1895 lsmash_free( data
);
1896 return LSMASH_ERR_MEMORY_ALLOC
;
1898 data
->start_time
= lsmash_bs_get_be64( bs
);
1899 data
->chapter_name_length
= lsmash_bs_get_byte( bs
);
1900 data
->chapter_name
= lsmash_malloc( data
->chapter_name_length
+ 1 );
1901 if( !data
->chapter_name
)
1903 lsmash_free( data
);
1904 return LSMASH_ERR_MEMORY_ALLOC
;
1906 for( uint8_t i
= 0; i
< data
->chapter_name_length
; i
++ )
1907 data
->chapter_name
[i
] = lsmash_bs_get_byte( bs
);
1908 data
->chapter_name
[data
->chapter_name_length
] = '\0';
1910 return isom_read_leaf_box_common_last_process( file
, box
, level
, chpl
);
1913 static int isom_read_mvex( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1915 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MOOV
) || ((isom_moov_t
*)parent
)->mvex
)
1916 return isom_read_unknown_box( file
, box
, parent
, level
);
1917 ADD_BOX( mvex
, isom_moov_t
);
1918 file
->flags
|= LSMASH_FILE_MODE_FRAGMENTED
;
1919 isom_box_common_copy( mvex
, box
);
1920 int ret
= isom_add_print_func( file
, mvex
, level
);
1923 return isom_read_children( file
, box
, mvex
, level
);
1926 static int isom_read_mehd( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1928 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MVEX
) || ((isom_mvex_t
*)parent
)->mehd
)
1929 return isom_read_unknown_box( file
, box
, parent
, level
);
1930 ADD_BOX( mehd
, isom_mvex_t
);
1931 lsmash_bs_t
*bs
= file
->bs
;
1932 if( box
->version
== 1 )
1933 mehd
->fragment_duration
= lsmash_bs_get_be64( bs
);
1935 mehd
->fragment_duration
= lsmash_bs_get_be32( bs
);
1936 return isom_read_leaf_box_common_last_process( file
, box
, level
, mehd
);
1939 static isom_sample_flags_t
isom_bs_get_sample_flags( lsmash_bs_t
*bs
)
1941 uint32_t temp
= lsmash_bs_get_be32( bs
);
1942 isom_sample_flags_t flags
;
1943 flags
.reserved
= (temp
>> 28) & 0xf;
1944 flags
.is_leading
= (temp
>> 26) & 0x3;
1945 flags
.sample_depends_on
= (temp
>> 24) & 0x3;
1946 flags
.sample_is_depended_on
= (temp
>> 22) & 0x3;
1947 flags
.sample_has_redundancy
= (temp
>> 20) & 0x3;
1948 flags
.sample_padding_value
= (temp
>> 17) & 0x7;
1949 flags
.sample_is_non_sync_sample
= (temp
>> 16) & 0x1;
1950 flags
.sample_degradation_priority
= temp
& 0xffff;
1954 static int isom_read_trex( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1956 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MVEX
) )
1957 return isom_read_unknown_box( file
, box
, parent
, level
);
1958 ADD_BOX( trex
, isom_mvex_t
);
1959 box
->parent
= parent
;
1960 lsmash_bs_t
*bs
= file
->bs
;
1961 trex
->track_ID
= lsmash_bs_get_be32( bs
);
1962 trex
->default_sample_description_index
= lsmash_bs_get_be32( bs
);
1963 trex
->default_sample_duration
= lsmash_bs_get_be32( bs
);
1964 trex
->default_sample_size
= lsmash_bs_get_be32( bs
);
1965 trex
->default_sample_flags
= isom_bs_get_sample_flags( bs
);
1966 return isom_read_leaf_box_common_last_process( file
, box
, level
, trex
);
1969 static int isom_read_moof( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1971 if( !lsmash_check_box_type_identical( parent
->type
, LSMASH_BOX_TYPE_UNSPECIFIED
) )
1972 return isom_read_unknown_box( file
, box
, parent
, level
);
1973 ADD_BOX( moof
, lsmash_file_t
);
1974 box
->parent
= parent
;
1975 isom_box_common_copy( moof
, box
);
1976 int ret
= isom_add_print_func( file
, moof
, level
);
1979 return isom_read_children( file
, box
, moof
, level
);
1982 static int isom_read_mfhd( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1984 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MOOF
) || ((isom_moof_t
*)parent
)->mfhd
)
1985 return isom_read_unknown_box( file
, box
, parent
, level
);
1986 ADD_BOX( mfhd
, isom_moof_t
);
1987 lsmash_bs_t
*bs
= file
->bs
;
1988 mfhd
->sequence_number
= lsmash_bs_get_be32( bs
);
1989 return isom_read_leaf_box_common_last_process( file
, box
, level
, mfhd
);
1992 static int isom_read_traf( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
1994 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MOOF
) )
1995 return isom_read_unknown_box( file
, box
, parent
, level
);
1996 ADD_BOX( traf
, isom_moof_t
);
1997 box
->parent
= parent
;
1998 isom_box_common_copy( traf
, box
);
1999 int ret
= isom_add_print_func( file
, traf
, level
);
2002 return isom_read_children( file
, box
, traf
, level
);
2005 static int isom_read_tfhd( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2007 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TRAF
) || ((isom_traf_t
*)parent
)->tfhd
)
2008 return isom_read_unknown_box( file
, box
, parent
, level
);
2009 ADD_BOX( tfhd
, isom_traf_t
);
2010 lsmash_bs_t
*bs
= file
->bs
;
2011 tfhd
->track_ID
= lsmash_bs_get_be32( bs
);
2012 if( box
->flags
& ISOM_TF_FLAGS_BASE_DATA_OFFSET_PRESENT
) tfhd
->base_data_offset
= lsmash_bs_get_be64( bs
);
2013 if( box
->flags
& ISOM_TF_FLAGS_SAMPLE_DESCRIPTION_INDEX_PRESENT
) tfhd
->sample_description_index
= lsmash_bs_get_be32( bs
);
2014 if( box
->flags
& ISOM_TF_FLAGS_DEFAULT_SAMPLE_DURATION_PRESENT
) tfhd
->default_sample_duration
= lsmash_bs_get_be32( bs
);
2015 if( box
->flags
& ISOM_TF_FLAGS_DEFAULT_SAMPLE_SIZE_PRESENT
) tfhd
->default_sample_size
= lsmash_bs_get_be32( bs
);
2016 if( box
->flags
& ISOM_TF_FLAGS_DEFAULT_SAMPLE_FLAGS_PRESENT
) tfhd
->default_sample_flags
= isom_bs_get_sample_flags( bs
);
2017 return isom_read_leaf_box_common_last_process( file
, box
, level
, tfhd
);
2020 static int isom_read_tfdt( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2022 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TRAF
) || ((isom_traf_t
*)parent
)->tfdt
)
2023 return isom_read_unknown_box( file
, box
, parent
, level
);
2024 ADD_BOX( tfdt
, isom_traf_t
);
2025 lsmash_bs_t
*bs
= file
->bs
;
2026 if( box
->version
== 1 )
2027 tfdt
->baseMediaDecodeTime
= lsmash_bs_get_be64( bs
);
2029 tfdt
->baseMediaDecodeTime
= lsmash_bs_get_be32( bs
);
2030 return isom_read_leaf_box_common_last_process( file
, box
, level
, tfdt
);
2033 static int isom_read_trun( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2035 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TRAF
) )
2036 return isom_read_unknown_box( file
, box
, parent
, level
);
2037 ADD_BOX( trun
, isom_traf_t
);
2038 box
->parent
= parent
;
2039 lsmash_bs_t
*bs
= file
->bs
;
2040 int has_optional_rows
= ISOM_TR_FLAGS_SAMPLE_DURATION_PRESENT
2041 | ISOM_TR_FLAGS_SAMPLE_SIZE_PRESENT
2042 | ISOM_TR_FLAGS_SAMPLE_FLAGS_PRESENT
2043 | ISOM_TR_FLAGS_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT
;
2044 has_optional_rows
&= box
->flags
;
2045 trun
->sample_count
= lsmash_bs_get_be32( bs
);
2046 if( box
->flags
& ISOM_TR_FLAGS_DATA_OFFSET_PRESENT
) trun
->data_offset
= lsmash_bs_get_be32( bs
);
2047 if( box
->flags
& ISOM_TR_FLAGS_FIRST_SAMPLE_FLAGS_PRESENT
) trun
->first_sample_flags
= isom_bs_get_sample_flags( bs
);
2048 if( trun
->sample_count
&& has_optional_rows
)
2050 trun
->optional
= lsmash_create_entry_list();
2051 if( !trun
->optional
)
2052 return LSMASH_ERR_MEMORY_ALLOC
;
2053 for( uint32_t i
= 0; i
< trun
->sample_count
; i
++ )
2055 isom_trun_optional_row_t
*data
= lsmash_malloc( sizeof(isom_trun_optional_row_t
) );
2057 return LSMASH_ERR_MEMORY_ALLOC
;
2058 if( lsmash_add_entry( trun
->optional
, data
) < 0 )
2060 lsmash_free( data
);
2061 return LSMASH_ERR_MEMORY_ALLOC
;
2063 if( box
->flags
& ISOM_TR_FLAGS_SAMPLE_DURATION_PRESENT
) data
->sample_duration
= lsmash_bs_get_be32( bs
);
2064 if( box
->flags
& ISOM_TR_FLAGS_SAMPLE_SIZE_PRESENT
) data
->sample_size
= lsmash_bs_get_be32( bs
);
2065 if( box
->flags
& ISOM_TR_FLAGS_SAMPLE_FLAGS_PRESENT
) data
->sample_flags
= isom_bs_get_sample_flags( bs
);
2066 if( box
->flags
& ISOM_TR_FLAGS_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT
) data
->sample_composition_time_offset
= lsmash_bs_get_be32( bs
);
2069 return isom_read_leaf_box_common_last_process( file
, box
, level
, trun
);
2072 static int isom_read_free( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2074 if( file
->fake_file_mode
)
2075 return isom_read_unknown_box( file
, box
, parent
, level
);
2076 isom_box_t
*skip
= lsmash_malloc_zero( sizeof(isom_box_t
) );
2078 return LSMASH_ERR_MEMORY_ALLOC
;
2079 isom_skip_box_rest( file
->bs
, box
);
2080 box
->manager
|= LSMASH_ABSENT_IN_FILE
;
2081 isom_box_common_copy( skip
, box
);
2082 int ret
= isom_add_print_func( file
, skip
, level
);
2085 lsmash_free( skip
);
2091 static int isom_read_mdat( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2093 if( file
->fake_file_mode
|| !lsmash_check_box_type_identical( parent
->type
, LSMASH_BOX_TYPE_UNSPECIFIED
) )
2094 return isom_read_unknown_box( file
, box
, parent
, level
);
2095 isom_box_t
*mdat
= lsmash_malloc_zero( sizeof(isom_box_t
) );
2097 return LSMASH_ERR_MEMORY_ALLOC
;
2098 isom_skip_box_rest( file
->bs
, box
);
2099 box
->manager
|= LSMASH_ABSENT_IN_FILE
;
2100 file
->flags
|= LSMASH_FILE_MODE_MEDIA
;
2101 isom_box_common_copy( mdat
, box
);
2102 int ret
= isom_add_print_func( file
, mdat
, level
);
2105 lsmash_free( mdat
);
2111 static int isom_read_meta( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2113 if( (!lsmash_check_box_type_identical( parent
->type
, LSMASH_BOX_TYPE_UNSPECIFIED
)
2114 && !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MOOV
)
2115 && !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TRAK
)
2116 && !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_UDTA
))
2117 || (lsmash_check_box_type_identical( parent
->type
, LSMASH_BOX_TYPE_UNSPECIFIED
) && ((lsmash_file_t
*)parent
)->meta
)
2118 || (lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MOOV
) && ((isom_moov_t
*)parent
)->meta
)
2119 || (lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TRAK
) && ((isom_trak_t
*)parent
)->meta
)
2120 || (lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_UDTA
) && ((isom_udta_t
*)parent
)->meta
) )
2121 return isom_read_unknown_box( file
, box
, parent
, level
);
2122 ADD_BOX( meta
, void );
2123 isom_box_common_copy( meta
, box
);
2124 int is_qtff
= lsmash_check_box_type_identical( box
->type
, QT_BOX_TYPE_META
);
2127 box
->manager
|= LSMASH_QTFF_BASE
;
2128 meta
->manager
|= LSMASH_QTFF_BASE
;
2130 int ret
= isom_add_print_func( file
, meta
, level
);
2133 return isom_read_children( file
, box
, meta
, level
);
2136 static int isom_read_keys( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2138 if( (!lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_META
) && !(parent
->manager
& LSMASH_QTFF_BASE
))
2139 || ((isom_meta_t
*)parent
)->keys
)
2140 return isom_read_unknown_box( file
, box
, parent
, level
);
2141 ADD_BOX( keys
, isom_meta_t
);
2142 lsmash_bs_t
*bs
= file
->bs
;
2143 uint32_t entry_count
= lsmash_bs_get_be32( bs
);
2144 for( uint64_t pos
= lsmash_bs_count( bs
); pos
< box
->size
&& keys
->list
->entry_count
< entry_count
; pos
= lsmash_bs_count( bs
) )
2146 isom_keys_entry_t
*data
= lsmash_malloc( sizeof(isom_keys_entry_t
) );
2148 return LSMASH_ERR_MEMORY_ALLOC
;
2149 if( lsmash_add_entry( keys
->list
, data
) < 0 )
2151 lsmash_free( data
);
2152 return LSMASH_ERR_MEMORY_ALLOC
;
2154 data
->key_size
= lsmash_bs_get_be32( bs
);
2155 data
->key_namespace
= lsmash_bs_get_be32( bs
);
2156 if( data
->key_size
> 8 )
2158 data
->key_value
= lsmash_bs_get_bytes( bs
, data
->key_size
- 8 );
2159 if( !data
->key_value
)
2160 return LSMASH_ERR_NAMELESS
;
2163 data
->key_value
= NULL
;
2165 return isom_read_leaf_box_common_last_process( file
, box
, level
, keys
);
2168 static int isom_read_ilst( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2170 if( (!lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_META
)
2171 && !lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_META
))
2172 || ((isom_meta_t
*)parent
)->ilst
)
2173 return isom_read_unknown_box( file
, box
, parent
, level
);
2174 ADD_BOX( ilst
, isom_meta_t
);
2175 isom_box_common_copy( ilst
, box
);
2176 int ret
= isom_add_print_func( file
, ilst
, level
);
2179 return isom_read_children( file
, box
, ilst
, level
);
2182 static int isom_read_metaitem( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2184 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_ILST
)
2185 && !lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_ILST
) )
2186 return isom_read_unknown_box( file
, box
, parent
, level
);
2187 isom_metaitem_t
*metaitem
= isom_add_metaitem( (isom_ilst_t
*)parent
, box
->type
.fourcc
);
2190 box
->parent
= parent
;
2191 isom_box_common_copy( metaitem
, box
);
2192 int ret
= isom_add_print_func( file
, metaitem
, level
);
2195 return isom_read_children( file
, box
, metaitem
, level
);
2198 static int isom_read_mean( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2200 if( parent
->type
.fourcc
!= ITUNES_METADATA_ITEM_CUSTOM
|| ((isom_metaitem_t
*)parent
)->mean
)
2201 return isom_read_unknown_box( file
, box
, parent
, level
);
2202 ADD_BOX( mean
, isom_metaitem_t
);
2203 lsmash_bs_t
*bs
= file
->bs
;
2204 mean
->meaning_string_length
= box
->size
- lsmash_bs_count( bs
);
2205 mean
->meaning_string
= lsmash_bs_get_bytes( bs
, mean
->meaning_string_length
);
2206 if( !mean
->meaning_string
)
2207 return LSMASH_ERR_NAMELESS
;
2208 return isom_read_leaf_box_common_last_process( file
, box
, level
, mean
);
2211 static int isom_read_name( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2213 if( parent
->type
.fourcc
!= ITUNES_METADATA_ITEM_CUSTOM
|| ((isom_metaitem_t
*)parent
)->name
)
2214 return isom_read_unknown_box( file
, box
, parent
, level
);
2215 ADD_BOX( name
, isom_metaitem_t
);
2216 lsmash_bs_t
*bs
= file
->bs
;
2217 name
->name_length
= box
->size
- lsmash_bs_count( bs
);
2218 name
->name
= lsmash_bs_get_bytes( bs
, name
->name_length
);
2220 return LSMASH_ERR_NAMELESS
;
2221 return isom_read_leaf_box_common_last_process( file
, box
, level
, name
);
2224 static int isom_read_data( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2226 if( ((isom_metaitem_t
*)parent
)->data
)
2227 return isom_read_unknown_box( file
, box
, parent
, level
);
2228 ADD_BOX( data
, isom_metaitem_t
);
2229 lsmash_bs_t
*bs
= file
->bs
;
2230 data
->value_length
= box
->size
- lsmash_bs_count( bs
) - 8;
2231 data
->reserved
= lsmash_bs_get_be16( bs
);
2232 data
->type_set_identifier
= lsmash_bs_get_byte( bs
);
2233 data
->type_code
= lsmash_bs_get_byte( bs
);
2234 data
->the_locale
= lsmash_bs_get_be32( bs
);
2235 if( data
->value_length
)
2237 data
->value
= lsmash_bs_get_bytes( bs
, data
->value_length
);
2239 return LSMASH_ERR_NAMELESS
;
2241 return isom_read_leaf_box_common_last_process( file
, box
, level
, data
);
2244 static int isom_read_WLOC( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2246 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_UDTA
) || ((isom_udta_t
*)parent
)->WLOC
)
2247 return isom_read_unknown_box( file
, box
, parent
, level
);
2248 ADD_BOX( WLOC
, isom_udta_t
);
2249 lsmash_bs_t
*bs
= file
->bs
;
2250 WLOC
->x
= lsmash_bs_get_be16( bs
);
2251 WLOC
->y
= lsmash_bs_get_be16( bs
);
2252 return isom_read_leaf_box_common_last_process( file
, box
, level
, WLOC
);
2255 static int isom_read_LOOP( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2257 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_UDTA
) || ((isom_udta_t
*)parent
)->LOOP
)
2258 return isom_read_unknown_box( file
, box
, parent
, level
);
2259 ADD_BOX( LOOP
, isom_udta_t
);
2260 lsmash_bs_t
*bs
= file
->bs
;
2261 LOOP
->looping_mode
= lsmash_bs_get_be32( bs
);
2262 return isom_read_leaf_box_common_last_process( file
, box
, level
, LOOP
);
2265 static int isom_read_SelO( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2267 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_UDTA
) || ((isom_udta_t
*)parent
)->SelO
)
2268 return isom_read_unknown_box( file
, box
, parent
, level
);
2269 ADD_BOX( SelO
, isom_udta_t
);
2270 lsmash_bs_t
*bs
= file
->bs
;
2271 SelO
->selection_only
= lsmash_bs_get_byte( bs
);
2272 return isom_read_leaf_box_common_last_process( file
, box
, level
, SelO
);
2275 static int isom_read_AllF( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2277 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_UDTA
) || ((isom_udta_t
*)parent
)->AllF
)
2278 return isom_read_unknown_box( file
, box
, parent
, level
);
2279 ADD_BOX( AllF
, isom_udta_t
);
2280 lsmash_bs_t
*bs
= file
->bs
;
2281 AllF
->play_all_frames
= lsmash_bs_get_byte( bs
);
2282 return isom_read_leaf_box_common_last_process( file
, box
, level
, AllF
);
2285 static int isom_read_cprt( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2287 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_UDTA
) )
2288 return isom_read_unknown_box( file
, box
, parent
, level
);
2289 ADD_BOX( cprt
, isom_udta_t
);
2290 box
->parent
= parent
;
2291 lsmash_bs_t
*bs
= file
->bs
;
2292 cprt
->language
= lsmash_bs_get_be16( bs
);
2293 cprt
->notice_length
= box
->size
- (ISOM_FULLBOX_COMMON_SIZE
+ 2);
2294 if( cprt
->notice_length
)
2296 cprt
->notice
= lsmash_bs_get_bytes( bs
, cprt
->notice_length
);
2299 cprt
->notice_length
= 0;
2300 return LSMASH_ERR_NAMELESS
;
2303 return isom_read_leaf_box_common_last_process( file
, box
, level
, cprt
);
2306 static int isom_read_mfra( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2308 if( !lsmash_check_box_type_identical( parent
->type
, LSMASH_BOX_TYPE_UNSPECIFIED
) || ((lsmash_file_t
*)parent
)->mfra
)
2309 return isom_read_unknown_box( file
, box
, parent
, level
);
2310 ADD_BOX( mfra
, lsmash_file_t
);
2311 isom_box_common_copy( mfra
, box
);
2312 int ret
= isom_add_print_func( file
, mfra
, level
);
2315 return isom_read_children( file
, box
, mfra
, level
);
2318 static int isom_read_tfra( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2320 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MFRA
) )
2321 return isom_read_unknown_box( file
, box
, parent
, level
);
2322 ADD_BOX( tfra
, isom_mfra_t
);
2323 box
->parent
= parent
;
2324 lsmash_bs_t
*bs
= file
->bs
;
2325 tfra
->track_ID
= lsmash_bs_get_be32( bs
);
2326 uint32_t temp
= lsmash_bs_get_be32( bs
);
2327 tfra
->number_of_entry
= lsmash_bs_get_be32( bs
);
2328 tfra
->reserved
= (temp
>> 6) & 0x3ffffff;
2329 tfra
->length_size_of_traf_num
= (temp
>> 4) & 0x3;
2330 tfra
->length_size_of_trun_num
= (temp
>> 2) & 0x3;
2331 tfra
->length_size_of_sample_num
= temp
& 0x3;
2332 if( tfra
->number_of_entry
)
2334 tfra
->list
= lsmash_create_entry_list();
2336 return LSMASH_ERR_MEMORY_ALLOC
;
2337 uint64_t (*bs_get_funcs
[5])( lsmash_bs_t
* ) =
2339 lsmash_bs_get_byte_to_64
,
2340 lsmash_bs_get_be16_to_64
,
2341 lsmash_bs_get_be24_to_64
,
2342 lsmash_bs_get_be32_to_64
,
2345 uint64_t (*bs_put_time
) ( lsmash_bs_t
* ) = bs_get_funcs
[ 3 + (box
->version
== 1) ];
2346 uint64_t (*bs_put_moof_offset
) ( lsmash_bs_t
* ) = bs_get_funcs
[ 3 + (box
->version
== 1) ];
2347 uint64_t (*bs_put_traf_number
) ( lsmash_bs_t
* ) = bs_get_funcs
[ tfra
->length_size_of_traf_num
];
2348 uint64_t (*bs_put_trun_number
) ( lsmash_bs_t
* ) = bs_get_funcs
[ tfra
->length_size_of_trun_num
];
2349 uint64_t (*bs_put_sample_number
)( lsmash_bs_t
* ) = bs_get_funcs
[ tfra
->length_size_of_sample_num
];
2350 for( uint32_t i
= 0; i
< tfra
->number_of_entry
; i
++ )
2352 isom_tfra_location_time_entry_t
*data
= lsmash_malloc( sizeof(isom_tfra_location_time_entry_t
) );
2354 return LSMASH_ERR_MEMORY_ALLOC
;
2355 if( lsmash_add_entry( tfra
->list
, data
) < 0 )
2357 lsmash_free( data
);
2358 return LSMASH_ERR_MEMORY_ALLOC
;
2360 data
->time
= bs_put_time ( bs
);
2361 data
->moof_offset
= bs_put_moof_offset ( bs
);
2362 data
->traf_number
= bs_put_traf_number ( bs
);
2363 data
->trun_number
= bs_put_trun_number ( bs
);
2364 data
->sample_number
= bs_put_sample_number( bs
);
2367 return isom_read_leaf_box_common_last_process( file
, box
, level
, tfra
);
2370 static int isom_read_mfro( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, int level
)
2372 if( !lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_MFRA
) || ((isom_mfra_t
*)parent
)->mfro
)
2373 return isom_read_unknown_box( file
, box
, parent
, level
);
2374 ADD_BOX( mfro
, isom_mfra_t
);
2375 lsmash_bs_t
*bs
= file
->bs
;
2376 mfro
->length
= lsmash_bs_get_be32( bs
);
2377 return isom_read_leaf_box_common_last_process( file
, box
, level
, mfro
);
2380 static void isom_read_skip_extra_bytes( lsmash_bs_t
*bs
, uint64_t size
)
2382 if( !bs
->unseekable
)
2384 /* lsmash_bs_read_seek() could fail on offset=INT64_MAX, so use (INT64_MAX >> 1) instead. */
2385 while( size
> (INT64_MAX
>> 1) )
2387 lsmash_bs_read_seek( bs
, INT64_MAX
>> 1, SEEK_CUR
);
2388 if( lsmash_bs_is_end( bs
, 0 ) )
2390 size
-= (INT64_MAX
>> 1);
2392 lsmash_bs_read_seek( bs
, size
, SEEK_CUR
);
2395 lsmash_bs_skip_bytes_64( bs
, size
);
2398 static int isom_read_skip_box_extra_bytes( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, uint64_t parent_pos
)
2400 lsmash_bs_t
*bs
= file
->bs
;
2401 /* Skip extra bytes of the parent box if any. */
2402 if( parent
->size
< parent_pos
+ ISOM_BASEBOX_COMMON_SIZE
)
2404 uint64_t extra_bytes
= parent
->size
- parent_pos
;
2405 isom_read_skip_extra_bytes( bs
, extra_bytes
);
2406 /* This is not the size of a box but makes sense in isom_read_children(). */
2407 box
->size
= extra_bytes
;
2410 /* Check if the size is valid or not. */
2411 if( lsmash_bs_is_end( bs
, 3 ) == 0 )
2413 uint64_t size
= (uint64_t)lsmash_bs_show_be32( bs
, 0 );
2415 && size
< ISOM_BASEBOX_COMMON_SIZE
)
2417 /* It's not a valid size of any box, therefore, it seems we are still within the box considered as the previous.
2418 * Skip bytes up to the next box of the parent box. */
2419 uint64_t extra_bytes
= parent
->size
- parent_pos
;
2420 isom_read_skip_extra_bytes( bs
, extra_bytes
);
2421 box
->size
= extra_bytes
;
2424 if( size
== 1 && lsmash_bs_is_end( bs
, 15 ) == 0 )
2425 size
= lsmash_bs_show_be64( bs
, 8 ); /* large size */
2426 if( size
== 0 && parent
!= (isom_box_t
*)file
)
2428 /* Check if this box is actually the last box or not. */
2429 uint64_t extra_bytes
= parent
->size
- parent_pos
;
2430 if( !bs
->unseekable
)
2431 size
= bs
->written
- lsmash_bs_get_stream_pos( bs
);
2434 size
= lsmash_bs_get_remaining_buffer_size( bs
);
2435 while( size
<= extra_bytes
)
2437 int ret
= lsmash_bs_read( bs
, 1 );
2438 if( bs
->eof
|| ret
< 0 )
2440 size
= lsmash_bs_get_remaining_buffer_size( bs
);
2443 if( size
!= extra_bytes
)
2445 /* This is not the size of the last box.
2446 * It seems we are still within the box considered as the previous or the parent box.
2447 * Skip bytes up to the next box. */
2448 if( box
->size
> lsmash_bs_count( bs
) )
2450 /* within the previous */
2451 isom_read_skip_extra_bytes( bs
, box
->size
- lsmash_bs_count( bs
) );
2452 box
->size
= 0; /* already added to the size of the parent box */
2456 /* within the parent */
2457 isom_read_skip_extra_bytes( bs
, extra_bytes
);
2458 box
->size
= extra_bytes
;
2467 int isom_read_box( lsmash_file_t
*file
, isom_box_t
*box
, isom_box_t
*parent
, uint64_t parent_pos
, int level
)
2469 assert( parent
&& parent
->root
&& parent
->file
);
2470 if( isom_read_skip_box_extra_bytes( file
, box
, parent
, parent_pos
) != 0 )
2472 memset( box
, 0, sizeof(isom_box_t
) );
2473 box
->root
= parent
->root
;
2474 box
->file
= parent
->file
;
2475 box
->parent
= parent
;
2476 lsmash_bs_t
*bs
= file
->bs
;
2477 int ret
= isom_bs_read_box_common( bs
, box
);
2479 return ret
; /* return if reached EOF */
2481 lsmash_box_type_t (*form_box_type_func
)( lsmash_compact_box_type_t
) = NULL
;
2482 int (*reader_func
)( lsmash_file_t
*, isom_box_t
*, isom_box_t
*, int ) = NULL
;
2483 if( lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_STSD
) )
2485 /* OK, this box is a sample entry.
2486 * Here, determine the suitable sample entry reader by media type if possible. */
2487 if( !isom_check_media_hdlr_from_stsd( (isom_stsd_t
*)parent
) )
2489 lsmash_media_type media_type
= isom_get_media_type_from_stsd( (isom_stsd_t
*)parent
);
2490 if( media_type
== ISOM_MEDIA_HANDLER_TYPE_VIDEO_TRACK
)
2491 reader_func
= isom_read_visual_description
;
2492 else if( media_type
== ISOM_MEDIA_HANDLER_TYPE_AUDIO_TRACK
)
2493 reader_func
= isom_read_audio_description
;
2494 else if( media_type
== ISOM_MEDIA_HANDLER_TYPE_TEXT_TRACK
)
2495 reader_func
= isom_read_text_description
;
2497 reader_func
= isom_read_other_description
;
2498 /* Determine either of file formats the sample type is defined in; ISOBMFF or QTFF. */
2499 static struct description_reader_table_tag
2501 lsmash_compact_box_type_t fourcc
;
2502 lsmash_box_type_t (*form_box_type_func
)( lsmash_compact_box_type_t
);
2503 } description_reader_table
[160] = { { 0, NULL
} };
2504 if( !description_reader_table
[0].form_box_type_func
)
2506 /* Initialize the table. */
2508 #define ADD_DESCRIPTION_READER_TABLE_ELEMENT( type, form_box_type_func ) \
2509 description_reader_table[i++] = (struct description_reader_table_tag){ type.fourcc, form_box_type_func }
2510 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_AVC1_VIDEO
, lsmash_form_iso_box_type
);
2511 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_AVC2_VIDEO
, lsmash_form_iso_box_type
);
2512 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_AVC3_VIDEO
, lsmash_form_iso_box_type
);
2513 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_AVC4_VIDEO
, lsmash_form_iso_box_type
);
2514 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_AVCP_VIDEO
, lsmash_form_iso_box_type
);
2515 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_DRAC_VIDEO
, lsmash_form_iso_box_type
);
2516 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_ENCV_VIDEO
, lsmash_form_iso_box_type
);
2517 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_HVC1_VIDEO
, lsmash_form_iso_box_type
);
2518 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_HEV1_VIDEO
, lsmash_form_iso_box_type
);
2519 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_MJP2_VIDEO
, lsmash_form_iso_box_type
);
2520 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_MP4V_VIDEO
, lsmash_form_iso_box_type
);
2521 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_MVC1_VIDEO
, lsmash_form_iso_box_type
);
2522 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_MVC2_VIDEO
, lsmash_form_iso_box_type
);
2523 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_S263_VIDEO
, lsmash_form_iso_box_type
);
2524 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_SVC1_VIDEO
, lsmash_form_iso_box_type
);
2525 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_VC_1_VIDEO
, lsmash_form_iso_box_type
);
2526 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_2VUY_VIDEO
, lsmash_form_qtff_box_type
);
2527 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_CFHD_VIDEO
, lsmash_form_qtff_box_type
);
2528 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_DV10_VIDEO
, lsmash_form_qtff_box_type
);
2529 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_DVOO_VIDEO
, lsmash_form_qtff_box_type
);
2530 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_DVOR_VIDEO
, lsmash_form_qtff_box_type
);
2531 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_DVTV_VIDEO
, lsmash_form_qtff_box_type
);
2532 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_DVVT_VIDEO
, lsmash_form_qtff_box_type
);
2533 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_HD10_VIDEO
, lsmash_form_qtff_box_type
);
2534 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_M105_VIDEO
, lsmash_form_qtff_box_type
);
2535 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_PNTG_VIDEO
, lsmash_form_qtff_box_type
);
2536 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_SVQ1_VIDEO
, lsmash_form_qtff_box_type
);
2537 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_SVQ3_VIDEO
, lsmash_form_qtff_box_type
);
2538 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_SHR0_VIDEO
, lsmash_form_qtff_box_type
);
2539 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_SHR1_VIDEO
, lsmash_form_qtff_box_type
);
2540 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_SHR2_VIDEO
, lsmash_form_qtff_box_type
);
2541 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_SHR3_VIDEO
, lsmash_form_qtff_box_type
);
2542 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_SHR4_VIDEO
, lsmash_form_qtff_box_type
);
2543 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_WRLE_VIDEO
, lsmash_form_qtff_box_type
);
2544 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_APCH_VIDEO
, lsmash_form_qtff_box_type
);
2545 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_APCN_VIDEO
, lsmash_form_qtff_box_type
);
2546 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_APCS_VIDEO
, lsmash_form_qtff_box_type
);
2547 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_APCO_VIDEO
, lsmash_form_qtff_box_type
);
2548 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_AP4H_VIDEO
, lsmash_form_qtff_box_type
);
2549 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_AP4X_VIDEO
, lsmash_form_qtff_box_type
);
2550 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_CIVD_VIDEO
, lsmash_form_qtff_box_type
);
2551 //ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_DRAC_VIDEO, lsmash_form_qtff_box_type );
2552 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_DVC_VIDEO
, lsmash_form_qtff_box_type
);
2553 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_DVCP_VIDEO
, lsmash_form_qtff_box_type
);
2554 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_DVPP_VIDEO
, lsmash_form_qtff_box_type
);
2555 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_DV5N_VIDEO
, lsmash_form_qtff_box_type
);
2556 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_DV5P_VIDEO
, lsmash_form_qtff_box_type
);
2557 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_DVH2_VIDEO
, lsmash_form_qtff_box_type
);
2558 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_DVH3_VIDEO
, lsmash_form_qtff_box_type
);
2559 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_DVH5_VIDEO
, lsmash_form_qtff_box_type
);
2560 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_DVH6_VIDEO
, lsmash_form_qtff_box_type
);
2561 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_DVHP_VIDEO
, lsmash_form_qtff_box_type
);
2562 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_DVHQ_VIDEO
, lsmash_form_qtff_box_type
);
2563 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_FLIC_VIDEO
, lsmash_form_qtff_box_type
);
2564 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_GIF_VIDEO
, lsmash_form_qtff_box_type
);
2565 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_H261_VIDEO
, lsmash_form_qtff_box_type
);
2566 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_H263_VIDEO
, lsmash_form_qtff_box_type
);
2567 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_JPEG_VIDEO
, lsmash_form_qtff_box_type
);
2568 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_MJPA_VIDEO
, lsmash_form_qtff_box_type
);
2569 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_MJPB_VIDEO
, lsmash_form_qtff_box_type
);
2570 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_PNG_VIDEO
, lsmash_form_qtff_box_type
);
2571 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_RLE_VIDEO
, lsmash_form_qtff_box_type
);
2572 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_RPZA_VIDEO
, lsmash_form_qtff_box_type
);
2573 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_TGA_VIDEO
, lsmash_form_qtff_box_type
);
2574 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_TIFF_VIDEO
, lsmash_form_qtff_box_type
);
2575 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_ULRA_VIDEO
, lsmash_form_qtff_box_type
);
2576 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_ULRG_VIDEO
, lsmash_form_qtff_box_type
);
2577 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_ULY2_VIDEO
, lsmash_form_qtff_box_type
);
2578 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_ULY0_VIDEO
, lsmash_form_qtff_box_type
);
2579 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_ULH2_VIDEO
, lsmash_form_qtff_box_type
);
2580 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_ULH0_VIDEO
, lsmash_form_qtff_box_type
);
2581 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_UQY2_VIDEO
, lsmash_form_qtff_box_type
);
2582 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_V210_VIDEO
, lsmash_form_qtff_box_type
);
2583 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_V216_VIDEO
, lsmash_form_qtff_box_type
);
2584 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_V308_VIDEO
, lsmash_form_qtff_box_type
);
2585 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_V408_VIDEO
, lsmash_form_qtff_box_type
);
2586 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_V410_VIDEO
, lsmash_form_qtff_box_type
);
2587 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_YUV2_VIDEO
, lsmash_form_qtff_box_type
);
2588 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_AC_3_AUDIO
, lsmash_form_iso_box_type
);
2589 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_ALAC_AUDIO
, lsmash_form_iso_box_type
);
2590 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_DRA1_AUDIO
, lsmash_form_iso_box_type
);
2591 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_DTSC_AUDIO
, lsmash_form_iso_box_type
);
2592 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_DTSE_AUDIO
, lsmash_form_iso_box_type
);
2593 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_DTSH_AUDIO
, lsmash_form_iso_box_type
);
2594 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_DTSL_AUDIO
, lsmash_form_iso_box_type
);
2595 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_EC_3_AUDIO
, lsmash_form_iso_box_type
);
2596 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_ENCA_AUDIO
, lsmash_form_iso_box_type
);
2597 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_G719_AUDIO
, lsmash_form_iso_box_type
);
2598 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_G726_AUDIO
, lsmash_form_iso_box_type
);
2599 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_M4AE_AUDIO
, lsmash_form_iso_box_type
);
2600 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_MLPA_AUDIO
, lsmash_form_iso_box_type
);
2601 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_MP4A_AUDIO
, lsmash_form_iso_box_type
);
2602 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_SAMR_AUDIO
, lsmash_form_iso_box_type
);
2603 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_SAWB_AUDIO
, lsmash_form_iso_box_type
);
2604 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_SAWP_AUDIO
, lsmash_form_iso_box_type
);
2605 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_SEVC_AUDIO
, lsmash_form_iso_box_type
);
2606 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_SQCP_AUDIO
, lsmash_form_iso_box_type
);
2607 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_SSMV_AUDIO
, lsmash_form_iso_box_type
);
2608 //ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_TWOS_AUDIO, lsmash_form_iso_box_type );
2609 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_WMA_AUDIO
, lsmash_form_iso_box_type
);
2610 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_23NI_AUDIO
, lsmash_form_qtff_box_type
);
2611 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_MAC3_AUDIO
, lsmash_form_qtff_box_type
);
2612 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_MAC6_AUDIO
, lsmash_form_qtff_box_type
);
2613 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_NONE_AUDIO
, lsmash_form_qtff_box_type
);
2614 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_QDM2_AUDIO
, lsmash_form_qtff_box_type
);
2615 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_QDMC_AUDIO
, lsmash_form_qtff_box_type
);
2616 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_QCLP_AUDIO
, lsmash_form_qtff_box_type
);
2617 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_AGSM_AUDIO
, lsmash_form_qtff_box_type
);
2618 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_ALAW_AUDIO
, lsmash_form_qtff_box_type
);
2619 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_CDX2_AUDIO
, lsmash_form_qtff_box_type
);
2620 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_CDX4_AUDIO
, lsmash_form_qtff_box_type
);
2621 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_DVCA_AUDIO
, lsmash_form_qtff_box_type
);
2622 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_DVI_AUDIO
, lsmash_form_qtff_box_type
);
2623 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_FL32_AUDIO
, lsmash_form_qtff_box_type
);
2624 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_FL64_AUDIO
, lsmash_form_qtff_box_type
);
2625 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_IMA4_AUDIO
, lsmash_form_qtff_box_type
);
2626 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_IN24_AUDIO
, lsmash_form_qtff_box_type
);
2627 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_IN32_AUDIO
, lsmash_form_qtff_box_type
);
2628 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_LPCM_AUDIO
, lsmash_form_qtff_box_type
);
2629 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_SOWT_AUDIO
, lsmash_form_qtff_box_type
);
2630 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_TWOS_AUDIO
, lsmash_form_qtff_box_type
);
2631 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_ULAW_AUDIO
, lsmash_form_qtff_box_type
);
2632 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_VDVA_AUDIO
, lsmash_form_qtff_box_type
);
2633 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_FULLMP3_AUDIO
, lsmash_form_qtff_box_type
);
2634 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_MP3_AUDIO
, lsmash_form_qtff_box_type
);
2635 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_ADPCM2_AUDIO
, lsmash_form_qtff_box_type
);
2636 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_ADPCM17_AUDIO
, lsmash_form_qtff_box_type
);
2637 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_GSM49_AUDIO
, lsmash_form_qtff_box_type
);
2638 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_NOT_SPECIFIED
, lsmash_form_qtff_box_type
);
2639 ADD_DESCRIPTION_READER_TABLE_ELEMENT( QT_CODEC_TYPE_TEXT_TEXT
, lsmash_form_qtff_box_type
);
2640 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_TX3G_TEXT
, lsmash_form_iso_box_type
);
2641 ADD_DESCRIPTION_READER_TABLE_ELEMENT( ISOM_CODEC_TYPE_MP4S_SYSTEM
, lsmash_form_iso_box_type
);
2642 ADD_DESCRIPTION_READER_TABLE_ELEMENT( LSMASH_CODEC_TYPE_RAW
, lsmash_form_qtff_box_type
);
2643 ADD_DESCRIPTION_READER_TABLE_ELEMENT( LSMASH_CODEC_TYPE_UNSPECIFIED
, NULL
);
2644 #undef ADD_DESCRIPTION_READER_TABLE_ELEMENT
2646 for( int i
= 0; description_reader_table
[i
].form_box_type_func
; i
++ )
2647 if( box
->type
.fourcc
== description_reader_table
[i
].fourcc
)
2649 form_box_type_func
= description_reader_table
[i
].form_box_type_func
;
2654 if( lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_WAVE
) )
2656 form_box_type_func
= lsmash_form_qtff_box_type
;
2657 if( box
->type
.fourcc
== QT_BOX_TYPE_FRMA
.fourcc
) reader_func
= isom_read_frma
;
2658 else if( box
->type
.fourcc
== QT_BOX_TYPE_ENDA
.fourcc
) reader_func
= isom_read_enda
;
2659 else if( box
->type
.fourcc
== QT_BOX_TYPE_ESDS
.fourcc
) reader_func
= isom_read_esds
;
2660 else if( box
->type
.fourcc
== QT_BOX_TYPE_CHAN
.fourcc
) reader_func
= isom_read_chan
;
2661 else if( box
->type
.fourcc
== QT_BOX_TYPE_TERMINATOR
.fourcc
) reader_func
= isom_read_terminator
;
2662 else reader_func
= isom_read_codec_specific
;
2665 if( lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_TREF
) )
2667 form_box_type_func
= lsmash_form_iso_box_type
;
2668 reader_func
= isom_read_track_reference_type
;
2671 if( lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_DREF
) )
2673 if( box
->type
.fourcc
== ISOM_BOX_TYPE_URL
.fourcc
2674 || box
->type
.fourcc
== ISOM_BOX_TYPE_URN
.fourcc
)
2675 form_box_type_func
= lsmash_form_iso_box_type
;
2676 else if( box
->type
.fourcc
== QT_BOX_TYPE_ALIS
.fourcc
2677 || box
->type
.fourcc
== QT_BOX_TYPE_RSRC
.fourcc
)
2678 form_box_type_func
= lsmash_form_qtff_box_type
;
2679 reader_func
= isom_read_dref_entry
;
2682 static struct box_reader_table_tag
2684 lsmash_compact_box_type_t fourcc
;
2685 lsmash_box_type_t (*form_box_type_func
)( lsmash_compact_box_type_t
);
2686 int (*reader_func
)( lsmash_file_t
*, isom_box_t
*, isom_box_t
*, int );
2687 } box_reader_table
[128] = { { 0, NULL
, NULL
} };
2688 if( !box_reader_table
[0].reader_func
)
2690 /* Initialize the table. */
2692 #define ADD_BOX_READER_TABLE_ELEMENT( type, form_box_type_func, reader_func ) \
2693 box_reader_table[i++] = (struct box_reader_table_tag){ type.fourcc, form_box_type_func, reader_func }
2694 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_FTYP
, lsmash_form_iso_box_type
, isom_read_ftyp
);
2695 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_STYP
, lsmash_form_iso_box_type
, isom_read_styp
);
2696 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_SIDX
, lsmash_form_iso_box_type
, isom_read_sidx
);
2697 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_MOOV
, lsmash_form_iso_box_type
, isom_read_moov
);
2698 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_MVHD
, lsmash_form_iso_box_type
, isom_read_mvhd
);
2699 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_IODS
, lsmash_form_iso_box_type
, isom_read_iods
);
2700 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_CTAB
, lsmash_form_qtff_box_type
, isom_read_ctab
);
2701 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_ESDS
, lsmash_form_iso_box_type
, isom_read_esds
);
2702 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_TRAK
, lsmash_form_iso_box_type
, isom_read_trak
);
2703 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_TKHD
, lsmash_form_iso_box_type
, isom_read_tkhd
);
2704 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_TAPT
, lsmash_form_qtff_box_type
, isom_read_tapt
);
2705 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_CLEF
, lsmash_form_qtff_box_type
, isom_read_clef
);
2706 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_PROF
, lsmash_form_qtff_box_type
, isom_read_prof
);
2707 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_ENOF
, lsmash_form_qtff_box_type
, isom_read_enof
);
2708 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_EDTS
, lsmash_form_iso_box_type
, isom_read_edts
);
2709 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_ELST
, lsmash_form_iso_box_type
, isom_read_elst
);
2710 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_TREF
, lsmash_form_iso_box_type
, isom_read_tref
);
2711 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_MDIA
, lsmash_form_iso_box_type
, isom_read_mdia
);
2712 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_MDHD
, lsmash_form_iso_box_type
, isom_read_mdhd
);
2713 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_HDLR
, lsmash_form_iso_box_type
, isom_read_hdlr
);
2714 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_MINF
, lsmash_form_iso_box_type
, isom_read_minf
);
2715 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_VMHD
, lsmash_form_iso_box_type
, isom_read_vmhd
);
2716 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_SMHD
, lsmash_form_iso_box_type
, isom_read_smhd
);
2717 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_HMHD
, lsmash_form_iso_box_type
, isom_read_hmhd
);
2718 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_NMHD
, lsmash_form_iso_box_type
, isom_read_nmhd
);
2719 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_GMHD
, lsmash_form_qtff_box_type
, isom_read_gmhd
);
2720 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_GMIN
, lsmash_form_qtff_box_type
, isom_read_gmin
);
2721 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_TEXT
, lsmash_form_qtff_box_type
, isom_read_text
);
2722 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_DINF
, lsmash_form_iso_box_type
, isom_read_dinf
);
2723 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_DREF
, lsmash_form_iso_box_type
, isom_read_dref
);
2724 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_STBL
, lsmash_form_iso_box_type
, isom_read_stbl
);
2725 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_STSD
, lsmash_form_iso_box_type
, isom_read_stsd
);
2726 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_BTRT
, lsmash_form_iso_box_type
, isom_read_btrt
);
2727 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_COLR
, lsmash_form_iso_box_type
, isom_read_colr
);
2728 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_CLAP
, lsmash_form_iso_box_type
, isom_read_clap
);
2729 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_PASP
, lsmash_form_iso_box_type
, isom_read_pasp
);
2730 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_GLBL
, lsmash_form_qtff_box_type
, isom_read_glbl
);
2731 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_GAMA
, lsmash_form_qtff_box_type
, isom_read_gama
);
2732 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_FIEL
, lsmash_form_qtff_box_type
, isom_read_fiel
);
2733 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_CSPC
, lsmash_form_qtff_box_type
, isom_read_cspc
);
2734 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_SGBT
, lsmash_form_qtff_box_type
, isom_read_sgbt
);
2735 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_STSL
, lsmash_form_iso_box_type
, isom_read_stsl
);
2736 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_WAVE
, lsmash_form_qtff_box_type
, isom_read_wave
);
2737 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_CHAN
, lsmash_form_qtff_box_type
, isom_read_chan
);
2738 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_SRAT
, lsmash_form_iso_box_type
, isom_read_srat
);
2739 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_FTAB
, lsmash_form_iso_box_type
, isom_read_ftab
);
2740 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_STTS
, lsmash_form_iso_box_type
, isom_read_stts
);
2741 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_CTTS
, lsmash_form_iso_box_type
, isom_read_ctts
);
2742 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_CSLG
, lsmash_form_iso_box_type
, isom_read_cslg
);
2743 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_STSS
, lsmash_form_iso_box_type
, isom_read_stss
);
2744 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_STPS
, lsmash_form_qtff_box_type
, isom_read_stps
);
2745 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_SDTP
, lsmash_form_iso_box_type
, isom_read_sdtp
);
2746 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_STSC
, lsmash_form_iso_box_type
, isom_read_stsc
);
2747 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_STSZ
, lsmash_form_iso_box_type
, isom_read_stsz
);
2748 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_STZ2
, lsmash_form_iso_box_type
, isom_read_stz2
);
2749 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_STCO
, lsmash_form_iso_box_type
, isom_read_stco
);
2750 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_CO64
, lsmash_form_iso_box_type
, isom_read_stco
);
2751 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_SGPD
, lsmash_form_iso_box_type
, isom_read_sgpd
);
2752 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_SBGP
, lsmash_form_iso_box_type
, isom_read_sbgp
);
2753 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_UDTA
, lsmash_form_iso_box_type
, isom_read_udta
);
2754 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_CHPL
, lsmash_form_iso_box_type
, isom_read_chpl
);
2755 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_WLOC
, lsmash_form_qtff_box_type
, isom_read_WLOC
);
2756 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_LOOP
, lsmash_form_qtff_box_type
, isom_read_LOOP
);
2757 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_SELO
, lsmash_form_qtff_box_type
, isom_read_SelO
);
2758 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_ALLF
, lsmash_form_qtff_box_type
, isom_read_AllF
);
2759 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_MVEX
, lsmash_form_iso_box_type
, isom_read_mvex
);
2760 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_MEHD
, lsmash_form_iso_box_type
, isom_read_mehd
);
2761 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_TREX
, lsmash_form_iso_box_type
, isom_read_trex
);
2762 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_MOOF
, lsmash_form_iso_box_type
, isom_read_moof
);
2763 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_MFHD
, lsmash_form_iso_box_type
, isom_read_mfhd
);
2764 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_TRAF
, lsmash_form_iso_box_type
, isom_read_traf
);
2765 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_TFHD
, lsmash_form_iso_box_type
, isom_read_tfhd
);
2766 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_TFDT
, lsmash_form_iso_box_type
, isom_read_tfdt
);
2767 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_TRUN
, lsmash_form_iso_box_type
, isom_read_trun
);
2768 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_FREE
, lsmash_form_iso_box_type
, isom_read_free
);
2769 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_SKIP
, lsmash_form_iso_box_type
, isom_read_free
);
2770 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_MDAT
, lsmash_form_iso_box_type
, isom_read_mdat
);
2771 ADD_BOX_READER_TABLE_ELEMENT( QT_BOX_TYPE_KEYS
, lsmash_form_qtff_box_type
, isom_read_keys
);
2772 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_MFRA
, lsmash_form_iso_box_type
, isom_read_mfra
);
2773 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_TFRA
, lsmash_form_iso_box_type
, isom_read_tfra
);
2774 ADD_BOX_READER_TABLE_ELEMENT( ISOM_BOX_TYPE_MFRO
, lsmash_form_iso_box_type
, isom_read_mfro
);
2775 ADD_BOX_READER_TABLE_ELEMENT( LSMASH_BOX_TYPE_UNSPECIFIED
, NULL
, NULL
);
2776 #undef ADD_BOX_READER_TABLE_ELEMENT
2778 for( int i
= 0; box_reader_table
[i
].reader_func
; i
++ )
2779 if( box
->type
.fourcc
== box_reader_table
[i
].fourcc
)
2781 form_box_type_func
= box_reader_table
[i
].form_box_type_func
;
2782 reader_func
= box_reader_table
[i
].reader_func
;
2785 if( box
->type
.fourcc
== ISOM_BOX_TYPE_META
.fourcc
)
2787 if( lsmash_bs_is_end ( bs
, 3 ) == 0
2788 && lsmash_bs_show_be32( bs
, 0 ) == 0 )
2789 form_box_type_func
= lsmash_form_iso_box_type
;
2791 form_box_type_func
= lsmash_form_qtff_box_type
;
2792 reader_func
= isom_read_meta
;
2795 if( box
->type
.fourcc
== ISOM_BOX_TYPE_ILST
.fourcc
)
2797 if( lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_META
) )
2798 form_box_type_func
= lsmash_form_iso_box_type
;
2799 else if( lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_META
) )
2800 form_box_type_func
= lsmash_form_qtff_box_type
;
2801 if( form_box_type_func
)
2803 reader_func
= isom_read_ilst
;
2807 if( lsmash_check_box_type_identical( parent
->type
, ISOM_BOX_TYPE_ILST
) )
2808 form_box_type_func
= lsmash_form_iso_box_type
;
2809 else if( lsmash_check_box_type_identical( parent
->type
, QT_BOX_TYPE_ILST
) )
2810 form_box_type_func
= lsmash_form_qtff_box_type
;
2811 if( form_box_type_func
)
2813 reader_func
= isom_read_metaitem
;
2816 if( parent
->parent
&& parent
->parent
->type
.fourcc
== ISOM_BOX_TYPE_ILST
.fourcc
)
2818 if( box
->type
.fourcc
== ISOM_BOX_TYPE_MEAN
.fourcc
)
2819 reader_func
= isom_read_mean
;
2820 else if( box
->type
.fourcc
== ISOM_BOX_TYPE_NAME
.fourcc
)
2821 reader_func
= isom_read_name
;
2822 else if( box
->type
.fourcc
== ISOM_BOX_TYPE_DATA
.fourcc
)
2823 reader_func
= isom_read_data
;
2826 form_box_type_func
= lsmash_form_iso_box_type
;
2830 else if( box
->type
.fourcc
== ISOM_BOX_TYPE_CPRT
.fourcc
)
2832 /* Avoid confusing udta.cprt with ilst.cprt. */
2833 form_box_type_func
= lsmash_form_iso_box_type
;
2834 reader_func
= isom_read_cprt
;
2837 if( parent
->parent
&& lsmash_check_box_type_identical( parent
->parent
->type
, ISOM_BOX_TYPE_STSD
) )
2839 static struct codec_specific_marker_table_tag
2841 lsmash_compact_box_type_t fourcc
;
2842 lsmash_box_type_t (*form_box_type_func
)( lsmash_compact_box_type_t
);
2843 } codec_specific_marker_table
[16] = { { 0, NULL
} };
2844 if( !codec_specific_marker_table
[0].form_box_type_func
)
2846 /* Initialize the table. */
2848 #define ADD_CODEC_SPECIFIC_MARKER_TABLE_ELEMENT( type, form_box_type_func ) \
2849 codec_specific_marker_table[i++] = (struct codec_specific_marker_table_tag){ type.fourcc, form_box_type_func }
2850 ADD_CODEC_SPECIFIC_MARKER_TABLE_ELEMENT( ISOM_BOX_TYPE_ALAC
, lsmash_form_iso_box_type
);
2851 ADD_CODEC_SPECIFIC_MARKER_TABLE_ELEMENT( ISOM_BOX_TYPE_AVCC
, lsmash_form_iso_box_type
);
2852 ADD_CODEC_SPECIFIC_MARKER_TABLE_ELEMENT( ISOM_BOX_TYPE_DAC3
, lsmash_form_iso_box_type
);
2853 ADD_CODEC_SPECIFIC_MARKER_TABLE_ELEMENT( ISOM_BOX_TYPE_DAMR
, lsmash_form_iso_box_type
);
2854 ADD_CODEC_SPECIFIC_MARKER_TABLE_ELEMENT( ISOM_BOX_TYPE_DDTS
, lsmash_form_iso_box_type
);
2855 ADD_CODEC_SPECIFIC_MARKER_TABLE_ELEMENT( ISOM_BOX_TYPE_DEC3
, lsmash_form_iso_box_type
);
2856 ADD_CODEC_SPECIFIC_MARKER_TABLE_ELEMENT( ISOM_BOX_TYPE_DVC1
, lsmash_form_iso_box_type
);
2857 ADD_CODEC_SPECIFIC_MARKER_TABLE_ELEMENT( ISOM_BOX_TYPE_HVCC
, lsmash_form_iso_box_type
);
2858 ADD_CODEC_SPECIFIC_MARKER_TABLE_ELEMENT( ISOM_BOX_TYPE_WFEX
, lsmash_form_iso_box_type
);
2859 ADD_CODEC_SPECIFIC_MARKER_TABLE_ELEMENT( QT_BOX_TYPE_GLBL
, lsmash_form_qtff_box_type
);
2860 ADD_CODEC_SPECIFIC_MARKER_TABLE_ELEMENT( LSMASH_BOX_TYPE_UNSPECIFIED
, NULL
);
2861 #undef ADD_CODEC_SPECIFIC_MARKER_TABLE_ELEMENT
2863 for( int i
= 0; codec_specific_marker_table
[i
].form_box_type_func
; i
++ )
2864 if( box
->type
.fourcc
== codec_specific_marker_table
[i
].fourcc
)
2866 form_box_type_func
= codec_specific_marker_table
[i
].form_box_type_func
;
2869 reader_func
= isom_read_codec_specific
;
2872 if( form_box_type_func
)
2873 box
->type
= form_box_type_func( box
->type
.fourcc
);
2874 if( (ret
= isom_read_fullbox_common_extension( bs
, box
)) < 0 )
2877 ? reader_func( file
, box
, parent
, level
)
2878 : isom_read_unknown_box( file
, box
, parent
, level
);
2881 int isom_read_file( lsmash_file_t
*file
)
2883 lsmash_bs_t
*bs
= file
->bs
;
2885 return LSMASH_ERR_NAMELESS
;
2886 /* Reset the counter so that we can use it to get position within the box. */
2887 lsmash_bs_reset_counter( bs
);
2888 if( file
->flags
& LSMASH_FILE_MODE_DUMP
)
2890 file
->print
= lsmash_create_entry_list();
2892 return LSMASH_ERR_MEMORY_ALLOC
;
2894 file
->size
= UINT64_MAX
;
2896 int ret
= isom_read_children( file
, &box
, file
, 0 );
2897 file
->size
= box
.size
;
2898 lsmash_bs_empty( bs
);
2899 bs
->error
= 0; /* Clear error flag. */
2902 return isom_check_compatibility( file
);