]> git.sesse.net Git - mlt/blobdiff - src/modules/avformat/producer_avformat.c
Update src/modules/avformat/producer_avformat.c
[mlt] / src / modules / avformat / producer_avformat.c
index fc21d02c0b9ec94e96728f0f08d97f9bd59361c7..933d2884d7d7b5f18573c3cca0b486854682eb69 100644 (file)
@@ -191,6 +191,16 @@ mlt_producer producer_avformat_init( mlt_profile profile, const char *service, c
                        // Register our get_frame implementation
                        producer->get_frame = producer_get_frame;
 
+                       // init mutexes
+                       pthread_mutex_init( &self->audio_mutex, NULL );
+                       pthread_mutex_init( &self->video_mutex, NULL );
+                       pthread_mutex_init( &self->packets_mutex, NULL );
+                       pthread_mutex_init( &self->open_mutex, NULL );
+
+                       // init queues
+                       self->apackets = mlt_deque_init();
+                       self->vpackets = mlt_deque_init();
+
                        if ( strcmp( service, "avformat-novalidate" ) )
                        {
                                // Open the file
@@ -199,6 +209,7 @@ mlt_producer producer_avformat_init( mlt_profile profile, const char *service, c
                                        // Clean up
                                        mlt_producer_close( producer );
                                        producer = NULL;
+                                       producer_avformat_close( self );
                                }
                                else if ( self->seekable )
                                {
@@ -789,8 +800,11 @@ static int get_basic_info( producer_avformat self, mlt_profile profile, const ch
                                if ( ret >= 0 && pkt.stream_index == self->video_index && pkt.size > 0 )
                                {
                                        get_aspect_ratio( properties, format->streams[ self->video_index ], codec_context, &pkt );
+                                       av_free_packet(&pkt);
                                        break;
                                }
+                               if ( ret >= 0 )
+                                       av_free_packet(&pkt);
                        }
                }
                else
@@ -824,10 +838,6 @@ static int producer_open( producer_avformat self, mlt_profile profile, const cha
        // Lock the service
        if ( take_lock )
        {
-               pthread_mutex_init( &self->audio_mutex, NULL );
-               pthread_mutex_init( &self->video_mutex, NULL );
-               pthread_mutex_init( &self->packets_mutex, NULL );
-               pthread_mutex_init( &self->open_mutex, NULL );
                pthread_mutex_lock( &self->audio_mutex );
                pthread_mutex_lock( &self->video_mutex );
        }
@@ -944,11 +954,6 @@ static int producer_open( producer_avformat self, mlt_profile profile, const cha
        }
        if ( filename )
                free( filename );
-       if ( !error )
-       {
-               self->apackets = mlt_deque_init();
-               self->vpackets = mlt_deque_init();
-       }
 
        if ( self->dummy_context )
        {
@@ -1243,7 +1248,7 @@ static void convert_image( AVFrame *frame, uint8_t *buffer, int pix_fmt,
 
        // extract alpha from planar formats
        if ( ( pix_fmt == PIX_FMT_YUVA420P
-#if LIBAVUTIL_VERSION_INT >= ((51<<16)+(35<<8)+101)
+#if defined(FFUDIV) && LIBAVUTIL_VERSION_INT >= ((51<<16)+(35<<8)+101)
                        || pix_fmt == PIX_FMT_YUVA444P
 #endif
                        ) &&
@@ -1397,9 +1402,26 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
        int image_size = 0;
 
        // Get the image cache
-       if ( ! self->image_cache && ! mlt_properties_get_int( properties, "noimagecache" ) )
+       if ( ! self->image_cache )
        {
-               self->image_cache = mlt_cache_init();
+               // if cache size supplied by environment variable
+               int cache_supplied = getenv( "MLT_AVFORMAT_CACHE" ) != NULL;
+               int cache_size = cache_supplied? atoi( getenv( "MLT_AVFORMAT_CACHE" ) ) : 0;
+
+               // cache size supplied via property
+               if ( mlt_properties_get( properties, "cache" ) )
+               {
+                       cache_supplied = 1;
+                       cache_size = mlt_properties_get_int( properties, "cache" );
+               }
+               if ( mlt_properties_get_int( properties, "noimagecache" ) )
+                       cache_size = 0;
+               // create cache if not disabled
+               if ( !cache_supplied || cache_size > 0 )
+                       self->image_cache = mlt_cache_init();
+               // set cache size if supplied
+               if ( self->image_cache && cache_supplied )
+                       mlt_cache_set_size( self->image_cache, cache_size );
        }
        if ( self->image_cache )
        {
@@ -1452,7 +1474,11 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
 
        // Turn on usage of new seek API and PTS for seeking
        int use_pts = self->seekable &&
-               codec_context->codec_id == CODEC_ID_H264 && codec_context->has_b_frames;
+               ( codec_context->codec_id == CODEC_ID_H264
+#if LIBAVCODEC_VERSION_INT >= ((52<<16)+(68<<8)+2)
+               || codec_context->codec_id == CODEC_ID_VP8
+#endif
+               );
        if ( mlt_properties_get( properties, "use_pts" ) )
                use_pts = mlt_properties_get_int( properties, "use_pts" );
        double delay = mlt_properties_get_double( properties, "video_delay" );
@@ -1548,7 +1574,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
                        if ( ret >= 0 && pkt.stream_index == self->video_index && pkt.size > 0 )
                        {
                                // Determine time code of the packet
-                               if ( pkt.pts == AV_NOPTS_VALUE )
+                               if ( use_pts && pkt.pts == AV_NOPTS_VALUE )
                                {
                                        self->invalid_pts_counter++;
                                        if ( self->invalid_pts_counter > 20 )
@@ -1865,8 +1891,11 @@ static int video_codec_init( producer_avformat self, int index, mlt_properties p
 #endif
 
                // Reset some image properties
-               mlt_properties_set_int( properties, "width", self->video_codec->width );
-               mlt_properties_set_int( properties, "height", self->video_codec->height );
+               if ( self->video_codec )
+               {
+                       mlt_properties_set_int( properties, "width", self->video_codec->width );
+                       mlt_properties_set_int( properties, "height", self->video_codec->height );
+               }
                // For DV, we'll just use the saved aspect ratio
                if ( codec_context->codec_id != CODEC_ID_DVVIDEO )
                        get_aspect_ratio( properties, stream, self->video_codec, NULL );
@@ -2250,7 +2279,7 @@ static int producer_get_audio( mlt_frame frame, void **buffer, mlt_audio_format
        }
 
        // Initialize the resamplers and buffers
-       for ( ; index < index_max; index++ )
+       for ( ; index < index_max && index < MAX_AUDIO_STREAMS; index++ )
        {
                // Get codec context
                AVCodecContext *codec_context = self->audio_codec[ index ];
@@ -2354,7 +2383,7 @@ static int producer_get_audio( mlt_frame frame, void **buffer, mlt_audio_format
 
                        // We only deal with audio from the selected audio index
                        index = pkt.stream_index;
-                       if ( ret >= 0 && pkt.data && pkt.size > 0 && ( index == self->audio_index ||
+                       if ( index < MAX_AUDIO_STREAMS && ret >= 0 && pkt.data && pkt.size > 0 && ( index == self->audio_index ||
                                 ( self->audio_index == INT_MAX && context->streams[ index ]->codec->codec_type == CODEC_TYPE_AUDIO ) ) )
                        {
                                int channels2 = ( self->audio_index == INT_MAX || !self->audio_resample[index] ) ?
@@ -2584,7 +2613,7 @@ static void producer_set_up_audio( producer_avformat self, mlt_frame frame )
        else if ( context && index > -1 && audio_codec_init( self, index, properties ) )
        {
                // Set the frame properties
-               if ( index < INT_MAX )
+               if ( index < MAX_AUDIO_STREAMS )
                {
                        mlt_properties_set_int( frame_properties, "frequency", self->audio_codec[ index ]->sample_rate );
                        mlt_properties_set_int( frame_properties, "channels", self->audio_codec[ index ]->channels );