diff --git a/include/AudioResampler.h b/include/AudioResampler.h index e14ff39b..645d9d36 100644 --- a/include/AudioResampler.h +++ b/include/AudioResampler.h @@ -47,6 +47,9 @@ namespace openshot { /// Sets the audio buffer and key settings int SetBuffer(AudioSampleBuffer *new_buffer, double sample_rate, double new_sample_rate); + /// Sets the audio buffer and key settings + int SetBuffer(AudioSampleBuffer *new_buffer, double ratio); + /// Get the resampled audio buffer AudioSampleBuffer* GetResampledBuffer(); }; diff --git a/include/Clip.h b/include/Clip.h index dee5ece9..2e824296 100644 --- a/include/Clip.h +++ b/include/Clip.h @@ -7,12 +7,19 @@ * \author Copyright (c) 2011 Jonathan Thomas */ +/// Do not include the juce unittest headers, because it collides with unittest++ +#ifndef __JUCE_UNITTEST_JUCEHEADER__ + #define __JUCE_UNITTEST_JUCEHEADER__ +#endif + #include #include "FFmpegReader.h" #include "FrameRate.h" #include "FrameMapper.h" #include "ImageReader.h" #include "KeyFrame.h" +#include "JuceLibraryCode/JuceHeader.h" +#include "AudioResampler.h" using namespace std; using namespace openshot; @@ -85,11 +92,17 @@ namespace openshot { string get_file_extension(string path); /// Adjust the audio and image of a time mapped frame - void apply_time_mapped_frame(tr1::shared_ptr frame, int frame_number); + tr1::shared_ptr get_time_mapped_frame(tr1::shared_ptr frame, int frame_number); + + /// Calculate the # of samples per video frame (for a specific frame number) + int GetSamplesPerFrame(int frame_number, Fraction rate); /// Init default settings for a clip void init_settings(); + /// Reverse an audio buffer + void reverse_buffer(juce::AudioSampleBuffer* buffer); + public: GravityType gravity; ///clear(); buffer_source = new AudioBufferSource(buffer); // Init resampling source @@ -21,6 +31,7 @@ AudioResampler::AudioResampler() : resample_source(NULL), buffer_source(NULL), n // Init resampled buffer resampled_buffer = new AudioSampleBuffer(2, 1); + resampled_buffer->clear(); // Init callback buffer resample_callback_buffer.buffer = resampled_buffer; @@ -32,9 +43,12 @@ AudioResampler::AudioResampler() : resample_source(NULL), buffer_source(NULL), n AudioResampler::~AudioResampler() { // Clean up - delete buffer_source; - delete resample_source; - delete resampled_buffer; + if (buffer_source) + delete buffer_source; + if (resample_source) + delete resample_source; + if (resampled_buffer) + delete resampled_buffer; } // Sets the audio buffer and updates the key settings @@ -45,13 +59,23 @@ int AudioResampler::SetBuffer(AudioSampleBuffer *new_buffer, double sample_rate, if (new_sample_rate <= 0) new_sample_rate == 44100; + // Set the sample ratio (the ratio of sample rate change) + source_ratio = sample_rate / new_sample_rate; + + // Call SetBuffer with ratio + SetBuffer(new_buffer, source_ratio); +} + +// Sets the audio buffer and key settings +int AudioResampler::SetBuffer(AudioSampleBuffer *new_buffer, double ratio) +{ // Update buffer & buffer source buffer = new_buffer; buffer_source->setBuffer(buffer); // Set the sample ratio (the ratio of sample rate change) - source_ratio = sample_rate / new_sample_rate; - dest_ratio = new_sample_rate / sample_rate; + source_ratio = ratio; + dest_ratio = 1.0 / ratio; num_of_samples = buffer->getNumSamples(); new_num_of_samples = round(num_of_samples * dest_ratio) - 1; @@ -62,7 +86,7 @@ int AudioResampler::SetBuffer(AudioSampleBuffer *new_buffer, double sample_rate, if (!isPrepared) { // Prepare to play the audio sources (and set the # of samples per chunk to a little more than expected) - resample_source->prepareToPlay(num_of_samples + 10, new_sample_rate); + resample_source->prepareToPlay(num_of_samples + 10, 0); isPrepared = true; } diff --git a/src/Clip.cpp b/src/Clip.cpp index 32c4b8b1..f02162bb 100644 --- a/src/Clip.cpp +++ b/src/Clip.cpp @@ -52,6 +52,8 @@ void Clip::init_settings() // Default pointers file_reader = NULL; resampler = NULL; + + cout << "INIT CLIP SETTINGS!!!!" << endl; } // Default Constructor for a clip @@ -64,6 +66,9 @@ Clip::Clip() // Constructor with reader Clip::Clip(FileReaderBase* reader) { + // Init all default settings + init_settings(); + // set reader pointer file_reader = reader; } @@ -160,7 +165,7 @@ float Clip::End() // if a time curve is present, use it's length if (time.Points.size() > 1) - return float(time.Values.size()) / fps; + return float(time.GetLength()) / fps; else // just use the duration (as detected by the reader) return end; @@ -175,19 +180,19 @@ tr1::shared_ptr Clip::GetFrame(int requested_frame) throw(ReaderClosed) // Is a time map detected int new_frame_number = requested_frame; if (time.Values.size() > 1) - new_frame_number = time.GetValue(requested_frame); + new_frame_number = time.GetInt(requested_frame); // Now that we have re-mapped what frame number is needed, go and get the frame pointer tr1::shared_ptr frame = file_reader->GetFrame(new_frame_number); // Get time mapped frame number (used to increase speed, change direction, etc...) - apply_time_mapped_frame(frame, requested_frame); + tr1::shared_ptr new_frame = get_time_mapped_frame(frame, requested_frame); // Apply basic image processing (scale, rotation, etc...) - apply_basic_image_processing(frame, new_frame_number); + //apply_basic_image_processing(new_frame, new_frame_number); // Return processed 'frame' - return frame; + return new_frame; } // Get file extension @@ -197,45 +202,212 @@ string Clip::get_file_extension(string path) return path.substr(path.find_last_of(".") + 1); } -// Adjust the audio and image of a time mapped frame -void Clip::apply_time_mapped_frame(tr1::shared_ptr frame, int frame_number) +// Reverse an audio buffer +void Clip::reverse_buffer(juce::AudioSampleBuffer* buffer) { + int number_of_samples = buffer->getNumSamples(); + int channels = buffer->getNumChannels(); + + // Reverse array (create new buffer to hold the reversed version) + AudioSampleBuffer *reversed = new juce::AudioSampleBuffer(channels, number_of_samples); + reversed->clear(); + + for (int channel = 0; channel < channels; channel++) + { + int n=0; + for (int s = number_of_samples - 1; s >= 0; s--, n++) + reversed->getSampleData(channel)[n] = buffer->getSampleData(channel)[s]; + } + + // Copy the samples back to the original array + buffer->clear(); + // Loop through channels, and get audio samples + for (int channel = 0; channel < channels; channel++) + // Get the audio samples for this channel + buffer->addFrom(channel, 0, reversed->getSampleData(channel), number_of_samples, 1.0f); + + delete reversed; + reversed = NULL; +} + +// Adjust the audio and image of a time mapped frame +tr1::shared_ptr Clip::get_time_mapped_frame(tr1::shared_ptr new_frame, int frame_number) +{ + cout << "TIME MAPPER: " << frame_number << endl; + // Check for a valid time map curve if (time.Values.size() > 1) { - // Create a resampler (only once) + // create buffer and resampler + juce::AudioSampleBuffer *samples = NULL; if (!resampler) resampler = new AudioResampler(); // Get new frame number int new_frame_number = time.GetInt(frame_number); - // Get previous and next values (if any) - int previous_value = time.GetValue(frame_number - 1); - int next_value = time.GetValue(frame_number + 1); + // Create a new frame + int samples_in_frame = GetSamplesPerFrame(new_frame_number, file_reader->info.fps); + //tr1::shared_ptr new_frame(new Frame(new_frame_number, 1, 1, "#000000", samples_in_frame, file_reader->info.channels)); - // difference between previous frame and current frame - int previous_diff = abs(new_frame_number - previous_value); + // Copy the image from the new frame + //new_frame->AddImage(file_reader->GetFrame(new_frame_number)->GetImage()); - // Are we repeating frames or skipping frames? - if ((previous_value == new_frame_number && frame_number > 0) || - (next_value == new_frame_number && frame_number < time.Values.size())) + + // Get delta (difference in previous Y value) + int delta = int(round(time.GetDelta(frame_number))); + + // Init audio vars + int sample_rate = file_reader->GetFrame(new_frame_number)->GetAudioSamplesRate(); + int channels = file_reader->info.channels; + int number_of_samples = file_reader->GetFrame(new_frame_number)->GetAudioSamplesCount(); + + // Determine if we are speeding up or slowing down + if (time.GetRepeatFraction(frame_number).den > 1) { - // Slow down audio (to make it fit on more frames) + // SLOW DOWN audio (split audio) + samples = new juce::AudioSampleBuffer(channels, number_of_samples); + samples->clear(); + // Loop through channels, and get audio samples + for (int channel = 0; channel < channels; channel++) + // Get the audio samples for this channel + samples->addFrom(channel, 0, file_reader->GetFrame(new_frame_number)->GetAudioSamples(channel), number_of_samples, 1.0f); + // Reverse the samples (if needed) + if (!time.IsIncreasing(frame_number)) + reverse_buffer(samples); + + // Resample audio to be X times slower (where X is the denominator of the repeat fraction) + resampler->SetBuffer(samples, 1.0 / time.GetRepeatFraction(frame_number).den); + + // Resample data, and return new buffer pointer + AudioSampleBuffer *buffer = resampler->GetResampledBuffer(); + int resampled_buffer_size = buffer->getNumSamples(); + + // Just take the samples we need for the requested frame + int start = (number_of_samples * (time.GetRepeatFraction(frame_number).num - 1)); + for (int channel = 0; channel < channels; channel++) + // Add new (slower) samples, to the frame object + new_frame->AddAudio(channel, 0, buffer->getSampleData(channel, start), number_of_samples, 1.0f); + + // Clean up + buffer = NULL; } - else if (previous_diff > 0 && previous_diff <= 30 && frame_number > 0) + else if (abs(delta) > 1 && abs(delta) < 100) { - // Speed up audio (to make it fit on less frames) + // SPEED UP (multiple frames of audio), as long as it's not more than X frames + samples = new juce::AudioSampleBuffer(channels, number_of_samples * abs(delta)); + samples->clear(); + int start = 0; + if (delta > 0) + { + // Loop through each frame in this delta + for (int delta_frame = new_frame_number - (delta - 1); delta_frame <= new_frame_number; delta_frame++) + { + // buffer to hold detal samples + int number_of_delta_samples = file_reader->GetFrame(delta_frame)->GetAudioSamplesCount(); + AudioSampleBuffer* delta_samples = new juce::AudioSampleBuffer(channels, number_of_delta_samples); + delta_samples->clear(); + for (int channel = 0; channel < channels; channel++) + delta_samples->addFrom(channel, 0, file_reader->GetFrame(delta_frame)->GetAudioSamples(channel), number_of_delta_samples, 1.0f); + + // Reverse the samples (if needed) + if (!time.IsIncreasing(frame_number)) + reverse_buffer(delta_samples); + + // Copy the samples to + for (int channel = 0; channel < channels; channel++) + // Get the audio samples for this channel + samples->addFrom(channel, start, delta_samples->getSampleData(channel), number_of_delta_samples, 1.0f); + + // Clean up + delete delta_samples; + delta_samples = NULL; + + // Increment start position + start += number_of_delta_samples; + } + } + else + { + // Loop through each frame in this delta + for (int delta_frame = new_frame_number - (delta + 1); delta_frame >= new_frame_number; delta_frame--) + { + // buffer to hold delta samples + int number_of_delta_samples = file_reader->GetFrame(delta_frame)->GetAudioSamplesCount(); + AudioSampleBuffer* delta_samples = new juce::AudioSampleBuffer(channels, number_of_delta_samples); + delta_samples->clear(); + + for (int channel = 0; channel < channels; channel++) + delta_samples->addFrom(channel, 0, file_reader->GetFrame(delta_frame)->GetAudioSamples(channel), number_of_delta_samples, 1.0f); + + // Reverse the samples (if needed) + if (!time.IsIncreasing(frame_number)) + reverse_buffer(delta_samples); + + // Copy the samples to + for (int channel = 0; channel < channels; channel++) + // Get the audio samples for this channel + samples->addFrom(channel, start, delta_samples->getSampleData(channel), number_of_delta_samples, 1.0f); + + // Clean up + delete delta_samples; + delta_samples = NULL; + + // Increment start position + start += number_of_delta_samples; + } + } + + // Resample audio to be X times faster (where X is the delta of the repeat fraction) + resampler->SetBuffer(samples, float(number_of_samples) / float(start)); + + // Resample data, and return new buffer pointer + AudioSampleBuffer *buffer = resampler->GetResampledBuffer(); + int resampled_buffer_size = buffer->getNumSamples(); + + // Add the newly resized audio samples to the current frame + for (int channel = 0; channel < channels; channel++) + // Add new (slower) samples, to the frame object + new_frame->AddAudio(channel, 0, buffer->getSampleData(channel), number_of_samples, 1.0f); + + // Clean up + buffer = NULL; + } + else if (!time.IsIncreasing(frame_number)) + { + // Use the samples on this frame, but reverse them + samples = new juce::AudioSampleBuffer(channels, number_of_samples); + samples->clear(); + + // Loop through channels, and get audio samples + for (int channel = 0; channel < channels; channel++) + // Get the audio samples for this channel + samples->addFrom(channel, 0, new_frame->GetAudioSamples(channel), number_of_samples, 1.0f); + + // reverse the samples + reverse_buffer(samples); + + // Add reversed samples to the frame object + for (int channel = 0; channel < channels; channel++) + new_frame->AddAudio(channel, 0, samples->getSampleData(channel), number_of_samples, 1.0f); } - - + // clean up + //delete resampler; + //resampler = NULL; + cout << "samples: "<< samples << endl; + delete samples; + samples = NULL; } + + // Return new time mapped frame + return new_frame; + } // Apply basic image processing (scale, rotate, move, etc...) @@ -261,3 +433,17 @@ int Clip::adjust_frame_number_minimum(int frame_number) return frame_number; } + +// Calculate the # of samples per video frame (for a specific frame number) +int Clip::GetSamplesPerFrame(int frame_number, Fraction rate) +{ + // Get the total # of samples for the previous frame, and the current frame (rounded) + double fps = rate.Reciprocal().ToDouble(); + double previous_samples = round((file_reader->info.sample_rate * fps) * (frame_number - 1)); + double total_samples = round((file_reader->info.sample_rate * fps) * frame_number); + + // Subtract the previous frame's total samples with this frame's total samples. Not all sample rates can + // be evenly divided into frames, so each frame can have have different # of samples. + double samples_per_frame = total_samples - previous_samples; + return samples_per_frame; +} diff --git a/src/Frame.cpp b/src/Frame.cpp index a8f1d590..b590f016 100644 --- a/src/Frame.cpp +++ b/src/Frame.cpp @@ -277,12 +277,6 @@ float* Frame::GetInterleavedAudioSamples(int new_sample_rate, AudioResampler* re int num_of_channels = audio->getNumChannels(); int num_of_samples = audio->getNumSamples(); -// DEBUG CODE -// if (number == 1) -// for (int s = 0; s < num_of_samples; s++) -// for (int c = 0; c < num_of_channels; c++) -// cout << buffer->getSampleData(c)[s] << endl; - // Resample to new sample rate (if needed) if (new_sample_rate != sample_rate) { @@ -484,6 +478,9 @@ void Frame::AddImage(tr1::shared_ptr new_image, bool only_odd_lin // Add audio samples to a specific channel void Frame::AddAudio(int destChannel, int destStartSample, const float* source, int numSamples, float gainToApplyToSource = 1.0f) { + // Always clear the range of samples first + audio->clear(destChannel, destStartSample, numSamples); + // Add samples to frame's audio buffer audio->addFrom(destChannel, destStartSample, source, numSamples, gainToApplyToSource); } diff --git a/src/KeyFrame.cpp b/src/KeyFrame.cpp index e3cfa7e5..08c93638 100644 --- a/src/KeyFrame.cpp +++ b/src/KeyFrame.cpp @@ -266,6 +266,16 @@ Point& Keyframe::GetPoint(int index) throw(OutOfBoundsPoint) { throw OutOfBoundsPoint("Invalid point requested", index, Points.size()); } +// Get the number of values (i.e. coordinates on the X axis) +int Keyframe::GetLength() { + // Check if it needs to be processed + if (needs_update) + Process(); + + // return the size of the Values vector + return Values.size(); +} + // Remove a point by matching a coordinate void Keyframe::RemovePoint(Point p) throw(OutOfBoundsPoint) { // mark as dirty diff --git a/src/Main.cpp b/src/Main.cpp index 8a39490e..b5a2e681 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -16,14 +16,14 @@ void FrameReady(int number) int main() { - Keyframe time; - //time.AddPoint(1, 300); - time.AddPoint(1, 500, LINEAR); - time.AddPoint(400, 100); - time.AddPoint(500, 500); - time.PrintValues(); - - return 0; +// Keyframe time; +// //time.AddPoint(1, 300); +// time.AddPoint(1, 500, LINEAR); +// time.AddPoint(400, 100); +// time.AddPoint(500, 500); +// time.PrintValues(); +// +// return 0; // openshot::FFmpegReader r1("/home/jonathan/Videos/sintel-1024-stereo.mp4"); @@ -34,70 +34,67 @@ int main() // return 0; -// // Create timeline -// Timeline t(640, 360, Framerate(24,1)); -// -// // Add some clips -// Clip c1("/home/jonathan/Videos/sintel-1024-stereo.mp4"); -// c1.Position(0.0); -// -//// c1.time.AddPoint(1, 50); -//// c1.time.AddPoint(100, 1); -//// c1.time.AddPoint(200, 90); -//// c1.time.PrintValues(); -// -// //c1.time.AddPoint(500, 500, LINEAR); -// c1.time.AddPoint(1, 300); -// c1.time.AddPoint(200, 500, LINEAR); + // Create timeline + Timeline t(640, 360, Framerate(24,1)); + + // Add some clips + Clip c1(new FFmpegReader("/home/jonathan/Videos/sintel-1024-stereo.mp4")); + c1.Position(0.0); + + c1.time.AddPoint(1, 500, LINEAR); + c1.time.AddPoint(500, 1, LINEAR); +// c1.time.AddPoint(1, 500, LINEAR); // c1.time.AddPoint(400, 100); // c1.time.AddPoint(500, 500); -// -// // Add clips -// t.AddClip(&c1); -// -// -// // Create a writer -// FFmpegWriter w("/home/jonathan/output.webm"); -// w.DisplayInfo(); -// -// // Set options -// w.SetAudioOptions(true, "libvorbis", 44100, 2, 128000, false); -// w.SetVideoOptions(true, "libvpx", Fraction(24, 1), 640, 360, Fraction(1,1), false, false, 2000000); -// -// // Prepare Streams -// w.PrepareStreams(); -// -// // Write header -// w.WriteHeader(); -// -// // Output stream info -// w.OutputStreamInfo(); -// -// for (int frame = 1; frame <= 500; frame++) -// { -// tr1::shared_ptr f = t.GetFrame(frame); -// if (f) -// { -// //f->AddOverlayNumber(0); -// -// // Write frame -// //cout << "queue frame " << frame << endl; -// cout << "queue frame " << frame << " (" << f->number << ", " << f << ")" << endl; -// w.WriteFrame(f); -// } -// } -// -// // Write Footer -// w.WriteTrailer(); -// -// // Close writer & reader -// w.Close(); -// -// // Close timeline -// t.Close(); -// -// cout << "Successfully Finished Timeline DEMO" << endl; -// return 0; + c1.time.PrintValues(); + + // Add clips + t.AddClip(&c1); + + + // Create a writer + FFmpegWriter w("/home/jonathan/output.mp3"); + w.DisplayInfo(); + + // Set options + w.SetAudioOptions(true, "libmp3lame", 44100, 2, 128000, false); + //w.SetAudioOptions(true, "libvorbis", 44100, 2, 128000, false); + //w.SetVideoOptions(true, "libvpx", Fraction(24, 1), 640, 360, Fraction(1,1), false, false, 2000000); + + // Prepare Streams + w.PrepareStreams(); + + // Write header + w.WriteHeader(); + + // Output stream info + w.OutputStreamInfo(); + + for (int frame = 1; frame <= 500; frame++) + { + tr1::shared_ptr f = t.GetFrame(frame); + if (f) + { + //f->AddOverlayNumber(0); + + // Write frame + //cout << "queue frame " << frame << endl; + cout << "queue frame " << frame << " (" << f->number << ", " << f << ")" << endl; + w.WriteFrame(f); + } + } + + // Write Footer + w.WriteTrailer(); + + // Close writer & reader + w.Close(); + + // Close timeline + t.Close(); + + cout << "Successfully Finished Timeline DEMO" << endl; + return 0; @@ -146,65 +143,65 @@ int main() // openshot::FFmpegReader r("/home/jonathan/Aptana Studio Workspace/OpenShotLibrary/src/examples/asdf.wdf"); - openshot::FrameMapper r(&r1, Framerate(30,1), PULLDOWN_CLASSIC); - - // Display debug info - r.Open(); - r.DisplayInfo(); - - // Create a writer - FFmpegWriter w("/home/jonathan/output.webm"); - w.DisplayInfo(); - - // Set options - w.SetAudioOptions(true, "libvorbis", 44100, 2, 128000, false); - w.SetVideoOptions(true, "libvpx", Fraction(30, 1), 640, 360, Fraction(1,1), false, false, 2000000); - - // Prepare Streams - w.PrepareStreams(); - - // Set Options -// w.SetOption(VIDEO_STREAM, "quality", "good"); -// w.SetOption(VIDEO_STREAM, "g", "120"); -// w.SetOption(VIDEO_STREAM, "qmin", "11"); -// w.SetOption(VIDEO_STREAM, "qmax", "51"); -// w.SetOption(VIDEO_STREAM, "profile", "0"); -// w.SetOption(VIDEO_STREAM, "speed", "0"); -// w.SetOption(VIDEO_STREAM, "level", "216"); -// w.SetOption(VIDEO_STREAM, "rc_lookahead", "16"); -// w.SetOption(VIDEO_STREAM, "rc_min_rate", "100000"); -// w.SetOption(VIDEO_STREAM, "rc_max_rate", "24000000"); -// w.SetOption(VIDEO_STREAM, "slices", "4"); -// w.SetOption(VIDEO_STREAM, "arnr_max_frames", "7"); -// w.SetOption(VIDEO_STREAM, "arnr_strength", "5"); -// w.SetOption(VIDEO_STREAM, "arnr_type", "3"); - - // Write header - w.WriteHeader(); - - // Output stream info - w.OutputStreamInfo(); - - //Frame *f = r.GetFrame(1); - - //for (int frame = 131; frame >= 1; frame--) - for (int frame = 1; frame <= 500; frame++) - { - tr1::shared_ptr f = r.GetFrame(frame); - //f->AddOverlayNumber(0); - //f->Display(); - - // Write frame - cout << "queue frame " << frame << endl; - w.WriteFrame(f); - } - - // Write Footer - w.WriteTrailer(); - - // Close writer & reader - w.Close(); - r.Close(); +// openshot::FrameMapper r(&r1, Framerate(30,1), PULLDOWN_CLASSIC); +// +// // Display debug info +// r.Open(); +// r.DisplayInfo(); +// +// // Create a writer +// FFmpegWriter w("/home/jonathan/output.webm"); +// w.DisplayInfo(); +// +// // Set options +// w.SetAudioOptions(true, "libvorbis", 44100, 2, 128000, false); +// w.SetVideoOptions(true, "libvpx", Fraction(30, 1), 640, 360, Fraction(1,1), false, false, 2000000); +// +// // Prepare Streams +// w.PrepareStreams(); +// +// // Set Options +//// w.SetOption(VIDEO_STREAM, "quality", "good"); +//// w.SetOption(VIDEO_STREAM, "g", "120"); +//// w.SetOption(VIDEO_STREAM, "qmin", "11"); +//// w.SetOption(VIDEO_STREAM, "qmax", "51"); +//// w.SetOption(VIDEO_STREAM, "profile", "0"); +//// w.SetOption(VIDEO_STREAM, "speed", "0"); +//// w.SetOption(VIDEO_STREAM, "level", "216"); +//// w.SetOption(VIDEO_STREAM, "rc_lookahead", "16"); +//// w.SetOption(VIDEO_STREAM, "rc_min_rate", "100000"); +//// w.SetOption(VIDEO_STREAM, "rc_max_rate", "24000000"); +//// w.SetOption(VIDEO_STREAM, "slices", "4"); +//// w.SetOption(VIDEO_STREAM, "arnr_max_frames", "7"); +//// w.SetOption(VIDEO_STREAM, "arnr_strength", "5"); +//// w.SetOption(VIDEO_STREAM, "arnr_type", "3"); +// +// // Write header +// w.WriteHeader(); +// +// // Output stream info +// w.OutputStreamInfo(); +// +// //Frame *f = r.GetFrame(1); +// +// //for (int frame = 131; frame >= 1; frame--) +// for (int frame = 1; frame <= 500; frame++) +// { +// tr1::shared_ptr f = r.GetFrame(frame); +// //f->AddOverlayNumber(0); +// //f->Display(); +// +// // Write frame +// cout << "queue frame " << frame << endl; +// w.WriteFrame(f); +// } +// +// // Write Footer +// w.WriteTrailer(); +// +// // Close writer & reader +// w.Close(); +// r.Close(); cout << "Successfully executed Main.cpp!" << endl;