From 34a07b8d8248e5dbfa1950152c1b67f463e6fe7e Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Wed, 4 Jul 2012 03:07:26 -0500 Subject: [PATCH] All known memory leaks are now fixed, and the memory seems to hold steady when looping through frames for many many minutes at a time. Fixed a bug with av_free_packet, which was breaking after an audio decode. Removed lots of debug statements. --- src/FFmpegReader.cpp | 49 +++++++++++++++++++++----------------------- src/Main.cpp | 8 +++----- 2 files changed, 26 insertions(+), 31 deletions(-) diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index f6a19eff..925d5432 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -339,8 +339,6 @@ Frame FFmpegReader::ReadStream(int requested_frame) // Determine related video frame and starting sample # from audio PTS audio_packet_location location = GetAudioPTSLocation(packet->pts); - cout << "Audio Location: frame: " << location.frame << ", start: " << location.sample_start << endl; - // Process Audio Packet ProcessAudioPacket(requested_frame, location.frame, location.sample_start); } @@ -360,10 +358,6 @@ Frame FFmpegReader::ReadStream(int requested_frame) if (is_cache_found) break; - // DEBUG - cout << "FRAMES: " << frames.size() << endl; - cout << "PACKETS: " << packets.size() << endl; - } // end while } // end omp master @@ -396,8 +390,6 @@ int FFmpegReader::GetNextPacket() if (found_packet >= 0) { // Add packet to packet cache - av_dup_packet(next_packet); - cout << "Adding next_packet (" << next_packet << ") for PTS: " << next_packet->pts << endl; packets[next_packet] = next_packet; // Update current packet pointer @@ -516,8 +508,9 @@ void FFmpegReader::ProcessVideoPacket(int requested_frame) Cache *my_cache = &working_cache; int *my_last_video_frame = &last_video_frame; AVPacket *my_packet = packets[packet]; + AVFrame *my_frame = frames[pFrame]; - #pragma omp task firstprivate(current_frame, my_last_video_frame, my_cache, my_packet, height, width, video_length, pix_fmt) + #pragma omp task firstprivate(current_frame, my_last_video_frame, my_cache, my_packet, my_frame, height, width, video_length, pix_fmt) { // Create variables for a RGB Frame (since most videos are not in RGB, we must convert it) AVFrame *pFrameRGB = NULL; @@ -551,9 +544,12 @@ void FFmpegReader::ProcessVideoPacket(int requested_frame) } // Resize / Convert to RGB - sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, + sws_scale(img_convert_ctx, my_frame->data, my_frame->linesize, 0, height, pFrameRGB->data, pFrameRGB->linesize); + // Deallocate swscontext + sws_freeContext(img_convert_ctx); + #pragma omp critical (openshot_cache) { @@ -579,7 +575,7 @@ void FFmpegReader::ProcessVideoPacket(int requested_frame) #pragma omp critical (packet_cache) { // Remove frame and packet - RemoveAVFrame(pFrame); + RemoveAVFrame(my_frame); RemoveAVPacket(my_packet); } @@ -595,7 +591,7 @@ void FFmpegReader::ProcessAudioPacket(int requested_frame, int target_frame, int if (target_frame < (requested_frame - 20)) { #pragma omp critical (packet_cache) - // Remove frame and packet + // Remove packet RemoveAVPacket(packet); // Skip to next frame without decoding or caching @@ -613,7 +609,6 @@ void FFmpegReader::ProcessAudioPacket(int requested_frame, int target_frame, int #pragma omp task firstprivate(requested_frame, target_frame, my_cache, my_packet, audio_buf, converted_audio, channel_buffer, resampleCtx, my_last_audio_frame, starting_sample) { - // Allocate audio buffer audio_buf = new int16_t[AVCODEC_MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; @@ -644,6 +639,13 @@ void FFmpegReader::ProcessAudioPacket(int requested_frame, int target_frame, int my_packet->size -= used; } + #pragma omp critical (packet_cache) + { + // Remove packet + av_init_packet(my_packet); // TODO: this is a hack, to prevent a bug calling av_free_packet after avcodec_decode_audio3() + RemoveAVPacket(my_packet); + } + // Re-sample audio samples (if needed) if(aCodecCtx->sample_fmt != AV_SAMPLE_FMT_S16) { // Audio needs to be converted @@ -761,12 +763,11 @@ void FFmpegReader::ProcessAudioPacket(int requested_frame, int target_frame, int iterate_channel_buffer = NULL; } - - #pragma omp critical (packet_cache) - { - // Remove frame and packet - RemoveAVPacket(my_packet); - } + // Clean up some arrays + delete audio_buf; + audio_buf = NULL; + delete converted_audio; + converted_audio = 0; #pragma omp critical (openshot_cache) { @@ -1196,18 +1197,14 @@ void FFmpegReader::RemoveAVFrame(AVFrame* remove_frame) // Remove AVPacket from cache (and deallocate it's memory) void FFmpegReader::RemoveAVPacket(AVPacket* remove_packet) { + // Remove packet (if any) if (packets.count(remove_packet)) { - // Free memory - //AVPacket *remove_packet = packets[PTS]; - cout << "removing packet (" << remove_packet << ", " << packets[remove_packet] << ") PTS " << packets[remove_packet]->pts << endl; - // Remove from cache packets.erase(remove_packet); - delete remove_packet; - //av_free_packet(remove_packet); - + // deallocate memory for packet + av_free_packet(remove_packet); } } diff --git a/src/Main.cpp b/src/Main.cpp index e5eb392c..9689b937 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -17,9 +17,9 @@ int main() // openshot::FFmpegReader r("/home/jonathan/apps/libopenshot/src/examples/test.mp4"); // openshot::FFmpegReader r("/home/jonathan/apps/libopenshot/src/examples/test1.mp4"); // openshot::FFmpegReader r("/home/jonathan/apps/libopenshot/src/examples/piano.wav"); - // openshot::FFmpegReader r("/home/jonathan/Videos/sintel-1024-stereo.mp4"); + openshot::FFmpegReader r("/home/jonathan/Videos/sintel-1024-stereo.mp4"); // openshot::FFmpegReader r("/home/jonathan/Videos/00001.mts"); - openshot::FFmpegReader r("/home/jonathan/Videos/sintel_trailer-720p.mp4"); + // openshot::FFmpegReader r("/home/jonathan/Videos/sintel_trailer-720p.mp4"); // openshot::FFmpegReader r("/home/jonathan/Aptana Studio Workspace/OpenShotLibrary/src/examples/piano.wav"); // openshot::FFmpegReader r("/home/jonathan/Music/Army of Lovers/Crucified/Army of Lovers - Crucified [Single Version].mp3"); // openshot::FFmpegReader r("/home/jonathan/Documents/OpenShot Art/test.jpeg"); @@ -32,7 +32,7 @@ int main() for (int repeat = 0; repeat <= 100; repeat++) { cout << "----------- REPEAT READER " << repeat << " ---------------" << endl; - for (int frame = 200; frame <= 400; frame++) + for (int frame = 1; frame <= 100; frame++) { Frame f = r.GetFrame(frame); //f.Play(); @@ -40,8 +40,6 @@ int main() //f.DisplayWaveform(false); } - sleep(1); - // Seek to frame 1 r.GetFrame(1); }