diff --git a/include/Cache.h b/include/Cache.h index 9b17c1d2..682c6dd1 100644 --- a/include/Cache.h +++ b/include/Cache.h @@ -8,7 +8,7 @@ */ #include -#include +#include #include "Frame.h" #include "Exceptions.h" @@ -26,7 +26,7 @@ namespace openshot { private: int max_frames; ///< This is the max number of frames to cache map frames; ///< This map holds the frame number and Frame objects - queue frame_numbers; ///< This queue holds a sequential list of cached Frame numbers + deque frame_numbers; ///< This queue holds a sequential list of cached Frame numbers /// Clean up cached frames that exceed the number in our max_frames variable void CleanUp(); @@ -44,14 +44,14 @@ namespace openshot { /// Check for the existance of a frame in the cache bool Exists(int frame_number); - /// Return the front frame and remove it - Frame Pop(); - /// Get a frame from the cache Frame GetFrame(int frame_number); - /// Get the front frame in this cache - Frame GetFront(); + /// Get the smallest frame number + Frame GetSmallestFrame(); + + /// Remove a specific frame + void Remove(int frame_number); /// Clear the cache of all frames void Clear(); diff --git a/src/Cache.cpp b/src/Cache.cpp index fd62cb94..c1ceae4e 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -23,7 +23,7 @@ void Cache::Add(int frame_number, Frame frame) { // Add frame to queue and map frames[frame_number] = frame; - frame_numbers.push(frame_number); + frame_numbers.push_front(frame_number); // Clean up older frames (that exceed the max frames) CleanUp(); @@ -46,23 +46,6 @@ bool Cache::Exists(int frame_number) return false; } -// Return the front frame and remove it -Frame Cache::Pop() -{ - // Remove the oldest frame - int frame_to_remove = frame_numbers.front(); - - // Get the front frame - Frame f = GetFrame(frame_to_remove); - - // Remove frame_number and frame - frame_numbers.pop(); - frames.erase(frame_to_remove); - - // Return the frame - return f; -} - // Get a frame from the cache Frame Cache::GetFrame(int frame_number) { @@ -77,11 +60,42 @@ Frame Cache::GetFrame(int frame_number) throw OutOfBoundsFrame("Frame not found in the cache", frame_number, -1); } -// Get the front frame in this cache -Frame Cache::GetFront() +// Get the smallest frame number +Frame Cache::GetSmallestFrame() { - // Return oldest frame in the cache - return GetFrame(frame_numbers.front()); + // Loop through frame numbers + deque::iterator itr; + int smallest_frame = -1; + for(itr = frame_numbers.begin(); itr != frame_numbers.end(); ++itr) + { + if (*itr < smallest_frame || smallest_frame == -1) + smallest_frame = *itr; + } + + // Return frame (or error if no frame found) + return GetFrame(smallest_frame); +} + +// Remove a specific frame +void Cache::Remove(int frame_number) +{ + // Get the frame (or throw exception) + Frame f = GetFrame(frame_number); + + // Loop through frame numbers + deque::iterator itr; + for(itr = frame_numbers.begin(); itr != frame_numbers.end(); ++itr) + { + if (*itr == frame_number) + { + // erase frame number + frame_numbers.erase(itr); + break; + } + } + + // Remove frame from map + frames.erase(frame_number); } // Clear the cache of all frames @@ -91,7 +105,7 @@ void Cache::Clear() frames.clear(); // pop each of the frames from the queue... which emptys the queue - while(!frame_numbers.empty()) frame_numbers.pop(); + while(!frame_numbers.empty()) frame_numbers.pop_back(); } // Count the frames in the queue @@ -108,11 +122,10 @@ void Cache::CleanUp() if (frame_numbers.size() > max_frames) { // Remove the oldest frame - int frame_to_remove = frame_numbers.front(); + int frame_to_remove = frame_numbers.back(); // Remove frame_number and frame - frame_numbers.pop(); - frames.erase(frame_to_remove); + Remove(frame_to_remove); } } @@ -124,12 +137,11 @@ void Cache::DisplayAndClear() while(!frame_numbers.empty()) { // Print the frame number - int frame_number = frame_numbers.front(); + int frame_number = frame_numbers.back(); cout << " " << i << ") --- Frame " << frame_number << endl; // Remove this frame - frame_numbers.pop(); - frames.erase(frame_number); + Remove(frame_number); // increment counter i++; diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index 15bb768a..ffe2ebd6 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -290,7 +290,8 @@ Frame FFmpegReader::ReadStream(int requested_frame) av_free(pFrame); // End of stream? Mark the any other working frames as 'finished' - CheckWorkingFrames(true); + if (end_of_stream) + CheckWorkingFrames(end_of_stream); // Return requested frame (if found) if (final_cache.Exists(requested_frame)) @@ -428,16 +429,12 @@ void FFmpegReader::ProcessAudioPacket(int requested_frame, int target_frame, int packet.size -= used; } - cout << "Samples Added to Frame " << target_frame << ": " << packet_samples << " (starting at sample: " << starting_sample << ")" << endl; - - for (int channel_filter = 0; channel_filter < info.channels; channel_filter++) { // Array of floats (to hold samples for each channel) int starting_frame_number = target_frame; int channel_buffer_size = (packet_samples / info.channels) + 1; float *channel_buffer = new float[channel_buffer_size]; - int position = 0; // Init buffer array for (int z = 0; z < channel_buffer_size; z++) @@ -446,7 +443,7 @@ void FFmpegReader::ProcessAudioPacket(int requested_frame, int target_frame, int // Loop through all samples and add them to our Frame based on channel. // Toggle through each channel number, since channel data is stored like (left right left right) int channel = 0; - + int position = 0; for (int sample = 0; sample < packet_samples; sample++) { // Only add samples for current channel @@ -460,7 +457,7 @@ void FFmpegReader::ProcessAudioPacket(int requested_frame, int target_frame, int } // increment channel (if needed) - if (channel < info.channels) + if ((channel + 1) < info.channels) // move to next channel channel ++; else @@ -468,13 +465,6 @@ void FFmpegReader::ProcessAudioPacket(int requested_frame, int target_frame, int channel = 0; } - // Add channel buffer to Frame object -// if (packet_samples > 0) // DEBUG to prevent overwriting samples with multiple audio packets -// { -// //cout << " *** ADDED AUDIO FOR FRAME " << current_frame << " *** (" << channel_buffer_size << " samples)" << endl; -// new_frame.AddAudio(channel_filter, audio_position, channel_buffer, channel_buffer_size, 1.0f); -// } - // Get Samples per frame int samples_per_frame = GetSamplesPerFrame(); @@ -769,7 +759,7 @@ void FFmpegReader::CheckWorkingFrames(bool end_of_stream) break; // Get the front frame of working cache - Frame f = working_cache.GetFront(); + Frame f = working_cache.GetSmallestFrame(); // Check if working frame is final if ((!end_of_stream && f.number <= last_video_frame && f.number < last_audio_frame) || end_of_stream) @@ -778,7 +768,7 @@ void FFmpegReader::CheckWorkingFrames(bool end_of_stream) final_cache.Add(f.number, f); // Remove frame from working cache - working_cache.Pop(); + working_cache.Remove(f.number); } else // Stop looping diff --git a/src/Main.cpp b/src/Main.cpp index b058670d..dcfbb085 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -17,8 +17,8 @@ int main() // openshot::FFmpegReader r("/home/jonathan/Aptana Studio Workspace/OpenShotLibrary/src/examples/test.mp4"); // openshot::FFmpegReader r("/home/jonathan/Aptana Studio Workspace/OpenShotLibrary/src/examples/test1.mp4"); // openshot::FFmpegReader r("/home/jonathan/Videos/OpenShot_Now_In_3d.mp4"); - // openshot::FFmpegReader r("/home/jonathan/Videos/sintel-1024-stereo.mp4"); - openshot::FFmpegReader r("/home/jonathan/Videos/sintel_trailer-720p.mp4"); + openshot::FFmpegReader r("/home/jonathan/Videos/sintel-1024-stereo.mp4"); + // openshot::FFmpegReader r("/home/jonathan/Videos/sintel_trailer-720p.mp4"); // openshot::FFmpegReader r("/home/jonathan/Aptana Studio Workspace/OpenShotLibrary/src/examples/test.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/bannertemplate.png"); @@ -28,7 +28,7 @@ int main() // Display debug info r.DisplayInfo(); - for (int frame = 300; frame < 400; frame++) + for (int frame = 1500; frame < 2000; frame++) { Frame f = r.GetFrame(frame); f.Play(); diff --git a/tests/Cache_Tests.cpp b/tests/Cache_Tests.cpp index b5be1e8c..6e8cd984 100644 --- a/tests/Cache_Tests.cpp +++ b/tests/Cache_Tests.cpp @@ -121,14 +121,14 @@ TEST(Cache_GetFrame) CHECK_EQUAL(3, c.GetFrame(3).number); } -TEST(Cache_GetFront) +TEST(Cache_GetSmallest) { // Create cache object (with a max of 10 items) Cache c(10); // Create 3 frames - Frame red(1, 300, 300, "red"); Frame blue(2, 400, 400, "blue"); + Frame red(1, 300, 300, "red"); Frame green(3, 500, 500, "green"); // Add frames to cache @@ -137,19 +137,19 @@ TEST(Cache_GetFront) c.Add(green.number, green); // Check if frame 1 is the front - CHECK_EQUAL(1, c.GetFront().number); + CHECK_EQUAL(1, c.GetSmallestFrame().number); // Check if frame 1 is STILL the front - CHECK_EQUAL(1, c.GetFront().number); + CHECK_EQUAL(1, c.GetSmallestFrame().number); // Erase frame 1 - c.Pop(); + c.Remove(1); // Check if frame 2 is the front - CHECK_EQUAL(2, c.GetFront().number); + CHECK_EQUAL(2, c.GetSmallestFrame().number); } -TEST(Cache_Pop) +TEST(Cache_Remove) { // Create cache object (with a max of 10 items) Cache c(10); @@ -164,13 +164,27 @@ TEST(Cache_Pop) c.Add(blue.number, blue); c.Add(green.number, green); - // Check if frame 1 is the front - Frame pop1 = c.Pop(); - CHECK_EQUAL(1, pop1.number); + // Check if count is 3 + CHECK_EQUAL(3, c.Count()); - Frame pop2 = c.Pop(); - CHECK_EQUAL(2, pop2.number); + // Check if frame 2 exists + CHECK_EQUAL(true, c.Exists(2)); - Frame pop3 = c.Pop(); - CHECK_EQUAL(3, pop3.number); + // Remove frame 2 + c.Remove(2); + + // Check if frame 2 exists + CHECK_EQUAL(false, c.Exists(2)); + + // Check if count is 2 + CHECK_EQUAL(2, c.Count()); + + // Remove frame 1 + c.Remove(1); + + // Check if frame 1 exists + CHECK_EQUAL(false, c.Exists(1)); + + // Check if count is 1 + CHECK_EQUAL(1, c.Count()); }