1
0
mirror of https://github.com/strawberrymusicplayer/strawberry synced 2025-01-27 15:49:43 +01:00

GstEnginePipeline: Simplify next uri reset code

This commit is contained in:
Jonas Kvinge 2024-11-10 15:38:00 +01:00
parent 04064ebf68
commit 6612eeb9e3
2 changed files with 72 additions and 56 deletions

View File

@ -134,8 +134,10 @@ GstEnginePipeline::GstEnginePipeline(QObject *parent)
buffering_(false),
pending_state_(GST_STATE_NULL),
pending_seek_nanosec_(-1),
pending_seek_ready_previous_state_(GST_STATE_NULL),
last_known_position_ns_(0),
next_uri_set_(false),
next_uri_need_reset_(false),
next_uri_reset_(false),
volume_set_(false),
volume_internal_(-1.0),
@ -1653,54 +1655,38 @@ void GstEnginePipeline::StateChangedMessageReceived(GstMessage *msg) {
qLog(Debug) << "Pipeline state changed from" << GstStateText(old_state) << "to" << GstStateText(new_state);
if (!pipeline_active_.value() && (new_state == GST_STATE_PAUSED || new_state == GST_STATE_PLAYING)) {
qLog(Debug) << "Pipeline is active";
pipeline_active_ = true;
if (pipeline_connected_.value()) {
if (!volume_set_.value()) {
SetVolume(volume_percent_.value());
}
if (pending_seek_nanosec_.value() != -1) {
if (next_uri_reset_.value() && new_state == GST_STATE_PAUSED) {
qLog(Debug) << "Reverting next uri and going to playing state.";
next_uri_reset_ = false;
pending_state_ = GST_STATE_PLAYING;
SeekDelayed(pending_seek_nanosec_.value());
pending_seek_nanosec_ = -1;
}
else {
SeekAsync(pending_seek_nanosec_.value());
pending_seek_nanosec_ = -1;
}
}
}
const bool pipeline_active = new_state == GST_STATE_PAUSED || new_state == GST_STATE_PLAYING;
if (pipeline_active != pipeline_active_.value()) {
pipeline_active_ = pipeline_active;
qLog(Debug) << "Pipeline is" << (pipeline_active ? "active" : "inactive");
}
else if (pipeline_active_.value() && new_state != GST_STATE_PAUSED && new_state != GST_STATE_PLAYING) {
qLog(Debug) << "Pipeline is inactive";
pipeline_active_ = false;
if (next_uri_set_.value() && new_state == GST_STATE_READY) {
next_uri_set_ = false;
{
QMutexLocker l(&mutex_url_);
g_object_set(G_OBJECT(pipeline_), "uri", gst_url_.constData(), nullptr);
}
if (pending_seek_nanosec_ == -1) {
qLog(Debug) << "Reverting next uri and going to playing state.";
SetStateAsync(GST_STATE_PLAYING);
}
else {
qLog(Debug) << "Reverting next uri and going to paused state.";
next_uri_reset_ = true;
SetStateAsync(GST_STATE_PAUSED);
}
}
if (new_state == GST_STATE_NULL && !finished_.value() && finish_requested_.value()) {
finished_ = true;
Q_EMIT Finished();
return;
}
if (pipeline_active_.value() && !buffering_.value()) {
if (pending_seek_nanosec_.value() != -1 && new_state == GST_STATE_PAUSED) {
SeekAsync(pending_seek_nanosec_.value());
pending_seek_nanosec_ = -1;
if (pipeline_connected_.value() && pipeline_active_.value() && !volume_set_.value()) {
SetVolume(volume_percent_.value());
}
if (next_uri_set_.value() && next_uri_need_reset_.value() && new_state == GST_STATE_READY && pending_seek_nanosec_.value() != -1) {
qLog(Debug) << "Reverting next uri and going to pause state.";
next_uri_set_ = false;
{
QMutexLocker l(&mutex_url_);
g_object_set(G_OBJECT(pipeline_), "uri", gst_url_.constData(), nullptr);
}
next_uri_need_reset_ = false;
next_uri_reset_ = true;
SetStateAsync(GST_STATE_PAUSED);
return;
}
if (pipeline_active_.value() && !buffering_.value() && !next_uri_need_reset_.value()) {
if (pending_seek_nanosec_.value() != -1) {
ProcessPendingSeek(new_state);
}
else if (pending_state_.value() != GST_STATE_NULL) {
SetStateAsync(pending_state_.value());
@ -1712,11 +1698,6 @@ void GstEnginePipeline::StateChangedMessageReceived(GstMessage *msg) {
}
}
if (new_state == GST_STATE_NULL && !finished_.value() && finish_requested_.value()) {
finished_ = true;
Q_EMIT Finished();
}
}
void GstEnginePipeline::BufferingMessageReceived(GstMessage *msg) {
@ -1746,9 +1727,8 @@ void GstEnginePipeline::BufferingMessageReceived(GstMessage *msg) {
qLog(Debug) << "Buffering finished";
buffering_ = false;
Q_EMIT BufferingFinished();
if (pending_seek_nanosec_.value() != -1) {
SeekAsync(pending_seek_nanosec_.value());
pending_seek_nanosec_ = -1;
if (pending_seek_nanosec_.value() != -1 && !next_uri_need_reset_.value()) {
ProcessPendingSeek(state());
}
else if (pending_state_.value() != GST_STATE_NULL) {
SetStateAsync(pending_state_.value());
@ -1867,14 +1847,20 @@ bool GstEnginePipeline::Seek(const qint64 nanosec) {
return true;
}
if (!pipeline_connected_.value() || !pipeline_active_.value()) {
if (next_uri_set_.value() || next_uri_reset_.value()) {
qLog(Debug) << "Seek to" << nanosec << "requested, but next uri is set, adding to pending seek to revert next uri.";
pending_seek_nanosec_ = nanosec;
if (!next_uri_need_reset_.value() && !next_uri_reset_.value()) {
next_uri_need_reset_ = true;
pending_seek_ready_previous_state_ = state();
SetState(GST_STATE_READY);
}
return true;
}
if (next_uri_set_.value()) {
if (!pipeline_connected_.value() || !pipeline_active_.value()) {
qLog(Debug) << "Seek to" << nanosec << "requested, but pipeline is not active, adding to pending seek.";
pending_seek_nanosec_ = nanosec;
SetState(GST_STATE_READY);
return true;
}
@ -1912,6 +1898,33 @@ void GstEnginePipeline::SeekDelayed(const qint64 nanosec) {
}
void GstEnginePipeline::ProcessPendingSeek(const GstState state) {
if (pending_seek_nanosec_.value() == -1) return;
if (next_uri_reset_.value()) {
if (state != GST_STATE_PAUSED) {
return;
}
if (pending_seek_ready_previous_state_.value() == GST_STATE_NULL) {
pending_seek_ready_previous_state_ = GST_STATE_PLAYING;
}
qLog(Debug) << "Next uri is reset, seeking and going back to" << GstStateText(pending_seek_ready_previous_state_.value());
if (pending_seek_ready_previous_state_.value() != GST_STATE_PAUSED) {
pending_state_ = pending_seek_ready_previous_state_.value();
}
pending_seek_ready_previous_state_ = GST_STATE_NULL;
next_uri_reset_ = false;
SeekDelayed(pending_seek_nanosec_.value());
}
else {
SeekAsync(pending_seek_nanosec_.value());
}
pending_seek_nanosec_ = -1;
}
void GstEnginePipeline::SetVolume(const uint volume_percent) {
if (volume_) {
@ -2171,4 +2184,3 @@ void GstEnginePipeline::RemoveAllBufferConsumers() {
QMutexLocker l(&mutex_buffer_consumers_);
buffer_consumers_.clear();
}

View File

@ -194,6 +194,8 @@ class GstEnginePipeline : public QObject {
void Disconnect();
void ResumeFaderAsync();
void ProcessPendingSeek(const GstState state);
private Q_SLOTS:
void SetStateFinishedSlot(const GstState state, const GstStateChangeReturn state_change_return);
void SetFaderVolume(const qreal volume);
@ -313,6 +315,7 @@ class GstEnginePipeline : public QObject {
mutex_protected<GstState> pending_state_;
mutex_protected<qint64> pending_seek_nanosec_;
mutex_protected<GstState> pending_seek_ready_previous_state_;
// We can only use gst_element_query_position() when the pipeline is in
// PAUSED nor PLAYING state. Whenever we get a new position (e.g. after a correct call to gst_element_query_position() or after a seek), we store
@ -321,6 +324,7 @@ class GstEnginePipeline : public QObject {
// Complete the transition to the next song when it starts playing
mutex_protected<bool> next_uri_set_;
mutex_protected<bool> next_uri_need_reset_;
mutex_protected<bool> next_uri_reset_;
mutex_protected<bool> volume_set_;