diff --git a/src/engine/gstenginepipeline.cpp b/src/engine/gstenginepipeline.cpp index daf328c6c..42d75943c 100644 --- a/src/engine/gstenginepipeline.cpp +++ b/src/engine/gstenginepipeline.cpp @@ -174,7 +174,9 @@ GstEnginePipeline::GstEnginePipeline(QObject *parent) logged_unsupported_analyzer_format_(false), about_to_finish_(false), finish_requested_(false), - finished_(false) { + finished_(false), + set_state_in_progress_(0), + set_state_async_in_progress_(0) { eq_band_gains_.reserve(kEqBandCount); for (int i = 0; i < kEqBandCount; ++i) eq_band_gains_ << 0; @@ -419,7 +421,7 @@ bool GstEnginePipeline::Finish() { Disconnect(); - if (IsStateNull()) { + if (IsStateNull() && set_state_async_in_progress_ == 0 && set_state_in_progress_ == 0) { finished_ = true; } else { @@ -1792,7 +1794,17 @@ bool GstEnginePipeline::IsStateNull() const { void GstEnginePipeline::SetStateAsync(const GstState state) { - QMetaObject::invokeMethod(this, "SetState", Qt::QueuedConnection, Q_ARG(GstState, state)); + ++set_state_async_in_progress_; + + QMetaObject::invokeMethod(this, "SetStateAsyncSlot", Qt::QueuedConnection, Q_ARG(GstState, state)); + +} + +void GstEnginePipeline::SetStateAsyncSlot(const GstState state) { + + --set_state_async_in_progress_; + + SetState(state); } @@ -1800,6 +1812,8 @@ QFuture GstEnginePipeline::SetState(const GstState state) qLog(Debug) << "Setting pipeline" << id() << "state to" << GstStateText(state); + ++set_state_in_progress_; + QFutureWatcher *watcher = new QFutureWatcher(); QObject::connect(watcher, &QFutureWatcher::finished, this, [this, watcher, state]() { const GstStateChangeReturn state_change_return = watcher->result(); @@ -1815,13 +1829,15 @@ QFuture GstEnginePipeline::SetState(const GstState state) void GstEnginePipeline::SetStateFinishedSlot(const GstState state, const GstStateChangeReturn state_change_return) { + --set_state_in_progress_; + switch (state_change_return) { case GST_STATE_CHANGE_SUCCESS: case GST_STATE_CHANGE_ASYNC: case GST_STATE_CHANGE_NO_PREROLL: qLog(Debug) << "Pipeline" << id() << "state successfully set to" << GstStateText(state); Q_EMIT SetStateFinished(state_change_return); - if (!finished_.value() && finish_requested_.value()) { + if (!finished_.value() && finish_requested_.value() && set_state_async_in_progress_ == 0 && set_state_in_progress_ == 0) { finished_ = true; Q_EMIT Finished(); } diff --git a/src/engine/gstenginepipeline.h b/src/engine/gstenginepipeline.h index 13e1f618c..e50a51cad 100644 --- a/src/engine/gstenginepipeline.h +++ b/src/engine/gstenginepipeline.h @@ -197,6 +197,7 @@ class GstEnginePipeline : public QObject { void ProcessPendingSeek(const GstState state); private Q_SLOTS: + void SetStateAsyncSlot(const GstState state); void SetStateFinishedSlot(const GstState state, const GstStateChangeReturn state_change_return); void SetFaderVolume(const qreal volume); void FaderTimelineStateChanged(const QTimeLine::State state); @@ -368,6 +369,9 @@ class GstEnginePipeline : public QObject { mutex_protected about_to_finish_; mutex_protected finish_requested_; mutex_protected finished_; + + mutex_protected set_state_in_progress_; + mutex_protected set_state_async_in_progress_; }; using GstEnginePipelinePtr = SharedPtr;