X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=src%2Fmodules%2Favformat%2Fproducer_avformat.c;h=0b9fdb2e15390133b9d595aefe3c3114a3d4a97b;hb=4c7f6cfcb34ddde69112a2d877eb4fb6c380091a;hp=8e59b2dadec7b96877344ac25078b4358f618033;hpb=190560740c17d9c9d30004517f1e77321eaf0a67;p=melted diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c index 8e59b2d..0b9fdb2 100644 --- a/src/modules/avformat/producer_avformat.c +++ b/src/modules/avformat/producer_avformat.c @@ -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...