Expose the codec name to the analysis files.
PiperOrigin-RevId: 447724152
This commit is contained in:
parent
4c838043d3
commit
f8f1a4d1ed
@ -21,17 +21,20 @@ import static java.util.concurrent.TimeUnit.SECONDS;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.media3.common.Format;
|
||||||
import androidx.media3.common.MediaItem;
|
import androidx.media3.common.MediaItem;
|
||||||
import androidx.media3.common.util.Log;
|
import androidx.media3.common.util.Log;
|
||||||
import androidx.media3.common.util.SystemClock;
|
import androidx.media3.common.util.SystemClock;
|
||||||
import androidx.test.platform.app.InstrumentationRegistry;
|
import androidx.test.platform.app.InstrumentationRegistry;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
import org.checkerframework.checker.nullness.compatqual.NullableType;
|
||||||
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
/** An android instrumentation test runner for {@link Transformer}. */
|
/** An android instrumentation test runner for {@link Transformer}. */
|
||||||
@ -140,6 +143,7 @@ public class TransformerAndroidTestRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
private final CodecNameForwardingEncoderFactory transformerEncoderFactory;
|
||||||
private final Transformer transformer;
|
private final Transformer transformer;
|
||||||
private final int timeoutSeconds;
|
private final int timeoutSeconds;
|
||||||
private final boolean calculateSsim;
|
private final boolean calculateSsim;
|
||||||
@ -154,7 +158,9 @@ public class TransformerAndroidTestRunner {
|
|||||||
boolean suppressAnalysisExceptions,
|
boolean suppressAnalysisExceptions,
|
||||||
@Nullable Map<String, Object> inputValues) {
|
@Nullable Map<String, Object> inputValues) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.transformer = transformer;
|
this.transformerEncoderFactory =
|
||||||
|
new CodecNameForwardingEncoderFactory(transformer.encoderFactory);
|
||||||
|
this.transformer = transformer.buildUpon().setEncoderFactory(transformerEncoderFactory).build();
|
||||||
this.timeoutSeconds = timeoutSeconds;
|
this.timeoutSeconds = timeoutSeconds;
|
||||||
this.calculateSsim = calculateSsim;
|
this.calculateSsim = calculateSsim;
|
||||||
this.suppressAnalysisExceptions = suppressAnalysisExceptions;
|
this.suppressAnalysisExceptions = suppressAnalysisExceptions;
|
||||||
@ -186,6 +192,7 @@ public class TransformerAndroidTestRunner {
|
|||||||
resultJson.put("exception", AndroidTestUtil.exceptionAsJsonObject(e));
|
resultJson.put("exception", AndroidTestUtil.exceptionAsJsonObject(e));
|
||||||
throw e;
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
|
resultJson.put("codecDetails", transformerEncoderFactory.getCodecNamesAsJsonObject());
|
||||||
AndroidTestUtil.writeTestSummaryToFile(context, testId, resultJson);
|
AndroidTestUtil.writeTestSummaryToFile(context, testId, resultJson);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -307,4 +314,57 @@ public class TransformerAndroidTestRunner {
|
|||||||
}
|
}
|
||||||
return resultBuilder.build();
|
return resultBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link Codec.EncoderFactory} that forwards all methods to another encoder factory, whilst
|
||||||
|
* providing visibility into the names of last codecs created by it.
|
||||||
|
*/
|
||||||
|
private static class CodecNameForwardingEncoderFactory implements Codec.EncoderFactory {
|
||||||
|
|
||||||
|
@Nullable public String audioEncoderName;
|
||||||
|
@Nullable public String videoEncoderName;
|
||||||
|
|
||||||
|
private final Codec.EncoderFactory encoderFactory;
|
||||||
|
|
||||||
|
public CodecNameForwardingEncoderFactory(Codec.EncoderFactory encoderFactory) {
|
||||||
|
this.encoderFactory = encoderFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Codec createForAudioEncoding(Format format, List<String> allowedMimeTypes)
|
||||||
|
throws TransformationException {
|
||||||
|
Codec audioEncoder = encoderFactory.createForAudioEncoding(format, allowedMimeTypes);
|
||||||
|
audioEncoderName = audioEncoder.getName();
|
||||||
|
return audioEncoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Codec createForVideoEncoding(Format format, List<String> allowedMimeTypes)
|
||||||
|
throws TransformationException {
|
||||||
|
Codec videoEncoder = encoderFactory.createForVideoEncoding(format, allowedMimeTypes);
|
||||||
|
videoEncoderName = videoEncoder.getName();
|
||||||
|
return videoEncoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean audioNeedsEncoding() {
|
||||||
|
return encoderFactory.audioNeedsEncoding();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean videoNeedsEncoding() {
|
||||||
|
return encoderFactory.videoNeedsEncoding();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject getCodecNamesAsJsonObject() throws JSONException {
|
||||||
|
JSONObject detailsJson = new JSONObject();
|
||||||
|
if (audioEncoderName != null) {
|
||||||
|
detailsJson.put("audioEncoderName", audioEncoderName);
|
||||||
|
}
|
||||||
|
if (videoEncoderName != null) {
|
||||||
|
detailsJson.put("videoEncoderName", videoEncoderName);
|
||||||
|
}
|
||||||
|
return detailsJson;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,6 +133,9 @@ public interface Codec {
|
|||||||
*/
|
*/
|
||||||
Format getConfigurationFormat();
|
Format getConfigurationFormat();
|
||||||
|
|
||||||
|
/** Returns the name of the underlying codec. */
|
||||||
|
String getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the input {@link Surface} of an underlying video encoder.
|
* Returns the input {@link Surface} of an underlying video encoder.
|
||||||
*
|
*
|
||||||
|
@ -19,6 +19,7 @@ package androidx.media3.transformer;
|
|||||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||||
import static androidx.media3.common.util.Assertions.checkState;
|
import static androidx.media3.common.util.Assertions.checkState;
|
||||||
import static androidx.media3.common.util.Assertions.checkStateNotNull;
|
import static androidx.media3.common.util.Assertions.checkStateNotNull;
|
||||||
|
import static androidx.media3.common.util.Util.SDK_INT;
|
||||||
|
|
||||||
import android.media.MediaCodec;
|
import android.media.MediaCodec;
|
||||||
import android.media.MediaCodec.BufferInfo;
|
import android.media.MediaCodec.BufferInfo;
|
||||||
@ -30,7 +31,6 @@ import androidx.media3.common.Format;
|
|||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.util.TraceUtil;
|
import androidx.media3.common.util.TraceUtil;
|
||||||
import androidx.media3.common.util.UnstableApi;
|
import androidx.media3.common.util.UnstableApi;
|
||||||
import androidx.media3.common.util.Util;
|
|
||||||
import androidx.media3.decoder.DecoderInputBuffer;
|
import androidx.media3.decoder.DecoderInputBuffer;
|
||||||
import com.google.common.base.Ascii;
|
import com.google.common.base.Ascii;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
@ -124,7 +124,7 @@ public final class DefaultCodec implements Codec {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxPendingFrameCount() {
|
public int getMaxPendingFrameCount() {
|
||||||
if (Util.SDK_INT < 29) {
|
if (SDK_INT < 29) {
|
||||||
// Prior to API 29, decoders may drop frames to keep their output surface from growing out of
|
// Prior to API 29, decoders may drop frames to keep their output surface from growing out of
|
||||||
// bounds. From API 29, the {@link MediaFormat#KEY_ALLOW_FRAME_DROP} key prevents frame
|
// bounds. From API 29, the {@link MediaFormat#KEY_ALLOW_FRAME_DROP} key prevents frame
|
||||||
// dropping even when the surface is full. Frame dropping is never desired, so allow a maximum
|
// dropping even when the surface is full. Frame dropping is never desired, so allow a maximum
|
||||||
@ -257,6 +257,23 @@ public final class DefaultCodec implements Codec {
|
|||||||
mediaCodec.release();
|
mediaCodec.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* <p>This name is of the actual codec, which may not be the same as the {@code mediaCodecName}
|
||||||
|
* passed to {@link #DefaultCodec(Format, MediaFormat, String, boolean, Surface)}.
|
||||||
|
*
|
||||||
|
* @see MediaCodec#getCanonicalName()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
if (SDK_INT >= 29) {
|
||||||
|
return mediaCodec.getCanonicalName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return mediaCodec.getName();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to dequeue an output buffer if there is no output buffer pending. Does nothing
|
* Attempts to dequeue an output buffer if there is no output buffer pending. Does nothing
|
||||||
* otherwise.
|
* otherwise.
|
||||||
|
@ -557,10 +557,10 @@ public final class Transformer {
|
|||||||
private final ImmutableList<GlEffect> videoFrameEffects;
|
private final ImmutableList<GlEffect> videoFrameEffects;
|
||||||
private final Looper looper;
|
private final Looper looper;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final Codec.EncoderFactory encoderFactory;
|
|
||||||
private final Codec.DecoderFactory decoderFactory;
|
|
||||||
private final Transformer.DebugViewProvider debugViewProvider;
|
private final Transformer.DebugViewProvider debugViewProvider;
|
||||||
private final ListenerSet<Transformer.Listener> listeners;
|
private final ListenerSet<Transformer.Listener> listeners;
|
||||||
|
private final Codec.DecoderFactory decoderFactory;
|
||||||
|
@VisibleForTesting /* package */ final Codec.EncoderFactory encoderFactory;
|
||||||
|
|
||||||
@Nullable private MuxerWrapper muxerWrapper;
|
@Nullable private MuxerWrapper muxerWrapper;
|
||||||
@Nullable private ExoPlayer player;
|
@Nullable private ExoPlayer player;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user