2 * factory.c -- the factory method interfaces
3 * Copyright (C) 2003-2012 Ushodaya Enterprises Limited
4 * Author: Charles Yates <charles.yates@pandora.be>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <framework/mlt.h>
28 extern mlt_consumer consumer_avformat_init( mlt_profile profile, char *file );
29 extern mlt_filter filter_avcolour_space_init( void *arg );
30 extern mlt_filter filter_avdeinterlace_init( void *arg );
31 extern mlt_filter filter_avresample_init( char *arg );
32 extern mlt_filter filter_swscale_init( mlt_profile profile, char *arg );
33 extern mlt_producer producer_avformat_init( mlt_profile profile, const char *service, char *file );
35 // ffmpeg Header files
36 #include <libavformat/avformat.h>
38 #include <libavdevice/avdevice.h>
40 #if LIBAVCODEC_VERSION_MAJOR >= 53
41 #include <libavutil/opt.h>
43 #include <libavcodec/opt.h>
46 // A static flag used to determine if avformat has been initialised
47 static int avformat_initialised = 0;
49 static int avformat_lockmgr(void **mutex, enum AVLockOp op)
51 pthread_mutex_t** pmutex = (pthread_mutex_t**) mutex;
56 *pmutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t));
57 pthread_mutex_init(*pmutex, NULL);
60 pthread_mutex_lock(*pmutex);
63 pthread_mutex_unlock(*pmutex);
66 pthread_mutex_destroy(*pmutex);
74 static void avformat_init( )
76 // Initialise avformat if necessary
77 if ( avformat_initialised == 0 )
79 avformat_initialised = 1;
80 av_lockmgr_register( &avformat_lockmgr );
83 avdevice_register_all();
85 #if LIBAVFORMAT_VERSION_INT >= ((53<<16)+(13<<8))
86 avformat_network_init();
88 av_log_set_level( mlt_log_get_level() );
92 static void *create_service( mlt_profile profile, mlt_service_type type, const char *id, void *arg )
96 if ( !strncmp( id, "avformat", 8 ) )
98 if ( type == producer_type )
99 return producer_avformat_init( profile, id, arg );
100 else if ( type == consumer_type )
101 return consumer_avformat_init( profile, arg );
105 if ( !strcmp( id, "avcolor_space" ) )
106 return filter_avcolour_space_init( arg );
107 if ( !strcmp( id, "avcolour_space" ) )
108 return filter_avcolour_space_init( arg );
109 if ( !strcmp( id, "avdeinterlace" ) )
110 return filter_avdeinterlace_init( arg );
111 if ( !strcmp( id, "avresample" ) )
112 return filter_avresample_init( arg );
114 if ( !strcmp( id, "swscale" ) )
115 return filter_swscale_init( profile, arg );
121 static void add_parameters( mlt_properties params, void *object, int req_flags, const char *unit, const char *subclass )
123 const AVOption *opt = NULL;
125 // For each AVOption on the AVClass object
126 #if LIBAVUTIL_VERSION_INT >= ((51<<16)+(12<<8)+0)
127 while ( ( opt = av_opt_next( object, opt ) ) )
129 while ( ( opt = av_next_option( object, opt ) ) )
132 // If matches flags and not a binary option (not supported by Mlt)
133 if ( !( opt->flags & req_flags ) || ( opt->type == FF_OPT_TYPE_BINARY ) )
136 // Ignore constants (keyword values)
137 if ( !unit && opt->type == FF_OPT_TYPE_CONST )
139 // When processing a groups of options (unit)...
140 // ...ignore non-constants
141 else if ( unit && opt->type != FF_OPT_TYPE_CONST )
143 // ...ignore constants not in this group
144 else if ( unit && opt->type == FF_OPT_TYPE_CONST && strcmp( unit, opt->unit ) )
146 // ..add constants to the 'values' sequence
147 else if ( unit && opt->type == FF_OPT_TYPE_CONST )
150 snprintf( key, 20, "%d", mlt_properties_count( params ) );
151 mlt_properties_set( params, key, opt->name );
155 // Create a map for this option.
156 mlt_properties p = mlt_properties_new();
158 snprintf( key, 20, "%d", mlt_properties_count( params ) );
159 // Add the map to the 'parameters' sequence.
160 mlt_properties_set_data( params, key, p, 0, (mlt_destructor) mlt_properties_close, NULL );
162 // Add the parameter metadata for this AVOption.
163 mlt_properties_set( p, "identifier", opt->name );
168 char *s = malloc( strlen( opt->help ) + strlen( subclass ) + 4 );
169 strcpy( s, opt->help );
171 strcat( s, subclass );
173 mlt_properties_set( p, "description", s );
177 mlt_properties_set( p, "description", opt->help );
182 case FF_OPT_TYPE_FLAGS:
183 mlt_properties_set( p, "type", "string" );
184 mlt_properties_set( p, "format", "flags" );
186 case FF_OPT_TYPE_INT:
189 mlt_properties_set( p, "type", "integer" );
190 if ( opt->min != INT_MIN )
191 mlt_properties_set_int( p, "minimum", (int) opt->min );
192 if ( opt->max != INT_MAX )
193 mlt_properties_set_int( p, "maximum", (int) opt->max );
194 #if LIBAVUTIL_VERSION_MAJOR > 50
195 mlt_properties_set_int( p, "default", (int) opt->default_val.dbl );
200 mlt_properties_set( p, "type", "string" );
201 mlt_properties_set( p, "format", "integer or keyword" );
204 case FF_OPT_TYPE_INT64:
205 mlt_properties_set( p, "type", "integer" );
206 mlt_properties_set( p, "format", "64-bit" );
207 if ( opt->min != INT64_MIN )
208 mlt_properties_set_int64( p, "minimum", (int64_t) opt->min );
209 if ( opt->max != INT64_MAX )
210 mlt_properties_set_int64( p, "maximum", (int64_t) opt->max );
211 #if LIBAVUTIL_VERSION_MAJOR > 50
212 mlt_properties_set_int64( p, "default", (int64_t) opt->default_val.dbl );
215 case FF_OPT_TYPE_FLOAT:
216 mlt_properties_set( p, "type", "float" );
217 if ( opt->min != FLT_MIN && opt->min != -340282346638528859811704183484516925440.0 )
218 mlt_properties_set_double( p, "minimum", opt->min );
219 if ( opt->max != FLT_MAX )
220 mlt_properties_set_double( p, "maximum", opt->max );
221 #if LIBAVUTIL_VERSION_MAJOR > 50
222 mlt_properties_set_double( p, "default", opt->default_val.dbl );
225 case FF_OPT_TYPE_DOUBLE:
226 mlt_properties_set( p, "type", "float" );
227 mlt_properties_set( p, "format", "double" );
228 if ( opt->min != DBL_MIN )
229 mlt_properties_set_double( p, "minimum", opt->min );
230 if ( opt->max != DBL_MAX )
231 mlt_properties_set_double( p, "maximum", opt->max );
232 #if LIBAVUTIL_VERSION_MAJOR > 50
233 mlt_properties_set_double( p, "default", opt->default_val.dbl );
236 case FF_OPT_TYPE_STRING:
237 mlt_properties_set( p, "type", "string" );
238 #if LIBAVUTIL_VERSION_MAJOR > 50
239 mlt_properties_set( p, "default", opt->default_val.str );
242 case FF_OPT_TYPE_RATIONAL:
243 mlt_properties_set( p, "type", "string" );
244 mlt_properties_set( p, "format", "numerator:denominator" );
246 case FF_OPT_TYPE_CONST:
248 mlt_properties_set( p, "type", "integer" );
249 mlt_properties_set( p, "format", "constant" );
252 // If the option belongs to a group (unit) and is not a constant (keyword value)
253 if ( opt->unit && opt->type != FF_OPT_TYPE_CONST )
255 // Create a 'values' sequence.
256 mlt_properties values = mlt_properties_new();
258 // Recurse to add constants in this group to the 'values' sequence.
259 add_parameters( values, object, req_flags, opt->unit, NULL );
260 if ( mlt_properties_count( values ) )
261 mlt_properties_set_data( p, "values", values, 0, (mlt_destructor) mlt_properties_close, NULL );
263 mlt_properties_close( values );
268 static mlt_properties avformat_metadata( mlt_service_type type, const char *id, void *data )
270 char file[ PATH_MAX ];
271 const char *service_type = NULL;
272 mlt_properties result = NULL;
274 // Convert the service type to a string.
278 service_type = "consumer";
281 service_type = "filter";
284 service_type = "producer";
286 case transition_type:
287 service_type = "transition";
292 // Load the yaml file
293 snprintf( file, PATH_MAX, "%s/avformat/%s_%s.yml", mlt_environment( "MLT_DATA" ), service_type, id );
294 result = mlt_properties_parse_yaml( file );
295 if ( result && ( type == consumer_type || type == producer_type ) )
297 // Annotate the yaml properties with AVOptions.
298 mlt_properties params = (mlt_properties) mlt_properties_get_data( result, "parameters", NULL );
299 AVFormatContext *avformat = avformat_alloc_context();
300 #if LIBAVCODEC_VERSION_INT > ((53<<16)+(8<<8)+0)
301 AVCodecContext *avcodec = avcodec_alloc_context3( NULL );
303 AVCodecContext *avcodec = avcodec_alloc_context();
305 int flags = ( type == consumer_type )? AV_OPT_FLAG_ENCODING_PARAM : AV_OPT_FLAG_DECODING_PARAM;
307 add_parameters( params, avformat, flags, NULL, NULL );
308 #if LIBAVFORMAT_VERSION_MAJOR >= 53
310 if ( type == producer_type )
312 AVInputFormat *f = NULL;
313 while ( ( f = av_iformat_next( f ) ) )
315 add_parameters( params, &f->priv_class, flags, NULL, f->name );
319 AVOutputFormat *f = NULL;
320 while ( ( f = av_oformat_next( f ) ) )
322 add_parameters( params, &f->priv_class, flags, NULL, f->name );
326 add_parameters( params, avcodec, flags, NULL, NULL );
327 #if LIBAVCODEC_VERSION_MAJOR >= 53
329 while ( ( c = av_codec_next( c ) ) )
331 add_parameters( params, &c->priv_class, flags, NULL, c->name );
343 MLT_REGISTER( consumer_type, "avformat", create_service );
344 MLT_REGISTER( producer_type, "avformat", create_service );
345 MLT_REGISTER( producer_type, "avformat-novalidate", create_service );
346 MLT_REGISTER_METADATA( consumer_type, "avformat", avformat_metadata, NULL );
347 MLT_REGISTER_METADATA( producer_type, "avformat", avformat_metadata, NULL );
350 MLT_REGISTER( filter_type, "avcolour_space", create_service );
351 MLT_REGISTER( filter_type, "avcolor_space", create_service );
352 MLT_REGISTER( filter_type, "avdeinterlace", create_service );
353 MLT_REGISTER( filter_type, "avresample", create_service );
355 MLT_REGISTER( filter_type, "swscale", create_service );