mirror of
https://github.com/androidx/media.git
synced 2025-05-12 18:19:50 +08:00
Propagate PCM encoding passed to AudioSamplePipeline.
PiperOrigin-RevId: 511810757
This commit is contained in:
parent
cc1ca860b1
commit
a6932f9bdd
@ -20,6 +20,7 @@ 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.decoder.DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DIRECT;
|
import static androidx.media3.decoder.DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DIRECT;
|
||||||
import static androidx.media3.decoder.DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DISABLED;
|
import static androidx.media3.decoder.DecoderInputBuffer.BUFFER_REPLACEMENT_MODE_DISABLED;
|
||||||
|
import static androidx.media3.transformer.DefaultCodec.DEFAULT_PCM_ENCODING;
|
||||||
import static java.lang.Math.min;
|
import static java.lang.Math.min;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@ -92,13 +93,14 @@ import org.checkerframework.dataflow.qual.Pure;
|
|||||||
}
|
}
|
||||||
|
|
||||||
audioProcessingPipeline = new AudioProcessingPipeline(audioProcessors);
|
audioProcessingPipeline = new AudioProcessingPipeline(audioProcessors);
|
||||||
|
// TODO(b/267301878): Once decoder format propagated, remove setting default PCM encoding.
|
||||||
AudioFormat pipelineInputAudioFormat =
|
AudioFormat pipelineInputAudioFormat =
|
||||||
new AudioFormat(
|
new AudioFormat(
|
||||||
firstInputFormat.sampleRate,
|
firstInputFormat.sampleRate,
|
||||||
firstInputFormat.channelCount,
|
firstInputFormat.channelCount,
|
||||||
// The decoder uses ENCODING_PCM_16BIT by default.
|
firstInputFormat.pcmEncoding != Format.NO_VALUE
|
||||||
// https://developer.android.com/reference/android/media/MediaCodec#raw-audio-buffers
|
? firstInputFormat.pcmEncoding
|
||||||
C.ENCODING_PCM_16BIT);
|
: DEFAULT_PCM_ENCODING);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
encoderInputAudioFormat = audioProcessingPipeline.configure(pipelineInputAudioFormat);
|
encoderInputAudioFormat = audioProcessingPipeline.configure(pipelineInputAudioFormat);
|
||||||
@ -117,6 +119,7 @@ import org.checkerframework.dataflow.qual.Pure;
|
|||||||
: checkNotNull(firstInputFormat.sampleMimeType))
|
: checkNotNull(firstInputFormat.sampleMimeType))
|
||||||
.setSampleRate(encoderInputAudioFormat.sampleRate)
|
.setSampleRate(encoderInputAudioFormat.sampleRate)
|
||||||
.setChannelCount(encoderInputAudioFormat.channelCount)
|
.setChannelCount(encoderInputAudioFormat.channelCount)
|
||||||
|
.setPcmEncoding(encoderInputAudioFormat.encoding)
|
||||||
.setAverageBitrate(DEFAULT_ENCODER_BITRATE)
|
.setAverageBitrate(DEFAULT_ENCODER_BITRATE)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
@ -52,13 +52,12 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
/** A default {@link Codec} implementation that uses {@link MediaCodec}. */
|
/** A default {@link Codec} implementation that uses {@link MediaCodec}. */
|
||||||
@UnstableApi
|
@UnstableApi
|
||||||
public final class DefaultCodec implements Codec {
|
public final class DefaultCodec implements Codec {
|
||||||
|
// MediaCodec decoders output 16 bit PCM, unless configured to output PCM float.
|
||||||
|
// https://developer.android.com/reference/android/media/MediaCodec#raw-audio-buffers.
|
||||||
|
public static final int DEFAULT_PCM_ENCODING = C.ENCODING_PCM_16BIT;
|
||||||
|
|
||||||
private static final String TAG = "DefaultCodec";
|
private static final String TAG = "DefaultCodec";
|
||||||
|
|
||||||
// MediaCodec decoders always output 16 bit PCM, unless configured to output PCM float.
|
|
||||||
// https://developer.android.com/reference/android/media/MediaCodec#raw-audio-buffers.
|
|
||||||
private static final int MEDIA_CODEC_PCM_ENCODING = C.ENCODING_PCM_16BIT;
|
|
||||||
|
|
||||||
private final BufferInfo outputBufferInfo;
|
private final BufferInfo outputBufferInfo;
|
||||||
/** The {@link MediaFormat} used to configure the underlying {@link MediaCodec}. */
|
/** The {@link MediaFormat} used to configure the underlying {@link MediaCodec}. */
|
||||||
private final MediaFormat configurationMediaFormat;
|
private final MediaFormat configurationMediaFormat;
|
||||||
@ -325,7 +324,7 @@ public final class DefaultCodec implements Codec {
|
|||||||
}
|
}
|
||||||
if (outputBufferIndex < 0) {
|
if (outputBufferIndex < 0) {
|
||||||
if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
|
if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
|
||||||
outputFormat = convertToFormat(mediaCodec.getOutputFormat());
|
outputFormat = convertToFormat(mediaCodec.getOutputFormat(), isDecoder);
|
||||||
ColorInfo expectedColorInfo =
|
ColorInfo expectedColorInfo =
|
||||||
isSdrToneMappingEnabled(configurationMediaFormat)
|
isSdrToneMappingEnabled(configurationMediaFormat)
|
||||||
? ColorInfo.SDR_BT709_LIMITED
|
? ColorInfo.SDR_BT709_LIMITED
|
||||||
@ -402,7 +401,7 @@ public final class DefaultCodec implements Codec {
|
|||||||
return transfer1 == transfer2;
|
return transfer1 == transfer2;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Format convertToFormat(MediaFormat mediaFormat) {
|
private static Format convertToFormat(MediaFormat mediaFormat, boolean isDecoder) {
|
||||||
ImmutableList.Builder<byte[]> csdBuffers = new ImmutableList.Builder<>();
|
ImmutableList.Builder<byte[]> csdBuffers = new ImmutableList.Builder<>();
|
||||||
int csdIndex = 0;
|
int csdIndex = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -424,12 +423,22 @@ public final class DefaultCodec implements Codec {
|
|||||||
.setHeight(mediaFormat.getInteger(MediaFormat.KEY_HEIGHT))
|
.setHeight(mediaFormat.getInteger(MediaFormat.KEY_HEIGHT))
|
||||||
.setColorInfo(MediaFormatUtil.getColorInfo(mediaFormat));
|
.setColorInfo(MediaFormatUtil.getColorInfo(mediaFormat));
|
||||||
} else if (MimeTypes.isAudio(mimeType)) {
|
} else if (MimeTypes.isAudio(mimeType)) {
|
||||||
// TODO(b/178685617): Only set the PCM encoding for audio/raw, once we have a way to
|
|
||||||
// simulate more realistic codec input/output formats in tests.
|
|
||||||
formatBuilder
|
formatBuilder
|
||||||
.setChannelCount(mediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT))
|
.setChannelCount(mediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT))
|
||||||
.setSampleRate(mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE))
|
.setSampleRate(mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE));
|
||||||
.setPcmEncoding(MEDIA_CODEC_PCM_ENCODING);
|
|
||||||
|
if (SDK_INT >= 24 && mediaFormat.containsKey(MediaFormat.KEY_PCM_ENCODING)) {
|
||||||
|
formatBuilder.setPcmEncoding(mediaFormat.getInteger(MediaFormat.KEY_PCM_ENCODING));
|
||||||
|
} else if (isDecoder) {
|
||||||
|
// TODO(b/178685617): Restrict this to only set the PCM encoding for audio/raw once we have
|
||||||
|
// a way to simulate more realistic codec input/output formats in tests.
|
||||||
|
|
||||||
|
// With Robolectric, codecs do not actually encode/decode. The format of buffers is passed
|
||||||
|
// through. However downstream components need to know the PCM encoding of the data being
|
||||||
|
// output, so if a decoder is not outputting raw audio, we need to set the PCM
|
||||||
|
// encoding to the default.
|
||||||
|
formatBuilder.setPcmEncoding(DEFAULT_PCM_ENCODING);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return formatBuilder.build();
|
return formatBuilder.build();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user