Allow enabling decoder fallback in DefaultRenderersFactory

Also allow enabling decoder fallback with MediaCodecAudioRenderer.

Issue: #5942
PiperOrigin-RevId: 250301422
This commit is contained in:
andrewlewis 2019-05-28 17:40:50 +01:00 committed by Oliver Woodman
parent 5d72942a49
commit 8bc14bc2a9
4 changed files with 70 additions and 3 deletions

View File

@ -14,6 +14,8 @@
* Prevent unexpected `DownloadHelper.Callback.onPrepared` callbacks after the * Prevent unexpected `DownloadHelper.Callback.onPrepared` callbacks after the
preparation of the `DownloadHelper` failed preparation of the `DownloadHelper` failed
([#5915](https://github.com/google/ExoPlayer/issues/5915)). ([#5915](https://github.com/google/ExoPlayer/issues/5915)).
* Allow enabling decoder fallback with `DefaultRenderersFactory`
([#5942](https://github.com/google/ExoPlayer/issues/5942)).
### 2.10.1 ### ### 2.10.1 ###

View File

@ -24,6 +24,7 @@ import androidx.annotation.Nullable;
import com.google.android.exoplayer2.audio.AudioCapabilities; import com.google.android.exoplayer2.audio.AudioCapabilities;
import com.google.android.exoplayer2.audio.AudioProcessor; import com.google.android.exoplayer2.audio.AudioProcessor;
import com.google.android.exoplayer2.audio.AudioRendererEventListener; import com.google.android.exoplayer2.audio.AudioRendererEventListener;
import com.google.android.exoplayer2.audio.DefaultAudioSink;
import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer; import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer;
import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.FrameworkMediaCrypto; import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
@ -90,6 +91,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
@ExtensionRendererMode private int extensionRendererMode; @ExtensionRendererMode private int extensionRendererMode;
private long allowedVideoJoiningTimeMs; private long allowedVideoJoiningTimeMs;
private boolean playClearSamplesWithoutKeys; private boolean playClearSamplesWithoutKeys;
private boolean enableDecoderFallback;
private MediaCodecSelector mediaCodecSelector; private MediaCodecSelector mediaCodecSelector;
/** @param context A {@link Context}. */ /** @param context A {@link Context}. */
@ -202,6 +204,19 @@ public class DefaultRenderersFactory implements RenderersFactory {
return this; return this;
} }
/**
* Sets 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 enableDecoderFallback Whether to enable fallback to lower-priority decoders if decoder
* initialization fails.
* @return This factory, for convenience.
*/
public DefaultRenderersFactory setEnableDecoderFallback(boolean enableDecoderFallback) {
this.enableDecoderFallback = enableDecoderFallback;
return this;
}
/** /**
* Sets a {@link MediaCodecSelector} for use by {@link MediaCodec} based renderers. * Sets a {@link MediaCodecSelector} for use by {@link MediaCodec} based renderers.
* *
@ -248,6 +263,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
mediaCodecSelector, mediaCodecSelector,
drmSessionManager, drmSessionManager,
playClearSamplesWithoutKeys, playClearSamplesWithoutKeys,
enableDecoderFallback,
eventHandler, eventHandler,
videoRendererEventListener, videoRendererEventListener,
allowedVideoJoiningTimeMs, allowedVideoJoiningTimeMs,
@ -258,6 +274,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
mediaCodecSelector, mediaCodecSelector,
drmSessionManager, drmSessionManager,
playClearSamplesWithoutKeys, playClearSamplesWithoutKeys,
enableDecoderFallback,
buildAudioProcessors(), buildAudioProcessors(),
eventHandler, eventHandler,
audioRendererEventListener, audioRendererEventListener,
@ -282,6 +299,9 @@ public class DefaultRenderersFactory implements RenderersFactory {
* @param playClearSamplesWithoutKeys Whether renderers are permitted to play clear regions of * @param playClearSamplesWithoutKeys Whether renderers are permitted to play clear regions of
* encrypted media prior to having obtained the keys necessary to decrypt encrypted regions of * encrypted media prior to having obtained the keys necessary to decrypt encrypted regions of
* the media. * 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 associated with the main thread's looper. * @param eventHandler A handler associated with the main thread's looper.
* @param eventListener An event listener. * @param eventListener An event listener.
* @param allowedVideoJoiningTimeMs The maximum duration for which video renderers can attempt to * @param allowedVideoJoiningTimeMs The maximum duration for which video renderers can attempt to
@ -294,6 +314,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
MediaCodecSelector mediaCodecSelector, MediaCodecSelector mediaCodecSelector,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager, @Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
boolean playClearSamplesWithoutKeys, boolean playClearSamplesWithoutKeys,
boolean enableDecoderFallback,
Handler eventHandler, Handler eventHandler,
VideoRendererEventListener eventListener, VideoRendererEventListener eventListener,
long allowedVideoJoiningTimeMs, long allowedVideoJoiningTimeMs,
@ -305,6 +326,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
allowedVideoJoiningTimeMs, allowedVideoJoiningTimeMs,
drmSessionManager, drmSessionManager,
playClearSamplesWithoutKeys, playClearSamplesWithoutKeys,
enableDecoderFallback,
eventHandler, eventHandler,
eventListener, eventListener,
MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY)); MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY));
@ -356,6 +378,9 @@ public class DefaultRenderersFactory implements RenderersFactory {
* @param playClearSamplesWithoutKeys Whether renderers are permitted to play clear regions of * @param playClearSamplesWithoutKeys Whether renderers are permitted to play clear regions of
* encrypted media prior to having obtained the keys necessary to decrypt encrypted regions of * encrypted media prior to having obtained the keys necessary to decrypt encrypted regions of
* the media. * 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 audioProcessors An array of {@link AudioProcessor}s that will process PCM audio buffers * @param audioProcessors An array of {@link AudioProcessor}s that will process PCM audio buffers
* before output. May be empty. * before output. May be empty.
* @param eventHandler A handler to use when invoking event listeners and outputs. * @param eventHandler A handler to use when invoking event listeners and outputs.
@ -368,6 +393,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
MediaCodecSelector mediaCodecSelector, MediaCodecSelector mediaCodecSelector,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager, @Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
boolean playClearSamplesWithoutKeys, boolean playClearSamplesWithoutKeys,
boolean enableDecoderFallback,
AudioProcessor[] audioProcessors, AudioProcessor[] audioProcessors,
Handler eventHandler, Handler eventHandler,
AudioRendererEventListener eventListener, AudioRendererEventListener eventListener,
@ -378,10 +404,10 @@ public class DefaultRenderersFactory implements RenderersFactory {
mediaCodecSelector, mediaCodecSelector,
drmSessionManager, drmSessionManager,
playClearSamplesWithoutKeys, playClearSamplesWithoutKeys,
enableDecoderFallback,
eventHandler, eventHandler,
eventListener, eventListener,
AudioCapabilities.getCapabilities(context), new DefaultAudioSink(AudioCapabilities.getCapabilities(context), audioProcessors)));
audioProcessors));
if (extensionRendererMode == EXTENSION_RENDERER_MODE_OFF) { if (extensionRendererMode == EXTENSION_RENDERER_MODE_OFF) {
return; return;

View File

@ -245,12 +245,50 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
@Nullable Handler eventHandler, @Nullable Handler eventHandler,
@Nullable AudioRendererEventListener eventListener, @Nullable AudioRendererEventListener eventListener,
AudioSink audioSink) { AudioSink audioSink) {
this(
context,
mediaCodecSelector,
drmSessionManager,
playClearSamplesWithoutKeys,
/* enableDecoderFallback= */ false,
eventHandler,
eventListener,
audioSink);
}
/**
* @param context A context.
* @param mediaCodecSelector A decoder selector.
* @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 audioSink The sink to which audio will be output.
*/
public MediaCodecAudioRenderer(
Context context,
MediaCodecSelector mediaCodecSelector,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
boolean playClearSamplesWithoutKeys,
boolean enableDecoderFallback,
@Nullable Handler eventHandler,
@Nullable AudioRendererEventListener eventListener,
AudioSink audioSink) {
super( super(
C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_AUDIO,
mediaCodecSelector, mediaCodecSelector,
drmSessionManager, drmSessionManager,
playClearSamplesWithoutKeys, playClearSamplesWithoutKeys,
/* enableDecoderFallback= */ false, enableDecoderFallback,
/* assumedMinimumCodecOperatingRate= */ 44100); /* assumedMinimumCodecOperatingRate= */ 44100);
this.context = context.getApplicationContext(); this.context = context.getApplicationContext();
this.audioSink = audioSink; this.audioSink = audioSink;

View File

@ -55,6 +55,7 @@ public class DebugRenderersFactory extends DefaultRenderersFactory {
MediaCodecSelector mediaCodecSelector, MediaCodecSelector mediaCodecSelector,
@Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager, @Nullable DrmSessionManager<FrameworkMediaCrypto> drmSessionManager,
boolean playClearSamplesWithoutKeys, boolean playClearSamplesWithoutKeys,
boolean enableDecoderFallback,
Handler eventHandler, Handler eventHandler,
VideoRendererEventListener eventListener, VideoRendererEventListener eventListener,
long allowedVideoJoiningTimeMs, long allowedVideoJoiningTimeMs,