From e5c45367d75fd8da08d5267c609ad11ee3ef169a Mon Sep 17 00:00:00 2001 From: lilo_booter Date: Tue, 25 May 2004 10:47:29 +0000 Subject: [PATCH] Sync with current ffmpeg CVS and minor clean up git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@316 d19143bc-622f-0410-bfdd-b5b2a6649095 --- src/modules/avformat/consumer_avformat.c | 57 +++++++++++++++++++++++++++--- src/modules/avformat/producer_avformat.c | 42 ++++++---------------- 2 files changed, 64 insertions(+), 35 deletions(-) diff --git a/src/modules/avformat/consumer_avformat.c b/src/modules/avformat/consumer_avformat.c index 41febfc..e511da3 100644 --- a/src/modules/avformat/consumer_avformat.c +++ b/src/modules/avformat/consumer_avformat.c @@ -35,17 +35,54 @@ // avformat header files #include +// +// This structure should be extended and made globally available in mlt +// + typedef struct { int16_t *buffer; int size; int used; + double time; + int frequency; + int channels; } *sample_fifo, sample_fifo_s; -sample_fifo sample_fifo_init( ) +sample_fifo sample_fifo_init( int frequency, int channels ) +{ + sample_fifo this = calloc( 1, sizeof( sample_fifo_s ) ); + this->frequency = frequency; + this->channels = channels; + return this; +} + +// sample_fifo_clear and check are temporarily aborted (not working as intended) + +void sample_fifo_clear( sample_fifo this, double time ) +{ + int words = ( float )( time - this->time ) * this->frequency * this->channels; + if ( ( int )( ( float )time * 100 ) < ( int )( ( float )this->time * 100 ) && this->used > words && words > 0 ) + { + memmove( this->buffer, &this->buffer[ words ], ( this->used - words ) * sizeof( int16_t ) ); + this->used -= words; + this->time = time; + } + else if ( ( int )( ( float )time * 100 ) != ( int )( ( float )this->time * 100 ) ) + { + this->used = 0; + this->time = time; + } +} + +void sample_fifo_check( sample_fifo this, double time ) { - return calloc( 1, sizeof( sample_fifo_s ) ); + if ( this->used == 0 ) + { + if ( ( int )( ( float )time * 100 ) < ( int )( ( float )this->time * 100 ) ) + this->time = time; + } } void sample_fifo_append( sample_fifo this, int16_t *samples, int count ) @@ -74,6 +111,8 @@ int sample_fifo_fetch( sample_fifo this, int16_t *samples, int count ) this->used -= count; memmove( this->buffer, &this->buffer[ count ], this->used * sizeof( int16_t ) ); + this->time += ( double )count / this->channels / this->frequency; + return count; } @@ -112,7 +151,6 @@ mlt_consumer consumer_avformat_init( char *arg ) mlt_properties_set( properties, "target", arg ); // sample and frame queue - mlt_properties_set_data( properties, "sample_fifo", sample_fifo_init( ), 0, ( mlt_destructor )sample_fifo_close, NULL ); mlt_properties_set_data( properties, "frame_queue", mlt_deque_init( ), 0, ( mlt_destructor )mlt_deque_close, NULL ); // Set avformat defaults (all lifted from ffmpeg.c) @@ -732,6 +770,15 @@ static void *consumer_thread( void *arg ) { samples = mlt_sample_calculator( fps, frequency, count ); mlt_frame_get_audio( frame, &pcm, &aud_fmt, &frequency, &channels, &samples ); + + // Create the fifo if we don't have one + if ( fifo == NULL ) + { + fifo = sample_fifo_init( frequency, channels ); + mlt_properties_set_data( properties, "sample_fifo", fifo, 0, ( mlt_destructor )sample_fifo_close, NULL ); + } + + // Append the samples sample_fifo_append( fifo, pcm, samples * channels ); total_time += ( samples * 1000000 ) / frequency; } @@ -748,12 +795,12 @@ static void *consumer_thread( void *arg ) { // Compute current audio and video time if (audio_st) - audio_pts = (double)audio_st->pts.val * oc->pts_num / oc->pts_den; + audio_pts = (double)audio_st->pts.val * audio_st->time_base.num / audio_st->time_base.den; else audio_pts = 0.0; if (video_st) - video_pts = (double)video_st->pts.val * oc->pts_num / oc->pts_den; + video_pts = (double)video_st->pts.val * video_st->time_base.num / video_st->time_base.den; else video_pts = 0.0; diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c index ef611af..b936ff3 100644 --- a/src/modules/avformat/producer_avformat.c +++ b/src/modules/avformat/producer_avformat.c @@ -62,9 +62,6 @@ mlt_producer producer_avformat_init( char *file ) // Set the resource property (required for all producers) mlt_properties_set( properties, "resource", file ); - // TEST: audio sync tweaking - mlt_properties_set_double( properties, "discrepancy", 1 ); - // Register our get_frame implementation this->get_frame = producer_get_frame; @@ -270,11 +267,11 @@ static int producer_open( mlt_producer this, char *file ) // Find default audio and video streams find_default_streams( context, &audio_index, &video_index ); + if ( context->start_time != AV_NOPTS_VALUE ) + mlt_properties_set_double( properties, "start_time", context->start_time ); + // Check if we're seekable (something funny about mpeg here :-/) - if ( strstr( file, ".mpg" ) == NULL && strstr( file, ".mpeg" ) == NULL ) - mlt_properties_set_int( properties, "seekable", av_seek_frame( context, -1, context->start_time ) >= 0 ); - else - mlt_properties_set_int( properties, "seekable", 1 ); + mlt_properties_set_int( properties, "seekable", av_seek_frame( context, -1, mlt_properties_get_double( properties, "start_time" ) ) >= 0 ); // Store selected audio and video indexes on properties mlt_properties_set_int( properties, "audio_index", audio_index ); @@ -385,6 +382,9 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form // We may want to use the source fps if available double source_fps = mlt_properties_get_double( properties, "source_fps" ); + // Get the seekable status + int seekable = mlt_properties_get_int( properties, "seekable" ); + // Set the result arguments that we know here (only *buffer is now required) *format = mlt_image_yuv422; *width = codec_context->width; @@ -413,7 +413,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form // We're paused - use last image paused = 1; } - else if ( position > expected && ( position - expected ) < 250 ) + else if ( !seekable && position > expected && ( position - expected ) < 250 ) { // Fast forward - seeking is inefficient for small distances - just ignore following frames ignore = position - expected; @@ -421,7 +421,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form else { // Set to the real timecode - av_seek_frame( context, -1, context->start_time + real_timecode * 1000000.0 ); + av_seek_frame( context, -1, mlt_properties_get_double( properties, "start_time" ) + real_timecode * 1000000.0 ); // Remove the cached info relating to the previous position mlt_properties_set_double( properties, "current_time", real_timecode ); @@ -760,7 +760,7 @@ static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form // We're paused - silence required paused = 1; } - else if ( position > expected && ( position - expected ) < 250 ) + else if ( !seekable && position > expected && ( position - expected ) < 250 ) { // Fast forward - seeking is inefficient for small distances - just ignore following frames ignore = position - expected; @@ -768,7 +768,7 @@ static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form else { // Set to the real timecode - if ( !seekable || av_seek_frame( context, -1, context->start_time + real_timecode * 1000000.0 ) != 0 ) + if ( av_seek_frame( context, -1, mlt_properties_get_double( properties, "start_time" ) + real_timecode * 1000000.0 ) != 0 ) paused = 1; // Clear the usage in the audio buffer @@ -839,25 +839,7 @@ static int producer_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form // If we're behind, ignore this packet float current_pts = (float)pkt.pts / 1000000.0; - double discrepancy = mlt_properties_get_double( properties, "discrepancy" ); - if ( current_pts != 0 && real_timecode != 0 ) - { - if ( discrepancy != 1 ) - discrepancy = ( discrepancy + ( real_timecode / current_pts ) ) / 2; - else - discrepancy = real_timecode / current_pts; - if ( discrepancy > 0.9 && discrepancy < 1.1 ) - discrepancy = 1.0; - else - discrepancy = floor( discrepancy + 0.5 ); - - if ( discrepancy == 0 ) - discrepancy = 1.0; - - mlt_properties_set_double( properties, "discrepancy", discrepancy ); - } - - if ( seekable && ( !ignore && discrepancy * current_pts <= ( real_timecode - 0.02 ) ) ) + if ( seekable && ( !ignore && current_pts <= ( real_timecode - 0.02 ) ) ) ignore = 1; } -- 1.7.4.4