X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=src%2Fmodules%2Favformat%2Fproducer_avformat.c;h=bf3654f311c80224acb69fec463595b7b7a991ff;hb=7067858fa9cf333f072778d30d31947ca095a308;hp=5d4a55fac8f565ed8bdd04eff3badf87a797e0f9;hpb=4fd1e0e28c398a075ed725c3f26b51a5b9fa98d0;p=melted diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c index 5d4a55f..bf3654f 100644 --- a/src/modules/avformat/producer_avformat.c +++ b/src/modules/avformat/producer_avformat.c @@ -74,11 +74,17 @@ mlt_producer producer_avformat_init( mlt_profile profile, char *file ) mlt_producer_close( this ); this = NULL; } - - // 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 ); + 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 ); + + // Default the user-selectable indices from the auto-detected indices + mlt_properties_set_int( properties, "audio_index", mlt_properties_get_int( properties, "_audio_index" ) ); + mlt_properties_set_int( properties, "video_index", mlt_properties_get_int( properties, "_video_index" ) ); + } } } @@ -290,7 +296,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 ); @@ -301,8 +307,8 @@ static int producer_open( mlt_producer this, mlt_profile profile, char *file ) av_bypass = 1; // Store selected audio and video indexes on properties - mlt_properties_set_int( properties, "audio_index", audio_index ); - mlt_properties_set_int( properties, "video_index", video_index ); + mlt_properties_set_int( properties, "_audio_index", audio_index ); + mlt_properties_set_int( properties, "_video_index", video_index ); mlt_properties_set_int( properties, "_last_position", -1 ); // Fetch the width, height and aspect ratio @@ -331,7 +337,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 ); @@ -680,9 +686,13 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame ) // Fetch the video_context AVFormatContext *context = mlt_properties_get_data( properties, "video_context", NULL ); - if ( !context ) + + // Get the video_index + int index = mlt_properties_get_int( properties, "video_index" ); + + // Reopen the file if necessary + if ( !context && index > -1 ) { - // Reopen the file mlt_events_block( properties, this ); producer_open( this, mlt_service_profile( MLT_PRODUCER_SERVICE(this) ), mlt_properties_get( properties, "resource" ) ); @@ -691,13 +701,33 @@ static void producer_set_up_video( mlt_producer this, mlt_frame frame ) mlt_events_unblock( properties, this ); } - // Get the video_index - int index = mlt_properties_get_int( properties, "video_index" ); + // Exception handling for video_index + if ( context && index >= (int) context->nb_streams ) + { + for ( index = context->nb_streams - 1; index >= 0 && context->streams[ index ]->codec->codec_type != CODEC_TYPE_VIDEO; --index ); + mlt_properties_set_int( properties, "video_index", index ); + } + if ( context && index > -1 && context->streams[ index ]->codec->codec_type != CODEC_TYPE_VIDEO ) + { + index = -1; + mlt_properties_set_int( properties, "video_index", index ); + } + + // Update the video properties if the index changed + if ( index > -1 && index != mlt_properties_get_int( properties, "_video_index" ) ) + { + // Fetch the width, height and aspect ratio + AVCodecContext *codec_context = context->streams[ index ]->codec; + mlt_properties_set_int( properties, "_video_index", index ); + mlt_properties_set_int( properties, "width", codec_context->width ); + mlt_properties_set_int( properties, "height", codec_context->height ); + mlt_properties_set_double( properties, "aspect_ratio", av_q2d( codec_context->sample_aspect_ratio ) ); + } // Get the frame properties mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); - if ( context != NULL && index != -1 ) + if ( context != NULL && index > -1 ) { // Get the video stream AVStream *stream = context->streams[ index ]; @@ -985,9 +1015,12 @@ static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form } // If we're behind, ignore this packet - float current_pts = av_q2d( stream->time_base ) * pkt.pts; - if ( seekable && ( !ignore && current_pts <= ( real_timecode - 0.02 ) ) ) - ignore = 1; + if ( pkt.pts >= 0 ) + { + float current_pts = av_q2d( stream->time_base ) * pkt.pts; + if ( seekable && ( !ignore && current_pts <= ( real_timecode - 0.02 ) ) ) + ignore = 1; + } } // We're finished with this packet regardless @@ -1042,8 +1075,31 @@ 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 ); + mlt_properties_set_data( properties, "dummy_context", NULL, 0, NULL, NULL ); + mlt_events_unblock( properties, this ); + } + + // Exception handling for audio_index + if ( context && index >= (int) context->nb_streams ) + { + for ( index = context->nb_streams - 1; index >= 0 && context->streams[ index ]->codec->codec_type != CODEC_TYPE_AUDIO; --index ); + mlt_properties_set_int( properties, "audio_index", index ); + } + if ( context && index > -1 && context->streams[ index ]->codec->codec_type != CODEC_TYPE_AUDIO ) + { + index = -1; + mlt_properties_set_int( properties, "audio_index", index ); + } + // Deal with audio context - if ( context != NULL && index != -1 ) + if ( context != NULL && index > -1 ) { // Get the frame properties mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame );