Fix a bug where the engine would skip a song that didn't exist, but then not play the next song.
This commit is contained in:
parent
bbd5b04244
commit
e761f2bdc8
|
@ -24,7 +24,6 @@
|
|||
#include "config.h"
|
||||
#include "gstengine.h"
|
||||
#include "gstenginepipeline.h"
|
||||
#include "core/boundfuturewatcher.h"
|
||||
#include "core/utilities.h"
|
||||
|
||||
#ifdef HAVE_IMOBILEDEVICE
|
||||
|
@ -493,8 +492,8 @@ bool GstEngine::Play(quint64 offset_nanosec) {
|
|||
return false;
|
||||
|
||||
QFuture<GstStateChangeReturn> future = current_pipeline_->SetState(GST_STATE_PLAYING);
|
||||
BoundFutureWatcher<GstStateChangeReturn, quint64>* watcher =
|
||||
new BoundFutureWatcher<GstStateChangeReturn, quint64>(offset_nanosec, this);
|
||||
PlayFutureWatcher* watcher = new PlayFutureWatcher(
|
||||
PlayFutureWatcherArg(offset_nanosec, current_pipeline_.get()), this);
|
||||
watcher->setFuture(future);
|
||||
connect(watcher, SIGNAL(finished()), SLOT(PlayDone()));
|
||||
|
||||
|
@ -502,17 +501,22 @@ bool GstEngine::Play(quint64 offset_nanosec) {
|
|||
}
|
||||
|
||||
void GstEngine::PlayDone() {
|
||||
BoundFutureWatcher<GstStateChangeReturn, quint64>* watcher =
|
||||
static_cast<BoundFutureWatcher<GstStateChangeReturn, quint64>*>(sender());
|
||||
PlayFutureWatcher* watcher = static_cast<PlayFutureWatcher*>(sender());
|
||||
watcher->deleteLater();
|
||||
|
||||
GstStateChangeReturn ret = watcher->result();
|
||||
quint64 offset_nanosec = watcher->data();
|
||||
quint64 offset_nanosec = watcher->data().first;
|
||||
|
||||
if (!current_pipeline_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't dereference this - it might be invalid
|
||||
GstEnginePipeline* dangerous_pipeline = watcher->data().second;
|
||||
if (dangerous_pipeline != current_pipeline_.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ret == GST_STATE_CHANGE_FAILURE) {
|
||||
// Failure, but we got a redirection URL - try loading that instead
|
||||
QUrl redirect_url = current_pipeline_->redirect_url();
|
||||
|
@ -675,6 +679,10 @@ void GstEngine::timerEvent(QTimerEvent* e) {
|
|||
}
|
||||
|
||||
void GstEngine::HandlePipelineError(const QString& message, int domain, int error_code) {
|
||||
GstEnginePipeline* pipeline_sender = qobject_cast<GstEnginePipeline*>(sender());
|
||||
if (!pipeline_sender || pipeline_sender != current_pipeline_.get())
|
||||
return;
|
||||
|
||||
qWarning() << "Gstreamer error:" << message;
|
||||
|
||||
current_pipeline_.reset();
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "bufferconsumer.h"
|
||||
#include "enginebase.h"
|
||||
#include "core/boundfuturewatcher.h"
|
||||
#include "core/timeconstants.h"
|
||||
|
||||
#include <QFuture>
|
||||
|
@ -125,6 +126,9 @@ class GstEngine : public Engine::Base, public BufferConsumer {
|
|||
void PlayDone();
|
||||
|
||||
private:
|
||||
typedef QPair<quint64, GstEnginePipeline*> PlayFutureWatcherArg;
|
||||
typedef BoundFutureWatcher<GstStateChangeReturn, PlayFutureWatcherArg> PlayFutureWatcher;
|
||||
|
||||
// Callbacks
|
||||
static void CanDecodeNewPadCallback(GstElement*, GstPad*, gboolean, gpointer);
|
||||
static void CanDecodeLastCallback(GstElement*, gpointer);
|
||||
|
|
|
@ -54,7 +54,6 @@ GstEnginePipeline::GstEnginePipeline(GstEngine* engine)
|
|||
next_end_offset_nanosec_(-1),
|
||||
ignore_next_seek_(false),
|
||||
ignore_tags_(false),
|
||||
ignore_errors_(false),
|
||||
pipeline_is_initialised_(false),
|
||||
pipeline_is_connected_(false),
|
||||
pending_seek_nanosec_(-1),
|
||||
|
@ -109,7 +108,6 @@ bool GstEnginePipeline::ReplaceDecodeBin(GstElement* new_bin) {
|
|||
// deletion in the main thread
|
||||
}
|
||||
|
||||
ignore_errors_ = false;
|
||||
uridecodebin_ = new_bin;
|
||||
segment_start_ = 0;
|
||||
segment_start_received_ = false;
|
||||
|
@ -310,10 +308,7 @@ GstBusSyncReply GstEnginePipeline::BusCallbackSync(GstBus*, GstMessage* msg, gpo
|
|||
break;
|
||||
|
||||
case GST_MESSAGE_ERROR:
|
||||
if (!instance->ignore_errors_) {
|
||||
instance->ignore_errors_ = true;
|
||||
QtConcurrent::run(instance, &GstEnginePipeline::ErrorMessageReceived, msg);
|
||||
}
|
||||
instance->ErrorMessageReceived(msg);
|
||||
break;
|
||||
|
||||
case GST_MESSAGE_ELEMENT:
|
||||
|
|
|
@ -188,9 +188,6 @@ class GstEnginePipeline : public QObject {
|
|||
// get sent while the Player still thinks it's playing the last song
|
||||
bool ignore_tags_;
|
||||
|
||||
// Set after the first error to ignore any others that arrive.
|
||||
bool ignore_errors_;
|
||||
|
||||
// When the gstreamer source requests a redirect we store the URL here and
|
||||
// callers can pick it up after the state change to PLAYING fails.
|
||||
QUrl redirect_url_;
|
||||
|
|
Loading…
Reference in New Issue