From dc3a9365959df686743e943697fe3984ee1513b8 Mon Sep 17 00:00:00 2001 From: Leon Styhre Date: Fri, 29 Jan 2021 21:46:48 +0100 Subject: [PATCH] Yet another attempt to get libVLC to reliably set the audio volume. --- es-core/src/components/VideoVlcComponent.cpp | 49 ++++++++++++++------ es-core/src/components/VideoVlcComponent.h | 2 + 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/es-core/src/components/VideoVlcComponent.cpp b/es-core/src/components/VideoVlcComponent.cpp index 083fec97c..33038756f 100644 --- a/es-core/src/components/VideoVlcComponent.cpp +++ b/es-core/src/components/VideoVlcComponent.cpp @@ -94,6 +94,7 @@ void VideoVlcComponent::setupContext() mContext.mutex = SDL_CreateMutex(); mContext.valid = true; resize(); + mHasSetAudioVolume = false; } } @@ -155,6 +156,14 @@ void VideoVlcComponent::resize() void VideoVlcComponent::render(const Transform4x4f& parentTrans) { + // Set the audio volume. As libVLC is very unreliable we need to make an additional + // attempt here in the render loop in addition to the initialization in startVideo(). + // This is required under some circumstances such as when running on a slow computer + // or sometimes even on a faster machine when changing to the video view style or + // when starting the application directly into a gamelist. + if (!mHasSetAudioVolume && mMediaPlayer) + setAudioVolume(); + VideoComponent::render(parentTrans); Transform4x4f trans = parentTrans * getTransform(); GuiComponent::renderChildren(trans); @@ -276,6 +285,27 @@ void VideoVlcComponent::calculateBlackRectangle() } } +void VideoVlcComponent::setAudioVolume() +{ + if (mMediaPlayer && libvlc_media_player_get_state(mMediaPlayer) == libvlc_Playing) { + // This small delay may avoid a race condition in libVLC that could crash the application. + SDL_Delay(2); + if ((!Settings::getInstance()->getBool("GamelistVideoAudio") && + !mScreensaverMode) || + (!Settings::getInstance()->getBool("ScreensaverVideoAudio") && + mScreensaverMode)) { + libvlc_audio_set_volume(mMediaPlayer, 0); + } + else { + if (libvlc_audio_get_mute(mMediaPlayer) == 1) + libvlc_audio_set_mute(mMediaPlayer, 0); + libvlc_audio_set_volume(mMediaPlayer, + Settings::getInstance()->getInt("SoundVolumeVideos")); + } + mHasSetAudioVolume = true; + } +} + void VideoVlcComponent::startVideo() { if (!mIsPlaying) { @@ -406,20 +436,11 @@ void VideoVlcComponent::startVideo() }; } - if (state == libvlc_Playing) { - if ((!Settings::getInstance()->getBool("GamelistVideoAudio") && - !mScreensaverMode) || - (!Settings::getInstance()->getBool("ScreensaverVideoAudio") && - mScreensaverMode)) { - libvlc_audio_set_volume(mMediaPlayer, 0); - } - else { - if (libvlc_audio_get_mute(mMediaPlayer) == 1) - libvlc_audio_set_mute(mMediaPlayer, 0); - libvlc_audio_set_volume(mMediaPlayer, - Settings::getInstance()->getInt("SoundVolumeVideos")); - } - } + // Attempt to set the audio volume. Under some circumstances it could fail + // as libVLC may not be correctly initialized. Therefore there is an + // additional call to this function in the render() loop. + setAudioVolume(); + // Update the playing state. mIsPlaying = true; mFadeIn = 0.0f; diff --git a/es-core/src/components/VideoVlcComponent.h b/es-core/src/components/VideoVlcComponent.h index bcca8c028..be452c7b7 100644 --- a/es-core/src/components/VideoVlcComponent.h +++ b/es-core/src/components/VideoVlcComponent.h @@ -53,6 +53,7 @@ private: void render(const Transform4x4f& parentTrans) override; void calculateBlackRectangle(); + void setAudioVolume(); // Start the video immediately. virtual void startVideo() override; @@ -70,6 +71,7 @@ private: libvlc_media_t* mMedia; libvlc_media_player_t* mMediaPlayer; VideoContext mContext; + bool mHasSetAudioVolume; std::shared_ptr mTexture; std::vector mVideoRectangleCoords; };