timelineeditor: Support importing timecode format v1 and automatic timescale generation.
[L-SMASH.git] / print.c
blob9b1976395712411dcb05e90867f596fd571c6e60
1 /*****************************************************************************
2 * print.c:
3 *****************************************************************************
4 * Copyright (C) 2010 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 #ifdef LSMASH_DEMUXER_ENABLED
25 #include "internal.h" /* must be placed first */
27 #include <stdlib.h>
28 #include <string.h>
29 #include <inttypes.h>
30 #include <stdarg.h> /* for isom_iprintf */
32 #include "box.h"
35 typedef int (*isom_print_box_t)( lsmash_root_t *, isom_box_t *, int );
37 typedef struct
39 int level;
40 isom_box_t *box;
41 isom_print_box_t func;
42 } isom_print_entry_t;
44 static void isom_iprintf( int indent, const char *format, ... )
46 va_list args;
47 va_start( args, format );
48 for( int i = 0; i < indent; i++ )
49 printf( " " );
50 vprintf( format, args );
51 va_end( args );
54 static void isom_iprintf_duration( int indent, char *field_name, uint64_t duration, uint32_t timescale )
56 if( !timescale )
58 isom_iprintf( indent, "duration = %"PRIu64"\n", duration );
59 return;
61 int dur = duration / timescale;
62 int hour = (dur / 3600) % 24;
63 int min = (dur / 60) % 60;
64 int sec = dur % 60;
65 int ms = ((double)duration / timescale - (hour * 3600 + min * 60 + sec)) * 1e3 + 0.5;
66 static char str[32];
67 sprintf( str, "%02d:%02d:%02d.%03d", hour, min, sec, ms );
68 isom_iprintf( indent, "%s = %"PRIu64" (%s)\n", field_name, duration, str );
71 static char *isom_mp4time2utc( uint64_t mp4time )
73 int year_offset = mp4time / 31536000;
74 int leap_years = year_offset / 4 + ((mp4time / 86400) > 366); /* 1904 itself is leap year */
75 int day = (mp4time / 86400) - (year_offset * 365) - leap_years + 1;
76 while( day < 1 )
78 --year_offset;
79 leap_years = year_offset / 4 + ((mp4time / 86400) > 366);
80 day = (mp4time / 86400) - (year_offset * 365) - leap_years + 1;
82 int year = 1904 + year_offset;
83 int is_leap = (!(year % 4) && (year % 100)) || !(year % 400);
84 static const int month_days[13] = { 29, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
85 int month;
86 for( month = 1; month <= 12; month++ )
88 int i = (month == 2 && is_leap) ? 0 : month;
89 if( day <= month_days[i] )
90 break;
91 day -= month_days[i];
93 int hour = (mp4time / 3600) % 24;
94 int min = (mp4time / 60) % 60;
95 int sec = mp4time % 60;
96 static char utc[64];
97 sprintf( utc, "UTC %d/%02d/%02d, %02d:%02d:%02d\n", year, month, day, hour, min, sec );
98 return utc;
101 static void isom_iprint_matrix( int indent, int32_t *matrix )
103 isom_iprintf( indent, "| a, b, u | | %f, %f, %f |\n", lsmash_fixed2double( matrix[0], 16 ),
104 lsmash_fixed2double( matrix[1], 16 ),
105 lsmash_fixed2double( matrix[2], 30 ) );
106 isom_iprintf( indent, "| c, d, v | = | %f, %f, %f |\n", lsmash_fixed2double( matrix[3], 16 ),
107 lsmash_fixed2double( matrix[4], 16 ),
108 lsmash_fixed2double( matrix[5], 30 ) );
109 isom_iprintf( indent, "| x, y, z | | %f, %f, %f |\n", lsmash_fixed2double( matrix[6], 16 ),
110 lsmash_fixed2double( matrix[7], 16 ),
111 lsmash_fixed2double( matrix[8], 30 ) );
114 static void isom_iprint_rgb_color( int indent, uint16_t *color )
116 isom_iprintf( indent, "{ R, G, B } = { %"PRIu16", %"PRIu16", %"PRIu16" }\n", color[0], color[1], color[2] );
119 static void isom_iprint_rgba_color( int indent, uint8_t *color )
121 isom_iprintf( indent, "{ R, G, B, A } = { %"PRIu8", %"PRIu8", %"PRIu8", %"PRIu8" }\n", color[0], color[1], color[2], color[3] );
124 static char *isom_unpack_iso_language( uint16_t language )
126 static char unpacked[4];
127 unpacked[0] = ((language >> 10) & 0x1f) + 0x60;
128 unpacked[1] = ((language >> 5) & 0x1f) + 0x60;
129 unpacked[2] = ( language & 0x1f) + 0x60;
130 unpacked[3] = 0;
131 return unpacked;
134 static void isom_iprint_sample_description_common_reserved( int indent, uint8_t *reserved )
136 uint64_t temp = ((uint64_t)reserved[0] << 40)
137 | ((uint64_t)reserved[1] << 32)
138 | ((uint64_t)reserved[2] << 24)
139 | ((uint64_t)reserved[3] << 16)
140 | ((uint64_t)reserved[4] << 8)
141 | (uint64_t)reserved[5];
142 isom_iprintf( indent, "reserved = 0x%012"PRIx64"\n", temp );
145 static void isom_iprint_sample_flags( int indent, char *field_name, isom_sample_flags_t *flags )
147 uint32_t temp = (flags->reserved << 28)
148 | (flags->is_leading << 26)
149 | (flags->sample_depends_on << 24)
150 | (flags->sample_is_depended_on << 22)
151 | (flags->sample_has_redundancy << 20)
152 | (flags->sample_padding_value << 17)
153 | (flags->sample_is_non_sync_sample << 16)
154 | flags->sample_degradation_priority;
155 isom_iprintf( indent++, "%s = 0x%08"PRIx32"\n", field_name, temp );
156 if( flags->is_leading & ISOM_SAMPLE_IS_UNDECODABLE_LEADING ) isom_iprintf( indent, "undecodable leading\n" );
157 else if( flags->is_leading & ISOM_SAMPLE_IS_NOT_LEADING ) isom_iprintf( indent, "non-leading\n" );
158 else if( flags->is_leading & ISOM_SAMPLE_IS_DECODABLE_LEADING ) isom_iprintf( indent, "decodable leading\n" );
159 if( flags->sample_depends_on & ISOM_SAMPLE_IS_INDEPENDENT ) isom_iprintf( indent, "independent\n" );
160 else if( flags->sample_depends_on & ISOM_SAMPLE_IS_NOT_INDEPENDENT ) isom_iprintf( indent, "dependent\n" );
161 if( flags->sample_is_depended_on & ISOM_SAMPLE_IS_NOT_DISPOSABLE ) isom_iprintf( indent, "non-disposable\n" );
162 else if( flags->sample_is_depended_on & ISOM_SAMPLE_IS_DISPOSABLE ) isom_iprintf( indent, "disposable\n" );
163 if( flags->sample_has_redundancy & ISOM_SAMPLE_HAS_REDUNDANCY ) isom_iprintf( indent, "redundant\n" );
164 else if( flags->sample_has_redundancy & ISOM_SAMPLE_HAS_NO_REDUNDANCY ) isom_iprintf( indent, "non-redundant\n" );
165 if( flags->sample_padding_value )
166 isom_iprintf( indent, "padding_bits = %"PRIu8"\n", flags->sample_padding_value );
167 isom_iprintf( indent, flags->sample_is_non_sync_sample ? "non-sync sample\n" : "sync sample\n" );
168 isom_iprintf( indent, "degradation_priority = %"PRIu16"\n", flags->sample_degradation_priority );
171 static inline int isom_print_simple( isom_box_t *box, int level, char *name )
173 if( !box )
174 return -1;
175 int indent = level;
176 isom_iprintf( indent++, "[%s: %s]\n", isom_4cc2str( box->type ), name );
177 isom_iprintf( indent, "position = %"PRIu64"\n", box->pos );
178 isom_iprintf( indent, "size = %"PRIu64"\n", box->size );
179 return 0;
182 static void isom_print_basebox_common( int indent, isom_box_t *box, char *name )
184 isom_print_simple( box, indent, name );
187 static void isom_print_fullbox_common( int indent, isom_box_t *box, char *name )
189 isom_iprintf( indent++, "[%s: %s]\n", isom_4cc2str( box->type ), name );
190 isom_iprintf( indent, "position = %"PRIu64"\n", box->pos );
191 isom_iprintf( indent, "size = %"PRIu64"\n", box->size );
192 isom_iprintf( indent, "version = %"PRIu8"\n", box->version );
193 isom_iprintf( indent, "flags = 0x%06"PRIx32"\n", box->flags & 0x00ffffff );
196 static void isom_print_box_common( int indent, isom_box_t *box, char *name )
198 isom_box_t *parent = box->parent;
199 if( parent && parent->type == ISOM_BOX_TYPE_STSD )
201 isom_print_basebox_common( indent, box, name );
202 return;
204 if( isom_is_fullbox( box ) )
205 isom_print_fullbox_common( indent, box, name );
206 else
207 isom_print_basebox_common( indent, box, name );
210 static int isom_print_unknown( lsmash_root_t *root, isom_box_t *box, int level )
212 if( !box )
213 return -1;
214 int indent = level;
215 isom_iprintf( indent++, "[%s]\n", isom_4cc2str( box->type ) );
216 isom_iprintf( indent, "size = %"PRIu64"\n", box->size );
217 return 0;
220 static int isom_print_ftyp( lsmash_root_t *root, isom_box_t *box, int level )
222 if( !box )
223 return -1;
224 isom_ftyp_t *ftyp = (isom_ftyp_t *)box;
225 int indent = level;
226 isom_print_box_common( indent++, box, "File Type Box" );
227 isom_iprintf( indent, "major_brand = %s\n", isom_4cc2str( ftyp->major_brand ) );
228 isom_iprintf( indent, "minor_version = %"PRIu32"\n", ftyp->minor_version );
229 isom_iprintf( indent++, "compatible_brands\n" );
230 for( uint32_t i = 0; i < ftyp->brand_count; i++ )
231 isom_iprintf( indent, "brand[%"PRIu32"] = %s\n", i, isom_4cc2str( ftyp->compatible_brands[i] ) );
232 return 0;
235 static int isom_print_moov( lsmash_root_t *root, isom_box_t *box, int level )
237 return isom_print_simple( box, level, "Movie Box" );
240 static int isom_print_mvhd( lsmash_root_t *root, isom_box_t *box, int level )
242 if( !box )
243 return -1;
244 isom_mvhd_t *mvhd = (isom_mvhd_t *)box;
245 int indent = level;
246 isom_print_box_common( indent++, box, "Movie Header Box" );
247 isom_iprintf( indent, "creation_time = %s", isom_mp4time2utc( mvhd->creation_time ) );
248 isom_iprintf( indent, "modification_time = %s", isom_mp4time2utc( mvhd->modification_time ) );
249 isom_iprintf( indent, "timescale = %"PRIu32"\n", mvhd->timescale );
250 isom_iprintf_duration( indent, "duration", mvhd->duration, mvhd->timescale );
251 isom_iprintf( indent, "rate = %f\n", lsmash_fixed2double( mvhd->rate, 16 ) );
252 isom_iprintf( indent, "volume = %f\n", lsmash_fixed2double( mvhd->volume, 8 ) );
253 isom_iprintf( indent, "reserved = 0x%04"PRIx16"\n", mvhd->reserved );
254 if( root->qt_compatible )
256 isom_iprintf( indent, "preferredLong1 = 0x%08"PRIx32"\n", mvhd->preferredLong[0] );
257 isom_iprintf( indent, "preferredLong2 = 0x%08"PRIx32"\n", mvhd->preferredLong[1] );
258 isom_iprintf( indent, "transformation matrix\n" );
259 isom_iprint_matrix( indent + 1, mvhd->matrix );
260 isom_iprintf( indent, "previewTime = %"PRId32"\n", mvhd->previewTime );
261 isom_iprintf( indent, "previewDuration = %"PRId32"\n", mvhd->previewDuration );
262 isom_iprintf( indent, "posterTime = %"PRId32"\n", mvhd->posterTime );
263 isom_iprintf( indent, "selectionTime = %"PRId32"\n", mvhd->selectionTime );
264 isom_iprintf( indent, "selectionDuration = %"PRId32"\n", mvhd->selectionDuration );
265 isom_iprintf( indent, "currentTime = %"PRId32"\n", mvhd->currentTime );
267 else
269 isom_iprintf( indent, "reserved = 0x%08"PRIx32"\n", mvhd->preferredLong[0] );
270 isom_iprintf( indent, "reserved = 0x%08"PRIx32"\n", mvhd->preferredLong[1] );
271 isom_iprintf( indent, "transformation matrix\n" );
272 isom_iprint_matrix( indent + 1, mvhd->matrix );
273 isom_iprintf( indent, "pre_defined = 0x%08"PRIx32"\n", mvhd->previewTime );
274 isom_iprintf( indent, "pre_defined = 0x%08"PRIx32"\n", mvhd->previewDuration );
275 isom_iprintf( indent, "pre_defined = 0x%08"PRIx32"\n", mvhd->posterTime );
276 isom_iprintf( indent, "pre_defined = 0x%08"PRIx32"\n", mvhd->selectionTime );
277 isom_iprintf( indent, "pre_defined = 0x%08"PRIx32"\n", mvhd->selectionDuration );
278 isom_iprintf( indent, "pre_defined = 0x%08"PRIx32"\n", mvhd->currentTime );
280 isom_iprintf( indent, "next_track_ID = %"PRIu32"\n", mvhd->next_track_ID );
281 return 0;
284 static int isom_print_iods( lsmash_root_t *root, isom_box_t *box, int level )
286 return isom_print_simple( box, level, "Object Descriptor Box" );
289 static int isom_print_esds( lsmash_root_t *root, isom_box_t *box, int level )
291 return isom_print_simple( box, level, "ES Descriptor Box" );
294 static int isom_print_trak( lsmash_root_t *root, isom_box_t *box, int level )
296 return isom_print_simple( box, level, "Track Box" );
299 static int isom_print_tkhd( lsmash_root_t *root, isom_box_t *box, int level )
301 if( !box )
302 return -1;
303 isom_tkhd_t *tkhd = (isom_tkhd_t *)box;
304 int indent = level;
305 isom_print_box_common( indent++, box, "Track Header Box" );
306 ++indent;
307 if( tkhd->flags & ISOM_TRACK_ENABLED )
308 isom_iprintf( indent, "Track enabled\n" );
309 else
310 isom_iprintf( indent, "Track disabled\n" );
311 if( tkhd->flags & ISOM_TRACK_IN_MOVIE )
312 isom_iprintf( indent, "Track in movie\n" );
313 if( tkhd->flags & ISOM_TRACK_IN_PREVIEW )
314 isom_iprintf( indent, "Track in preview\n" );
315 if( root->qt_compatible && (tkhd->flags & QT_TRACK_IN_POSTER) )
316 isom_iprintf( indent, "Track in poster\n" );
317 isom_iprintf( --indent, "creation_time = %s", isom_mp4time2utc( tkhd->creation_time ) );
318 isom_iprintf( indent, "modification_time = %s", isom_mp4time2utc( tkhd->modification_time ) );
319 isom_iprintf( indent, "track_ID = %"PRIu32"\n", tkhd->track_ID );
320 isom_iprintf( indent, "reserved = 0x%08"PRIx32"\n", tkhd->reserved1 );
321 if( root && root->moov && root->moov->mvhd )
322 isom_iprintf_duration( indent, "duration", tkhd->duration, root->moov->mvhd->timescale );
323 else
324 isom_iprintf_duration( indent, "duration", tkhd->duration, 0 );
325 isom_iprintf( indent, "reserved = 0x%08"PRIx32"\n", tkhd->reserved2[0] );
326 isom_iprintf( indent, "reserved = 0x%08"PRIx32"\n", tkhd->reserved2[1] );
327 isom_iprintf( indent, "layer = %"PRId16"\n", tkhd->layer );
328 isom_iprintf( indent, "alternate_group = %"PRId16"\n", tkhd->alternate_group );
329 isom_iprintf( indent, "volume = %f\n", lsmash_fixed2double( tkhd->volume, 8 ) );
330 isom_iprintf( indent, "reserved = 0x%04"PRIx16"\n", tkhd->reserved3 );
331 isom_iprintf( indent, "transformation matrix\n" );
332 isom_iprint_matrix( indent + 1, tkhd->matrix );
333 isom_iprintf( indent, "width = %f\n", lsmash_fixed2double( tkhd->width, 16 ) );
334 isom_iprintf( indent, "height = %f\n", lsmash_fixed2double( tkhd->height, 16 ) );
335 return 0;
338 static int isom_print_tapt( lsmash_root_t *root, isom_box_t *box, int level )
340 return isom_print_simple( box, level, "Track Aperture Mode Dimensions Box" );
343 static int isom_print_clef( lsmash_root_t *root, isom_box_t *box, int level )
345 if( !box )
346 return -1;
347 isom_clef_t *clef = (isom_clef_t *)box;
348 int indent = level;
349 isom_print_box_common( indent++, box, "Track Clean Aperture Dimensions Box" );
350 isom_iprintf( indent, "width = %f\n", lsmash_fixed2double( clef->width, 16 ) );
351 isom_iprintf( indent, "height = %f\n", lsmash_fixed2double( clef->height, 16 ) );
352 return 0;
355 static int isom_print_prof( lsmash_root_t *root, isom_box_t *box, int level )
357 if( !box )
358 return -1;
359 isom_prof_t *prof = (isom_prof_t *)box;
360 int indent = level;
361 isom_print_box_common( indent++, box, "Track Production Aperture Dimensions Box" );
362 isom_iprintf( indent, "width = %f\n", lsmash_fixed2double( prof->width, 16 ) );
363 isom_iprintf( indent, "height = %f\n", lsmash_fixed2double( prof->height, 16 ) );
364 return 0;
367 static int isom_print_enof( lsmash_root_t *root, isom_box_t *box, int level )
369 if( !box )
370 return -1;
371 isom_enof_t *enof = (isom_enof_t *)box;
372 int indent = level;
373 isom_print_box_common( indent++, box, "Track Encoded Pixels Dimensions Box" );
374 isom_iprintf( indent, "width = %f\n", lsmash_fixed2double( enof->width, 16 ) );
375 isom_iprintf( indent, "height = %f\n", lsmash_fixed2double( enof->height, 16 ) );
376 return 0;
379 static int isom_print_edts( lsmash_root_t *root, isom_box_t *box, int level )
381 return isom_print_simple( box, level, "Edit Box" );
384 static int isom_print_elst( lsmash_root_t *root, isom_box_t *box, int level )
386 if( !box )
387 return -1;
388 isom_elst_t *elst = (isom_elst_t *)box;
389 int indent = level;
390 uint32_t i = 0;
391 isom_print_box_common( indent++, box, "Edit List Box" );
392 isom_iprintf( indent, "entry_count = %"PRIu32"\n", elst->list->entry_count );
393 for( lsmash_entry_t *entry = elst->list->head; entry; entry = entry->next )
395 isom_elst_entry_t *data = (isom_elst_entry_t *)entry->data;
396 isom_iprintf( indent++, "entry[%"PRIu32"]\n", i++ );
397 isom_iprintf( indent, "segment_duration = %"PRIu64"\n", data->segment_duration );
398 isom_iprintf( indent, "media_time = %"PRId64"\n", data->media_time );
399 isom_iprintf( indent--, "media_rate = %f\n", lsmash_fixed2double( data->media_rate, 16 ) );
401 return 0;
404 static int isom_print_tref( lsmash_root_t *root, isom_box_t *box, int level )
406 return isom_print_simple( box, level, "Track Reference Box" );
409 static int isom_print_track_reference_type( lsmash_root_t *root, isom_box_t *box, int level )
411 if( !box )
412 return -1;
413 isom_tref_type_t *ref = (isom_tref_type_t *)box;
414 int indent = level;
415 isom_print_box_common( indent++, box, "Track Reference Type Box" );
416 for( uint32_t i = 0; i < ref->ref_count; i++ )
417 isom_iprintf( indent, "track_ID[%"PRIu32"] = %"PRIu32"\n", i, ref->track_ID[i] );
418 return 0;
421 return isom_print_simple( box, level, "Track Reference Type Box" );
424 static int isom_print_mdia( lsmash_root_t *root, isom_box_t *box, int level )
426 return isom_print_simple( box, level, "Media Box" );
429 static int isom_print_mdhd( lsmash_root_t *root, isom_box_t *box, int level )
431 if( !box )
432 return -1;
433 isom_mdhd_t *mdhd = (isom_mdhd_t *)box;
434 int indent = level;
435 isom_print_box_common( indent++, box, "Media Header Box" );
436 isom_iprintf( indent, "creation_time = %s", isom_mp4time2utc( mdhd->creation_time ) );
437 isom_iprintf( indent, "modification_time = %s", isom_mp4time2utc( mdhd->modification_time ) );
438 isom_iprintf( indent, "timescale = %"PRIu32"\n", mdhd->timescale );
439 isom_iprintf_duration( indent, "duration", mdhd->duration, mdhd->timescale );
440 if( mdhd->language >= 0x800 )
441 isom_iprintf( indent, "language = %s\n", isom_unpack_iso_language( mdhd->language ) );
442 else
443 isom_iprintf( indent, "language = %"PRIu16"\n", mdhd->language );
444 if( root->qt_compatible )
445 isom_iprintf( indent, "quality = %"PRId16"\n", mdhd->quality );
446 else
447 isom_iprintf( indent, "pre_defined = 0x%04"PRIx16"\n", mdhd->quality );
448 return 0;
451 static int isom_print_hdlr( lsmash_root_t *root, isom_box_t *box, int level )
453 if( !box )
454 return -1;
455 isom_hdlr_t *hdlr = (isom_hdlr_t *)box;
456 int indent = level;
457 char str[hdlr->componentName_length + 1];
458 memcpy( str, hdlr->componentName, hdlr->componentName_length );
459 str[hdlr->componentName_length] = 0;
460 isom_print_box_common( indent++, box, "Handler Reference Box" );
461 if( root->qt_compatible )
463 isom_iprintf( indent, "componentType = %s\n", isom_4cc2str( hdlr->componentType ) );
464 isom_iprintf( indent, "componentSubtype = %s\n", isom_4cc2str( hdlr->componentSubtype ) );
465 isom_iprintf( indent, "componentManufacturer = %s\n", isom_4cc2str( hdlr->componentManufacturer ) );
466 isom_iprintf( indent, "componentFlags = 0x%08"PRIx32"\n", hdlr->componentFlags );
467 isom_iprintf( indent, "componentFlagsMask = 0x%08"PRIx32"\n", hdlr->componentFlagsMask );
468 if( hdlr->componentName_length )
469 isom_iprintf( indent, "componentName = %s\n", &str[1] );
471 else
473 isom_iprintf( indent, "pre_defined = 0x%08"PRIx32"\n", hdlr->componentType );
474 isom_iprintf( indent, "handler_type = %s\n", isom_4cc2str( hdlr->componentSubtype ) );
475 isom_iprintf( indent, "reserved = 0x%08"PRIx32"\n", hdlr->componentManufacturer );
476 isom_iprintf( indent, "reserved = 0x%08"PRIx32"\n", hdlr->componentFlags );
477 isom_iprintf( indent, "reserved = 0x%08"PRIx32"\n", hdlr->componentFlagsMask );
478 isom_iprintf( indent, "name = %s\n", str );
480 return 0;
483 static int isom_print_minf( lsmash_root_t *root, isom_box_t *box, int level )
485 return isom_print_simple( box, level, "Media Information Box" );
488 static int isom_print_vmhd( lsmash_root_t *root, isom_box_t *box, int level )
490 if( !box )
491 return -1;
492 isom_vmhd_t *vmhd = (isom_vmhd_t *)box;
493 int indent = level;
494 isom_print_box_common( indent++, box, "Video Media Header Box" );
495 isom_iprintf( indent, "graphicsmode = %"PRIu16"\n", vmhd->graphicsmode );
496 isom_iprintf( indent, "opcolor\n" );
497 isom_iprint_rgb_color( indent + 1, vmhd->opcolor );
498 return 0;
501 static int isom_print_smhd( lsmash_root_t *root, isom_box_t *box, int level )
503 if( !box )
504 return -1;
505 isom_smhd_t *smhd = (isom_smhd_t *)box;
506 int indent = level;
507 isom_print_box_common( indent++, box, "Sound Media Header Box" );
508 isom_iprintf( indent, "balance = %f\n", lsmash_fixed2double( smhd->balance, 8 ) );
509 isom_iprintf( indent, "reserved = 0x%04"PRIx16"\n", smhd->reserved );
510 return 0;
513 static int isom_print_hmhd( lsmash_root_t *root, isom_box_t *box, int level )
515 if( !box )
516 return -1;
517 isom_hmhd_t *hmhd = (isom_hmhd_t *)box;
518 int indent = level;
519 isom_print_box_common( indent++, box, "Hint Media Header Box" );
520 isom_iprintf( indent, "maxPDUsize = %"PRIu16"\n", hmhd->maxPDUsize );
521 isom_iprintf( indent, "avgPDUsize = %"PRIu16"\n", hmhd->avgPDUsize );
522 isom_iprintf( indent, "maxbitrate = %"PRIu32"\n", hmhd->maxbitrate );
523 isom_iprintf( indent, "avgbitrate = %"PRIu32"\n", hmhd->avgbitrate );
524 isom_iprintf( indent, "reserved = 0x%08"PRIx32"\n", hmhd->reserved );
525 return 0;
528 static int isom_print_nmhd( lsmash_root_t *root, isom_box_t *box, int level )
530 return isom_print_simple( box, level, "Null Media Header Box" );
533 static int isom_print_gmhd( lsmash_root_t *root, isom_box_t *box, int level )
535 return isom_print_simple( box, level, "Generic Media Information Header Box" );
538 static int isom_print_gmin( lsmash_root_t *root, isom_box_t *box, int level )
540 if( !box )
541 return -1;
542 isom_gmin_t *gmin = (isom_gmin_t *)box;
543 int indent = level;
544 isom_print_box_common( indent++, box, "Generic Media Information Box" );
545 isom_iprintf( indent, "graphicsmode = %"PRIu16"\n", gmin->graphicsmode );
546 isom_iprintf( indent, "opcolor\n" );
547 isom_iprint_rgb_color( indent + 1, gmin->opcolor );
548 isom_iprintf( indent, "balance = %f\n", lsmash_fixed2double( gmin->balance, 8 ) );
549 isom_iprintf( indent, "reserved = 0x%04"PRIx16"\n", gmin->reserved );
550 return 0;
553 static int isom_print_text( lsmash_root_t *root, isom_box_t *box, int level )
555 if( !box )
556 return -1;
557 isom_text_t *text = (isom_text_t *)box;
558 int indent = level;
559 isom_print_box_common( indent++, box, "Text Media Information Box" );
560 isom_iprintf( indent, "Unknown matrix\n" );
561 isom_iprint_matrix( indent + 1, text->matrix );
562 return 0;
565 static int isom_print_dinf( lsmash_root_t *root, isom_box_t *box, int level )
567 return isom_print_simple( box, level, "Data Information Box" );
570 static int isom_print_dref( lsmash_root_t *root, isom_box_t *box, int level )
572 if( !box )
573 return -1;
574 isom_dref_t *dref = (isom_dref_t *)box;
575 int indent = level;
576 isom_print_box_common( indent++, box, "Data Reference Box" );
577 isom_iprintf( indent, "entry_count = %"PRIu16"\n", dref->list->entry_count );
578 return 0;
581 static int isom_print_url( lsmash_root_t *root, isom_box_t *box, int level )
583 if( !box )
584 return -1;
585 isom_dref_entry_t *url = (isom_dref_entry_t *)box;
586 int indent = level;
587 isom_print_box_common( indent++, box, "Data Entry Url Box" );
588 if( url->flags & 0x000001 )
589 isom_iprintf( indent, "location = in the same file\n" );
590 else
591 isom_iprintf( indent, "location = %s\n", url->location );
592 return 0;
595 static int isom_print_stbl( lsmash_root_t *root, isom_box_t *box, int level )
597 return isom_print_simple( box, level, "Sample Table Box" );
600 static int isom_print_stsd( lsmash_root_t *root, isom_box_t *box, int level )
602 if( !box || !((isom_stsd_t *)box)->list )
603 return -1;
604 isom_stsd_t *stsd = (isom_stsd_t *)box;
605 int indent = level;
606 isom_print_box_common( indent++, box, "Sample Description Box" );
607 isom_iprintf( indent, "entry_count = %"PRIu16"\n", stsd->list->entry_count );
608 return 0;
611 static int isom_print_visual_description( lsmash_root_t *root, isom_box_t *box, int level )
613 if( !box )
614 return -1;
615 isom_visual_entry_t *visual = (isom_visual_entry_t *)box;
616 int indent = level;
617 isom_iprintf( indent++, "[%s: Visual Description]\n", isom_4cc2str( visual->type ) );
618 isom_iprintf( indent, "position = %"PRIu64"\n", visual->pos );
619 isom_iprintf( indent, "size = %"PRIu64"\n", visual->size );
620 isom_iprint_sample_description_common_reserved( indent, visual->reserved );
621 isom_iprintf( indent, "data_reference_index = %"PRIu16"\n", visual->data_reference_index );
622 if( root->qt_compatible )
624 isom_iprintf( indent, "version = %"PRId16"\n", visual->version );
625 isom_iprintf( indent, "revision_level = %"PRId16"\n", visual->revision_level );
626 isom_iprintf( indent, "vendor = %s\n", isom_4cc2str( visual->vendor ) );
627 isom_iprintf( indent, "temporalQuality = %"PRIu32"\n", visual->temporalQuality );
628 isom_iprintf( indent, "spatialQuality = %"PRIu32"\n", visual->spatialQuality );
629 isom_iprintf( indent, "width = %"PRIu16"\n", visual->width );
630 isom_iprintf( indent, "height = %"PRIu16"\n", visual->height );
631 isom_iprintf( indent, "horizresolution = %f\n", lsmash_fixed2double( visual->horizresolution, 16 ) );
632 isom_iprintf( indent, "vertresolution = %f\n", lsmash_fixed2double( visual->vertresolution, 16 ) );
633 isom_iprintf( indent, "dataSize = %"PRIu32"\n", visual->dataSize );
634 isom_iprintf( indent, "frame_count = %"PRIu16"\n", visual->frame_count );
635 isom_iprintf( indent, "compressorname_length = %"PRIu8"\n", visual->compressorname[0] );
636 isom_iprintf( indent, "compressorname = %s\n", visual->compressorname + 1 );
637 isom_iprintf( indent, "depth = 0x%04"PRIx16, visual->depth );
638 if( visual->depth == 32 )
639 printf( " (colour with alpha)\n" );
640 else if( visual->depth >= 33 && visual->depth <= 40 )
641 printf( " (grayscale with no alpha)\n" );
642 else
643 printf( "\n" );
644 isom_iprintf( indent, "color_table_ID = %"PRId16"\n", visual->color_table_ID );
646 else
648 isom_iprintf( indent, "pre_defined = 0x%04"PRIx16"\n", visual->version );
649 isom_iprintf( indent, "reserved = 0x%04"PRIx16"\n", visual->revision_level );
650 isom_iprintf( indent, "pre_defined = 0x%08"PRIx32"\n", visual->vendor );
651 isom_iprintf( indent, "pre_defined = 0x%08"PRIx32"\n", visual->temporalQuality );
652 isom_iprintf( indent, "pre_defined = 0x%08"PRIx32"\n", visual->spatialQuality );
653 isom_iprintf( indent, "width = %"PRIu16"\n", visual->width );
654 isom_iprintf( indent, "height = %"PRIu16"\n", visual->height );
655 isom_iprintf( indent, "horizresolution = %f\n", lsmash_fixed2double( visual->horizresolution, 16 ) );
656 isom_iprintf( indent, "vertresolution = %f\n", lsmash_fixed2double( visual->vertresolution, 16 ) );
657 isom_iprintf( indent, "reserved = 0x%08"PRIx32"\n", visual->dataSize );
658 isom_iprintf( indent, "frame_count = %"PRIu16"\n", visual->frame_count );
659 isom_iprintf( indent, "compressorname_length = %"PRIu8"\n", visual->compressorname[0] );
660 isom_iprintf( indent, "compressorname = %s\n", visual->compressorname + 1 );
661 isom_iprintf( indent, "depth = 0x%04"PRIx16, visual->depth );
662 if( visual->depth == 0x0018 )
663 printf( " (colour with no alpha)\n" );
664 else if( visual->depth == 0x0028 )
665 printf( " (grayscale with no alpha)\n" );
666 else if( visual->depth == 0x0020 )
667 printf( " (gray or colour with alpha)\n" );
668 else
669 printf( "\n" );
670 isom_iprintf( indent, "pre_defined = 0x%04"PRIx16"\n", visual->color_table_ID );
672 return 0;
675 static int isom_print_btrt( lsmash_root_t *root, isom_box_t *box, int level )
677 if( !box )
678 return -1;
679 isom_btrt_t *btrt = (isom_btrt_t *)box;
680 int indent = level;
681 isom_print_box_common( indent++, box, "Bit Rate Box" );
682 isom_iprintf( indent, "bufferSizeDB = %"PRIu32"\n", btrt->bufferSizeDB );
683 isom_iprintf( indent, "maxBitrate = %"PRIu32"\n", btrt->maxBitrate );
684 isom_iprintf( indent, "avgBitrate = %"PRIu32"\n", btrt->avgBitrate );
685 return 0;
688 static int isom_print_clap( lsmash_root_t *root, isom_box_t *box, int level )
690 if( !box )
691 return -1;
692 isom_clap_t *clap = (isom_clap_t *)box;
693 int indent = level;
694 isom_print_box_common( indent++, box, "Clean Aperture Box" );
695 isom_iprintf( indent, "cleanApertureWidthN = %"PRIu32"\n", clap->cleanApertureWidthN );
696 isom_iprintf( indent, "cleanApertureWidthD = %"PRIu32"\n", clap->cleanApertureWidthD );
697 isom_iprintf( indent, "cleanApertureHeightN = %"PRIu32"\n", clap->cleanApertureHeightN );
698 isom_iprintf( indent, "cleanApertureHeightD = %"PRIu32"\n", clap->cleanApertureHeightD );
699 isom_iprintf( indent, "horizOffN = %"PRId32"\n", clap->horizOffN );
700 isom_iprintf( indent, "horizOffD = %"PRIu32"\n", clap->horizOffD );
701 isom_iprintf( indent, "vertOffN = %"PRId32"\n", clap->vertOffN );
702 isom_iprintf( indent, "vertOffD = %"PRIu32"\n", clap->vertOffD );
703 return 0;
706 static int isom_print_pasp( lsmash_root_t *root, isom_box_t *box, int level )
708 if( !box )
709 return -1;
710 isom_pasp_t *pasp = (isom_pasp_t *)box;
711 int indent = level;
712 isom_print_box_common( indent++, box, "Pixel Aspect Ratio Box" );
713 isom_iprintf( indent, "hSpacing = %"PRIu32"\n", pasp->hSpacing );
714 isom_iprintf( indent, "vSpacing = %"PRIu32"\n", pasp->vSpacing );
715 return 0;
718 static int isom_print_colr( lsmash_root_t *root, isom_box_t *box, int level )
720 if( !box )
721 return -1;
722 isom_colr_t *colr = (isom_colr_t *)box;
723 int indent = level;
724 isom_print_box_common( indent++, box, "Color Parameter Box" );
725 isom_iprintf( indent, "color_parameter_type = %s\n", isom_4cc2str( colr->color_parameter_type ) );
726 if( colr->color_parameter_type == QT_COLOR_PARAMETER_TYPE_NCLC )
728 isom_iprintf( indent, "primaries_index = %"PRIu16"\n", colr->primaries_index );
729 isom_iprintf( indent, "transfer_function_index = %"PRIu16"\n", colr->transfer_function_index );
730 isom_iprintf( indent, "matrix_index = %"PRIu16"\n", colr->matrix_index );
732 return 0;
735 static int isom_print_stsl( lsmash_root_t *root, isom_box_t *box, int level )
737 if( !box )
738 return -1;
739 isom_stsl_t *stsl = (isom_stsl_t *)box;
740 int indent = level;
741 isom_print_box_common( indent++, box, "Sample Scale Box" );
742 isom_iprintf( indent, "constraint_flag = %s\n", (stsl->constraint_flag & 0x01) ? "on" : "off" );
743 isom_iprintf( indent, "scale_method = " );
744 if( stsl->scale_method == ISOM_SCALING_METHOD_FILL )
745 printf( "'fill'\n" );
746 else if( stsl->scale_method == ISOM_SCALING_METHOD_HIDDEN )
747 printf( "'hidden'\n" );
748 else if( stsl->scale_method == ISOM_SCALING_METHOD_MEET )
749 printf( "'meet'\n" );
750 else if( stsl->scale_method == ISOM_SCALING_METHOD_SLICE_X )
751 printf( "'slice' in the x-coodinate\n" );
752 else if( stsl->scale_method == ISOM_SCALING_METHOD_SLICE_Y )
753 printf( "'slice' in the y-coodinate\n" );
754 isom_iprintf( indent, "display_center_x = %"PRIu16"\n", stsl->display_center_x );
755 isom_iprintf( indent, "display_center_y = %"PRIu16"\n", stsl->display_center_y );
756 return 0;
759 static int isom_print_avcC( lsmash_root_t *root, isom_box_t *box, int level )
761 if( !box )
762 return -1;
763 isom_avcC_t *avcC = (isom_avcC_t *)box;
764 int indent = level;
765 isom_print_box_common( indent++, box, "AVC Configuration Box" );
766 isom_iprintf( indent, "configurationVersion = %"PRIu8"\n", avcC->configurationVersion );
767 isom_iprintf( indent, "AVCProfileIndication = %"PRIu8"\n", avcC->AVCProfileIndication );
768 isom_iprintf( indent, "profile_compatibility = 0x%02"PRIu8"\n", avcC->profile_compatibility );
769 isom_iprintf( indent, "AVCLevelIndication = %"PRIu8"\n", avcC->AVCLevelIndication );
770 isom_iprintf( indent, "lengthSizeMinusOne = %"PRIu8"\n", avcC->lengthSizeMinusOne & 0x03 );
771 isom_iprintf( indent, "numOfSequenceParameterSets = %"PRIu8"\n", avcC->numOfSequenceParameterSets & 0x1f );
772 isom_iprintf( indent, "numOfPictureParameterSets = %"PRIu8"\n", avcC->numOfPictureParameterSets );
773 if( ISOM_REQUIRES_AVCC_EXTENSION( avcC->AVCProfileIndication ) )
775 isom_iprintf( indent, "chroma_format = %"PRIu8"\n", avcC->chroma_format & 0x03 );
776 isom_iprintf( indent, "bit_depth_luma_minus8 = %"PRIu8"\n", avcC->bit_depth_luma_minus8 & 0x7 );
777 isom_iprintf( indent, "bit_depth_chroma_minus8 = %"PRIu8"\n", avcC->bit_depth_chroma_minus8 & 0x7 );
778 isom_iprintf( indent, "numOfSequenceParameterSetExt = %"PRIu8"\n", avcC->numOfSequenceParameterSetExt );
780 return 0;
783 static int isom_print_audio_description( lsmash_root_t *root, isom_box_t *box, int level )
785 if( !box )
786 return -1;
787 isom_audio_entry_t *audio = (isom_audio_entry_t *)box;
788 int indent = level;
789 isom_iprintf( indent++, "[%s: Audio Description]\n", isom_4cc2str( audio->type ) );
790 isom_iprintf( indent, "position = %"PRIu64"\n", audio->pos );
791 isom_iprintf( indent, "size = %"PRIu64"\n", audio->size );
792 isom_iprint_sample_description_common_reserved( indent, audio->reserved );
793 isom_iprintf( indent, "data_reference_index = %"PRIu16"\n", audio->data_reference_index );
794 if( root->qt_compatible )
796 isom_iprintf( indent, "version = %"PRId16"\n", audio->version );
797 isom_iprintf( indent, "revision_level = %"PRId16"\n", audio->revision_level );
798 isom_iprintf( indent, "vendor = %s\n", isom_4cc2str( audio->vendor ) );
799 isom_iprintf( indent, "channelcount = %"PRIu16"\n", audio->channelcount );
800 isom_iprintf( indent, "samplesize = %"PRIu16"\n", audio->samplesize );
801 isom_iprintf( indent, "compression_ID = %"PRId16"\n", audio->compression_ID );
802 isom_iprintf( indent, "packet_size = %"PRIu16"\n", audio->packet_size );
804 else
806 isom_iprintf( indent, "reserved = 0x%04"PRIx16"\n", audio->version );
807 isom_iprintf( indent, "reserved = 0x%04"PRIx16"\n", audio->revision_level );
808 isom_iprintf( indent, "reserved = 0x%08"PRIx32"\n", audio->vendor );
809 isom_iprintf( indent, "channelcount = %"PRIu16"\n", audio->channelcount );
810 isom_iprintf( indent, "samplesize = %"PRIu16"\n", audio->samplesize );
811 isom_iprintf( indent, "pre_defined = %"PRId16"\n", audio->compression_ID );
812 isom_iprintf( indent, "reserved = %"PRIu16"\n", audio->packet_size );
814 isom_iprintf( indent, "samplerate = %f\n", lsmash_fixed2double( audio->samplerate, 16 ) );
815 if( audio->version == 1 )
817 isom_iprintf( indent, "samplesPerPacket = %"PRIu32"\n", audio->samplesPerPacket );
818 isom_iprintf( indent, "bytesPerPacket = %"PRIu32"\n", audio->bytesPerPacket );
819 isom_iprintf( indent, "bytesPerFrame = %"PRIu32"\n", audio->bytesPerFrame );
820 isom_iprintf( indent, "bytesPerSample = %"PRIu32"\n", audio->bytesPerSample );
822 else if( audio->version == 2 )
824 isom_iprintf( indent, "sizeOfStructOnly = %"PRIu32"\n", audio->sizeOfStructOnly );
825 isom_iprintf( indent, "audioSampleRate = %lf\n", lsmash_int2float64( audio->audioSampleRate ) );
826 isom_iprintf( indent, "numAudioChannels = %"PRIu32"\n", audio->numAudioChannels );
827 isom_iprintf( indent, "always7F000000 = 0x%08"PRIx32"\n", audio->always7F000000 );
828 isom_iprintf( indent, "constBitsPerChannel = %"PRIu32"\n", audio->constBitsPerChannel );
829 isom_iprintf( indent++, "formatSpecificFlags = 0x%08"PRIx32"\n", audio->formatSpecificFlags );
830 if( isom_is_lpcm_audio( audio->type ) )
832 isom_iprintf( indent, "sample format: " );
833 if( audio->formatSpecificFlags & QT_LPCM_FORMAT_FLAG_FLOAT )
834 printf( "floating point\n" );
835 else
837 printf( "integer\n" );
838 isom_iprintf( indent, "signedness: " );
839 printf( audio->formatSpecificFlags & QT_LPCM_FORMAT_FLAG_SIGNED_INTEGER ? "signed\n" : "unsigned\n" );
841 if( audio->constBytesPerAudioPacket != 1 )
843 isom_iprintf( indent, "endianness: " );
844 printf( audio->formatSpecificFlags & QT_LPCM_FORMAT_FLAG_BIG_ENDIAN ? "big\n" : "little\n" );
846 isom_iprintf( indent, "packed: " );
847 if( audio->formatSpecificFlags & QT_LPCM_FORMAT_FLAG_PACKED )
848 printf( "yes\n" );
849 else
851 printf( "no\n" );
852 isom_iprintf( indent, "alignment: " );
853 printf( audio->formatSpecificFlags & QT_LPCM_FORMAT_FLAG_ALIGNED_HIGH ? "high\n" : "low\n" );
855 if( audio->numAudioChannels > 1 )
857 isom_iprintf( indent, "interleved: " );
858 printf( audio->formatSpecificFlags & QT_LPCM_FORMAT_FLAG_NON_INTERLEAVED ? "no\n" : "yes\n" );
861 isom_iprintf( --indent, "constBytesPerAudioPacket = %"PRIu32"\n", audio->constBytesPerAudioPacket );
862 isom_iprintf( indent, "constLPCMFramesPerAudioPacket = %"PRIu32"\n", audio->constLPCMFramesPerAudioPacket );
864 return 0;
867 static int isom_print_wave( lsmash_root_t *root, isom_box_t *box, int level )
869 return isom_print_simple( box, level, "Sound Information Decompression Parameters Box" );
872 static int isom_print_frma( lsmash_root_t *root, isom_box_t *box, int level )
874 if( !box )
875 return -1;
876 isom_frma_t *frma = (isom_frma_t *)box;
877 int indent = level;
878 isom_print_box_common( indent++, box, "Format Box" );
879 isom_iprintf( indent, "data_format = %s\n", isom_4cc2str( frma->data_format ) );
880 return 0;
883 static int isom_print_enda( lsmash_root_t *root, isom_box_t *box, int level )
885 if( !box )
886 return -1;
887 isom_enda_t *enda = (isom_enda_t *)box;
888 int indent = level;
889 isom_print_box_common( indent++, box, "Audio Endian Box" );
890 isom_iprintf( indent, "littleEndian = %s\n", enda->littleEndian ? "yes" : "no" );
891 return 0;
894 static int isom_print_terminator( lsmash_root_t *root, isom_box_t *box, int level )
896 if( !box )
897 return -1;
898 isom_terminator_t *terminator = (isom_terminator_t *)box;
899 int indent = level;
900 isom_iprintf( indent++, "[0x00000000: Terminator Box]\n" );
901 isom_iprintf( indent, "position = %"PRIu64"\n", terminator->pos );
902 isom_iprintf( indent, "size = %"PRIu64"\n", terminator->size );
903 return 0;
906 static int isom_print_chan( lsmash_root_t *root, isom_box_t *box, int level )
908 if( !box )
909 return -1;
910 isom_chan_t *chan = (isom_chan_t *)box;
911 int indent = level;
912 isom_print_box_common( indent++, box, "Channel Compositor Box" );
913 isom_iprintf( indent, "channelLayoutTag = 0x%08"PRIx32"\n", chan->channelLayoutTag );
914 isom_iprintf( indent, "channelBitmap = 0x%08"PRIx32"\n", chan->channelBitmap );
915 isom_iprintf( indent, "numberChannelDescriptions = %"PRIu32"\n", chan->numberChannelDescriptions );
916 if( chan->numberChannelDescriptions )
918 isom_channel_description_t *desc = chan->channelDescriptions;
919 for( uint32_t i = 0; i < chan->numberChannelDescriptions; i++ )
921 isom_iprintf( indent++, "ChannelDescriptions[%"PRIu32"]\n", i );
922 isom_iprintf( indent, "channelLabel = 0x%08"PRIx32"\n", desc->channelLabel );
923 isom_iprintf( indent, "channelFlags = 0x%08"PRIx32"\n", desc->channelFlags );
924 for( int j = 0; j < 3; j++ )
925 isom_iprintf( indent, "coordinates[%d] = %f\n", j, lsmash_int2float32( desc->coordinates[j] ) );
926 --indent;
929 return 0;
932 static int isom_print_text_description( lsmash_root_t *root, isom_box_t *box, int level )
934 if( !box )
935 return -1;
936 isom_text_entry_t *text = (isom_text_entry_t *)box;
937 int indent = level;
938 isom_iprintf( indent++, "[text: QuickTime Text Description]\n" );
939 isom_iprintf( indent, "position = %"PRIu64"\n", text->pos );
940 isom_iprintf( indent, "size = %"PRIu64"\n", text->size );
941 isom_iprint_sample_description_common_reserved( indent, text->reserved );
942 isom_iprintf( indent, "data_reference_index = %"PRIu16"\n", text->data_reference_index );
943 isom_iprintf( indent, "displayFlags = 0x%08"PRId32"\n", text->displayFlags );
944 isom_iprintf( indent, "textJustification = %"PRId32"\n", text->textJustification );
945 isom_iprintf( indent, "bgColor\n" );
946 isom_iprint_rgb_color( indent + 1, text->bgColor );
947 isom_iprintf( indent, "top = %"PRId16"\n", text->top );
948 isom_iprintf( indent, "left = %"PRId16"\n", text->left );
949 isom_iprintf( indent, "bottom = %"PRId16"\n", text->bottom );
950 isom_iprintf( indent, "right = %"PRId16"\n", text->right );
951 isom_iprintf( indent, "scrpStartChar = %"PRId32"\n", text->scrpStartChar );
952 isom_iprintf( indent, "scrpHeight = %"PRId16"\n", text->scrpHeight );
953 isom_iprintf( indent, "scrpAscent = %"PRId16"\n", text->scrpAscent );
954 isom_iprintf( indent, "scrpFont = %"PRId16"\n", text->scrpFont );
955 isom_iprintf( indent, "scrpFace = %"PRIu16"\n", text->scrpFace );
956 isom_iprintf( indent, "scrpSize = %"PRId16"\n", text->scrpSize );
957 isom_iprintf( indent, "scrpColor\n" );
958 isom_iprint_rgb_color( indent + 1, text->scrpColor );
959 if( text->font_name_length )
960 isom_iprintf( indent, "font_name = %s\n", text->font_name );
961 return 0;
964 static int isom_print_tx3g_description( lsmash_root_t *root, isom_box_t *box, int level )
966 if( !box )
967 return -1;
968 isom_tx3g_entry_t *tx3g = (isom_tx3g_entry_t *)box;
969 int indent = level;
970 isom_iprintf( indent++, "[tx3g: Timed Text Description]\n" );
971 isom_iprintf( indent, "position = %"PRIu64"\n", tx3g->pos );
972 isom_iprintf( indent, "size = %"PRIu64"\n", tx3g->size );
973 isom_iprint_sample_description_common_reserved( indent, tx3g->reserved );
974 isom_iprintf( indent, "data_reference_index = %"PRIu16"\n", tx3g->data_reference_index );
975 isom_iprintf( indent, "displayFlags = 0x%08"PRId32"\n", tx3g->displayFlags );
976 isom_iprintf( indent, "horizontal_justification = %"PRId8"\n", tx3g->horizontal_justification );
977 isom_iprintf( indent, "vertical_justification = %"PRId8"\n", tx3g->vertical_justification );
978 isom_iprintf( indent, "background_color_rgba\n" );
979 isom_iprint_rgba_color( indent + 1, tx3g->background_color_rgba );
980 isom_iprintf( indent, "top = %"PRId16"\n", tx3g->top );
981 isom_iprintf( indent, "left = %"PRId16"\n", tx3g->left );
982 isom_iprintf( indent, "bottom = %"PRId16"\n", tx3g->bottom );
983 isom_iprintf( indent, "right = %"PRId16"\n", tx3g->right );
984 isom_iprintf( indent, "startChar = %"PRIu16"\n", tx3g->startChar );
985 isom_iprintf( indent, "endChar = %"PRIu16"\n", tx3g->endChar );
986 isom_iprintf( indent, "font_ID = %"PRIu16"\n", tx3g->font_ID );
987 isom_iprintf( indent, "face_style_flags = %"PRIu8"\n", tx3g->face_style_flags );
988 isom_iprintf( indent, "font_size = %"PRIu8"\n", tx3g->font_size );
989 isom_iprintf( indent, "text_color_rgba\n" );
990 isom_iprint_rgba_color( indent + 1, tx3g->text_color_rgba );
991 return 0;
994 static int isom_print_ftab( lsmash_root_t *root, isom_box_t *box, int level )
996 if( !box || !((isom_ftab_t *)box)->list )
997 return -1;
998 isom_ftab_t *ftab = (isom_ftab_t *)box;
999 int indent = level;
1000 uint16_t i = 0;
1001 isom_print_box_common( indent++, box, "Font Table Box" );
1002 isom_iprintf( indent, "entry_count = %"PRIu16"\n", ftab->list->entry_count );
1003 for( lsmash_entry_t *entry = ftab->list->head; entry; entry = entry->next )
1005 isom_font_record_t *data = (isom_font_record_t *)entry->data;
1006 isom_iprintf( indent++, "entry[%"PRIu16"]\n", i++ );
1007 isom_iprintf( indent, "font_ID = %"PRIu16"\n", data->font_ID );
1008 if( data->font_name_length )
1009 isom_iprintf( indent, "font_name = %s\n", data->font_name );
1010 --indent;
1012 return 0;
1015 static int isom_print_stts( lsmash_root_t *root, isom_box_t *box, int level )
1017 if( !box || !((isom_stts_t *)box)->list )
1018 return -1;
1019 isom_stts_t *stts = (isom_stts_t *)box;
1020 int indent = level;
1021 uint32_t i = 0;
1022 isom_print_box_common( indent++, box, "Decoding Time to Sample Box" );
1023 isom_iprintf( indent, "entry_count = %"PRIu32"\n", stts->list->entry_count );
1024 for( lsmash_entry_t *entry = stts->list->head; entry; entry = entry->next )
1026 isom_stts_entry_t *data = (isom_stts_entry_t *)entry->data;
1027 isom_iprintf( indent++, "entry[%"PRIu32"]\n", i++ );
1028 isom_iprintf( indent, "sample_count = %"PRIu32"\n", data->sample_count );
1029 isom_iprintf( indent--, "sample_delta = %"PRIu32"\n", data->sample_delta );
1031 return 0;
1034 static int isom_print_ctts( lsmash_root_t *root, isom_box_t *box, int level )
1036 if( !box || !((isom_ctts_t *)box)->list )
1037 return -1;
1038 isom_ctts_t *ctts = (isom_ctts_t *)box;
1039 int indent = level;
1040 uint32_t i = 0;
1041 isom_print_box_common( indent++, box, "Composition Time to Sample Box" );
1042 isom_iprintf( indent, "entry_count = %"PRIu32"\n", ctts->list->entry_count );
1043 if( root->qt_compatible || ctts->version == 1 )
1044 for( lsmash_entry_t *entry = ctts->list->head; entry; entry = entry->next )
1046 isom_ctts_entry_t *data = (isom_ctts_entry_t *)entry->data;
1047 isom_iprintf( indent++, "entry[%"PRIu32"]\n", i++ );
1048 isom_iprintf( indent, "sample_count = %"PRIu32"\n", data->sample_count );
1049 isom_iprintf( indent--, "sample_offset = %"PRId32"\n", (union {uint32_t ui; int32_t si;}){data->sample_offset}.si );
1051 else
1052 for( lsmash_entry_t *entry = ctts->list->head; entry; entry = entry->next )
1054 isom_ctts_entry_t *data = (isom_ctts_entry_t *)entry->data;
1055 isom_iprintf( indent++, "entry[%"PRIu32"]\n", i++ );
1056 isom_iprintf( indent, "sample_count = %"PRIu32"\n", data->sample_count );
1057 isom_iprintf( indent--, "sample_offset = %"PRIu32"\n", data->sample_offset );
1059 return 0;
1062 static int isom_print_cslg( lsmash_root_t *root, isom_box_t *box, int level )
1064 if( !box )
1065 return -1;
1066 isom_cslg_t *cslg = (isom_cslg_t *)box;
1067 int indent = level;
1068 if( root->qt_compatible )
1070 isom_print_box_common( indent++, box, "Composition Shift Least Greatest Box" );
1071 isom_iprintf( indent, "compositionOffsetToDTDDeltaShift = %"PRId32"\n", cslg->compositionToDTSShift );
1072 isom_iprintf( indent, "leastDecodeToDisplayDelta = %"PRId32"\n", cslg->leastDecodeToDisplayDelta );
1073 isom_iprintf( indent, "greatestDecodeToDisplayDelta = %"PRId32"\n", cslg->greatestDecodeToDisplayDelta );
1074 isom_iprintf( indent, "displayStartTime = %"PRId32"\n", cslg->compositionStartTime );
1075 isom_iprintf( indent, "displayEndTime = %"PRId32"\n", cslg->compositionEndTime );
1077 else
1079 isom_print_box_common( indent++, box, "Composition to Decode Box" );
1080 isom_iprintf( indent, "compositionToDTSShift = %"PRId32"\n", cslg->compositionToDTSShift );
1081 isom_iprintf( indent, "leastDecodeToDisplayDelta = %"PRId32"\n", cslg->leastDecodeToDisplayDelta );
1082 isom_iprintf( indent, "greatestDecodeToDisplayDelta = %"PRId32"\n", cslg->greatestDecodeToDisplayDelta );
1083 isom_iprintf( indent, "compositionStartTime = %"PRId32"\n", cslg->compositionStartTime );
1084 isom_iprintf( indent, "compositionEndTime = %"PRId32"\n", cslg->compositionEndTime );
1086 return 0;
1089 static int isom_print_stss( lsmash_root_t *root, isom_box_t *box, int level )
1091 if( !box || !((isom_stss_t *)box)->list )
1092 return -1;
1093 isom_stss_t *stss = (isom_stss_t *)box;
1094 int indent = level;
1095 uint32_t i = 0;
1096 isom_print_box_common( indent++, box, "Sync Sample Box" );
1097 isom_iprintf( indent, "entry_count = %"PRIu32"\n", stss->list->entry_count );
1098 for( lsmash_entry_t *entry = stss->list->head; entry; entry = entry->next )
1099 isom_iprintf( indent, "sample_number[%"PRIu32"] = %"PRIu32"\n", i++, ((isom_stss_entry_t *)entry->data)->sample_number );
1100 return 0;
1103 static int isom_print_stps( lsmash_root_t *root, isom_box_t *box, int level )
1105 if( !box || !((isom_stps_t *)box)->list )
1106 return -1;
1107 isom_stps_t *stps = (isom_stps_t *)box;
1108 int indent = level;
1109 uint32_t i = 0;
1110 isom_print_box_common( indent++, box, "Partial Sync Sample Box" );
1111 isom_iprintf( indent, "entry_count = %"PRIu32"\n", stps->list->entry_count );
1112 for( lsmash_entry_t *entry = stps->list->head; entry; entry = entry->next )
1113 isom_iprintf( indent, "sample_number[%"PRIu32"] = %"PRIu32"\n", i++, ((isom_stps_entry_t *)entry->data)->sample_number );
1114 return 0;
1117 static int isom_print_sdtp( lsmash_root_t *root, isom_box_t *box, int level )
1119 if( !box || !((isom_sdtp_t *)box)->list )
1120 return -1;
1121 isom_sdtp_t *sdtp = (isom_sdtp_t *)box;
1122 int indent = level;
1123 uint32_t i = 0;
1124 isom_print_box_common( indent++, box, "Independent and Disposable Samples Box" );
1125 for( lsmash_entry_t *entry = sdtp->list->head; entry; entry = entry->next )
1127 isom_sdtp_entry_t *data = (isom_sdtp_entry_t *)entry->data;
1128 isom_iprintf( indent++, "entry[%"PRIu32"]\n", i++ );
1129 if( data->is_leading || data->sample_depends_on || data->sample_is_depended_on || data->sample_has_redundancy )
1131 if( root->avc_extensions )
1133 if( data->is_leading & ISOM_SAMPLE_IS_UNDECODABLE_LEADING )
1134 isom_iprintf( indent, "undecodable leading\n" );
1135 else if( data->is_leading & ISOM_SAMPLE_IS_NOT_LEADING )
1136 isom_iprintf( indent, "non-leading\n" );
1137 else if( data->is_leading & ISOM_SAMPLE_IS_DECODABLE_LEADING )
1138 isom_iprintf( indent, "decodable leading\n" );
1140 else if( data->is_leading & QT_SAMPLE_EARLIER_PTS_ALLOWED )
1141 isom_iprintf( indent, "early display times allowed\n" );
1142 if( data->sample_depends_on & ISOM_SAMPLE_IS_INDEPENDENT )
1143 isom_iprintf( indent, "independent\n" );
1144 else if( data->sample_depends_on & ISOM_SAMPLE_IS_NOT_INDEPENDENT )
1145 isom_iprintf( indent, "dependent\n" );
1146 if( data->sample_is_depended_on & ISOM_SAMPLE_IS_NOT_DISPOSABLE )
1147 isom_iprintf( indent, "non-disposable\n" );
1148 else if( data->sample_is_depended_on & ISOM_SAMPLE_IS_DISPOSABLE )
1149 isom_iprintf( indent, "disposable\n" );
1150 if( data->sample_has_redundancy & ISOM_SAMPLE_HAS_REDUNDANCY )
1151 isom_iprintf( indent, "redundant\n" );
1152 else if( data->sample_has_redundancy & ISOM_SAMPLE_HAS_NO_REDUNDANCY )
1153 isom_iprintf( indent, "non-redundant\n" );
1155 else
1156 isom_iprintf( indent, "no description\n" );
1157 --indent;
1159 return 0;
1162 static int isom_print_stsc( lsmash_root_t *root, isom_box_t *box, int level )
1164 if( !box || !((isom_stsc_t *)box)->list )
1165 return -1;
1166 isom_stsc_t *stsc = (isom_stsc_t *)box;
1167 int indent = level;
1168 uint32_t i = 0;
1169 isom_print_box_common( indent++, box, "Sample To Chunk Box" );
1170 isom_iprintf( indent, "entry_count = %"PRIu32"\n", stsc->list->entry_count );
1171 for( lsmash_entry_t *entry = stsc->list->head; entry; entry = entry->next )
1173 isom_stsc_entry_t *data = (isom_stsc_entry_t *)entry->data;
1174 isom_iprintf( indent++, "entry[%"PRIu32"]\n", i++ );
1175 isom_iprintf( indent, "first_chunk = %"PRIu32"\n", data->first_chunk );
1176 isom_iprintf( indent, "samples_per_chunk = %"PRIu32"\n", data->samples_per_chunk );
1177 isom_iprintf( indent--, "sample_description_index = %"PRIu32"\n", data->sample_description_index );
1179 return 0;
1182 static int isom_print_stsz( lsmash_root_t *root, isom_box_t *box, int level )
1184 if( !box )
1185 return -1;
1186 isom_stsz_t *stsz = (isom_stsz_t *)box;
1187 int indent = level;
1188 uint32_t i = 0;
1189 isom_print_box_common( indent++, box, "Sample Size Box" );
1190 if( !stsz->sample_size )
1191 isom_iprintf( indent, "sample_size = 0 (variable)\n" );
1192 else
1193 isom_iprintf( indent, "sample_size = %"PRIu32" (constant)\n", stsz->sample_size );
1194 isom_iprintf( indent, "sample_count = %"PRIu32"\n", stsz->sample_count );
1195 if( !stsz->sample_size && stsz->list )
1196 for( lsmash_entry_t *entry = stsz->list->head; entry; entry = entry->next )
1198 isom_stsz_entry_t *data = (isom_stsz_entry_t *)entry->data;
1199 isom_iprintf( indent, "entry_size[%"PRIu32"] = %"PRIu32"\n", i++, data->entry_size );
1201 return 0;
1204 static int isom_print_stco( lsmash_root_t *root, isom_box_t *box, int level )
1206 if( !box || !((isom_stco_t *)box)->list )
1207 return -1;
1208 isom_stco_t *stco = (isom_stco_t *)box;
1209 int indent = level;
1210 uint32_t i = 0;
1211 isom_print_box_common( indent++, box, "Chunk Offset Box" );
1212 isom_iprintf( indent, "entry_count = %"PRIu32"\n", stco->list->entry_count );
1213 if( stco->type == ISOM_BOX_TYPE_STCO )
1215 for( lsmash_entry_t *entry = stco->list->head; entry; entry = entry->next )
1216 isom_iprintf( indent, "chunk_offset[%"PRIu32"] = %"PRIu32"\n", i++, ((isom_stco_entry_t *)entry->data)->chunk_offset );
1218 else
1220 for( lsmash_entry_t *entry = stco->list->head; entry; entry = entry->next )
1221 isom_iprintf( indent, "chunk_offset[%"PRIu32"] = %"PRIu64"\n", i++, ((isom_co64_entry_t *)entry->data)->chunk_offset );
1223 return 0;
1226 static int isom_print_sgpd( lsmash_root_t *root, isom_box_t *box, int level )
1228 if( !box || !((isom_sgpd_entry_t *)box)->list )
1229 return -1;
1230 isom_sgpd_entry_t *sgpd = (isom_sgpd_entry_t *)box;
1231 int indent = level;
1232 uint32_t i = 0;
1233 isom_print_box_common( indent++, box, "Sample Group Description Box" );
1234 isom_iprintf( indent, "grouping_type = %s\n", isom_4cc2str( sgpd->grouping_type ) );
1235 if( sgpd->version == 1 )
1237 isom_iprintf( indent, "default_length = %"PRIu32, sgpd->default_length );
1238 printf( " %s\n", sgpd->default_length ? "(constant)" : "(variable)" );
1240 isom_iprintf( indent, "entry_count = %"PRIu32"\n", sgpd->list->entry_count );
1241 switch( sgpd->grouping_type )
1243 case ISOM_GROUP_TYPE_RAP :
1244 for( lsmash_entry_t *entry = sgpd->list->head; entry; entry = entry->next )
1246 if( sgpd->version == 1 && !sgpd->default_length )
1247 isom_iprintf( indent, "description_length[%"PRIu32"] = %"PRIu32"\n", i++, ((isom_rap_entry_t *)entry->data)->description_length );
1248 else
1250 isom_rap_entry_t *rap = (isom_rap_entry_t *)entry->data;
1251 isom_iprintf( indent++, "entry[%"PRIu32"]\n", i++ );
1252 isom_iprintf( indent, "num_leading_samples_known = %"PRIu8"\n", rap->num_leading_samples_known );
1253 isom_iprintf( indent--, "num_leading_samples = %"PRIu8"\n", rap->num_leading_samples );
1256 break;
1257 case ISOM_GROUP_TYPE_ROLL :
1258 for( lsmash_entry_t *entry = sgpd->list->head; entry; entry = entry->next )
1260 if( sgpd->version == 1 && !sgpd->default_length )
1261 isom_iprintf( indent, "description_length[%"PRIu32"] = %"PRIu32"\n", i++, ((isom_roll_entry_t *)entry->data)->description_length );
1262 else
1263 isom_iprintf( indent, "roll_distance[%"PRIu32"] = %"PRId16"\n", i++, ((isom_roll_entry_t *)entry->data)->roll_distance );
1265 break;
1266 default :
1267 break;
1269 return 0;
1272 static int isom_print_sbgp( lsmash_root_t *root, isom_box_t *box, int level )
1274 if( !box || !((isom_sbgp_entry_t *)box)->list )
1275 return -1;
1276 isom_sbgp_entry_t *sbgp = (isom_sbgp_entry_t *)box;
1277 int indent = level;
1278 uint32_t i = 0;
1279 isom_print_box_common( indent++, box, "Sample to Group Box" );
1280 isom_iprintf( indent, "grouping_type = %s\n", isom_4cc2str( sbgp->grouping_type ) );
1281 if( sbgp->version == 1 )
1282 isom_iprintf( indent, "grouping_type_parameter = %s\n", isom_4cc2str( sbgp->grouping_type_parameter ) );
1283 isom_iprintf( indent, "entry_count = %"PRIu32"\n", sbgp->list->entry_count );
1284 for( lsmash_entry_t *entry = sbgp->list->head; entry; entry = entry->next )
1286 isom_group_assignment_entry_t *data = (isom_group_assignment_entry_t *)entry->data;
1287 isom_iprintf( indent++, "entry[%"PRIu32"]\n", i++ );
1288 isom_iprintf( indent, "sample_count = %"PRIu32"\n", data->sample_count );
1289 isom_iprintf( indent--, "group_description_index = %"PRIu32, data->group_description_index );
1290 if( !data->group_description_index )
1291 printf( " (not in this grouping type)\n" );
1292 else
1293 printf( "\n" );
1295 return 0;
1298 static int isom_print_udta( lsmash_root_t *root, isom_box_t *box, int level )
1300 return isom_print_simple( box, level, "User Data Box" );
1303 static int isom_print_chpl( lsmash_root_t *root, isom_box_t *box, int level )
1305 if( !box )
1306 return -1;
1307 isom_chpl_t *chpl = (isom_chpl_t *)box;
1308 uint32_t timescale;
1309 if( !chpl->version )
1311 if( !root->moov && !root->moov->mvhd )
1312 return -1;
1313 timescale = root->moov->mvhd->timescale;
1315 else
1316 timescale = 10000000;
1317 int indent = level;
1318 uint32_t i = 0;
1319 isom_print_box_common( indent++, box, "Chapter List Box" );
1320 if( chpl->version == 1 )
1322 isom_iprintf( indent, "unknown = 0x%02"PRIx8"\n", chpl->unknown );
1323 isom_iprintf( indent, "entry_count = %"PRIu32"\n", chpl->list->entry_count );
1325 else
1326 isom_iprintf( indent, "entry_count = %"PRIu8"\n", (uint8_t)chpl->list->entry_count );
1327 for( lsmash_entry_t *entry = chpl->list->head; entry; entry = entry->next )
1329 isom_chpl_entry_t *data = (isom_chpl_entry_t *)entry->data;
1330 int64_t start_time = data->start_time / timescale;
1331 int hh = start_time / 3600;
1332 int mm = (start_time / 60) % 60;
1333 int ss = start_time % 60;
1334 int ms = ((data->start_time / (double)timescale) - hh * 3600 - mm * 60 - ss) * 1e3 + 0.5;
1335 char str[256];
1336 memset( str, 0, sizeof(str) );
1337 memcpy( str, data->chapter_name, data->chapter_name_length );
1338 isom_iprintf( indent++, "chapter[%"PRIu32"]\n", i++ );
1339 isom_iprintf( indent, "start_time = %02d:%02d:%02d.%03d\n", hh, mm, ss, ms );
1340 isom_iprintf( indent--, "chapter_name = %s\n", data->chapter_name );
1342 return 0;
1345 static int isom_print_meta( lsmash_root_t *root, isom_box_t *box, int level )
1347 return isom_print_simple( box, level, "Meta Box" );
1350 static int isom_print_ilst( lsmash_root_t *root, isom_box_t *box, int level )
1352 return isom_print_simple( box, level, "Metadata Item List Box" );
1355 static int isom_print_metaitem( lsmash_root_t *root, isom_box_t *box, int level )
1357 if( !box )
1358 return -1;
1359 isom_metaitem_t *metaitem = (isom_metaitem_t *)box;
1360 char *name;
1361 static const struct
1363 uint32_t type;
1364 char *name;
1365 } metaitem_table[] =
1367 { LSMASH_4CC( 0xA9, 'a', 'l', 'b' ), "Album Name" },
1368 { LSMASH_4CC( 0xA9, 'a', 'r', 't' ), "Artist" },
1369 { LSMASH_4CC( 0xA9, 'A', 'R', 'T' ), "Artist" },
1370 { LSMASH_4CC( 0xA9, 'c', 'm', 't' ), "User Comment" },
1371 { LSMASH_4CC( 0xA9, 'd', 'a', 'y' ), "Release Date" },
1372 { LSMASH_4CC( 0xA9, 'e', 'n', 'c' ), "Encoded By" },
1373 { LSMASH_4CC( 0xA9, 'g', 'e', 'n' ), "User Genre" },
1374 { LSMASH_4CC( 0xA9, 'g', 'r', 'p' ), "Grouping" },
1375 { LSMASH_4CC( 0xA9, 'l', 'y', 'r' ), "Lyrics" },
1376 { LSMASH_4CC( 0xA9, 'n', 'a', 'm' ), "Title" },
1377 { LSMASH_4CC( 0xA9, 't', 'o', 'o' ), "Encoding Tool" },
1378 { LSMASH_4CC( 0xA9, 'w', 'r', 't' ), "Composer" },
1379 { LSMASH_4CC( 'a', 'A', 'R', 'T' ), "Album Artist" },
1380 { LSMASH_4CC( 'c', 'a', 't', 'g' ), "Category" },
1381 { LSMASH_4CC( 'c', 'o', 'v', 'r' ), "Cover Art" },
1382 { LSMASH_4CC( 'c', 'p', 'i', 'l' ), "Disc Compilation" },
1383 { LSMASH_4CC( 'c', 'p', 'r', 't' ), "Copyright" },
1384 { LSMASH_4CC( 'd', 'e', 's', 'c' ), "Description" },
1385 { LSMASH_4CC( 'd', 'i', 's', 'k' ), "Disc Number" },
1386 { LSMASH_4CC( 'e', 'g', 'i', 'd' ), "Episode Global Unique ID" },
1387 { LSMASH_4CC( 'g', 'n', 'r', 'e' ), "Pre-defined Genre" },
1388 { LSMASH_4CC( 'g', 'r', 'u', 'p' ), "Grouping" },
1389 { LSMASH_4CC( 'h', 'd', 'v', 'd' ), "High Definition Video" },
1390 { LSMASH_4CC( 'k', 'e', 'y', 'w' ), "Keyword" },
1391 { LSMASH_4CC( 'l', 'd', 'e', 's' ), "Long Description" },
1392 { LSMASH_4CC( 'p', 'c', 's', 't' ), "Podcast" },
1393 { LSMASH_4CC( 'p', 'g', 'a', 'p' ), "Gapless Playback" },
1394 { LSMASH_4CC( 'p', 'u', 'r', 'd' ), "Purcase Date" },
1395 { LSMASH_4CC( 'p', 'u', 'r', 'l' ), "Podcast URL" },
1396 { LSMASH_4CC( 'r', 't', 'n', 'g' ), "Content Rating" },
1397 { LSMASH_4CC( 's', 't', 'i', 'k' ), "Media Type" },
1398 { LSMASH_4CC( 't', 'm', 'p', 'o' ), "Beats Per Minute" },
1399 { LSMASH_4CC( 't', 'r', 'k', 'n' ), "Track Number" },
1400 { LSMASH_4CC( 't', 'v', 'e', 'n' ), "TV Episode Number" },
1401 { LSMASH_4CC( 't', 'v', 'e', 's' ), "TV Episode" },
1402 { LSMASH_4CC( 't', 'v', 'n', 'n' ), "TV Network" },
1403 { LSMASH_4CC( 't', 'v', 's', 'h' ), "TV Show Name" },
1404 { LSMASH_4CC( 't', 'v', 's', 'n' ), "TV Season" },
1405 { LSMASH_4CC( 'a', 'k', 'I', 'D' ), "iTunes Account Used for Purchase" },
1406 { LSMASH_4CC( 'a', 'p', 'I', 'D' ), "iTunes Acount Type" },
1407 { LSMASH_4CC( 'a', 't', 'I', 'D' ), "iTunes Artist ID" },
1408 { LSMASH_4CC( 'c', 'm', 'I', 'D' ), "iTunes Composer ID" },
1409 { LSMASH_4CC( 'c', 'n', 'I', 'D' ), "iTunes Content ID" },
1410 { LSMASH_4CC( 'g', 'e', 'I', 'D' ), "iTunes TV Genre ID" },
1411 { LSMASH_4CC( 'p', 'l', 'I', 'D' ), "iTunes Playlist ID" },
1412 { LSMASH_4CC( 's', 'f', 'I', 'D' ), "iTunes Country Code" },
1413 { LSMASH_4CC( '-', '-', '-', '-' ), "Custom Metadata Item" },
1414 { 0 }
1416 int i;
1417 for( i = 0; metaitem_table[i].type; i++ )
1418 if( metaitem->type == metaitem_table[i].type )
1420 name = metaitem_table[i].name;
1421 break;
1423 if( !metaitem_table[i].type )
1424 name = "Unknown";
1425 return isom_print_simple( box, level, name );
1428 static int isom_print_name( lsmash_root_t *root, isom_box_t *box, int level )
1430 if( !box )
1431 return -1;
1432 isom_name_t *name = (isom_name_t *)box;
1433 int indent = level;
1434 isom_print_box_common( indent++, box, "Name Box" );
1435 char str[name->name_length + 1];
1436 memcpy( str, name->name, name->name_length );
1437 str[name->name_length] = 0;
1438 isom_iprintf( indent, "name = %s\n", str );
1439 return 0;
1442 static int isom_print_mean( lsmash_root_t *root, isom_box_t *box, int level )
1444 if( !box )
1445 return -1;
1446 isom_mean_t *mean = (isom_mean_t *)box;
1447 int indent = level;
1448 isom_print_box_common( indent++, box, "Mean Box" );
1449 char str[mean->meaning_string_length + 1];
1450 memcpy( str, mean->meaning_string, mean->meaning_string_length );
1451 str[mean->meaning_string_length] = 0;
1452 isom_iprintf( indent, "meaning_string = %s\n", str );
1453 return 0;
1456 static int isom_print_data( lsmash_root_t *root, isom_box_t *box, int level )
1458 if( !box )
1459 return -1;
1460 isom_data_t *data = (isom_data_t *)box;
1461 int indent = level;
1462 isom_print_box_common( indent++, box, "Data Box" );
1463 isom_iprintf( indent, "reserved = %"PRIu16"\n", data->reserved );
1464 isom_iprintf( indent, "type_set_identifier = %"PRIu8"%s\n",
1465 data->type_set_identifier,
1466 data->type_set_identifier ? "" : " (basic type set)" );
1467 isom_iprintf( indent, "type_code = %"PRIu8"\n", data->type_code );
1468 isom_iprintf( indent, "the_locale = %"PRIu32"\n", data->the_locale );
1469 if( data->type_code == 21 )
1471 /* integer type */
1472 isom_iprintf( indent, "value = " );
1473 if( data->value_length )
1475 printf( "0x" );
1476 for( uint32_t i = 0; i < data->value_length; i++ )
1477 printf( "%02"PRIx8, data->value[i] );
1479 printf( "\n" );
1481 else
1483 char str[data->value_length + 1];
1484 memcpy( str, data->value, data->value_length );
1485 str[data->value_length] = 0;
1486 isom_iprintf( indent, "value = %s\n", str );
1488 return 0;
1491 static int isom_print_mvex( lsmash_root_t *root, isom_box_t *box, int level )
1493 return isom_print_simple( box, level, "Movie Extends Box" );
1496 static int isom_print_mehd( lsmash_root_t *root, isom_box_t *box, int level )
1498 if( !box )
1499 return -1;
1500 isom_mehd_t *mehd = (isom_mehd_t *)box;
1501 int indent = level;
1502 isom_print_box_common( indent++, box, "Movie Extends Header Box" );
1503 if( root && root->moov && root->moov->mvhd )
1504 isom_iprintf_duration( indent, "fragment_duration", mehd->fragment_duration, root->moov->mvhd->timescale );
1505 else
1506 isom_iprintf_duration( indent, "fragment_duration", mehd->fragment_duration, 0 );
1507 return 0;
1510 static int isom_print_trex( lsmash_root_t *root, isom_box_t *box, int level )
1512 if( !box )
1513 return -1;
1514 isom_trex_entry_t *trex = (isom_trex_entry_t *)box;
1515 int indent = level;
1516 isom_print_box_common( indent++, box, "Track Extends Box" );
1517 isom_iprintf( indent, "track_ID = %"PRIu32"\n", trex->track_ID );
1518 isom_iprintf( indent, "default_sample_description_index = %"PRIu32"\n", trex->default_sample_description_index );
1519 isom_iprintf( indent, "default_sample_duration = %"PRIu32"\n", trex->default_sample_duration );
1520 isom_iprintf( indent, "default_sample_size = %"PRIu32"\n", trex->default_sample_size );
1521 isom_iprint_sample_flags( indent, "default_sample_flags", &trex->default_sample_flags );
1522 return 0;
1525 static int isom_print_moof( lsmash_root_t *root, isom_box_t *box, int level )
1527 return isom_print_simple( box, level, "Movie Fragment Box" );
1530 static int isom_print_mfhd( lsmash_root_t *root, isom_box_t *box, int level )
1532 if( !box )
1533 return -1;
1534 isom_mfhd_t *mfhd = (isom_mfhd_t *)box;
1535 int indent = level;
1536 isom_print_box_common( indent++, box, "Movie Fragment Header Box" );
1537 isom_iprintf( indent, "sequence_number = %"PRIu32"\n", mfhd->sequence_number );
1538 return 0;
1541 static int isom_print_traf( lsmash_root_t *root, isom_box_t *box, int level )
1543 return isom_print_simple( box, level, "Track Fragment Box" );
1546 static int isom_print_tfhd( lsmash_root_t *root, isom_box_t *box, int level )
1548 if( !box )
1549 return -1;
1550 isom_tfhd_t *tfhd = (isom_tfhd_t *)box;
1551 int indent = level;
1552 isom_print_box_common( indent++, box, "Track Fragment Header Box" );
1553 ++indent;
1554 if( tfhd->flags & ISOM_TF_FLAGS_BASE_DATA_OFFSET_PRESENT ) isom_iprintf( indent, "base-data-offset-present\n" );
1555 if( tfhd->flags & ISOM_TF_FLAGS_SAMPLE_DESCRIPTION_INDEX_PRESENT ) isom_iprintf( indent, "sample-description-index-present\n" );
1556 if( tfhd->flags & ISOM_TF_FLAGS_DEFAULT_SAMPLE_DURATION_PRESENT ) isom_iprintf( indent, "default-sample-duration-present\n" );
1557 if( tfhd->flags & ISOM_TF_FLAGS_DEFAULT_SAMPLE_SIZE_PRESENT ) isom_iprintf( indent, "default-sample-size-present\n" );
1558 if( tfhd->flags & ISOM_TF_FLAGS_DEFAULT_SAMPLE_FLAGS_PRESENT ) isom_iprintf( indent, "default-sample-flags-present\n" );
1559 isom_iprintf( --indent, "track_ID = %"PRIu32"\n", tfhd->track_ID );
1560 if( tfhd->flags & ISOM_TF_FLAGS_BASE_DATA_OFFSET_PRESENT )
1561 isom_iprintf( indent, "base_data_offset = %"PRIu64"\n", tfhd->base_data_offset );
1562 if( tfhd->flags & ISOM_TF_FLAGS_SAMPLE_DESCRIPTION_INDEX_PRESENT )
1563 isom_iprintf( indent, "sample_description_index = %"PRIu32"\n", tfhd->sample_description_index );
1564 if( tfhd->flags & ISOM_TF_FLAGS_DEFAULT_SAMPLE_DURATION_PRESENT )
1565 isom_iprintf( indent, "default_sample_duration = %"PRIu32"\n", tfhd->default_sample_duration );
1566 if( tfhd->flags & ISOM_TF_FLAGS_DEFAULT_SAMPLE_SIZE_PRESENT )
1567 isom_iprintf( indent, "default_sample_size = %"PRIu32"\n", tfhd->default_sample_size );
1568 if( tfhd->flags & ISOM_TF_FLAGS_DEFAULT_SAMPLE_FLAGS_PRESENT )
1569 isom_iprint_sample_flags( indent, "default_sample_flags", &tfhd->default_sample_flags );
1570 return 0;
1573 static int isom_print_trun( lsmash_root_t *root, isom_box_t *box, int level )
1575 if( !box )
1576 return -1;
1577 isom_trun_entry_t *trun = (isom_trun_entry_t *)box;
1578 int indent = level;
1579 isom_print_box_common( indent++, box, "Track Fragment Run Box" );
1580 ++indent;
1581 if( trun->flags & ISOM_TR_FLAGS_DATA_OFFSET_PRESENT ) isom_iprintf( indent, "data-offset-present\n" );
1582 if( trun->flags & ISOM_TR_FLAGS_FIRST_SAMPLE_FLAGS_PRESENT ) isom_iprintf( indent, "first-sample-flags-present\n" );
1583 if( trun->flags & ISOM_TR_FLAGS_SAMPLE_DURATION_PRESENT ) isom_iprintf( indent, "sample-duration-present\n" );
1584 if( trun->flags & ISOM_TR_FLAGS_SAMPLE_SIZE_PRESENT ) isom_iprintf( indent, "sample-size-present\n" );
1585 if( trun->flags & ISOM_TR_FLAGS_SAMPLE_FLAGS_PRESENT ) isom_iprintf( indent, "sample-flags-present\n" );
1586 if( trun->flags & ISOM_TR_FLAGS_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT ) isom_iprintf( indent, "sample-composition-time-offsets-present\n" );
1587 isom_iprintf( --indent, "sample_count = %"PRIu32"\n", trun->sample_count );
1588 if( trun->flags & ISOM_TR_FLAGS_DATA_OFFSET_PRESENT )
1589 isom_iprintf( indent, "data_offset = %"PRId32"\n", trun->data_offset );
1590 if( trun->flags & ISOM_TR_FLAGS_FIRST_SAMPLE_FLAGS_PRESENT )
1591 isom_iprint_sample_flags( indent, "first_sample_flags", &trun->first_sample_flags );
1592 if( trun->optional )
1594 uint32_t i = 0;
1595 for( lsmash_entry_t *entry = trun->optional->head; entry; entry = entry->next )
1597 isom_trun_optional_row_t *row = (isom_trun_optional_row_t *)entry->data;
1598 isom_iprintf( indent++, "sample[%"PRIu32"]\n", i++ );
1599 if( trun->flags & ISOM_TR_FLAGS_SAMPLE_DURATION_PRESENT )
1600 isom_iprintf( indent, "sample_duration = %"PRIu32"\n", row->sample_duration );
1601 if( trun->flags & ISOM_TR_FLAGS_SAMPLE_SIZE_PRESENT )
1602 isom_iprintf( indent, "sample_size = %"PRIu32"\n", row->sample_size );
1603 if( trun->flags & ISOM_TR_FLAGS_SAMPLE_FLAGS_PRESENT )
1604 isom_iprint_sample_flags( indent, "sample_flags", &row->sample_flags );
1605 if( trun->flags & ISOM_TR_FLAGS_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT )
1606 isom_iprintf( indent, "sample_composition_time_offset = %"PRIu32"\n", row->sample_composition_time_offset );
1607 --indent;
1610 return 0;
1613 static int isom_print_free( lsmash_root_t *root, isom_box_t *box, int level )
1615 return isom_print_simple( box, level, "Free Space Box" );
1618 static int isom_print_mdat( lsmash_root_t *root, isom_box_t *box, int level )
1620 return isom_print_simple( box, level, "Media Data Box" );
1623 static int isom_print_mfra( lsmash_root_t *root, isom_box_t *box, int level )
1625 return isom_print_simple( box, level, "Movie Fragment Random Access Box" );
1628 static int isom_print_tfra( lsmash_root_t *root, isom_box_t *box, int level )
1630 if( !box )
1631 return -1;
1632 isom_tfra_entry_t *tfra = (isom_tfra_entry_t *)box;
1633 int indent = level;
1634 isom_print_box_common( indent++, box, "Track Fragment Random Access Box" );
1635 isom_iprintf( indent, "track_ID = %"PRIu32"\n", tfra->track_ID );
1636 isom_iprintf( indent, "reserved = 0x%08"PRIx32"\n", tfra->reserved );
1637 isom_iprintf( indent, "length_size_of_traf_num = %"PRIu8"\n", tfra->length_size_of_traf_num );
1638 isom_iprintf( indent, "length_size_of_trun_num = %"PRIu8"\n", tfra->length_size_of_trun_num );
1639 isom_iprintf( indent, "length_size_of_sample_num = %"PRIu8"\n", tfra->length_size_of_sample_num );
1640 isom_iprintf( indent, "number_of_entry = %"PRIu32"\n", tfra->number_of_entry );
1641 if( tfra->list )
1643 uint32_t i = 0;
1644 for( lsmash_entry_t *entry = tfra->list->head; entry; entry = entry->next )
1646 isom_tfra_location_time_entry_t *data = (isom_tfra_location_time_entry_t *)entry->data;
1647 isom_iprintf( indent++, "entry[%"PRIu32"]\n", i++ );
1648 isom_iprintf( indent, "time = %"PRIu64"\n", data->time );
1649 isom_iprintf( indent, "moof_offset = %"PRIu64"\n", data->moof_offset );
1650 isom_iprintf( indent, "traf_number = %"PRIu32"\n", data->traf_number );
1651 isom_iprintf( indent, "trun_number = %"PRIu32"\n", data->trun_number );
1652 isom_iprintf( indent, "sample_number = %"PRIu32"\n", data->sample_number );
1653 --indent;
1656 return 0;
1659 static int isom_print_mfro( lsmash_root_t *root, isom_box_t *box, int level )
1661 if( !box )
1662 return -1;
1663 isom_mfro_t *mfro = (isom_mfro_t *)box;
1664 int indent = level;
1665 isom_print_box_common( indent++, box, "Movie Fragment Random Access Offset Box" );
1666 isom_iprintf( indent, "size = %"PRIu32"\n", mfro->length );
1667 return 0;
1670 int lsmash_print_movie( lsmash_root_t *root )
1672 if( !root || !root->print || !(root->flags & LSMASH_FILE_MODE_DUMP) )
1673 return -1;
1674 printf( "[ROOT]\n" );
1675 printf( " size = %"PRIu64"\n", root->size );
1676 for( lsmash_entry_t *entry = root->print->head; entry; entry = entry->next )
1678 isom_print_entry_t *data = (isom_print_entry_t *)entry->data;
1679 if( !data || data->func( root, data->box, data->level ) )
1680 return -1;
1682 return 0;
1685 static isom_print_box_t isom_select_print_func( isom_box_t *box )
1687 if( box->manager & LSMASH_UNKNOWN_BOX )
1688 return isom_print_unknown;
1689 if( box->parent )
1691 isom_box_t *parent = box->parent;
1692 if( parent->type == ISOM_BOX_TYPE_STSD )
1693 switch( box->type )
1695 case ISOM_CODEC_TYPE_AVC1_VIDEO :
1696 case ISOM_CODEC_TYPE_AVC2_VIDEO :
1697 case ISOM_CODEC_TYPE_AVCP_VIDEO :
1698 case ISOM_CODEC_TYPE_DRAC_VIDEO :
1699 case ISOM_CODEC_TYPE_ENCV_VIDEO :
1700 case ISOM_CODEC_TYPE_MJP2_VIDEO :
1701 case ISOM_CODEC_TYPE_MP4V_VIDEO :
1702 case ISOM_CODEC_TYPE_MVC1_VIDEO :
1703 case ISOM_CODEC_TYPE_MVC2_VIDEO :
1704 case ISOM_CODEC_TYPE_S263_VIDEO :
1705 case ISOM_CODEC_TYPE_SVC1_VIDEO :
1706 case ISOM_CODEC_TYPE_VC_1_VIDEO :
1707 return isom_print_visual_description;
1708 case ISOM_CODEC_TYPE_AC_3_AUDIO :
1709 case ISOM_CODEC_TYPE_ALAC_AUDIO :
1710 case ISOM_CODEC_TYPE_DRA1_AUDIO :
1711 case ISOM_CODEC_TYPE_DTSC_AUDIO :
1712 case ISOM_CODEC_TYPE_DTSH_AUDIO :
1713 case ISOM_CODEC_TYPE_DTSL_AUDIO :
1714 case ISOM_CODEC_TYPE_DTSE_AUDIO :
1715 case ISOM_CODEC_TYPE_EC_3_AUDIO :
1716 case ISOM_CODEC_TYPE_ENCA_AUDIO :
1717 case ISOM_CODEC_TYPE_G719_AUDIO :
1718 case ISOM_CODEC_TYPE_G726_AUDIO :
1719 case ISOM_CODEC_TYPE_M4AE_AUDIO :
1720 case ISOM_CODEC_TYPE_MLPA_AUDIO :
1721 case ISOM_CODEC_TYPE_MP4A_AUDIO :
1722 //case ISOM_CODEC_TYPE_RAW_AUDIO :
1723 case ISOM_CODEC_TYPE_SAMR_AUDIO :
1724 case ISOM_CODEC_TYPE_SAWB_AUDIO :
1725 case ISOM_CODEC_TYPE_SAWP_AUDIO :
1726 case ISOM_CODEC_TYPE_SEVC_AUDIO :
1727 case ISOM_CODEC_TYPE_SQCP_AUDIO :
1728 case ISOM_CODEC_TYPE_SSMV_AUDIO :
1729 //case ISOM_CODEC_TYPE_TWOS_AUDIO :
1730 case QT_CODEC_TYPE_23NI_AUDIO :
1731 case QT_CODEC_TYPE_MAC3_AUDIO :
1732 case QT_CODEC_TYPE_MAC6_AUDIO :
1733 case QT_CODEC_TYPE_NONE_AUDIO :
1734 case QT_CODEC_TYPE_QDM2_AUDIO :
1735 case QT_CODEC_TYPE_QDMC_AUDIO :
1736 case QT_CODEC_TYPE_QCLP_AUDIO :
1737 case QT_CODEC_TYPE_AGSM_AUDIO :
1738 case QT_CODEC_TYPE_ALAW_AUDIO :
1739 case QT_CODEC_TYPE_CDX2_AUDIO :
1740 case QT_CODEC_TYPE_CDX4_AUDIO :
1741 case QT_CODEC_TYPE_DVCA_AUDIO :
1742 case QT_CODEC_TYPE_DVI_AUDIO :
1743 case QT_CODEC_TYPE_FL32_AUDIO :
1744 case QT_CODEC_TYPE_FL64_AUDIO :
1745 case QT_CODEC_TYPE_IMA4_AUDIO :
1746 case QT_CODEC_TYPE_IN24_AUDIO :
1747 case QT_CODEC_TYPE_IN32_AUDIO :
1748 case QT_CODEC_TYPE_LPCM_AUDIO :
1749 case QT_CODEC_TYPE_RAW_AUDIO :
1750 case QT_CODEC_TYPE_SOWT_AUDIO :
1751 case QT_CODEC_TYPE_TWOS_AUDIO :
1752 case QT_CODEC_TYPE_ULAW_AUDIO :
1753 case QT_CODEC_TYPE_VDVA_AUDIO :
1754 case QT_CODEC_TYPE_FULLMP3_AUDIO :
1755 case QT_CODEC_TYPE_MP3_AUDIO :
1756 case QT_CODEC_TYPE_ADPCM2_AUDIO :
1757 case QT_CODEC_TYPE_ADPCM17_AUDIO :
1758 case QT_CODEC_TYPE_GSM49_AUDIO :
1759 case QT_CODEC_TYPE_NOT_SPECIFIED :
1760 return isom_print_audio_description;
1761 case QT_CODEC_TYPE_TEXT_TEXT :
1762 return isom_print_text_description;
1763 case ISOM_CODEC_TYPE_TX3G_TEXT :
1764 return isom_print_tx3g_description;
1765 default :
1766 return isom_print_unknown;
1768 if( parent->type == QT_BOX_TYPE_WAVE )
1769 switch( box->type )
1771 case QT_BOX_TYPE_FRMA :
1772 return isom_print_frma;
1773 case QT_BOX_TYPE_ENDA :
1774 return isom_print_enda;
1775 case ISOM_BOX_TYPE_ESDS :
1776 return isom_print_esds;
1777 case QT_BOX_TYPE_TERMINATOR :
1778 return isom_print_terminator;
1779 default :
1780 return isom_print_unknown;
1782 if( parent->type == ISOM_BOX_TYPE_TREF )
1783 return isom_print_track_reference_type;
1784 if( parent->parent && parent->parent->type == ISOM_BOX_TYPE_ILST )
1786 if( parent->type == LSMASH_4CC( '-', '-', '-', '-' ) )
1788 if( box->type == ISOM_BOX_TYPE_MEAN )
1789 return isom_print_mean;
1790 if( box->type == ISOM_BOX_TYPE_NAME )
1791 return isom_print_name;
1793 if( box->type == ISOM_BOX_TYPE_DATA )
1794 return isom_print_data;
1796 if( parent->type == ISOM_BOX_TYPE_ILST )
1797 return isom_print_metaitem;
1799 switch( box->type )
1801 case ISOM_BOX_TYPE_FTYP :
1802 return isom_print_ftyp;
1803 case ISOM_BOX_TYPE_MOOV :
1804 return isom_print_moov;
1805 case ISOM_BOX_TYPE_MVHD :
1806 return isom_print_mvhd;
1807 case ISOM_BOX_TYPE_IODS :
1808 return isom_print_iods;
1809 case ISOM_BOX_TYPE_ESDS :
1810 return isom_print_esds;
1811 case ISOM_BOX_TYPE_TRAK :
1812 return isom_print_trak;
1813 case ISOM_BOX_TYPE_TKHD :
1814 return isom_print_tkhd;
1815 case QT_BOX_TYPE_TAPT :
1816 return isom_print_tapt;
1817 case QT_BOX_TYPE_CLEF :
1818 return isom_print_clef;
1819 case QT_BOX_TYPE_PROF :
1820 return isom_print_prof;
1821 case QT_BOX_TYPE_ENOF :
1822 return isom_print_enof;
1823 case ISOM_BOX_TYPE_EDTS :
1824 return isom_print_edts;
1825 case ISOM_BOX_TYPE_ELST :
1826 return isom_print_elst;
1827 case ISOM_BOX_TYPE_TREF :
1828 return isom_print_tref;
1829 case ISOM_BOX_TYPE_MDIA :
1830 return isom_print_mdia;
1831 case ISOM_BOX_TYPE_MDHD :
1832 return isom_print_mdhd;
1833 case ISOM_BOX_TYPE_HDLR :
1834 return isom_print_hdlr;
1835 case ISOM_BOX_TYPE_MINF :
1836 return isom_print_minf;
1837 case ISOM_BOX_TYPE_VMHD :
1838 return isom_print_vmhd;
1839 case ISOM_BOX_TYPE_SMHD :
1840 return isom_print_smhd;
1841 case ISOM_BOX_TYPE_HMHD :
1842 return isom_print_hmhd;
1843 case ISOM_BOX_TYPE_NMHD :
1844 return isom_print_nmhd;
1845 case QT_BOX_TYPE_GMHD :
1846 return isom_print_gmhd;
1847 case QT_BOX_TYPE_GMIN :
1848 return isom_print_gmin;
1849 case QT_BOX_TYPE_TEXT :
1850 return isom_print_text;
1851 case ISOM_BOX_TYPE_DINF :
1852 return isom_print_dinf;
1853 case ISOM_BOX_TYPE_DREF :
1854 return isom_print_dref;
1855 case ISOM_BOX_TYPE_URL :
1856 return isom_print_url;
1857 case ISOM_BOX_TYPE_STBL :
1858 return isom_print_stbl;
1859 case ISOM_BOX_TYPE_STSD :
1860 return isom_print_stsd;
1861 case ISOM_BOX_TYPE_BTRT :
1862 return isom_print_btrt;
1863 case ISOM_BOX_TYPE_CLAP :
1864 return isom_print_clap;
1865 case ISOM_BOX_TYPE_PASP :
1866 return isom_print_pasp;
1867 case QT_BOX_TYPE_COLR :
1868 return isom_print_colr;
1869 case ISOM_BOX_TYPE_STSL :
1870 return isom_print_stsl;
1871 case ISOM_BOX_TYPE_AVCC :
1872 return isom_print_avcC;
1873 case QT_BOX_TYPE_WAVE :
1874 return isom_print_wave;
1875 case QT_BOX_TYPE_CHAN :
1876 return isom_print_chan;
1877 case ISOM_BOX_TYPE_FTAB :
1878 return isom_print_ftab;
1879 case ISOM_BOX_TYPE_STTS :
1880 return isom_print_stts;
1881 case ISOM_BOX_TYPE_CTTS :
1882 return isom_print_ctts;
1883 case ISOM_BOX_TYPE_CSLG :
1884 return isom_print_cslg;
1885 case ISOM_BOX_TYPE_STSS :
1886 return isom_print_stss;
1887 case QT_BOX_TYPE_STPS :
1888 return isom_print_stps;
1889 case ISOM_BOX_TYPE_SDTP :
1890 return isom_print_sdtp;
1891 case ISOM_BOX_TYPE_STSC :
1892 return isom_print_stsc;
1893 case ISOM_BOX_TYPE_STSZ :
1894 return isom_print_stsz;
1895 case ISOM_BOX_TYPE_STCO :
1896 case ISOM_BOX_TYPE_CO64 :
1897 return isom_print_stco;
1898 case ISOM_BOX_TYPE_SGPD :
1899 return isom_print_sgpd;
1900 case ISOM_BOX_TYPE_SBGP :
1901 return isom_print_sbgp;
1902 case ISOM_BOX_TYPE_UDTA :
1903 return isom_print_udta;
1904 case ISOM_BOX_TYPE_CHPL :
1905 return isom_print_chpl;
1906 case ISOM_BOX_TYPE_MVEX :
1907 return isom_print_mvex;
1908 case ISOM_BOX_TYPE_MEHD :
1909 return isom_print_mehd;
1910 case ISOM_BOX_TYPE_TREX :
1911 return isom_print_trex;
1912 case ISOM_BOX_TYPE_MOOF :
1913 return isom_print_moof;
1914 case ISOM_BOX_TYPE_MFHD :
1915 return isom_print_mfhd;
1916 case ISOM_BOX_TYPE_TRAF :
1917 return isom_print_traf;
1918 case ISOM_BOX_TYPE_TFHD :
1919 return isom_print_tfhd;
1920 case ISOM_BOX_TYPE_TRUN :
1921 return isom_print_trun;
1922 case ISOM_BOX_TYPE_FREE :
1923 case ISOM_BOX_TYPE_SKIP :
1924 return isom_print_free;
1925 case ISOM_BOX_TYPE_MDAT :
1926 return isom_print_mdat;
1927 case ISOM_BOX_TYPE_META :
1928 return isom_print_meta;
1929 case ISOM_BOX_TYPE_ILST :
1930 return isom_print_ilst;
1931 case ISOM_BOX_TYPE_MFRA :
1932 return isom_print_mfra;
1933 case ISOM_BOX_TYPE_TFRA :
1934 return isom_print_tfra;
1935 case ISOM_BOX_TYPE_MFRO :
1936 return isom_print_mfro;
1937 default :
1938 return isom_print_unknown;
1942 int isom_add_print_func( lsmash_root_t *root, void *box, int level )
1944 if( !(root->flags & LSMASH_FILE_MODE_DUMP) )
1945 return 0;
1946 isom_print_entry_t *data = malloc( sizeof(isom_print_entry_t) );
1947 if( !data )
1948 return -1;
1949 data->level = level;
1950 data->box = (isom_box_t *)box;
1951 data->func = isom_select_print_func( (isom_box_t *)box );
1952 if( !data->func || lsmash_add_entry( root->print, data ) )
1954 free( data );
1955 return -1;
1957 return 0;
1960 static void isom_remove_print_func( isom_print_entry_t *data )
1962 if( !data || !data->box )
1963 return;
1964 if( data->box->manager & LSMASH_ABSENT_IN_ROOT )
1965 free( data->box ); /* free flagged box */
1966 free( data );
1969 void isom_remove_print_funcs( lsmash_root_t *root )
1971 lsmash_remove_list( root->print, isom_remove_print_func );
1972 root->print = NULL;
1975 #endif /* LSMASH_DEMUXER_ENABLED */