producer_avformat.c: bugfix reading file over http.
[melted] / src / modules / avformat / producer_avformat.c
index 8e59b2d..0b9fdb2 100644 (file)
@@ -74,6 +74,13 @@ mlt_producer producer_avformat_init( mlt_profile profile, char *file )
                                mlt_producer_close( this );
                                this = NULL;
                        }
+                       else
+                       {
+                               // Close the file to release resources for large playlists - reopen later as needed
+                               mlt_properties_set_data( properties, "dummy_context", NULL, 0, NULL, NULL );
+                               mlt_properties_set_data( properties, "audio_context", NULL, 0, NULL, NULL );
+                               mlt_properties_set_data( properties, "video_context", NULL, 0, NULL, NULL );
+                       }
                }
        }
 
@@ -285,7 +292,7 @@ static int producer_open( mlt_producer this, mlt_profile profile, char *file )
                                mlt_properties_set_double( properties, "_start_time", context->start_time );
                        
                        // Check if we're seekable (something funny about mpeg here :-/)
-                       if ( strcmp( file, "pipe:" ) && strncmp( file, "http://", 6 ) )
+                       if ( strcmp( file, "pipe:" ) && strncmp( file, "http://", 6 )  && strncmp( file, "udp:", 4 )  && strncmp( file, "tcp:", 4 ) && strncmp( file, "rtsp:", 5 )  && strncmp( file, "rtp:", 4 ) )
                        {
                                mlt_properties_set_int( properties, "seekable", av_seek_frame( context, -1, mlt_properties_get_double( properties, "_start_time" ), AVSEEK_FLAG_BACKWARD ) >= 0 );
                                mlt_properties_set_data( properties, "dummy_context", context, 0, producer_file_close, NULL );
@@ -326,7 +333,7 @@ static int producer_open( mlt_producer this, mlt_profile profile, char *file )
                                mlt_properties_set_int(properties, "meta.attr.track.markup", context->track );
                        
                        // We're going to cheat here - for a/v files, we will have two contexts (reasoning will be clear later)
-                       if ( av == 0 && !av_bypass && audio_index != -1 && video_index != -1 )
+                       if ( av == 0 && audio_index != -1 && video_index != -1 )
                        {
                                // We'll use the open one as our video_context
                                mlt_properties_set_data( properties, "video_context", context, 0, producer_file_close, NULL );
@@ -647,6 +654,8 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
                                mlt_properties_set_int( properties, "_got_picture", 1 );
                        }
                }
+               if ( !got_picture )
+                       mlt_frame_get_image( frame, buffer, format, width, height, writable );
        }
 
        // Very untidy - for rawvideo, the packet contains the frame, hence the free packet
@@ -677,6 +686,18 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame )
        // Get the video_index
        int index = mlt_properties_get_int( properties, "video_index" );
 
+       // Reopen the file if necessary
+       if ( !context && index != -1 )
+       {
+               mlt_events_block( properties, this );
+               producer_open( this, mlt_service_profile( MLT_PRODUCER_SERVICE(this) ),
+                       mlt_properties_get( properties, "resource" ) );
+               context = mlt_properties_get_data( properties, "video_context", NULL );
+               index = mlt_properties_get_int( properties, "video_index" );
+               mlt_properties_set_data( properties, "dummy_context", NULL, 0, NULL, NULL );
+               mlt_events_unblock( properties, this );
+       }
+
        // Get the frame properties
        mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame );
 
@@ -708,6 +729,7 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame )
                        codec = avcodec_find_decoder( codec_context->codec_id );
 
                        // If we don't have a codec and we can't initialise it, we can't do much more...
+                       avformat_lock( );
                        if ( codec != NULL && avcodec_open( codec_context, codec ) >= 0 )
                        {
                                // Now store the codec with its destructor
@@ -718,6 +740,7 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame )
                                // Remember that we can't use this later
                                mlt_properties_set_int( properties, "video_index", -1 );
                        }
+                       avformat_unlock( );
                }
 
                // No codec, no show...
@@ -1023,6 +1046,18 @@ static void producer_set_up_audio( mlt_producer this, mlt_frame frame )
        // Get the audio_index
        int index = mlt_properties_get_int( properties, "audio_index" );
 
+       // Reopen the file if necessary
+       if ( !context && index != -1 )
+       {
+               mlt_events_block( properties, this );
+               producer_open( this, mlt_service_profile( MLT_PRODUCER_SERVICE(this) ),
+                       mlt_properties_get( properties, "resource" ) );
+               context = mlt_properties_get_data( properties, "audio_context", NULL );
+               index = mlt_properties_get_int( properties, "audio_index" );
+               mlt_properties_set_data( properties, "dummy_context", NULL, 0, NULL, NULL );
+               mlt_events_unblock( properties, this );
+       }
+
        // Deal with audio context
        if ( context != NULL && index != -1 )
        {
@@ -1045,6 +1080,7 @@ static void producer_set_up_audio( mlt_producer this, mlt_frame frame )
                        codec = avcodec_find_decoder( codec_context->codec_id );
 
                        // If we don't have a codec and we can't initialise it, we can't do much more...
+                       avformat_lock( );
                        if ( codec != NULL && avcodec_open( codec_context, codec ) >= 0 )
                        {
                                // Now store the codec with its destructor
@@ -1056,6 +1092,7 @@ static void producer_set_up_audio( mlt_producer this, mlt_frame frame )
                                // Remember that we can't use this later
                                mlt_properties_set_int( properties, "audio_index", -1 );
                        }
+                       avformat_unlock( );
                }
 
                // No codec, no show...