Replace MediaFormat with Format class in muxer module
PiperOrigin-RevId: 526655859
This commit is contained in:
parent
f1d9a0a819
commit
b11dd106ae
@ -25,6 +25,7 @@ import androidx.media3.common.C;
|
|||||||
import androidx.media3.common.ColorInfo;
|
import androidx.media3.common.ColorInfo;
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -65,6 +66,70 @@ public final class MediaFormatUtil {
|
|||||||
|
|
||||||
private static final int MAX_POWER_OF_TWO_INT = 1 << 30;
|
private static final int MAX_POWER_OF_TWO_INT = 1 << 30;
|
||||||
|
|
||||||
|
/** Returns a {@link Format} representing the given {@link MediaFormat}. */
|
||||||
|
@SuppressLint("InlinedApi") // Inlined MediaFormat keys.
|
||||||
|
public static Format createFormatFromMediaFormat(MediaFormat mediaFormat) {
|
||||||
|
Format.Builder formatBuilder =
|
||||||
|
new Format.Builder()
|
||||||
|
.setSampleMimeType(mediaFormat.getString(MediaFormat.KEY_MIME))
|
||||||
|
.setLanguage(mediaFormat.getString(MediaFormat.KEY_LANGUAGE))
|
||||||
|
.setPeakBitrate(
|
||||||
|
getInteger(mediaFormat, KEY_MAX_BIT_RATE, /* defaultValue= */ Format.NO_VALUE))
|
||||||
|
.setAverageBitrate(
|
||||||
|
getInteger(
|
||||||
|
mediaFormat, MediaFormat.KEY_BIT_RATE, /* defaultValue= */ Format.NO_VALUE))
|
||||||
|
.setCodecs(mediaFormat.getString(MediaFormat.KEY_CODECS_STRING))
|
||||||
|
.setFrameRate(getFrameRate(mediaFormat, /* defaultValue= */ Format.NO_VALUE))
|
||||||
|
.setWidth(
|
||||||
|
getInteger(mediaFormat, MediaFormat.KEY_WIDTH, /* defaultValue= */ Format.NO_VALUE))
|
||||||
|
.setHeight(
|
||||||
|
getInteger(
|
||||||
|
mediaFormat, MediaFormat.KEY_HEIGHT, /* defaultValue= */ Format.NO_VALUE))
|
||||||
|
.setPixelWidthHeightRatio(
|
||||||
|
getPixelWidthHeightRatio(mediaFormat, /* defaultValue= */ 1.0f))
|
||||||
|
.setMaxInputSize(
|
||||||
|
getInteger(
|
||||||
|
mediaFormat,
|
||||||
|
MediaFormat.KEY_MAX_INPUT_SIZE,
|
||||||
|
/* defaultValue= */ Format.NO_VALUE))
|
||||||
|
.setRotationDegrees(
|
||||||
|
getInteger(mediaFormat, MediaFormat.KEY_ROTATION, /* defaultValue= */ 0))
|
||||||
|
// TODO(b/278101856): Disallow invalid values after confirming.
|
||||||
|
.setColorInfo(getColorInfo(mediaFormat, /* allowInvalidValues= */ true))
|
||||||
|
.setSampleRate(
|
||||||
|
getInteger(
|
||||||
|
mediaFormat, MediaFormat.KEY_SAMPLE_RATE, /* defaultValue= */ Format.NO_VALUE))
|
||||||
|
.setChannelCount(
|
||||||
|
getInteger(
|
||||||
|
mediaFormat,
|
||||||
|
MediaFormat.KEY_CHANNEL_COUNT,
|
||||||
|
/* defaultValue= */ Format.NO_VALUE))
|
||||||
|
.setPcmEncoding(
|
||||||
|
getInteger(
|
||||||
|
mediaFormat,
|
||||||
|
MediaFormat.KEY_PCM_ENCODING,
|
||||||
|
/* defaultValue= */ Format.NO_VALUE));
|
||||||
|
|
||||||
|
ImmutableList.Builder<byte[]> csdBuffers = new ImmutableList.Builder<>();
|
||||||
|
int csdIndex = 0;
|
||||||
|
while (true) {
|
||||||
|
@Nullable ByteBuffer csdByteBuffer = mediaFormat.getByteBuffer("csd-" + csdIndex);
|
||||||
|
if (csdByteBuffer == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
byte[] csdBufferData = new byte[csdByteBuffer.remaining()];
|
||||||
|
csdByteBuffer.get(csdBufferData);
|
||||||
|
csdByteBuffer.rewind();
|
||||||
|
|
||||||
|
csdBuffers.add(csdBufferData);
|
||||||
|
csdIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
formatBuilder.setInitializationData(csdBuffers.build());
|
||||||
|
|
||||||
|
return formatBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@link MediaFormat} representing the given ExoPlayer {@link Format}.
|
* Returns a {@link MediaFormat} representing the given ExoPlayer {@link Format}.
|
||||||
*
|
*
|
||||||
@ -203,6 +268,13 @@ public final class MediaFormatUtil {
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public static ColorInfo getColorInfo(MediaFormat mediaFormat) {
|
public static ColorInfo getColorInfo(MediaFormat mediaFormat) {
|
||||||
|
return getColorInfo(mediaFormat, /* allowInvalidValues= */ false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal methods.
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static ColorInfo getColorInfo(MediaFormat mediaFormat, boolean allowInvalidValues) {
|
||||||
if (SDK_INT < 24) {
|
if (SDK_INT < 24) {
|
||||||
// MediaFormat KEY_COLOR_TRANSFER and other KEY_COLOR values available from API 24.
|
// MediaFormat KEY_COLOR_TRANSFER and other KEY_COLOR values available from API 24.
|
||||||
return null;
|
return null;
|
||||||
@ -220,6 +292,8 @@ public final class MediaFormatUtil {
|
|||||||
@Nullable
|
@Nullable
|
||||||
byte[] hdrStaticInfo =
|
byte[] hdrStaticInfo =
|
||||||
hdrStaticInfoByteBuffer != null ? getArray(hdrStaticInfoByteBuffer) : null;
|
hdrStaticInfoByteBuffer != null ? getArray(hdrStaticInfoByteBuffer) : null;
|
||||||
|
|
||||||
|
if (!allowInvalidValues) {
|
||||||
// Some devices may produce invalid values from MediaFormat#getInteger.
|
// Some devices may produce invalid values from MediaFormat#getInteger.
|
||||||
// See b/239435670 for more information.
|
// See b/239435670 for more information.
|
||||||
if (!isValidColorSpace(colorSpace)) {
|
if (!isValidColorSpace(colorSpace)) {
|
||||||
@ -231,6 +305,7 @@ public final class MediaFormatUtil {
|
|||||||
if (!isValidColorTransfer(colorTransfer)) {
|
if (!isValidColorTransfer(colorTransfer)) {
|
||||||
colorTransfer = Format.NO_VALUE;
|
colorTransfer = Format.NO_VALUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (colorSpace != Format.NO_VALUE
|
if (colorSpace != Format.NO_VALUE
|
||||||
|| colorRange != Format.NO_VALUE
|
|| colorRange != Format.NO_VALUE
|
||||||
@ -246,16 +321,47 @@ public final class MediaFormatUtil {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Supports {@link MediaFormat#getInteger(String, int)} for {@code API < 29}. */
|
||||||
* Provides the same functionality as {@link MediaFormat#getInteger(String, int)}.
|
|
||||||
*
|
|
||||||
* <p>{@link MediaFormat#getInteger(String, int)} is only available from API 29. This convenience
|
|
||||||
* method provides support on lower API versions.
|
|
||||||
*/
|
|
||||||
public static int getInteger(MediaFormat mediaFormat, String name, int defaultValue) {
|
public static int getInteger(MediaFormat mediaFormat, String name, int defaultValue) {
|
||||||
return mediaFormat.containsKey(name) ? mediaFormat.getInteger(name) : defaultValue;
|
return mediaFormat.containsKey(name) ? mediaFormat.getInteger(name) : defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Supports {@link MediaFormat#getFloat(String, float)} for {@code API < 29}. */
|
||||||
|
public static float getFloat(MediaFormat mediaFormat, String name, float defaultValue) {
|
||||||
|
return mediaFormat.containsKey(name) ? mediaFormat.getFloat(name) : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the frame rate from a {@link MediaFormat}.
|
||||||
|
*
|
||||||
|
* <p>The {@link MediaFormat#KEY_FRAME_RATE} can have both integer and float value so it returns
|
||||||
|
* which ever value is set.
|
||||||
|
*/
|
||||||
|
private static float getFrameRate(MediaFormat mediaFormat, float defaultValue) {
|
||||||
|
float frameRate = defaultValue;
|
||||||
|
if (mediaFormat.containsKey(MediaFormat.KEY_FRAME_RATE)) {
|
||||||
|
try {
|
||||||
|
frameRate = mediaFormat.getFloat(MediaFormat.KEY_FRAME_RATE);
|
||||||
|
} catch (ClassCastException ex) {
|
||||||
|
frameRate = mediaFormat.getInteger(MediaFormat.KEY_FRAME_RATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return frameRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the ratio between a pixel's width and height for a {@link MediaFormat}. */
|
||||||
|
// Inlined MediaFormat.KEY_PIXEL_ASPECT_RATIO_WIDTH and MediaFormat.KEY_PIXEL_ASPECT_RATIO_HEIGHT.
|
||||||
|
@SuppressLint("InlinedApi")
|
||||||
|
private static float getPixelWidthHeightRatio(MediaFormat mediaFormat, float defaultValue) {
|
||||||
|
if (mediaFormat.containsKey(MediaFormat.KEY_PIXEL_ASPECT_RATIO_WIDTH)
|
||||||
|
&& mediaFormat.containsKey(MediaFormat.KEY_PIXEL_ASPECT_RATIO_HEIGHT)) {
|
||||||
|
return (float) mediaFormat.getInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_WIDTH)
|
||||||
|
/ (float) mediaFormat.getInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_HEIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] getArray(ByteBuffer byteBuffer) {
|
public static byte[] getArray(ByteBuffer byteBuffer) {
|
||||||
byte[] array = new byte[byteBuffer.remaining()];
|
byte[] array = new byte[byteBuffer.remaining()];
|
||||||
byteBuffer.get(array);
|
byteBuffer.get(array);
|
||||||
|
@ -24,12 +24,96 @@ import androidx.media3.common.Format;
|
|||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
/** Unit tests for {@link MediaFormatUtil}. */
|
/** Unit tests for {@link MediaFormatUtil}. */
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
public class MediaFormatUtilTest {
|
public class MediaFormatUtilTest {
|
||||||
|
@Test
|
||||||
|
public void createFormatFromMediaFormat_withEmptyMap_generatesExpectedFormat() {
|
||||||
|
Format format = MediaFormatUtil.createFormatFromMediaFormat(new MediaFormat());
|
||||||
|
|
||||||
|
assertThat(format.sampleMimeType).isNull();
|
||||||
|
assertThat(format.language).isNull();
|
||||||
|
assertThat(format.peakBitrate).isEqualTo(Format.NO_VALUE);
|
||||||
|
assertThat(format.averageBitrate).isEqualTo(Format.NO_VALUE);
|
||||||
|
assertThat(format.codecs).isNull();
|
||||||
|
assertThat(format.frameRate).isEqualTo(Format.NO_VALUE);
|
||||||
|
assertThat(format.width).isEqualTo(Format.NO_VALUE);
|
||||||
|
assertThat(format.height).isEqualTo(Format.NO_VALUE);
|
||||||
|
assertThat(format.pixelWidthHeightRatio).isEqualTo(1.0f);
|
||||||
|
assertThat(format.maxInputSize).isEqualTo(Format.NO_VALUE);
|
||||||
|
assertThat(format.rotationDegrees).isEqualTo(0);
|
||||||
|
assertThat(format.colorInfo).isNull();
|
||||||
|
assertThat(format.sampleRate).isEqualTo(Format.NO_VALUE);
|
||||||
|
assertThat(format.channelCount).isEqualTo(Format.NO_VALUE);
|
||||||
|
assertThat(format.pcmEncoding).isEqualTo(Format.NO_VALUE);
|
||||||
|
assertThat(format.initializationData).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createFormatFromMediaFormat_withPopulatedMap_generatesExpectedFormat() {
|
||||||
|
MediaFormat mediaFormat = new MediaFormat();
|
||||||
|
mediaFormat.setString(MediaFormat.KEY_MIME, MimeTypes.VIDEO_H264);
|
||||||
|
mediaFormat.setString(MediaFormat.KEY_LANGUAGE, "eng");
|
||||||
|
mediaFormat.setInteger(MediaFormatUtil.KEY_MAX_BIT_RATE, 128000);
|
||||||
|
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 128000);
|
||||||
|
mediaFormat.setString(MediaFormat.KEY_CODECS_STRING, "avc.123");
|
||||||
|
mediaFormat.setFloat(MediaFormat.KEY_FRAME_RATE, 4);
|
||||||
|
mediaFormat.setInteger(MediaFormat.KEY_WIDTH, 10);
|
||||||
|
mediaFormat.setInteger(MediaFormat.KEY_HEIGHT, 8);
|
||||||
|
mediaFormat.setInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_WIDTH, 15);
|
||||||
|
mediaFormat.setInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_HEIGHT, 5);
|
||||||
|
mediaFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 10);
|
||||||
|
mediaFormat.setInteger(MediaFormat.KEY_ROTATION, 90);
|
||||||
|
mediaFormat.setInteger(MediaFormat.KEY_COLOR_STANDARD, C.COLOR_SPACE_BT601);
|
||||||
|
mediaFormat.setInteger(MediaFormat.KEY_COLOR_TRANSFER, C.COLOR_TRANSFER_HLG);
|
||||||
|
mediaFormat.setInteger(MediaFormat.KEY_COLOR_RANGE, C.COLOR_RANGE_FULL);
|
||||||
|
mediaFormat.setByteBuffer(MediaFormat.KEY_HDR_STATIC_INFO, ByteBuffer.wrap(new byte[] {3}));
|
||||||
|
mediaFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE, 11);
|
||||||
|
mediaFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 2);
|
||||||
|
mediaFormat.setInteger(MediaFormat.KEY_PCM_ENCODING, C.ENCODING_PCM_8BIT);
|
||||||
|
mediaFormat.setByteBuffer("csd-0", ByteBuffer.wrap(new byte[] {7}));
|
||||||
|
mediaFormat.setByteBuffer("csd-1", ByteBuffer.wrap(new byte[] {10}));
|
||||||
|
|
||||||
|
Format format = MediaFormatUtil.createFormatFromMediaFormat(mediaFormat);
|
||||||
|
|
||||||
|
assertThat(format.sampleMimeType).isEqualTo(mediaFormat.getString(MediaFormat.KEY_MIME));
|
||||||
|
// Format stores normalized language code.
|
||||||
|
assertThat(format.language)
|
||||||
|
.isEqualTo(Util.normalizeLanguageCode(mediaFormat.getString(MediaFormat.KEY_LANGUAGE)));
|
||||||
|
assertThat(format.peakBitrate)
|
||||||
|
.isEqualTo(mediaFormat.getInteger(MediaFormatUtil.KEY_MAX_BIT_RATE));
|
||||||
|
assertThat(format.averageBitrate).isEqualTo(mediaFormat.getInteger(MediaFormat.KEY_BIT_RATE));
|
||||||
|
assertThat(format.codecs).isEqualTo(mediaFormat.getString(MediaFormat.KEY_CODECS_STRING));
|
||||||
|
assertThat(format.frameRate).isEqualTo(mediaFormat.getFloat(MediaFormat.KEY_FRAME_RATE));
|
||||||
|
assertThat(format.width).isEqualTo(mediaFormat.getInteger(MediaFormat.KEY_WIDTH));
|
||||||
|
assertThat(format.height).isEqualTo(mediaFormat.getInteger(MediaFormat.KEY_HEIGHT));
|
||||||
|
// Ratio of MediaFormat.KEY_PIXEL_ASPECT_RATIO_WIDTH (15) and
|
||||||
|
// MediaFormat.KEY_PIXEL_ASPECT_RATIO_HEIGHT (5).
|
||||||
|
assertThat(format.pixelWidthHeightRatio).isEqualTo(3.0f);
|
||||||
|
assertThat(format.maxInputSize)
|
||||||
|
.isEqualTo(mediaFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE));
|
||||||
|
assertThat(format.rotationDegrees).isEqualTo(mediaFormat.getInteger(MediaFormat.KEY_ROTATION));
|
||||||
|
assertThat(format.colorInfo.colorSpace)
|
||||||
|
.isEqualTo(mediaFormat.getInteger(MediaFormat.KEY_COLOR_STANDARD));
|
||||||
|
assertThat(format.colorInfo.colorTransfer)
|
||||||
|
.isEqualTo(mediaFormat.getInteger(MediaFormat.KEY_COLOR_TRANSFER));
|
||||||
|
assertThat(format.colorInfo.colorRange)
|
||||||
|
.isEqualTo(mediaFormat.getInteger(MediaFormat.KEY_COLOR_RANGE));
|
||||||
|
assertThat(format.colorInfo.hdrStaticInfo)
|
||||||
|
.isEqualTo(mediaFormat.getByteBuffer(MediaFormat.KEY_HDR_STATIC_INFO).array());
|
||||||
|
assertThat(format.sampleRate).isEqualTo(mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE));
|
||||||
|
assertThat(format.channelCount)
|
||||||
|
.isEqualTo(mediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT));
|
||||||
|
assertThat(format.pcmEncoding).isEqualTo(mediaFormat.getInteger(MediaFormat.KEY_PCM_ENCODING));
|
||||||
|
assertThat(format.initializationData.get(0))
|
||||||
|
.isEqualTo(mediaFormat.getByteBuffer("csd-0").array());
|
||||||
|
assertThat(format.initializationData.get(1))
|
||||||
|
.isEqualTo(mediaFormat.getByteBuffer("csd-1").array());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createMediaFormatFromFormat_withEmptyFormat_generatesExpectedEntries() {
|
public void createMediaFormatFromFormat_withEmptyFormat_generatesExpectedEntries() {
|
||||||
@ -146,7 +230,7 @@ public class MediaFormatUtilTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createMediaFormatFromFormat_withPcmEncoding_setsCustomPcmEncodingEntry() {
|
public void createMediaFormatFromFormat_withCustomPcmEncoding_setsCustomPcmEncodingEntry() {
|
||||||
Format format = new Format.Builder().setPcmEncoding(C.ENCODING_PCM_16BIT_BIG_ENDIAN).build();
|
Format format = new Format.Builder().setPcmEncoding(C.ENCODING_PCM_16BIT_BIG_ENDIAN).build();
|
||||||
MediaFormat mediaFormat = MediaFormatUtil.createMediaFormatFromFormat(format);
|
MediaFormat mediaFormat = MediaFormatUtil.createMediaFormatFromFormat(format);
|
||||||
assertThat(mediaFormat.getInteger(MediaFormatUtil.KEY_PCM_ENCODING_EXTENDED))
|
assertThat(mediaFormat.getInteger(MediaFormatUtil.KEY_PCM_ENCODING_EXTENDED))
|
||||||
|
@ -10,6 +10,7 @@ format 0:
|
|||||||
data = length 30, hash F6F3D010
|
data = length 30, hash F6F3D010
|
||||||
data = length 10, hash 7A0D0F2B
|
data = length 10, hash 7A0D0F2B
|
||||||
format 1:
|
format 1:
|
||||||
|
averageBitrate = 131072
|
||||||
sampleMimeType = audio/mp4a-latm
|
sampleMimeType = audio/mp4a-latm
|
||||||
channelCount = 1
|
channelCount = 1
|
||||||
sampleRate = 44100
|
sampleRate = 44100
|
||||||
|
@ -12,6 +12,7 @@ format 0:
|
|||||||
data = length 10, hash 7A0D0F2B
|
data = length 10, hash 7A0D0F2B
|
||||||
container metadata = entries=[xyz: latitude=40.68, longitude=-74.5]
|
container metadata = entries=[xyz: latitude=40.68, longitude=-74.5]
|
||||||
format 1:
|
format 1:
|
||||||
|
averageBitrate = 131072
|
||||||
sampleMimeType = audio/mp4a-latm
|
sampleMimeType = audio/mp4a-latm
|
||||||
channelCount = 1
|
channelCount = 1
|
||||||
sampleRate = 48000
|
sampleRate = 48000
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
format 0:
|
format 0:
|
||||||
|
averageBitrate = 131072
|
||||||
sampleMimeType = audio/mp4a-latm
|
sampleMimeType = audio/mp4a-latm
|
||||||
channelCount = 1
|
channelCount = 1
|
||||||
sampleRate = 44100
|
sampleRate = 44100
|
||||||
|
@ -12,6 +12,7 @@ format 0:
|
|||||||
data = length 10, hash 7A0D0F2B
|
data = length 10, hash 7A0D0F2B
|
||||||
container metadata = entries=[xyz: latitude=40.68, longitude=-74.5]
|
container metadata = entries=[xyz: latitude=40.68, longitude=-74.5]
|
||||||
format 1:
|
format 1:
|
||||||
|
averageBitrate = 131072
|
||||||
sampleMimeType = audio/mp4a-latm
|
sampleMimeType = audio/mp4a-latm
|
||||||
channelCount = 2
|
channelCount = 2
|
||||||
sampleRate = 44100
|
sampleRate = 44100
|
||||||
|
@ -12,6 +12,7 @@ format 0:
|
|||||||
data = length 10, hash 7A0D0F2B
|
data = length 10, hash 7A0D0F2B
|
||||||
container metadata = entries=[xyz: latitude=40.68, longitude=-74.5]
|
container metadata = entries=[xyz: latitude=40.68, longitude=-74.5]
|
||||||
format 1:
|
format 1:
|
||||||
|
averageBitrate = 131072
|
||||||
sampleMimeType = audio/mp4a-latm
|
sampleMimeType = audio/mp4a-latm
|
||||||
channelCount = 2
|
channelCount = 2
|
||||||
sampleRate = 44100
|
sampleRate = 44100
|
||||||
|
@ -12,6 +12,7 @@ format 0:
|
|||||||
data = length 10, hash 7A0D0F2B
|
data = length 10, hash 7A0D0F2B
|
||||||
container metadata = entries=[xyz: latitude=40.68, longitude=-74.5]
|
container metadata = entries=[xyz: latitude=40.68, longitude=-74.5]
|
||||||
format 1:
|
format 1:
|
||||||
|
averageBitrate = 131072
|
||||||
sampleMimeType = audio/mp4a-latm
|
sampleMimeType = audio/mp4a-latm
|
||||||
channelCount = 2
|
channelCount = 2
|
||||||
sampleRate = 44100
|
sampleRate = 44100
|
||||||
|
@ -15,6 +15,7 @@ format 0:
|
|||||||
data = length 29, hash 4746B5D9
|
data = length 29, hash 4746B5D9
|
||||||
data = length 10, hash 7A0D0F2B
|
data = length 10, hash 7A0D0F2B
|
||||||
format 1:
|
format 1:
|
||||||
|
averageBitrate = 131072
|
||||||
sampleMimeType = audio/mp4a-latm
|
sampleMimeType = audio/mp4a-latm
|
||||||
channelCount = 2
|
channelCount = 2
|
||||||
sampleRate = 44100
|
sampleRate = 44100
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
format 0:
|
format 0:
|
||||||
|
averageBitrate = 131072
|
||||||
sampleMimeType = audio/mp4a-latm
|
sampleMimeType = audio/mp4a-latm
|
||||||
channelCount = 6
|
channelCount = 6
|
||||||
sampleRate = 48000
|
sampleRate = 48000
|
||||||
|
@ -12,6 +12,7 @@ format 0:
|
|||||||
data = length 10, hash 7A0D0F2B
|
data = length 10, hash 7A0D0F2B
|
||||||
container metadata = entries=[mdta: key=com.android.capture.fps, value=43700000, smta: captureFrameRate=240.0, svcTemporalLayerCount=4, SlowMotion: segments=[Segment: startTimeMs=88, endTimeMs=879, speedDivisor=2, Segment: startTimeMs=1255, endTimeMs=1970, speedDivisor=8]]
|
container metadata = entries=[mdta: key=com.android.capture.fps, value=43700000, smta: captureFrameRate=240.0, svcTemporalLayerCount=4, SlowMotion: segments=[Segment: startTimeMs=88, endTimeMs=879, speedDivisor=2, Segment: startTimeMs=1255, endTimeMs=1970, speedDivisor=8]]
|
||||||
format 1:
|
format 1:
|
||||||
|
averageBitrate = 131072
|
||||||
sampleMimeType = audio/mp4a-latm
|
sampleMimeType = audio/mp4a-latm
|
||||||
channelCount = 2
|
channelCount = 2
|
||||||
sampleRate = 12000
|
sampleRate = 12000
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
format 0:
|
format 0:
|
||||||
|
averageBitrate = 131072
|
||||||
sampleMimeType = audio/mp4a-latm
|
sampleMimeType = audio/mp4a-latm
|
||||||
channelCount = 1
|
channelCount = 1
|
||||||
sampleRate = 44100
|
sampleRate = 44100
|
||||||
|
@ -41,7 +41,6 @@ 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.common.util.Util;
|
||||||
import androidx.media3.decoder.DecoderInputBuffer;
|
import androidx.media3.decoder.DecoderInputBuffer;
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
|
import org.checkerframework.checker.initialization.qual.UnknownInitialization;
|
||||||
@ -392,34 +391,9 @@ public final class DefaultCodec implements Codec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Format convertToFormat(MediaFormat mediaFormat, boolean isDecoder) {
|
private static Format convertToFormat(MediaFormat mediaFormat, boolean isDecoder) {
|
||||||
ImmutableList.Builder<byte[]> csdBuffers = new ImmutableList.Builder<>();
|
|
||||||
int csdIndex = 0;
|
|
||||||
while (true) {
|
|
||||||
@Nullable ByteBuffer csdByteBuffer = mediaFormat.getByteBuffer("csd-" + csdIndex);
|
|
||||||
if (csdByteBuffer == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
byte[] csdBufferData = new byte[csdByteBuffer.remaining()];
|
|
||||||
csdByteBuffer.get(csdBufferData);
|
|
||||||
csdBuffers.add(csdBufferData);
|
|
||||||
csdIndex++;
|
|
||||||
}
|
|
||||||
String mimeType = mediaFormat.getString(MediaFormat.KEY_MIME);
|
|
||||||
Format.Builder formatBuilder =
|
Format.Builder formatBuilder =
|
||||||
new Format.Builder().setSampleMimeType(mimeType).setInitializationData(csdBuffers.build());
|
MediaFormatUtil.createFormatFromMediaFormat(mediaFormat).buildUpon();
|
||||||
if (MimeTypes.isVideo(mimeType)) {
|
if (isDecoder) {
|
||||||
formatBuilder
|
|
||||||
.setWidth(mediaFormat.getInteger(MediaFormat.KEY_WIDTH))
|
|
||||||
.setHeight(mediaFormat.getInteger(MediaFormat.KEY_HEIGHT))
|
|
||||||
.setColorInfo(MediaFormatUtil.getColorInfo(mediaFormat));
|
|
||||||
} else if (MimeTypes.isAudio(mimeType)) {
|
|
||||||
formatBuilder
|
|
||||||
.setChannelCount(mediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT))
|
|
||||||
.setSampleRate(mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE));
|
|
||||||
|
|
||||||
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
|
// 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.
|
// a way to simulate more realistic codec input/output formats in tests.
|
||||||
|
|
||||||
@ -429,7 +403,6 @@ public final class DefaultCodec implements Codec {
|
|||||||
// encoding to the default.
|
// encoding to the default.
|
||||||
formatBuilder.setPcmEncoding(DEFAULT_PCM_ENCODING);
|
formatBuilder.setPcmEncoding(DEFAULT_PCM_ENCODING);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return formatBuilder.build();
|
return formatBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user