mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Set LogSessionId on Transformer decoders and encoders
PiperOrigin-RevId: 737636636
This commit is contained in:
parent
4932300b9a
commit
40ab0d40a1
@ -74,7 +74,10 @@ public final class TestTransformerBuilder {
|
||||
maxDelayBetweenMuxerSamplesMs = Transformer.DEFAULT_MAX_DELAY_BETWEEN_MUXER_SAMPLES_MS;
|
||||
assetLoaderFactory =
|
||||
new DefaultAssetLoaderFactory(
|
||||
context, new DefaultDecoderFactory.Builder(context).build(), clock);
|
||||
context,
|
||||
new DefaultDecoderFactory.Builder(context).build(),
|
||||
clock,
|
||||
/* logSessionId= */ null);
|
||||
muxerFactory = new DefaultMuxer.Factory();
|
||||
looper = Util.getCurrentOrMainLooper();
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ import android.graphics.Bitmap.Config;
|
||||
import android.media.Image;
|
||||
import android.media.MediaCodec;
|
||||
import android.media.MediaCodecInfo;
|
||||
import android.media.metrics.LogSessionId;
|
||||
import android.opengl.EGLContext;
|
||||
import android.opengl.EGLDisplay;
|
||||
import android.os.Build;
|
||||
@ -1225,13 +1226,15 @@ public final class AndroidTestUtil {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec createForAudioEncoding(Format format) throws ExportException {
|
||||
return encoderFactory.createForAudioEncoding(format);
|
||||
public Codec createForAudioEncoding(Format format, @Nullable LogSessionId logSessionId)
|
||||
throws ExportException {
|
||||
return encoderFactory.createForAudioEncoding(format, logSessionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec createForVideoEncoding(Format format) throws ExportException {
|
||||
return encoderFactory.createForVideoEncoding(format);
|
||||
public Codec createForVideoEncoding(Format format, @Nullable LogSessionId logSessionId)
|
||||
throws ExportException {
|
||||
return encoderFactory.createForVideoEncoding(format, logSessionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -26,6 +26,7 @@ import static org.junit.Assume.assumeTrue;
|
||||
import android.content.Context;
|
||||
import android.media.MediaCodec;
|
||||
import android.media.MediaFormat;
|
||||
import android.media.metrics.LogSessionId;
|
||||
import android.view.Surface;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.C;
|
||||
@ -166,7 +167,8 @@ public class ForceEndOfStreamTest {
|
||||
new DefaultAssetLoaderFactory(
|
||||
context,
|
||||
new FrameDroppingDecoderFactory(context, MP4_ASSET.videoFrameCount, framesToSkip),
|
||||
Clock.DEFAULT))
|
||||
Clock.DEFAULT,
|
||||
/* logSessionId= */ null))
|
||||
.build();
|
||||
}
|
||||
|
||||
@ -192,17 +194,21 @@ public class ForceEndOfStreamTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec createForAudioDecoding(Format format) throws ExportException {
|
||||
return defaultDecoderFactory.createForAudioDecoding(format);
|
||||
public Codec createForAudioDecoding(Format format, @Nullable LogSessionId logSessionId)
|
||||
throws ExportException {
|
||||
return defaultDecoderFactory.createForAudioDecoding(format, logSessionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec createForVideoDecoding(
|
||||
Format format, Surface outputSurface, boolean requestSdrToneMapping)
|
||||
Format format,
|
||||
Surface outputSurface,
|
||||
boolean requestSdrToneMapping,
|
||||
@Nullable LogSessionId logSessionId)
|
||||
throws ExportException {
|
||||
return new FrameDroppingDecoder(
|
||||
defaultDecoderFactory.createForVideoDecoding(
|
||||
format, outputSurface, requestSdrToneMapping),
|
||||
format, outputSurface, requestSdrToneMapping, logSessionId),
|
||||
sourceFrameCount,
|
||||
framesToDrop);
|
||||
}
|
||||
|
@ -224,7 +224,8 @@ public final class SequenceEffectTestUtil {
|
||||
ImmutableList.of(decoderMediaCodecInfo))
|
||||
.build();
|
||||
AssetLoader.Factory assetLoaderFactory =
|
||||
new DefaultAssetLoaderFactory(context, decoderFactory, Clock.DEFAULT);
|
||||
new DefaultAssetLoaderFactory(
|
||||
context, decoderFactory, Clock.DEFAULT, /* logSessionId= */ null);
|
||||
Codec.EncoderFactory encoderFactory =
|
||||
new DefaultEncoderFactory.Builder(context)
|
||||
.setRequestedVideoEncoderSettings(
|
||||
|
@ -64,6 +64,7 @@ import static org.junit.Assume.assumeTrue;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.media.MediaFormat;
|
||||
import android.media.metrics.LogSessionId;
|
||||
import android.net.Uri;
|
||||
import android.opengl.EGLContext;
|
||||
import android.os.Handler;
|
||||
@ -71,6 +72,7 @@ import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.util.Pair;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.Effect;
|
||||
import androidx.media3.common.Format;
|
||||
@ -2616,12 +2618,14 @@ public class TransformerEndToEndTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec createForAudioEncoding(Format format) throws ExportException {
|
||||
return encoderFactory.createForAudioEncoding(format);
|
||||
public Codec createForAudioEncoding(Format format, @Nullable LogSessionId logSessionId)
|
||||
throws ExportException {
|
||||
return encoderFactory.createForAudioEncoding(format, logSessionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec createForVideoEncoding(Format format) throws ExportException {
|
||||
public Codec createForVideoEncoding(Format format, @Nullable LogSessionId logSessionId)
|
||||
throws ExportException {
|
||||
throw ExportException.createForCodec(
|
||||
new IllegalArgumentException(),
|
||||
ExportException.ERROR_CODE_ENCODER_INIT_FAILED,
|
||||
|
@ -152,7 +152,8 @@ public class TranscodeForegroundSpeedTest {
|
||||
.setShouldConfigureOperatingRate(true)
|
||||
.build();
|
||||
AssetLoader.Factory assetLoaderFactory =
|
||||
new DefaultAssetLoaderFactory(context, decoderFactory, Clock.DEFAULT);
|
||||
new DefaultAssetLoaderFactory(
|
||||
context, decoderFactory, Clock.DEFAULT, /* logSessionId= */ null);
|
||||
Transformer transformer =
|
||||
new Transformer.Builder(context)
|
||||
.setVideoMimeType(MimeTypes.VIDEO_H264)
|
||||
|
@ -229,7 +229,8 @@ public class TranscodeSpeedTest {
|
||||
Codec.DecoderFactory decoderFactory =
|
||||
new DefaultDecoderFactory.Builder(context).setShouldConfigureOperatingRate(true).build();
|
||||
AssetLoader.Factory assetLoaderFactory =
|
||||
new DefaultAssetLoaderFactory(context, decoderFactory, Clock.DEFAULT);
|
||||
new DefaultAssetLoaderFactory(
|
||||
context, decoderFactory, Clock.DEFAULT, /* logSessionId= */ null);
|
||||
Transformer transformer =
|
||||
ExperimentalAnalyzerModeFactory.buildAnalyzer(context)
|
||||
.buildUpon()
|
||||
|
@ -21,6 +21,7 @@ import static androidx.media3.common.util.Assertions.checkState;
|
||||
import static androidx.media3.decoder.DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DISABLED;
|
||||
import static java.lang.Math.min;
|
||||
|
||||
import android.media.metrics.LogSessionId;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.Format;
|
||||
@ -58,7 +59,8 @@ import org.checkerframework.dataflow.qual.Pure;
|
||||
AudioMixer.Factory mixerFactory,
|
||||
Codec.EncoderFactory encoderFactory,
|
||||
MuxerWrapper muxerWrapper,
|
||||
FallbackListener fallbackListener)
|
||||
FallbackListener fallbackListener,
|
||||
@Nullable LogSessionId logSessionId)
|
||||
throws ExportException {
|
||||
super(firstAssetLoaderTrackFormat, muxerWrapper);
|
||||
SonicAudioProcessor outputResampler = new SonicAudioProcessor();
|
||||
@ -96,7 +98,8 @@ import org.checkerframework.dataflow.qual.Pure;
|
||||
findSupportedMimeTypeForEncoderAndMuxer(
|
||||
requestedEncoderFormat,
|
||||
muxerWrapper.getSupportedSampleMimeTypes(C.TRACK_TYPE_AUDIO)))
|
||||
.build());
|
||||
.build(),
|
||||
logSessionId);
|
||||
|
||||
AudioFormat actualEncoderAudioFormat = new AudioFormat(encoder.getInputFormat());
|
||||
// This occurs when the encoder does not support the requested format. In this case, the audio
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package androidx.media3.transformer;
|
||||
|
||||
import android.media.metrics.LogSessionId;
|
||||
import android.view.Surface;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.Format;
|
||||
@ -31,17 +32,23 @@ import androidx.media3.common.Format;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec createForAudioDecoding(Format format) throws ExportException {
|
||||
Codec audioDecoder = decoderFactory.createForAudioDecoding(format);
|
||||
public Codec createForAudioDecoding(Format format, @Nullable LogSessionId logSessionId)
|
||||
throws ExportException {
|
||||
Codec audioDecoder = decoderFactory.createForAudioDecoding(format, logSessionId);
|
||||
audioDecoderName = audioDecoder.getName();
|
||||
return audioDecoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec createForVideoDecoding(
|
||||
Format format, Surface outputSurface, boolean requestSdrToneMapping) throws ExportException {
|
||||
Format format,
|
||||
Surface outputSurface,
|
||||
boolean requestSdrToneMapping,
|
||||
@Nullable LogSessionId logSessionId)
|
||||
throws ExportException {
|
||||
Codec videoDecoder =
|
||||
decoderFactory.createForVideoDecoding(format, outputSurface, requestSdrToneMapping);
|
||||
decoderFactory.createForVideoDecoding(
|
||||
format, outputSurface, requestSdrToneMapping, logSessionId);
|
||||
videoDecoderName = videoDecoder.getName();
|
||||
return videoDecoder;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package androidx.media3.transformer;
|
||||
|
||||
import android.media.metrics.LogSessionId;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.Format;
|
||||
|
||||
@ -30,15 +31,17 @@ import androidx.media3.common.Format;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec createForAudioEncoding(Format format) throws ExportException {
|
||||
Codec audioEncoder = encoderFactory.createForAudioEncoding(format);
|
||||
public Codec createForAudioEncoding(Format format, @Nullable LogSessionId logSessionId)
|
||||
throws ExportException {
|
||||
Codec audioEncoder = encoderFactory.createForAudioEncoding(format, logSessionId);
|
||||
audioEncoderName = audioEncoder.getName();
|
||||
return audioEncoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec createForVideoEncoding(Format format) throws ExportException {
|
||||
Codec videoEncoder = encoderFactory.createForVideoEncoding(format);
|
||||
public Codec createForVideoEncoding(Format format, @Nullable LogSessionId logSessionId)
|
||||
throws ExportException {
|
||||
Codec videoEncoder = encoderFactory.createForVideoEncoding(format, logSessionId);
|
||||
videoEncoderName = videoEncoder.getName();
|
||||
return videoEncoder;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
package androidx.media3.transformer;
|
||||
|
||||
import android.media.MediaCodec.BufferInfo;
|
||||
import android.media.metrics.LogSessionId;
|
||||
import android.view.Surface;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.C;
|
||||
@ -41,10 +42,13 @@ public interface Codec {
|
||||
*
|
||||
* @param format The {@link Format} (of the input data) used to determine the underlying decoder
|
||||
* and its configuration values.
|
||||
* @param logSessionId The optional {@link LogSessionId} of the {@link
|
||||
* android.media.metrics.EditingSession}.
|
||||
* @return A {@link Codec} for audio decoding.
|
||||
* @throws ExportException If no suitable {@link Codec} can be created.
|
||||
*/
|
||||
Codec createForAudioDecoding(Format format) throws ExportException;
|
||||
Codec createForAudioDecoding(Format format, @Nullable LogSessionId logSessionId)
|
||||
throws ExportException;
|
||||
|
||||
/**
|
||||
* Returns a {@link Codec} for video decoding.
|
||||
@ -53,11 +57,17 @@ public interface Codec {
|
||||
* and its configuration values.
|
||||
* @param outputSurface The {@link Surface} to which the decoder output is rendered.
|
||||
* @param requestSdrToneMapping Whether to request tone-mapping to SDR.
|
||||
* @param logSessionId The optional {@link LogSessionId} of the {@link
|
||||
* android.media.metrics.EditingSession}.
|
||||
* @return A {@link Codec} for video decoding.
|
||||
* @throws ExportException If no suitable {@link Codec} can be created.
|
||||
*/
|
||||
Codec createForVideoDecoding(
|
||||
Format format, Surface outputSurface, boolean requestSdrToneMapping) throws ExportException;
|
||||
Format format,
|
||||
Surface outputSurface,
|
||||
boolean requestSdrToneMapping,
|
||||
@Nullable LogSessionId logSessionId)
|
||||
throws ExportException;
|
||||
}
|
||||
|
||||
/** A factory for {@linkplain Codec encoder} instances. */
|
||||
@ -77,11 +87,14 @@ public interface Codec {
|
||||
* encoder and its configuration values. {@link Format#sampleMimeType}, {@link
|
||||
* Format#sampleRate}, {@link Format#channelCount} and {@link Format#bitrate} are set to
|
||||
* those of the desired output video format.
|
||||
* @param logSessionId The optional {@link LogSessionId} of the {@link
|
||||
* android.media.metrics.EditingSession}.
|
||||
* @return A {@link Codec} for encoding audio to the requested {@link Format#sampleMimeType MIME
|
||||
* type}.
|
||||
* @throws ExportException If no suitable {@link Codec} can be created.
|
||||
*/
|
||||
Codec createForAudioEncoding(Format format) throws ExportException;
|
||||
Codec createForAudioEncoding(Format format, @Nullable LogSessionId logSessionId)
|
||||
throws ExportException;
|
||||
|
||||
/**
|
||||
* Returns a {@link Codec} for video encoding.
|
||||
@ -100,11 +113,14 @@ public interface Codec {
|
||||
* Format#frameRate} is set to the requested output frame rate, if available. {@link
|
||||
* Format#colorInfo} is set to the requested output color characteristics, if available.
|
||||
* {@link Format#rotationDegrees} is always 0.
|
||||
* @param logSessionId The optional {@link LogSessionId} of the {@link
|
||||
* android.media.metrics.EditingSession}.
|
||||
* @return A {@link Codec} for encoding video to the requested {@linkplain Format#sampleMimeType
|
||||
* MIME type}.
|
||||
* @throws ExportException If no suitable {@link Codec} can be created.
|
||||
*/
|
||||
Codec createForVideoEncoding(Format format) throws ExportException;
|
||||
Codec createForVideoEncoding(Format format, @Nullable LogSessionId logSessionId)
|
||||
throws ExportException;
|
||||
|
||||
/** Returns whether the audio needs to be encoded because of encoder specific configuration. */
|
||||
default boolean audioNeedsEncoding() {
|
||||
|
@ -22,6 +22,7 @@ import static androidx.media3.transformer.TransformerUtil.isImage;
|
||||
import android.content.Context;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.ColorSpace;
|
||||
import android.media.metrics.LogSessionId;
|
||||
import android.os.Looper;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.C;
|
||||
@ -58,6 +59,7 @@ public final class DefaultAssetLoaderFactory implements AssetLoader.Factory {
|
||||
@Nullable private final MediaSource.Factory mediaSourceFactory;
|
||||
private final BitmapLoader bitmapLoader;
|
||||
@Nullable private final TrackSelector.Factory trackSelectorFactory;
|
||||
@Nullable private final LogSessionId logSessionId;
|
||||
|
||||
private AssetLoader.@MonotonicNonNull Factory imageAssetLoaderFactory;
|
||||
private AssetLoader.@MonotonicNonNull Factory exoPlayerAssetLoaderFactory;
|
||||
@ -74,15 +76,21 @@ public final class DefaultAssetLoaderFactory implements AssetLoader.Factory {
|
||||
* necessary).
|
||||
* @param clock The {@link Clock} to use. It should always be {@link Clock#DEFAULT}, except for
|
||||
* testing.
|
||||
* @param logSessionId The optional {@link LogSessionId} of the {@link
|
||||
* android.media.metrics.EditingSession}.
|
||||
*/
|
||||
public DefaultAssetLoaderFactory(
|
||||
Context context, Codec.DecoderFactory decoderFactory, Clock clock) {
|
||||
Context context,
|
||||
Codec.DecoderFactory decoderFactory,
|
||||
Clock clock,
|
||||
@Nullable LogSessionId logSessionId) {
|
||||
// TODO: b/381519379 - Deprecate this constructor and replace with a builder.
|
||||
this.context = context.getApplicationContext();
|
||||
this.decoderFactory = decoderFactory;
|
||||
this.clock = clock;
|
||||
this.mediaSourceFactory = null;
|
||||
this.trackSelectorFactory = null;
|
||||
this.logSessionId = logSessionId;
|
||||
@Nullable BitmapFactory.Options options = null;
|
||||
if (Util.SDK_INT >= 26) {
|
||||
options = new BitmapFactory.Options();
|
||||
@ -113,6 +121,7 @@ public final class DefaultAssetLoaderFactory implements AssetLoader.Factory {
|
||||
clock = Clock.DEFAULT;
|
||||
mediaSourceFactory = null;
|
||||
trackSelectorFactory = null;
|
||||
logSessionId = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -140,6 +149,7 @@ public final class DefaultAssetLoaderFactory implements AssetLoader.Factory {
|
||||
this.mediaSourceFactory = mediaSourceFactory;
|
||||
this.bitmapLoader = bitmapLoader;
|
||||
this.trackSelectorFactory = null;
|
||||
this.logSessionId = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -170,6 +180,7 @@ public final class DefaultAssetLoaderFactory implements AssetLoader.Factory {
|
||||
this.mediaSourceFactory = mediaSourceFactory;
|
||||
this.bitmapLoader = bitmapLoader;
|
||||
this.trackSelectorFactory = trackSelectorFactory;
|
||||
this.logSessionId = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -196,7 +207,12 @@ public final class DefaultAssetLoaderFactory implements AssetLoader.Factory {
|
||||
if (exoPlayerAssetLoaderFactory == null) {
|
||||
exoPlayerAssetLoaderFactory =
|
||||
new ExoPlayerAssetLoader.Factory(
|
||||
context, decoderFactory, clock, mediaSourceFactory, trackSelectorFactory);
|
||||
context,
|
||||
decoderFactory,
|
||||
clock,
|
||||
mediaSourceFactory,
|
||||
trackSelectorFactory,
|
||||
logSessionId);
|
||||
}
|
||||
return exoPlayerAssetLoaderFactory.createAssetLoader(
|
||||
editedMediaItem, looper, listener, compositionSettings);
|
||||
|
@ -25,6 +25,7 @@ import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.media.MediaCodec;
|
||||
import android.media.MediaFormat;
|
||||
import android.media.metrics.LogSessionId;
|
||||
import android.os.Build;
|
||||
import android.util.Pair;
|
||||
import android.view.Surface;
|
||||
@ -237,16 +238,25 @@ public final class DefaultDecoderFactory implements Codec.DecoderFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultCodec createForAudioDecoding(Format format) throws ExportException {
|
||||
public DefaultCodec createForAudioDecoding(Format format, @Nullable LogSessionId logSessionId)
|
||||
throws ExportException {
|
||||
MediaFormat mediaFormat = createMediaFormatFromFormat(format);
|
||||
return createCodecForMediaFormat(
|
||||
mediaFormat, format, /* outputSurface= */ null, /* devicePrefersSoftwareDecoder= */ false);
|
||||
mediaFormat,
|
||||
format,
|
||||
/* outputSurface= */ null,
|
||||
/* devicePrefersSoftwareDecoder= */ false,
|
||||
logSessionId);
|
||||
}
|
||||
|
||||
@SuppressLint("InlinedApi")
|
||||
@Override
|
||||
public DefaultCodec createForVideoDecoding(
|
||||
Format format, Surface outputSurface, boolean requestSdrToneMapping) throws ExportException {
|
||||
Format format,
|
||||
Surface outputSurface,
|
||||
boolean requestSdrToneMapping,
|
||||
@Nullable LogSessionId logSessionId)
|
||||
throws ExportException {
|
||||
if (ColorInfo.isTransferHdr(format.colorInfo)) {
|
||||
if (requestSdrToneMapping
|
||||
&& (SDK_INT < 31
|
||||
@ -298,14 +308,15 @@ public final class DefaultDecoderFactory implements Codec.DecoderFactory {
|
||||
}
|
||||
|
||||
return createCodecForMediaFormat(
|
||||
mediaFormat, format, outputSurface, devicePrefersSoftwareDecoder(format));
|
||||
mediaFormat, format, outputSurface, devicePrefersSoftwareDecoder(format), logSessionId);
|
||||
}
|
||||
|
||||
private DefaultCodec createCodecForMediaFormat(
|
||||
MediaFormat mediaFormat,
|
||||
Format format,
|
||||
@Nullable Surface outputSurface,
|
||||
boolean devicePrefersSoftwareDecoder)
|
||||
boolean devicePrefersSoftwareDecoder,
|
||||
@Nullable LogSessionId logSessionId)
|
||||
throws ExportException {
|
||||
List<MediaCodecInfo> decoderInfos = ImmutableList.of();
|
||||
checkNotNull(format.sampleMimeType);
|
||||
@ -344,6 +355,9 @@ public final class DefaultDecoderFactory implements Codec.DecoderFactory {
|
||||
mediaFormat.setInteger(
|
||||
MediaFormat.KEY_COLOR_TRANSFER_REQUEST, MediaFormat.COLOR_TRANSFER_HLG);
|
||||
}
|
||||
if (SDK_INT >= 35 && logSessionId != null) {
|
||||
TransformerUtil.Api35.setLogSessionIdToMediaCodecFormat(mediaFormat, logSessionId);
|
||||
}
|
||||
List<ExportException> codecInitExceptions = new ArrayList<>();
|
||||
DefaultCodec codec =
|
||||
createCodecFromDecoderInfos(
|
||||
|
@ -32,6 +32,7 @@ import static java.lang.Math.round;
|
||||
import android.content.Context;
|
||||
import android.media.MediaCodecInfo;
|
||||
import android.media.MediaFormat;
|
||||
import android.media.metrics.LogSessionId;
|
||||
import android.os.Build;
|
||||
import android.util.Size;
|
||||
import androidx.annotation.IntRange;
|
||||
@ -190,7 +191,8 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultCodec createForAudioEncoding(Format format) throws ExportException {
|
||||
public DefaultCodec createForAudioEncoding(Format format, @Nullable LogSessionId logSessionId)
|
||||
throws ExportException {
|
||||
if (format.bitrate == Format.NO_VALUE) {
|
||||
format = format.buildUpon().setAverageBitrate(DEFAULT_AUDIO_BITRATE).build();
|
||||
}
|
||||
@ -236,6 +238,9 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
||||
if (requestedAudioEncoderSettings.bitrate != AudioEncoderSettings.NO_VALUE) {
|
||||
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, requestedAudioEncoderSettings.bitrate);
|
||||
}
|
||||
if (SDK_INT >= 35 && logSessionId != null) {
|
||||
TransformerUtil.Api35.setLogSessionIdToMediaCodecFormat(mediaFormat, logSessionId);
|
||||
}
|
||||
|
||||
return new DefaultCodec(
|
||||
context,
|
||||
@ -254,7 +259,8 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
||||
* in {@link Format} are ignored when {@link VideoEncoderSettings#bitrate} is set.
|
||||
*/
|
||||
@Override
|
||||
public DefaultCodec createForVideoEncoding(Format format) throws ExportException {
|
||||
public DefaultCodec createForVideoEncoding(Format format, @Nullable LogSessionId logSessionId)
|
||||
throws ExportException {
|
||||
if (format.frameRate == Format.NO_VALUE || deviceNeedsDefaultFrameRateWorkaround()) {
|
||||
format = format.buildUpon().setFrameRate(DEFAULT_FRAME_RATE).build();
|
||||
}
|
||||
@ -385,6 +391,9 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory {
|
||||
|
||||
if (Util.SDK_INT >= 35) {
|
||||
mediaFormat.setInteger(MediaFormat.KEY_IMPORTANCE, max(0, -codecPriority));
|
||||
if (logSessionId != null) {
|
||||
TransformerUtil.Api35.setLogSessionIdToMediaCodecFormat(mediaFormat, logSessionId);
|
||||
}
|
||||
}
|
||||
|
||||
return new DefaultCodec(
|
||||
|
@ -18,6 +18,7 @@ package androidx.media3.transformer;
|
||||
import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||
|
||||
import android.media.MediaCodec;
|
||||
import android.media.metrics.LogSessionId;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.Format;
|
||||
@ -30,15 +31,18 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
private static final String TAG = "ExoAssetLoaderAudioRenderer";
|
||||
|
||||
private final Codec.DecoderFactory decoderFactory;
|
||||
@Nullable private final LogSessionId logSessionId;
|
||||
|
||||
private boolean hasPendingConsumerInput;
|
||||
|
||||
public ExoAssetLoaderAudioRenderer(
|
||||
Codec.DecoderFactory decoderFactory,
|
||||
TransformerMediaClock mediaClock,
|
||||
AssetLoader.Listener assetLoaderListener) {
|
||||
AssetLoader.Listener assetLoaderListener,
|
||||
@Nullable LogSessionId logSessionId) {
|
||||
super(C.TRACK_TYPE_AUDIO, mediaClock, assetLoaderListener);
|
||||
this.decoderFactory = decoderFactory;
|
||||
this.logSessionId = logSessionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -48,7 +52,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
|
||||
@Override
|
||||
protected void initDecoder(Format inputFormat) throws ExportException {
|
||||
decoder = decoderFactory.createForAudioDecoding(inputFormat);
|
||||
decoder = decoderFactory.createForAudioDecoding(inputFormat, logSessionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -20,6 +20,7 @@ import static androidx.media3.common.util.Assertions.checkStateNotNull;
|
||||
import static androidx.media3.transformer.TransformerUtil.getDecoderOutputColor;
|
||||
|
||||
import android.media.MediaCodec;
|
||||
import android.media.metrics.LogSessionId;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.ColorInfo;
|
||||
@ -39,6 +40,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
private final Codec.DecoderFactory decoderFactory;
|
||||
private final @Composition.HdrMode int hdrMode;
|
||||
private final List<Long> decodeOnlyPresentationTimestamps;
|
||||
@Nullable private final LogSessionId logSessionId;
|
||||
|
||||
private @MonotonicNonNull SefSlowMotionFlattener sefVideoSlowMotionFlattener;
|
||||
private int maxDecoderPendingFrameCount;
|
||||
@ -48,11 +50,13 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
Codec.DecoderFactory decoderFactory,
|
||||
@Composition.HdrMode int hdrMode,
|
||||
TransformerMediaClock mediaClock,
|
||||
AssetLoader.Listener assetLoaderListener) {
|
||||
AssetLoader.Listener assetLoaderListener,
|
||||
@Nullable LogSessionId logSessionId) {
|
||||
super(C.TRACK_TYPE_VIDEO, mediaClock, assetLoaderListener);
|
||||
this.flattenForSlowMotion = flattenForSlowMotion;
|
||||
this.decoderFactory = decoderFactory;
|
||||
this.hdrMode = hdrMode;
|
||||
this.logSessionId = logSessionId;
|
||||
decodeOnlyPresentationTimestamps = new ArrayList<>();
|
||||
maxDecoderPendingFrameCount = C.INDEX_UNSET;
|
||||
}
|
||||
@ -118,7 +122,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
||||
decoderFactory.createForVideoDecoding(
|
||||
inputFormat,
|
||||
checkNotNull(sampleConsumer.getInputSurface()),
|
||||
isDecoderToneMappingRequired);
|
||||
isDecoderToneMappingRequired,
|
||||
logSessionId);
|
||||
maxDecoderPendingFrameCount = decoder.getMaxPendingFrameCount();
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ import static androidx.media3.transformer.TransformerUtil.isImage;
|
||||
import static java.lang.Math.min;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.metrics.LogSessionId;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import androidx.annotation.Nullable;
|
||||
@ -72,6 +73,7 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
||||
private final Clock clock;
|
||||
@Nullable private final MediaSource.Factory mediaSourceFactory;
|
||||
@Nullable private final TrackSelector.Factory trackSelectorFactory;
|
||||
@Nullable private final LogSessionId logSessionId;
|
||||
|
||||
/**
|
||||
* Creates an instance using a {@link DefaultMediaSourceFactory}.
|
||||
@ -89,7 +91,8 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
||||
decoderFactory,
|
||||
clock,
|
||||
/* mediaSourceFactory= */ null,
|
||||
/* trackSelectorFactory= */ null);
|
||||
/* trackSelectorFactory= */ null,
|
||||
/* logSessionId= */ null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -109,7 +112,13 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
||||
Clock clock,
|
||||
MediaSource.Factory mediaSourceFactory) {
|
||||
// TODO: b/381519379 - Deprecate this constructor and replace with a builder.
|
||||
this(context, decoderFactory, clock, mediaSourceFactory, /* trackSelectorFactory= */ null);
|
||||
this(
|
||||
context,
|
||||
decoderFactory,
|
||||
clock,
|
||||
mediaSourceFactory,
|
||||
/* trackSelectorFactory= */ null,
|
||||
/* logSessionId= */ null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -124,19 +133,23 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
||||
* transform.
|
||||
* @param trackSelectorFactory The {@link TrackSelector.Factory} to use when selecting the track
|
||||
* to transform.
|
||||
* @param logSessionId The optional {@link LogSessionId} of the {@link
|
||||
* android.media.metrics.EditingSession}.
|
||||
*/
|
||||
public Factory(
|
||||
Context context,
|
||||
Codec.DecoderFactory decoderFactory,
|
||||
Clock clock,
|
||||
@Nullable MediaSource.Factory mediaSourceFactory,
|
||||
@Nullable TrackSelector.Factory trackSelectorFactory) {
|
||||
@Nullable TrackSelector.Factory trackSelectorFactory,
|
||||
@Nullable LogSessionId logSessionId) {
|
||||
// TODO: b/381519379 - Deprecate this constructor and replace with a builder.
|
||||
this.context = context;
|
||||
this.decoderFactory = decoderFactory;
|
||||
this.clock = clock;
|
||||
this.mediaSourceFactory = mediaSourceFactory;
|
||||
this.trackSelectorFactory = trackSelectorFactory;
|
||||
this.logSessionId = logSessionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -176,7 +189,8 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
||||
looper,
|
||||
listener,
|
||||
clock,
|
||||
trackSelectorFactory);
|
||||
trackSelectorFactory,
|
||||
logSessionId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,7 +212,8 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
||||
Looper looper,
|
||||
Listener listener,
|
||||
Clock clock,
|
||||
TrackSelector.Factory trackSelectorFactory) {
|
||||
TrackSelector.Factory trackSelectorFactory,
|
||||
@Nullable LogSessionId logSessionId) {
|
||||
this.context = context;
|
||||
this.editedMediaItem = editedMediaItem;
|
||||
this.decoderFactory = new CapturingDecoderFactory(decoderFactory);
|
||||
@ -223,7 +238,8 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
||||
editedMediaItem.flattenForSlowMotion,
|
||||
this.decoderFactory,
|
||||
hdrMode,
|
||||
listener))
|
||||
listener,
|
||||
logSessionId))
|
||||
.setMediaSourceFactory(mediaSourceFactory)
|
||||
.setTrackSelector(trackSelector)
|
||||
.setLoadControl(loadControl)
|
||||
@ -291,6 +307,7 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
||||
private final Codec.DecoderFactory decoderFactory;
|
||||
private final @Composition.HdrMode int hdrMode;
|
||||
private final Listener assetLoaderListener;
|
||||
@Nullable private final LogSessionId logSessionId;
|
||||
|
||||
public RenderersFactoryImpl(
|
||||
boolean removeAudio,
|
||||
@ -298,13 +315,15 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
||||
boolean flattenForSlowMotion,
|
||||
Codec.DecoderFactory decoderFactory,
|
||||
@Composition.HdrMode int hdrMode,
|
||||
Listener assetLoaderListener) {
|
||||
Listener assetLoaderListener,
|
||||
@Nullable LogSessionId logSessionId) {
|
||||
this.removeAudio = removeAudio;
|
||||
this.removeVideo = removeVideo;
|
||||
this.flattenForSlowMotion = flattenForSlowMotion;
|
||||
this.decoderFactory = decoderFactory;
|
||||
this.hdrMode = hdrMode;
|
||||
this.assetLoaderListener = assetLoaderListener;
|
||||
this.logSessionId = logSessionId;
|
||||
mediaClock = new TransformerMediaClock();
|
||||
}
|
||||
|
||||
@ -318,12 +337,18 @@ public final class ExoPlayerAssetLoader implements AssetLoader {
|
||||
ArrayList<Renderer> renderers = new ArrayList<>();
|
||||
if (!removeAudio) {
|
||||
renderers.add(
|
||||
new ExoAssetLoaderAudioRenderer(decoderFactory, mediaClock, assetLoaderListener));
|
||||
new ExoAssetLoaderAudioRenderer(
|
||||
decoderFactory, mediaClock, assetLoaderListener, logSessionId));
|
||||
}
|
||||
if (!removeVideo) {
|
||||
renderers.add(
|
||||
new ExoAssetLoaderVideoRenderer(
|
||||
flattenForSlowMotion, decoderFactory, hdrMode, mediaClock, assetLoaderListener));
|
||||
flattenForSlowMotion,
|
||||
decoderFactory,
|
||||
hdrMode,
|
||||
mediaClock,
|
||||
assetLoaderListener,
|
||||
logSessionId));
|
||||
}
|
||||
return renderers.toArray(new Renderer[renderers.size()]);
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import static androidx.media3.common.util.Assertions.checkState;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.MediaCodec.BufferInfo;
|
||||
import android.media.metrics.LogSessionId;
|
||||
import android.view.Surface;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.C;
|
||||
@ -93,12 +94,12 @@ public final class ExperimentalAnalyzerModeFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec createForAudioEncoding(Format format) {
|
||||
public Codec createForAudioEncoding(Format format, @Nullable LogSessionId logSessionId) {
|
||||
return new DroppingEncoder(context, format);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec createForVideoEncoding(Format format) {
|
||||
public Codec createForVideoEncoding(Format format, @Nullable LogSessionId logSessionId) {
|
||||
return new DroppingEncoder(context, format);
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ import static java.lang.Math.round;
|
||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.metrics.LogSessionId;
|
||||
import android.os.Looper;
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.Nullable;
|
||||
@ -1601,15 +1602,7 @@ public final class Transformer {
|
||||
transformationRequest =
|
||||
transformationRequest.buildUpon().setHdrMode(composition.hdrMode).build();
|
||||
}
|
||||
FallbackListener fallbackListener =
|
||||
new FallbackListener(composition, listeners, applicationHandler, transformationRequest);
|
||||
AssetLoader.Factory assetLoaderFactory = this.assetLoaderFactory;
|
||||
if (useDefaultAssetLoaderFactory || assetLoaderFactory == null) {
|
||||
assetLoaderFactory =
|
||||
new DefaultAssetLoaderFactory(
|
||||
context, new DefaultDecoderFactory.Builder(context).build(), clock);
|
||||
}
|
||||
DebugTraceUtil.reset();
|
||||
LogSessionId logSessionId = null;
|
||||
if (canCollectEditingMetrics()) {
|
||||
@Nullable String muxerName = null;
|
||||
if (muxerFactory instanceof InAppMp4Muxer.Factory) {
|
||||
@ -1619,10 +1612,24 @@ public final class Transformer {
|
||||
} else if (muxerFactory instanceof DefaultMuxer.Factory) {
|
||||
muxerName = DefaultMuxer.MUXER_NAME;
|
||||
}
|
||||
EditingMetricsCollector.MetricsReporter metricsReporter =
|
||||
checkNotNull(metricsReporterFactory).create();
|
||||
if (metricsReporter instanceof EditingMetricsCollector.DefaultMetricsReporter) {
|
||||
logSessionId =
|
||||
((EditingMetricsCollector.DefaultMetricsReporter) metricsReporter).getLogSessionId();
|
||||
}
|
||||
editingMetricsCollector =
|
||||
new EditingMetricsCollector(
|
||||
checkNotNull(metricsReporterFactory).create(), EXPORTER_NAME, muxerName);
|
||||
new EditingMetricsCollector(metricsReporter, EXPORTER_NAME, muxerName);
|
||||
}
|
||||
FallbackListener fallbackListener =
|
||||
new FallbackListener(composition, listeners, applicationHandler, transformationRequest);
|
||||
AssetLoader.Factory assetLoaderFactory = this.assetLoaderFactory;
|
||||
if (useDefaultAssetLoaderFactory || assetLoaderFactory == null) {
|
||||
assetLoaderFactory =
|
||||
new DefaultAssetLoaderFactory(
|
||||
context, new DefaultDecoderFactory.Builder(context).build(), clock, logSessionId);
|
||||
}
|
||||
DebugTraceUtil.reset();
|
||||
transformerInternal =
|
||||
new TransformerInternal(
|
||||
context,
|
||||
@ -1640,7 +1647,8 @@ public final class Transformer {
|
||||
applicationHandler,
|
||||
debugViewProvider,
|
||||
clock,
|
||||
initialTimestampOffsetUs);
|
||||
initialTimestampOffsetUs,
|
||||
logSessionId);
|
||||
transformerInternal.start();
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,7 @@ import static java.lang.Math.max;
|
||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.metrics.LogSessionId;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
@ -201,7 +202,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
HandlerWrapper applicationHandler,
|
||||
DebugViewProvider debugViewProvider,
|
||||
Clock clock,
|
||||
long videoSampleTimestampOffsetUs) {
|
||||
long videoSampleTimestampOffsetUs,
|
||||
@Nullable LogSessionId logSessionId) {
|
||||
this.context = context;
|
||||
this.composition = composition;
|
||||
this.encoderFactory = new CapturingEncoderFactory(encoderFactory);
|
||||
@ -240,7 +242,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
audioMixerFactory,
|
||||
videoFrameProcessorFactory,
|
||||
fallbackListener,
|
||||
debugViewProvider);
|
||||
debugViewProvider,
|
||||
logSessionId);
|
||||
EditedMediaItemSequence sequence = composition.sequences.get(i);
|
||||
sequenceAssetLoaders.add(
|
||||
new SequenceAssetLoader(
|
||||
@ -555,6 +558,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
private final VideoFrameProcessor.Factory videoFrameProcessorFactory;
|
||||
private final FallbackListener fallbackListener;
|
||||
private final DebugViewProvider debugViewProvider;
|
||||
@Nullable private final LogSessionId logSessionId;
|
||||
private long currentSequenceDurationUs;
|
||||
|
||||
public SequenceAssetLoaderListener(
|
||||
@ -564,7 +568,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
AudioMixer.Factory audioMixerFactory,
|
||||
VideoFrameProcessor.Factory videoFrameProcessorFactory,
|
||||
FallbackListener fallbackListener,
|
||||
DebugViewProvider debugViewProvider) {
|
||||
DebugViewProvider debugViewProvider,
|
||||
@Nullable LogSessionId logSessionId) {
|
||||
this.sequenceIndex = sequenceIndex;
|
||||
this.firstEditedMediaItem = composition.sequences.get(sequenceIndex).editedMediaItems.get(0);
|
||||
this.composition = composition;
|
||||
@ -573,6 +578,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
this.videoFrameProcessorFactory = videoFrameProcessorFactory;
|
||||
this.fallbackListener = fallbackListener;
|
||||
this.debugViewProvider = debugViewProvider;
|
||||
this.logSessionId = logSessionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -696,7 +702,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
audioMixerFactory,
|
||||
encoderFactory,
|
||||
muxerWrapper,
|
||||
fallbackListener));
|
||||
fallbackListener,
|
||||
logSessionId));
|
||||
} else {
|
||||
Format firstFormat;
|
||||
if (MimeTypes.isVideo(assetLoaderOutputFormat.sampleMimeType)) {
|
||||
@ -738,7 +745,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
videoSampleTimestampOffsetUs,
|
||||
/* hasMultipleInputs= */ assetLoaderInputTracker.hasMultipleConcurrentVideoTracks(),
|
||||
portraitEncodingEnabled,
|
||||
maxFramesInEncoder));
|
||||
maxFramesInEncoder,
|
||||
logSessionId));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,8 +29,11 @@ import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.media.MediaCodec;
|
||||
import android.media.MediaCodecInfo;
|
||||
import android.media.MediaFormat;
|
||||
import android.media.metrics.LogSessionId;
|
||||
import android.util.Pair;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.ColorInfo;
|
||||
import androidx.media3.common.Effect;
|
||||
@ -375,4 +378,23 @@ public final class TransformerUtil {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** Utility for setting LogSessionId on MediaFormat (API 35+). */
|
||||
@RequiresApi(35)
|
||||
public static final class Api35 {
|
||||
private Api35() {}
|
||||
|
||||
/**
|
||||
* Sets the log session ID to the provided {@link MediaFormat}.
|
||||
*
|
||||
* @param mediaFormat The {@link MediaFormat} to set the log session ID on.
|
||||
* @param logSessionId The {@link LogSessionId} to set.
|
||||
*/
|
||||
public static void setLogSessionIdToMediaCodecFormat(
|
||||
MediaFormat mediaFormat, LogSessionId logSessionId) {
|
||||
if (!logSessionId.equals(LogSessionId.LOG_SESSION_ID_NONE)) {
|
||||
mediaFormat.setString("log-session-id", logSessionId.getStringId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.media.MediaCodec;
|
||||
import android.media.metrics.LogSessionId;
|
||||
import android.util.Pair;
|
||||
import android.view.Surface;
|
||||
import androidx.annotation.Nullable;
|
||||
@ -99,7 +100,8 @@ import org.checkerframework.dataflow.qual.Pure;
|
||||
long initialTimestampOffsetUs,
|
||||
boolean hasMultipleInputs,
|
||||
boolean portraitEncodingEnabled,
|
||||
int maxFramesInEncoder)
|
||||
int maxFramesInEncoder,
|
||||
@Nullable LogSessionId logSessionId)
|
||||
throws ExportException {
|
||||
// TODO: b/278259383 - Consider delaying configuration of VideoSampleExporter to use the decoder
|
||||
// output format instead of the extractor output format, to match AudioSampleExporter behavior.
|
||||
@ -137,7 +139,8 @@ import org.checkerframework.dataflow.qual.Pure;
|
||||
portraitEncodingEnabled,
|
||||
muxerWrapper.getSupportedSampleMimeTypes(C.TRACK_TYPE_VIDEO),
|
||||
transformationRequest,
|
||||
fallbackListener);
|
||||
fallbackListener,
|
||||
logSessionId);
|
||||
encoderOutputBuffer =
|
||||
new DecoderInputBuffer(DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DISABLED);
|
||||
|
||||
@ -252,6 +255,7 @@ import org.checkerframework.dataflow.qual.Pure;
|
||||
private final FallbackListener fallbackListener;
|
||||
private final String requestedOutputMimeType;
|
||||
private final @Composition.HdrMode int hdrModeAfterFallback;
|
||||
@Nullable private final LogSessionId logSessionId;
|
||||
|
||||
private @MonotonicNonNull SurfaceInfo encoderSurfaceInfo;
|
||||
|
||||
@ -265,7 +269,8 @@ import org.checkerframework.dataflow.qual.Pure;
|
||||
boolean portraitEncodingEnabled,
|
||||
List<String> muxerSupportedMimeTypes,
|
||||
TransformationRequest transformationRequest,
|
||||
FallbackListener fallbackListener) {
|
||||
FallbackListener fallbackListener,
|
||||
@Nullable LogSessionId logSessionId) {
|
||||
checkArgument(inputFormat.colorInfo != null);
|
||||
this.encoderFactory = encoderFactory;
|
||||
this.inputFormat = inputFormat;
|
||||
@ -273,6 +278,7 @@ import org.checkerframework.dataflow.qual.Pure;
|
||||
this.muxerSupportedMimeTypes = muxerSupportedMimeTypes;
|
||||
this.transformationRequest = transformationRequest;
|
||||
this.fallbackListener = fallbackListener;
|
||||
this.logSessionId = logSessionId;
|
||||
Pair<String, Integer> outputMimeTypeAndHdrModeAfterFallback =
|
||||
getRequestedOutputMimeTypeAndHdrModeAfterFallback(inputFormat, transformationRequest);
|
||||
requestedOutputMimeType = outputMimeTypeAndHdrModeAfterFallback.first;
|
||||
@ -347,7 +353,8 @@ import org.checkerframework.dataflow.qual.Pure;
|
||||
.setSampleMimeType(
|
||||
findSupportedMimeTypeForEncoderAndMuxer(
|
||||
requestedEncoderFormat, muxerSupportedMimeTypes))
|
||||
.build());
|
||||
.build(),
|
||||
logSessionId);
|
||||
|
||||
Format actualEncoderFormat = encoder.getConfigurationFormat();
|
||||
|
||||
|
@ -111,7 +111,7 @@ public class DefaultEncoderFactoryTest {
|
||||
Format actualVideoFormat =
|
||||
new DefaultEncoderFactory.Builder(context)
|
||||
.build()
|
||||
.createForVideoEncoding(requestedVideoFormat)
|
||||
.createForVideoEncoding(requestedVideoFormat, /* logSessionId= */ null)
|
||||
.getConfigurationFormat();
|
||||
|
||||
assertThat(actualVideoFormat.sampleMimeType).isEqualTo(MimeTypes.VIDEO_H264);
|
||||
@ -129,7 +129,9 @@ public class DefaultEncoderFactoryTest {
|
||||
ExportException exportException =
|
||||
assertThrows(
|
||||
ExportException.class,
|
||||
() -> encoderFactory.createForVideoEncoding(requestedVideoFormat));
|
||||
() ->
|
||||
encoderFactory.createForVideoEncoding(
|
||||
requestedVideoFormat, /* logSessionId= */ null));
|
||||
assertThat(exportException.errorCode).isEqualTo(ERROR_CODE_ENCODING_FORMAT_UNSUPPORTED);
|
||||
}
|
||||
|
||||
@ -140,7 +142,7 @@ public class DefaultEncoderFactoryTest {
|
||||
Format actualVideoFormat =
|
||||
new DefaultEncoderFactory.Builder(context)
|
||||
.build()
|
||||
.createForVideoEncoding(requestedVideoFormat)
|
||||
.createForVideoEncoding(requestedVideoFormat, /* logSessionId= */ null)
|
||||
.getConfigurationFormat();
|
||||
|
||||
assertThat(actualVideoFormat.width).isEqualTo(1920);
|
||||
@ -158,7 +160,7 @@ public class DefaultEncoderFactoryTest {
|
||||
new DefaultEncoderFactory.Builder(context)
|
||||
.setRequestedVideoEncoderSettings(VideoEncoderSettings.DEFAULT)
|
||||
.build()
|
||||
.createForVideoEncoding(requestedVideoFormat)
|
||||
.createForVideoEncoding(requestedVideoFormat, /* logSessionId= */ null)
|
||||
.getConfigurationFormat();
|
||||
|
||||
assertThat(actualVideoFormat.sampleMimeType).isEqualTo(MimeTypes.VIDEO_H264);
|
||||
@ -175,7 +177,7 @@ public class DefaultEncoderFactoryTest {
|
||||
Format actualVideoFormat =
|
||||
new DefaultEncoderFactory.Builder(context)
|
||||
.build()
|
||||
.createForVideoEncoding(requestedVideoFormat)
|
||||
.createForVideoEncoding(requestedVideoFormat, /* logSessionId= */ null)
|
||||
.getConfigurationFormat();
|
||||
|
||||
assertThat(actualVideoFormat.sampleMimeType).isEqualTo(MimeTypes.VIDEO_H264);
|
||||
@ -198,7 +200,7 @@ public class DefaultEncoderFactoryTest {
|
||||
.setRequestedVideoEncoderSettings(
|
||||
new VideoEncoderSettings.Builder().setBitrate(10_000_000).build())
|
||||
.build()
|
||||
.createForVideoEncoding(requestedVideoFormat)
|
||||
.createForVideoEncoding(requestedVideoFormat, /* logSessionId= */ null)
|
||||
.getConfigurationFormat();
|
||||
|
||||
assertThat(actualVideoFormat.sampleMimeType).isEqualTo(MimeTypes.VIDEO_H264);
|
||||
@ -216,7 +218,7 @@ public class DefaultEncoderFactoryTest {
|
||||
Codec videoEncoder =
|
||||
new DefaultEncoderFactory.Builder(context)
|
||||
.build()
|
||||
.createForVideoEncoding(requestedVideoFormat);
|
||||
.createForVideoEncoding(requestedVideoFormat, /* logSessionId= */ null);
|
||||
|
||||
assertThat(videoEncoder).isInstanceOf(DefaultCodec.class);
|
||||
MediaFormat configurationMediaFormat =
|
||||
@ -241,7 +243,7 @@ public class DefaultEncoderFactoryTest {
|
||||
.setEncoderPerformanceParameters(/* operatingRate= */ -1, /* priority= */ 1)
|
||||
.build())
|
||||
.build()
|
||||
.createForVideoEncoding(requestedVideoFormat);
|
||||
.createForVideoEncoding(requestedVideoFormat, /* logSessionId= */ null);
|
||||
|
||||
assertThat(videoEncoder).isInstanceOf(DefaultCodec.class);
|
||||
MediaFormat configurationMediaFormat =
|
||||
@ -266,7 +268,7 @@ public class DefaultEncoderFactoryTest {
|
||||
/* operatingRate= */ VideoEncoderSettings.RATE_UNSET, /* priority= */ 1)
|
||||
.build())
|
||||
.build()
|
||||
.createForVideoEncoding(requestedVideoFormat);
|
||||
.createForVideoEncoding(requestedVideoFormat, /* logSessionId= */ null);
|
||||
|
||||
assertThat(videoEncoder).isInstanceOf(DefaultCodec.class);
|
||||
MediaFormat configurationMediaFormat =
|
||||
@ -290,7 +292,7 @@ public class DefaultEncoderFactoryTest {
|
||||
VideoEncoderSettings.RATE_UNSET, VideoEncoderSettings.RATE_UNSET)
|
||||
.build())
|
||||
.build()
|
||||
.createForVideoEncoding(requestedVideoFormat);
|
||||
.createForVideoEncoding(requestedVideoFormat, /* logSessionId= */ null);
|
||||
|
||||
assertThat(videoEncoder).isInstanceOf(DefaultCodec.class);
|
||||
MediaFormat configurationMediaFormat =
|
||||
@ -309,7 +311,7 @@ public class DefaultEncoderFactoryTest {
|
||||
.setRequestedVideoEncoderSettings(
|
||||
new VideoEncoderSettings.Builder().setRepeatPreviousFrameIntervalUs(33_333).build())
|
||||
.build()
|
||||
.createForVideoEncoding(requestedVideoFormat);
|
||||
.createForVideoEncoding(requestedVideoFormat, /* logSessionId= */ null);
|
||||
|
||||
assertThat(
|
||||
videoEncoder
|
||||
@ -326,7 +328,7 @@ public class DefaultEncoderFactoryTest {
|
||||
DefaultCodec videoEncoder =
|
||||
new DefaultEncoderFactory.Builder(context)
|
||||
.build()
|
||||
.createForVideoEncoding(requestedVideoFormat);
|
||||
.createForVideoEncoding(requestedVideoFormat, /* logSessionId= */ null);
|
||||
|
||||
assertThat(
|
||||
videoEncoder
|
||||
@ -344,7 +346,7 @@ public class DefaultEncoderFactoryTest {
|
||||
new DefaultEncoderFactory.Builder(context)
|
||||
.setVideoEncoderSelector((mimeType) -> ImmutableList.of())
|
||||
.build()
|
||||
.createForVideoEncoding(requestedVideoFormat));
|
||||
.createForVideoEncoding(requestedVideoFormat, /* logSessionId= */ null));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -357,7 +359,7 @@ public class DefaultEncoderFactoryTest {
|
||||
new DefaultEncoderFactory.Builder(context)
|
||||
.setEnableFallback(true)
|
||||
.build()
|
||||
.createForAudioEncoding(requestedAudioFormat);
|
||||
.createForAudioEncoding(requestedAudioFormat, /* logSessionId= */ null);
|
||||
|
||||
Format inputFormat = codec.getInputFormat();
|
||||
Format configurationFormat = codec.getConfigurationFormat();
|
||||
|
@ -173,7 +173,12 @@ public class ExoPlayerAssetLoaderTest {
|
||||
Codec.DecoderFactory decoderFactory = new DefaultDecoderFactory.Builder(context).build();
|
||||
EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(MediaItem.fromUri(uri)).build();
|
||||
return new ExoPlayerAssetLoader.Factory(
|
||||
context, decoderFactory, clock, /* mediaSourceFactory= */ null, trackSelectorFactory)
|
||||
context,
|
||||
decoderFactory,
|
||||
clock,
|
||||
/* mediaSourceFactory= */ null,
|
||||
trackSelectorFactory,
|
||||
/* logSessionId= */ null)
|
||||
.createAssetLoader(
|
||||
editedMediaItem,
|
||||
Looper.myLooper(),
|
||||
|
@ -25,8 +25,10 @@ import static org.mockito.Mockito.when;
|
||||
import android.media.MediaCodecInfo;
|
||||
import android.media.MediaCodecInfo.CodecProfileLevel;
|
||||
import android.media.MediaFormat;
|
||||
import android.media.metrics.LogSessionId;
|
||||
import android.net.Uri;
|
||||
import android.os.Looper;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.media3.common.C;
|
||||
import androidx.media3.common.ColorInfo;
|
||||
import androidx.media3.common.Format;
|
||||
@ -74,7 +76,8 @@ public final class VideoEncoderWrapperTest {
|
||||
/* portraitEncodingEnabled= */ false,
|
||||
/* muxerSupportedMimeTypes= */ ImmutableList.of(MimeTypes.VIDEO_H264),
|
||||
emptyTransformationRequest,
|
||||
fallbackListener);
|
||||
fallbackListener,
|
||||
/* logSessionId= */ null);
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@ -184,12 +187,12 @@ public final class VideoEncoderWrapperTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec createForAudioEncoding(Format format) {
|
||||
public Codec createForAudioEncoding(Format format, @Nullable LogSessionId logSessionId) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Codec createForVideoEncoding(Format format) {
|
||||
public Codec createForVideoEncoding(Format format, @Nullable LogSessionId logSessionId) {
|
||||
Codec mockEncoder = mock(Codec.class);
|
||||
if (fallbackWidth != C.LENGTH_UNSET) {
|
||||
format = format.buildUpon().setWidth(fallbackWidth).build();
|
||||
|
Loading…
x
Reference in New Issue
Block a user