diff --git a/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt b/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt index b208bc2f..9ec7fb42 100644 --- a/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt +++ b/android/app/src/main/kotlin/com/edde746/plezy/exoplayer/ExoPlayerCore.kt @@ -1905,7 +1905,12 @@ class ExoPlayerCore(private val activity: Activity) : Player.Listener { cancelDecoderHangCheck() stopPositionUpdates() handler.removeCallbacksAndMessages(null) - frameRateManager?.clearVideoFrameRate() + // releasePending (not clearVideoFrameRate): on the ExoPlayer→MPV fallback + // path, dispose runs after the rate switch has been applied — clearing + // preferredDisplayModeId here would renegotiate HDMI back to default + // before MPV's surface comes up. Explicit user-leave still calls + // clearVideoFrameRate via Dart (video_player_screen.dart). + frameRateManager?.releasePending() frameRateManager = null audioFocusManager?.release() audioFocusManager = null diff --git a/android/app/src/main/kotlin/com/edde746/plezy/mpv/MpvPlayerCore.kt b/android/app/src/main/kotlin/com/edde746/plezy/mpv/MpvPlayerCore.kt index 37b1e6f5..8bc01226 100644 --- a/android/app/src/main/kotlin/com/edde746/plezy/mpv/MpvPlayerCore.kt +++ b/android/app/src/main/kotlin/com/edde746/plezy/mpv/MpvPlayerCore.kt @@ -767,8 +767,11 @@ class MpvPlayerCore(private val activity: Activity) : SurfaceHolder.Callback { handler.removeCallbacksAndMessages(null) - // Clean up frame rate and audio focus - frameRateManager?.clearVideoFrameRate() + // Clean up frame rate and audio focus. + // releasePending (not clearVideoFrameRate): symmetric with ExoPlayerCore — + // dispose only releases the listener/pending future. Restoring the + // display mode is the explicit Dart-side clearVideoFrameRate's job. + frameRateManager?.releasePending() frameRateManager = null audioFocusManager?.release() audioFocusManager = null diff --git a/android/app/src/main/kotlin/com/edde746/plezy/shared/FrameRateManager.kt b/android/app/src/main/kotlin/com/edde746/plezy/shared/FrameRateManager.kt index fd2d109a..446fadff 100644 --- a/android/app/src/main/kotlin/com/edde746/plezy/shared/FrameRateManager.kt +++ b/android/app/src/main/kotlin/com/edde746/plezy/shared/FrameRateManager.kt @@ -90,6 +90,17 @@ class FrameRateManager( } } + // Release pending callbacks/listener without restoring the display mode. + // Used by player-core dispose paths so a backend handoff (e.g. ExoPlayer→MPV + // audio fallback) doesn't clobber the just-applied refresh-rate switch — + // window-scoped preferredDisplayModeId persists across the SurfaceView swap, + // letting MPV inherit the rate without a second HDMI renegotiation. + fun releasePending() { + Log.d(TAG, "releasePending") + currentVideoFps = 0f + firePendingCompletion("release", switched = false) + } + private fun cancelPendingCallbacks() { pendingSettleRunnable?.let { handler.removeCallbacks(it) } watchdogRunnable?.let { handler.removeCallbacks(it) }