description: Remove a redundant condition for looking for suitable samplerate.
[L-SMASH.git] / core / print.c
blobf2a9d1ae5571272bc4d327652adff1bda2644e76
1 /*****************************************************************************
2 * print.c:
3 *****************************************************************************
4 * Copyright (C) 2010-2014 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 "common/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)( FILE *, lsmash_file_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_ifprintf_duration( FILE *fp, int indent, char *field_name, uint64_t duration, uint32_t timescale )
46 if( !timescale )
48 lsmash_ifprintf( fp, indent, "duration = %"PRIu64"\n", duration );
49 return;
51 int dur = duration / timescale;
52 int hour = (dur / 3600) % 24;
53 int min = (dur / 60) % 60;
54 int sec = dur % 60;
55 int ms = ((double)duration / timescale - (hour * 3600 + min * 60 + sec)) * 1e3 + 0.5;
56 static char str[32];
57 sprintf( str, "%02d:%02d:%02d.%03d", hour, min, sec, ms );
58 lsmash_ifprintf( fp, indent, "%s = %"PRIu64" (%s)\n", field_name, duration, str );
61 static char *isom_mp4time2utc( uint64_t mp4time )
63 int year_offset = mp4time / 31536000;
64 int leap_years = year_offset / 4 + ((mp4time / 86400) > 366); /* 1904 itself is leap year */
65 int day = (mp4time / 86400) - (year_offset * 365) - leap_years + 1;
66 while( day < 1 )
68 --year_offset;
69 leap_years = year_offset / 4 + ((mp4time / 86400) > 366);
70 day = (mp4time / 86400) - (year_offset * 365) - leap_years + 1;
72 int year = 1904 + year_offset;
73 int is_leap = (!(year % 4) && (year % 100)) || !(year % 400);
74 static const int month_days[13] = { 29, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
75 int month;
76 for( month = 1; month <= 12; month++ )
78 int i = (month == 2 && is_leap) ? 0 : month;
79 if( day <= month_days[i] )
80 break;
81 day -= month_days[i];
83 int hour = (mp4time / 3600) % 24;
84 int min = (mp4time / 60) % 60;
85 int sec = mp4time % 60;
86 static char utc[64];
87 sprintf( utc, "UTC %d/%02d/%02d, %02d:%02d:%02d\n", year, month, day, hour, min, sec );
88 return utc;
91 static void isom_ifprintf_matrix( FILE *fp, int indent, int32_t *matrix )
93 lsmash_ifprintf( fp, indent, "| a, b, u | | %f, %f, %f |\n", lsmash_fixed2double( matrix[0], 16 ),
94 lsmash_fixed2double( matrix[1], 16 ),
95 lsmash_fixed2double( matrix[2], 30 ) );
96 lsmash_ifprintf( fp, indent, "| c, d, v | = | %f, %f, %f |\n", lsmash_fixed2double( matrix[3], 16 ),
97 lsmash_fixed2double( matrix[4], 16 ),
98 lsmash_fixed2double( matrix[5], 30 ) );
99 lsmash_ifprintf( fp, indent, "| x, y, w | | %f, %f, %f |\n", lsmash_fixed2double( matrix[6], 16 ),
100 lsmash_fixed2double( matrix[7], 16 ),
101 lsmash_fixed2double( matrix[8], 30 ) );
104 static void isom_ifprintf_rgb_color( FILE *fp, int indent, uint16_t *color )
106 lsmash_ifprintf( fp, indent, "{ R, G, B } = { %"PRIu16", %"PRIu16", %"PRIu16" }\n", color[0], color[1], color[2] );
109 static void isom_ifprintf_rgba_color( FILE *fp, int indent, uint8_t *color )
111 lsmash_ifprintf( fp, indent, "{ R, G, B, A } = { %"PRIu8", %"PRIu8", %"PRIu8", %"PRIu8" }\n", color[0], color[1], color[2], color[3] );
114 static char *isom_unpack_iso_language( uint16_t language )
116 static char unpacked[4];
117 unpacked[0] = ((language >> 10) & 0x1f) + 0x60;
118 unpacked[1] = ((language >> 5) & 0x1f) + 0x60;
119 unpacked[2] = ( language & 0x1f) + 0x60;
120 unpacked[3] = 0;
121 return unpacked;
124 static void isom_ifprintf_sample_description_common_reserved( FILE *fp, int indent, uint8_t *reserved )
126 uint64_t temp = ((uint64_t)reserved[0] << 40)
127 | ((uint64_t)reserved[1] << 32)
128 | ((uint64_t)reserved[2] << 24)
129 | ((uint64_t)reserved[3] << 16)
130 | ((uint64_t)reserved[4] << 8)
131 | (uint64_t)reserved[5];
132 lsmash_ifprintf( fp, indent, "reserved = 0x%012"PRIx64"\n", temp );
135 static void isom_ifprintf_sample_flags( FILE *fp, int indent, char *field_name, isom_sample_flags_t *flags )
137 uint32_t temp = (flags->reserved << 28)
138 | (flags->is_leading << 26)
139 | (flags->sample_depends_on << 24)
140 | (flags->sample_is_depended_on << 22)
141 | (flags->sample_has_redundancy << 20)
142 | (flags->sample_padding_value << 17)
143 | (flags->sample_is_non_sync_sample << 16)
144 | flags->sample_degradation_priority;
145 lsmash_ifprintf( fp, indent++, "%s = 0x%08"PRIx32"\n", field_name, temp );
146 if( flags->is_leading & ISOM_SAMPLE_IS_UNDECODABLE_LEADING ) lsmash_ifprintf( fp, indent, "undecodable leading\n" );
147 else if( flags->is_leading & ISOM_SAMPLE_IS_NOT_LEADING ) lsmash_ifprintf( fp, indent, "non-leading\n" );
148 else if( flags->is_leading & ISOM_SAMPLE_IS_DECODABLE_LEADING ) lsmash_ifprintf( fp, indent, "decodable leading\n" );
149 if( flags->sample_depends_on & ISOM_SAMPLE_IS_INDEPENDENT ) lsmash_ifprintf( fp, indent, "independent\n" );
150 else if( flags->sample_depends_on & ISOM_SAMPLE_IS_NOT_INDEPENDENT ) lsmash_ifprintf( fp, indent, "dependent\n" );
151 if( flags->sample_is_depended_on & ISOM_SAMPLE_IS_NOT_DISPOSABLE ) lsmash_ifprintf( fp, indent, "non-disposable\n" );
152 else if( flags->sample_is_depended_on & ISOM_SAMPLE_IS_DISPOSABLE ) lsmash_ifprintf( fp, indent, "disposable\n" );
153 if( flags->sample_has_redundancy & ISOM_SAMPLE_HAS_REDUNDANCY ) lsmash_ifprintf( fp, indent, "redundant\n" );
154 else if( flags->sample_has_redundancy & ISOM_SAMPLE_HAS_NO_REDUNDANCY ) lsmash_ifprintf( fp, indent, "non-redundant\n" );
155 if( flags->sample_padding_value )
156 lsmash_ifprintf( fp, indent, "padding_bits = %"PRIu8"\n", flags->sample_padding_value );
157 lsmash_ifprintf( fp, indent, flags->sample_is_non_sync_sample ? "non-sync sample\n" : "sync sample\n" );
158 lsmash_ifprintf( fp, indent, "degradation_priority = %"PRIu16"\n", flags->sample_degradation_priority );
161 static inline int isom_print_simple( FILE *fp, isom_box_t *box, int level, char *name )
163 int indent = level;
164 if( box->type.fourcc != ISOM_BOX_TYPE_UUID.fourcc )
166 lsmash_ifprintf( fp, indent++, "[%s: %s]\n", isom_4cc2str( box->type.fourcc ), name );
167 lsmash_ifprintf( fp, indent, "position = %"PRIu64"\n", box->pos );
168 lsmash_ifprintf( fp, indent, "size = %"PRIu64"\n", box->size );
170 else
172 lsmash_ifprintf( fp, indent++, "[uuid: UUID Box]\n" );
173 lsmash_ifprintf( fp, indent, "position = %"PRIu64"\n", box->pos );
174 lsmash_ifprintf( fp, indent, "size = %"PRIu64"\n", box->size );
175 lsmash_ifprintf( fp, indent++, "usertype\n" );
176 if( isom_is_printable_4cc( box->type.user.fourcc ) )
177 lsmash_ifprintf( fp, indent, "type = %s\n", isom_4cc2str( box->type.user.fourcc ) );
178 lsmash_ifprintf( fp, indent, "name = %s\n", name );
179 lsmash_ifprintf( fp, indent, "uuid = 0x%08"PRIx32"-%04"PRIx16"-%04"PRIx16"-%04"PRIx16"-%04"PRIx16"0x%08"PRIx32"\n",
180 box->type.user.fourcc,
181 (box->type.user.id[0] << 8) | box->type.user.id[1], (box->type.user.id[2] << 8) | box->type.user.id[3],
182 (box->type.user.id[4] << 8) | box->type.user.id[5], (box->type.user.id[6] << 8) | box->type.user.id[7],
183 (box->type.user.id[8] << 24) | (box->type.user.id[9] << 16) | (box->type.user.id[10] << 8) | box->type.user.id[11] );
185 return 0;
188 static void isom_print_basebox_common( FILE *fp, int indent, isom_box_t *box, char *name )
190 isom_print_simple( fp, box, indent, name );
193 static void isom_print_fullbox_common( FILE *fp, int indent, isom_box_t *box, char *name )
195 isom_print_simple( fp, box, indent++, name );
196 lsmash_ifprintf( fp, indent, "version = %"PRIu8"\n", box->version );
197 lsmash_ifprintf( fp, indent, "flags = 0x%06"PRIx32"\n", box->flags & 0x00ffffff );
200 static void isom_print_box_common( FILE *fp, int indent, isom_box_t *box, char *name )
202 isom_box_t *parent = box->parent;
203 if( parent && lsmash_check_box_type_identical( parent->type, ISOM_BOX_TYPE_STSD ) )
205 isom_print_basebox_common( fp, indent, box, name );
206 return;
208 if( isom_is_fullbox( box ) )
209 isom_print_fullbox_common( fp, indent, box, name );
210 else
211 isom_print_basebox_common( fp, indent, box, name );
214 static int isom_print_unknown( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
216 int indent = level;
217 if( box->type.fourcc != ISOM_BOX_TYPE_UUID.fourcc )
219 lsmash_ifprintf( fp, indent++, "[%s]\n", isom_4cc2str( box->type.fourcc ) );
220 lsmash_ifprintf( fp, indent, "position = %"PRIu64"\n", box->pos );
221 lsmash_ifprintf( fp, indent, "size = %"PRIu64"\n", box->size );
223 else
225 lsmash_ifprintf( fp, indent++, "[uuid: UUID Box]\n" );
226 lsmash_ifprintf( fp, indent, "position = %"PRIu64"\n", box->pos );
227 lsmash_ifprintf( fp, indent, "size = %"PRIu64"\n", box->size );
228 lsmash_ifprintf( fp, indent++, "usertype\n" );
229 if( isom_is_printable_4cc( box->type.user.fourcc ) )
230 lsmash_ifprintf( fp, indent, "type = %s\n", isom_4cc2str( box->type.user.fourcc ) );
231 lsmash_ifprintf( fp, indent, "uuid = 0x%08"PRIx32"-%04"PRIx16"-%04"PRIx16"-%04"PRIx16"-%04"PRIx16"%08"PRIx32"\n",
232 box->type.user.fourcc,
233 (box->type.user.id[0] << 8) | box->type.user.id[1], (box->type.user.id[2] << 8) | box->type.user.id[3],
234 (box->type.user.id[4] << 8) | box->type.user.id[5], (box->type.user.id[6] << 8) | box->type.user.id[7],
235 (box->type.user.id[8] << 24) | (box->type.user.id[9] << 16) | (box->type.user.id[10] << 8) | box->type.user.id[11] );
237 return 0;
240 static void isom_print_brand_description( FILE *fp, lsmash_brand_type brand )
242 if( brand == 0 )
243 return;
244 static const struct
246 lsmash_brand_type brand;
247 char *description;
248 } brand_description_table[] =
250 { ISOM_BRAND_TYPE_3G2A, "3GPP2" },
251 { ISOM_BRAND_TYPE_3GE6, "3GPP Release 6 Extended Presentation Profile" },
252 { ISOM_BRAND_TYPE_3GE9, "3GPP Release 9 Extended Presentation Profile" },
253 { ISOM_BRAND_TYPE_3GF9, "3GPP Release 9 File-delivery Server Profile" },
254 { ISOM_BRAND_TYPE_3GG6, "3GPP Release 6 General Profile" },
255 { ISOM_BRAND_TYPE_3GG9, "3GPP Release 9 General Profile" },
256 { ISOM_BRAND_TYPE_3GH9, "3GPP Release 9 Adaptive Streaming Profile" },
257 { ISOM_BRAND_TYPE_3GM9, "3GPP Release 9 Media Segment Profile" },
258 { ISOM_BRAND_TYPE_3GP4, "3GPP Release 4" },
259 { ISOM_BRAND_TYPE_3GP5, "3GPP Release 5" },
260 { ISOM_BRAND_TYPE_3GP6, "3GPP Release 6 Basic Profile" },
261 { ISOM_BRAND_TYPE_3GP7, "3GPP Release 7" },
262 { ISOM_BRAND_TYPE_3GP8, "3GPP Release 8" },
263 { ISOM_BRAND_TYPE_3GP9, "3GPP Release 9 Basic Profile" },
264 { ISOM_BRAND_TYPE_3GR6, "3GPP Release 6 Progressive Download Profile" },
265 { ISOM_BRAND_TYPE_3GR9, "3GPP Release 9 Progressive Download Profile" },
266 { ISOM_BRAND_TYPE_3GS6, "3GPP Release 6 Streaming Server Profile" },
267 { ISOM_BRAND_TYPE_3GS9, "3GPP Release 9 Streaming Server Profile" },
268 { ISOM_BRAND_TYPE_3GT9, "3GPP Release 9 Media Stream Recording Profile" },
269 { ISOM_BRAND_TYPE_ARRI, "ARRI Digital Camera" },
270 { ISOM_BRAND_TYPE_CAEP, "Canon Digital Camera" },
271 { ISOM_BRAND_TYPE_CDES, "Convergent Designs" },
272 { ISOM_BRAND_TYPE_LCAG, "Leica digital camera" },
273 { ISOM_BRAND_TYPE_M4A , "iTunes MPEG-4 audio protected or not" },
274 { ISOM_BRAND_TYPE_M4B , "iTunes AudioBook protected or not" },
275 { ISOM_BRAND_TYPE_M4P , "MPEG-4 protected audio" },
276 { ISOM_BRAND_TYPE_M4V , "MPEG-4 protected audio+video" },
277 { ISOM_BRAND_TYPE_MFSM, "Media File for Samsung video Metadata" },
278 { ISOM_BRAND_TYPE_MPPI, "Photo Player Multimedia Application Format" },
279 { ISOM_BRAND_TYPE_ROSS, "Ross Video" },
280 { ISOM_BRAND_TYPE_AVC1, "Advanced Video Coding extensions" },
281 { ISOM_BRAND_TYPE_BBXM, "Blinkbox Master File" },
282 { ISOM_BRAND_TYPE_CAQV, "Casio Digital Camera" },
283 { ISOM_BRAND_TYPE_CCFF, "Common container file format" },
284 { ISOM_BRAND_TYPE_DA0A, "DMB AF" },
285 { ISOM_BRAND_TYPE_DA0B, "DMB AF" },
286 { ISOM_BRAND_TYPE_DA1A, "DMB AF" },
287 { ISOM_BRAND_TYPE_DA1B, "DMB AF" },
288 { ISOM_BRAND_TYPE_DA2A, "DMB AF" },
289 { ISOM_BRAND_TYPE_DA2B, "DMB AF" },
290 { ISOM_BRAND_TYPE_DA3A, "DMB AF" },
291 { ISOM_BRAND_TYPE_DA3B, "DMB AF" },
292 { ISOM_BRAND_TYPE_DASH, "Indexed self-initializing Media Segment" },
293 { ISOM_BRAND_TYPE_DBY1, "MP4 files with Dolby content" },
294 { ISOM_BRAND_TYPE_DMB1, "DMB AF" },
295 { ISOM_BRAND_TYPE_DSMS, "Self-initializing Media Segment" },
296 { ISOM_BRAND_TYPE_DV1A, "DMB AF" },
297 { ISOM_BRAND_TYPE_DV1B, "DMB AF" },
298 { ISOM_BRAND_TYPE_DV2A, "DMB AF" },
299 { ISOM_BRAND_TYPE_DV2B, "DMB AF" },
300 { ISOM_BRAND_TYPE_DV3A, "DMB AF" },
301 { ISOM_BRAND_TYPE_DV3B, "DMB AF" },
302 { ISOM_BRAND_TYPE_DVR1, "DVB RTP" },
303 { ISOM_BRAND_TYPE_DVT1, "DVB Transport Stream" },
304 { ISOM_BRAND_TYPE_IFRM, "Apple iFrame" },
305 { ISOM_BRAND_TYPE_ISC2, "Files encrypted according to ISMACryp 2.0" },
306 { ISOM_BRAND_TYPE_ISO2, "ISO Base Media file format version 2" },
307 { ISOM_BRAND_TYPE_ISO3, "ISO Base Media file format version 3" },
308 { ISOM_BRAND_TYPE_ISO4, "ISO Base Media file format version 4" },
309 { ISOM_BRAND_TYPE_ISO5, "ISO Base Media file format version 5" },
310 { ISOM_BRAND_TYPE_ISO6, "ISO Base Media file format version 6" },
311 { ISOM_BRAND_TYPE_ISO7, "ISO Base Media file format version 7" },
312 { ISOM_BRAND_TYPE_ISOM, "ISO Base Media file format version 1" },
313 { ISOM_BRAND_TYPE_JPSI, "The JPSearch data interchange format" },
314 { ISOM_BRAND_TYPE_LMSG, "last Media Segment indicator" },
315 { ISOM_BRAND_TYPE_MJ2S, "Motion JPEG 2000 simple profile" },
316 { ISOM_BRAND_TYPE_MJP2, "Motion JPEG 2000, general profile" },
317 { ISOM_BRAND_TYPE_MP21, "MPEG-21" },
318 { ISOM_BRAND_TYPE_MP41, "MP4 version 1" },
319 { ISOM_BRAND_TYPE_MP42, "MP4 version 2" },
320 { ISOM_BRAND_TYPE_MP71, "MPEG-7 file-level metadata" },
321 { ISOM_BRAND_TYPE_MSDH, "Media Segment" },
322 { ISOM_BRAND_TYPE_MSIX, "Indexed Media Segment" },
323 { ISOM_BRAND_TYPE_NIKO, "Nikon Digital Camera" },
324 { ISOM_BRAND_TYPE_ODCF, "OMA DCF" },
325 { ISOM_BRAND_TYPE_OPF2, "OMA PDCF" },
326 { ISOM_BRAND_TYPE_OPX2, "OMA Adapted PDCF" },
327 { ISOM_BRAND_TYPE_PANA, "Panasonic Digital Camera" },
328 { ISOM_BRAND_TYPE_PIFF, "Protected Interoperable File Format" },
329 { ISOM_BRAND_TYPE_PNVI, "Panasonic Video Intercom" },
330 { ISOM_BRAND_TYPE_QT , "QuickTime file format" },
331 { ISOM_BRAND_TYPE_RISX, "Representation Index Segment" },
332 { ISOM_BRAND_TYPE_SDV , "SD Video" },
333 { ISOM_BRAND_TYPE_SIMS, "Sub-Indexed Media Segment" },
334 { ISOM_BRAND_TYPE_SISX, "Single Index Segment" },
335 { ISOM_BRAND_TYPE_SSSS, "Subsegment Index Segment" },
336 { 0, NULL }
338 for( int i = 0; brand_description_table[i].description; i++ )
339 if( brand == brand_description_table[i].brand )
341 fprintf( fp, " : %s\n", brand_description_table[i].description );
342 return;
344 fprintf( fp, "\n" );
347 static void isom_print_file_type
349 FILE *fp,
350 int indent,
351 uint32_t major_brand,
352 uint32_t minor_version,
353 uint32_t brand_count,
354 uint32_t *compatible_brands
357 lsmash_ifprintf( fp, indent, "major_brand = %s", isom_4cc2str( major_brand ) );
358 isom_print_brand_description( fp, major_brand );
359 lsmash_ifprintf( fp, indent, "minor_version = %"PRIu32"\n", minor_version );
360 lsmash_ifprintf( fp, indent++, "compatible_brands\n" );
361 for( uint32_t i = 0; i < brand_count; i++ )
363 if( compatible_brands[i] )
365 lsmash_ifprintf( fp, indent, "brand[%"PRIu32"] = %s", i, isom_4cc2str( compatible_brands[i] ) );
366 isom_print_brand_description( fp, compatible_brands[i] );
368 else
369 lsmash_ifprintf( fp, indent, "brand[%"PRIu32"] = (void)\n", i );
373 static int isom_print_ftyp( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
375 isom_ftyp_t *ftyp = (isom_ftyp_t *)box;
376 int indent = level;
377 isom_print_box_common( fp, indent++, box, "File Type Box" );
378 isom_print_file_type( fp, indent, ftyp->major_brand, ftyp->minor_version, ftyp->brand_count, ftyp->compatible_brands );
379 return 0;
382 static int isom_print_styp( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
384 /* Print 'valid' if this box is the first box in a file. */
385 int valid;
386 if( file
387 && file->print
388 && file->print->head
389 && file->print->head->data )
390 valid = (box == ((isom_print_entry_t *)file->print->head->data)->box);
391 else
392 valid = 0;
393 char *name = valid ? "Segment Type Box (valid)" : "Segment Type Box";
394 isom_styp_t *styp = (isom_styp_t *)box;
395 int indent = level;
396 isom_print_box_common( fp, indent++, box, name );
397 isom_print_file_type( fp, indent, styp->major_brand, styp->minor_version, styp->brand_count, styp->compatible_brands );
398 return 0;
401 static int isom_print_sidx( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
403 if( !((isom_sidx_t *)box)->list )
404 return -1;
405 isom_sidx_t *sidx = (isom_sidx_t *)box;
406 int indent = level;
407 isom_print_box_common( fp, indent++, box, "Segment Index Box" );
408 lsmash_ifprintf( fp, indent, "reference_ID = %"PRIu32"\n", sidx->reference_ID );
409 lsmash_ifprintf( fp, indent, "timescale = %"PRIu32"\n", sidx->timescale );
410 lsmash_ifprintf( fp, indent, "earliest_presentation_time = %"PRIu64"\n", sidx->earliest_presentation_time );
411 lsmash_ifprintf( fp, indent, "first_offset = %"PRIu64"\n", sidx->first_offset );
412 lsmash_ifprintf( fp, indent, "reserved = %"PRIu16"\n", sidx->reserved );
413 lsmash_ifprintf( fp, indent, "reference_count = %"PRIu16"\n", sidx->reference_count );
414 uint32_t i = 0;
415 for( lsmash_entry_t *entry = sidx->list->head; entry; entry = entry->next )
417 isom_sidx_referenced_item_t *data = (isom_sidx_referenced_item_t *)entry->data;
418 lsmash_ifprintf( fp, indent++, "entry[%"PRIu32"]\n", i++ );
419 lsmash_ifprintf( fp, indent, "reference_type = %"PRIu8" (%s)\n", data->reference_type, data->reference_type ? "index" : "media" );
420 lsmash_ifprintf( fp, indent, "reference_size = %"PRIu32"\n", data->reference_size );
421 lsmash_ifprintf( fp, indent, "subsegment_duration = %"PRIu32"\n", data->subsegment_duration );
422 lsmash_ifprintf( fp, indent, "starts_with_SAP = %"PRIu8"%s\n", data->starts_with_SAP, data->starts_with_SAP ? " (yes)" : "" );
423 lsmash_ifprintf( fp, indent, "SAP_type = %"PRIu8"%s\n", data->SAP_type, data->SAP_type == 0 ? " (unknown)" : "" );
424 lsmash_ifprintf( fp, indent--, "SAP_delta_time = %"PRIu32"\n", data->SAP_delta_time );
426 return 0;
429 static int isom_print_moov( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
431 return isom_print_simple( fp, box, level, "Movie Box" );
434 static int isom_print_mvhd( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
436 isom_mvhd_t *mvhd = (isom_mvhd_t *)box;
437 int indent = level;
438 isom_print_box_common( fp, indent++, box, "Movie Header Box" );
439 lsmash_ifprintf( fp, indent, "creation_time = %s", isom_mp4time2utc( mvhd->creation_time ) );
440 lsmash_ifprintf( fp, indent, "modification_time = %s", isom_mp4time2utc( mvhd->modification_time ) );
441 lsmash_ifprintf( fp, indent, "timescale = %"PRIu32"\n", mvhd->timescale );
442 isom_ifprintf_duration( fp, indent, "duration", mvhd->duration, mvhd->timescale );
443 lsmash_ifprintf( fp, indent, "rate = %f\n", lsmash_fixed2double( mvhd->rate, 16 ) );
444 lsmash_ifprintf( fp, indent, "volume = %f\n", lsmash_fixed2double( mvhd->volume, 8 ) );
445 lsmash_ifprintf( fp, indent, "reserved = 0x%04"PRIx16"\n", mvhd->reserved );
446 if( file->qt_compatible )
448 lsmash_ifprintf( fp, indent, "preferredLong1 = 0x%08"PRIx32"\n", mvhd->preferredLong[0] );
449 lsmash_ifprintf( fp, indent, "preferredLong2 = 0x%08"PRIx32"\n", mvhd->preferredLong[1] );
450 lsmash_ifprintf( fp, indent, "transformation matrix\n" );
451 isom_ifprintf_matrix( fp, indent + 1, mvhd->matrix );
452 lsmash_ifprintf( fp, indent, "previewTime = %"PRId32"\n", mvhd->previewTime );
453 lsmash_ifprintf( fp, indent, "previewDuration = %"PRId32"\n", mvhd->previewDuration );
454 lsmash_ifprintf( fp, indent, "posterTime = %"PRId32"\n", mvhd->posterTime );
455 lsmash_ifprintf( fp, indent, "selectionTime = %"PRId32"\n", mvhd->selectionTime );
456 lsmash_ifprintf( fp, indent, "selectionDuration = %"PRId32"\n", mvhd->selectionDuration );
457 lsmash_ifprintf( fp, indent, "currentTime = %"PRId32"\n", mvhd->currentTime );
459 else
461 lsmash_ifprintf( fp, indent, "reserved = 0x%08"PRIx32"\n", mvhd->preferredLong[0] );
462 lsmash_ifprintf( fp, indent, "reserved = 0x%08"PRIx32"\n", mvhd->preferredLong[1] );
463 lsmash_ifprintf( fp, indent, "transformation matrix\n" );
464 isom_ifprintf_matrix( fp, indent + 1, mvhd->matrix );
465 lsmash_ifprintf( fp, indent, "pre_defined = 0x%08"PRIx32"\n", mvhd->previewTime );
466 lsmash_ifprintf( fp, indent, "pre_defined = 0x%08"PRIx32"\n", mvhd->previewDuration );
467 lsmash_ifprintf( fp, indent, "pre_defined = 0x%08"PRIx32"\n", mvhd->posterTime );
468 lsmash_ifprintf( fp, indent, "pre_defined = 0x%08"PRIx32"\n", mvhd->selectionTime );
469 lsmash_ifprintf( fp, indent, "pre_defined = 0x%08"PRIx32"\n", mvhd->selectionDuration );
470 lsmash_ifprintf( fp, indent, "pre_defined = 0x%08"PRIx32"\n", mvhd->currentTime );
472 lsmash_ifprintf( fp, indent, "next_track_ID = %"PRIu32"\n", mvhd->next_track_ID );
473 return 0;
476 static void isom_pring_qt_color_table( FILE *fp, int indent, isom_qt_color_table_t *color_table )
478 isom_qt_color_array_t *array = color_table->array;
479 if( !array )
480 return;
481 lsmash_ifprintf( fp, indent, "ctSeed = %"PRIu32"\n", color_table->seed );
482 lsmash_ifprintf( fp, indent, "ctFlags = 0x%04"PRIx16"\n", color_table->flags );
483 lsmash_ifprintf( fp, indent, "ctSize = %"PRIu16"\n", color_table->size );
484 lsmash_ifprintf( fp, indent++, "ctTable\n" );
485 for( uint16_t i = 0; i <= color_table->size; i++ )
486 lsmash_ifprintf( fp, indent,
487 "color[%"PRIu16"] = { 0x%04"PRIx16", 0x%04"PRIx16", 0x%04"PRIx16", 0x%04"PRIx16" }\n",
488 i, array[i].value, array[i].r, array[i].g, array[i].b );
491 static int isom_print_ctab( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
493 isom_ctab_t *ctab = (isom_ctab_t *)box;
494 int indent = level;
495 isom_print_box_common( fp, indent, box, "Color Table Box" );
496 isom_pring_qt_color_table( fp, indent + 1, &ctab->color_table );
497 return 0;
500 static int isom_print_iods( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
502 extern void mp4sys_print_descriptor( FILE *, void *, int );
503 isom_iods_t *iods = (isom_iods_t *)box;
504 int indent = level;
505 isom_print_box_common( fp, indent, box, "Object Descriptor Box" );
506 mp4sys_print_descriptor( fp, iods->OD, indent + 1 );
507 return 0;
510 static int isom_print_trak( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
512 return isom_print_simple( fp, box, level, "Track Box" );
515 static int isom_print_tkhd( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
517 isom_tkhd_t *tkhd = (isom_tkhd_t *)box;
518 int indent = level;
519 isom_print_box_common( fp, indent++, box, "Track Header Box" );
520 ++indent;
521 if( tkhd->flags & ISOM_TRACK_ENABLED )
522 lsmash_ifprintf( fp, indent, "Track enabled\n" );
523 else
524 lsmash_ifprintf( fp, indent, "Track disabled\n" );
525 if( tkhd->flags & ISOM_TRACK_IN_MOVIE )
526 lsmash_ifprintf( fp, indent, "Track in movie\n" );
527 if( tkhd->flags & ISOM_TRACK_IN_PREVIEW )
528 lsmash_ifprintf( fp, indent, "Track in preview\n" );
529 if( file->qt_compatible && (tkhd->flags & QT_TRACK_IN_POSTER) )
530 lsmash_ifprintf( fp, indent, "Track in poster\n" );
531 lsmash_ifprintf( fp, --indent, "creation_time = %s", isom_mp4time2utc( tkhd->creation_time ) );
532 lsmash_ifprintf( fp, indent, "modification_time = %s", isom_mp4time2utc( tkhd->modification_time ) );
533 lsmash_ifprintf( fp, indent, "track_ID = %"PRIu32"\n", tkhd->track_ID );
534 lsmash_ifprintf( fp, indent, "reserved = 0x%08"PRIx32"\n", tkhd->reserved1 );
535 if( file && file->moov && file->moov->mvhd )
536 isom_ifprintf_duration( fp, indent, "duration", tkhd->duration, file->moov->mvhd->timescale );
537 else
538 isom_ifprintf_duration( fp, indent, "duration", tkhd->duration, 0 );
539 lsmash_ifprintf( fp, indent, "reserved = 0x%08"PRIx32"\n", tkhd->reserved2[0] );
540 lsmash_ifprintf( fp, indent, "reserved = 0x%08"PRIx32"\n", tkhd->reserved2[1] );
541 lsmash_ifprintf( fp, indent, "layer = %"PRId16"\n", tkhd->layer );
542 lsmash_ifprintf( fp, indent, "alternate_group = %"PRId16"\n", tkhd->alternate_group );
543 lsmash_ifprintf( fp, indent, "volume = %f\n", lsmash_fixed2double( tkhd->volume, 8 ) );
544 lsmash_ifprintf( fp, indent, "reserved = 0x%04"PRIx16"\n", tkhd->reserved3 );
545 lsmash_ifprintf( fp, indent, "transformation matrix\n" );
546 isom_ifprintf_matrix( fp, indent + 1, tkhd->matrix );
547 lsmash_ifprintf( fp, indent, "width = %f\n", lsmash_fixed2double( tkhd->width, 16 ) );
548 lsmash_ifprintf( fp, indent, "height = %f\n", lsmash_fixed2double( tkhd->height, 16 ) );
549 return 0;
552 static int isom_print_tapt( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
554 return isom_print_simple( fp, box, level, "Track Aperture Mode Dimensions Box" );
557 static int isom_print_clef( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
559 isom_clef_t *clef = (isom_clef_t *)box;
560 int indent = level;
561 isom_print_box_common( fp, indent++, box, "Track Clean Aperture Dimensions Box" );
562 lsmash_ifprintf( fp, indent, "width = %f\n", lsmash_fixed2double( clef->width, 16 ) );
563 lsmash_ifprintf( fp, indent, "height = %f\n", lsmash_fixed2double( clef->height, 16 ) );
564 return 0;
567 static int isom_print_prof( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
569 isom_prof_t *prof = (isom_prof_t *)box;
570 int indent = level;
571 isom_print_box_common( fp, indent++, box, "Track Production Aperture Dimensions Box" );
572 lsmash_ifprintf( fp, indent, "width = %f\n", lsmash_fixed2double( prof->width, 16 ) );
573 lsmash_ifprintf( fp, indent, "height = %f\n", lsmash_fixed2double( prof->height, 16 ) );
574 return 0;
577 static int isom_print_enof( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
579 isom_enof_t *enof = (isom_enof_t *)box;
580 int indent = level;
581 isom_print_box_common( fp, indent++, box, "Track Encoded Pixels Dimensions Box" );
582 lsmash_ifprintf( fp, indent, "width = %f\n", lsmash_fixed2double( enof->width, 16 ) );
583 lsmash_ifprintf( fp, indent, "height = %f\n", lsmash_fixed2double( enof->height, 16 ) );
584 return 0;
587 static int isom_print_edts( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
589 return isom_print_simple( fp, box, level, "Edit Box" );
592 static int isom_print_elst( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
594 isom_elst_t *elst = (isom_elst_t *)box;
595 int indent = level;
596 uint32_t i = 0;
597 isom_print_box_common( fp, indent++, box, "Edit List Box" );
598 lsmash_ifprintf( fp, indent, "entry_count = %"PRIu32"\n", elst->list->entry_count );
599 for( lsmash_entry_t *entry = elst->list->head; entry; entry = entry->next )
601 isom_elst_entry_t *data = (isom_elst_entry_t *)entry->data;
602 lsmash_ifprintf( fp, indent++, "entry[%"PRIu32"]\n", i++ );
603 lsmash_ifprintf( fp, indent, "segment_duration = %"PRIu64"\n", data->segment_duration );
604 lsmash_ifprintf( fp, indent, "media_time = %"PRId64"\n", data->media_time );
605 lsmash_ifprintf( fp, indent--, "media_rate = %f\n", lsmash_fixed2double( data->media_rate, 16 ) );
607 return 0;
610 static int isom_print_tref( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
612 return isom_print_simple( fp, box, level, "Track Reference Box" );
615 static int isom_print_track_reference_type( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
617 isom_tref_type_t *ref = (isom_tref_type_t *)box;
618 int indent = level;
619 isom_print_box_common( fp, indent++, box, "Track Reference Type Box" );
620 for( uint32_t i = 0; i < ref->ref_count; i++ )
621 lsmash_ifprintf( fp, indent, "track_ID[%"PRIu32"] = %"PRIu32"\n", i, ref->track_ID[i] );
622 return 0;
625 static int isom_print_mdia( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
627 return isom_print_simple( fp, box, level, "Media Box" );
630 static int isom_print_mdhd( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
632 isom_mdhd_t *mdhd = (isom_mdhd_t *)box;
633 int indent = level;
634 isom_print_box_common( fp, indent++, box, "Media Header Box" );
635 lsmash_ifprintf( fp, indent, "creation_time = %s", isom_mp4time2utc( mdhd->creation_time ) );
636 lsmash_ifprintf( fp, indent, "modification_time = %s", isom_mp4time2utc( mdhd->modification_time ) );
637 lsmash_ifprintf( fp, indent, "timescale = %"PRIu32"\n", mdhd->timescale );
638 isom_ifprintf_duration( fp, indent, "duration", mdhd->duration, mdhd->timescale );
639 if( mdhd->language >= 0x800 )
640 lsmash_ifprintf( fp, indent, "language = %s\n", isom_unpack_iso_language( mdhd->language ) );
641 else
642 lsmash_ifprintf( fp, indent, "language = %"PRIu16"\n", mdhd->language );
643 if( file->qt_compatible )
644 lsmash_ifprintf( fp, indent, "quality = %"PRId16"\n", mdhd->quality );
645 else
646 lsmash_ifprintf( fp, indent, "pre_defined = 0x%04"PRIx16"\n", mdhd->quality );
647 return 0;
650 static int isom_print_hdlr( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
652 isom_hdlr_t *hdlr = (isom_hdlr_t *)box;
653 int indent = level;
654 char str[hdlr->componentName_length + 1];
655 memcpy( str, hdlr->componentName, hdlr->componentName_length );
656 str[hdlr->componentName_length] = 0;
657 isom_print_box_common( fp, indent++, box, "Handler Reference Box" );
658 if( file->qt_compatible )
660 lsmash_ifprintf( fp, indent, "componentType = %s\n", isom_4cc2str( hdlr->componentType ) );
661 lsmash_ifprintf( fp, indent, "componentSubtype = %s\n", isom_4cc2str( hdlr->componentSubtype ) );
662 lsmash_ifprintf( fp, indent, "componentManufacturer = %s\n", isom_4cc2str( hdlr->componentManufacturer ) );
663 lsmash_ifprintf( fp, indent, "componentFlags = 0x%08"PRIx32"\n", hdlr->componentFlags );
664 lsmash_ifprintf( fp, indent, "componentFlagsMask = 0x%08"PRIx32"\n", hdlr->componentFlagsMask );
665 if( hdlr->componentName_length )
666 lsmash_ifprintf( fp, indent, "componentName = %s\n", &str[1] );
667 else
668 lsmash_ifprintf( fp, indent, "componentName = \n" );
670 else
672 lsmash_ifprintf( fp, indent, "pre_defined = 0x%08"PRIx32"\n", hdlr->componentType );
673 lsmash_ifprintf( fp, indent, "handler_type = %s\n", isom_4cc2str( hdlr->componentSubtype ) );
674 lsmash_ifprintf( fp, indent, "reserved = 0x%08"PRIx32"\n", hdlr->componentManufacturer );
675 lsmash_ifprintf( fp, indent, "reserved = 0x%08"PRIx32"\n", hdlr->componentFlags );
676 lsmash_ifprintf( fp, indent, "reserved = 0x%08"PRIx32"\n", hdlr->componentFlagsMask );
677 lsmash_ifprintf( fp, indent, "name = %s\n", str );
679 return 0;
682 static int isom_print_minf( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
684 return isom_print_simple( fp, box, level, "Media Information Box" );
687 static int isom_print_vmhd( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
689 isom_vmhd_t *vmhd = (isom_vmhd_t *)box;
690 int indent = level;
691 isom_print_box_common( fp, indent++, box, "Video Media Header Box" );
692 lsmash_ifprintf( fp, indent, "graphicsmode = %"PRIu16"\n", vmhd->graphicsmode );
693 lsmash_ifprintf( fp, indent, "opcolor\n" );
694 isom_ifprintf_rgb_color( fp, indent + 1, vmhd->opcolor );
695 return 0;
698 static int isom_print_smhd( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
700 isom_smhd_t *smhd = (isom_smhd_t *)box;
701 int indent = level;
702 isom_print_box_common( fp, indent++, box, "Sound Media Header Box" );
703 lsmash_ifprintf( fp, indent, "balance = %f\n", lsmash_fixed2double( smhd->balance, 8 ) );
704 lsmash_ifprintf( fp, indent, "reserved = 0x%04"PRIx16"\n", smhd->reserved );
705 return 0;
708 static int isom_print_hmhd( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
710 isom_hmhd_t *hmhd = (isom_hmhd_t *)box;
711 int indent = level;
712 isom_print_box_common( fp, indent++, box, "Hint Media Header Box" );
713 lsmash_ifprintf( fp, indent, "maxPDUsize = %"PRIu16"\n", hmhd->maxPDUsize );
714 lsmash_ifprintf( fp, indent, "avgPDUsize = %"PRIu16"\n", hmhd->avgPDUsize );
715 lsmash_ifprintf( fp, indent, "maxbitrate = %"PRIu32"\n", hmhd->maxbitrate );
716 lsmash_ifprintf( fp, indent, "avgbitrate = %"PRIu32"\n", hmhd->avgbitrate );
717 lsmash_ifprintf( fp, indent, "reserved = 0x%08"PRIx32"\n", hmhd->reserved );
718 return 0;
721 static int isom_print_nmhd( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
723 isom_print_box_common( fp, level, box, "Null Media Header Box" );
724 return 0;
727 static int isom_print_gmhd( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
729 return isom_print_simple( fp, box, level, "Generic Media Information Header Box" );
732 static int isom_print_gmin( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
734 isom_gmin_t *gmin = (isom_gmin_t *)box;
735 int indent = level;
736 isom_print_box_common( fp, indent++, box, "Generic Media Information Box" );
737 lsmash_ifprintf( fp, indent, "graphicsmode = %"PRIu16"\n", gmin->graphicsmode );
738 lsmash_ifprintf( fp, indent, "opcolor\n" );
739 isom_ifprintf_rgb_color( fp, indent + 1, gmin->opcolor );
740 lsmash_ifprintf( fp, indent, "balance = %f\n", lsmash_fixed2double( gmin->balance, 8 ) );
741 lsmash_ifprintf( fp, indent, "reserved = 0x%04"PRIx16"\n", gmin->reserved );
742 return 0;
745 static int isom_print_text( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
747 isom_text_t *text = (isom_text_t *)box;
748 int indent = level;
749 isom_print_box_common( fp, indent++, box, "Text Media Information Box" );
750 lsmash_ifprintf( fp, indent, "Unknown matrix\n" );
751 isom_ifprintf_matrix( fp, indent + 1, text->matrix );
752 return 0;
755 static int isom_print_dinf( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
757 return isom_print_simple( fp, box, level, "Data Information Box" );
760 static int isom_print_dref( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
762 isom_dref_t *dref = (isom_dref_t *)box;
763 int indent = level;
764 isom_print_box_common( fp, indent++, box, "Data Reference Box" );
765 lsmash_ifprintf( fp, indent, "entry_count = %"PRIu16"\n", dref->list.entry_count );
766 return 0;
769 static int isom_print_url( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
771 isom_dref_entry_t *url = (isom_dref_entry_t *)box;
772 int indent = level;
773 isom_print_box_common( fp, indent++, box, "Data Entry Url Box" );
774 if( url->flags & 0x000001 )
775 lsmash_ifprintf( fp, indent, "location = in the same file\n" );
776 else
777 lsmash_ifprintf( fp, indent, "location = %s\n", url->location );
778 return 0;
781 static int isom_print_stbl( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
783 return isom_print_simple( fp, box, level, "Sample Table Box" );
786 static int isom_print_stsd( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
788 isom_stsd_t *stsd = (isom_stsd_t *)box;
789 int indent = level;
790 isom_print_box_common( fp, indent++, box, "Sample Description Box" );
791 lsmash_ifprintf( fp, indent, "entry_count = %"PRIu32"\n", stsd->entry_count );
792 return 0;
795 static int isom_print_visual_description( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
797 isom_visual_entry_t *visual = (isom_visual_entry_t *)box;
798 int indent = level;
799 lsmash_ifprintf( fp, indent++, "[%s: Visual Description]\n", isom_4cc2str( visual->type.fourcc ) );
800 lsmash_ifprintf( fp, indent, "position = %"PRIu64"\n", visual->pos );
801 lsmash_ifprintf( fp, indent, "size = %"PRIu64"\n", visual->size );
802 isom_ifprintf_sample_description_common_reserved( fp, indent, visual->reserved );
803 lsmash_ifprintf( fp, indent, "data_reference_index = %"PRIu16"\n", visual->data_reference_index );
804 if( file->qt_compatible )
806 lsmash_ifprintf( fp, indent, "version = %"PRId16"\n", visual->version );
807 lsmash_ifprintf( fp, indent, "revision_level = %"PRId16"\n", visual->revision_level );
808 lsmash_ifprintf( fp, indent, "vendor = %s\n", isom_4cc2str( visual->vendor ) );
809 lsmash_ifprintf( fp, indent, "temporalQuality = %"PRIu32"\n", visual->temporalQuality );
810 lsmash_ifprintf( fp, indent, "spatialQuality = %"PRIu32"\n", visual->spatialQuality );
811 lsmash_ifprintf( fp, indent, "width = %"PRIu16"\n", visual->width );
812 lsmash_ifprintf( fp, indent, "height = %"PRIu16"\n", visual->height );
813 lsmash_ifprintf( fp, indent, "horizresolution = %f\n", lsmash_fixed2double( visual->horizresolution, 16 ) );
814 lsmash_ifprintf( fp, indent, "vertresolution = %f\n", lsmash_fixed2double( visual->vertresolution, 16 ) );
815 lsmash_ifprintf( fp, indent, "dataSize = %"PRIu32"\n", visual->dataSize );
816 lsmash_ifprintf( fp, indent, "frame_count = %"PRIu16"\n", visual->frame_count );
817 lsmash_ifprintf( fp, indent, "compressorname_length = %"PRIu8"\n", visual->compressorname[0] );
818 lsmash_ifprintf( fp, indent, "compressorname = %s\n", visual->compressorname + 1 );
819 lsmash_ifprintf( fp, indent, "depth = 0x%04"PRIx16, visual->depth );
820 if( visual->depth == 32 )
821 fprintf( fp, " (colour with alpha)\n" );
822 else if( visual->depth >= 33 && visual->depth <= 40 )
823 fprintf( fp, " (grayscale with no alpha)\n" );
824 else
825 fprintf( fp, "\n" );
826 lsmash_ifprintf( fp, indent, "color_table_ID = %"PRId16"\n", visual->color_table_ID );
827 if( visual->color_table_ID == 0 )
828 isom_pring_qt_color_table( fp, indent, &visual->color_table );
830 else
832 lsmash_ifprintf( fp, indent, "pre_defined = 0x%04"PRIx16"\n", visual->version );
833 lsmash_ifprintf( fp, indent, "reserved = 0x%04"PRIx16"\n", visual->revision_level );
834 lsmash_ifprintf( fp, indent, "pre_defined = 0x%08"PRIx32"\n", visual->vendor );
835 lsmash_ifprintf( fp, indent, "pre_defined = 0x%08"PRIx32"\n", visual->temporalQuality );
836 lsmash_ifprintf( fp, indent, "pre_defined = 0x%08"PRIx32"\n", visual->spatialQuality );
837 lsmash_ifprintf( fp, indent, "width = %"PRIu16"\n", visual->width );
838 lsmash_ifprintf( fp, indent, "height = %"PRIu16"\n", visual->height );
839 lsmash_ifprintf( fp, indent, "horizresolution = %f\n", lsmash_fixed2double( visual->horizresolution, 16 ) );
840 lsmash_ifprintf( fp, indent, "vertresolution = %f\n", lsmash_fixed2double( visual->vertresolution, 16 ) );
841 lsmash_ifprintf( fp, indent, "reserved = 0x%08"PRIx32"\n", visual->dataSize );
842 lsmash_ifprintf( fp, indent, "frame_count = %"PRIu16"\n", visual->frame_count );
843 lsmash_ifprintf( fp, indent, "compressorname_length = %"PRIu8"\n", visual->compressorname[0] );
844 lsmash_ifprintf( fp, indent, "compressorname = %s\n", visual->compressorname + 1 );
845 lsmash_ifprintf( fp, indent, "depth = 0x%04"PRIx16, visual->depth );
846 if( visual->depth == 0x0018 )
847 fprintf( fp, " (colour with no alpha)\n" );
848 else if( visual->depth == 0x0028 )
849 fprintf( fp, " (grayscale with no alpha)\n" );
850 else if( visual->depth == 0x0020 )
851 fprintf( fp, " (gray or colour with alpha)\n" );
852 else
853 fprintf( fp, "\n" );
854 lsmash_ifprintf( fp, indent, "pre_defined = 0x%04"PRIx16"\n", visual->color_table_ID );
856 return 0;
859 static int isom_print_glbl( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
861 isom_glbl_t *glbl = (isom_glbl_t *)box;
862 int indent = level;
863 isom_print_box_common( fp, indent++, box, "Global Header Box" );
864 if( glbl->header_data )
866 lsmash_ifprintf( fp, indent, "global_header[]\n" );
867 for( uint32_t i = 0; i < glbl->header_size; i += 8 )
869 lsmash_ifprintf( fp, indent + 1, "" );
870 for( uint32_t j = 0; ; j++ )
871 if( j == 7 || (i + j == glbl->header_size - 1) )
873 fprintf( fp, "0x%02"PRIx8"\n", glbl->header_data[i + j] );
874 break;
876 else
877 fprintf( fp, "0x%02"PRIx8" ", glbl->header_data[i + j] );
880 return 0;
883 static int isom_print_clap( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
885 isom_clap_t *clap = (isom_clap_t *)box;
886 int indent = level;
887 isom_print_box_common( fp, indent++, box, "Clean Aperture Box" );
888 lsmash_ifprintf( fp, indent, "cleanApertureWidthN = %"PRIu32"\n", clap->cleanApertureWidthN );
889 lsmash_ifprintf( fp, indent, "cleanApertureWidthD = %"PRIu32"\n", clap->cleanApertureWidthD );
890 lsmash_ifprintf( fp, indent, "cleanApertureHeightN = %"PRIu32"\n", clap->cleanApertureHeightN );
891 lsmash_ifprintf( fp, indent, "cleanApertureHeightD = %"PRIu32"\n", clap->cleanApertureHeightD );
892 lsmash_ifprintf( fp, indent, "horizOffN = %"PRId32"\n", clap->horizOffN );
893 lsmash_ifprintf( fp, indent, "horizOffD = %"PRIu32"\n", clap->horizOffD );
894 lsmash_ifprintf( fp, indent, "vertOffN = %"PRId32"\n", clap->vertOffN );
895 lsmash_ifprintf( fp, indent, "vertOffD = %"PRIu32"\n", clap->vertOffD );
896 return 0;
899 static int isom_print_pasp( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
901 isom_pasp_t *pasp = (isom_pasp_t *)box;
902 int indent = level;
903 isom_print_box_common( fp, indent++, box, "Pixel Aspect Ratio Box" );
904 lsmash_ifprintf( fp, indent, "hSpacing = %"PRIu32"\n", pasp->hSpacing );
905 lsmash_ifprintf( fp, indent, "vSpacing = %"PRIu32"\n", pasp->vSpacing );
906 return 0;
909 static int isom_print_colr( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
911 isom_colr_t *colr = (isom_colr_t *)box;
912 int indent = level;
913 isom_print_box_common( fp, indent++, box, colr->manager & LSMASH_QTFF_BASE ? "Color Parameter Box" : "Colour Information Box" );
914 lsmash_ifprintf( fp, indent, "color_parameter_type = %s\n", isom_4cc2str( colr->color_parameter_type ) );
915 if( colr->color_parameter_type == QT_COLOR_PARAMETER_TYPE_NCLC
916 || colr->color_parameter_type == ISOM_COLOR_PARAMETER_TYPE_NCLX )
918 lsmash_ifprintf( fp, indent, "primaries_index = %"PRIu16"\n", colr->primaries_index );
919 lsmash_ifprintf( fp, indent, "transfer_function_index = %"PRIu16"\n", colr->transfer_function_index );
920 lsmash_ifprintf( fp, indent, "matrix_index = %"PRIu16"\n", colr->matrix_index );
921 if( colr->color_parameter_type == ISOM_COLOR_PARAMETER_TYPE_NCLX )
923 if( colr->manager & LSMASH_INCOMPLETE_BOX )
925 lsmash_ifprintf( fp, indent, "full_range_flag = N/A\n" );
926 lsmash_ifprintf( fp, indent, "reserved = N/A\n" );
928 else
930 lsmash_ifprintf( fp, indent, "full_range_flag = %"PRIu8"\n", colr->full_range_flag );
931 lsmash_ifprintf( fp, indent, "reserved = 0x%08"PRIx8"\n", colr->reserved );
935 return 0;
938 static int isom_print_gama( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
940 isom_gama_t *gama = (isom_gama_t *)box;
941 int indent = level;
942 isom_print_box_common( fp, indent++, box, "Gamma Level Box" );
943 if( gama->level == 0x00023333 )
944 lsmash_ifprintf( fp, indent, "level = 2.2 (standard television video gamma)\n" );
945 else
947 lsmash_ifprintf( fp, indent, "level = %f", lsmash_fixed2double( gama->level, 16 ) );
948 if( gama->level == 0 )
949 fprintf( fp, " (platform's standard gamma)" );
950 else if( gama->level == 0xffffffff )
951 fprintf( fp, " (no gamma-correction)" );
952 fprintf( fp, "\n" );
954 return 0;
957 static int isom_print_fiel( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
959 isom_fiel_t *fiel = (isom_fiel_t *)box;
960 int indent = level;
961 isom_print_box_common( fp, indent++, box, "Field/Frame Information Box" );
962 lsmash_ifprintf( fp, indent, "fields = %"PRIu8" (%s)\n", fiel->fields, fiel->fields > 1 ? "interlaced" : "progressive scan" );
963 lsmash_ifprintf( fp, indent, "detail = %"PRIu8, fiel->detail );
964 if( fiel->fields > 1 )
966 static const char *field_orderings[5] =
967 { "unknown", "temporal top first", "temporal bottom first", "spatial first line early", "spatial first line late" };
968 int ordering = 0;
969 if( fiel->fields == 2 )
971 if( fiel->detail == QT_FIELD_ORDERINGS_TEMPORAL_TOP_FIRST )
972 ordering = 1;
973 else if( fiel->detail == QT_FIELD_ORDERINGS_TEMPORAL_BOTTOM_FIRST )
974 ordering = 2;
975 else if( fiel->detail == QT_FIELD_ORDERINGS_SPATIAL_FIRST_LINE_EARLY )
976 ordering = 3;
977 else if( fiel->detail == QT_FIELD_ORDERINGS_SPATIAL_FIRST_LINE_LATE )
978 ordering = 4;
980 fprintf( fp, " (%s)\n", field_orderings[ordering] );
982 else
983 fprintf( fp, "\n" );
984 return 0;
987 static int isom_print_cspc( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
989 isom_cspc_t *cspc = (isom_cspc_t *)box;
990 int indent = level;
991 isom_print_box_common( fp, indent++, box, "Colorspace Box" );
992 static const struct
994 lsmash_qt_pixel_format pixel_format;
995 char *description;
996 } unprintable_pixel_format_table[] =
998 { QT_PIXEL_FORMAT_TYPE_1_MONOCHROME, "1 bit indexed" },
999 { QT_PIXEL_FORMAT_TYPE_2_INDEXED, "2 bit indexed" },
1000 { QT_PIXEL_FORMAT_TYPE_4_INDEXED, "4 bit indexed" },
1001 { QT_PIXEL_FORMAT_TYPE_8_INDEXED, "8 bit indexed" },
1002 { QT_PIXEL_FORMAT_TYPE_1_INDEXED_GRAY_WHITE_IS_ZERO, "1 bit indexed gray, white is zero" },
1003 { QT_PIXEL_FORMAT_TYPE_2_INDEXED_GRAY_WHITE_IS_ZERO, "2 bit indexed gray, white is zero" },
1004 { QT_PIXEL_FORMAT_TYPE_4_INDEXED_GRAY_WHITE_IS_ZERO, "4 bit indexed gray, white is zero" },
1005 { QT_PIXEL_FORMAT_TYPE_8_INDEXED_GRAY_WHITE_IS_ZERO, "8 bit indexed gray, white is zero" },
1006 { QT_PIXEL_FORMAT_TYPE_16BE555, "16 bit BE RGB 555" },
1007 { QT_PIXEL_FORMAT_TYPE_24RGB, "24 bit RGB" },
1008 { QT_PIXEL_FORMAT_TYPE_32ARGB, "32 bit ARGB" },
1009 { 0, NULL }
1011 for( int i = 0; unprintable_pixel_format_table[i].pixel_format; i++ )
1012 if( cspc->pixel_format == unprintable_pixel_format_table[i].pixel_format )
1014 lsmash_ifprintf( fp, indent, "pixel_format = 0x%08"PRIx32" (%s)\n", cspc->pixel_format, unprintable_pixel_format_table[i].description );
1015 return 0;
1017 lsmash_ifprintf( fp, indent, "pixel_format = %s\n", isom_4cc2str( cspc->pixel_format ) );
1018 return 0;
1021 static int isom_print_sgbt( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1023 isom_sgbt_t *sgbt = (isom_sgbt_t *)box;
1024 int indent = level;
1025 isom_print_box_common( fp, indent++, box, "Significant Bits Box" );
1026 lsmash_ifprintf( fp, indent, "significantBits = %"PRIu8"\n", sgbt->significantBits );
1027 return 0;
1030 static int isom_print_stsl( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1032 isom_stsl_t *stsl = (isom_stsl_t *)box;
1033 int indent = level;
1034 isom_print_box_common( fp, indent++, box, "Sample Scale Box" );
1035 lsmash_ifprintf( fp, indent, "constraint_flag = %s\n", (stsl->constraint_flag & 0x01) ? "on" : "off" );
1036 lsmash_ifprintf( fp, indent, "scale_method = " );
1037 if( stsl->scale_method == ISOM_SCALE_METHOD_FILL )
1038 fprintf( fp, "'fill'\n" );
1039 else if( stsl->scale_method == ISOM_SCALE_METHOD_HIDDEN )
1040 fprintf( fp, "'hidden'\n" );
1041 else if( stsl->scale_method == ISOM_SCALE_METHOD_MEET )
1042 fprintf( fp, "'meet'\n" );
1043 else if( stsl->scale_method == ISOM_SCALE_METHOD_SLICE_X )
1044 fprintf( fp, "'slice' in the x-coodinate\n" );
1045 else if( stsl->scale_method == ISOM_SCALE_METHOD_SLICE_Y )
1046 fprintf( fp, "'slice' in the y-coodinate\n" );
1047 lsmash_ifprintf( fp, indent, "display_center_x = %"PRIu16"\n", stsl->display_center_x );
1048 lsmash_ifprintf( fp, indent, "display_center_y = %"PRIu16"\n", stsl->display_center_y );
1049 return 0;
1052 static int isom_print_audio_description( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1054 isom_audio_entry_t *audio = (isom_audio_entry_t *)box;
1055 int indent = level;
1056 lsmash_ifprintf( fp, indent++, "[%s: Audio Description]\n", isom_4cc2str( audio->type.fourcc ) );
1057 lsmash_ifprintf( fp, indent, "position = %"PRIu64"\n", audio->pos );
1058 lsmash_ifprintf( fp, indent, "size = %"PRIu64"\n", audio->size );
1059 isom_ifprintf_sample_description_common_reserved( fp, indent, audio->reserved );
1060 lsmash_ifprintf( fp, indent, "data_reference_index = %"PRIu16"\n", audio->data_reference_index );
1061 if( file->qt_compatible )
1063 lsmash_ifprintf( fp, indent, "version = %"PRId16"\n", audio->version );
1064 lsmash_ifprintf( fp, indent, "revision_level = %"PRId16"\n", audio->revision_level );
1065 lsmash_ifprintf( fp, indent, "vendor = %s\n", isom_4cc2str( audio->vendor ) );
1066 lsmash_ifprintf( fp, indent, "channelcount = %"PRIu16"\n", audio->channelcount );
1067 lsmash_ifprintf( fp, indent, "samplesize = %"PRIu16"\n", audio->samplesize );
1068 lsmash_ifprintf( fp, indent, "compression_ID = %"PRId16"\n", audio->compression_ID );
1069 lsmash_ifprintf( fp, indent, "packet_size = %"PRIu16"\n", audio->packet_size );
1071 else
1073 lsmash_ifprintf( fp, indent, "reserved = 0x%04"PRIx16"\n", audio->version );
1074 lsmash_ifprintf( fp, indent, "reserved = 0x%04"PRIx16"\n", audio->revision_level );
1075 lsmash_ifprintf( fp, indent, "reserved = 0x%08"PRIx32"\n", audio->vendor );
1076 lsmash_ifprintf( fp, indent, "channelcount = %"PRIu16"\n", audio->channelcount );
1077 lsmash_ifprintf( fp, indent, "samplesize = %"PRIu16"\n", audio->samplesize );
1078 lsmash_ifprintf( fp, indent, "pre_defined = %"PRId16"\n", audio->compression_ID );
1079 lsmash_ifprintf( fp, indent, "reserved = %"PRIu16"\n", audio->packet_size );
1081 lsmash_ifprintf( fp, indent, "samplerate = %f\n", lsmash_fixed2double( audio->samplerate, 16 ) );
1082 if( audio->version == 1 && (audio->manager & LSMASH_QTFF_BASE) )
1084 lsmash_ifprintf( fp, indent, "samplesPerPacket = %"PRIu32"\n", audio->samplesPerPacket );
1085 lsmash_ifprintf( fp, indent, "bytesPerPacket = %"PRIu32"\n", audio->bytesPerPacket );
1086 lsmash_ifprintf( fp, indent, "bytesPerFrame = %"PRIu32"\n", audio->bytesPerFrame );
1087 lsmash_ifprintf( fp, indent, "bytesPerSample = %"PRIu32"\n", audio->bytesPerSample );
1089 else if( audio->version == 2 )
1091 lsmash_ifprintf( fp, indent, "sizeOfStructOnly = %"PRIu32"\n", audio->sizeOfStructOnly );
1092 lsmash_ifprintf( fp, indent, "audioSampleRate = %lf\n", lsmash_int2float64( audio->audioSampleRate ) );
1093 lsmash_ifprintf( fp, indent, "numAudioChannels = %"PRIu32"\n", audio->numAudioChannels );
1094 lsmash_ifprintf( fp, indent, "always7F000000 = 0x%08"PRIx32"\n", audio->always7F000000 );
1095 lsmash_ifprintf( fp, indent, "constBitsPerChannel = %"PRIu32"\n", audio->constBitsPerChannel );
1096 lsmash_ifprintf( fp, indent++, "formatSpecificFlags = 0x%08"PRIx32"\n", audio->formatSpecificFlags );
1097 if( isom_is_lpcm_audio( audio ) )
1099 lsmash_ifprintf( fp, indent, "sample format: " );
1100 if( audio->formatSpecificFlags & QT_LPCM_FORMAT_FLAG_FLOAT )
1101 fprintf( fp, "floating point\n" );
1102 else
1104 fprintf( fp, "integer\n" );
1105 lsmash_ifprintf( fp, indent, "signedness: " );
1106 fprintf( fp, audio->formatSpecificFlags & QT_LPCM_FORMAT_FLAG_SIGNED_INTEGER ? "signed\n" : "unsigned\n" );
1108 if( audio->constBytesPerAudioPacket != 1 )
1110 lsmash_ifprintf( fp, indent, "endianness: " );
1111 fprintf( fp, audio->formatSpecificFlags & QT_LPCM_FORMAT_FLAG_BIG_ENDIAN ? "big\n" : "little\n" );
1113 lsmash_ifprintf( fp, indent, "packed: " );
1114 if( audio->formatSpecificFlags & QT_LPCM_FORMAT_FLAG_PACKED )
1115 fprintf( fp, "yes\n" );
1116 else
1118 fprintf( fp, "no\n" );
1119 lsmash_ifprintf( fp, indent, "alignment: " );
1120 fprintf( fp, audio->formatSpecificFlags & QT_LPCM_FORMAT_FLAG_ALIGNED_HIGH ? "high\n" : "low\n" );
1122 if( audio->numAudioChannels > 1 )
1124 lsmash_ifprintf( fp, indent, "interleved: " );
1125 fprintf( fp, audio->formatSpecificFlags & QT_LPCM_FORMAT_FLAG_NON_INTERLEAVED ? "no\n" : "yes\n" );
1128 lsmash_ifprintf( fp, --indent, "constBytesPerAudioPacket = %"PRIu32"\n", audio->constBytesPerAudioPacket );
1129 lsmash_ifprintf( fp, indent, "constLPCMFramesPerAudioPacket = %"PRIu32"\n", audio->constLPCMFramesPerAudioPacket );
1131 return 0;
1134 static int isom_print_wave( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1136 return isom_print_simple( fp, box, level, "Sound Information Decompression Parameters Box" );
1139 static int isom_print_frma( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1141 isom_frma_t *frma = (isom_frma_t *)box;
1142 int indent = level;
1143 isom_print_box_common( fp, indent++, box, "Format Box" );
1144 lsmash_ifprintf( fp, indent, "data_format = %s\n", isom_4cc2str( frma->data_format ) );
1145 return 0;
1148 static int isom_print_enda( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1150 isom_enda_t *enda = (isom_enda_t *)box;
1151 int indent = level;
1152 isom_print_box_common( fp, indent++, box, "Audio Endian Box" );
1153 lsmash_ifprintf( fp, indent, "littleEndian = %s\n", enda->littleEndian ? "yes" : "no" );
1154 return 0;
1157 static int isom_print_terminator( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1159 isom_terminator_t *terminator = (isom_terminator_t *)box;
1160 int indent = level;
1161 lsmash_ifprintf( fp, indent++, "[0x00000000: Terminator Box]\n" );
1162 lsmash_ifprintf( fp, indent, "position = %"PRIu64"\n", terminator->pos );
1163 lsmash_ifprintf( fp, indent, "size = %"PRIu64"\n", terminator->size );
1164 return 0;
1167 static int isom_print_chan( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1169 isom_chan_t *chan = (isom_chan_t *)box;
1170 int indent = level;
1171 isom_print_box_common( fp, indent++, box, "Audio Channel Layout Box" );
1172 lsmash_ifprintf( fp, indent, "channelLayoutTag = 0x%08"PRIx32"\n", chan->channelLayoutTag );
1173 lsmash_ifprintf( fp, indent, "channelBitmap = 0x%08"PRIx32"\n", chan->channelBitmap );
1174 lsmash_ifprintf( fp, indent, "numberChannelDescriptions = %"PRIu32"\n", chan->numberChannelDescriptions );
1175 if( chan->numberChannelDescriptions )
1177 isom_channel_description_t *desc = chan->channelDescriptions;
1178 for( uint32_t i = 0; i < chan->numberChannelDescriptions; i++ )
1180 lsmash_ifprintf( fp, indent++, "ChannelDescriptions[%"PRIu32"]\n", i );
1181 lsmash_ifprintf( fp, indent, "channelLabel = 0x%08"PRIx32"\n", desc->channelLabel );
1182 lsmash_ifprintf( fp, indent, "channelFlags = 0x%08"PRIx32"\n", desc->channelFlags );
1183 for( int j = 0; j < 3; j++ )
1184 lsmash_ifprintf( fp, indent, "coordinates[%d] = %f\n", j, lsmash_int2float32( desc->coordinates[j] ) );
1185 --indent;
1188 return 0;
1191 static int isom_print_srat( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1193 isom_srat_t *srat = (isom_srat_t *)box;
1194 int indent = level;
1195 isom_print_box_common( fp, indent++, box, "Sampling Rate Box" );
1196 lsmash_ifprintf( fp, indent, "sampling_rate = %"PRIu32"\n", srat->sampling_rate );
1197 return 0;
1200 static int isom_print_text_description( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1202 isom_qt_text_entry_t *text = (isom_qt_text_entry_t *)box;
1203 int indent = level;
1204 lsmash_ifprintf( fp, indent++, "[text: QuickTime Text Description]\n" );
1205 lsmash_ifprintf( fp, indent, "position = %"PRIu64"\n", text->pos );
1206 lsmash_ifprintf( fp, indent, "size = %"PRIu64"\n", text->size );
1207 isom_ifprintf_sample_description_common_reserved( fp, indent, text->reserved );
1208 lsmash_ifprintf( fp, indent, "data_reference_index = %"PRIu16"\n", text->data_reference_index );
1209 lsmash_ifprintf( fp, indent, "displayFlags = 0x%08"PRId32"\n", text->displayFlags );
1210 lsmash_ifprintf( fp, indent, "textJustification = %"PRId32"\n", text->textJustification );
1211 lsmash_ifprintf( fp, indent, "bgColor\n" );
1212 isom_ifprintf_rgb_color( fp, indent + 1, text->bgColor );
1213 lsmash_ifprintf( fp, indent, "top = %"PRId16"\n", text->top );
1214 lsmash_ifprintf( fp, indent, "left = %"PRId16"\n", text->left );
1215 lsmash_ifprintf( fp, indent, "bottom = %"PRId16"\n", text->bottom );
1216 lsmash_ifprintf( fp, indent, "right = %"PRId16"\n", text->right );
1217 lsmash_ifprintf( fp, indent, "scrpStartChar = %"PRId32"\n", text->scrpStartChar );
1218 lsmash_ifprintf( fp, indent, "scrpHeight = %"PRId16"\n", text->scrpHeight );
1219 lsmash_ifprintf( fp, indent, "scrpAscent = %"PRId16"\n", text->scrpAscent );
1220 lsmash_ifprintf( fp, indent, "scrpFont = %"PRId16"\n", text->scrpFont );
1221 lsmash_ifprintf( fp, indent, "scrpFace = %"PRIu16"\n", text->scrpFace );
1222 lsmash_ifprintf( fp, indent, "scrpSize = %"PRId16"\n", text->scrpSize );
1223 lsmash_ifprintf( fp, indent, "scrpColor\n" );
1224 isom_ifprintf_rgb_color( fp, indent + 1, text->scrpColor );
1225 if( text->font_name_length )
1226 lsmash_ifprintf( fp, indent, "font_name = %s\n", text->font_name );
1227 return 0;
1230 static int isom_print_tx3g_description( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1232 isom_tx3g_entry_t *tx3g = (isom_tx3g_entry_t *)box;
1233 int indent = level;
1234 lsmash_ifprintf( fp, indent++, "[tx3g: Timed Text Description]\n" );
1235 lsmash_ifprintf( fp, indent, "position = %"PRIu64"\n", tx3g->pos );
1236 lsmash_ifprintf( fp, indent, "size = %"PRIu64"\n", tx3g->size );
1237 isom_ifprintf_sample_description_common_reserved( fp, indent, tx3g->reserved );
1238 lsmash_ifprintf( fp, indent, "data_reference_index = %"PRIu16"\n", tx3g->data_reference_index );
1239 lsmash_ifprintf( fp, indent, "displayFlags = 0x%08"PRId32"\n", tx3g->displayFlags );
1240 lsmash_ifprintf( fp, indent, "horizontal_justification = %"PRId8"\n", tx3g->horizontal_justification );
1241 lsmash_ifprintf( fp, indent, "vertical_justification = %"PRId8"\n", tx3g->vertical_justification );
1242 lsmash_ifprintf( fp, indent, "background_color_rgba\n" );
1243 isom_ifprintf_rgba_color( fp, indent + 1, tx3g->background_color_rgba );
1244 lsmash_ifprintf( fp, indent, "top = %"PRId16"\n", tx3g->top );
1245 lsmash_ifprintf( fp, indent, "left = %"PRId16"\n", tx3g->left );
1246 lsmash_ifprintf( fp, indent, "bottom = %"PRId16"\n", tx3g->bottom );
1247 lsmash_ifprintf( fp, indent, "right = %"PRId16"\n", tx3g->right );
1248 lsmash_ifprintf( fp, indent, "startChar = %"PRIu16"\n", tx3g->startChar );
1249 lsmash_ifprintf( fp, indent, "endChar = %"PRIu16"\n", tx3g->endChar );
1250 lsmash_ifprintf( fp, indent, "font_ID = %"PRIu16"\n", tx3g->font_ID );
1251 lsmash_ifprintf( fp, indent, "face_style_flags = %"PRIu8"\n", tx3g->face_style_flags );
1252 lsmash_ifprintf( fp, indent, "font_size = %"PRIu8"\n", tx3g->font_size );
1253 lsmash_ifprintf( fp, indent, "text_color_rgba\n" );
1254 isom_ifprintf_rgba_color( fp, indent + 1, tx3g->text_color_rgba );
1255 return 0;
1258 static int isom_print_ftab( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1260 if( !((isom_ftab_t *)box)->list )
1261 return LSMASH_ERR_INVALID_DATA;
1262 isom_ftab_t *ftab = (isom_ftab_t *)box;
1263 int indent = level;
1264 uint16_t i = 0;
1265 isom_print_box_common( fp, indent++, box, "Font Table Box" );
1266 lsmash_ifprintf( fp, indent, "entry_count = %"PRIu16"\n", ftab->list->entry_count );
1267 for( lsmash_entry_t *entry = ftab->list->head; entry; entry = entry->next )
1269 isom_font_record_t *data = (isom_font_record_t *)entry->data;
1270 lsmash_ifprintf( fp, indent++, "entry[%"PRIu16"]\n", i++ );
1271 lsmash_ifprintf( fp, indent, "font_ID = %"PRIu16"\n", data->font_ID );
1272 if( data->font_name_length )
1273 lsmash_ifprintf( fp, indent, "font_name = %s\n", data->font_name );
1274 --indent;
1276 return 0;
1279 static int isom_print_mp4s_description( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1281 isom_mp4s_entry_t *mp4s = (isom_mp4s_entry_t *)box;
1282 int indent = level;
1283 lsmash_ifprintf( fp, indent++, "[%s: MPEG-4 Systems Description]\n", isom_4cc2str( mp4s->type.fourcc ) );
1284 lsmash_ifprintf( fp, indent, "position = %"PRIu64"\n", mp4s->pos );
1285 lsmash_ifprintf( fp, indent, "size = %"PRIu64"\n", mp4s->size );
1286 isom_ifprintf_sample_description_common_reserved( fp, indent, mp4s->reserved );
1287 lsmash_ifprintf( fp, indent, "data_reference_index = %"PRIu16"\n", mp4s->data_reference_index );
1288 return 0;
1291 static int isom_print_sample_description_extesion( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1293 extern int mp4sys_print_codec_specific( FILE *, lsmash_file_t *, isom_box_t *, int );
1294 extern int h264_print_codec_specific( FILE *, lsmash_file_t *, isom_box_t *, int );
1295 extern int hevc_print_codec_specific( FILE *, lsmash_file_t *, isom_box_t *, int );
1296 extern int h264_print_bitrate( FILE *, lsmash_file_t *, isom_box_t *, int );
1297 extern int vc1_print_codec_specific( FILE *, lsmash_file_t *, isom_box_t *, int );
1298 extern int ac3_print_codec_specific( FILE *, lsmash_file_t *, isom_box_t *, int );
1299 extern int eac3_print_codec_specific( FILE *, lsmash_file_t *, isom_box_t *, int );
1300 extern int dts_print_codec_specific( FILE *, lsmash_file_t *, isom_box_t *, int );
1301 extern int alac_print_codec_specific( FILE *, lsmash_file_t *, isom_box_t *, int );
1302 extern int wma_print_codec_specific( FILE *, lsmash_file_t *, isom_box_t *, int );
1303 static struct print_description_extension_table_tag
1305 lsmash_box_type_t type;
1306 int (*print_func)( FILE *, lsmash_file_t *, isom_box_t *, int );
1307 } print_description_extension_table[32] = { { LSMASH_BOX_TYPE_INITIALIZER, NULL } };
1308 if( !print_description_extension_table[0].print_func )
1310 /* Initialize the table. */
1311 int i = 0;
1312 #define ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( type, func ) \
1313 print_description_extension_table[i++] = (struct print_description_extension_table_tag){ type, func }
1314 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( ISOM_BOX_TYPE_CLAP, isom_print_clap );
1315 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( ISOM_BOX_TYPE_PASP, isom_print_pasp );
1316 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( ISOM_BOX_TYPE_STSL, isom_print_stsl );
1317 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( ISOM_BOX_TYPE_COLR, isom_print_colr );
1318 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( QT_BOX_TYPE_COLR, isom_print_colr );
1319 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( QT_BOX_TYPE_GAMA, isom_print_gama );
1320 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( QT_BOX_TYPE_FIEL, isom_print_fiel );
1321 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( QT_BOX_TYPE_CSPC, isom_print_cspc );
1322 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( QT_BOX_TYPE_SGBT, isom_print_sgbt );
1323 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( QT_BOX_TYPE_CTAB, isom_print_ctab );
1324 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( QT_BOX_TYPE_GLBL, isom_print_glbl );
1325 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( QT_BOX_TYPE_WAVE, isom_print_wave );
1326 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( QT_BOX_TYPE_CHAN, isom_print_chan );
1327 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( ISOM_BOX_TYPE_ESDS, mp4sys_print_codec_specific );
1328 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( ISOM_BOX_TYPE_AVCC, h264_print_codec_specific );
1329 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( ISOM_BOX_TYPE_BTRT, h264_print_bitrate );
1330 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( ISOM_BOX_TYPE_HVCC, hevc_print_codec_specific );
1331 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( ISOM_BOX_TYPE_DVC1, vc1_print_codec_specific );
1332 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( ISOM_BOX_TYPE_DAC3, ac3_print_codec_specific );
1333 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( ISOM_BOX_TYPE_DEC3, eac3_print_codec_specific );
1334 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( ISOM_BOX_TYPE_DDTS, dts_print_codec_specific );
1335 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( ISOM_BOX_TYPE_ALAC, alac_print_codec_specific );
1336 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( ISOM_BOX_TYPE_WFEX, wma_print_codec_specific );
1337 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( ISOM_BOX_TYPE_FTAB, isom_print_ftab );
1338 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( QT_BOX_TYPE_ESDS, mp4sys_print_codec_specific );
1339 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( QT_BOX_TYPE_ALAC, alac_print_codec_specific );
1340 ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT( LSMASH_BOX_TYPE_UNSPECIFIED, NULL );
1341 #undef ADD_PRINT_DESCRIPTION_EXTENSION_TABLE_ELEMENT
1343 for( int i = 0; print_description_extension_table[i].print_func; i++ )
1344 if( lsmash_check_box_type_identical( box->type, print_description_extension_table[i].type ) )
1345 return print_description_extension_table[i].print_func( fp, file, box, level );
1346 return isom_print_unknown( fp, file, box, level );
1349 static int isom_print_stts( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1351 if( !((isom_stts_t *)box)->list )
1352 return LSMASH_ERR_INVALID_DATA;
1353 isom_stts_t *stts = (isom_stts_t *)box;
1354 int indent = level;
1355 uint32_t i = 0;
1356 isom_print_box_common( fp, indent++, box, "Decoding Time to Sample Box" );
1357 lsmash_ifprintf( fp, indent, "entry_count = %"PRIu32"\n", stts->list->entry_count );
1358 for( lsmash_entry_t *entry = stts->list->head; entry; entry = entry->next )
1360 isom_stts_entry_t *data = (isom_stts_entry_t *)entry->data;
1361 lsmash_ifprintf( fp, indent++, "entry[%"PRIu32"]\n", i++ );
1362 lsmash_ifprintf( fp, indent, "sample_count = %"PRIu32"\n", data->sample_count );
1363 lsmash_ifprintf( fp, indent--, "sample_delta = %"PRIu32"\n", data->sample_delta );
1365 return 0;
1368 static int isom_print_ctts( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1370 if( !((isom_ctts_t *)box)->list )
1371 return LSMASH_ERR_INVALID_DATA;
1372 isom_ctts_t *ctts = (isom_ctts_t *)box;
1373 int indent = level;
1374 uint32_t i = 0;
1375 isom_print_box_common( fp, indent++, box, "Composition Time to Sample Box" );
1376 lsmash_ifprintf( fp, indent, "entry_count = %"PRIu32"\n", ctts->list->entry_count );
1377 if( file->qt_compatible || ctts->version == 1 )
1378 for( lsmash_entry_t *entry = ctts->list->head; entry; entry = entry->next )
1380 isom_ctts_entry_t *data = (isom_ctts_entry_t *)entry->data;
1381 lsmash_ifprintf( fp, indent++, "entry[%"PRIu32"]\n", i++ );
1382 lsmash_ifprintf( fp, indent, "sample_count = %"PRIu32"\n", data->sample_count );
1383 lsmash_ifprintf( fp, indent--, "sample_offset = %"PRId32"\n", (union {uint32_t ui; int32_t si;}){ data->sample_offset }.si );
1385 else
1386 for( lsmash_entry_t *entry = ctts->list->head; entry; entry = entry->next )
1388 isom_ctts_entry_t *data = (isom_ctts_entry_t *)entry->data;
1389 lsmash_ifprintf( fp, indent++, "entry[%"PRIu32"]\n", i++ );
1390 lsmash_ifprintf( fp, indent, "sample_count = %"PRIu32"\n", data->sample_count );
1391 lsmash_ifprintf( fp, indent--, "sample_offset = %"PRIu32"\n", data->sample_offset );
1393 return 0;
1396 static int isom_print_cslg( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1398 isom_cslg_t *cslg = (isom_cslg_t *)box;
1399 int indent = level;
1400 if( file->qt_compatible )
1402 isom_print_box_common( fp, indent++, box, "Composition Shift Least Greatest Box" );
1403 lsmash_ifprintf( fp, indent, "compositionOffsetToDTDDeltaShift = %"PRId32"\n", cslg->compositionToDTSShift );
1404 lsmash_ifprintf( fp, indent, "leastDecodeToDisplayDelta = %"PRId32"\n", cslg->leastDecodeToDisplayDelta );
1405 lsmash_ifprintf( fp, indent, "greatestDecodeToDisplayDelta = %"PRId32"\n", cslg->greatestDecodeToDisplayDelta );
1406 lsmash_ifprintf( fp, indent, "displayStartTime = %"PRId32"\n", cslg->compositionStartTime );
1407 lsmash_ifprintf( fp, indent, "displayEndTime = %"PRId32"\n", cslg->compositionEndTime );
1409 else
1411 isom_print_box_common( fp, indent++, box, "Composition to Decode Box" );
1412 lsmash_ifprintf( fp, indent, "compositionToDTSShift = %"PRId32"\n", cslg->compositionToDTSShift );
1413 lsmash_ifprintf( fp, indent, "leastDecodeToDisplayDelta = %"PRId32"\n", cslg->leastDecodeToDisplayDelta );
1414 lsmash_ifprintf( fp, indent, "greatestDecodeToDisplayDelta = %"PRId32"\n", cslg->greatestDecodeToDisplayDelta );
1415 lsmash_ifprintf( fp, indent, "compositionStartTime = %"PRId32"\n", cslg->compositionStartTime );
1416 lsmash_ifprintf( fp, indent, "compositionEndTime = %"PRId32"\n", cslg->compositionEndTime );
1418 return 0;
1421 static int isom_print_stss( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1423 if( !((isom_stss_t *)box)->list )
1424 return LSMASH_ERR_INVALID_DATA;
1425 isom_stss_t *stss = (isom_stss_t *)box;
1426 int indent = level;
1427 uint32_t i = 0;
1428 isom_print_box_common( fp, indent++, box, "Sync Sample Box" );
1429 lsmash_ifprintf( fp, indent, "entry_count = %"PRIu32"\n", stss->list->entry_count );
1430 for( lsmash_entry_t *entry = stss->list->head; entry; entry = entry->next )
1431 lsmash_ifprintf( fp, indent, "sample_number[%"PRIu32"] = %"PRIu32"\n", i++, ((isom_stss_entry_t *)entry->data)->sample_number );
1432 return 0;
1435 static int isom_print_stps( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1437 if( !((isom_stps_t *)box)->list )
1438 return LSMASH_ERR_INVALID_DATA;
1439 isom_stps_t *stps = (isom_stps_t *)box;
1440 int indent = level;
1441 uint32_t i = 0;
1442 isom_print_box_common( fp, indent++, box, "Partial Sync Sample Box" );
1443 lsmash_ifprintf( fp, indent, "entry_count = %"PRIu32"\n", stps->list->entry_count );
1444 for( lsmash_entry_t *entry = stps->list->head; entry; entry = entry->next )
1445 lsmash_ifprintf( fp, indent, "sample_number[%"PRIu32"] = %"PRIu32"\n", i++, ((isom_stps_entry_t *)entry->data)->sample_number );
1446 return 0;
1449 static int isom_print_sdtp( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1451 if( !((isom_sdtp_t *)box)->list )
1452 return LSMASH_ERR_INVALID_DATA;
1453 isom_sdtp_t *sdtp = (isom_sdtp_t *)box;
1454 int indent = level;
1455 uint32_t i = 0;
1456 isom_print_box_common( fp, indent++, box, "Independent and Disposable Samples Box" );
1457 for( lsmash_entry_t *entry = sdtp->list->head; entry; entry = entry->next )
1459 isom_sdtp_entry_t *data = (isom_sdtp_entry_t *)entry->data;
1460 lsmash_ifprintf( fp, indent++, "entry[%"PRIu32"]\n", i++ );
1461 if( data->is_leading || data->sample_depends_on || data->sample_is_depended_on || data->sample_has_redundancy )
1463 if( file->avc_extensions )
1465 if( data->is_leading & ISOM_SAMPLE_IS_UNDECODABLE_LEADING )
1466 lsmash_ifprintf( fp, indent, "undecodable leading\n" );
1467 else if( data->is_leading & ISOM_SAMPLE_IS_NOT_LEADING )
1468 lsmash_ifprintf( fp, indent, "non-leading\n" );
1469 else if( data->is_leading & ISOM_SAMPLE_IS_DECODABLE_LEADING )
1470 lsmash_ifprintf( fp, indent, "decodable leading\n" );
1472 else if( data->is_leading & QT_SAMPLE_EARLIER_PTS_ALLOWED )
1473 lsmash_ifprintf( fp, indent, "early display times allowed\n" );
1474 if( data->sample_depends_on & ISOM_SAMPLE_IS_INDEPENDENT )
1475 lsmash_ifprintf( fp, indent, "independent\n" );
1476 else if( data->sample_depends_on & ISOM_SAMPLE_IS_NOT_INDEPENDENT )
1477 lsmash_ifprintf( fp, indent, "dependent\n" );
1478 if( data->sample_is_depended_on & ISOM_SAMPLE_IS_NOT_DISPOSABLE )
1479 lsmash_ifprintf( fp, indent, "non-disposable\n" );
1480 else if( data->sample_is_depended_on & ISOM_SAMPLE_IS_DISPOSABLE )
1481 lsmash_ifprintf( fp, indent, "disposable\n" );
1482 if( data->sample_has_redundancy & ISOM_SAMPLE_HAS_REDUNDANCY )
1483 lsmash_ifprintf( fp, indent, "redundant\n" );
1484 else if( data->sample_has_redundancy & ISOM_SAMPLE_HAS_NO_REDUNDANCY )
1485 lsmash_ifprintf( fp, indent, "non-redundant\n" );
1487 else
1488 lsmash_ifprintf( fp, indent, "no description\n" );
1489 --indent;
1491 return 0;
1494 static int isom_print_stsc( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1496 if( !((isom_stsc_t *)box)->list )
1497 return LSMASH_ERR_INVALID_DATA;
1498 isom_stsc_t *stsc = (isom_stsc_t *)box;
1499 int indent = level;
1500 uint32_t i = 0;
1501 isom_print_box_common( fp, indent++, box, "Sample To Chunk Box" );
1502 lsmash_ifprintf( fp, indent, "entry_count = %"PRIu32"\n", stsc->list->entry_count );
1503 for( lsmash_entry_t *entry = stsc->list->head; entry; entry = entry->next )
1505 isom_stsc_entry_t *data = (isom_stsc_entry_t *)entry->data;
1506 lsmash_ifprintf( fp, indent++, "entry[%"PRIu32"]\n", i++ );
1507 lsmash_ifprintf( fp, indent, "first_chunk = %"PRIu32"\n", data->first_chunk );
1508 lsmash_ifprintf( fp, indent, "samples_per_chunk = %"PRIu32"\n", data->samples_per_chunk );
1509 lsmash_ifprintf( fp, indent--, "sample_description_index = %"PRIu32"\n", data->sample_description_index );
1511 return 0;
1514 static int isom_print_stsz( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1516 isom_stsz_t *stsz = (isom_stsz_t *)box;
1517 int indent = level;
1518 uint32_t i = 0;
1519 isom_print_box_common( fp, indent++, box, "Sample Size Box" );
1520 if( !stsz->sample_size )
1521 lsmash_ifprintf( fp, indent, "sample_size = 0 (variable)\n" );
1522 else
1523 lsmash_ifprintf( fp, indent, "sample_size = %"PRIu32" (constant)\n", stsz->sample_size );
1524 lsmash_ifprintf( fp, indent, "sample_count = %"PRIu32"\n", stsz->sample_count );
1525 if( !stsz->sample_size && stsz->list )
1526 for( lsmash_entry_t *entry = stsz->list->head; entry; entry = entry->next )
1528 isom_stsz_entry_t *data = (isom_stsz_entry_t *)entry->data;
1529 lsmash_ifprintf( fp, indent, "entry_size[%"PRIu32"] = %"PRIu32"\n", i++, data->entry_size );
1531 return 0;
1534 static int isom_print_stco( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1536 if( !((isom_stco_t *)box)->list )
1537 return LSMASH_ERR_INVALID_DATA;
1538 isom_stco_t *stco = (isom_stco_t *)box;
1539 int indent = level;
1540 uint32_t i = 0;
1541 isom_print_box_common( fp, indent++, box, "Chunk Offset Box" );
1542 lsmash_ifprintf( fp, indent, "entry_count = %"PRIu32"\n", stco->list->entry_count );
1543 if( lsmash_check_box_type_identical( stco->type, ISOM_BOX_TYPE_STCO ) )
1545 for( lsmash_entry_t *entry = stco->list->head; entry; entry = entry->next )
1546 lsmash_ifprintf( fp, indent, "chunk_offset[%"PRIu32"] = %"PRIu32"\n", i++, ((isom_stco_entry_t *)entry->data)->chunk_offset );
1548 else
1550 for( lsmash_entry_t *entry = stco->list->head; entry; entry = entry->next )
1551 lsmash_ifprintf( fp, indent, "chunk_offset[%"PRIu32"] = %"PRIu64"\n", i++, ((isom_co64_entry_t *)entry->data)->chunk_offset );
1553 return 0;
1556 static int isom_print_sgpd( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1558 if( !((isom_sgpd_t *)box)->list )
1559 return LSMASH_ERR_INVALID_DATA;
1560 isom_sgpd_t *sgpd = (isom_sgpd_t *)box;
1561 int indent = level;
1562 uint32_t i = 0;
1563 isom_print_box_common( fp, indent++, box, "Sample Group Description Box" );
1564 lsmash_ifprintf( fp, indent, "grouping_type = %s\n", isom_4cc2str( sgpd->grouping_type ) );
1565 if( sgpd->version == 1 )
1567 lsmash_ifprintf( fp, indent, "default_length = %"PRIu32, sgpd->default_length );
1568 fprintf( fp, " %s\n", sgpd->default_length ? "(constant)" : "(variable)" );
1570 lsmash_ifprintf( fp, indent, "entry_count = %"PRIu32"\n", sgpd->list->entry_count );
1571 switch( sgpd->grouping_type )
1573 case ISOM_GROUP_TYPE_RAP :
1574 for( lsmash_entry_t *entry = sgpd->list->head; entry; entry = entry->next )
1576 if( sgpd->version == 1 && !sgpd->default_length )
1577 lsmash_ifprintf( fp, indent, "description_length[%"PRIu32"] = %"PRIu32"\n", i++, ((isom_rap_entry_t *)entry->data)->description_length );
1578 else
1580 isom_rap_entry_t *rap = (isom_rap_entry_t *)entry->data;
1581 lsmash_ifprintf( fp, indent++, "entry[%"PRIu32"]\n", i++ );
1582 lsmash_ifprintf( fp, indent, "num_leading_samples_known = %"PRIu8"\n", rap->num_leading_samples_known );
1583 lsmash_ifprintf( fp, indent--, "num_leading_samples = %"PRIu8"\n", rap->num_leading_samples );
1586 break;
1587 case ISOM_GROUP_TYPE_ROLL :
1588 case ISOM_GROUP_TYPE_PROL :
1589 for( lsmash_entry_t *entry = sgpd->list->head; entry; entry = entry->next )
1591 if( sgpd->version == 1 && !sgpd->default_length )
1592 lsmash_ifprintf( fp, indent, "description_length[%"PRIu32"] = %"PRIu32"\n", i++, ((isom_roll_entry_t *)entry->data)->description_length );
1593 else
1594 lsmash_ifprintf( fp, indent, "roll_distance[%"PRIu32"] = %"PRId16"\n", i++, ((isom_roll_entry_t *)entry->data)->roll_distance );
1596 break;
1597 default :
1598 break;
1600 return 0;
1603 static int isom_print_sbgp( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1605 if( !((isom_sbgp_t *)box)->list )
1606 return LSMASH_ERR_INVALID_DATA;
1607 isom_sbgp_t *sbgp = (isom_sbgp_t *)box;
1608 int indent = level;
1609 int is_fragment = sbgp->parent && lsmash_check_box_type_identical( sbgp->parent->type, ISOM_BOX_TYPE_TRAF );
1610 uint32_t i = 0;
1611 isom_print_box_common( fp, indent++, box, "Sample to Group Box" );
1612 lsmash_ifprintf( fp, indent, "grouping_type = %s\n", isom_4cc2str( sbgp->grouping_type ) );
1613 if( sbgp->version == 1 )
1614 lsmash_ifprintf( fp, indent, "grouping_type_parameter = %s\n", isom_4cc2str( sbgp->grouping_type_parameter ) );
1615 lsmash_ifprintf( fp, indent, "entry_count = %"PRIu32"\n", sbgp->list->entry_count );
1616 for( lsmash_entry_t *entry = sbgp->list->head; entry; entry = entry->next )
1618 isom_group_assignment_entry_t *data = (isom_group_assignment_entry_t *)entry->data;
1619 lsmash_ifprintf( fp, indent++, "entry[%"PRIu32"]\n", i++ );
1620 lsmash_ifprintf( fp, indent, "sample_count = %"PRIu32"\n", data->sample_count );
1621 lsmash_ifprintf( fp, indent--, "group_description_index = %"PRIu32, data->group_description_index );
1622 if( is_fragment && data->group_description_index >= 0x10000 )
1623 fprintf( fp, " (i.e. %"PRIu32" for this fragment-local group)", data->group_description_index - 0x10000 );
1624 if( !data->group_description_index )
1625 fprintf( fp, " (not in this grouping type)\n" );
1626 else
1627 fprintf( fp, "\n" );
1629 return 0;
1632 static int isom_print_udta( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1634 return isom_print_simple( fp, box, level, "User Data Box" );
1637 static int isom_print_chpl( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1639 isom_chpl_t *chpl = (isom_chpl_t *)box;
1640 uint32_t timescale;
1641 if( !chpl->version )
1643 if( !file || !file->moov || !file->moov->mvhd )
1644 return LSMASH_ERR_INVALID_DATA;
1645 timescale = file->moov->mvhd->timescale;
1647 else
1648 timescale = 10000000;
1649 int indent = level;
1650 uint32_t i = 0;
1651 isom_print_box_common( fp, indent++, box, "Chapter List Box" );
1652 if( chpl->version == 1 )
1654 lsmash_ifprintf( fp, indent, "unknown = 0x%02"PRIx8"\n", chpl->unknown );
1655 lsmash_ifprintf( fp, indent, "entry_count = %"PRIu32"\n", chpl->list->entry_count );
1657 else
1658 lsmash_ifprintf( fp, indent, "entry_count = %"PRIu8"\n", (uint8_t)chpl->list->entry_count );
1659 for( lsmash_entry_t *entry = chpl->list->head; entry; entry = entry->next )
1661 isom_chpl_entry_t *data = (isom_chpl_entry_t *)entry->data;
1662 int64_t start_time = data->start_time / timescale;
1663 int hh = start_time / 3600;
1664 int mm = (start_time / 60) % 60;
1665 int ss = start_time % 60;
1666 int ms = ((data->start_time / (double)timescale) - hh * 3600 - mm * 60 - ss) * 1e3 + 0.5;
1667 int with_bom = 0;
1668 if( !memcmp( data->chapter_name, "\xEF\xBB\xBF", 3 ) ) /* detect BOM */
1670 data->chapter_name += 3;
1671 with_bom = 1;
1673 lsmash_ifprintf( fp, indent++, "chapter[%"PRIu32"]\n", i++ );
1674 lsmash_ifprintf( fp, indent, "start_time = %02d:%02d:%02d.%03d\n", hh, mm, ss, ms );
1675 lsmash_ifprintf( fp, indent--, with_bom ? "chapter_name = %s ( it has BOM in it )\n" : "chapter_name = %s\n", data->chapter_name );
1677 return 0;
1680 static int isom_print_meta( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1682 int indent = level;
1683 if( !(box->manager & LSMASH_QTFF_BASE) )
1685 isom_print_basebox_common( fp, indent++, box, "Meta Box" );
1686 lsmash_ifprintf( fp, indent, "version = %"PRIu8"\n", box->version );
1687 lsmash_ifprintf( fp, indent, "flags = 0x%06"PRIx32"\n", box->flags & 0x00ffffff );
1689 else
1690 isom_print_basebox_common( fp, indent, box, "Metadata Box" );
1691 return 0;
1694 static int isom_print_keys( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1696 if( !((isom_keys_t *)box)->list )
1697 return LSMASH_ERR_INVALID_DATA;
1698 isom_keys_t *keys = (isom_keys_t *)box;
1699 int indent = level;
1700 uint32_t i = 1;
1701 isom_print_box_common( fp, indent++, box, "Metadata Item Keys Box" );
1702 lsmash_ifprintf( fp, indent, "entry_count = %"PRIu32"\n", keys->list->entry_count );
1703 for( lsmash_entry_t *entry = keys->list->head; entry; entry = entry->next )
1705 isom_keys_entry_t *data = (isom_keys_entry_t *)entry->data;
1706 lsmash_ifprintf( fp, indent++, "[key %"PRIu32"]\n", i++ );
1707 lsmash_ifprintf( fp, indent, "key_size = %"PRIu32"\n", data->key_size );
1708 lsmash_ifprintf( fp, indent, "key_namespace = %s\n", isom_4cc2str( data->key_namespace ) );
1709 uint32_t value_length = data->key_size - 8;
1710 char str[value_length + 1];
1711 memcpy( str, data->key_value, value_length );
1712 str[value_length] = 0;
1713 lsmash_ifprintf( fp, indent--, "key_value = %s\n", str );
1715 return 0;
1718 static int isom_print_ilst( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1720 return isom_print_simple( fp, box, level, "Metadata Item List Box" );
1723 static int isom_print_metaitem( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1725 isom_metaitem_t *metaitem = (isom_metaitem_t *)box;
1726 if( box->parent && box->parent->parent && (box->parent->parent->manager & LSMASH_QTFF_BASE) )
1728 int indent = level;
1729 lsmash_ifprintf( fp, indent++, "[key_index %"PRIu32": Metadata Item Box]\n", box->type.fourcc );
1730 lsmash_ifprintf( fp, indent, "position = %"PRIu64"\n", box->pos );
1731 lsmash_ifprintf( fp, indent, "size = %"PRIu64"\n", box->size );
1732 return 0;
1734 static const struct
1736 lsmash_itunes_metadata_item item;
1737 char *name;
1738 } metaitem_table[] =
1740 { ITUNES_METADATA_ITEM_ALBUM_NAME, "Album Name" },
1741 { ITUNES_METADATA_ITEM_ARTIST, "Artist" },
1742 { ITUNES_METADATA_ITEM_USER_COMMENT, "User Comment" },
1743 { ITUNES_METADATA_ITEM_RELEASE_DATE, "Release Date" },
1744 { ITUNES_METADATA_ITEM_ENCODED_BY, "Encoded By" },
1745 { ITUNES_METADATA_ITEM_USER_GENRE, "User Genre" },
1746 { ITUNES_METADATA_ITEM_GROUPING, "Grouping" },
1747 { ITUNES_METADATA_ITEM_LYRICS, "Lyrics" },
1748 { ITUNES_METADATA_ITEM_TITLE, "Title" },
1749 { ITUNES_METADATA_ITEM_ENCODING_TOOL, "Encoding Tool" },
1750 { ITUNES_METADATA_ITEM_COMPOSER, "Composer" },
1751 { ITUNES_METADATA_ITEM_ALBUM_ARTIST, "Album Artist" },
1752 { ITUNES_METADATA_ITEM_PODCAST_CATEGORY, "Podcast Category" },
1753 { ITUNES_METADATA_ITEM_COVER_ART, "Cover Art" },
1754 { ITUNES_METADATA_ITEM_DISC_COMPILATION, "Disc Compilation" },
1755 { ITUNES_METADATA_ITEM_COPYRIGHT, "Copyright" },
1756 { ITUNES_METADATA_ITEM_DESCRIPTION, "Description" },
1757 { ITUNES_METADATA_ITEM_DISC_NUMBER, "Disc Number" },
1758 { ITUNES_METADATA_ITEM_EPISODE_GLOBAL_ID, "Episode Global Unique ID" },
1759 { ITUNES_METADATA_ITEM_PREDEFINED_GENRE, "Pre-defined Genre" },
1760 { ITUNES_METADATA_ITEM_GROUPING_DRAFT, "Grouping (Overall work like TIT1 in ID3)" },
1761 { ITUNES_METADATA_ITEM_HIGH_DEFINITION_VIDEO, "High Definition Video" },
1762 { ITUNES_METADATA_ITEM_PODCAST_KEYWORD, "Podcast Keyword" },
1763 { ITUNES_METADATA_ITEM_LONG_DESCRIPTION, "Long Description" },
1764 { ITUNES_METADATA_ITEM_PODCAST, "Podcast" },
1765 { ITUNES_METADATA_ITEM_GAPLESS_PLAYBACK, "Gapless Playback" },
1766 { ITUNES_METADATA_ITEM_PURCHASE_DATE, "Purchase Date" },
1767 { ITUNES_METADATA_ITEM_PODCAST_URL, "Podcast URL" },
1768 { ITUNES_METADATA_ITEM_CONTENT_RATING, "Content Rating" },
1769 { ITUNES_METADATA_ITEM_MEDIA_TYPE, "Media Type" },
1770 { ITUNES_METADATA_ITEM_BEATS_PER_MINUTE, "Beats Per Minute" },
1771 { ITUNES_METADATA_ITEM_TRACK_NUMBER, "Track Number" },
1772 { ITUNES_METADATA_ITEM_TV_EPISODE_ID, "TV Episode ID" },
1773 { ITUNES_METADATA_ITEM_TV_EPISODE, "TV Episode" },
1774 { ITUNES_METADATA_ITEM_TV_NETWORK, "TV Network" },
1775 { ITUNES_METADATA_ITEM_TV_SHOW_NAME, "TV Show Name" },
1776 { ITUNES_METADATA_ITEM_TV_SEASON, "TV Season" },
1777 { ITUNES_METADATA_ITEM_ITUNES_PURCHASE_ACCOUNT_ID, "iTunes Account Used for Purchase" },
1778 { ITUNES_METADATA_ITEM_ITUNES_ACCOUNT_TYPE, "iTunes Account Type" },
1779 { ITUNES_METADATA_ITEM_ITUNES_ARTIST_ID, "iTunes Artist ID" },
1780 { ITUNES_METADATA_ITEM_ITUNES_COMPOSER_ID, "iTunes Composer ID" },
1781 { ITUNES_METADATA_ITEM_ITUNES_CATALOG_ID, "iTunes Catalog ID" },
1782 { ITUNES_METADATA_ITEM_ITUNES_TV_GENRE_ID, "iTunes TV Genre ID" },
1783 { ITUNES_METADATA_ITEM_ITUNES_PLAYLIST_ID, "iTunes Playlist ID" },
1784 { ITUNES_METADATA_ITEM_ITUNES_COUNTRY_CODE, "iTunes Country Code" },
1785 { ITUNES_METADATA_ITEM_ITUNES_SORT_ALBUM, "Sort Album" },
1786 { ITUNES_METADATA_ITEM_ITUNES_SORT_ARTIST, "Sort Artist" },
1787 { ITUNES_METADATA_ITEM_ITUNES_SORT_ALBUM_ARTIST, "Sort Album Artist" },
1788 { ITUNES_METADATA_ITEM_ITUNES_SORT_COMPOSER, "Sort Composer" },
1789 { ITUNES_METADATA_ITEM_ITUNES_SORT_NAME, "Sort Name" },
1790 { ITUNES_METADATA_ITEM_ITUNES_SORT_SHOW, "Sort Show" },
1791 { ITUNES_METADATA_ITEM_CUSTOM, "Custom Metadata Item" },
1792 { 0, NULL }
1794 char *name = NULL;
1795 int i;
1796 for( i = 0; metaitem_table[i].name; i++ )
1797 if( metaitem->type.fourcc == metaitem_table[i].item )
1799 name = metaitem_table[i].name;
1800 break;
1802 if( !name )
1803 name = "Unknown";
1804 uint32_t name_length = strlen( name );
1805 uint32_t display_name_length = name_length + 20;
1806 char display_name[display_name_length + 1];
1807 memcpy( display_name, "Metadata Item Box (", 19 );
1808 memcpy( display_name + 19, name, name_length );
1809 display_name[display_name_length - 1] = ')';
1810 display_name[display_name_length] = 0;
1811 return isom_print_simple( fp, box, level, display_name );
1814 static int isom_print_name( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1816 isom_name_t *name = (isom_name_t *)box;
1817 int indent = level;
1818 isom_print_box_common( fp, indent++, box, "Name Box" );
1819 char str[name->name_length + 1];
1820 memcpy( str, name->name, name->name_length );
1821 str[name->name_length] = 0;
1822 lsmash_ifprintf( fp, indent, "name = %s\n", str );
1823 return 0;
1826 static int isom_print_mean( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1828 isom_mean_t *mean = (isom_mean_t *)box;
1829 int indent = level;
1830 isom_print_box_common( fp, indent++, box, "Mean Box" );
1831 char str[mean->meaning_string_length + 1];
1832 memcpy( str, mean->meaning_string, mean->meaning_string_length );
1833 str[mean->meaning_string_length] = 0;
1834 lsmash_ifprintf( fp, indent, "meaning_string = %s\n", str );
1835 return 0;
1838 static int isom_print_data( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
1840 isom_data_t *data = (isom_data_t *)box;
1841 int indent = level;
1842 isom_print_box_common( fp, indent++, box, "Data Box" );
1843 if( box->parent && box->parent->parent && box->parent->parent->parent
1844 && (box->parent->parent->parent->manager & LSMASH_QTFF_BASE) )
1846 uint32_t type_set_indicator = data->reserved >> 8;
1847 uint32_t well_known_type = ((data->reserved << 16) | (data->type_set_identifier << 8) | data->type_code) & 0xffffff;
1848 char *well_known_type_name;
1849 static const struct
1851 uint32_t type;
1852 char *name;
1853 } well_known_type_table[] =
1855 { 0, "reserved" },
1856 { 1, "UTF-8" },
1857 { 2, "UTF-16 BE" },
1858 { 3, "S/JIS" },
1859 { 4, "UTF-8 sort" },
1860 { 5, "UTF-16 sort" },
1861 { 13, "JPEG in a JFIF wrapper" },
1862 { 14, "PNG in a PNG wrapper" },
1863 { 21, "BE Signed Integer" },
1864 { 22, "BE Unsigned Integer" },
1865 { 23, "BE Float32" },
1866 { 24, "BE Float64" },
1867 { 27, "BMP (Windows bitmap format graphics)" },
1868 { 28, "QuickTime Metadata box" },
1869 { UINT32_MAX }
1871 int table_index;
1872 for( table_index = 0; well_known_type_table[table_index].type != UINT32_MAX; table_index++ )
1873 if( well_known_type == well_known_type_table[table_index].type )
1875 well_known_type_name = well_known_type_table[table_index].name;
1876 break;
1878 if( well_known_type_table[table_index].type == UINT32_MAX )
1879 well_known_type_name = "Unknown";
1880 lsmash_ifprintf( fp, indent, "type_set_indicator = %"PRIu8"\n", type_set_indicator );
1881 lsmash_ifprintf( fp, indent, "well_known_type = %"PRIu32" (%s)\n", well_known_type, well_known_type_name );
1882 lsmash_ifprintf( fp, indent, "locale_indicator = %"PRIu32"\n", data->the_locale );
1883 if( data->value_length == 0 )
1885 lsmash_ifprintf( fp, indent, "value = (null)\n" );
1886 return 0;
1888 if( well_known_type == 1 )
1890 /* UTF-8 without any count or null terminator */
1891 char str[data->value_length + 1];
1892 memcpy( str, data->value, data->value_length );
1893 str[data->value_length] = 0;
1894 lsmash_ifprintf( fp, indent, "value = %s\n", str );
1896 else if( well_known_type == 13 || well_known_type == 14 || well_known_type == 27 )
1897 lsmash_ifprintf( fp, indent, "value = (binary data)\n" );
1898 else if( well_known_type == 21 && data->value_length <= 4 )
1899 /* a big-endian signed integer in 1,2,3 or 4 bytes */
1900 goto show_in_signed_integer;
1901 else if( well_known_type == 22 && data->value_length <= 4 )
1903 /* a big-endian unsigned integer in 1,2,3 or 4 bytes */
1904 uint32_t integer = data->value[0];
1905 for( uint32_t i = 1; i < data->value_length; i++ )
1906 integer = (integer << 8) | data->value[i];
1907 lsmash_ifprintf( fp, indent, "value = %"PRIu32"\n", integer );
1909 else if( well_known_type == 23 && data->value_length == 4 )
1911 /* a big-endian 32-bit floating point value (IEEE754) */
1912 uint32_t float32 = LSMASH_GET_BE32( data->value );
1913 lsmash_ifprintf( fp, indent, "value = %f\n", lsmash_int2float32( float32 ) );
1915 else if( well_known_type == 24 && data->value_length == 8 )
1917 /* a big-endian 64-bit floating point value (IEEE754) */
1918 uint64_t float64 = LSMASH_GET_BE64( data->value );
1919 lsmash_ifprintf( fp, indent, "value = %lf\n", lsmash_int2float64( float64 ) );
1921 else
1922 goto show_in_binary;
1924 else
1926 char *basic_data_type_name;
1927 static const struct
1929 uint32_t type;
1930 char *name;
1931 } basic_data_type_table[] =
1933 { 0, "Implicit" },
1934 { 1, "UTF-8" },
1935 { 2, "UTF-16 BE" },
1936 { 3, "S/JIS" },
1937 { 6, "HTML" },
1938 { 7, "XML" },
1939 { 8, "UUID" },
1940 { 9, "ISRC" },
1941 { 10, "MI3P" },
1942 { 12, "GIF" },
1943 { 13, "JPEG in a JFIF wrapper" },
1944 { 14, "PNG in a PNG wrapper" },
1945 { 15, "URL" },
1946 { 16, "duration" },
1947 { 17, "date/time" },
1948 { 18, "Genres" },
1949 { 21, "BE Signed Integer" },
1950 { 24, "RIAA-PA (RIAA Parental advisory)" },
1951 { 25, "UPC (Universal Product Code)" },
1952 { 27, "BMP (Windows bitmap format graphics)" },
1953 { UINT32_MAX }
1955 int table_index;
1956 for( table_index = 0; basic_data_type_table[table_index].type != UINT32_MAX; table_index++ )
1957 if( data->type_code == basic_data_type_table[table_index].type )
1959 basic_data_type_name = basic_data_type_table[table_index].name;
1960 break;
1962 if( basic_data_type_table[table_index].type == UINT32_MAX )
1963 basic_data_type_name = "Unknown";
1964 lsmash_ifprintf( fp, indent, "reserved = %"PRIu16"\n", data->reserved );
1965 lsmash_ifprintf( fp, indent, "type_set_identifier = %"PRIu8"%s\n",
1966 data->type_set_identifier,
1967 data->type_set_identifier ? "" : " (basic type set)" );
1968 lsmash_ifprintf( fp, indent, "type_code = %"PRIu8" (%s)\n", data->type_code, basic_data_type_name );
1969 lsmash_ifprintf( fp, indent, "the_locale = %"PRIu32"\n", data->the_locale );
1970 if( data->value_length == 0 )
1972 lsmash_ifprintf( fp, indent, "value = (null)\n" );
1973 return 0;
1975 if( data->type_code == 6 || data->type_code == 7
1976 || data->type_code == 12 || data->type_code == 13
1977 || data->type_code == 14 || data->type_code == 27 )
1978 lsmash_ifprintf( fp, indent, "value = (binary data)\n" );
1979 else if( data->type_code == 8 && data->value_length == 16 )
1980 /* UUID */
1981 lsmash_ifprintf( fp, indent, "value = 0x%08"PRIx32"-%04"PRIx16"-%04"PRIx16"-%04"PRIx16"-%04"PRIx16"0x%08"PRIx32"\n",
1982 LSMASH_GET_BE32( &data->value[ 0] ),
1983 LSMASH_GET_BE16( &data->value[ 4] ),
1984 LSMASH_GET_BE16( &data->value[ 6] ),
1985 LSMASH_GET_BE16( &data->value[ 8] ),
1986 LSMASH_GET_BE16( &data->value[10] ),
1987 LSMASH_GET_BE32( &data->value[12] ) );
1988 else if( data->type_code == 16 && data->value_length == 4 )
1990 /* duration in milliseconds */
1991 uint32_t duration = LSMASH_GET_BE32( data->value );
1992 lsmash_ifprintf( fp, indent, "value = %"PRIu32" milliseconds\n", duration );
1994 else if( data->type_code == 17 && (data->value_length == 4 || data->value_length == 8) )
1996 /* UTC, counting seconds since midnight on 1 January, 1904 */
1997 uint64_t mp4time = data->value_length == 8
1998 ? LSMASH_GET_BE64( data->value )
1999 : LSMASH_GET_BE32( data->value );
2000 isom_mp4time2utc( mp4time );
2002 else if( data->type_code == 21 && data->value_length <= 8 )
2003 /* a big-endian signed integer in 1,2,3,4 or 8 bytes */
2004 goto show_in_signed_integer;
2005 else if( data->type_code == 24 )
2007 /* RIAA-PA (RIAA Parental advisory) 8-bit integer */
2008 lsmash_ifprintf( fp, indent, "value = %"PRIu8, data->value[0] );
2009 if( (signed)data->value[0] == -1 )
2010 fprintf( fp, " (no)" );
2011 else if( data->value[0] == 1 )
2012 fprintf( fp, " (yes)" );
2013 else if( data->value[0] == 0 )
2014 fprintf( fp, " (unspecified)" );
2015 fprintf( fp, "\n" );
2017 else if( data->type_code == 1 || data->type_code == 2 || data->type_code == 3
2018 || data->type_code == 9 || data->type_code == 10 || data->type_code == 15
2019 || data->type_code == 25 )
2021 /* String */
2022 char str[data->value_length + 1];
2023 memcpy( str, data->value, data->value_length );
2024 str[data->value_length] = 0;
2025 lsmash_ifprintf( fp, indent, "value = %s\n", str );
2027 else
2028 goto show_in_binary;
2030 return 0;
2031 show_in_signed_integer:;
2032 uint64_t integer = data->value[0];
2033 uint64_t max_value = 0xff;
2034 for( uint32_t i = 1; i < data->value_length; i++ )
2036 integer = (integer << 8) | data->value[i];
2037 max_value = (max_value << 8) | 0xff;
2039 lsmash_ifprintf( fp, indent, "value = %"PRId64"\n", (int64_t)(integer | (integer > (max_value >> 1) ? ~max_value : 0)) );
2040 return 0;
2041 show_in_binary:
2042 lsmash_ifprintf( fp, indent, "value = " );
2043 if( data->value_length )
2045 fprintf( fp, "0x" );
2046 for( uint32_t i = 0; i < data->value_length; i++ )
2047 fprintf( fp, "%02"PRIx8, data->value[i] );
2049 fprintf( fp, "\n" );
2050 return 0;
2053 static int isom_print_WLOC( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
2055 isom_WLOC_t *WLOC = (isom_WLOC_t *)box;
2056 int indent = level;
2057 isom_print_box_common( fp, indent++, box, "Window Location Box" );
2058 lsmash_ifprintf( fp, indent, "x = %"PRIu16"\n", WLOC->x );
2059 lsmash_ifprintf( fp, indent, "y = %"PRIu16"\n", WLOC->y );
2060 return 0;
2063 static int isom_print_LOOP( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
2065 isom_LOOP_t *LOOP = (isom_LOOP_t *)box;
2066 int indent = level;
2067 isom_print_box_common( fp, indent++, box, "Looping Box" );
2068 lsmash_ifprintf( fp, indent, "looping_mode = %"PRIu32, LOOP->looping_mode );
2069 switch( LOOP->looping_mode )
2071 case 0 :
2072 fprintf( fp, " (none)\n" );
2073 break;
2074 case 1 :
2075 fprintf( fp, " (looping)\n" );
2076 break;
2077 case 2 :
2078 fprintf( fp, " (palindromic looping)\n" );
2079 break;
2080 default :
2081 fprintf( fp, "\n" );
2082 break;
2084 return 0;
2087 static int isom_print_SelO( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
2089 isom_SelO_t *SelO = (isom_SelO_t *)box;
2090 int indent = level;
2091 isom_print_box_common( fp, indent++, box, "Play Selection Only Box" );
2092 lsmash_ifprintf( fp, indent, "selection_only = %"PRIu8"\n", SelO->selection_only );
2093 return 0;
2096 static int isom_print_AllF( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
2098 isom_AllF_t *AllF = (isom_AllF_t *)box;
2099 int indent = level;
2100 isom_print_box_common( fp, indent++, box, "Play All Frames Box" );
2101 lsmash_ifprintf( fp, indent, "play_all_frames = %"PRIu8"\n", AllF->play_all_frames );
2102 return 0;
2105 static int isom_print_cprt( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
2107 isom_cprt_t *cprt = (isom_cprt_t *)box;
2108 int indent = level;
2109 char str[cprt->notice_length + 1];
2110 memcpy( str, cprt->notice, cprt->notice_length );
2111 str[cprt->notice_length] = 0;
2112 isom_print_box_common( fp, indent++, box, "Copyright Box" );
2113 lsmash_ifprintf( fp, indent, "language = %s\n", isom_unpack_iso_language( cprt->language ) );
2114 lsmash_ifprintf( fp, indent, "notice = %s\n", str );
2115 return 0;
2118 static int isom_print_mvex( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
2120 return isom_print_simple( fp, box, level, "Movie Extends Box" );
2123 static int isom_print_mehd( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
2125 isom_mehd_t *mehd = (isom_mehd_t *)box;
2126 int indent = level;
2127 isom_print_box_common( fp, indent++, box, "Movie Extends Header Box" );
2128 if( file && file->moov && file->moov->mvhd )
2129 isom_ifprintf_duration( fp, indent, "fragment_duration", mehd->fragment_duration, file->moov->mvhd->timescale );
2130 else
2131 isom_ifprintf_duration( fp, indent, "fragment_duration", mehd->fragment_duration, 0 );
2132 return 0;
2135 static int isom_print_trex( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
2137 isom_trex_t *trex = (isom_trex_t *)box;
2138 int indent = level;
2139 isom_print_box_common( fp, indent++, box, "Track Extends Box" );
2140 lsmash_ifprintf( fp, indent, "track_ID = %"PRIu32"\n", trex->track_ID );
2141 lsmash_ifprintf( fp, indent, "default_sample_description_index = %"PRIu32"\n", trex->default_sample_description_index );
2142 lsmash_ifprintf( fp, indent, "default_sample_duration = %"PRIu32"\n", trex->default_sample_duration );
2143 lsmash_ifprintf( fp, indent, "default_sample_size = %"PRIu32"\n", trex->default_sample_size );
2144 isom_ifprintf_sample_flags( fp, indent, "default_sample_flags", &trex->default_sample_flags );
2145 return 0;
2148 static int isom_print_moof( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
2150 return isom_print_simple( fp, box, level, "Movie Fragment Box" );
2153 static int isom_print_mfhd( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
2155 isom_mfhd_t *mfhd = (isom_mfhd_t *)box;
2156 int indent = level;
2157 isom_print_box_common( fp, indent++, box, "Movie Fragment Header Box" );
2158 lsmash_ifprintf( fp, indent, "sequence_number = %"PRIu32"\n", mfhd->sequence_number );
2159 return 0;
2162 static int isom_print_traf( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
2164 return isom_print_simple( fp, box, level, "Track Fragment Box" );
2167 static int isom_print_tfhd( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
2169 isom_tfhd_t *tfhd = (isom_tfhd_t *)box;
2170 int indent = level;
2171 isom_print_box_common( fp, indent++, box, "Track Fragment Header Box" );
2172 ++indent;
2173 if( tfhd->flags & ISOM_TF_FLAGS_BASE_DATA_OFFSET_PRESENT ) lsmash_ifprintf( fp, indent, "base-data-offset-present\n" );
2174 if( tfhd->flags & ISOM_TF_FLAGS_SAMPLE_DESCRIPTION_INDEX_PRESENT ) lsmash_ifprintf( fp, indent, "sample-description-index-present\n" );
2175 if( tfhd->flags & ISOM_TF_FLAGS_DEFAULT_SAMPLE_DURATION_PRESENT ) lsmash_ifprintf( fp, indent, "default-sample-duration-present\n" );
2176 if( tfhd->flags & ISOM_TF_FLAGS_DEFAULT_SAMPLE_SIZE_PRESENT ) lsmash_ifprintf( fp, indent, "default-sample-size-present\n" );
2177 if( tfhd->flags & ISOM_TF_FLAGS_DEFAULT_SAMPLE_FLAGS_PRESENT ) lsmash_ifprintf( fp, indent, "default-sample-flags-present\n" );
2178 if( tfhd->flags & ISOM_TF_FLAGS_DEFAULT_BASE_IS_MOOF ) lsmash_ifprintf( fp, indent, "default-base-is-moof\n" );
2179 lsmash_ifprintf( fp, --indent, "track_ID = %"PRIu32"\n", tfhd->track_ID );
2180 if( tfhd->flags & ISOM_TF_FLAGS_BASE_DATA_OFFSET_PRESENT )
2181 lsmash_ifprintf( fp, indent, "base_data_offset = %"PRIu64"\n", tfhd->base_data_offset );
2182 if( tfhd->flags & ISOM_TF_FLAGS_SAMPLE_DESCRIPTION_INDEX_PRESENT )
2183 lsmash_ifprintf( fp, indent, "sample_description_index = %"PRIu32"\n", tfhd->sample_description_index );
2184 if( tfhd->flags & ISOM_TF_FLAGS_DEFAULT_SAMPLE_DURATION_PRESENT )
2185 lsmash_ifprintf( fp, indent, "default_sample_duration = %"PRIu32"\n", tfhd->default_sample_duration );
2186 if( tfhd->flags & ISOM_TF_FLAGS_DEFAULT_SAMPLE_SIZE_PRESENT )
2187 lsmash_ifprintf( fp, indent, "default_sample_size = %"PRIu32"\n", tfhd->default_sample_size );
2188 if( tfhd->flags & ISOM_TF_FLAGS_DEFAULT_SAMPLE_FLAGS_PRESENT )
2189 isom_ifprintf_sample_flags( fp, indent, "default_sample_flags", &tfhd->default_sample_flags );
2190 return 0;
2193 static int isom_print_tfdt( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
2195 isom_tfdt_t *tfdt = (isom_tfdt_t *)box;
2196 int indent = level;
2197 isom_print_box_common( fp, indent++, box, "Track Fragment Base Media Decode Time Box" );
2198 lsmash_ifprintf( fp, indent, "baseMediaDecodeTime = %"PRIu64"\n", tfdt->baseMediaDecodeTime );
2199 return 0;
2202 static int isom_print_trun( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
2204 isom_trun_t *trun = (isom_trun_t *)box;
2205 int indent = level;
2206 isom_print_box_common( fp, indent++, box, "Track Fragment Run Box" );
2207 ++indent;
2208 if( trun->flags & ISOM_TR_FLAGS_DATA_OFFSET_PRESENT ) lsmash_ifprintf( fp, indent, "data-offset-present\n" );
2209 if( trun->flags & ISOM_TR_FLAGS_FIRST_SAMPLE_FLAGS_PRESENT ) lsmash_ifprintf( fp, indent, "first-sample-flags-present\n" );
2210 if( trun->flags & ISOM_TR_FLAGS_SAMPLE_DURATION_PRESENT ) lsmash_ifprintf( fp, indent, "sample-duration-present\n" );
2211 if( trun->flags & ISOM_TR_FLAGS_SAMPLE_SIZE_PRESENT ) lsmash_ifprintf( fp, indent, "sample-size-present\n" );
2212 if( trun->flags & ISOM_TR_FLAGS_SAMPLE_FLAGS_PRESENT ) lsmash_ifprintf( fp, indent, "sample-flags-present\n" );
2213 if( trun->flags & ISOM_TR_FLAGS_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT ) lsmash_ifprintf( fp, indent, "sample-composition-time-offsets-present\n" );
2214 lsmash_ifprintf( fp, --indent, "sample_count = %"PRIu32"\n", trun->sample_count );
2215 if( trun->flags & ISOM_TR_FLAGS_DATA_OFFSET_PRESENT )
2216 lsmash_ifprintf( fp, indent, "data_offset = %"PRId32"\n", trun->data_offset );
2217 if( trun->flags & ISOM_TR_FLAGS_FIRST_SAMPLE_FLAGS_PRESENT )
2218 isom_ifprintf_sample_flags( fp, indent, "first_sample_flags", &trun->first_sample_flags );
2219 if( trun->optional )
2221 uint32_t i = 0;
2222 for( lsmash_entry_t *entry = trun->optional->head; entry; entry = entry->next )
2224 isom_trun_optional_row_t *row = (isom_trun_optional_row_t *)entry->data;
2225 lsmash_ifprintf( fp, indent++, "sample[%"PRIu32"]\n", i++ );
2226 if( trun->flags & ISOM_TR_FLAGS_SAMPLE_DURATION_PRESENT )
2227 lsmash_ifprintf( fp, indent, "sample_duration = %"PRIu32"\n", row->sample_duration );
2228 if( trun->flags & ISOM_TR_FLAGS_SAMPLE_SIZE_PRESENT )
2229 lsmash_ifprintf( fp, indent, "sample_size = %"PRIu32"\n", row->sample_size );
2230 if( trun->flags & ISOM_TR_FLAGS_SAMPLE_FLAGS_PRESENT )
2231 isom_ifprintf_sample_flags( fp, indent, "sample_flags", &row->sample_flags );
2232 if( trun->flags & ISOM_TR_FLAGS_SAMPLE_COMPOSITION_TIME_OFFSET_PRESENT )
2234 if( trun->version == 0 )
2235 lsmash_ifprintf( fp, indent, "sample_composition_time_offset = %"PRIu32"\n",
2236 row->sample_composition_time_offset );
2237 else
2238 lsmash_ifprintf( fp, indent, "sample_composition_time_offset = %"PRId32"\n",
2239 (union {uint32_t ui; int32_t si;}){ row->sample_composition_time_offset }.si );
2241 --indent;
2244 return 0;
2247 static int isom_print_free( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
2249 return isom_print_simple( fp, box, level, "Free Space Box" );
2252 static int isom_print_mdat( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
2254 return isom_print_simple( fp, box, level, "Media Data Box" );
2257 static int isom_print_mfra( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
2259 return isom_print_simple( fp, box, level, "Movie Fragment Random Access Box" );
2262 static int isom_print_tfra( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
2264 isom_tfra_t *tfra = (isom_tfra_t *)box;
2265 int indent = level;
2266 isom_print_box_common( fp, indent++, box, "Track Fragment Random Access Box" );
2267 lsmash_ifprintf( fp, indent, "track_ID = %"PRIu32"\n", tfra->track_ID );
2268 lsmash_ifprintf( fp, indent, "reserved = 0x%08"PRIx32"\n", tfra->reserved );
2269 lsmash_ifprintf( fp, indent, "length_size_of_traf_num = %"PRIu8"\n", tfra->length_size_of_traf_num );
2270 lsmash_ifprintf( fp, indent, "length_size_of_trun_num = %"PRIu8"\n", tfra->length_size_of_trun_num );
2271 lsmash_ifprintf( fp, indent, "length_size_of_sample_num = %"PRIu8"\n", tfra->length_size_of_sample_num );
2272 lsmash_ifprintf( fp, indent, "number_of_entry = %"PRIu32"\n", tfra->number_of_entry );
2273 if( tfra->list )
2275 uint32_t i = 0;
2276 for( lsmash_entry_t *entry = tfra->list->head; entry; entry = entry->next )
2278 isom_tfra_location_time_entry_t *data = (isom_tfra_location_time_entry_t *)entry->data;
2279 lsmash_ifprintf( fp, indent++, "entry[%"PRIu32"]\n", i++ );
2280 lsmash_ifprintf( fp, indent, "time = %"PRIu64"\n", data->time );
2281 lsmash_ifprintf( fp, indent, "moof_offset = %"PRIu64"\n", data->moof_offset );
2282 lsmash_ifprintf( fp, indent, "traf_number = %"PRIu32"\n", data->traf_number );
2283 lsmash_ifprintf( fp, indent, "trun_number = %"PRIu32"\n", data->trun_number );
2284 lsmash_ifprintf( fp, indent, "sample_number = %"PRIu32"\n", data->sample_number );
2285 --indent;
2288 return 0;
2291 static int isom_print_mfro( FILE *fp, lsmash_file_t *file, isom_box_t *box, int level )
2293 isom_mfro_t *mfro = (isom_mfro_t *)box;
2294 int indent = level;
2295 isom_print_box_common( fp, indent++, box, "Movie Fragment Random Access Offset Box" );
2296 lsmash_ifprintf( fp, indent, "size = %"PRIu32"\n", mfro->length );
2297 return 0;
2300 int lsmash_print_movie( lsmash_root_t *root, const char *filename )
2302 if( !root )
2303 return LSMASH_ERR_FUNCTION_PARAM;
2304 lsmash_file_t *file = root->file;
2305 if( !file
2306 || !file->print
2307 || !(file->flags & LSMASH_FILE_MODE_DUMP) )
2308 return LSMASH_ERR_FUNCTION_PARAM;
2309 FILE *destination;
2310 if( !strcmp( filename, "-" ) )
2311 destination = stdout;
2312 else
2313 destination = lsmash_fopen( filename, "wb" );
2314 fprintf( destination, "[File]\n" );
2315 fprintf( destination, " size = %"PRIu64"\n", file->size );
2316 for( lsmash_entry_t *entry = file->print->head; entry; entry = entry->next )
2318 isom_print_entry_t *data = (isom_print_entry_t *)entry->data;
2319 if( !data || !data->box )
2321 fclose( destination );
2322 return LSMASH_ERR_NAMELESS;
2324 int ret = data->func( destination, file, data->box, data->level );
2325 if( ret < 0 )
2327 fclose( destination );
2328 return ret;
2331 fclose( destination );
2332 return 0;
2335 static isom_print_box_t isom_select_print_func( isom_box_t *box )
2337 if( box->manager & LSMASH_UNKNOWN_BOX )
2338 return isom_print_unknown;
2339 if( box->parent )
2341 isom_box_t *parent = box->parent;
2342 if( lsmash_check_box_type_identical( parent->type, ISOM_BOX_TYPE_STSD ) )
2344 lsmash_codec_type_t sample_type = box->type;
2345 if( lsmash_check_codec_type_identical( sample_type, LSMASH_CODEC_TYPE_RAW ) )
2347 if( box->manager & LSMASH_VIDEO_DESCRIPTION )
2348 return isom_print_visual_description;
2349 else if( box->manager & LSMASH_AUDIO_DESCRIPTION )
2350 return isom_print_audio_description;
2352 static struct print_description_table_tag
2354 lsmash_codec_type_t type;
2355 isom_print_box_t func;
2356 } print_description_table[160] = { { LSMASH_CODEC_TYPE_INITIALIZER, NULL } };
2357 if( !print_description_table[0].func )
2359 /* Initialize the table. */
2360 int i = 0;
2361 #define ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( type, func ) print_description_table[i++] = (struct print_description_table_tag){ type, func }
2362 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_AVC1_VIDEO, isom_print_visual_description );
2363 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_AVC2_VIDEO, isom_print_visual_description );
2364 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_AVC3_VIDEO, isom_print_visual_description );
2365 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_AVC4_VIDEO, isom_print_visual_description );
2366 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_AVCP_VIDEO, isom_print_visual_description );
2367 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_DRAC_VIDEO, isom_print_visual_description );
2368 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_ENCV_VIDEO, isom_print_visual_description );
2369 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_HVC1_VIDEO, isom_print_visual_description );
2370 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_HEV1_VIDEO, isom_print_visual_description );
2371 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_MJP2_VIDEO, isom_print_visual_description );
2372 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_MP4V_VIDEO, isom_print_visual_description );
2373 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_MVC1_VIDEO, isom_print_visual_description );
2374 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_MVC2_VIDEO, isom_print_visual_description );
2375 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_S263_VIDEO, isom_print_visual_description );
2376 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_SVC1_VIDEO, isom_print_visual_description );
2377 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_VC_1_VIDEO, isom_print_visual_description );
2378 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_2VUY_VIDEO, isom_print_visual_description );
2379 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_CFHD_VIDEO, isom_print_visual_description );
2380 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_DV10_VIDEO, isom_print_visual_description );
2381 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_DVOO_VIDEO, isom_print_visual_description );
2382 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_DVOR_VIDEO, isom_print_visual_description );
2383 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_DVTV_VIDEO, isom_print_visual_description );
2384 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_DVVT_VIDEO, isom_print_visual_description );
2385 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_HD10_VIDEO, isom_print_visual_description );
2386 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_M105_VIDEO, isom_print_visual_description );
2387 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_PNTG_VIDEO, isom_print_visual_description );
2388 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_SVQ1_VIDEO, isom_print_visual_description );
2389 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_SVQ3_VIDEO, isom_print_visual_description );
2390 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_SHR0_VIDEO, isom_print_visual_description );
2391 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_SHR1_VIDEO, isom_print_visual_description );
2392 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_SHR2_VIDEO, isom_print_visual_description );
2393 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_SHR3_VIDEO, isom_print_visual_description );
2394 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_SHR4_VIDEO, isom_print_visual_description );
2395 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_WRLE_VIDEO, isom_print_visual_description );
2396 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_APCH_VIDEO, isom_print_visual_description );
2397 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_APCN_VIDEO, isom_print_visual_description );
2398 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_APCS_VIDEO, isom_print_visual_description );
2399 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_APCO_VIDEO, isom_print_visual_description );
2400 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_AP4H_VIDEO, isom_print_visual_description );
2401 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_CIVD_VIDEO, isom_print_visual_description );
2402 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_DRAC_VIDEO, isom_print_visual_description );
2403 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_DVC_VIDEO, isom_print_visual_description );
2404 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_DVCP_VIDEO, isom_print_visual_description );
2405 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_DVPP_VIDEO, isom_print_visual_description );
2406 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_DV5N_VIDEO, isom_print_visual_description );
2407 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_DV5P_VIDEO, isom_print_visual_description );
2408 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_DVH2_VIDEO, isom_print_visual_description );
2409 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_DVH3_VIDEO, isom_print_visual_description );
2410 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_DVH5_VIDEO, isom_print_visual_description );
2411 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_DVH6_VIDEO, isom_print_visual_description );
2412 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_DVHP_VIDEO, isom_print_visual_description );
2413 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_DVHQ_VIDEO, isom_print_visual_description );
2414 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_FLIC_VIDEO, isom_print_visual_description );
2415 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_GIF_VIDEO, isom_print_visual_description );
2416 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_H261_VIDEO, isom_print_visual_description );
2417 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_H263_VIDEO, isom_print_visual_description );
2418 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_JPEG_VIDEO, isom_print_visual_description );
2419 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_MJPA_VIDEO, isom_print_visual_description );
2420 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_MJPB_VIDEO, isom_print_visual_description );
2421 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_PNG_VIDEO, isom_print_visual_description );
2422 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_RLE_VIDEO, isom_print_visual_description );
2423 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_RPZA_VIDEO, isom_print_visual_description );
2424 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_TGA_VIDEO, isom_print_visual_description );
2425 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_TIFF_VIDEO, isom_print_visual_description );
2426 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_ULRA_VIDEO, isom_print_visual_description );
2427 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_ULRG_VIDEO, isom_print_visual_description );
2428 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_ULY2_VIDEO, isom_print_visual_description );
2429 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_ULY0_VIDEO, isom_print_visual_description );
2430 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_ULH2_VIDEO, isom_print_visual_description );
2431 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_ULH0_VIDEO, isom_print_visual_description );
2432 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_V210_VIDEO, isom_print_visual_description );
2433 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_V216_VIDEO, isom_print_visual_description );
2434 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_V308_VIDEO, isom_print_visual_description );
2435 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_V408_VIDEO, isom_print_visual_description );
2436 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_V410_VIDEO, isom_print_visual_description );
2437 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_YUV2_VIDEO, isom_print_visual_description );
2438 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_AC_3_AUDIO, isom_print_audio_description );
2439 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_ALAC_AUDIO, isom_print_audio_description );
2440 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_DRA1_AUDIO, isom_print_audio_description );
2441 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_DTSC_AUDIO, isom_print_audio_description );
2442 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_DTSE_AUDIO, isom_print_audio_description );
2443 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_DTSH_AUDIO, isom_print_audio_description );
2444 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_DTSL_AUDIO, isom_print_audio_description );
2445 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_EC_3_AUDIO, isom_print_audio_description );
2446 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_ENCA_AUDIO, isom_print_audio_description );
2447 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_G719_AUDIO, isom_print_audio_description );
2448 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_G726_AUDIO, isom_print_audio_description );
2449 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_M4AE_AUDIO, isom_print_audio_description );
2450 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_MLPA_AUDIO, isom_print_audio_description );
2451 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_MP4A_AUDIO, isom_print_audio_description );
2452 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_SAMR_AUDIO, isom_print_audio_description );
2453 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_SAWB_AUDIO, isom_print_audio_description );
2454 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_SAWP_AUDIO, isom_print_audio_description );
2455 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_SEVC_AUDIO, isom_print_audio_description );
2456 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_SQCP_AUDIO, isom_print_audio_description );
2457 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_SSMV_AUDIO, isom_print_audio_description );
2458 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_TWOS_AUDIO, isom_print_audio_description );
2459 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_WMA_AUDIO, isom_print_audio_description );
2460 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_MP4A_AUDIO, isom_print_audio_description );
2461 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_23NI_AUDIO, isom_print_audio_description );
2462 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_MAC3_AUDIO, isom_print_audio_description );
2463 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_MAC6_AUDIO, isom_print_audio_description );
2464 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_NONE_AUDIO, isom_print_audio_description );
2465 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_QDM2_AUDIO, isom_print_audio_description );
2466 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_QDMC_AUDIO, isom_print_audio_description );
2467 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_QCLP_AUDIO, isom_print_audio_description );
2468 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_AGSM_AUDIO, isom_print_audio_description );
2469 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_ALAW_AUDIO, isom_print_audio_description );
2470 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_CDX2_AUDIO, isom_print_audio_description );
2471 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_CDX4_AUDIO, isom_print_audio_description );
2472 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_DVCA_AUDIO, isom_print_audio_description );
2473 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_DVI_AUDIO, isom_print_audio_description );
2474 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_FL32_AUDIO, isom_print_audio_description );
2475 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_FL64_AUDIO, isom_print_audio_description );
2476 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_IMA4_AUDIO, isom_print_audio_description );
2477 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_IN24_AUDIO, isom_print_audio_description );
2478 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_IN32_AUDIO, isom_print_audio_description );
2479 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_LPCM_AUDIO, isom_print_audio_description );
2480 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_SOWT_AUDIO, isom_print_audio_description );
2481 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_TWOS_AUDIO, isom_print_audio_description );
2482 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_ULAW_AUDIO, isom_print_audio_description );
2483 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_VDVA_AUDIO, isom_print_audio_description );
2484 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_FULLMP3_AUDIO, isom_print_audio_description );
2485 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_MP3_AUDIO, isom_print_audio_description );
2486 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_ADPCM2_AUDIO, isom_print_audio_description );
2487 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_ADPCM17_AUDIO, isom_print_audio_description );
2488 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_GSM49_AUDIO, isom_print_audio_description );
2489 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_NOT_SPECIFIED, isom_print_audio_description );
2490 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( QT_CODEC_TYPE_TEXT_TEXT, isom_print_text_description );
2491 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_TX3G_TEXT, isom_print_tx3g_description );
2492 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( ISOM_CODEC_TYPE_MP4S_SYSTEM, isom_print_mp4s_description );
2493 ADD_PRINT_DESCRIPTION_TABLE_ELEMENT( LSMASH_CODEC_TYPE_UNSPECIFIED, NULL );
2494 #undef ADD_PRINT_DESCRIPTION_TABLE_ELEMENT
2496 for( int i = 0; print_description_table[i].func; i++ )
2497 if( lsmash_check_codec_type_identical( sample_type, print_description_table[i].type ) )
2498 return print_description_table[i].func;
2499 return isom_print_unknown;
2501 if( lsmash_check_box_type_identical( parent->type, QT_BOX_TYPE_WAVE ) )
2503 if( lsmash_check_box_type_identical( box->type, QT_BOX_TYPE_FRMA ) )
2504 return isom_print_frma;
2505 else if( lsmash_check_box_type_identical( box->type, QT_BOX_TYPE_ENDA ) )
2506 return isom_print_enda;
2507 else if( lsmash_check_box_type_identical( box->type, QT_BOX_TYPE_TERMINATOR ) )
2508 return isom_print_terminator;
2509 else
2510 return isom_print_sample_description_extesion;
2512 if( lsmash_check_box_type_identical( parent->type, ISOM_BOX_TYPE_TREF ) )
2513 return isom_print_track_reference_type;
2514 if( parent->parent )
2516 if( lsmash_check_box_type_identical( parent->parent->type, ISOM_BOX_TYPE_STSD ) )
2517 return isom_print_sample_description_extesion;
2518 else if( lsmash_check_box_type_identical( parent->parent->type, ISOM_BOX_TYPE_ILST )
2519 || lsmash_check_box_type_identical( parent->parent->type, QT_BOX_TYPE_ILST ) )
2521 if( parent->type.fourcc == LSMASH_4CC( '-', '-', '-', '-' ) )
2523 if( lsmash_check_box_type_identical( box->type, ISOM_BOX_TYPE_MEAN ) )
2524 return isom_print_mean;
2525 if( lsmash_check_box_type_identical( box->type, ISOM_BOX_TYPE_NAME ) )
2526 return isom_print_name;
2528 if( lsmash_check_box_type_identical( box->type, ISOM_BOX_TYPE_DATA ) )
2529 return isom_print_data;
2532 if( lsmash_check_box_type_identical( parent->type, ISOM_BOX_TYPE_ILST )
2533 || lsmash_check_box_type_identical( parent->type, QT_BOX_TYPE_ILST ) )
2534 return isom_print_metaitem;
2536 static struct print_box_table_tag
2538 lsmash_box_type_t type;
2539 isom_print_box_t func;
2540 } print_box_table[128] = { { LSMASH_BOX_TYPE_INITIALIZER, NULL } };
2541 if( !print_box_table[0].func )
2543 /* Initialize the table. */
2544 int i = 0;
2545 #define ADD_PRINT_BOX_TABLE_ELEMENT( type, func ) print_box_table[i++] = (struct print_box_table_tag){ type, func }
2546 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_FTYP, isom_print_ftyp );
2547 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_STYP, isom_print_styp );
2548 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_SIDX, isom_print_sidx );
2549 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_MOOV, isom_print_moov );
2550 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_MVHD, isom_print_mvhd );
2551 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_IODS, isom_print_iods );
2552 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_CTAB, isom_print_ctab );
2553 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_TRAK, isom_print_trak );
2554 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_TKHD, isom_print_tkhd );
2555 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_TAPT, isom_print_tapt );
2556 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_CLEF, isom_print_clef );
2557 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_PROF, isom_print_prof );
2558 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_ENOF, isom_print_enof );
2559 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_EDTS, isom_print_edts );
2560 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_ELST, isom_print_elst );
2561 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_TREF, isom_print_tref );
2562 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_MDIA, isom_print_mdia );
2563 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_MDHD, isom_print_mdhd );
2564 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_HDLR, isom_print_hdlr );
2565 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_MINF, isom_print_minf );
2566 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_VMHD, isom_print_vmhd );
2567 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_SMHD, isom_print_smhd );
2568 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_HMHD, isom_print_hmhd );
2569 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_NMHD, isom_print_nmhd );
2570 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_GMHD, isom_print_gmhd );
2571 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_GMIN, isom_print_gmin );
2572 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_TEXT, isom_print_text );
2573 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_DINF, isom_print_dinf );
2574 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_DREF, isom_print_dref );
2575 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_URL, isom_print_url );
2576 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_STBL, isom_print_stbl );
2577 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_STSD, isom_print_stsd );
2578 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_CLAP, isom_print_clap );
2579 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_PASP, isom_print_pasp );
2580 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_COLR, isom_print_colr );
2581 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_COLR, isom_print_colr );
2582 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_GLBL, isom_print_glbl );
2583 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_GAMA, isom_print_gama );
2584 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_FIEL, isom_print_fiel );
2585 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_CSPC, isom_print_cspc );
2586 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_SGBT, isom_print_sgbt );
2587 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_STSL, isom_print_stsl );
2588 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_WAVE, isom_print_wave );
2589 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_CHAN, isom_print_chan );
2590 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_SRAT, isom_print_srat );
2591 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_FTAB, isom_print_ftab );
2592 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_STTS, isom_print_stts );
2593 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_CTTS, isom_print_ctts );
2594 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_CSLG, isom_print_cslg );
2595 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_STSS, isom_print_stss );
2596 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_STPS, isom_print_stps );
2597 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_SDTP, isom_print_sdtp );
2598 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_STSC, isom_print_stsc );
2599 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_STSZ, isom_print_stsz );
2600 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_STCO, isom_print_stco );
2601 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_CO64, isom_print_stco );
2602 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_SGPD, isom_print_sgpd );
2603 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_SBGP, isom_print_sbgp );
2604 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_UDTA, isom_print_udta );
2605 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_CHPL, isom_print_chpl );
2606 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_WLOC, isom_print_WLOC );
2607 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_LOOP, isom_print_LOOP );
2608 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_SELO, isom_print_SelO );
2609 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_ALLF, isom_print_AllF );
2610 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_CPRT, isom_print_cprt );
2611 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_MVEX, isom_print_mvex );
2612 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_MEHD, isom_print_mehd );
2613 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_TREX, isom_print_trex );
2614 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_MOOF, isom_print_moof );
2615 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_MFHD, isom_print_mfhd );
2616 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_TRAF, isom_print_traf );
2617 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_TFHD, isom_print_tfhd );
2618 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_TFDT, isom_print_tfdt );
2619 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_TRUN, isom_print_trun );
2620 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_FREE, isom_print_free );
2621 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_SKIP, isom_print_free );
2622 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_MDAT, isom_print_mdat );
2623 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_KEYS, isom_print_keys );
2624 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_META, isom_print_meta );
2625 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_ILST, isom_print_ilst );
2626 ADD_PRINT_BOX_TABLE_ELEMENT( QT_BOX_TYPE_ILST, isom_print_ilst );
2627 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_MFRA, isom_print_mfra );
2628 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_TFRA, isom_print_tfra );
2629 ADD_PRINT_BOX_TABLE_ELEMENT( ISOM_BOX_TYPE_MFRO, isom_print_mfro );
2630 ADD_PRINT_BOX_TABLE_ELEMENT( LSMASH_BOX_TYPE_UNSPECIFIED, NULL );
2631 #undef ADD_PRINT_BOX_TABLE_ELEMENT
2633 for( int i = 0; print_box_table[i].func; i++ )
2634 if( lsmash_check_box_type_identical( box->type, print_box_table[i].type ) )
2635 return print_box_table[i].func;
2636 return isom_print_unknown;
2639 static inline void isom_print_remove_plastic_box( isom_box_t *box )
2641 if( box->manager & LSMASH_ABSENT_IN_FILE )
2642 /* free flagged box */
2643 isom_remove_box_by_itself( box );
2646 int isom_add_print_func( lsmash_file_t *file, void *box, int level )
2648 if( !(file->flags & LSMASH_FILE_MODE_DUMP) )
2650 isom_print_remove_plastic_box( box );
2651 return 0;
2653 isom_print_entry_t *data = lsmash_malloc( sizeof(isom_print_entry_t) );
2654 if( !data )
2656 isom_print_remove_plastic_box( box );
2657 return LSMASH_ERR_MEMORY_ALLOC;
2659 data->level = level;
2660 data->box = (isom_box_t *)box;
2661 data->func = isom_select_print_func( (isom_box_t *)box );
2662 assert( data->func );
2663 if( lsmash_add_entry( file->print, data ) < 0 )
2665 isom_print_remove_plastic_box( data->box );
2666 lsmash_free( data );
2667 return LSMASH_ERR_MEMORY_ALLOC;
2669 return 0;
2672 static void isom_remove_print_func( isom_print_entry_t *data )
2674 if( !data || !data->box )
2675 return;
2676 isom_print_remove_plastic_box( data->box );
2677 lsmash_free( data );
2680 void isom_remove_print_funcs( lsmash_file_t *file )
2682 lsmash_remove_list( file->print, isom_remove_print_func );
2683 file->print = NULL;
2686 #endif /* LSMASH_DEMUXER_ENABLED */