[Android] FrameRateManager: prevent play to be called wrongfully
Nicolas Pomepuy
git at videolan.org
Mon Sep 5 11:05:57 UTC 2022
vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Thu Sep 1 07:45:13 2022 +0200| [c712bdd675305e7f9c980e901680bd16913b2973] | committer: Nicolas Pomepuy
FrameRateManager: prevent play to be called wrongfully
By only registering the DisplayListener when needed and then unregister it
right away.
Fixes #2671
> https://code.videolan.org/videolan/vlc-android/commit/c712bdd675305e7f9c980e901680bd16913b2973
---
.../src/org/videolan/vlc/util/FrameRateManager.kt | 41 ++++++++++++----------
1 file changed, 22 insertions(+), 19 deletions(-)
diff --git a/application/vlc-android/src/org/videolan/vlc/util/FrameRateManager.kt b/application/vlc-android/src/org/videolan/vlc/util/FrameRateManager.kt
index cac34d6dd..0841406a2 100644
--- a/application/vlc-android/src/org/videolan/vlc/util/FrameRateManager.kt
+++ b/application/vlc-android/src/org/videolan/vlc/util/FrameRateManager.kt
@@ -19,31 +19,30 @@ import java.math.RoundingMode
private const val TAG = "VLC/FrameRateMatch"
private const val SHORT_VIDEO_LENGTH = 300000
+
class FrameRateManager(var context: Context, var service: PlaybackService) {
- init {
- // listen for display change and resume play
- // TODO: check if display change is because of frame rate mode switch
- val displayListener = object : DisplayManager.DisplayListener {
- override fun onDisplayAdded(displayId: Int) = Unit
- override fun onDisplayRemoved(displayId: Int) = Unit
- override fun onDisplayChanged(displayId: Int) {
- //switching mode may cause playback to pause i.e HDMI
- //wait 2 seconds and resume play, mode switch will have happened by then
- Handler(Looper.getMainLooper()).postDelayed({
+
+ // listen for display change and resume play
+ private val displayListener = object : DisplayManager.DisplayListener {
+ override fun onDisplayAdded(displayId: Int) = Unit
+ override fun onDisplayRemoved(displayId: Int) = Unit
+ override fun onDisplayChanged(displayId: Int) {
+ //switching mode may cause playback to pause i.e HDMI
+ //wait 2 seconds and resume play, mode switch will have happened by then
+ Handler(Looper.getMainLooper()).postDelayed({
val videoTrack = try {
this at FrameRateManager.service.mediaplayer.currentVideoTrack
} catch (e: IllegalStateException) {
null
}
- if (videoTrack != null) {
- service.play()
- }
- }, 2000)
- }
+ if (videoTrack != null) {
+ if (BuildConfig.DEBUG) Log.d(TAG, "Call play.")
+ service.play()
+ }
+ }, 2000)
+ getDisplayManager().unregisterDisplayListener(this)
}
-
- getDisplayManager().registerDisplayListener(displayListener, Handler(Looper.getMainLooper()))
}
/**
@@ -71,15 +70,16 @@ class FrameRateManager(var context: Context, var service: PlaybackService) {
@RequiresApi(Build.VERSION_CODES.R)
fun setFrameRateR(videoFrameRate: Float, surface: Surface) {
- if (BuildConfig.DEBUG) Log.d(TAG, "Optimal frame rate will be set by Android system")
+ if (BuildConfig.DEBUG) Log.d(TAG, "setFrameRateR: Optimal frame rate will be set by Android system")
//Android 11 does not support Frame Rate Strategy
surface.setFrameRate(videoFrameRate, Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE)
+ getDisplayManager().registerDisplayListener(displayListener, Handler(Looper.getMainLooper()))
}
@RequiresApi(Build.VERSION_CODES.S)
fun setFrameRateS(videoFrameRate: Float, surface: Surface) {
- if (BuildConfig.DEBUG) Log.d(TAG, "Optimal frame rate will be set by Android system")
+ if (BuildConfig.DEBUG) Log.d(TAG, "setFrameRateS: Optimal frame rate will be set by Android system")
//on Android 12 and up supports Frame Rate Strategy
//for short video less than 5 minutes, only change frame rate if seamless
@@ -102,11 +102,13 @@ class FrameRateManager(var context: Context, var service: PlaybackService) {
if (seamless) {
//switch will be seamless
surface.setFrameRate(videoFrameRate, Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, Surface.CHANGE_FRAME_RATE_ALWAYS)
+ getDisplayManager().registerDisplayListener(displayListener, Handler(Looper.getMainLooper()))
} else if (!seamless && (getDisplayManager().matchContentFrameRateUserPreference == DisplayManager.MATCH_CONTENT_FRAMERATE_ALWAYS)) {
//switch will be non seamless, check if user has opted in for this at the OS level
//TODO: only included this here because Android guide makes it sound like seamless-behavior includes stuff like HDMI switching
//may have to remove this block since we intend to switch only if it will be seamless
surface.setFrameRate(videoFrameRate, Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, Surface.CHANGE_FRAME_RATE_ALWAYS)
+ getDisplayManager().registerDisplayListener(displayListener, Handler(Looper.getMainLooper()))
}
}
}
@@ -144,6 +146,7 @@ class FrameRateManager(var context: Context, var service: PlaybackService) {
// set frame rate
if (modeToUse != currentMode) {
window.attributes.preferredDisplayModeId = modeToUse.modeId
+ getDisplayManager().registerDisplayListener(displayListener, Handler(Looper.getMainLooper()))
}
}
}
More information about the Android
mailing list