Skip to content

Commit

Permalink
Add device-specific opt-ins for async MediaCodecAdapter
Browse files Browse the repository at this point in the history
Some devices just don't work very well with the synchronous
model, but are currently still excluded from our approximate
API 31 check. This change allows to include additional devices
or device groups by passing in the Context to the default
adapter.

It also adopts the workaround added in amzn/exoplayer-amazon-port@ebceee0
for Fire TV Smart devices that exhibit this issue.

PiperOrigin-RevId: 614642545
(cherry picked from commit e4a5584)
  • Loading branch information
tonihei authored and l1068 committed Apr 15, 2024
1 parent b7b47e0 commit 8a66055
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public class DefaultRenderersFactory implements RenderersFactory {
*/
public DefaultRenderersFactory(Context context) {
this.context = context;
codecAdapterFactory = new DefaultMediaCodecAdapterFactory();
codecAdapterFactory = new DefaultMediaCodecAdapterFactory(context);
extensionRendererMode = EXTENSION_RENDERER_MODE_OFF;
allowedVideoJoiningTimeMs = DEFAULT_ALLOWED_VIDEO_JOINING_TIME_MS;
mediaCodecSelector = MediaCodecSelector.DEFAULT;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ public MediaCodecAudioRenderer(
AudioSink audioSink) {
this(
context,
MediaCodecAdapter.Factory.DEFAULT,
MediaCodecAdapter.Factory.getDefault(context),
mediaCodecSelector,
/* enableDecoderFallback= */ false,
eventHandler,
Expand Down Expand Up @@ -219,7 +219,7 @@ public MediaCodecAudioRenderer(
AudioSink audioSink) {
this(
context,
MediaCodecAdapter.Factory.DEFAULT,
MediaCodecAdapter.Factory.getDefault(context),
mediaCodecSelector,
enableDecoderFallback,
eventHandler,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@

import static java.lang.annotation.ElementType.TYPE_USE;

import android.content.Context;
import android.media.MediaCodec;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.Log;
import androidx.media3.common.util.UnstableApi;
Expand Down Expand Up @@ -54,12 +56,30 @@ public final class DefaultMediaCodecAdapterFactory implements MediaCodecAdapter.

private static final String TAG = "DMCodecAdapterFactory";

@Nullable private final Context context;

private @Mode int asynchronousMode;
private boolean asyncCryptoFlagEnabled;

/**
* @deprecated Use {@link #DefaultMediaCodecAdapterFactory(Context)} instead.
*/
@Deprecated
public DefaultMediaCodecAdapterFactory() {
asynchronousMode = MODE_DEFAULT;
asyncCryptoFlagEnabled = true;
context = null;
}

/**
* Creates the default media codec adapter factory.
*
* @param context A {@link Context}.
*/
public DefaultMediaCodecAdapterFactory(Context context) {
this.context = context;
asynchronousMode = MODE_DEFAULT;
asyncCryptoFlagEnabled = true;
}

/**
Expand Down Expand Up @@ -105,7 +125,7 @@ public MediaCodecAdapter createAdapter(MediaCodecAdapter.Configuration configura
throws IOException {
if (Util.SDK_INT >= 23
&& (asynchronousMode == MODE_ENABLED
|| (asynchronousMode == MODE_DEFAULT && Util.SDK_INT >= 31))) {
|| (asynchronousMode == MODE_DEFAULT && shouldUseAsynchronousAdapterInDefaultMode()))) {
int trackType = MimeTypes.getTrackType(configuration.format.sampleMimeType);
Log.i(
TAG,
Expand All @@ -118,4 +138,19 @@ public MediaCodecAdapter createAdapter(MediaCodecAdapter.Configuration configura
}
return new SynchronousMediaCodecAdapter.Factory().createAdapter(configuration);
}

private boolean shouldUseAsynchronousAdapterInDefaultMode() {
if (Util.SDK_INT >= 31) {
// Asynchronous codec interactions started to be reliable for all devices on API 31+.
return true;
}
// Allow additional devices that work reliably with the asynchronous adapter and show
// performance problems when not using it.
if (context != null
&& Util.SDK_INT >= 28
&& context.getPackageManager().hasSystemFeature("com.amazon.hardware.tv_screen")) {
return true;
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package androidx.media3.exoplayer.mediacodec;

import android.content.Context;
import android.media.MediaCodec;
import android.media.MediaCrypto;
import android.media.MediaFormat;
Expand Down Expand Up @@ -120,9 +121,23 @@ private Configuration(
/** A factory for {@link MediaCodecAdapter} instances. */
interface Factory {

/** Default factory used in most cases. */
/**
* @deprecated Use {@link #getDefault} instead.
*/
@Deprecated
@SuppressWarnings("deprecation") // Forwarding to deprecated method.
Factory DEFAULT = new DefaultMediaCodecAdapterFactory();

/**
* Returns the default factory that should be used in most cases.
*
* @param context A {@link Context}.
* @return The default factory.
*/
static Factory getDefault(Context context) {
return new DefaultMediaCodecAdapterFactory(context);
}

/** Creates a {@link MediaCodecAdapter} instance. */
MediaCodecAdapter createAdapter(Configuration configuration) throws IOException;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ public MediaCodecVideoRenderer(
int maxDroppedFramesToNotify) {
this(
context,
MediaCodecAdapter.Factory.DEFAULT,
MediaCodecAdapter.Factory.getDefault(context),
mediaCodecSelector,
allowedJoiningTimeMs,
/* enableDecoderFallback= */ false,
Expand Down Expand Up @@ -255,7 +255,7 @@ public MediaCodecVideoRenderer(
int maxDroppedFramesToNotify) {
this(
context,
MediaCodecAdapter.Factory.DEFAULT,
MediaCodecAdapter.Factory.getDefault(context),
mediaCodecSelector,
allowedJoiningTimeMs,
enableDecoderFallback,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.upstream.DefaultAllocator;
import androidx.media3.test.utils.FakeSampleStream;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
import java.nio.ByteBuffer;
Expand Down Expand Up @@ -480,7 +481,7 @@ private static class TestRenderer extends MediaCodecRenderer {
public TestRenderer() {
super(
C.TRACK_TYPE_AUDIO,
MediaCodecAdapter.Factory.DEFAULT,
MediaCodecAdapter.Factory.getDefault(ApplicationProvider.getApplicationContext()),
/* mediaCodecSelector= */ (mimeType, requiresSecureDecoder, requiresTunnelingDecoder) ->
Collections.singletonList(
MediaCodecInfo.newInstance(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public class CapturingRenderersFactory implements RenderersFactory, Dumper.Dumpa
*/
public CapturingRenderersFactory(Context context) {
this.context = context;
this.mediaCodecAdapterFactory = new CapturingMediaCodecAdapter.Factory();
this.mediaCodecAdapterFactory = new CapturingMediaCodecAdapter.Factory(context);
this.audioSink = new CapturingAudioSink(new DefaultAudioSink.Builder(context).build());
this.imageOutput = new CapturingImageOutput();
this.imageDecoderFactory = ImageDecoder.Factory.DEFAULT;
Expand Down Expand Up @@ -168,9 +168,11 @@ private static class CapturingMediaCodecAdapter implements MediaCodecAdapter, Du

private static class Factory implements MediaCodecAdapter.Factory, Dumper.Dumpable {

private final Context context;
private final List<CapturingMediaCodecAdapter> constructedAdapters;

private Factory() {
private Factory(Context context) {
this.context = context;
constructedAdapters = new ArrayList<>();
}

Expand All @@ -179,7 +181,7 @@ private Factory() {
public MediaCodecAdapter createAdapter(Configuration configuration) throws IOException {
CapturingMediaCodecAdapter adapter =
new CapturingMediaCodecAdapter(
MediaCodecAdapter.Factory.DEFAULT.createAdapter(configuration),
MediaCodecAdapter.Factory.getDefault(context).createAdapter(configuration),
configuration.codecInfo.name);
constructedAdapters.add(adapter);
return adapter;
Expand Down

0 comments on commit 8a66055

Please sign in to comment.