mirror of
https://github.com/samsonjs/media.git
synced 2026-04-05 11:15:46 +00:00
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:
parent
baf00406c0
commit
401e20d9c8
5 changed files with 70 additions and 32 deletions
|
|
@ -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 ###
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue