Signal fallback via renderer constructor

Remove MediaCodecSelector.DEFAULT_WITH_FALLBACK, as codec selectors
will need to be able to return a list of decoder infos even when not
using fallback in a later change. Instead signal that fallback should
be used via a renderer constructor.

Fallback is always disabled for audio.

PiperOrigin-RevId: 242454172
This commit is contained in:
andrewlewis 2019-04-08 14:46:02 +01:00 committed by Oliver Woodman
parent baf00406c0
commit 401e20d9c8
5 changed files with 70 additions and 32 deletions

View file

@ -102,6 +102,9 @@
([#5698](https://github.com/google/ExoPlayer/issues/5698),
[#5694](https://github.com/google/ExoPlayer/issues/5694)).
* Move `PriorityTaskManager` from `DefaultLoadControl` to `SimpleExoPlayer`.
* Remove `MediaCodecSelector.DEFAULT_WITH_FALLBACK`. Apps should instead signal
that fallback should be used by passing `true` as the `enableDecoderFallback`
parameter when instantiating the video renderer.
### 2.9.6 ###

View file

@ -250,6 +250,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
mediaCodecSelector,
drmSessionManager,
playClearSamplesWithoutKeys,
/* enableDecoderFallback= */ false,
/* assumedMinimumCodecOperatingRate= */ 44100);
this.context = context.getApplicationContext();
this.audioSink = audioSink;

View file

@ -53,6 +53,7 @@ import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
@ -289,6 +290,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
private final MediaCodecSelector mediaCodecSelector;
@Nullable private final DrmSessionManager<FrameworkMediaCrypto> drmSessionManager;
private final boolean playClearSamplesWithoutKeys;
private final boolean enableDecoderFallback;
private final float assumedMinimumCodecOperatingRate;
private final DecoderInputBuffer buffer;
private final DecoderInputBuffer flagsOnlyBuffer;
@ -354,6 +356,9 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
* begin in parallel with key acquisition. This parameter specifies whether the renderer is
* permitted to play clear regions of encrypted media files before {@code drmSessionManager}
* has obtained the keys necessary to decrypt encrypted regions of the media.
* @param enableDecoderFallback Whether to enable fallback to lower-priority decoders if decoder
* initialization fails. This may result in using a decoder that is less efficient or slower
* than the primary decoder.
* @param assumedMinimumCodecOperatingRate A codec operating rate that all codecs instantiated by
* this renderer are assumed to meet implicitly (i.e. without the operating rate being set
* explicitly using {@link MediaFormat#KEY_OPERATING_RATE}).
@ -363,11 +368,13 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
MediaCodecSelector mediaCodecSelector,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
boolean playClearSamplesWithoutKeys,
boolean enableDecoderFallback,
float assumedMinimumCodecOperatingRate) {
super(trackType);
this.mediaCodecSelector = Assertions.checkNotNull(mediaCodecSelector);
this.drmSessionManager = drmSessionManager;
this.playClearSamplesWithoutKeys = playClearSamplesWithoutKeys;
this.enableDecoderFallback = enableDecoderFallback;
this.assumedMinimumCodecOperatingRate = assumedMinimumCodecOperatingRate;
buffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DISABLED);
flagsOnlyBuffer = DecoderInputBuffer.newFlagsOnlyInstance();
@ -735,8 +742,14 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
throws DecoderInitializationException {
if (availableCodecInfos == null) {
try {
availableCodecInfos =
new ArrayDeque<>(getAvailableCodecInfos(mediaCryptoRequiresSecureDecoder));
List<MediaCodecInfo> allAvailableCodecInfos =
getAvailableCodecInfos(mediaCryptoRequiresSecureDecoder);
if (enableDecoderFallback) {
availableCodecInfos = new ArrayDeque<>(allAvailableCodecInfos);
} else {
availableCodecInfos =
new ArrayDeque<>(Collections.singletonList(allAvailableCodecInfos.get(0)));
}
preferredDecoderInitializationException = null;
} catch (DecoderQueryException e) {
throw new DecoderInitializationException(

View file

@ -18,7 +18,6 @@ package com.google.android.exoplayer2.mediacodec;
import android.media.MediaCodec;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException;
import java.util.Collections;
import java.util.List;
/**
@ -31,32 +30,6 @@ public interface MediaCodecSelector {
* the given format.
*/
MediaCodecSelector DEFAULT =
new MediaCodecSelector() {
@Override
public List<MediaCodecInfo> getDecoderInfos(String mimeType, boolean requiresSecureDecoder)
throws DecoderQueryException {
List<MediaCodecInfo> decoderInfos =
MediaCodecUtil.getDecoderInfos(mimeType, requiresSecureDecoder);
return decoderInfos.isEmpty()
? Collections.emptyList()
: Collections.singletonList(decoderInfos.get(0));
}
@Override
public @Nullable MediaCodecInfo getPassthroughDecoderInfo() throws DecoderQueryException {
return MediaCodecUtil.getPassthroughDecoderInfo();
}
};
/**
* A {@link MediaCodecSelector} that returns a list of decoders in priority order, allowing
* fallback to less preferred decoders if initialization fails.
*
* <p>Note: if a hardware-accelerated video decoder fails to initialize, this selector may provide
* a software video decoder to use as a fallback. Using software decoding can be inefficient, and
* the decoder may be too slow to keep up with the playback position.
*/
MediaCodecSelector DEFAULT_WITH_FALLBACK =
new MediaCodecSelector() {
@Override
public List<MediaCodecInfo> getDecoderInfos(String mimeType, boolean requiresSecureDecoder)

View file

@ -210,16 +210,64 @@ public class MediaCodecVideoRenderer extends MediaCodecRenderer {
* @param maxDroppedFramesToNotify The maximum number of frames that can be dropped between
* invocations of {@link VideoRendererEventListener#onDroppedFrames(int, long)}.
*/
public MediaCodecVideoRenderer(Context context, MediaCodecSelector mediaCodecSelector,
public MediaCodecVideoRenderer(
Context context,
MediaCodecSelector mediaCodecSelector,
long allowedJoiningTimeMs,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
boolean playClearSamplesWithoutKeys, @Nullable Handler eventHandler,
@Nullable VideoRendererEventListener eventListener, int maxDroppedFramesToNotify) {
boolean playClearSamplesWithoutKeys,
@Nullable Handler eventHandler,
@Nullable VideoRendererEventListener eventListener,
int maxDroppedFramesToNotify) {
this(
context,
mediaCodecSelector,
allowedJoiningTimeMs,
drmSessionManager,
playClearSamplesWithoutKeys,
/* enableDecoderFallback= */ false,
eventHandler,
eventListener,
maxDroppedFramesToNotify);
}
/**
* @param context A context.
* @param mediaCodecSelector A decoder selector.
* @param allowedJoiningTimeMs The maximum duration in milliseconds for which this video renderer
* can attempt to seamlessly join an ongoing playback.
* @param drmSessionManager For use with encrypted content. May be null if support for encrypted
* content is not required.
* @param playClearSamplesWithoutKeys Encrypted media may contain clear (un-encrypted) regions.
* For example a media file may start with a short clear region so as to allow playback to
* begin in parallel with key acquisition. This parameter specifies whether the renderer is
* permitted to play clear regions of encrypted media files before {@code drmSessionManager}
* has obtained the keys necessary to decrypt encrypted regions of the media.
* @param enableDecoderFallback Whether to enable fallback to lower-priority decoders if decoder
* initialization fails. This may result in using a decoder that is slower/less efficient than
* the primary decoder.
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
* null if delivery of events is not required.
* @param eventListener A listener of events. May be null if delivery of events is not required.
* @param maxDroppedFramesToNotify The maximum number of frames that can be dropped between
* invocations of {@link VideoRendererEventListener#onDroppedFrames(int, long)}.
*/
public MediaCodecVideoRenderer(
Context context,
MediaCodecSelector mediaCodecSelector,
long allowedJoiningTimeMs,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
boolean playClearSamplesWithoutKeys,
boolean enableDecoderFallback,
@Nullable Handler eventHandler,
@Nullable VideoRendererEventListener eventListener,
int maxDroppedFramesToNotify) {
super(
C.TRACK_TYPE_VIDEO,
mediaCodecSelector,
drmSessionManager,
playClearSamplesWithoutKeys,
enableDecoderFallback,
/* assumedMinimumCodecOperatingRate= */ 30);
this.allowedJoiningTimeMs = allowedJoiningTimeMs;
this.maxDroppedFramesToNotify = maxDroppedFramesToNotify;