Skip to content
Extraits de code Groupes Projets
Vérifiée Valider 67f9fc8a rédigé par Kubat's avatar Kubat
Parcourir les fichiers

MPV: Add a button to re-create the MPV context if something went wrong during widget init

The race condition between Qt's widget creation and mpv getting the WID
doesn't seem to be fixed for now, will need to investigate further.
parent c5516bf7
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
<file alias="media-pause.svg">icons/breeze-dark/media-playback-pause.svg</file> <file alias="media-pause.svg">icons/breeze-dark/media-playback-pause.svg</file>
<file alias="media-play.svg">icons/breeze-dark/media-playback-start.svg</file> <file alias="media-play.svg">icons/breeze-dark/media-playback-start.svg</file>
<file alias="media-stop.svg">icons/breeze-dark/media-playback-stop.svg</file> <file alias="media-stop.svg">icons/breeze-dark/media-playback-stop.svg</file>
<file alias="run.svg">icons/breeze-dark/run-build-file.svg</file>
</qresource> </qresource>
<qresource prefix="icons/light"> <qresource prefix="icons/light">
<file alias="document-new.svg">icons/breeze-light/document-new.svg</file> <file alias="document-new.svg">icons/breeze-light/document-new.svg</file>
...@@ -53,6 +54,7 @@ ...@@ -53,6 +54,7 @@
<file alias="media-pause.svg">icons/breeze-light/media-playback-pause.svg</file> <file alias="media-pause.svg">icons/breeze-light/media-playback-pause.svg</file>
<file alias="media-play.svg">icons/breeze-light/media-playback-start.svg</file> <file alias="media-play.svg">icons/breeze-light/media-playback-start.svg</file>
<file alias="media-stop.svg">icons/breeze-light/media-playback-stop.svg</file> <file alias="media-stop.svg">icons/breeze-light/media-playback-stop.svg</file>
<file alias="run.svg">icons/breeze-light/run-build-file.svg</file>
</qresource> </qresource>
<!-- QDarkStyle style sheet, MIT Licence --> <!-- QDarkStyle style sheet, MIT Licence -->
......
...@@ -19,10 +19,12 @@ MpvContainer::MpvContainer(QWidget *parent) ...@@ -19,10 +19,12 @@ MpvContainer::MpvContainer(QWidget *parent)
setAttribute(Qt::WA_DontCreateNativeAncestors); setAttribute(Qt::WA_DontCreateNativeAncestors);
setAttribute(Qt::WA_NativeWindow); setAttribute(Qt::WA_NativeWindow);
initializeMpv();
} }
void void
MpvContainer::intializeMpv() MpvContainer::initializeMpv()
{ {
if (isMpvAlreadyInitialized) if (isMpvAlreadyInitialized)
throw std::logic_error("MPV is already initialized!"); throw std::logic_error("MPV is already initialized!");
...@@ -42,13 +44,24 @@ MpvContainer::intializeMpv() ...@@ -42,13 +44,24 @@ MpvContainer::intializeMpv()
mpv_observe_property(mpv, 0, "duration", MPV_FORMAT_DOUBLE); mpv_observe_property(mpv, 0, "duration", MPV_FORMAT_DOUBLE);
mpv_observe_property(mpv, 0, "time-pos", MPV_FORMAT_DOUBLE); mpv_observe_property(mpv, 0, "time-pos", MPV_FORMAT_DOUBLE);
connect(this, &MpvContainer::mpvEvent, this, &MpvContainer::onMpvEvent, Qt::QueuedConnection);
mpv_set_wakeup_callback(mpv, &MpvContainer::mpvEventWakeUpCB, this);
if (int rc = mpv_initialize(mpv); rc < 0) { if (int rc = mpv_initialize(mpv); rc < 0) {
printMpvError(rc); printMpvError(rc);
throw std::runtime_error("Failed to initialize the mpv context"); throw std::runtime_error("Failed to initialize the mpv context");
} }
}
connect(this, &MpvContainer::mpvEvent, this, &MpvContainer::onMpvEvent, Qt::QueuedConnection); void
mpv_set_wakeup_callback(mpv, &MpvContainer::mpvEventWakeUpCB, this); MpvContainer::reCreateMpvContext()
{
closeMpv();
mpv = mpv_create();
if (mpv == nullptr)
throw std::runtime_error("Failed to create the MPV context");
initializeMpv();
loadFile(previousLoadedFile);
} }
void void
...@@ -74,11 +87,10 @@ MpvContainer::closeMpv() noexcept ...@@ -74,11 +87,10 @@ MpvContainer::closeMpv() noexcept
qDebug() << "Closing the MPV context"; qDebug() << "Closing the MPV context";
registerMpvTimeCallback(nullptr); registerMpvTimeCallback(nullptr);
registerMpvDurationCallback(nullptr); registerMpvDurationCallback(nullptr);
mpv_handle *tmp_mpv = mpv; mpv_wait_async_requests(mpv);
mpv = nullptr; // Stop all other callbacks here mpv_terminate_destroy(mpv);
mpv_destroy(tmp_mpv); mpv = nullptr; // Stop all other callbacks here
// mpv_wait_async_requests(tmp_mpv); isMpvAlreadyInitialized = false; // De-init
// mpv_terminate_destroy(tmp_mpv);
} }
} }
...@@ -233,10 +245,12 @@ MpvContainer::onMpvEvent() noexcept ...@@ -233,10 +245,12 @@ MpvContainer::onMpvEvent() noexcept
void void
MpvContainer::loadFile(const QString &filename) noexcept MpvContainer::loadFile(const QString &filename) noexcept
{ {
qDebug() << "Loading file" << filename;
if (filename.size() == 0) if (filename.size() == 0)
return; return;
qDebug() << "Loading file" << filename;
if (previousLoadedFile != filename)
previousLoadedFile = filename;
const QByteArray cFileName = filename.toUtf8(); const QByteArray cFileName = filename.toUtf8();
asyncCommand(AsyncCmdType::LoadFile, { "loadfile", cFileName.data(), nullptr }); asyncCommand(AsyncCmdType::LoadFile, { "loadfile", cFileName.data(), nullptr });
} }
......
...@@ -27,17 +27,8 @@ class MpvContainer final : public QWidget { ...@@ -27,17 +27,8 @@ class MpvContainer final : public QWidget {
TogglePlayback TogglePlayback
}; };
private:
bool isPlaybackPaused{ true };
bool isMpvAlreadyInitialized{ false };
mpv_handle *volatile mpv{ nullptr };
qint64 sid{ -1 };
std::function<void(double)> mpvTimeCallback{ nullptr };
std::function<void(double)> mpvDurationCallback{ nullptr };
public: public:
explicit MpvContainer(QWidget *parent); explicit MpvContainer(QWidget *parent);
void intializeMpv();
~MpvContainer() noexcept override; ~MpvContainer() noexcept override;
void loadFile(const QString &) noexcept; void loadFile(const QString &) noexcept;
...@@ -52,6 +43,7 @@ public: ...@@ -52,6 +43,7 @@ public:
void registerMpvDurationCallback(std::function<void(double)>) noexcept; void registerMpvDurationCallback(std::function<void(double)>) noexcept;
private: private:
void initializeMpv();
void handleMpvEvent(const mpv_event *const) noexcept; void handleMpvEvent(const mpv_event *const) noexcept;
void closeMpv() noexcept; void closeMpv() noexcept;
void printMpvError(int) const noexcept; void printMpvError(int) const noexcept;
...@@ -63,10 +55,19 @@ private: ...@@ -63,10 +55,19 @@ private:
// Must be static to be passed as a function ptr // Must be static to be passed as a function ptr
static void mpvEventWakeUpCB(void *) noexcept; static void mpvEventWakeUpCB(void *) noexcept;
bool isPlaybackPaused{ true };
bool isMpvAlreadyInitialized{ false };
mpv_handle *volatile mpv{ nullptr };
qint64 sid{ -1 };
QString previousLoadedFile{};
std::function<void(double)> mpvTimeCallback{ nullptr };
std::function<void(double)> mpvDurationCallback{ nullptr };
public slots: public slots:
void mpvPlay() noexcept; void mpvPlay() noexcept;
void mpvPause() noexcept; void mpvPause() noexcept;
void mpvTogglePlayback() noexcept; void mpvTogglePlayback() noexcept;
void reCreateMpvContext();
private slots: private slots:
void onMpvEvent() noexcept; void onMpvEvent() noexcept;
......
...@@ -9,6 +9,8 @@ MpvControls::MpvControls(MpvContainer *passedContainer, QWidget *parent) noexcep ...@@ -9,6 +9,8 @@ MpvControls::MpvControls(MpvContainer *passedContainer, QWidget *parent) noexcep
{ {
auto *progressBar = new QSlider(this); auto *progressBar = new QSlider(this);
auto *togglePlaybackButton = new QPushButton(playIcon, "", this); // Be default MPV is paused auto *togglePlaybackButton = new QPushButton(playIcon, "", this); // Be default MPV is paused
auto *reCreateMpvButton = new QPushButton(
reCreateMpvIcon, "", this); // Recreate the MPV context if something went wrong
progressBar->setTracking(false); progressBar->setTracking(false);
progressBar->setOrientation(Qt::Horizontal); progressBar->setOrientation(Qt::Horizontal);
...@@ -55,6 +57,7 @@ MpvControls::MpvControls(MpvContainer *passedContainer, QWidget *parent) noexcep ...@@ -55,6 +57,7 @@ MpvControls::MpvControls(MpvContainer *passedContainer, QWidget *parent) noexcep
}); });
connect(togglePlaybackButton, &QAbstractButton::clicked, mpv, &MpvContainer::mpvTogglePlayback); connect(togglePlaybackButton, &QAbstractButton::clicked, mpv, &MpvContainer::mpvTogglePlayback);
connect(reCreateMpvButton, &QAbstractButton::clicked, mpv, &MpvContainer::reCreateMpvContext);
connect(mpv, &MpvContainer::mpvPlaybackToggled, this, connect(mpv, &MpvContainer::mpvPlaybackToggled, this,
[this, togglePlaybackButton](bool isPlay) noexcept -> void { [this, togglePlaybackButton](bool isPlay) noexcept -> void {
togglePlaybackButton->setIcon(isPlay ? pauseIcon : playIcon); togglePlaybackButton->setIcon(isPlay ? pauseIcon : playIcon);
...@@ -62,6 +65,7 @@ MpvControls::MpvControls(MpvContainer *passedContainer, QWidget *parent) noexcep ...@@ -62,6 +65,7 @@ MpvControls::MpvControls(MpvContainer *passedContainer, QWidget *parent) noexcep
auto *centralLayout = new QHBoxLayout(this); auto *centralLayout = new QHBoxLayout(this);
centralLayout->addWidget(togglePlaybackButton); centralLayout->addWidget(togglePlaybackButton);
centralLayout->addWidget(reCreateMpvButton);
centralLayout->addWidget(progressBar, 1); centralLayout->addWidget(progressBar, 1);
setLayout(centralLayout); setLayout(centralLayout);
} }
...@@ -23,6 +23,7 @@ private: ...@@ -23,6 +23,7 @@ private:
const QIcon playIcon{ VIVY_ICON_PLAY }; const QIcon playIcon{ VIVY_ICON_PLAY };
const QIcon pauseIcon{ VIVY_ICON_PAUSE }; const QIcon pauseIcon{ VIVY_ICON_PAUSE };
const QIcon reCreateMpvIcon{ VIVY_ICON_RUN };
public: public:
explicit MpvControls(MpvContainer *mpv, QWidget *parent) noexcept; explicit MpvControls(MpvContainer *mpv, QWidget *parent) noexcept;
......
...@@ -14,8 +14,6 @@ VideoView::VideoView(QWidget *parent) noexcept ...@@ -14,8 +14,6 @@ VideoView::VideoView(QWidget *parent) noexcept
centralLayout->addWidget(new MpvControls(mpv, this)); centralLayout->addWidget(new MpvControls(mpv, this));
setLayout(centralLayout); setLayout(centralLayout);
mpv->intializeMpv();
} }
void void
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#define VIVY_ICON_PLAY ":icons/dark/media-play.svg" #define VIVY_ICON_PLAY ":icons/dark/media-play.svg"
#define VIVY_ICON_PAUSE ":icons/dark/media-pause.svg" #define VIVY_ICON_PAUSE ":icons/dark/media-pause.svg"
#define VIVY_ICON_STOP ":icons/dark/media-stop.svg" #define VIVY_ICON_STOP ":icons/dark/media-stop.svg"
#define VIVY_ICON_RUN ":icons/dark/run.svg"
// Detect MacOS // Detect MacOS
#if defined(Q_OS_DARWIN) || defined(Q_OS_MACOS) #if defined(Q_OS_DARWIN) || defined(Q_OS_MACOS)
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter