]> git.sesse.net Git - mlt/blobdiff - src/modules/avformat/consumer_avformat.c
Detect video codecs that use the new libavcodec "encode2" method.
[mlt] / src / modules / avformat / consumer_avformat.c
index a4aa08d25c07f22f15a2a1a27b4c1146904c677e..20e25fa6db8013b11d922dea91431f7d00877a5d 100644 (file)
@@ -50,6 +50,7 @@
 #if LIBAVUTIL_VERSION_INT >= ((50<<16)+(38<<8)+0)
 #  include <libavutil/samplefmt.h>
 #else
+#  define AV_SAMPLE_FMT_NONE SAMPLE_FMT_NONE
 #  define AV_SAMPLE_FMT_S16 SAMPLE_FMT_S16
 #  define AV_SAMPLE_FMT_S32 SAMPLE_FMT_S32
 #  define AV_SAMPLE_FMT_FLT SAMPLE_FMT_FLT
@@ -177,9 +178,6 @@ mlt_consumer consumer_avformat_init( mlt_profile profile, char *arg )
                mlt_properties_set_double( properties, "muxdelay", 0.7 );
                mlt_properties_set_double( properties, "muxpreload", 0.5 );
 
-               // Some AVOption defaults we like
-               mlt_properties_set( properties, "strict", "experimental" );
-
                // Ensure termination at end of the stream
                mlt_properties_set_int( properties, "terminate_on_pause", 1 );
                
@@ -259,7 +257,11 @@ static int consumer_start( mlt_consumer consumer )
                mlt_properties_set_data( properties, "vcodec", codecs, 0, (mlt_destructor) mlt_properties_close, NULL );
                mlt_properties_set_data( doc, "video_codecs", codecs, 0, NULL, NULL );
                while ( ( codec = av_codec_next( codec ) ) )
+#if LIBAVCODEC_VERSION_INT >= ((53<<16)+(34<<8)+0)
+                       if ( (codec->encode || codec->encode2) && codec->type == CODEC_TYPE_VIDEO )
+#else
                        if ( codec->encode && codec->type == CODEC_TYPE_VIDEO )
+#endif
                        {
                                snprintf( key, sizeof(key), "%d", mlt_properties_count( codecs ) );
                                mlt_properties_set( codecs, key, codec->name );
@@ -336,11 +338,11 @@ static int consumer_start( mlt_consumer consumer )
                // Assign the thread to properties
                mlt_properties_set_data( properties, "thread", thread, sizeof( pthread_t ), free, NULL );
 
-               // Set the running state
-               mlt_properties_set_int( properties, "running", 1 );
-
                // Create the thread
                pthread_create( thread, NULL, consumer_thread, consumer );
+
+               // Set the running state
+               mlt_properties_set_int( properties, "running", 1 );
        }
        return error;
 }
@@ -352,18 +354,18 @@ static int consumer_stop( mlt_consumer consumer )
 {
        // Get the properties
        mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
+       pthread_t *thread = mlt_properties_get_data( properties, "thread", NULL );
 
        // Check that we're running
-       if ( mlt_properties_get_int( properties, "running" ) )
+       if ( thread )
        {
-               // Get the thread
-               pthread_t *thread = mlt_properties_get_data( properties, "thread", NULL );
-
                // Stop the thread
                mlt_properties_set_int( properties, "running", 0 );
 
                // Wait for termination
                pthread_join( *thread, NULL );
+
+               mlt_properties_set( properties, "thread", NULL );
        }
 
        return 0;
@@ -393,7 +395,7 @@ static void apply_properties( void *obj, mlt_properties properties, int flags )
        for ( i = 0; i < count; i++ )
        {
                const char *opt_name = mlt_properties_get_name( properties, i );
-#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(7<<8)+0)
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(10<<8)+0)
                const AVOption *opt = av_opt_find( obj, opt_name, NULL, flags, flags );
 #else
                const AVOption *opt = av_find_opt( obj, opt_name, NULL, flags, flags );
@@ -403,7 +405,7 @@ static void apply_properties( void *obj, mlt_properties properties, int flags )
                if ( !opt && (
                        ( opt_name[0] == 'v' && ( flags & AV_OPT_FLAG_VIDEO_PARAM ) ) ||
                        ( opt_name[0] == 'a' && ( flags & AV_OPT_FLAG_AUDIO_PARAM ) ) ) )
-#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(7<<8)+0)
+#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(10<<8)+0)
                        opt = av_opt_find( obj, ++opt_name, NULL, flags, flags );
 #else
                        opt = av_find_opt( obj, ++opt_name, NULL, flags, flags );
@@ -1218,6 +1220,10 @@ static void *consumer_thread( void *arg )
                                acodec = mlt_properties_get( properties, "_acodec" );
                                audio_codec = avcodec_find_encoder_by_name( acodec );
                        }
