mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +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),
|
([#5698](https://github.com/google/ExoPlayer/issues/5698),
|
||||||
[#5694](https://github.com/google/ExoPlayer/issues/5694)).
|
[#5694](https://github.com/google/ExoPlayer/issues/5694)).
|
||||||
* Move `PriorityTaskManager` from `DefaultLoadControl` to `SimpleExoPlayer`.
|
* 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 ###
|
### 2.9.6 ###
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -250,6 +250,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||||
mediaCodecSelector,
|
mediaCodecSelector,
|
||||||
drmSessionManager,
|
drmSessionManager,
|
||||||
playClearSamplesWithoutKeys,
|
playClearSamplesWithoutKeys,
|
||||||
|
/* enableDecoderFallback= */ false,
|
||||||
/* assumedMinimumCodecOperatingRate= */ 44100);
|
/* assumedMinimumCodecOperatingRate= */ 44100);
|
||||||
this.context = context.getApplicationContext();
|
this.context = context.getApplicationContext();
|
||||||
this.audioSink = audioSink;
|
this.audioSink = audioSink;
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -289,6 +290,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
private final MediaCodecSelector mediaCodecSelector;
|
private final MediaCodecSelector mediaCodecSelector;
|
||||||
@Nullable private final DrmSessionManager<FrameworkMediaCrypto> drmSessionManager;
|
@Nullable private final DrmSessionManager<FrameworkMediaCrypto> drmSessionManager;
|
||||||
private final boolean playClearSamplesWithoutKeys;
|
private final boolean playClearSamplesWithoutKeys;
|
||||||
|
private final boolean enableDecoderFallback;
|
||||||
private final float assumedMinimumCodecOperatingRate;
|
private final float assumedMinimumCodecOperatingRate;
|
||||||
private final DecoderInputBuffer buffer;
|
private final DecoderInputBuffer buffer;
|
||||||
private final DecoderInputBuffer flagsOnlyBuffer;
|
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
|
* 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}
|
* permitted to play clear regions of encrypted media files before {@code drmSessionManager}
|
||||||
* has obtained the keys necessary to decrypt encrypted regions of the media.
|
* 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
|
* @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
|
* this renderer are assumed to meet implicitly (i.e. without the operating rate being set
|
||||||
* explicitly using {@link MediaFormat#KEY_OPERATING_RATE}).
|
* explicitly using {@link MediaFormat#KEY_OPERATING_RATE}).
|
||||||
|
|
@ -363,11 +368,13 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
MediaCodecSelector mediaCodecSelector,
|
MediaCodecSelector mediaCodecSelector,
|
||||||
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
|
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
|
||||||
boolean playClearSamplesWithoutKeys,
|
boolean playClearSamplesWithoutKeys,
|
||||||
|
boolean enableDecoderFallback,
|
||||||
float assumedMinimumCodecOperatingRate) {
|
float assumedMinimumCodecOperatingRate) {
|
||||||
super(trackType);
|
super(trackType);
|
||||||
this.mediaCodecSelector = Assertions.checkNotNull(mediaCodecSelector);
|
this.mediaCodecSelector = Assertions.checkNotNull(mediaCodecSelector);
|
||||||
this.drmSessionManager = drmSessionManager;
|
this.drmSessionManager = drmSessionManager;
|
||||||
this.playClearSamplesWithoutKeys = playClearSamplesWithoutKeys;
|
this.playClearSamplesWithoutKeys = playClearSamplesWithoutKeys;
|
||||||
|
this.enableDecoderFallback = enableDecoderFallback;
|
||||||
this.assumedMinimumCodecOperatingRate = assumedMinimumCodecOperatingRate;
|
this.assumedMinimumCodecOperatingRate = assumedMinimumCodecOperatingRate;
|
||||||
buffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DISABLED);
|
buffer = new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DISABLED);
|
||||||
flagsOnlyBuffer = DecoderInputBuffer.newFlagsOnlyInstance();
|
flagsOnlyBuffer = DecoderInputBuffer.newFlagsOnlyInstance();
|
||||||
|
|
@ -735,8 +742,14 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
||||||
throws DecoderInitializationException {
|
throws DecoderInitializationException {
|
||||||
if (availableCodecInfos == null) {
|
if (availableCodecInfos == null) {
|
||||||
try {
|
try {
|
||||||
availableCodecInfos =
|
List<MediaCodecInfo> allAvailableCodecInfos =
|
||||||
new ArrayDeque<>(getAvailableCodecInfos(mediaCryptoRequiresSecureDecoder));
|
getAvailableCodecInfos(mediaCryptoRequiresSecureDecoder);
|
||||||
|
if (enableDecoderFallback) {
|
||||||
|
availableCodecInfos = new ArrayDeque<>(allAvailableCodecInfos);
|
||||||
|
} else {
|
||||||
|
availableCodecInfos =
|
||||||
|
new ArrayDeque<>(Collections.singletonList(allAvailableCodecInfos.get(0)));
|
||||||
|
}
|
||||||
preferredDecoderInitializationException = null;
|
preferredDecoderInitializationException = null;
|
||||||
} catch (DecoderQueryException e) {
|
} catch (DecoderQueryException e) {
|
||||||
throw new DecoderInitializationException(
|
throw new DecoderInitializationException(
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ package com.google.android.exoplayer2.mediacodec;
|
||||||
import android.media.MediaCodec;
|
import android.media.MediaCodec;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException;
|
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -31,32 +30,6 @@ public interface MediaCodecSelector {
|
||||||
* the given format.
|
* the given format.
|
||||||
*/
|
*/
|
||||||
MediaCodecSelector DEFAULT =
|
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() {
|
new MediaCodecSelector() {
|
||||||
@Override
|
@Override
|
||||||
public List<MediaCodecInfo> getDecoderInfos(String mimeType, boolean requiresSecureDecoder)
|
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
|
* @param maxDroppedFramesToNotify The maximum number of frames that can be dropped between
|
||||||
* invocations of {@link VideoRendererEventListener#onDroppedFrames(int, long)}.
|
* invocations of {@link VideoRendererEventListener#onDroppedFrames(int, long)}.
|
||||||
*/
|
*/
|
||||||
public MediaCodecVideoRenderer(Context context, MediaCodecSelector mediaCodecSelector,
|
public MediaCodecVideoRenderer(
|
||||||
|
Context context,
|
||||||
|
MediaCodecSelector mediaCodecSelector,
|
||||||
long allowedJoiningTimeMs,
|
long allowedJoiningTimeMs,
|
||||||
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
|
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
|
||||||
boolean playClearSamplesWithoutKeys, @Nullable Handler eventHandler,
|
boolean playClearSamplesWithoutKeys,
|
||||||
@Nullable VideoRendererEventListener eventListener, int maxDroppedFramesToNotify) {
|
@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(
|
super(
|
||||||
C.TRACK_TYPE_VIDEO,
|
C.TRACK_TYPE_VIDEO,
|
||||||
mediaCodecSelector,
|
mediaCodecSelector,
|
||||||
drmSessionManager,
|
drmSessionManager,
|
||||||
playClearSamplesWithoutKeys,
|
playClearSamplesWithoutKeys,
|
||||||
|
enableDecoderFallback,
|
||||||
/* assumedMinimumCodecOperatingRate= */ 30);
|
/* assumedMinimumCodecOperatingRate= */ 30);
|
||||||
this.allowedJoiningTimeMs = allowedJoiningTimeMs;
|
this.allowedJoiningTimeMs = allowedJoiningTimeMs;
|
||||||
this.maxDroppedFramesToNotify = maxDroppedFramesToNotify;
|
this.maxDroppedFramesToNotify = maxDroppedFramesToNotify;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue