diff --git a/include/DummyReader.h b/include/DummyReader.h new file mode 100644 index 00000000..90259cc3 --- /dev/null +++ b/include/DummyReader.h @@ -0,0 +1,66 @@ +#ifndef OPENSHOT_DUMMY_READER_H +#define OPENSHOT_DUMMY_READER_H + +/** + * \file + * \brief Header file for ImageReader class + * \author Copyright (c) 2011 Jonathan Thomas + */ + +#include "FileReaderBase.h" + +#include +#include +#include +#include +#include +#include +#include "Magick++.h" +#include "Cache.h" +#include "Exceptions.h" +#include "FileReaderBase.h" +#include "FrameRate.h" + +using namespace std; + +namespace openshot +{ + /** + * \brief This class is used as a simple, dummy reader, which always returns a blank frame, and + * can be created with any framerate or samplerate. This is useful in unit tests that need to test + * different framerates or samplerates. + */ + class DummyReader : public FileReaderBase + { + private: + tr1::shared_ptr image_frame; + Framerate fps; + float duration; + int sample_rate; + int width; + int height; + int channels; + bool is_open; + + public: + + /// Constructor for DummyReader. + DummyReader(Framerate fps, int width, int height, int sample_rate, int channels, float duration); + + /// Close File + void Close(); + + /// Get an openshot::Frame object for a specific frame number of this reader. All numbers + /// return the same Frame, since they all share the same image data. + /// + /// @returns The requested frame (containing the image) + /// @param[requested_frame] number The frame number that is requested. + tr1::shared_ptr GetFrame(int requested_frame) throw(ReaderClosed); + + /// Open File - which is called by the constructor automatically + void Open() throw(InvalidFile); + }; + +} + +#endif diff --git a/include/OpenShot.h b/include/OpenShot.h index 01fcca27..3acf2118 100644 --- a/include/OpenShot.h +++ b/include/OpenShot.h @@ -30,6 +30,7 @@ #include "Cache.h" #include "Clip.h" #include "Coordinate.h" +#include "DummyReader.h" #include "Exceptions.h" #include "FileReaderBase.h" #include "FileWriterBase.h" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ee3b5109..5c5e3fdf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,6 +45,7 @@ add_library(openshot SHARED Cache.cpp Clip.cpp Coordinate.cpp + DummyReader.cpp FileReaderBase.cpp FileWriterBase.cpp FFmpegReader.cpp diff --git a/src/DummyReader.cpp b/src/DummyReader.cpp new file mode 100644 index 00000000..b209d10a --- /dev/null +++ b/src/DummyReader.cpp @@ -0,0 +1,89 @@ +#include "../include/DummyReader.h" + +using namespace openshot; + +// Constructor for DummyReader. Pass a framerate and samplerate. +DummyReader::DummyReader(Framerate fps, int width, int height, int sample_rate, int channels, float duration) : + fps(fps), width(width), height(height), sample_rate(sample_rate), channels(channels), duration(duration) +{ + // Init FileInfo struct (clear all values) + InitFileInfo(); + + // Open and Close the reader, to populate it's attributes (such as height, width, etc...) + Open(); + Close(); +} + +// Open image file +void DummyReader::Open() throw(InvalidFile) +{ + // Open reader if not already open + if (!is_open) + { + // Create or get frame object + image_frame = tr1::shared_ptr(new Frame(1, width, height, "#000000", sample_rate, channels)); + + // Add Image data to frame + image_frame->AddImage(new Magick::Image(Magick::Geometry(width, height), Magick::Color("#000000"))); + + // Update image properties + info.has_audio = false; + info.has_video = true; + info.file_size = width * height * sizeof(int); + info.vcodec = "raw"; + info.width = width; + info.height = height; + info.pixel_ratio.num = 1; + info.pixel_ratio.den = 1; + info.duration = duration; + info.fps.num = fps.GetFraction().num; + info.fps.den = fps.GetFraction().den; + info.video_timebase.num = fps.GetFraction().den; + info.video_timebase.den = fps.GetFraction().num; + info.video_length = round(info.duration * info.fps.ToDouble()); + + // Calculate the DAR (display aspect ratio) + Fraction size(info.width * info.pixel_ratio.num, info.height * info.pixel_ratio.den); + + // Reduce size fraction + size.Reduce(); + + // Set the ratio based on the reduced fraction + info.display_ratio.num = size.num; + info.display_ratio.den = size.den; + + // Mark as "open" + is_open = true; + } +} + +// Close image file +void DummyReader::Close() +{ + // Close all objects, if reader is 'open' + if (is_open) + { + // Mark as "closed" + is_open = false; + } +} + +// Get an openshot::Frame object for a specific frame number of this reader. +tr1::shared_ptr DummyReader::GetFrame(int requested_frame) throw(ReaderClosed) +{ + // Check for open reader (or throw exception) + if (!is_open) + throw ReaderClosed("The ImageReader is closed. Call Open() before calling this method.", "dummy"); + + if (image_frame) + { + // Always return same frame (regardless of which frame number was requested) + image_frame->number = requested_frame; + return image_frame; + } + else + // no frame loaded + throw InvalidFile("No frame could be created from this type of file.", "dummy"); +} + + diff --git a/src/ImageReader.cpp b/src/ImageReader.cpp index 3e2a06f7..164833f3 100644 --- a/src/ImageReader.cpp +++ b/src/ImageReader.cpp @@ -86,8 +86,11 @@ tr1::shared_ptr ImageReader::GetFrame(int requested_frame) throw(ReaderCl throw ReaderClosed("The ImageReader is closed. Call Open() before calling this method.", path); if (image_frame) + { // Always return same frame (regardless of which frame number was requested) + image_frame->number = requested_frame; return image_frame; + } else // no frame loaded throw InvalidFile("No frame could be created from this type of file.", path); diff --git a/src/Main.cpp b/src/Main.cpp index 8a878552..80461b54 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -17,9 +17,9 @@ void FrameReady(int number) int main() { - openshot::FFmpegReader r1("/home/jonathan/Videos/sintel_trailer-720p.mp4"); + openshot::FFmpegReader r1("/home/jonathan/Videos/sintel-1024-stereo.mp4"); r1.Open(); - FrameMapper map(&r1, Framerate(24,1), PULLDOWN_NONE); + FrameMapper map(&r1, Framerate(2,1), PULLDOWN_NONE); map.PrintMapping(); return 0; diff --git a/src/openshot.i b/src/openshot.i index 76c3fb52..0fde639b 100644 --- a/src/openshot.i +++ b/src/openshot.i @@ -8,6 +8,7 @@ #include "../include/Cache.h" #include "../include/Clip.h" #include "../include/Coordinate.h" +#include "../include/DummyReader.h" #include "../include/Exceptions.h" #include "../include/FileReaderBase.h" #include "../include/FileWriterBase.h" @@ -93,6 +94,7 @@ %include "../include/Cache.h" %include "../include/Clip.h" %include "../include/Coordinate.h" +%include "../include/DummyReader.h" %include "../include/Exceptions.h" %include "../include/FileReaderBase.h" %include "../include/FileWriterBase.h" diff --git a/tests/FrameMapper_Tests.cpp b/tests/FrameMapper_Tests.cpp index 2af03ed5..82d792c9 100644 --- a/tests/FrameMapper_Tests.cpp +++ b/tests/FrameMapper_Tests.cpp @@ -7,7 +7,7 @@ using namespace openshot; TEST(FrameMapper_Get_Valid_Frame) { // Create a reader - FFmpegReader r("../../src/examples/test.mp4"); + DummyReader r(Framerate(24,1), 720, 480, 22000, 2, 5.0); // Create mapping between 24 fps and 29.97 fps using classic pulldown FrameMapper mapping(&r, Framerate(30000, 1001), PULLDOWN_CLASSIC); @@ -28,7 +28,7 @@ TEST(FrameMapper_Get_Valid_Frame) TEST(FrameMapper_Invalid_Frame_Too_Small) { // Create a reader - FFmpegReader r("../../src/examples/test.mp4"); + DummyReader r(Framerate(24,1), 720, 480, 22000, 2, 5.0); // Create mapping 24 fps and 29.97 fps FrameMapper mapping(&r, Framerate(30000, 1001), PULLDOWN_CLASSIC); @@ -41,7 +41,7 @@ TEST(FrameMapper_Invalid_Frame_Too_Small) TEST(FrameMapper_Invalid_Frame_Too_Large) { // Create a reader - FFmpegReader r("../../src/examples/test.mp4"); + DummyReader r(Framerate(24,1), 720, 480, 22000, 2, 4.0); // Create mapping 24 fps and 29.97 fps FrameMapper mapping(&r, Framerate(30000, 1001), PULLDOWN_CLASSIC); @@ -53,7 +53,7 @@ TEST(FrameMapper_Invalid_Frame_Too_Large) TEST(FrameMapper_24_fps_to_30_fps_Pulldown_Classic) { // Create a reader - FFmpegReader r("../../src/examples/test.mp4"); + DummyReader r(Framerate(24,1), 720, 480, 22000, 2, 5.0); // Create mapping 24 fps and 29.97 fps FrameMapper mapping(&r, Framerate(30000, 1001), PULLDOWN_CLASSIC); @@ -70,7 +70,7 @@ TEST(FrameMapper_24_fps_to_30_fps_Pulldown_Classic) TEST(FrameMapper_24_fps_to_30_fps_Pulldown_Advanced) { // Create a reader - FFmpegReader r("../../src/examples/test.mp4"); + DummyReader r(Framerate(24,1), 720, 480, 22000, 2, 5.0); // Create mapping 24 fps and 29.97 fps FrameMapper mapping(&r, Framerate(30000, 1001), PULLDOWN_ADVANCED); @@ -90,7 +90,7 @@ TEST(FrameMapper_24_fps_to_30_fps_Pulldown_Advanced) TEST(FrameMapper_24_fps_to_30_fps_Pulldown_None) { // Create a reader - FFmpegReader r("../../src/examples/test.mp4"); + DummyReader r(Framerate(24,1), 720, 480, 22000, 2, 5.0); // Create mapping 24 fps and 29.97 fps FrameMapper mapping(&r, Framerate(30000, 1001), PULLDOWN_NONE); @@ -107,7 +107,7 @@ TEST(FrameMapper_24_fps_to_30_fps_Pulldown_None) TEST(FrameMapper_30_fps_to_24_fps_Pulldown_Classic) { // Create a reader - FFmpegReader r("../../src/examples/test.mp4"); + DummyReader r(Framerate(30000, 1001), 720, 480, 22000, 2, 5.0); // Create mapping between 29.97 fps and 24 fps FrameMapper mapping(&r, Framerate(24, 1), PULLDOWN_CLASSIC); @@ -127,7 +127,7 @@ TEST(FrameMapper_30_fps_to_24_fps_Pulldown_Classic) TEST(FrameMapper_30_fps_to_24_fps_Pulldown_Advanced) { // Create a reader - FFmpegReader r("../../src/examples/test.mp4"); + DummyReader r(Framerate(30000, 1001), 720, 480, 22000, 2, 5.0); // Create mapping between 29.97 fps and 24 fps FrameMapper mapping(&r, Framerate(24, 1), PULLDOWN_ADVANCED); @@ -147,7 +147,7 @@ TEST(FrameMapper_30_fps_to_24_fps_Pulldown_Advanced) TEST(FrameMapper_30_fps_to_24_fps_Pulldown_None) { // Create a reader - FFmpegReader r("../../src/examples/test.mp4"); + DummyReader r(Framerate(30000, 1001), 720, 480, 22000, 2, 5.0); // Create mapping between 29.97 fps and 24 fps FrameMapper mapping(&r, Framerate(24, 1), PULLDOWN_NONE); @@ -164,7 +164,7 @@ TEST(FrameMapper_30_fps_to_24_fps_Pulldown_None) TEST(FrameMapper_MapTime) { // Create a reader - FFmpegReader r("../../src/examples/test.mp4"); + DummyReader r(Framerate(24, 1), 720, 480, 22000, 2, 5.0); // Create mapping 24 fps and 24 fps FrameMapper mapping(&r, Framerate(24, 1), PULLDOWN_NONE);