+                       else if ( !strcmp( acodec, "aac" ) )
+                       {
+                               mlt_properties_set( properties, "astrict", "experimental" );
+                       }
                }
                else
                {
@@ -1434,7 +1440,8 @@ static void *consumer_thread( void *arg )
 #endif
                        {
                                mlt_log_error( MLT_CONSUMER_SERVICE( consumer ), "Could not open '%s'\n", filename );
-                               mlt_properties_set_int( properties, "running", 0 );
+                               mlt_events_fire( properties, "consumer-fatal-error", NULL );
+                               goto on_fatal_error;
                        }
                }
        
@@ -1450,7 +1457,8 @@ static void *consumer_thread( void *arg )
        else
        {
                mlt_log_error( MLT_CONSUMER_SERVICE( consumer ), "Invalid output format parameters\n" );
-               mlt_properties_set_int( properties, "running", 0 );
+               mlt_events_fire( properties, "consumer-fatal-error", NULL );
+               goto on_fatal_error;
        }
 #endif
 
@@ -1460,7 +1468,10 @@ static void *consumer_thread( void *arg )
 
        // Last check - need at least one stream
        if ( !audio_st[0] && !video_st )
-               mlt_properties_set_int( properties, "running", 0 );
+       {
+               mlt_events_fire( properties, "consumer-fatal-error", NULL );
+               goto on_fatal_error;
+       }
 
        // Get the starting time (can ignore the times above)
        gettimeofday( &ante, NULL );
@@ -1500,15 +1511,16 @@ static void *consumer_thread( void *arg )
                                        fifo = sample_fifo_init( frequency, channels );
                                        mlt_properties_set_data( properties, "sample_fifo", fifo, 0, ( mlt_destructor )sample_fifo_close, NULL );
                                }
+                               if ( pcm )
+                               {
+                                       // Silence if not normal forward speed
+                                       if ( mlt_properties_get_double( frame_properties, "_speed" ) != 1.0 )
+                                               memset( pcm, 0, samples * channels * sample_bytes );
 
-                               // Silence if not normal forward speed
-                               if ( mlt_properties_get_double( frame_properties, "_speed" ) != 1.0 )
-                                       memset( pcm, 0, samples * channels * sample_bytes );
-
-                               // Append the samples
-                               sample_fifo_append( fifo, pcm, samples * channels * sample_bytes );
-                               total_time += ( samples * 1000000 ) / frequency;
-
+                                       // Append the samples
+                                       sample_fifo_append( fifo, pcm, samples * channels * sample_bytes );
+                                       total_time += ( samples * 1000000 ) / frequency;
+                               }
                                if ( !video_st )
                                        mlt_events_fire( properties, "consumer-frame-show", frame, NULL );
                        }
@@ -1699,7 +1711,7 @@ static void *consumer_thread( void *arg )
 
                                                // Do the colour space conversion
 #ifdef SWSCALE
-                                               int flags = SWS_BILINEAR;
+                                               int flags = SWS_BICUBIC;
 #ifdef USE_MMX
                                                flags |= SWS_CPU_CAPS_MMX;
 #endif
@@ -1852,7 +1864,7 @@ static void *consumer_thread( void *arg )
                        av_init_packet( &pkt );
                        pkt.size = 0;
 
-                       if ( /*( c->capabilities & CODEC_CAP_SMALL_LAST_FRAME ) &&*/
+                       if ( fifo &&
                                ( channels * audio_input_frame_size < sample_fifo_used( fifo ) / sample_bytes ) )
                        {
                                sample_fifo_fetch( fifo, audio_buf_1, channels * audio_input_frame_size * sample_bytes );
@@ -1914,7 +1926,8 @@ static void *consumer_thread( void *arg )
 on_fatal_error:
        
        // Write the trailer, if any
-       av_write_trailer( oc );
+       if ( frames )
+               av_write_trailer( oc );
 
        // close each codec
        if ( video_st )
@@ -1927,13 +1940,13 @@ on_fatal_error:
                av_freep( &oc->streams[i] );
 
        // Close the output file
-       if ( !( fmt->flags & AVFMT_NOFILE ) )
+       if ( !( fmt->flags & AVFMT_NOFILE ) &&
+               !mlt_properties_get_int( properties, "redirect" ) )
        {
 #if LIBAVFORMAT_VERSION_MAJOR >= 53
-               if ( !mlt_properties_get_int( properties, "redirect" ) )
-                       avio_close( oc->pb );
+               if ( oc->pb  ) avio_close( oc->pb );
 #elif LIBAVFORMAT_VERSION_MAJOR >= 52
-               url_fclose( oc->pb );
+               if ( oc->pb  ) url_fclose( oc->pb );
 #else
                url_fclose( &oc->pb );
 #endif
@@ -1953,8 +1966,6 @@ on_fatal_error:
        av_free( oc );
 
        // Just in case we terminated on pause
-       mlt_properties_set_int( properties, "running", 0 );
-
        mlt_consumer_stopped( consumer );
        mlt_properties_close( frame_meta_properties );