Improve gst engine error handling

This commit is contained in:
Jonas Kvinge 2018-10-30 23:39:08 +01:00
parent faee1977fe
commit ff35b01bac
3 changed files with 24 additions and 20 deletions

View File

@ -1,8 +1,8 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2017-2018 Jonas Kvinge <jonas@jkvinge.net> *
* Copyright (C) 2003-2005 by Mark Kretschmann <markey@web.de> * * Copyright (C) 2003-2005 by Mark Kretschmann <markey@web.de> *
* Copyright (C) 2005 by Jakub Stachowski <qbast@go2.pl> * * Copyright (C) 2005 by Jakub Stachowski <qbast@go2.pl> *
* Copyright (C) 2006 Paul Cifarelli <paul@cifarelli.net> * * Copyright (C) 2006 Paul Cifarelli <paul@cifarelli.net> *
* Copyright (C) 2017-2018 Jonas Kvinge <jonas@jkvinge.net> *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
@ -206,6 +206,7 @@ bool GstEngine::Load(const QUrl &media_url, const QUrl &original_url, Engine::Tr
current_pipeline_->StartFader(fadeout_duration_nanosec_, QTimeLine::Forward); current_pipeline_->StartFader(fadeout_duration_nanosec_, QTimeLine::Forward);
return true; return true;
} }
bool GstEngine::Play(quint64 offset_nanosec) { bool GstEngine::Play(quint64 offset_nanosec) {
@ -470,18 +471,17 @@ void GstEngine::SetEnvironment() {
} }
GstElement *GstEngine::CreateElement(const QString &factoryName, GstElement *bin, bool fatal, bool showerror) { GstElement *GstEngine::CreateElement(const QString &factoryName, GstElement *bin, bool showerror) {
// Make a unique name // Make a unique name
QString name = factoryName + "-" + QString::number(next_element_id_++); QString name = factoryName + "-" + QString::number(next_element_id_++);
GstElement *element = gst_element_factory_make(factoryName.toUtf8().constData(), name.toUtf8().constData()); GstElement *element = gst_element_factory_make(factoryName.toUtf8().constData(), name.toUtf8().constData());
if (!element) { if (!element) {
if (showerror) if (showerror) emit Error(QString("GStreamer could not create the element: %1.").arg(factoryName));
emit Error(QString("GStreamer could not create the element: %1. Please make sure that you have installed all necessary GStreamer plugins").arg(factoryName));
else qLog(Error) << "GStreamer could not create the element:" << factoryName; else qLog(Error) << "GStreamer could not create the element:" << factoryName;
//if (fatal) gst_object_unref(GST_OBJECT(bin)); emit StateChanged(Engine::Error);
emit FatalError();
return nullptr; return nullptr;
} }
@ -566,21 +566,25 @@ void GstEngine::EndOfStreamReached(int pipeline_id, bool has_next_track) {
BufferingFinished(); BufferingFinished();
} }
emit TrackEnded(); emit TrackEnded();
} }
void GstEngine::HandlePipelineError(int pipeline_id, const QString &message, int domain, int error_code) { void GstEngine::HandlePipelineError(int pipeline_id, const QString &message, int domain, int error_code) {
if (!current_pipeline_.get() || current_pipeline_->id() != pipeline_id) if (!current_pipeline_.get() || current_pipeline_->id() != pipeline_id) return;
return;
qLog(Warning) << "Gstreamer error:" << domain << error_code << message; qLog(Error) << "Gstreamer error:" << domain << error_code << message;
current_pipeline_.reset(); current_pipeline_.reset();
BufferingFinished(); BufferingFinished();
emit StateChanged(Engine::Error); emit StateChanged(Engine::Error);
// unable to play media stream with this url
emit InvalidSongRequested(media_url_); if (domain == GST_RESOURCE_ERROR && (error_code == GST_RESOURCE_ERROR_NOT_FOUND || error_code == GST_RESOURCE_ERROR_NOT_AUTHORIZED)) {
emit InvalidSongRequested(media_url_);
}
else {
emit FatalError();
}
emit Error(message); emit Error(message);

View File

@ -1,8 +1,8 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2017-2018 Jonas Kvinge <jonas@jkvinge.net> *
* Copyright (C) 2003-2005 by Mark Kretschmann <markey@web.de> * * Copyright (C) 2003-2005 by Mark Kretschmann <markey@web.de> *
* Copyright (C) 2005 by Jakub Stachowski <qbast@go2.pl> * * Copyright (C) 2005 by Jakub Stachowski <qbast@go2.pl> *
* Copyright (C) 2006 Paul Cifarelli <paul@cifarelli.net> * * Copyright (C) 2006 Paul Cifarelli <paul@cifarelli.net> *
* Copyright (C) 2017-2018 Jonas Kvinge <jonas@jkvinge.net> *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
@ -93,7 +93,7 @@ class GstEngine : public Engine::Base, public GstBufferConsumer {
void InitialiseGStreamer(); void InitialiseGStreamer();
void SetEnvironment(); void SetEnvironment();
GstElement *CreateElement(const QString &factoryName, GstElement *bin = 0, bool fatal = true, bool showerror = true); GstElement *CreateElement(const QString &factoryName, GstElement *bin = nullptr, bool showerror = true);
void ConsumeBuffer(GstBuffer *buffer, int pipeline_id); void ConsumeBuffer(GstBuffer *buffer, int pipeline_id);
public slots: public slots:

View File

@ -239,9 +239,9 @@ bool GstEnginePipeline::InitAudioBin() {
probe_sink = engine_->CreateElement("fakesink", audiobin_); probe_sink = engine_->CreateElement("fakesink", audiobin_);
audio_queue = engine_->CreateElement("queue", audiobin_); audio_queue = engine_->CreateElement("queue", audiobin_);
equalizer_preamp_ = engine_->CreateElement("volume", audiobin_, false, true); equalizer_preamp_ = engine_->CreateElement("volume", audiobin_, false);
equalizer_ = engine_->CreateElement("equalizer-nbands", audiobin_, false, true); equalizer_ = engine_->CreateElement("equalizer-nbands", audiobin_, false);
audio_panorama_ = engine_->CreateElement("audiopanorama", audiobin_, false, false); audio_panorama_ = engine_->CreateElement("audiopanorama", audiobin_, false);
volume_ = engine_->CreateElement("volume", audiobin_); volume_ = engine_->CreateElement("volume", audiobin_);
audioscale_ = engine_->CreateElement("audioresample", audiobin_); audioscale_ = engine_->CreateElement("audioresample", audiobin_);
convert = engine_->CreateElement("audioconvert", audiobin_); convert = engine_->CreateElement("audioconvert", audiobin_);
@ -257,9 +257,9 @@ bool GstEnginePipeline::InitAudioBin() {
GstElement *convert_sink = tee; GstElement *convert_sink = tee;
if (rg_enabled_) { if (rg_enabled_) {
rgvolume_ = engine_->CreateElement("rgvolume", audiobin_, false, true); rgvolume_ = engine_->CreateElement("rgvolume", audiobin_, false);
rglimiter_ = engine_->CreateElement("rglimiter", audiobin_, false, true); rglimiter_ = engine_->CreateElement("rglimiter", audiobin_, false);
audioconvert2_ = engine_->CreateElement("audioconvert", audiobin_, false, true); audioconvert2_ = engine_->CreateElement("audioconvert", audiobin_, false);
if (rgvolume_ && rglimiter_ && audioconvert2_) { if (rgvolume_ && rglimiter_ && audioconvert2_) {
event_probe = audioconvert2_; event_probe = audioconvert2_;
convert_sink = rgvolume_; convert_sink = rgvolume_;