From 773882222b42ccc4ee38a4db69ce838d2322d693 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Thu, 21 Mar 2019 00:36:57 +1100 Subject: [PATCH] detect failure to open file, fixes #608 --- rendering/cacher.cpp | 44 +++++++++++++++++++++++++++++++++++++------- rendering/cacher.h | 7 +++++++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/rendering/cacher.cpp b/rendering/cacher.cpp index d7082b52d..8d23fe99b 100644 --- a/rendering/cacher.cpp +++ b/rendering/cacher.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "project/projectelements.h" @@ -39,6 +40,7 @@ #include "panels/panels.h" #include "global/config.h" #include "global/debug.h" +#include "ui/mainwindow.h" // Enable verbose audio messages - good for debugging reversed audio //#define AUDIOWARNINGS @@ -847,7 +849,12 @@ void Cacher::WakeMainThread() Cacher::Cacher(Clip* c) : clip(c), frame_(nullptr), - pkt(nullptr) + pkt(nullptr), + formatCtx(nullptr), + opts(nullptr), + filter_graph(nullptr), + codecCtx(nullptr), + is_valid_state_(false) {} void Cacher::OpenWorker() { @@ -911,6 +918,7 @@ void Cacher::OpenWorker() { char err[1024]; av_strerror(errCode, err, 1024); qCritical() << "Could not open" << filename << "-" << err; + olive::MainWindow->statusBar()->showMessage(tr("Could not open %1 - %2").arg(filename, err)); return; } @@ -919,6 +927,7 @@ void Cacher::OpenWorker() { char err[1024]; av_strerror(errCode, err, 1024); qCritical() << "Could not open" << filename << "-" << err; + olive::MainWindow->statusBar()->showMessage(tr("Could not open %1 - %2").arg(filename, err)); return; } @@ -1083,6 +1092,8 @@ void Cacher::OpenWorker() { } qInfo() << "Clip opened on track" << clip->track() << "(took" << (QDateTime::currentMSecsSinceEpoch() - time_start) << "ms)"; + + is_valid_state_ = true; } void Cacher::CacheWorker() { @@ -1112,17 +1123,27 @@ void Cacher::CloseWorker() { } if (clip->media() != nullptr && clip->media()->get_type() == MEDIA_TYPE_FOOTAGE) { - avfilter_graph_free(&filter_graph); + if (filter_graph != nullptr) { + avfilter_graph_free(&filter_graph); + filter_graph = nullptr; + } - avcodec_close(codecCtx); - avcodec_free_context(&codecCtx); + if (codecCtx != nullptr) { + avcodec_close(codecCtx); + avcodec_free_context(&codecCtx); + codecCtx = nullptr; + } - av_dict_free(&opts); + if (opts != nullptr) { + av_dict_free(&opts); + } // protection for get_timebase() stream = nullptr; - avformat_close_input(&formatCtx); + if (formatCtx != nullptr) { + avformat_close_input(&formatCtx); + } } clip->reset(); @@ -1144,11 +1165,16 @@ void Cacher::run() { queued_ = false; if (!caching_) { break; - } else { + } else if (is_valid_state_) { CacheWorker(); + } else { + // main thread waits until cacher starts fully, but the cacher can't run, so we just wake it up here + WakeMainThread(); } } + is_valid_state_ = false; + CloseWorker(); clip->state_change_lock.unlock(); @@ -1169,6 +1195,10 @@ void Cacher::Open() void Cacher::Cache(long playhead, bool scrubbing, QVector& nests, int playback_speed) { + if (!is_valid_state_) { + return; + } + if (clip->media_stream() != nullptr && queue_.size() > 0 && clip->media_stream()->infinite_length) { diff --git a/rendering/cacher.h b/rendering/cacher.h index 57fca0e75..2b5f827da 100644 --- a/rendering/cacher.h +++ b/rendering/cacher.h @@ -465,6 +465,13 @@ private: */ bool caching_; + /** + * @brief Internal variable for whether the current Cacher state is valid or not + * + * If there was an error opening the Cacher for any reason, this will be false. + */ + bool is_valid_state_; + /** * @brief Internal function for opening the file handles and decoder *