Avoid to create a new thread when changing state. Make the UI more reactive, especially when Qt threadpool is already full (for example when fingerprinting several files in parallel for MusicBrainz autotagging)

This commit is contained in:
Arnaud Bienner 2011-05-03 00:02:35 +00:00
parent 1bf7577764
commit 709d339866
4 changed files with 11 additions and 40 deletions

View File

@ -396,24 +396,10 @@ bool GstEngine::Play(quint64 offset_nanosec) {
if (!current_pipeline_)
return false;
QFuture<GstStateChangeReturn> future = current_pipeline_->SetState(GST_STATE_PLAYING);
PlayFutureWatcher* watcher = new PlayFutureWatcher(
PlayFutureWatcherArg(offset_nanosec, current_pipeline_->id()), this);
watcher->setFuture(future);
connect(watcher, SIGNAL(finished()), SLOT(PlayDone()));
GstStateChangeReturn ret = current_pipeline_->SetState(GST_STATE_PLAYING);
return true;
}
void GstEngine::PlayDone() {
PlayFutureWatcher* watcher = static_cast<PlayFutureWatcher*>(sender());
watcher->deleteLater();
GstStateChangeReturn ret = watcher->result();
quint64 offset_nanosec = watcher->data().first;
if (!current_pipeline_ || watcher->data().second != current_pipeline_->id()) {
return;
if (!current_pipeline_) {
return false;
}
if (ret == GST_STATE_CHANGE_FAILURE) {
@ -423,13 +409,13 @@ void GstEngine::PlayDone() {
qLog(Info) << "Redirecting to" << redirect_url;
current_pipeline_ = CreatePipeline(redirect_url, end_nanosec_);
Play(offset_nanosec);
return;
return false;
}
// Failure - give up
qLog(Warning) << "Could not set thread to PLAYING.";
current_pipeline_.reset();
return;
return false;
}
StartTimers();
@ -444,6 +430,7 @@ void GstEngine::PlayDone() {
emit StateChanged(Engine::Playing);
// we've successfully started playing a media stream with this url
emit ValidSongRequested(url_);
return true;
}
@ -773,27 +760,13 @@ int GstEngine::AddBackgroundStream(shared_ptr<GstEnginePipeline> pipeline) {
const int stream_id = next_background_stream_id_++;
background_streams_[stream_id] = pipeline;
QFuture<GstStateChangeReturn> future = pipeline->SetState(GST_STATE_PLAYING);
BoundFutureWatcher<GstStateChangeReturn, int>* watcher =
new BoundFutureWatcher<GstStateChangeReturn, int>(stream_id, this);
watcher->setFuture(future);
connect(watcher, SIGNAL(finished()), SLOT(BackgroundStreamPlayDone()));
return stream_id;
}
void GstEngine::BackgroundStreamPlayDone() {
BoundFutureWatcher<GstStateChangeReturn, int>* watcher =
static_cast<BoundFutureWatcher<GstStateChangeReturn, int>*>(sender());
watcher->deleteLater();
const int stream_id = watcher->data();
GstStateChangeReturn ret = watcher->result();
GstStateChangeReturn ret = pipeline->SetState(GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE) {
qLog(Warning) << "Could not set thread to PLAYING.";
background_streams_.remove(stream_id);
}
return stream_id;
}
int GstEngine::AddBackgroundStream(const QUrl& url) {

View File

@ -121,8 +121,6 @@ class GstEngine : public Engine::Base, public BufferConsumer {
void FadeoutFinished();
void SeekNow();
void BackgroundStreamFinished();
void BackgroundStreamPlayDone();
void PlayDone();
private:
typedef QPair<quint64, int> PlayFutureWatcherArg;

View File

@ -616,8 +616,8 @@ GstState GstEnginePipeline::state() const {
return s;
}
QFuture<GstStateChangeReturn> GstEnginePipeline::SetState(GstState state) {
return QtConcurrent::run(&gst_element_set_state, pipeline_, state);
GstStateChangeReturn GstEnginePipeline::SetState(GstState state) {
return gst_element_set_state(pipeline_, state);
}
bool GstEnginePipeline::Seek(qint64 nanosec) {

View File

@ -61,7 +61,7 @@ class GstEnginePipeline : public QObject {
void RemoveAllBufferConsumers();
// Control the music playback
QFuture<GstStateChangeReturn> SetState(GstState state);
GstStateChangeReturn SetState(GstState state);
Q_INVOKABLE bool Seek(qint64 nanosec);
void SetEqualizerEnabled(bool enabled);
void SetEqualizerParams(int preamp, const QList<int>& band_gains);