X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=src%2Fmodules%2Favformat%2Fproducer_avformat.c;h=0b9fdb2e15390133b9d595aefe3c3114a3d4a97b;hb=4c7f6cfcb34ddde69112a2d877eb4fb6c380091a;hp=f0019353d213184c42864f12560e0099f227af94;hpb=151f4c1412afcde1ce3bb1cfa7128f274f89a0aa;p=melted diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c index f001935..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 ); @@ -640,13 +647,15 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form if ( got_picture ) { mlt_properties_set_int( frame_properties, "progressive", !av_frame->interlaced_frame ); - mlt_properties_set_int( frame_properties, "top_field_first", av_frame->top_field_first ); + mlt_properties_set_int( properties, "top_field_first", av_frame->top_field_first ); convert_image( av_frame, *buffer, codec_context->pix_fmt, *format, *width, *height ); mlt_properties_set_data( frame_properties, "image", *buffer, size, (mlt_destructor)mlt_pool_release, NULL ); mlt_properties_set_int( properties, "_current_position", int_position ); 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... @@ -728,6 +751,28 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame ) double force_aspect_ratio = mlt_properties_get_double( properties, "force_aspect_ratio" ); double aspect_ratio; + if ( strcmp( codec_context->codec->name, "dvvideo" ) == 0 ) + { + // Override FFmpeg's notion of DV aspect ratios, which are + // based upon a width of 704. Since we do not have a normaliser + // that crops (nor is cropping 720 wide ITU-R 601 video always desirable) + // we just coerce the values to facilitate a passive behaviour through + // the rescale normaliser when using equivalent producers and consumers. + // = display_aspect / (width * height) + if ( codec_context->sample_aspect_ratio.num == 10 && + codec_context->sample_aspect_ratio.den == 11 ) + force_aspect_ratio = 8.0/9.0; // 4:3 NTSC + else if ( codec_context->sample_aspect_ratio.num == 59 && + codec_context->sample_aspect_ratio.den == 54 ) + force_aspect_ratio = 16.0/15.0; // 4:3 PAL + else if ( codec_context->sample_aspect_ratio.num == 40 && + codec_context->sample_aspect_ratio.den == 33 ) + force_aspect_ratio = 32.0/27.0; // 16:9 NTSC + else if ( codec_context->sample_aspect_ratio.num == 118 && + codec_context->sample_aspect_ratio.den == 81 ) + force_aspect_ratio = 64.0/45.0; // 16:9 PAL + } + // XXX: We won't know the real aspect ratio until an image is decoded // but we do need it now (to satisfy filter_resize) - take a guess based // on pal/ntsc @@ -741,8 +786,7 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame ) } else { - int is_pal = mlt_producer_get_fps( this ) == 25.0; - aspect_ratio = is_pal ? 59.0/54.0 : 10.0/11.0; + aspect_ratio = 1.0; } // Determine the fps @@ -1002,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 ) { @@ -1020,20 +1076,11 @@ static void producer_set_up_audio( mlt_producer this, mlt_frame frame ) // Initialise the codec if necessary if ( codec == NULL ) { - // Initialise multi-threading - int thread_count = mlt_properties_get_int( properties, "threads" ); - if ( thread_count == 0 && getenv( "MLT_AVFORMAT_THREADS" ) ) - thread_count = atoi( getenv( "MLT_AVFORMAT_THREADS" ) ); - if ( thread_count > 1 ) - { - avcodec_thread_init( codec_context, thread_count ); - codec_context->thread_count = thread_count; - } - // Find the codec 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 @@ -1045,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...