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
This commit is contained in:
tonihei 2024-03-11 09:46:07 -07:00 committed by Copybara-Service
parent 6f109ffa6a
commit cbed80ecf3
2 changed files with 27 additions and 18 deletions

View File

@ -44,6 +44,9 @@
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
([#966](https://github.com/androidx/media/issues/966)). ([#966](https://github.com/androidx/media/issues/966)).
* 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)).
* Text: * Text:
* Metadata: * Metadata:
* Image: * Image:

View File

@ -662,7 +662,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
if (joining) { if (joining) {
videoFrameReleaseControl.join(); videoFrameReleaseControl.join();
} }
maybeUpdateOnFrameRenderedListener(); maybeSetupTunnelingForFirstFrame();
consecutiveDroppedFrameCount = 0; consecutiveDroppedFrameCount = 0;
} }
@ -707,7 +707,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 {
@ -848,7 +848,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.
@ -1130,9 +1130,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
@ -1464,7 +1462,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());
} }
@ -1694,17 +1692,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);
} }
} }