GstEnginePipeline: Make sure all set states are finished before finishing pipeline

This commit is contained in:
Jonas Kvinge
2025-01-05 18:58:03 +01:00
parent be8097919b
commit 7afae70bb0
2 changed files with 24 additions and 4 deletions

View File

@@ -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<GstStateChangeReturn> GstEnginePipeline::SetState(const GstState state)
qLog(Debug) << "Setting pipeline" << id() << "state to" << GstStateText(state);
++set_state_in_progress_;
QFutureWatcher<GstStateChangeReturn> *watcher = new QFutureWatcher<GstStateChangeReturn>();
QObject::connect(watcher, &QFutureWatcher<GstStateChangeReturn>::finished, this, [this, watcher, state]() {
const GstStateChangeReturn state_change_return = watcher->result();
@@ -1815,13 +1829,15 @@ QFuture<GstStateChangeReturn> 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();
}

View File

@@ -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<bool> about_to_finish_;
mutex_protected<bool> finish_requested_;
mutex_protected<bool> finished_;
mutex_protected<int> set_state_in_progress_;
mutex_protected<int> set_state_async_in_progress_;
};
using GstEnginePipelinePtr = SharedPtr<GstEnginePipeline>;