change to use displaymanager listener for refresh rate updating

This commit is contained in:
Drew Hill 2017-10-12 14:52:14 -04:00
parent ac3501dd84
commit 3a1a032fa8
2 changed files with 68 additions and 5 deletions

View File

@ -236,7 +236,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
tunnelingAudioSessionId = getConfiguration().tunnelingAudioSessionId; tunnelingAudioSessionId = getConfiguration().tunnelingAudioSessionId;
tunneling = tunnelingAudioSessionId != C.AUDIO_SESSION_ID_UNSET; tunneling = tunnelingAudioSessionId != C.AUDIO_SESSION_ID_UNSET;
eventDispatcher.enabled(decoderCounters); eventDispatcher.enabled(decoderCounters);
frameReleaseTimeHelper.enable(context); frameReleaseTimeHelper.enable();
} }
@Override @Override

View File

@ -17,6 +17,8 @@ package com.google.android.exoplayer2.video;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.content.Context; import android.content.Context;
import android.hardware.display.DisplayManager;
import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.HandlerThread; import android.os.HandlerThread;
import android.os.Message; import android.os.Message;
@ -31,6 +33,7 @@ import com.google.android.exoplayer2.C;
@TargetApi(16) @TargetApi(16)
public final class VideoFrameReleaseTimeHelper { public final class VideoFrameReleaseTimeHelper {
private static final int DISPLAY_ID_UNKNOWN = -1;
private static final double DISPLAY_REFRESH_RATE_UNKNOWN = -1; private static final double DISPLAY_REFRESH_RATE_UNKNOWN = -1;
private static final long CHOREOGRAPHER_SAMPLE_DELAY_MILLIS = 500; private static final long CHOREOGRAPHER_SAMPLE_DELAY_MILLIS = 500;
private static final long MAX_ALLOWED_DRIFT_NS = 20000000; private static final long MAX_ALLOWED_DRIFT_NS = 20000000;
@ -38,6 +41,9 @@ public final class VideoFrameReleaseTimeHelper {
private static final long VSYNC_OFFSET_PERCENTAGE = 80; private static final long VSYNC_OFFSET_PERCENTAGE = 80;
private static final int MIN_FRAMES_FOR_ADJUSTMENT = 6; private static final int MIN_FRAMES_FOR_ADJUSTMENT = 6;
private DisplayManager.DisplayListener displayListener = null;
private Context context = null;
private VSyncSampler vsyncSampler; private VSyncSampler vsyncSampler;
private boolean useDefaultDisplayVsync; private boolean useDefaultDisplayVsync;
private long vsyncDurationNs; private long vsyncDurationNs;
@ -68,6 +74,8 @@ public final class VideoFrameReleaseTimeHelper {
*/ */
public VideoFrameReleaseTimeHelper(Context context) { public VideoFrameReleaseTimeHelper(Context context) {
this(getDefaultDisplayRefreshRate(context)); this(getDefaultDisplayRefreshRate(context));
this.context = context;
registerDisplayListener();
} }
private VideoFrameReleaseTimeHelper(double defaultDisplayRefreshRate) { private VideoFrameReleaseTimeHelper(double defaultDisplayRefreshRate) {
@ -77,12 +85,12 @@ public final class VideoFrameReleaseTimeHelper {
/** /**
* Enables the helper. * Enables the helper.
*/ */
public void enable(Context context) { public void enable() {
haveSync = false; haveSync = false;
if (useDefaultDisplayVsync) { if (useDefaultDisplayVsync) {
setSync(getDefaultDisplayRefreshRate(context));
vsyncSampler.addObserver(); vsyncSampler.addObserver();
} }
registerDisplayListener();
} }
/** /**
@ -92,6 +100,29 @@ public final class VideoFrameReleaseTimeHelper {
if (useDefaultDisplayVsync) { if (useDefaultDisplayVsync) {
vsyncSampler.removeObserver(); vsyncSampler.removeObserver();
} }
unregisterDisplayListener();
}
private void registerDisplayListener() {
if (displayListener == null && context != null &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
DisplayManager displayManager = context.getSystemService(DisplayManager.class);
if (displayManager != null) {
displayListener = new DefaultDisplayListener(context);
displayManager.registerDisplayListener(displayListener, null);
}
}
}
private void unregisterDisplayListener() {
if (context != null && displayListener != null &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
DisplayManager displayManager = context.getSystemService(DisplayManager.class);
if (displayManager != null) {
displayManager.unregisterDisplayListener(displayListener);
displayListener = null;
}
}
} }
private void setSync(double defaultDisplayRefreshRate) { private void setSync(double defaultDisplayRefreshRate) {
@ -206,10 +237,16 @@ public final class VideoFrameReleaseTimeHelper {
return snappedAfterDiff < snappedBeforeDiff ? snappedAfterNs : snappedBeforeNs; return snappedAfterDiff < snappedBeforeDiff ? snappedAfterNs : snappedBeforeNs;
} }
private static int getDefaultDisplayId(Context context) {
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
return manager != null && manager.getDefaultDisplay() != null ?
manager.getDefaultDisplay().getDisplayId() : DISPLAY_ID_UNKNOWN;
}
private static double getDefaultDisplayRefreshRate(Context context) { private static double getDefaultDisplayRefreshRate(Context context) {
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
return manager.getDefaultDisplay() != null ? manager.getDefaultDisplay().getRefreshRate() return manager != null && manager.getDefaultDisplay() != null ?
: DISPLAY_REFRESH_RATE_UNKNOWN; manager.getDefaultDisplay().getRefreshRate() : DISPLAY_REFRESH_RATE_UNKNOWN;
} }
/** /**
@ -307,4 +344,30 @@ public final class VideoFrameReleaseTimeHelper {
} }
@TargetApi(17)
private class DefaultDisplayListener implements DisplayManager.DisplayListener {
private final Context context;
DefaultDisplayListener(Context context) {
this.context = context;
}
@Override
public void onDisplayAdded(int displayId) {
}
@Override
public void onDisplayRemoved(int displayId) {
}
@Override
public void onDisplayChanged(int displayId) {
final int defaultDisplayId = getDefaultDisplayId(context);
if (displayId == defaultDisplayId || defaultDisplayId == DISPLAY_ID_UNKNOWN) {
setSync(getDefaultDisplayRefreshRate(context));
}
}
}
} }