Always set PARAMETER_KEY_TUNNEL_PEEK when tunneling

This should already be the default, but some devices seem
to not adhere to this contract and assume the default is unset.

Issue: androidx/media#1169
PiperOrigin-RevId: 614697283
(cherry picked from commit cbed80ecf36d3ff49ec9d2806670f1fda3551aba)
This commit is contained in:
tonihei 2024-03-11 09:46:07 -07:00 committed by SheenaChhabra
parent 3f3d60eb6a
commit c8ae6d1142
2 changed files with 27 additions and 18 deletions

View File

@ -27,6 +27,9 @@
* Add workaround for a device issue on Galaxy Tab S7 FE, Chromecast with * Add workaround for a device issue on Galaxy Tab S7 FE, Chromecast with
Google TV, and Lenovo M10 FHD Plus that causes 60fps H265 streams to be Google TV, and Lenovo M10 FHD Plus that causes 60fps H265 streams to be
marked as unsupported marked as unsupported
* Add workaround that ensures the first frame is always rendered while
tunneling even if the device does not do this automatically as required
by the API ([#1169](https://github.com/androidx/media/issues/1169)).
([#966](https://github.com/androidx/media/issues/966)). ([#966](https://github.com/androidx/media/issues/966)).
* DRM: * DRM:
* Work around a `NoSuchMethodError` which can be thrown by the `MediaDrm` * Work around a `NoSuchMethodError` which can be thrown by the `MediaDrm`

View File

@ -659,7 +659,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
if (joining) { if (joining) {
videoFrameReleaseControl.join(); videoFrameReleaseControl.join();
} }
maybeUpdateOnFrameRenderedListener(); maybeSetupTunnelingForFirstFrame();
consecutiveDroppedFrameCount = 0; consecutiveDroppedFrameCount = 0;
} }
@ -704,7 +704,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
protected void onDisabled() { protected void onDisabled() {
reportedVideoSize = null; reportedVideoSize = null;
videoFrameReleaseControl.onDisabled(); videoFrameReleaseControl.onDisabled();
maybeUpdateOnFrameRenderedListener(); maybeSetupTunnelingForFirstFrame();
haveReportedFirstFrameRenderedForCurrentSurface = false; haveReportedFirstFrameRenderedForCurrentSurface = false;
tunnelingOnFrameRenderedListener = null; tunnelingOnFrameRenderedListener = null;
try { try {
@ -846,7 +846,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
videoSinkProvider.clearOutputSurfaceInfo(); videoSinkProvider.clearOutputSurfaceInfo();
} }
} }
maybeUpdateOnFrameRenderedListener(); maybeSetupTunnelingForFirstFrame();
} else if (displaySurface != null && displaySurface != placeholderSurface) { } else if (displaySurface != null && displaySurface != placeholderSurface) {
// The display surface is set and unchanged. If we know the video size and/or have already // The display surface is set and unchanged. If we know the video size and/or have already
// rendered to the display surface, report these again immediately. // rendered to the display surface, report these again immediately.
@ -1129,9 +1129,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
codecNeedsSetOutputSurfaceWorkaround = codecNeedsSetOutputSurfaceWorkaround(name); codecNeedsSetOutputSurfaceWorkaround = codecNeedsSetOutputSurfaceWorkaround(name);
codecHandlesHdr10PlusOutOfBandMetadata = codecHandlesHdr10PlusOutOfBandMetadata =
checkNotNull(getCodecInfo()).isHdr10PlusOutOfBandMetadataSupported(); checkNotNull(getCodecInfo()).isHdr10PlusOutOfBandMetadataSupported();
if (Util.SDK_INT >= 23 && tunneling) { maybeSetupTunnelingForFirstFrame();
tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(checkNotNull(getCodec()));
}
} }
@Override @Override
@ -1462,7 +1460,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
protected void onProcessedStreamChange() { protected void onProcessedStreamChange() {
super.onProcessedStreamChange(); super.onProcessedStreamChange();
videoFrameReleaseControl.onProcessedStreamChange(); videoFrameReleaseControl.onProcessedStreamChange();
maybeUpdateOnFrameRenderedListener(); maybeSetupTunnelingForFirstFrame();
if (videoSinkProvider.isInitialized()) { if (videoSinkProvider.isInitialized()) {
videoSinkProvider.setStreamOffsetUs(getOutputStreamOffsetUs()); videoSinkProvider.setStreamOffsetUs(getOutputStreamOffsetUs());
} }
@ -1693,17 +1691,25 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
} }
} }
private void maybeUpdateOnFrameRenderedListener() { private void maybeSetupTunnelingForFirstFrame() {
// The first frame notification is triggered by renderOutputBuffer or renderOutputBufferV21 for if (!tunneling || Util.SDK_INT < 23) {
// non-tunneled playback, onQueueInputBuffer for tunneled playback prior to API level 23, and // The first frame notification for tunneling is triggered by onQueueInputBuffer prior to API
// OnFrameRenderedListenerV23.onFrameRenderedListener for tunneled playback on API level 23 and // level 23 and no setup is needed here.
// above. return;
if (Util.SDK_INT >= 23 && tunneling) { }
@Nullable MediaCodecAdapter codec = getCodec(); @Nullable MediaCodecAdapter codec = getCodec();
// If codec is null then the listener will be instantiated in configureCodec. if (codec == null) {
if (codec != null) { // If codec is null, then the setup will be triggered again in onCodecInitialized.
tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(codec); return;
} }
tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(codec);
if (Util.SDK_INT >= 33) {
// This should be the default anyway according to the API contract, but some devices are known
// to not adhere to this contract and need to get the parameter explicitly. See
// https://github.com/androidx/media/issues/1169.
Bundle codecParameters = new Bundle();
codecParameters.putInt(MediaCodec.PARAMETER_KEY_TUNNEL_PEEK, 1);
codec.setParameters(codecParameters);
} }
} }