Video player resources are now completely freed up after finishing view transitions

This commit is contained in:
Leon Styhre 2024-09-15 11:34:28 +02:00
parent d1f9dc7e23
commit 5300e54295
6 changed files with 53 additions and 5 deletions

View file

@ -96,6 +96,15 @@ void GamelistView::onShow()
mPrimary->onShowPrimary();
}
void GamelistView::onHide()
{
for (auto& video : mVideoComponents)
video->stopVideoPlayer(false);
for (auto& video : mStaticVideoComponents)
video->stopVideoPlayer(false);
}
void GamelistView::onTransition()
{
for (auto& animation : mLottieAnimComponents)

View file

@ -23,6 +23,7 @@ public:
// Called when a FileData* is added, has its metadata changed, or is removed.
void onFileChanged(FileData* file, bool reloadGamelist) override;
void onShow() override;
void onHide() override;
void onTransition() override;
void preloadGamelist() { updateView(CursorState::CURSOR_STOPPED); }

View file

@ -50,6 +50,12 @@ void SystemView::onShow()
mPrimary->onShowPrimary();
}
void SystemView::onHide()
{
for (auto& video : mSystemElements[mPrimary->getCursor()].videoComponents)
video->stopVideoPlayer(false);
}
void SystemView::onTransition()
{
for (auto& anim : mSystemElements[mPrimary->getCursor()].lottieAnimComponents)
@ -284,9 +290,15 @@ void SystemView::onCursorChanged(const CursorState& state)
}
if (mLastCursor >= 0 && mLastCursor <= static_cast<int>(mSystemElements.size())) {
if (transitionAnim == ViewTransitionAnimation::INSTANT || isAnimationPlaying(0)) {
for (auto& video : mSystemElements[mLastCursor].videoComponents)
video->stopVideoPlayer(false);
}
else {
for (auto& video : mSystemElements[mLastCursor].videoComponents)
video->pauseVideoPlayer();
}
}
for (auto& container : mSystemElements[mPrimary->getCursor()].containerComponents)
container->resetComponent();
@ -316,6 +328,7 @@ void SystemView::onCursorChanged(const CursorState& state)
mCamOffset = static_cast<float>(cursor);
}
const int prevLastCursor {mLastCursor};
mLastCursor = cursor;
for (auto& video : mSystemElements[cursor].videoComponents)
@ -390,7 +403,7 @@ void SystemView::onCursorChanged(const CursorState& state)
if (transitionAnim == ViewTransitionAnimation::FADE) {
float startFade {mFadeOpacity};
anim = new LambdaAnimation(
[this, startFade, endPos](float t) {
[this, startFade, endPos, prevLastCursor](float t) {
if (t < 0.3f)
mFadeOpacity =
glm::mix(0.0f, 1.0f, glm::clamp(t / 0.2f + startFade, 0.0f, 1.0f));
@ -405,6 +418,11 @@ void SystemView::onCursorChanged(const CursorState& state)
if (mNavigated && t >= 0.7f && t != 1.0f)
mMaxFade = true;
if (t == 1.0f && prevLastCursor >= 0) {
for (auto& video : mSystemElements[prevLastCursor].videoComponents)
video->stopVideoPlayer(false);
}
// Update the game count when the entire animation has been completed.
if (mFadeOpacity == 1.0f) {
mMaxFade = false;
@ -416,7 +434,7 @@ void SystemView::onCursorChanged(const CursorState& state)
else if (transitionAnim == ViewTransitionAnimation::SLIDE) {
mUpdatedGameCount = false;
anim = new LambdaAnimation(
[this, startPos, endPos, posMax](float t) {
[this, startPos, endPos, posMax, prevLastCursor](float t) {
// Non-linear interpolation.
t = 1.0f - (1.0f - t) * (1.0f - t);
float f {(endPos * t) + (startPos * (1.0f - t))};
@ -428,6 +446,11 @@ void SystemView::onCursorChanged(const CursorState& state)
mCamOffset = f;
if (t == 1.0f && prevLastCursor >= 0) {
for (auto& video : mSystemElements[prevLastCursor].videoComponents)
video->stopVideoPlayer(false);
}
// Hack to make the game count being updated in the middle of the animation.
bool update {false};
if (endPos == -1.0f && fabs(fabs(posMax) - fabs(mCamOffset)) > 0.5f &&

View file

@ -38,6 +38,7 @@ public:
SystemView();
void onShow() override;
void onHide() override;
void onTransition() override;
void goToSystem(SystemData* system, bool animate);

View file

@ -731,6 +731,14 @@ void ViewController::goToGamelist(SystemData* system)
bool slideTransitions {false};
bool fadeTransitions {false};
// Special case where we moved to another gamelist while the system to gamelist animation
// was still playing, in this case we need to explictly call onHide() so that all system view
// videos are stopped.
if (mState.previouslyViewed == ViewMode::SYSTEM_SELECT &&
mState.viewing == ViewMode::GAMELIST && isAnimationPlaying(0)) {
getSystemListView()->onHide();
}
if (mCurrentView != nullptr)
mCurrentView->onTransition();
@ -926,6 +934,8 @@ void ViewController::playViewTransition(ViewTransition transitionType, bool inst
this->mCamera[3].x = -target.x;
this->mCamera[3].y = -target.y;
this->mCamera[3].z = -target.z;
if (mState.previouslyViewed == ViewMode::SYSTEM_SELECT)
getSystemListView()->onHide();
if (mPreviousView)
mPreviousView->onHide();
},
@ -946,6 +956,8 @@ void ViewController::playViewTransition(ViewTransition transitionType, bool inst
};
auto fadeCallback = [this]() {
if (mState.previouslyViewed == ViewMode::SYSTEM_SELECT || mSystemViewTransition)
getSystemListView()->onHide();
if (mPreviousView)
mPreviousView->onHide();
};
@ -975,6 +987,8 @@ void ViewController::playViewTransition(ViewTransition transitionType, bool inst
}
else if (transitionAnim == ViewTransitionAnimation::SLIDE) {
auto slideCallback = [this]() {
if (mState.previouslyViewed == ViewMode::SYSTEM_SELECT || mSystemViewTransition)
getSystemListView()->onHide();
if (mSkipView) {
mSkipView->onHide();
mSkipView.reset();

View file

@ -1662,7 +1662,7 @@ void VideoFFmpegComponent::stopVideoPlayer(bool muteAudio)
std::queue<AudioFrame>().swap(mAudioFrameQueue);
// Clear the audio buffer.
if (AudioManager::sAudioDevice != 0)
if (muteAudio && AudioManager::sAudioDevice != 0)
AudioManager::getInstance().clearStream();
if (mFormatContext) {