Remove dead code related to MediaCodec now minSdk is 21

This removes several workarounds that are no longer needed, including
`codecNeedsMonoChannelCountWorkaround` which has been permanently
disabled since the (incomplete) minSdk 19 clean-up in fb7438378d.

PiperOrigin-RevId: 652495578
This commit is contained in:
ibaker 2024-07-15 08:48:51 -07:00 committed by Copybara-Service
parent 1bb8d5f956
commit bb9ff30c3a
11 changed files with 68 additions and 252 deletions

View File

@ -1192,7 +1192,7 @@ package androidx.media3.common {
field public static final androidx.media3.common.VideoSize UNKNOWN;
field @IntRange(from=0) public final int height;
field @FloatRange(from=0, fromInclusive=false) public final float pixelWidthHeightRatio;
field @IntRange(from=0, to=359) public final int unappliedRotationDegrees;
field @Deprecated @IntRange(from=0, to=359) public final int unappliedRotationDegrees;
field @IntRange(from=0) public final int width;
}

View File

@ -41,19 +41,10 @@ public final class VideoSize {
public final int height;
/**
* Clockwise rotation in degrees that the application should apply for the video for it to be
* rendered in the correct orientation.
*
* <p>Is 0 if unknown or if no rotation is needed.
*
* <p>Player should apply video rotation internally, in which case unappliedRotationDegrees is 0.
* But when a player can't apply the rotation, for example before API level 21, the unapplied
* rotation is reported by this field for application to handle.
*
* <p>Applications that use {@link android.view.TextureView} can apply the rotation by calling
* {@link android.view.TextureView#setTransform}.
* @deprecated Rotation is handled internally by the player, so this is always zero.
*/
@IntRange(from = 0, to = 359)
@Deprecated
public final int unappliedRotationDegrees;
/**
@ -73,7 +64,7 @@ public final class VideoSize {
*/
@UnstableApi
public VideoSize(@IntRange(from = 0) int width, @IntRange(from = 0) int height) {
this(width, height, DEFAULT_UNAPPLIED_ROTATION_DEGREES, DEFAULT_PIXEL_WIDTH_HEIGHT_RATIO);
this(width, height, DEFAULT_PIXEL_WIDTH_HEIGHT_RATIO);
}
/**
@ -81,13 +72,25 @@ public final class VideoSize {
*
* @param width The video width in pixels.
* @param height The video height in pixels.
* @param unappliedRotationDegrees Clockwise rotation in degrees that the application should apply
* for the video for it to be rendered in the correct orientation. See {@link
* #unappliedRotationDegrees}.
* @param pixelWidthHeightRatio The width to height ratio of each pixel. For the normal case of
* square pixels this will be equal to 1.0. Different values are indicative of anamorphic
* content.
*/
@SuppressWarnings("deprecation") // Calling through to deprecated constructor
@UnstableApi
public VideoSize(
@IntRange(from = 0) int width,
@IntRange(from = 0) int height,
@FloatRange(from = 0, fromInclusive = false) float pixelWidthHeightRatio) {
this(width, height, DEFAULT_UNAPPLIED_ROTATION_DEGREES, pixelWidthHeightRatio);
}
/**
* @deprecated Use {@link VideoSize#VideoSize(int, int, float)} instead. {@code
* unappliedRotationDegrees} is not needed on API 21+.
*/
@SuppressWarnings("deprecation") // Setting deprecate field
@Deprecated
@UnstableApi
public VideoSize(
@IntRange(from = 0) int width,
@ -100,6 +103,7 @@ public final class VideoSize {
this.pixelWidthHeightRatio = pixelWidthHeightRatio;
}
@SuppressWarnings("deprecation") // Including deprecated field in equality
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
@ -115,6 +119,7 @@ public final class VideoSize {
return false;
}
@SuppressWarnings("deprecation") // Including deprecated field in hashCode
@Override
public int hashCode() {
int result = 7;
@ -130,6 +135,7 @@ public final class VideoSize {
private static final String FIELD_UNAPPLIED_ROTATION_DEGREES = Util.intToStringMaxRadix(2);
private static final String FIELD_PIXEL_WIDTH_HEIGHT_RATIO = Util.intToStringMaxRadix(3);
@SuppressWarnings("deprecation") // Including deprecated field in bundle
@UnstableApi
public Bundle toBundle() {
Bundle bundle = new Bundle();
@ -141,6 +147,7 @@ public final class VideoSize {
}
/** Restores a {@code VideoSize} from a {@link Bundle}. */
@SuppressWarnings("deprecation") // Parsing deprecated field from bundle
@UnstableApi
public static VideoSize fromBundle(Bundle bundle) {
int width = bundle.getInt(FIELD_WIDTH, DEFAULT_WIDTH);

View File

@ -32,6 +32,7 @@ public final class VideoSizeTest {
}
@Test
@SuppressWarnings("deprecation") // Testing bundling of deprecated field.
public void roundTripViaBundle_ofArbitraryVideoSize_yieldsEqualInstance() {
VideoSize videoSize =
new VideoSize(

View File

@ -58,7 +58,6 @@ import androidx.media3.common.util.TimedValueQueue;
import androidx.media3.common.util.TraceUtil;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.container.NalUnitUtil;
import androidx.media3.decoder.CryptoConfig;
import androidx.media3.decoder.DecoderInputBuffer;
import androidx.media3.decoder.DecoderInputBuffer.InsufficientCapacityException;
@ -170,7 +169,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
format.sampleMimeType,
secureDecoderRequired,
mediaCodecInfo,
Util.SDK_INT >= 21 ? getDiagnosticInfoV21(cause) : null,
(cause instanceof CodecException) ? ((CodecException) cause).getDiagnosticInfo() : null,
/* fallbackDecoderInitializationException= */ null);
}
@ -203,15 +202,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
fallbackException);
}
@RequiresApi(21)
@Nullable
private static String getDiagnosticInfoV21(@Nullable Throwable cause) {
if (cause instanceof CodecException) {
return ((CodecException) cause).getDiagnosticInfo();
}
return null;
}
private static String buildCustomDiagnosticInfo(int errorCode) {
String sign = errorCode < 0 ? "neg_" : "";
String packageName = "androidx.media3.exoplayer.mediacodec";
@ -373,13 +363,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
@Nullable private DecoderInitializationException preferredDecoderInitializationException;
@Nullable private MediaCodecInfo codecInfo;
private @AdaptationWorkaroundMode int codecAdaptationWorkaroundMode;
private boolean codecNeedsDiscardToSpsWorkaround;
private boolean codecNeedsFlushWorkaround;
private boolean codecNeedsSosFlushWorkaround;
private boolean codecNeedsEosFlushWorkaround;
private boolean codecNeedsEosOutputExceptionWorkaround;
private boolean codecNeedsEosBufferTimestampWorkaround;
private boolean codecNeedsMonoChannelCountWorkaround;
private boolean codecNeedsAdaptationWorkaroundBuffer;
private boolean shouldSkipAdaptationWorkaroundOutputBuffer;
private boolean codecNeedsEosPropagation;
@ -898,9 +884,10 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
}
decoderCounters.ensureUpdated();
} catch (IllegalStateException e) {
if (isMediaCodecException(e)) {
if (e instanceof CodecException) {
onCodecError(e);
boolean isRecoverable = Util.SDK_INT >= 21 && isRecoverableMediaCodecExceptionV21(e);
boolean isRecoverable =
(e instanceof CodecException) && ((CodecException) e).isRecoverable();
if (isRecoverable) {
releaseCodec();
}
@ -945,7 +932,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
return false;
}
if (codecDrainAction == DRAIN_ACTION_REINITIALIZE
|| codecNeedsFlushWorkaround
|| (codecNeedsSosFlushWorkaround && !codecHasOutputMediaFormat)
|| (codecNeedsEosFlushWorkaround && codecReceivedEos)) {
releaseCodec();
@ -1020,13 +1006,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
codecHasOutputMediaFormat = false;
codecOperatingRate = CODEC_OPERATING_RATE_UNSET;
codecAdaptationWorkaroundMode = ADAPTATION_WORKAROUND_MODE_NEVER;
codecNeedsDiscardToSpsWorkaround = false;
codecNeedsFlushWorkaround = false;
codecNeedsSosFlushWorkaround = false;
codecNeedsEosFlushWorkaround = false;
codecNeedsEosOutputExceptionWorkaround = false;
codecNeedsEosBufferTimestampWorkaround = false;
codecNeedsMonoChannelCountWorkaround = false;
codecNeedsEosPropagation = false;
codecRegisteredOnBufferAvailableListener = false;
codecReconfigured = false;
@ -1238,9 +1220,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
TraceUtil.beginSection("createCodec:" + codecName);
codec = codecAdapterFactory.createAdapter(configuration);
codecRegisteredOnBufferAvailableListener =
Util.SDK_INT >= 21
&& Api21.registerOnBufferAvailableListener(
codec, new MediaCodecRendererCodecAdapterListener());
codec.registerOnBufferAvailableListener(new MediaCodecRendererCodecAdapterListener());
} finally {
TraceUtil.endSection();
}
@ -1258,14 +1238,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
this.codecOperatingRate = codecOperatingRate;
codecInputFormat = inputFormat;
codecAdaptationWorkaroundMode = codecAdaptationWorkaroundMode(codecName);
codecNeedsDiscardToSpsWorkaround =
codecNeedsDiscardToSpsWorkaround(codecName, checkNotNull(codecInputFormat));
codecNeedsFlushWorkaround = codecNeedsFlushWorkaround(codecName);
codecNeedsSosFlushWorkaround = codecNeedsSosFlushWorkaround(codecName);
codecNeedsEosFlushWorkaround = codecNeedsEosFlushWorkaround(codecName);
codecNeedsEosOutputExceptionWorkaround = codecNeedsEosOutputExceptionWorkaround(codecName);
codecNeedsEosBufferTimestampWorkaround = codecNeedsEosBufferTimestampWorkaround(codecName);
codecNeedsMonoChannelCountWorkaround = false;
codecNeedsEosPropagation =
codecNeedsEosPropagationWorkaround(codecInfo) || getCodecNeedsEosPropagation();
if (checkNotNull(codec).needsReconfiguration()) {
@ -1462,13 +1437,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
if (bufferEncrypted) {
buffer.cryptoInfo.increaseClearDataFirstSubSampleBy(adaptiveReconfigurationBytes);
}
if (codecNeedsDiscardToSpsWorkaround && !bufferEncrypted) {
NalUnitUtil.discardToSps(checkNotNull(buffer.data));
if (checkNotNull(buffer.data).position() == 0) {
return true;
}
codecNeedsDiscardToSpsWorkaround = false;
}
long presentationTimeUs = buffer.timeUs;
@ -1950,7 +1918,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
private boolean drainAndFlushCodec() {
if (codecReceivedBuffers) {
codecDrainState = DRAIN_STATE_SIGNAL_END_OF_STREAM;
if (codecNeedsFlushWorkaround || codecNeedsEosFlushWorkaround) {
if (codecNeedsEosFlushWorkaround) {
codecDrainAction = DRAIN_ACTION_REINITIALIZE;
return false;
} else {
@ -1973,7 +1941,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
private boolean drainAndUpdateCodecDrmSessionV23() throws ExoPlaybackException {
if (codecReceivedBuffers) {
codecDrainState = DRAIN_STATE_SIGNAL_END_OF_STREAM;
if (codecNeedsFlushWorkaround || codecNeedsEosFlushWorkaround) {
if (codecNeedsEosFlushWorkaround) {
codecDrainAction = DRAIN_ACTION_REINITIALIZE;
return false;
} else {
@ -2060,12 +2028,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
outputBuffer.position(outputBufferInfo.offset);
outputBuffer.limit(outputBufferInfo.offset + outputBufferInfo.size);
}
if (codecNeedsEosBufferTimestampWorkaround
&& outputBufferInfo.presentationTimeUs == 0
&& (outputBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0
&& largestQueuedPresentationTimeUs != C.TIME_UNSET) {
outputBufferInfo.presentationTimeUs = lastBufferInStreamPresentationTimeUs;
}
isDecodeOnlyOutputBuffer = outputBufferInfo.presentationTimeUs < getLastResetPositionUs();
isLastOutputBuffer =
lastBufferInStreamPresentationTimeUs != C.TIME_UNSET
@ -2138,9 +2100,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
shouldSkipAdaptationWorkaroundOutputBuffer = true;
return;
}
if (codecNeedsMonoChannelCountWorkaround) {
mediaFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
}
codecOutputMediaFormat = mediaFormat;
codecOutputMediaFormatChanged = true;
}
@ -2557,44 +2516,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
/* startTimeUs= */ startTimeUs, /* frameTimeUs= */ frameTimeUs));
}
private static boolean isMediaCodecException(IllegalStateException error) {
if (Util.SDK_INT >= 21 && isMediaCodecExceptionV21(error)) {
return true;
}
StackTraceElement[] stackTrace = error.getStackTrace();
return stackTrace.length > 0 && stackTrace[0].getClassName().equals("android.media.MediaCodec");
}
@RequiresApi(21)
private static boolean isMediaCodecExceptionV21(IllegalStateException error) {
return error instanceof MediaCodec.CodecException;
}
@RequiresApi(21)
private static boolean isRecoverableMediaCodecExceptionV21(IllegalStateException error) {
if (error instanceof MediaCodec.CodecException) {
return ((MediaCodec.CodecException) error).isRecoverable();
}
return false;
}
/**
* Returns whether the decoder is known to fail when flushed.
*
* <p>If true is returned, the renderer will work around the issue by releasing the decoder and
* instantiating a new one rather than flushing the current instance.
*
* <p>See [Internal: b/8347958, b/8543366].
*
* @param name The name of the decoder.
* @return True if the decoder is known to fail when flushed.
*/
private static boolean codecNeedsFlushWorkaround(String name) {
return Util.SDK_INT == 19
&& Util.MODEL.startsWith("SM-G800")
&& ("OMX.Exynos.avc.dec".equals(name) || "OMX.Exynos.avc.dec.secure".equals(name));
}
/**
* Returns a mode that specifies when the adaptation workaround should be enabled.
*
@ -2628,23 +2549,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
}
}
/**
* Returns whether the decoder is an H.264/AVC decoder known to fail if NAL units are queued
* before the codec specific data.
*
* <p>If true is returned, the renderer will work around the issue by discarding data up to the
* SPS.
*
* @param name The name of the decoder.
* @param format The {@link Format} used to configure the decoder.
* @return True if the decoder is known to fail if NAL units are queued before CSD.
*/
private static boolean codecNeedsDiscardToSpsWorkaround(String name, Format format) {
return Util.SDK_INT < 21
&& format.initializationData.isEmpty()
&& "OMX.MTK.VIDEO.DECODER.AVC".equals(name);
}
/**
* Returns whether the decoder is known to behave incorrectly if flushed prior to having output a
* {@link MediaFormat}.
@ -2708,24 +2612,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|| "OMX.amlogic.avc.decoder.awesome.secure".equals(name)));
}
/**
* Returns whether the decoder may output a non-empty buffer with timestamp 0 as the end of stream
* buffer.
*
* <p>See <a href="https://github.com/google/ExoPlayer/issues/5045">GitHub issue #5045</a>.
*/
private static boolean codecNeedsEosBufferTimestampWorkaround(String codecName) {
return Util.SDK_INT < 21
&& "OMX.SEC.mp3.dec".equals(codecName)
&& "samsung".equals(Util.MANUFACTURER)
&& (Util.DEVICE.startsWith("baffin")
|| Util.DEVICE.startsWith("grand")
|| Util.DEVICE.startsWith("fortuna")
|| Util.DEVICE.startsWith("gprimelte")
|| Util.DEVICE.startsWith("j2y18lte")
|| Util.DEVICE.startsWith("ms01"));
}
/**
* Returns whether the decoder may throw an {@link IllegalStateException} from {@link
* MediaCodec#dequeueOutputBuffer(MediaCodec.BufferInfo, long)} or {@link
@ -2763,15 +2649,6 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
}
}
@RequiresApi(21)
private static final class Api21 {
@DoNotInline
public static boolean registerOnBufferAvailableListener(
MediaCodecAdapter codec, MediaCodecRendererCodecAdapterListener listener) {
return codec.registerOnBufferAvailableListener(listener);
}
}
@RequiresApi(31)
private static final class Api31 {
private Api31() {}

View File

@ -1260,7 +1260,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
}
int width;
int height;
int unappliedRotationDegrees = 0;
float pixelWidthHeightRatio;
if (tunneling) {
@ -1283,22 +1282,16 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
: mediaFormat.getInteger(MediaFormat.KEY_HEIGHT);
}
pixelWidthHeightRatio = format.pixelWidthHeightRatio;
if (codecAppliesRotation()) {
// On API level 21 and above the decoder applies the rotation when rendering to the surface.
// Hence currentUnappliedRotation should always be 0. For 90 and 270 degree rotations, we need
// to flip the width, height and pixel aspect ratio to reflect the rotation that was applied.
if (format.rotationDegrees == 90 || format.rotationDegrees == 270) {
int rotatedHeight = width;
width = height;
height = rotatedHeight;
pixelWidthHeightRatio = 1 / pixelWidthHeightRatio;
}
} else if (videoSink == null) {
// Neither the codec nor the video sink applies the rotation.
unappliedRotationDegrees = format.rotationDegrees;
// The decoder applies the rotation when rendering to the surface. For 90 and 270 degree
// rotations, we need to flip the width, height and pixel aspect ratio to reflect the rotation
// that was applied.
if (format.rotationDegrees == 90 || format.rotationDegrees == 270) {
int rotatedHeight = width;
width = height;
height = rotatedHeight;
pixelWidthHeightRatio = 1 / pixelWidthHeightRatio;
}
decodedVideoSize =
new VideoSize(width, height, unappliedRotationDegrees, pixelWidthHeightRatio);
decodedVideoSize = new VideoSize(width, height, pixelWidthHeightRatio);
if (videoSink != null && videoSinkNeedsRegisterInputStream) {
onReadyToRegisterVideoSinkInputStream();
@ -1308,7 +1301,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
.buildUpon()
.setWidth(width)
.setHeight(height)
.setRotationDegrees(unappliedRotationDegrees)
.setPixelWidthHeightRatio(pixelWidthHeightRatio)
.build());
} else {
@ -1455,7 +1447,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
case VideoFrameReleaseControl.FRAME_RELEASE_TRY_AGAIN_LATER:
return false;
case VideoFrameReleaseControl.FRAME_RELEASE_SCHEDULED:
return maybeReleaseFrame(checkStateNotNull(codec), bufferIndex, presentationTimeUs, format);
releaseFrame(checkStateNotNull(codec), bufferIndex, presentationTimeUs, format);
return true;
default:
throw new IllegalStateException(String.valueOf(frameReleaseAction));
}
@ -1469,46 +1462,22 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
return -startPositionUs;
}
private boolean maybeReleaseFrame(
private void releaseFrame(
MediaCodecAdapter codec, int bufferIndex, long presentationTimeUs, Format format) {
long releaseTimeNs = videoFrameReleaseInfo.getReleaseTimeNs();
long earlyUs = videoFrameReleaseInfo.getEarlyUs();
if (Util.SDK_INT >= 21) {
// Let the underlying framework time the release.
if (shouldSkipBuffersWithIdenticalReleaseTime() && releaseTimeNs == lastFrameReleaseTimeNs) {
// This frame should be displayed on the same vsync with the previous released frame. We
// are likely rendering frames at a rate higher than the screen refresh rate. Skip
// this buffer so that it's returned to MediaCodec sooner otherwise MediaCodec may not
// be able to keep decoding with this rate [b/263454203].
skipOutputBuffer(codec, bufferIndex, presentationTimeUs);
} else {
notifyFrameMetadataListener(presentationTimeUs, releaseTimeNs, format);
renderOutputBufferV21(codec, bufferIndex, presentationTimeUs, releaseTimeNs);
}
updateVideoFrameProcessingOffsetCounters(earlyUs);
lastFrameReleaseTimeNs = releaseTimeNs;
return true;
} else if (earlyUs < 30000) {
// We need to time the release ourselves.
if (earlyUs > 11000) {
// We're a little too early to render the frame. Sleep until the frame can be rendered.
// Note: The 11ms threshold was chosen fairly arbitrarily.
try {
// Subtracting 10000 rather than 11000 ensures the sleep time will be at least 1ms.
Thread.sleep((earlyUs - 10000) / 1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
}
notifyFrameMetadataListener(presentationTimeUs, releaseTimeNs, format);
renderOutputBuffer(codec, bufferIndex, presentationTimeUs);
updateVideoFrameProcessingOffsetCounters(earlyUs);
return true;
if (shouldSkipBuffersWithIdenticalReleaseTime() && releaseTimeNs == lastFrameReleaseTimeNs) {
// This frame should be displayed on the same vsync with the previous released frame. We
// are likely rendering frames at a rate higher than the screen refresh rate. Skip
// this buffer so that it's returned to MediaCodec sooner otherwise MediaCodec may not
// be able to keep decoding with this rate [b/263454203].
skipOutputBuffer(codec, bufferIndex, presentationTimeUs);
} else {
// Too soon.
return false;
notifyFrameMetadataListener(presentationTimeUs, releaseTimeNs, format);
renderOutputBufferV21(codec, bufferIndex, presentationTimeUs, releaseTimeNs);
}
updateVideoFrameProcessingOffsetCounters(earlyUs);
lastFrameReleaseTimeNs = releaseTimeNs;
}
private void notifyFrameMetadataListener(
@ -1715,21 +1684,14 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
*/
private void renderOutputBuffer(
MediaCodecAdapter codec, int index, long presentationTimeUs, long releaseTimeNs) {
if (Util.SDK_INT >= 21) {
renderOutputBufferV21(codec, index, presentationTimeUs, releaseTimeNs);
} else {
renderOutputBuffer(codec, index, presentationTimeUs);
}
renderOutputBufferV21(codec, index, presentationTimeUs, releaseTimeNs);
}
/**
* Renders the output buffer with the specified index. This method is only called if the platform
* API version of the device is less than 21.
*
* @param codec The codec that owns the output buffer.
* @param index The index of the output buffer to drop.
* @param presentationTimeUs The presentation time of the output buffer, in microseconds.
* @deprecated Override {@link #renderOutputBufferV21} instead. The library has min SDK 21, so
* this method is never called.
*/
@Deprecated
protected void renderOutputBuffer(MediaCodecAdapter codec, int index, long presentationTimeUs) {
TraceUtil.beginSection("releaseOutputBuffer");
codec.releaseOutputBuffer(index, true);
@ -1751,7 +1713,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
* @param presentationTimeUs The presentation time of the output buffer, in microseconds.
* @param releaseTimeNs The wallclock time at which the frame should be displayed, in nanoseconds.
*/
@RequiresApi(21)
protected void renderOutputBufferV21(
MediaCodecAdapter codec, int index, long presentationTimeUs, long releaseTimeNs) {
TraceUtil.beginSection("releaseOutputBuffer");
@ -1903,12 +1864,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
codec.setOutputSurface(surface);
}
@RequiresApi(21)
private static void configureTunnelingV21(MediaFormat mediaFormat, int tunnelingAudioSessionId) {
mediaFormat.setFeatureEnabled(CodecCapabilities.FEATURE_TunneledPlayback, true);
mediaFormat.setInteger(MediaFormat.KEY_AUDIO_SESSION_ID, tunnelingAudioSessionId);
}
/**
* Returns the framework {@link MediaFormat} that should be used to configure the decoder.
*
@ -1924,7 +1879,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
* @return The framework {@link MediaFormat} that should be used to configure the decoder.
*/
@SuppressLint("InlinedApi")
@TargetApi(21) // tunnelingAudioSessionId is unset if Util.SDK_INT < 21
protected MediaFormat getMediaFormat(
Format format,
String codecMimeType,
@ -1968,7 +1922,8 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
mediaFormat.setInteger("auto-frc", 0);
}
if (tunnelingAudioSessionId != C.AUDIO_SESSION_ID_UNSET) {
configureTunnelingV21(mediaFormat, tunnelingAudioSessionId);
mediaFormat.setFeatureEnabled(CodecCapabilities.FEATURE_TunneledPlayback, true);
mediaFormat.setInteger(MediaFormat.KEY_AUDIO_SESSION_ID, tunnelingAudioSessionId);
}
if (Util.SDK_INT >= 35) {
mediaFormat.setInteger(MediaFormat.KEY_IMPORTANCE, max(0, -rendererPriority));
@ -2066,7 +2021,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
if (longEdgePx <= formatLongEdgePx || shortEdgePx <= formatShortEdgePx) {
// Don't return a size not larger than the format for which the codec is being configured.
return null;
} else if (Util.SDK_INT >= 21) {
} else {
Point alignedSize =
codecInfo.alignVideoSizeV21(
isVerticalVideo ? shortEdgePx : longEdgePx,
@ -2076,20 +2031,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
&& codecInfo.isVideoSizeAndRateSupportedV21(alignedSize.x, alignedSize.y, frameRate)) {
return alignedSize;
}
} else {
try {
// Conservatively assume the codec requires 16px width and height alignment.
longEdgePx = Util.ceilDivide(longEdgePx, 16) * 16;
shortEdgePx = Util.ceilDivide(shortEdgePx, 16) * 16;
if (longEdgePx * shortEdgePx <= MediaCodecUtil.maxH264DecodableFrameSize()) {
return new Point(
isVerticalVideo ? shortEdgePx : longEdgePx,
isVerticalVideo ? longEdgePx : shortEdgePx);
}
} catch (DecoderQueryException e) {
// We tried our best. Give up!
return null;
}
}
}
return null;
@ -2118,10 +2059,6 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer
}
}
private static boolean codecAppliesRotation() {
return Util.SDK_INT >= 21;
}
/**
* Returns whether the device is known to do post processing by default that isn't compatible with
* ExoPlayer.

View File

@ -636,6 +636,7 @@ public class MediaCodecVideoRendererTest {
}
@Test
@SuppressWarnings("deprecation") // Testing propagation of deprecated unappliedRotationDegrees.
public void render_sendsVideoSizeChangeWithCurrentFormatValues() throws Exception {
FakeSampleStream fakeSampleStream =
new FakeSampleStream(

View File

@ -2649,7 +2649,7 @@ public class MediaControllerListenerTest {
@Test
public void onVideoSizeChanged() throws Exception {
VideoSize defaultVideoSize = MediaTestUtils.createDefaultVideoSize();
VideoSize defaultVideoSize = MediaTestUtils.getDefaultVideoSize();
RemoteMediaSession session = createRemoteMediaSession(TEST_ON_VIDEO_SIZE_CHANGED);
MediaController controller = controllerTestRule.createController(session.getToken());
List<VideoSize> videoSizeFromGetterList = new ArrayList<>();

View File

@ -874,6 +874,7 @@ public class MediaControllerTest {
}
@Test
@SuppressWarnings("deprecation") // Testing propagation of deprecated unappliedRotationDegrees.
public void getVideoSize_returnsVideoSizeOfPlayerInSession() throws Exception {
VideoSize testVideoSize =
new VideoSize(

View File

@ -289,7 +289,7 @@ public class MediaSessionProviderService extends Service {
case TEST_ON_TRACKS_CHANGED_VIDEO_TO_AUDIO_TRANSITION:
case TEST_ON_VIDEO_SIZE_CHANGED:
{
mockPlayer.videoSize = MediaTestUtils.createDefaultVideoSize();
mockPlayer.videoSize = MediaTestUtils.getDefaultVideoSize();
mockPlayer.currentTracks = MediaTestUtils.createDefaultVideoTracks();
break;
}

View File

@ -94,13 +94,9 @@ public final class MediaTestUtils {
/* trackSelected= */ new boolean[] {true})));
}
/** Returns a new {@link VideoSize} instance for testing purpose. */
public static VideoSize createDefaultVideoSize() {
return new VideoSize(
DEFAULT_VIDEO_SIZE.width,
DEFAULT_VIDEO_SIZE.height,
DEFAULT_VIDEO_SIZE.unappliedRotationDegrees,
DEFAULT_VIDEO_SIZE.pixelWidthHeightRatio);
/** Returns a {@link VideoSize} instance for testing purpose. */
public static VideoSize getDefaultVideoSize() {
return DEFAULT_VIDEO_SIZE;
}
/** Create a media item with the mediaId for testing purpose. */

View File

@ -157,11 +157,7 @@ public class FakeVideoRenderer extends FakeRenderer {
handler.post(
() -> {
VideoSize videoSize =
new VideoSize(
format.width,
format.height,
format.rotationDegrees,
format.pixelWidthHeightRatio);
new VideoSize(format.width, format.height, format.pixelWidthHeightRatio);
if (!Objects.equals(videoSize, videoSizeRef.get())) {
eventListener.onVideoSizeChanged(videoSize);
videoSizeRef.set(videoSize);