vc1: Evaluate return value properly.
[L-SMASH.git] / cli / importer.c
blobf1ed1d916fef3d65b913d1b63e4b4649d5619752
1 /*****************************************************************************
2 * importer.c
3 *****************************************************************************
4 * Copyright (C) 2010-2014 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 */
26 #include <string.h>
28 #define LSMASH_IMPORTER_INTERNAL
29 #include "importer.h"
31 /***************************************************************************
32 importer classes
33 ***************************************************************************/
34 static const lsmash_class_t lsmash_importer_class =
36 "importer",
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 h264_importer;
48 extern const importer_functions hevc_importer;
49 extern const importer_functions vc1_importer;
51 /******** importer listing table ********/
52 static const importer_functions *importer_func_table[] =
54 &mp4sys_adts_importer,
55 &mp4sys_mp3_importer,
56 &amr_importer,
57 &ac3_importer,
58 &eac3_importer,
59 &mp4a_als_importer,
60 &dts_importer,
61 &h264_importer,
62 &hevc_importer,
63 &vc1_importer,
64 NULL,
67 /***************************************************************************
68 importer public interfaces
69 ***************************************************************************/
71 /******** importer public functions ********/
73 void lsmash_importer_close( importer_t *importer )
75 if( !importer )
76 return;
77 if( !importer->is_stdin && importer->stream )
78 fclose( importer->stream );
79 if( importer->funcs.cleanup )
80 importer->funcs.cleanup( importer );
81 lsmash_remove_list( importer->summaries, lsmash_cleanup_summary );
82 lsmash_free( importer );
85 importer_t *lsmash_importer_open( const char *identifier, const char *format )
87 if( identifier == NULL )
88 return NULL;
89 int auto_detect = ( format == NULL || !strcmp( format, "auto" ) );
90 importer_t *importer = (importer_t *)lsmash_malloc_zero( sizeof(importer_t) );
91 if( !importer )
92 return NULL;
93 importer->class = &lsmash_importer_class;
94 if( !strcmp( identifier, "-" ) )
96 /* special treatment for stdin */
97 if( auto_detect )
99 lsmash_log( importer, LSMASH_LOG_ERROR, "auto importer detection on stdin is not supported.\n" );
100 goto fail;
102 importer->stream = stdin;
103 importer->is_stdin = 1;
105 else if( (importer->stream = lsmash_fopen( identifier, "rb" )) == NULL )
107 lsmash_log( importer, LSMASH_LOG_ERROR, "failed to open %s.\n", identifier );
108 goto fail;
110 importer->summaries = lsmash_create_entry_list();
111 if( !importer->summaries )
113 lsmash_log( importer, LSMASH_LOG_ERROR, "failed to set up the importer.\n" );
114 goto fail;
116 /* find importer */
117 importer->log_level = LSMASH_LOG_QUIET; /* Any error log is confusing for the probe step. */
118 const importer_functions *funcs;
119 if( auto_detect )
121 /* just rely on detector. */
122 for( int i = 0; (funcs = importer_func_table[i]) != NULL; i++ )
124 importer->class = &funcs->class;
125 if( !funcs->detectable )
126 continue;
127 if( !funcs->probe( importer ) || lsmash_fseek( importer->stream, 0, SEEK_SET ) )
128 break;
131 else
133 /* needs name matching. */
134 for( int i = 0; (funcs = importer_func_table[i]) != NULL; i++ )
136 importer->class = &funcs->class;
137 if( strcmp( importer->class->name, format ) )
138 continue;
139 if( funcs->probe( importer ) )
140 funcs = NULL;
141 break;
144 importer->log_level = LSMASH_LOG_INFO;
145 if( !funcs )
147 importer->class = &lsmash_importer_class;
148 lsmash_log( importer, LSMASH_LOG_ERROR, "failed to find the matched importer.\n" );
149 goto fail;
151 importer->funcs = *funcs;
152 return importer;
153 fail:
154 lsmash_importer_close( importer );
155 return NULL;
158 /* 0 if success, positive if changed, negative if failed */
159 int lsmash_importer_get_access_unit( importer_t *importer, uint32_t track_number, lsmash_sample_t *buffered_sample )
161 if( !importer || !importer->funcs.get_accessunit || !buffered_sample->data || buffered_sample->length == 0 )
162 return -1;
163 return importer->funcs.get_accessunit( importer, track_number, buffered_sample );
166 /* Return 0 if failed, otherwise succeeded. */
167 uint32_t lsmash_importer_get_last_delta( importer_t *importer, uint32_t track_number )
169 if( !importer || !importer->funcs.get_last_delta )
170 return 0;
171 return importer->funcs.get_last_delta( importer, track_number );
174 uint32_t lsmash_importer_get_track_count( importer_t *importer )
176 if( !importer || !importer->summaries )
177 return 0;
178 return importer->summaries->entry_count;
181 lsmash_summary_t *lsmash_duplicate_summary( importer_t *importer, uint32_t track_number )
183 if( !importer )
184 return NULL;
185 lsmash_summary_t *src_summary = lsmash_get_entry_data( importer->summaries, track_number );
186 if( !src_summary )
187 return NULL;
188 lsmash_summary_t *summary = lsmash_create_summary( src_summary->summary_type );
189 if( !summary )
190 return NULL;
191 lsmash_codec_specific_list_t *opaque = summary->opaque;
192 switch( src_summary->summary_type )
194 case LSMASH_SUMMARY_TYPE_VIDEO :
195 *(lsmash_video_summary_t *)summary = *(lsmash_video_summary_t *)src_summary;
196 break;
197 case LSMASH_SUMMARY_TYPE_AUDIO :
198 *(lsmash_audio_summary_t *)summary = *(lsmash_audio_summary_t *)src_summary;
199 break;
200 default :
201 lsmash_cleanup_summary( summary );
202 return NULL;
204 summary->opaque = opaque;
205 for( lsmash_entry_t *entry = src_summary->opaque->list.head; entry; entry = entry->next )
207 lsmash_codec_specific_t *src_specific = (lsmash_codec_specific_t *)entry->data;
208 if( !src_specific )
209 continue;
210 lsmash_codec_specific_t *dup = isom_duplicate_codec_specific_data( src_specific );
211 if( lsmash_add_entry( &summary->opaque->list, dup ) )
213 lsmash_cleanup_summary( (lsmash_summary_t *)summary );
214 lsmash_destroy_codec_specific_data( dup );
215 return NULL;
218 return summary;