mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Use DummySurface on S8 where possible
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=158838707
This commit is contained in:
parent
fb12a659a2
commit
f3e9166a4e
@ -41,6 +41,8 @@ import static android.opengl.GLES20.glDeleteTextures;
|
|||||||
import static android.opengl.GLES20.glGenTextures;
|
import static android.opengl.GLES20.glGenTextures;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.graphics.SurfaceTexture;
|
import android.graphics.SurfaceTexture;
|
||||||
import android.graphics.SurfaceTexture.OnFrameAvailableListener;
|
import android.graphics.SurfaceTexture.OnFrameAvailableListener;
|
||||||
import android.opengl.EGL14;
|
import android.opengl.EGL14;
|
||||||
@ -68,19 +70,8 @@ public final class DummySurface extends Surface {
|
|||||||
|
|
||||||
private static final int EGL_PROTECTED_CONTENT_EXT = 0x32C0;
|
private static final int EGL_PROTECTED_CONTENT_EXT = 0x32C0;
|
||||||
|
|
||||||
/**
|
private static boolean secureSupported;
|
||||||
* Whether the device supports secure dummy surfaces.
|
private static boolean secureSupportedInitialized;
|
||||||
*/
|
|
||||||
public static final boolean SECURE_SUPPORTED;
|
|
||||||
static {
|
|
||||||
if (Util.SDK_INT >= 17) {
|
|
||||||
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
|
||||||
String extensions = EGL14.eglQueryString(display, EGL10.EGL_EXTENSIONS);
|
|
||||||
SECURE_SUPPORTED = extensions != null && extensions.contains("EGL_EXT_protected_content");
|
|
||||||
} else {
|
|
||||||
SECURE_SUPPORTED = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the surface is secure.
|
* Whether the surface is secure.
|
||||||
@ -90,18 +81,40 @@ public final class DummySurface extends Surface {
|
|||||||
private final DummySurfaceThread thread;
|
private final DummySurfaceThread thread;
|
||||||
private boolean threadReleased;
|
private boolean threadReleased;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the device supports secure dummy surfaces.
|
||||||
|
*
|
||||||
|
* @param context Any {@link Context}.
|
||||||
|
* @return Whether the device supports secure dummy surfaces.
|
||||||
|
*/
|
||||||
|
public static synchronized boolean isSecureSupported(Context context) {
|
||||||
|
if (!secureSupportedInitialized) {
|
||||||
|
if (Util.SDK_INT >= 17) {
|
||||||
|
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||||
|
String extensions = EGL14.eglQueryString(display, EGL10.EGL_EXTENSIONS);
|
||||||
|
secureSupported = extensions != null && extensions.contains("EGL_EXT_protected_content")
|
||||||
|
&& !deviceNeedsSecureDummySurfaceWorkaround(context);
|
||||||
|
}
|
||||||
|
secureSupportedInitialized = true;
|
||||||
|
}
|
||||||
|
return secureSupported;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a newly created dummy surface. The surface must be released by calling {@link #release}
|
* Returns a newly created dummy surface. The surface must be released by calling {@link #release}
|
||||||
* when it's no longer required.
|
* when it's no longer required.
|
||||||
* <p>
|
* <p>
|
||||||
* Must only be called if {@link Util#SDK_INT} is 17 or higher.
|
* Must only be called if {@link Util#SDK_INT} is 17 or higher.
|
||||||
*
|
*
|
||||||
|
* @param context Any {@link Context}.
|
||||||
* @param secure Whether a secure surface is required. Must only be requested if
|
* @param secure Whether a secure surface is required. Must only be requested if
|
||||||
* {@link #SECURE_SUPPORTED} is {@code true}.
|
* {@link #isSecureSupported(Context)} returns {@code true}.
|
||||||
|
* @throws IllegalStateException If a secure surface is requested on a device for which
|
||||||
|
* {@link #isSecureSupported(Context)} returns {@code false}.
|
||||||
*/
|
*/
|
||||||
public static DummySurface newInstanceV17(boolean secure) {
|
public static DummySurface newInstanceV17(Context context, boolean secure) {
|
||||||
assertApiLevel17OrHigher();
|
assertApiLevel17OrHigher();
|
||||||
Assertions.checkState(!secure || SECURE_SUPPORTED);
|
Assertions.checkState(!secure || isSecureSupported(context));
|
||||||
DummySurfaceThread thread = new DummySurfaceThread();
|
DummySurfaceThread thread = new DummySurfaceThread();
|
||||||
return thread.init(secure);
|
return thread.init(secure);
|
||||||
}
|
}
|
||||||
@ -133,6 +146,23 @@ public final class DummySurface extends Surface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the device is known to advertise secure surface textures but not implement them
|
||||||
|
* correctly.
|
||||||
|
*
|
||||||
|
* @param context Any {@link Context}.
|
||||||
|
*/
|
||||||
|
private static boolean deviceNeedsSecureDummySurfaceWorkaround(Context context) {
|
||||||
|
return Util.SDK_INT == 24
|
||||||
|
&& (Util.MODEL.startsWith("SM-G950") || Util.MODEL.startsWith("SM-G955"))
|
||||||
|
&& !hasVrModeHighPerformanceSystemFeatureV24(context.getPackageManager());
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(24)
|
||||||
|
private static boolean hasVrModeHighPerformanceSystemFeatureV24(PackageManager packageManager) {
|
||||||
|
return packageManager.hasSystemFeature(PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE);
|
||||||
|
}
|
||||||
|
|
||||||
private static class DummySurfaceThread extends HandlerThread implements OnFrameAvailableListener,
|
private static class DummySurfaceThread extends HandlerThread implements OnFrameAvailableListener,
|
||||||
Callback {
|
Callback {
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||||||
// pending output streams that have fewer frames than the codec latency.
|
// pending output streams that have fewer frames than the codec latency.
|
||||||
private static final int MAX_PENDING_OUTPUT_STREAM_OFFSET_COUNT = 10;
|
private static final int MAX_PENDING_OUTPUT_STREAM_OFFSET_COUNT = 10;
|
||||||
|
|
||||||
|
private final Context context;
|
||||||
private final VideoFrameReleaseTimeHelper frameReleaseTimeHelper;
|
private final VideoFrameReleaseTimeHelper frameReleaseTimeHelper;
|
||||||
private final EventDispatcher eventDispatcher;
|
private final EventDispatcher eventDispatcher;
|
||||||
private final long allowedJoiningTimeMs;
|
private final long allowedJoiningTimeMs;
|
||||||
@ -167,6 +168,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||||||
super(C.TRACK_TYPE_VIDEO, mediaCodecSelector, drmSessionManager, playClearSamplesWithoutKeys);
|
super(C.TRACK_TYPE_VIDEO, mediaCodecSelector, drmSessionManager, playClearSamplesWithoutKeys);
|
||||||
this.allowedJoiningTimeMs = allowedJoiningTimeMs;
|
this.allowedJoiningTimeMs = allowedJoiningTimeMs;
|
||||||
this.maxDroppedFramesToNotify = maxDroppedFramesToNotify;
|
this.maxDroppedFramesToNotify = maxDroppedFramesToNotify;
|
||||||
|
this.context = context.getApplicationContext();
|
||||||
frameReleaseTimeHelper = new VideoFrameReleaseTimeHelper(context);
|
frameReleaseTimeHelper = new VideoFrameReleaseTimeHelper(context);
|
||||||
eventDispatcher = new EventDispatcher(eventHandler, eventListener);
|
eventDispatcher = new EventDispatcher(eventHandler, eventListener);
|
||||||
deviceNeedsAutoFrcWorkaround = deviceNeedsAutoFrcWorkaround();
|
deviceNeedsAutoFrcWorkaround = deviceNeedsAutoFrcWorkaround();
|
||||||
@ -341,7 +343,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||||||
} else {
|
} else {
|
||||||
MediaCodecInfo codecInfo = getCodecInfo();
|
MediaCodecInfo codecInfo = getCodecInfo();
|
||||||
if (codecInfo != null && shouldUseDummySurface(codecInfo.secure)) {
|
if (codecInfo != null && shouldUseDummySurface(codecInfo.secure)) {
|
||||||
dummySurface = DummySurface.newInstanceV17(codecInfo.secure);
|
dummySurface = DummySurface.newInstanceV17(context, codecInfo.secure);
|
||||||
surface = dummySurface;
|
surface = dummySurface;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -394,7 +396,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||||||
if (surface == null) {
|
if (surface == null) {
|
||||||
Assertions.checkState(shouldUseDummySurface(codecInfo.secure));
|
Assertions.checkState(shouldUseDummySurface(codecInfo.secure));
|
||||||
if (dummySurface == null) {
|
if (dummySurface == null) {
|
||||||
dummySurface = DummySurface.newInstanceV17(codecInfo.secure);
|
dummySurface = DummySurface.newInstanceV17(context, codecInfo.secure);
|
||||||
}
|
}
|
||||||
surface = dummySurface;
|
surface = dummySurface;
|
||||||
}
|
}
|
||||||
@ -653,8 +655,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldUseDummySurface(boolean codecIsSecure) {
|
private boolean shouldUseDummySurface(boolean codecIsSecure) {
|
||||||
return Util.SDK_INT >= 23 && !tunneling && (!codecIsSecure
|
return Util.SDK_INT >= 23 && !tunneling
|
||||||
|| (DummySurface.SECURE_SUPPORTED && !deviceNeedsSecureDummySurfaceWorkaround()));
|
&& (!codecIsSecure || DummySurface.isSecureSupported(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setJoiningDeadlineMs() {
|
private void setJoiningDeadlineMs() {
|
||||||
@ -921,18 +923,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
|
|||||||
codec.setVideoScalingMode(scalingMode);
|
codec.setVideoScalingMode(scalingMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether the device is known to fail outputting from a secure decoder to a secure
|
|
||||||
* surface texture.
|
|
||||||
* <p>
|
|
||||||
* If true is returned then use of {@link DummySurface} is disabled for secure playbacks.
|
|
||||||
*/
|
|
||||||
private static boolean deviceNeedsSecureDummySurfaceWorkaround() {
|
|
||||||
// See [Internal: b/37197802].
|
|
||||||
return Util.SDK_INT == 24
|
|
||||||
&& (Util.MODEL.startsWith("SM-G950") || Util.MODEL.startsWith("SM-G955"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the device is known to enable frame-rate conversion logic that negatively
|
* Returns whether the device is known to enable frame-rate conversion logic that negatively
|
||||||
* impacts ExoPlayer.
|
* impacts ExoPlayer.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user