Browse Source

FrameRateManager: prevent play to be called wrongfully

By only registering the DisplayListener when needed and then unregister it
right away.
Fixes #2671
merge-requests/1535/head
Nicolas Pomepuy 4 years ago
parent
commit
c712bdd675
  1. 41
      application/vlc-android/src/org/videolan/vlc/util/FrameRateManager.kt

41
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@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()))
}
}
}

Loading…
Cancel
Save