]> git.sesse.net Git - mlt/blob - src/modules/avformat/factory.c
Detect video codecs that use the new libavcodec "encode2" method.
[mlt] / src / modules / avformat / factory.c
1 /*
2  * factory.c -- the factory method interfaces
3  * Copyright (C) 2003-2012 Ushodaya Enterprises Limited
4  * Author: Charles Yates <charles.yates@pandora.be>
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include <string.h>
22 #include <pthread.h>
23 #include <limits.h>
24 #include <float.h>
25
26 #include <framework/mlt.h>
27
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 );
34
35 // ffmpeg Header files
36 #include <libavformat/avformat.h>
37 #ifdef AVDEVICE
38 #include <libavdevice/avdevice.h>
39 #endif
40 #if LIBAVCODEC_VERSION_MAJOR >= 53
41 #include <libavutil/opt.h>
42 #else
43 #include <libavcodec/opt.h>
44 #endif
45
46 // A static flag used to determine if avformat has been initialised
47 static int avformat_initialised = 0;
48
49 static int avformat_lockmgr(void **mutex, enum AVLockOp op)
50 {
51    pthread_mutex_t** pmutex = (pthread_mutex_t**) mutex;
52
53    switch (op)
54    {
55    case AV_LOCK_CREATE:
56       *pmutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t));
57        pthread_mutex_init(*pmutex, NULL);
58        break;
59    case AV_LOCK_OBTAIN:
60        pthread_mutex_lock(*pmutex);
61        break;
62    case AV_LOCK_RELEASE:
63        pthread_mutex_unlock(*pmutex);
64        break;
65    case AV_LOCK_DESTROY:
66        pthread_mutex_destroy(*pmutex);
67        free(*pmutex);
68        break;
69    }
70
71    return 0;
72 }
73
74 static void avformat_init( )
75 {
76         // Initialise avformat if necessary
77         if ( avformat_initialised == 0 )
78         {
79                 avformat_initialised = 1;
80                 av_lockmgr_register( &avformat_lockmgr );
81                 av_register_all( );
82 #ifdef AVDEVICE
83                 avdevice_register_all();
84 #endif
85 #if LIBAVFORMAT_VERSION_INT >= ((53<<16)+(13<<8))
86                 avformat_network_init();
87 #endif
88                 av_log_set_level( mlt_log_get_level() );
89         }
90 }
91
92 static void *create_service( mlt_profile profile, mlt_service_type type, const char *id, void *arg )
93 {
94         avformat_init( );
95 #ifdef CODECS
96         if ( !strncmp( id, "avformat", 8 ) )
97         {
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 );
102         }
103 #endif
104 #ifdef FILTERS
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 );
113 #ifdef SWSCALE
114         if ( !strcmp( id, "swscale" ) )
115                 return filter_swscale_init( profile, arg );
116 #endif
117 #endif
118         return NULL;
119 }
120
121 static void add_parameters( mlt_properties params, void *object, int req_flags, const char *unit, const char *subclass )
122 {
123         const AVOption *opt = NULL;
124
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 ) ) )
128 #else
129         while ( ( opt = av_next_option( object, opt ) ) )
130 #endif
131         {
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 ) )
134             continue;
135
136                 // Ignore constants (keyword values)
137                 if ( !unit && opt->type == FF_OPT_TYPE_CONST )
138                         continue;
139                 // When processing a groups of options (unit)...
140                 // ...ignore non-constants
141                 else if ( unit && opt->type != FF_OPT_TYPE_CONST )
142                         continue;
143                 // ...ignore constants not in this group
144                 else if ( unit && opt->type == FF_OPT_TYPE_CONST && strcmp( unit, opt->unit ) )
145                         continue;
146                 // ..add constants to the 'values' sequence
147                 else if ( unit && opt->type == FF_OPT_TYPE_CONST )
148                 {
149                         char key[20];
150                         snprintf( key, 20, "%d", mlt_properties_count( params ) );
151                         mlt_properties_set( params, key, opt->name );
152                         continue;
153                 }
154
155                 // Create a map for this option.
156                 mlt_properties p = mlt_properties_new();
157                 char key[20];
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 );
161
162                 // Add the parameter metadata for this AVOption.
163                 mlt_properties_set( p, "identifier", opt->name );
164                 if ( opt->help )
165                 {
166                         if ( subclass )
167                         {
168                                 char *s = malloc( strlen( opt->help ) + strlen( subclass ) + 4 );
169                                 strcpy( s, opt->help );
170                                 strcat( s, " (" );
171                                 strcat( s, subclass );
172                                 strcat( s, ")" );
173                                 mlt_properties_set( p, "description", s );
174                                 free( s );
175                         }
176                         else
177                                 mlt_properties_set( p, "description", opt->help );
178                 }
179
180         switch ( opt->type )
181                 {
182                 case FF_OPT_TYPE_FLAGS:
183                         mlt_properties_set( p, "type", "string" );
184                         mlt_properties_set( p, "format", "flags" );
185                         break;
186                 case FF_OPT_TYPE_INT:
187                         if ( !opt->unit )
188                         {
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 );
196 #endif
197                         }
198                         else
199                         {
200                                 mlt_properties_set( p, "type", "string" );
201                                 mlt_properties_set( p, "format", "integer or keyword" );
202                         }
203                         break;
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 );
213 #endif
214                         break;
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 );
223 #endif
224                         break;
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 );
234 #endif
235                         break;
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 );
240 #endif
241                         break;
242                 case FF_OPT_TYPE_RATIONAL:
243                         mlt_properties_set( p, "type", "string" );
244                         mlt_properties_set( p, "format", "numerator:denominator" );
245                         break;
246                 case FF_OPT_TYPE_CONST:
247                 default:
248                         mlt_properties_set( p, "type", "integer" );
249                         mlt_properties_set( p, "format", "constant" );
250                         break;
251         }
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 )
254                 {
255                         // Create a 'values' sequence.
256                         mlt_properties values = mlt_properties_new();
257
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 );
262                         else
263                                 mlt_properties_close( values );
264                 }
265         }
266 }
267
268 static mlt_properties avformat_metadata( mlt_service_type type, const char *id, void *data )
269 {
270         char file[ PATH_MAX ];
271         const char *service_type = NULL;
272         mlt_properties result = NULL;
273
274         // Convert the service type to a string.
275         switch ( type )
276         {
277                 case consumer_type:
278                         service_type = "consumer";
279                         break;
280                 case filter_type:
281                         service_type = "filter";
282                         break;
283                 case producer_type:
284                         service_type = "producer";
285                         break;
286                 case transition_type:
287                         service_type = "transition";
288                         break;
289                 default:
290                         return NULL;
291         }
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 ) )
296         {
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 );
302 #else
303                 AVCodecContext *avcodec = avcodec_alloc_context();
304 #endif
305                 int flags = ( type == consumer_type )? AV_OPT_FLAG_ENCODING_PARAM : AV_OPT_FLAG_DECODING_PARAM;
306
307                 add_parameters( params, avformat, flags, NULL, NULL );
308 #if LIBAVFORMAT_VERSION_MAJOR >= 53
309                 avformat_init();
310                 if ( type == producer_type )
311                 {
312                         AVInputFormat *f = NULL;
313                         while ( ( f = av_iformat_next( f ) ) )
314                                 if ( f->priv_class )
315                                         add_parameters( params, &f->priv_class, flags, NULL, f->name );
316                 }
317                 else
318                 {
319                         AVOutputFormat *f = NULL;
320                         while ( ( f = av_oformat_next( f ) ) )
321                                 if ( f->priv_class )
322                                         add_parameters( params, &f->priv_class, flags, NULL, f->name );
323                 }
324 #endif
325
326                 add_parameters( params, avcodec, flags, NULL, NULL );
327 #if LIBAVCODEC_VERSION_MAJOR >= 53
328                 AVCodec *c = NULL;
329                 while ( ( c = av_codec_next( c ) ) )
330                         if ( c->priv_class )
331                                 add_parameters( params, &c->priv_class, flags, NULL, c->name );
332 #endif
333
334                 av_free( avformat );
335                 av_free( avcodec );
336         }
337         return result;
338 }
339
340 MLT_REPOSITORY
341 {
342 #ifdef CODECS
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 );
348 #endif
349 #ifdef FILTERS
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 );
354 #ifdef SWSCALE
355         MLT_REGISTER( filter_type, "swscale", create_service );
356 #endif
357 #endif
358 }