diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 6bb1b08cd7..0d27c53384 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -14,6 +14,10 @@ `TrackGroup` constructor. This fixes a crash when resuming playback after backgrounding the app with an active track override ((#9718)[https://github.com/google/ExoPlayer/issues/9718]). + * Sleep and retry when creating a `MediaCodec` instance fails. This works + around an issue that occurs on some devices when switching a surface + from a secure codec to another codec + (#8696)[https://github.com/google/ExoPlayer/issues/8696]. * Android 12 compatibility: * Upgrade the Cast extension to depend on `com.google.android.gms:play-services-cast-framework:20.1.0`. Earlier 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 cb2194bbc5..72497d2771 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 @@ -976,13 +976,27 @@ public abstract class MediaCodecRenderer extends BaseRenderer { DecoderInitializationException.NO_SUITABLE_DECODER_ERROR); } + MediaCodecInfo preferredCodecInfo = availableCodecInfos.peekFirst(); while (codec == null) { MediaCodecInfo codecInfo = availableCodecInfos.peekFirst(); if (!shouldInitCodec(codecInfo)) { return; } try { - initCodec(codecInfo, crypto); + try { + initCodec(codecInfo, crypto); + } catch (Exception e) { + if (codecInfo == preferredCodecInfo) { + // If creating the preferred decoder failed then sleep briefly before retrying. + // Workaround for [internal b/191966399]. + // See also https://github.com/google/ExoPlayer/issues/8696. + Log.w(TAG, "Preferred decoder instantiation failed. Sleeping for 50ms then retrying."); + Thread.sleep(/* millis= */ 50); + initCodec(codecInfo, crypto); + } else { + throw e; + } + } } catch (Exception e) { Log.w(TAG, "Failed to initialize decoder: " + codecInfo, e); // This codec failed to initialize, so fall back to the next codec in the list (if any). We @@ -1060,13 +1074,17 @@ public abstract class MediaCodecRenderer extends BaseRenderer { codecOperatingRate = CODEC_OPERATING_RATE_UNSET; } codecInitializingTimestamp = SystemClock.elapsedRealtime(); - TraceUtil.beginSection("createCodec:" + codecName); MediaCodecAdapter.Configuration configuration = getMediaCodecConfiguration(codecInfo, inputFormat, crypto, codecOperatingRate); if (Util.SDK_INT >= 31) { Api31.setLogSessionIdToMediaCodecFormat(configuration, getPlayerId()); } - codec = codecAdapterFactory.createAdapter(configuration); + try { + TraceUtil.beginSection("createCodec:" + codecName); + codec = codecAdapterFactory.createAdapter(configuration); + } finally { + TraceUtil.endSection(); + } codecInitializedTimestamp = SystemClock.elapsedRealtime(); this.codecInfo = codecInfo;