Skip to content

Commit

Permalink
Always set PARAMETER_KEY_TUNNEL_PEEK when tunneling
Browse files Browse the repository at this point in the history
This should already be the default, but some devices seem
to not adhere to this contract and assume the default is unset.

Issue: androidx#1169
PiperOrigin-RevId: 614697283
(cherry picked from commit cbed80e)
  • Loading branch information
tonihei authored and l1068 committed Apr 15, 2024
1 parent 8a66055 commit 3972d25
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 18 deletions.
3 changes: 3 additions & 0 deletions RELEASENOTES.md
Expand Up @@ -27,6 +27,9 @@
* 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
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)).
* DRM:
* Work around a `NoSuchMethodError` which can be thrown by the `MediaDrm`
Expand Down
Expand Up @@ -659,7 +659,7 @@ protected void onPositionReset(long positionUs, boolean joining) throws ExoPlayb
if (joining) {
videoFrameReleaseControl.join();
}
maybeUpdateOnFrameRenderedListener();
maybeSetupTunnelingForFirstFrame();
consecutiveDroppedFrameCount = 0;
}

Expand Down Expand Up @@ -704,7 +704,7 @@ protected void onStopped() {
protected void onDisabled() {
reportedVideoSize = null;
videoFrameReleaseControl.onDisabled();
maybeUpdateOnFrameRenderedListener();
maybeSetupTunnelingForFirstFrame();
haveReportedFirstFrameRenderedForCurrentSurface = false;
tunnelingOnFrameRenderedListener = null;
try {
Expand Down Expand Up @@ -846,7 +846,7 @@ private void setOutput(@Nullable Object output) throws ExoPlaybackException {
videoSinkProvider.clearOutputSurfaceInfo();
}
}
maybeUpdateOnFrameRenderedListener();
maybeSetupTunnelingForFirstFrame();
} else if (displaySurface != null && displaySurface != placeholderSurface) {
// 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.
Expand Down Expand Up @@ -1129,9 +1129,7 @@ protected void onCodecInitialized(
codecNeedsSetOutputSurfaceWorkaround = codecNeedsSetOutputSurfaceWorkaround(name);
codecHandlesHdr10PlusOutOfBandMetadata =
checkNotNull(getCodecInfo()).isHdr10PlusOutOfBandMetadataSupported();
if (Util.SDK_INT >= 23 && tunneling) {
tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(checkNotNull(getCodec()));
}
maybeSetupTunnelingForFirstFrame();
}

@Override
Expand Down Expand Up @@ -1462,7 +1460,7 @@ protected void onProcessedOutputBuffer(long presentationTimeUs) {
protected void onProcessedStreamChange() {
super.onProcessedStreamChange();
videoFrameReleaseControl.onProcessedStreamChange();
maybeUpdateOnFrameRenderedListener();
maybeSetupTunnelingForFirstFrame();
if (videoSinkProvider.isInitialized()) {
videoSinkProvider.setStreamOffsetUs(getOutputStreamOffsetUs());
}
Expand Down Expand Up @@ -1693,17 +1691,25 @@ private void releasePlaceholderSurface() {
}
}

private void maybeUpdateOnFrameRenderedListener() {
// The first frame notification is triggered by renderOutputBuffer or renderOutputBufferV21 for
// non-tunneled playback, onQueueInputBuffer for tunneled playback prior to API level 23, and
// OnFrameRenderedListenerV23.onFrameRenderedListener for tunneled playback on API level 23 and
// above.
if (Util.SDK_INT >= 23 && tunneling) {
@Nullable MediaCodecAdapter codec = getCodec();
// If codec is null then the listener will be instantiated in configureCodec.
if (codec != null) {
tunnelingOnFrameRenderedListener = new OnFrameRenderedListenerV23(codec);
}
private void maybeSetupTunnelingForFirstFrame() {
if (!tunneling || Util.SDK_INT < 23) {
// The first frame notification for tunneling is triggered by onQueueInputBuffer prior to API
// level 23 and no setup is needed here.
return;
}
@Nullable MediaCodecAdapter codec = getCodec();
if (codec == null) {
// If codec is null, then the setup will be triggered again in onCodecInitialized.
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);
}
}

Expand Down

0 comments on commit 3972d25

Please sign in to comment.