From cfa837df5c20a217de574f6d8d53ef161716f973 Mon Sep 17 00:00:00 2001 From: olly Date: Thu, 6 Jun 2019 00:42:40 +0100 Subject: [PATCH] Don't throw DecoderQueryException from getCodecMaxSize It's only thrown in an edge case on API level 20 and below. If it is thrown it causes playback failure when playback could succeed, by throwing up through configureCodec. It seems better just to catch the exception and have the codec be configured using the format's own width and height. PiperOrigin-RevId: 251745539 --- .../mediacodec/MediaCodecRenderer.java | 4 +-- .../video/MediaCodecVideoRenderer.java | 35 ++++++++++--------- .../testutil/DebugRenderersFactory.java | 4 +-- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java index d636467303..d00b218c38 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecRenderer.java @@ -455,15 +455,13 @@ public abstract class MediaCodecRenderer extends BaseRenderer { * @param crypto For drm protected playbacks, a {@link MediaCrypto} to use for decryption. * @param codecOperatingRate The codec operating rate, or {@link #CODEC_OPERATING_RATE_UNSET} if * no codec operating rate should be set. - * @throws DecoderQueryException If an error occurs querying {@code codecInfo}. */ protected abstract void configureCodec( MediaCodecInfo codecInfo, MediaCodec codec, Format format, MediaCrypto crypto, - float codecOperatingRate) - throws DecoderQueryException; + float codecOperatingRate); protected final void maybeInitCodec() throws ExoPlaybackException { if (codec != null || inputFormat == null) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java index 33eb1095c3..45ab06db45 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/video/MediaCodecVideoRenderer.java @@ -581,8 +581,7 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { MediaCodec codec, Format format, MediaCrypto crypto, - float codecOperatingRate) - throws DecoderQueryException { + float codecOperatingRate) { codecMaxValues = getCodecMaxValues(codecInfo, format, getStreamFormats()); MediaFormat mediaFormat = getMediaFormat( @@ -1210,11 +1209,9 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { * @param format The format for which the codec is being configured. * @param streamFormats The possible stream formats. * @return Suitable {@link CodecMaxValues}. - * @throws DecoderQueryException If an error occurs querying {@code codecInfo}. */ protected CodecMaxValues getCodecMaxValues( - MediaCodecInfo codecInfo, Format format, Format[] streamFormats) - throws DecoderQueryException { + MediaCodecInfo codecInfo, Format format, Format[] streamFormats) { int maxWidth = format.width; int maxHeight = format.height; int maxInputSize = getMaxInputSize(codecInfo, format); @@ -1264,17 +1261,15 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { } /** - * Returns a maximum video size to use when configuring a codec for {@code format} in a way - * that will allow possible adaptation to other compatible formats that are expected to have the - * same aspect ratio, but whose sizes are unknown. + * Returns a maximum video size to use when configuring a codec for {@code format} in a way that + * will allow possible adaptation to other compatible formats that are expected to have the same + * aspect ratio, but whose sizes are unknown. * * @param codecInfo Information about the {@link MediaCodec} being configured. * @param format The format for which the codec is being configured. * @return The maximum video size to use, or null if the size of {@code format} should be used. - * @throws DecoderQueryException If an error occurs querying {@code codecInfo}. */ - private static Point getCodecMaxSize(MediaCodecInfo codecInfo, Format format) - throws DecoderQueryException { + private static Point getCodecMaxSize(MediaCodecInfo codecInfo, Format format) { boolean isVerticalVideo = format.height > format.width; int formatLongEdgePx = isVerticalVideo ? format.height : format.width; int formatShortEdgePx = isVerticalVideo ? format.width : format.height; @@ -1292,12 +1287,18 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer { return alignedSize; } } else { - // 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); + 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; } } } diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/DebugRenderersFactory.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/DebugRenderersFactory.java index e1243d34ba..d6b72048a1 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/DebugRenderersFactory.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/DebugRenderersFactory.java @@ -31,7 +31,6 @@ import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.FrameworkMediaCrypto; import com.google.android.exoplayer2.mediacodec.MediaCodecInfo; import com.google.android.exoplayer2.mediacodec.MediaCodecSelector; -import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException; import com.google.android.exoplayer2.video.MediaCodecVideoRenderer; import com.google.android.exoplayer2.video.VideoRendererEventListener; import java.nio.ByteBuffer; @@ -115,8 +114,7 @@ public class DebugRenderersFactory extends DefaultRenderersFactory { MediaCodec codec, Format format, MediaCrypto crypto, - float operatingRate) - throws DecoderQueryException { + float operatingRate) { // If the codec is being initialized whilst the renderer is started, default behavior is to // render the first frame (i.e. the keyframe before the current position), then drop frames up // to the current playback position. For test runs that place a maximum limit on the number of