H.264 importer: Fix a memory leak introduced by the previous commit.
[L-SMASH.git] / cli / boxdumper.c
blob3a9901b4d68c142a45c2d2237b9e9a56b947eb81
1 /*****************************************************************************
2 * boxdumper.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 #include <stdio.h>
24 #include <string.h>
25 #include <strings.h>
26 #include <stdlib.h>
27 #include <inttypes.h>
28 #ifdef _WIN32
29 #include <io.h>
30 #include <fcntl.h>
31 #endif
33 #include "lsmash.h"
34 #include "cli.h"
36 #include "config.h"
38 #define eprintf( ... ) fprintf( stderr, __VA_ARGS__ )
40 static void display_version( void )
42 eprintf( "\n"
43 "L-SMASH isom/mov structual analyzer rev%s %s\n"
44 "Built on %s %s\n"
45 "Copyright (C) 2010-2014 L-SMASH project\n",
46 LSMASH_REV, LSMASH_GIT_HASH, __DATE__, __TIME__ );
49 static void display_help( void )
51 display_version();
52 eprintf( "\n"
53 "Usage: boxdumper [option] input\n"
54 " options:\n"
55 " --help Display help\n"
56 " --version Display version information\n"
57 " --box Dump box structure\n"
58 " --chapter Extract chapter list\n"
59 " --timestamp Dump media timestamps\n" );
62 static int boxdumper_error
64 lsmash_root_t *root,
65 lsmash_file_parameters_t *file_param,
66 const char *message
69 lsmash_close_file( file_param );
70 lsmash_destroy_root( root );
71 eprintf( "%s", message );
72 return -1;
75 #define BOXDUMPER_ERR( message ) boxdumper_error( root, &file_param, message )
76 #define DO_NOTHING
78 int main( int argc, char *argv[] )
80 if ( argc < 2 )
82 display_help();
83 return -1;
85 else if( !strcasecmp( argv[1], "-h" ) || !strcasecmp( argv[1], "--help" ) )
87 display_help();
88 return 0;
90 else if( !strcasecmp( argv[1], "-v" ) || !strcasecmp( argv[1], "--version" ) )
92 display_version();
93 return 0;
95 int dump_box = 1;
96 int chapter = 0;
97 char *filename;
98 lsmash_get_mainargs( &argc, &argv );
99 if( argc > 2 )
101 if( !strcasecmp( argv[1], "--box" ) )
102 DO_NOTHING;
103 else if( !strcasecmp( argv[1], "--chapter" ) )
104 chapter = 1;
105 else if( !strcasecmp( argv[1], "--timestamp" ) )
106 dump_box = 0;
107 else
109 display_help();
110 return -1;
112 filename = argv[2];
114 else
116 filename = argv[1];
118 #ifdef _WIN32
119 _setmode( _fileno(stdin), _O_BINARY );
120 #endif
121 /* Open the input file. */
122 lsmash_root_t *root = lsmash_create_root();
123 if( !root )
125 fprintf( stderr, "Failed to create a ROOT.\n" );
126 return -1;
128 lsmash_file_parameters_t file_param = { 0 };
129 if( lsmash_open_file( filename, 1, &file_param ) < 0 )
130 return BOXDUMPER_ERR( "Failed to open an input file.\n" );
131 if( dump_box )
132 file_param.mode |= LSMASH_FILE_MODE_DUMP;
133 lsmash_file_t *file = lsmash_set_file( root, &file_param );
134 if( !file )
135 return BOXDUMPER_ERR( "Failed to add a file into a ROOT.\n" );
136 if( lsmash_read_file( file, &file_param ) < 0 )
137 return BOXDUMPER_ERR( "Failed to read a file\n" );
138 /* Dump the input file. */
139 if( chapter )
141 if( lsmash_print_chapter_list( root ) )
142 return BOXDUMPER_ERR( "Failed to extract chapter.\n" );
144 else if( dump_box )
146 if( lsmash_print_movie( root, "-" ) )
147 return BOXDUMPER_ERR( "Failed to dump box structure.\n" );
149 else
151 lsmash_movie_parameters_t movie_param;
152 lsmash_initialize_movie_parameters( &movie_param );
153 lsmash_get_movie_parameters( root, &movie_param );
154 uint32_t num_tracks = movie_param.number_of_tracks;
155 for( uint32_t track_number = 1; track_number <= num_tracks; track_number++ )
157 uint32_t track_ID = lsmash_get_track_ID( root, track_number );
158 if( !track_ID )
159 return BOXDUMPER_ERR( "Failed to get track_ID.\n" );
160 lsmash_media_parameters_t media_param;
161 lsmash_initialize_media_parameters( &media_param );
162 if( lsmash_get_media_parameters( root, track_ID, &media_param ) )
163 return BOXDUMPER_ERR( "Failed to get media parameters.\n" );
164 if( lsmash_construct_timeline( root, track_ID ) )
165 return BOXDUMPER_ERR( "Failed to construct timeline.\n" );
166 uint32_t timeline_shift;
167 if( lsmash_get_composition_to_decode_shift_from_media_timeline( root, track_ID, &timeline_shift ) )
168 return BOXDUMPER_ERR( "Failed to get timestamps.\n" );
169 lsmash_media_ts_list_t ts_list;
170 if( lsmash_get_media_timestamps( root, track_ID, &ts_list ) )
171 return BOXDUMPER_ERR( "Failed to get timestamps.\n" );
172 fprintf( stdout, "track_ID: %"PRIu32"\n", track_ID );
173 fprintf( stdout, "Media timescale: %"PRIu32"\n", media_param.timescale );
174 lsmash_media_ts_t *ts_array = ts_list.timestamp;
175 if( !ts_array )
177 fprintf( stdout, "\n" );
178 continue;
180 for( uint32_t i = 0; i < ts_list.sample_count; i++ )
181 fprintf( stdout, "DTS = %"PRIu64", CTS = %"PRIu64"\n", ts_array[i].dts, ts_array[i].cts + timeline_shift );
182 lsmash_free( ts_array );
183 fprintf( stdout, "\n" );
186 lsmash_destroy_root( root );
187 return 0;