From d0556bc33fba8f8b881f3064db3907c4cd6eccb6 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Fri, 25 Jan 2013 02:24:18 -0600 Subject: [PATCH] Fixed a big audio regression, with a buggy isnear() function, which did not take into account the amount of frames between the sample locations. --- include/FFmpegReader.h | 5 +++++ src/FFmpegReader.cpp | 39 +++++++++++++++++++++++---------------- src/Main.cpp | 10 ++++++++++ 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/include/FFmpegReader.h b/include/FFmpegReader.h index 5e996a6f..5572c30a 100644 --- a/include/FFmpegReader.h +++ b/include/FFmpegReader.h @@ -45,6 +45,11 @@ namespace openshot int is_near(audio_packet_location location, int samples_per_frame, int amount) { + // Is frame even close to this one? + if (abs(location.frame - frame) >= 2) + // This is too far away to be considered + return false; + int sample_diff = abs(location.sample_start - sample_start); if (location.frame == frame && sample_diff >= 0 && sample_diff <= amount) // close diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index aeb80631..aa88172c 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -363,14 +363,14 @@ tr1::shared_ptr FFmpegReader::ReadStream(int requested_frame) int packet_error = -1; // Minimum number of packets to process (for performance reasons) - int frames_processed = 0; - int minimum_frames = 8; + int packets_processed = 0; + int minimum_packets = 16; //omp_set_num_threads(1); omp_set_nested(true); #pragma omp parallel { - #pragma omp single + #pragma omp master { // Loop through the stream until the correct frame is found while (true) @@ -449,11 +449,11 @@ tr1::shared_ptr FFmpegReader::ReadStream(int requested_frame) is_cache_found = final_cache.Exists(requested_frame); // Increment frames processed - frames_processed++; + packets_processed++; } // Break once the frame is found - if (is_cache_found && frames_processed >= minimum_frames) + if (is_cache_found && packets_processed >= minimum_packets) break; } // end while @@ -983,15 +983,18 @@ void FFmpegReader::Seek(int requested_frame) throw(TooManySeeks) } // Seek audio stream (if not already seeked... and if an audio stream is found) - seek_target = ConvertFrameToAudioPTS(requested_frame - buffer_amount); - if (!seek_worked && info.has_audio && av_seek_frame(pFormatCtx, info.audio_stream_index, seek_target, AVSEEK_FLAG_BACKWARD) < 0) { - seek_worked = false; - fprintf(stderr, "%s: error while seeking audio stream\n", pFormatCtx->filename); - } else + if (!seek_worked) { - // AUDIO SEEK - seek_worked = true; - is_video_seek = false; + seek_target = ConvertFrameToAudioPTS(requested_frame - buffer_amount); + if (info.has_audio && av_seek_frame(pFormatCtx, info.audio_stream_index, seek_target, AVSEEK_FLAG_BACKWARD) < 0) { + seek_worked = false; + fprintf(stderr, "%s: error while seeking audio stream\n", pFormatCtx->filename); + } else + { + // AUDIO SEEK + seek_worked = true; + is_video_seek = false; + } } // Was the seek successful? @@ -1005,6 +1008,10 @@ void FFmpegReader::Seek(int requested_frame) throw(TooManySeeks) if (info.has_video) avcodec_flush_buffers(pCodecCtx); + // Reset previous audio location to zero + previous_packet_location.frame = -1; + previous_packet_location.sample_start = 0; + // init seek flags is_seeking = true; seeking_pts = seek_target; @@ -1129,9 +1136,8 @@ audio_packet_location FFmpegReader::GetAudioPTSLocation(int pts) // Prepare final audio packet location audio_packet_location location = {whole_frame, sample_start}; - // Compare to previous audio packet (and fix small gaps due to varying PTS timestamps) - if (location.is_near(previous_packet_location, samples_per_frame, samples_per_frame)) + if (previous_packet_location.frame != -1 && location.is_near(previous_packet_location, samples_per_frame, samples_per_frame)) { int orig_frame = location.frame; int orig_start = location.sample_start; @@ -1149,7 +1155,8 @@ audio_packet_location FFmpegReader::GetAudioPTSLocation(int pts) location.frame++; } - //cout << "GAP DETECTED!!! Changing frame " << orig_frame << ":" << orig_start << " to frame " << location.frame << ":" << location.sample_start << endl; + if (display_debug) + cout << "AUDIO GAP DETECTED!!! Changing frame " << orig_frame << ":" << orig_start << " to frame " << location.frame << ":" << location.sample_start << endl; } //else // cout << "NOT NEAR!!! frame " << location.frame << ":" << location.sample_start << " prev frame " << previous_packet_location.frame << ":" << previous_packet_location.sample_start << endl; diff --git a/src/Main.cpp b/src/Main.cpp index 56867b99..3686cda0 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -18,6 +18,16 @@ void FrameReady(int number) int main() { + FFmpegReader r("/home/jonathan/Apps/videcho_site/media/user_files/videos/74c51b3a-66bc-11e2-9c6a-001fd00ee3aa.webm"); + r.Open(); + tr1::shared_ptr f = r.GetFrame(75); + f->Display(); + r.Close(); + + return 0; + + + /* TIMELINE ---------------- */ Timeline t(720, 420, Framerate(24,1), 48000, 2);