From 183b0714e2b574a94c5707edeceb2d3d72165eeb Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Fri, 16 Sep 2016 17:43:26 -0500 Subject: [PATCH] Added a new optimized constructor to some readers (FFmpegReader, QtImageReader, ImageReader) to not Open() in the constructor, which dramatically speeds up creating hundreds of Readers (i.e. when opening a project). This is really only useful when inflating the reader with Json right after you instantiate it... --- include/FFmpegReader.h | 5 +++++ include/ImageReader.h | 5 +++++ include/QtImageReader.h | 5 +++++ include/ReaderBase.h | 8 +------- src/Clip.cpp | 6 +++--- src/FFmpegReader.cpp | 27 +++++++++++++++++++++++++-- src/ImageReader.cpp | 9 +++++++++ src/QtImageReader.cpp | 9 +++++++++ src/ReaderBase.cpp | 10 ---------- 9 files changed, 62 insertions(+), 22 deletions(-) diff --git a/include/FFmpegReader.h b/include/FFmpegReader.h index 468d6e15..378bb7fd 100644 --- a/include/FFmpegReader.h +++ b/include/FFmpegReader.h @@ -230,6 +230,11 @@ namespace openshot /// frame 1, or it throws one of the following exceptions. FFmpegReader(string path) throw(InvalidFile, NoStreamsFound, InvalidCodec); + /// Constructor for FFmpegReader. This only opens the media file to inspect it's properties + /// if inspect_reader=true. When not inspecting the media file, it's much faster, and useful + /// when you are inflating the object using JSON after instantiating it. + FFmpegReader(string path, bool inspect_reader) throw(InvalidFile, NoStreamsFound, InvalidCodec); + /// Destructor ~FFmpegReader(); diff --git a/include/ImageReader.h b/include/ImageReader.h index 8891c339..2ee98e15 100644 --- a/include/ImageReader.h +++ b/include/ImageReader.h @@ -77,6 +77,11 @@ namespace openshot /// frame 1, or it throws one of the following exceptions. ImageReader(string path) throw(InvalidFile); + /// Constructor for ImageReader. This only opens the media file to inspect it's properties + /// if inspect_reader=true. When not inspecting the media file, it's much faster, and useful + /// when you are inflating the object using JSON after instantiating it. + ImageReader(string path, bool inspect_reader) throw(InvalidFile); + /// Close File void Close(); diff --git a/include/QtImageReader.h b/include/QtImageReader.h index 988341a1..559e2230 100644 --- a/include/QtImageReader.h +++ b/include/QtImageReader.h @@ -80,6 +80,11 @@ namespace openshot /// frame 1, or it throws one of the following exceptions. QtImageReader(string path) throw(InvalidFile); + /// Constructor for QtImageReader. This only opens the media file to inspect it's properties + /// if inspect_reader=true. When not inspecting the media file, it's much faster, and useful + /// when you are inflating the object using JSON after instantiating it. + QtImageReader(string path, bool inspect_reader) throw(InvalidFile); + /// Close File void Close(); diff --git a/include/ReaderBase.h b/include/ReaderBase.h index a3f2d22b..1163839e 100644 --- a/include/ReaderBase.h +++ b/include/ReaderBase.h @@ -116,9 +116,6 @@ namespace openshot /// Display file information in the standard output stream (stdout) void DisplayInfo(); - /// Test method to draw a bitmap on a Qt QGraphicsScene - void DrawFrameOnScene(string path, long _graphics_scene_address); - /// Get the cache object used by this reader (note: not all readers use cache) virtual CacheBase* GetCache() = 0; @@ -130,9 +127,6 @@ namespace openshot /// @param[in] number The frame number that is requested. virtual tr1::shared_ptr GetFrame(long int number) = 0; - /// A thread safe version of GetFrame. - //tr1::shared_ptr GetFrameSafe(int number); - /// Determine if reader is open or closed virtual bool IsOpen() = 0; @@ -146,7 +140,7 @@ namespace openshot virtual void SetJsonValue(Json::Value root) = 0; ///< Load Json::JsonValue into this object /// Set Max Image Size (used for performance optimization) - void SetMaxSize(int width, int height) { max_width = width; max_height = height; }; + void SetMaxSize(int width, int height) { max_width = width; max_height = height; }; /// Open the reader (and start consuming resources, such as images or video files) virtual void Open() = 0; diff --git a/src/Clip.cpp b/src/Clip.cpp index b00d4bb2..a93db20a 100644 --- a/src/Clip.cpp +++ b/src/Clip.cpp @@ -910,20 +910,20 @@ void Clip::SetJsonValue(Json::Value root) { if (type == "FFmpegReader") { // Create new reader - reader = new FFmpegReader(root["reader"]["path"].asString()); + reader = new FFmpegReader(root["reader"]["path"].asString(), false); reader->SetJsonValue(root["reader"]); } else if (type == "QtImageReader") { // Create new reader - reader = new QtImageReader(root["reader"]["path"].asString()); + reader = new QtImageReader(root["reader"]["path"].asString(), false); reader->SetJsonValue(root["reader"]); #ifdef USE_IMAGEMAGICK } else if (type == "ImageReader") { // Create new reader - reader = new ImageReader(root["reader"]["path"].asString()); + reader = new ImageReader(root["reader"]["path"].asString(), false); reader->SetJsonValue(root["reader"]); } else if (type == "TextReader") { diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index 605d4913..00f9d316 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -53,6 +53,29 @@ FFmpegReader::FFmpegReader(string path) throw(InvalidFile, NoStreamsFound, Inval Close(); } +FFmpegReader::FFmpegReader(string path, bool inspect_reader) throw(InvalidFile, NoStreamsFound, InvalidCodec) + : last_frame(0), is_seeking(0), seeking_pts(0), seeking_frame(0), seek_count(0), + audio_pts_offset(99999), video_pts_offset(99999), path(path), is_video_seek(true), check_interlace(false), + check_fps(false), enable_seek(true), is_open(false), seek_audio_frame_found(0), seek_video_frame_found(0), + prev_samples(0), prev_pts(0), pts_total(0), pts_counter(0), is_duration_known(false), largest_frame_processed(0), + current_video_frame(0), has_missing_frames(false), num_packets_since_video_frame(0), num_checks_since_final(0) { + + // Initialize FFMpeg, and register all formats and codecs + av_register_all(); + avcodec_register_all(); + + // Init cache + working_cache.SetMaxBytesFromInfo(OPEN_MP_NUM_PROCESSORS * 30, info.width, info.height, info.sample_rate, info.channels); + missing_frames.SetMaxBytesFromInfo(OPEN_MP_NUM_PROCESSORS * 2, info.width, info.height, info.sample_rate, info.channels); + final_cache.SetMaxBytesFromInfo(OPEN_MP_NUM_PROCESSORS * 2, info.width, info.height, info.sample_rate, info.channels); + + // Open and Close the reader, to populate it's attributes (such as height, width, etc...) + if (inspect_reader) { + Open(); + Close(); + } +} + FFmpegReader::~FFmpegReader() { if (is_open) // Auto close reader if not already done @@ -198,11 +221,11 @@ void FFmpegReader::Close() // Close all objects, if reader is 'open' if (is_open) { - ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::Close", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1); - // Mark as "closed" is_open = false; + ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::Close", "", -1, "", -1, "", -1, "", -1, "", -1, "", -1); + // Close the codec if (info.has_video) { diff --git a/src/ImageReader.cpp b/src/ImageReader.cpp index 39ceda24..abf0583a 100644 --- a/src/ImageReader.cpp +++ b/src/ImageReader.cpp @@ -36,6 +36,15 @@ ImageReader::ImageReader(string path) throw(InvalidFile) : path(path), is_open(f Close(); } +ImageReader::ImageReader(string path, bool inspect_reader) throw(InvalidFile) : path(path), is_open(false) +{ + // Open and Close the reader, to populate it's attributes (such as height, width, etc...) + if (inspect_reader) { + Open(); + Close(); + } +} + // Open image file void ImageReader::Open() throw(InvalidFile) { diff --git a/src/QtImageReader.cpp b/src/QtImageReader.cpp index 3ff479a3..5bfecc59 100644 --- a/src/QtImageReader.cpp +++ b/src/QtImageReader.cpp @@ -36,6 +36,15 @@ QtImageReader::QtImageReader(string path) throw(InvalidFile) : path(path), is_op Close(); } +QtImageReader::QtImageReader(string path, bool inspect_reader) throw(InvalidFile) : path(path), is_open(false) +{ + // Open and Close the reader, to populate it's attributes (such as height, width, etc...) + if (inspect_reader) { + Open(); + Close(); + } +} + // Open image file void QtImageReader::Open() throw(InvalidFile) { diff --git a/src/ReaderBase.cpp b/src/ReaderBase.cpp index 83875c1b..ff5e43c7 100644 --- a/src/ReaderBase.cpp +++ b/src/ReaderBase.cpp @@ -227,13 +227,3 @@ void ReaderBase::SetJsonValue(Json::Value root) { info.audio_timebase.den = root["audio_timebase"]["den"].asInt(); } } - -// Test method to draw a bitmap on a Qt QGraphicsScene -void ReaderBase::DrawFrameOnScene(string path, long _graphics_scene_address) { - - // Get pixmap - QGraphicsScene *scene = reinterpret_cast(_graphics_scene_address); - QGraphicsPixmapItem *item = new QGraphicsPixmapItem(QPixmap(QString(path.c_str()))); - scene->addItem(item); - -}