1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2010-2015 L-SMASH project
6 * Authors: Takashi Hirata <silverfilain@gmail.com>
7 * Contributors: Yusuke Nakamura <muken.the.vfrmaniac@gmail.com>
9 * Permission to use, copy, modify, and/or distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 *****************************************************************************/
22 /* This file is available under an ISC license. */
24 #include "common/internal.h" /* must be placed first */
28 #define LSMASH_IMPORTER_INTERNAL
31 /***************************************************************************
33 ***************************************************************************/
34 static const lsmash_class_t lsmash_importer_class
=
37 offsetof( importer_t
, log_level
)
40 extern const importer_functions mp4sys_adts_importer
;
41 extern const importer_functions mp4sys_mp3_importer
;
42 extern const importer_functions amr_importer
;
43 extern const importer_functions ac3_importer
;
44 extern const importer_functions eac3_importer
;
45 extern const importer_functions mp4a_als_importer
;
46 extern const importer_functions dts_importer
;
47 extern const importer_functions wave_importer
;
48 extern const importer_functions h264_importer
;
49 extern const importer_functions hevc_importer
;
50 extern const importer_functions vc1_importer
;
51 extern const importer_functions isobm_importer
;
53 /******** importer listing table ********/
54 static const importer_functions
*importer_func_table
[] =
56 &mp4sys_adts_importer
,
71 /***************************************************************************
72 importer public interfaces
73 ***************************************************************************/
75 /******** importer public functions ********/
76 importer_t
*lsmash_importer_alloc( void )
78 importer_t
*importer
= (importer_t
*)lsmash_malloc_zero( sizeof(importer_t
) );
81 importer
->root
= lsmash_create_root();
84 lsmash_free( importer
);
87 importer
->summaries
= lsmash_create_entry_list();
88 if( !importer
->summaries
)
90 lsmash_destroy_root( importer
->root
);
91 lsmash_free( importer
);
94 importer
->class = &lsmash_importer_class
;
98 void lsmash_importer_destroy( importer_t
*importer
)
102 if( importer
->funcs
.cleanup
)
103 importer
->funcs
.cleanup( importer
);
104 lsmash_remove_list( importer
->summaries
, lsmash_cleanup_summary
);
105 if( importer
->root
&& importer
->root
!= importer
->file
->root
)
106 importer
->root
->file
= NULL
; /* not internally opened file */
107 lsmash_destroy_root( importer
->root
);
108 lsmash_free( importer
);
111 int lsmash_importer_set_file( importer_t
*importer
, lsmash_file_t
*file
)
113 if( !importer
|| !file
|| !file
->bs
)
114 return LSMASH_ERR_NAMELESS
;
115 importer
->root
->file
= file
;
116 importer
->file
= file
;
117 importer
->bs
= file
->bs
;
121 void lsmash_importer_close( importer_t
*importer
)
125 if( !importer
->is_stdin
)
126 lsmash_close_file( &importer
->file_param
);
127 lsmash_importer_destroy( importer
);
130 int lsmash_importer_find( importer_t
*importer
, const char *format
, int auto_detect
)
132 importer
->log_level
= LSMASH_LOG_QUIET
; /* Any error log is confusing for the probe step. */
133 const importer_functions
*funcs
;
134 int err
= LSMASH_ERR_NAMELESS
;
137 /* just rely on detector. */
138 for( int i
= 0; (funcs
= importer_func_table
[i
]) != NULL
; i
++ )
140 importer
->class = &funcs
->class;
141 if( !funcs
->detectable
)
143 if( (err
= funcs
->probe( importer
)) == 0
144 || lsmash_bs_read_seek( importer
->bs
, 0, SEEK_SET
) != 0 )
150 /* needs name matching. */
151 for( int i
= 0; (funcs
= importer_func_table
[i
]) != NULL
; i
++ )
153 importer
->class = &funcs
->class;
154 if( strcmp( importer
->class->name
, format
) )
156 if( (err
= funcs
->probe( importer
)) < 0 )
161 importer
->log_level
= LSMASH_LOG_INFO
;
164 importer
->class = &lsmash_importer_class
;
165 lsmash_log( importer
, LSMASH_LOG_ERROR
, "failed to find the matched importer.\n" );
168 importer
->funcs
= *funcs
;
172 importer_t
*lsmash_importer_open( const char *identifier
, const char *format
)
174 if( identifier
== NULL
)
176 int auto_detect
= (format
== NULL
|| !strcmp( format
, "auto" ));
177 importer_t
*importer
= lsmash_importer_alloc();
180 /* Open an input 'stream'. */
181 if( !strcmp( identifier
, "-" ) )
183 /* special treatment for stdin */
186 lsmash_log( importer
, LSMASH_LOG_ERROR
, "auto importer detection on stdin is not supported.\n" );
189 importer
->is_stdin
= 1;
191 if( lsmash_open_file( identifier
, 1, &importer
->file_param
) < 0 )
193 lsmash_log( importer
, LSMASH_LOG_ERROR
, "failed to open %s.\n", identifier
);
196 lsmash_file_t
*file
= lsmash_set_file( importer
->root
, &importer
->file_param
);
199 lsmash_log( importer
, LSMASH_LOG_ERROR
, "failed to set opened file.\n" );
202 lsmash_importer_set_file( importer
, file
);
203 if( lsmash_importer_find( importer
, format
, auto_detect
) < 0 )
207 lsmash_importer_close( importer
);
211 /* 0 if success, positive if changed, negative if failed */
212 int lsmash_importer_get_access_unit( importer_t
*importer
, uint32_t track_number
, lsmash_sample_t
**p_sample
)
214 if( !importer
|| !p_sample
)
215 return LSMASH_ERR_FUNCTION_PARAM
;
216 if( !importer
->funcs
.get_accessunit
)
217 return LSMASH_ERR_NAMELESS
;
219 return importer
->funcs
.get_accessunit( importer
, track_number
, p_sample
);
222 /* Return 0 if failed, otherwise succeeded. */
223 uint32_t lsmash_importer_get_last_delta( importer_t
*importer
, uint32_t track_number
)
225 if( !importer
|| !importer
->funcs
.get_last_delta
)
227 return importer
->funcs
.get_last_delta( importer
, track_number
);
230 int lsmash_importer_construct_timeline( importer_t
*importer
, uint32_t track_number
)
233 return LSMASH_ERR_FUNCTION_PARAM
;
234 if( !importer
->funcs
.construct_timeline
)
235 return LSMASH_ERR_PATCH_WELCOME
;
236 return importer
->funcs
.construct_timeline( importer
, track_number
);
239 uint32_t lsmash_importer_get_track_count( importer_t
*importer
)
241 if( !importer
|| !importer
->summaries
)
243 return importer
->summaries
->entry_count
;
246 lsmash_summary_t
*lsmash_duplicate_summary( importer_t
*importer
, uint32_t track_number
)
250 lsmash_summary_t
*src_summary
= lsmash_get_entry_data( importer
->summaries
, track_number
);
253 lsmash_summary_t
*summary
= lsmash_create_summary( src_summary
->summary_type
);
256 lsmash_codec_specific_list_t
*opaque
= summary
->opaque
;
257 switch( src_summary
->summary_type
)
259 case LSMASH_SUMMARY_TYPE_VIDEO
:
260 *(lsmash_video_summary_t
*)summary
= *(lsmash_video_summary_t
*)src_summary
;
262 case LSMASH_SUMMARY_TYPE_AUDIO
:
263 *(lsmash_audio_summary_t
*)summary
= *(lsmash_audio_summary_t
*)src_summary
;
266 lsmash_cleanup_summary( summary
);
269 summary
->opaque
= opaque
;
270 for( lsmash_entry_t
*entry
= src_summary
->opaque
->list
.head
; entry
; entry
= entry
->next
)
272 lsmash_codec_specific_t
*src_specific
= (lsmash_codec_specific_t
*)entry
->data
;
275 lsmash_codec_specific_t
*dup
= isom_duplicate_codec_specific_data( src_specific
);
276 if( lsmash_add_entry( &summary
->opaque
->list
, dup
) < 0 )
278 lsmash_cleanup_summary( (lsmash_summary_t
*)summary
);
279 lsmash_destroy_codec_specific_data( dup
);
286 int lsmash_importer_make_fake_movie( importer_t
*importer
)
288 if( !importer
|| !importer
->file
|| (importer
->file
->flags
& LSMASH_FILE_MODE_BOX
) )
289 return LSMASH_ERR_FUNCTION_PARAM
;
290 if( !isom_movie_create( importer
->file
) )
291 return LSMASH_ERR_NAMELESS
;
295 int lsmash_importer_make_fake_track( importer_t
*importer
, lsmash_media_type media_type
, uint32_t *track_ID
)
297 if( !importer
|| !importer
->file
|| (importer
->file
->flags
& LSMASH_FILE_MODE_BOX
) || !track_ID
)
298 return LSMASH_ERR_FUNCTION_PARAM
;
299 isom_trak_t
*trak
= isom_track_create( importer
->file
, media_type
);
303 || trak
->tkhd
->track_ID
== 0
305 || !trak
->mdia
->minf
)
307 err
= LSMASH_ERR_NAMELESS
;
310 if( (err
= isom_complement_data_reference( trak
->mdia
->minf
)) < 0 )
312 *track_ID
= trak
->tkhd
->track_ID
;
315 isom_remove_box_by_itself( trak
);
319 void lsmash_importer_break_fake_movie( importer_t
*importer
)
321 if( !importer
|| !importer
->file
)
323 isom_remove_box_by_itself( importer
->file
->moov
);