mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Refactor ShadowMediaCodec to be used for transcoding cases
This is a step towards unifying ShadowMediaCodecConfig for ExoPlayer and Transcoding tests. This change includes extracting encoder/decoder configurtion logic to a static method that can be called by `ShadowMediaCodecConfig.CodecImpl#configure()` and `TestUtil#addCodec()`. This is a non-functional refactor. PiperOrigin-RevId: 734137675
This commit is contained in:
parent
c95516f0ab
commit
c030e49dd6
@ -63,6 +63,49 @@ public final class ShadowMediaCodecConfig extends ExternalResource {
|
|||||||
supportedMimeTypes = new HashSet<>(mimeTypes);
|
supportedMimeTypes = new HashSet<>(mimeTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures a shadow MediaCodec.
|
||||||
|
*
|
||||||
|
* @param codecName The name of the codec.
|
||||||
|
* @param mimeType The MIME type of the codec.
|
||||||
|
* @param isEncoder Whether the codec is an encoder or a decoder.
|
||||||
|
* @param profileLevels A list of profiles and levels supported by the codec.
|
||||||
|
* @param colorFormats A list of color formats supported by the codec.
|
||||||
|
* @param codecConfig The {@link ShadowMediaCodec.CodecConfig} for the codec, specifying its
|
||||||
|
* behavior.
|
||||||
|
*/
|
||||||
|
public static void configureShadowMediaCodec(
|
||||||
|
String codecName,
|
||||||
|
String mimeType,
|
||||||
|
boolean isEncoder,
|
||||||
|
ImmutableList<CodecProfileLevel> profileLevels,
|
||||||
|
ImmutableList<Integer> colorFormats,
|
||||||
|
ShadowMediaCodec.CodecConfig codecConfig) {
|
||||||
|
MediaFormat mediaFormat = new MediaFormat();
|
||||||
|
mediaFormat.setString(MediaFormat.KEY_MIME, mimeType);
|
||||||
|
MediaCodecInfoBuilder.CodecCapabilitiesBuilder capabilities =
|
||||||
|
MediaCodecInfoBuilder.CodecCapabilitiesBuilder.newBuilder()
|
||||||
|
.setMediaFormat(mediaFormat)
|
||||||
|
.setIsEncoder(isEncoder);
|
||||||
|
if (!profileLevels.isEmpty()) {
|
||||||
|
capabilities.setProfileLevels(profileLevels.toArray(new CodecProfileLevel[0]));
|
||||||
|
}
|
||||||
|
if (!colorFormats.isEmpty()) {
|
||||||
|
capabilities.setColorFormats(Ints.toArray(colorFormats));
|
||||||
|
}
|
||||||
|
ShadowMediaCodecList.addCodec(
|
||||||
|
MediaCodecInfoBuilder.newBuilder()
|
||||||
|
.setName(codecName)
|
||||||
|
.setIsEncoder(isEncoder)
|
||||||
|
.setCapabilities(capabilities.build())
|
||||||
|
.build());
|
||||||
|
if (isEncoder) {
|
||||||
|
ShadowMediaCodec.addEncoder(codecName, codecConfig);
|
||||||
|
} else {
|
||||||
|
ShadowMediaCodec.addDecoder(codecName, codecConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void addSupportedMimeTypes(String... mimeTypes) {
|
public void addSupportedMimeTypes(String... mimeTypes) {
|
||||||
for (String mimeType : mimeTypes) {
|
for (String mimeType : mimeTypes) {
|
||||||
checkState(!supportedMimeTypes.contains(mimeType), "MIME type already added: " + mimeType);
|
checkState(!supportedMimeTypes.contains(mimeType), "MIME type already added: " + mimeType);
|
||||||
@ -231,29 +274,19 @@ public final class ShadowMediaCodecConfig extends ExternalResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void configure() {
|
public void configure() {
|
||||||
MediaFormat mediaFormat = new MediaFormat();
|
|
||||||
mediaFormat.setString(MediaFormat.KEY_MIME, mimeType);
|
|
||||||
MediaCodecInfoBuilder.CodecCapabilitiesBuilder capabilities =
|
|
||||||
MediaCodecInfoBuilder.CodecCapabilitiesBuilder.newBuilder().setMediaFormat(mediaFormat);
|
|
||||||
if (!profileLevels.isEmpty()) {
|
|
||||||
capabilities.setProfileLevels(
|
|
||||||
profileLevels.toArray(new MediaCodecInfo.CodecProfileLevel[0]));
|
|
||||||
}
|
|
||||||
if (!colorFormats.isEmpty()) {
|
|
||||||
capabilities.setColorFormats(Ints.toArray(colorFormats));
|
|
||||||
}
|
|
||||||
ShadowMediaCodecList.addCodec(
|
|
||||||
MediaCodecInfoBuilder.newBuilder()
|
|
||||||
.setName(codecName)
|
|
||||||
.setCapabilities(capabilities.build())
|
|
||||||
.build());
|
|
||||||
// TODO: Update ShadowMediaCodec to consider the MediaFormat.KEY_MAX_INPUT_SIZE value passed
|
// TODO: Update ShadowMediaCodec to consider the MediaFormat.KEY_MAX_INPUT_SIZE value passed
|
||||||
// to configure() so we don't have to specify large buffers here.
|
// to configure() so we don't have to specify large buffers here.
|
||||||
int bufferSize = mimeType.equals(MimeTypes.VIDEO_H265) ? 250_000 : 150_000;
|
int bufferSize = mimeType.equals(MimeTypes.VIDEO_H265) ? 250_000 : 150_000;
|
||||||
ShadowMediaCodec.addDecoder(
|
configureShadowMediaCodec(
|
||||||
codecName,
|
codecName,
|
||||||
|
mimeType,
|
||||||
|
/* isEncoder= */ false,
|
||||||
|
profileLevels,
|
||||||
|
colorFormats,
|
||||||
new ShadowMediaCodec.CodecConfig(
|
new ShadowMediaCodec.CodecConfig(
|
||||||
/* inputBufferSize= */ bufferSize, /* outputBufferSize= */ bufferSize, this));
|
/* inputBufferSize= */ bufferSize,
|
||||||
|
/* outputBufferSize= */ bufferSize,
|
||||||
|
/* codec= */ this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package androidx.media3.transformer;
|
package androidx.media3.transformer;
|
||||||
|
|
||||||
import android.media.MediaFormat;
|
import static androidx.media3.test.utils.robolectric.ShadowMediaCodecConfig.configureShadowMediaCodec;
|
||||||
|
|
||||||
import androidx.media3.common.MimeTypes;
|
import androidx.media3.common.MimeTypes;
|
||||||
import androidx.media3.common.audio.AudioProcessor;
|
import androidx.media3.common.audio.AudioProcessor;
|
||||||
import androidx.media3.common.audio.ChannelMixingAudioProcessor;
|
import androidx.media3.common.audio.ChannelMixingAudioProcessor;
|
||||||
@ -24,10 +25,8 @@ import androidx.media3.common.audio.SonicAudioProcessor;
|
|||||||
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 com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.primitives.Ints;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
import org.robolectric.shadows.MediaCodecInfoBuilder;
|
|
||||||
import org.robolectric.shadows.ShadowMediaCodec;
|
import org.robolectric.shadows.ShadowMediaCodec;
|
||||||
import org.robolectric.shadows.ShadowMediaCodecList;
|
import org.robolectric.shadows.ShadowMediaCodecList;
|
||||||
|
|
||||||
@ -209,33 +208,17 @@ public final class TestUtil {
|
|||||||
private static void addCodec(
|
private static void addCodec(
|
||||||
String mimeType,
|
String mimeType,
|
||||||
ShadowMediaCodec.CodecConfig codecConfig,
|
ShadowMediaCodec.CodecConfig codecConfig,
|
||||||
List<Integer> colorFormats,
|
ImmutableList<Integer> colorFormats,
|
||||||
boolean isDecoder) {
|
boolean isDecoder) {
|
||||||
String codecName =
|
String codecName =
|
||||||
Util.formatInvariant(
|
Util.formatInvariant(
|
||||||
isDecoder ? "exo.%s.decoder" : "exo.%s.encoder", mimeType.replace('/', '-'));
|
isDecoder ? "exo.%s.decoder" : "exo.%s.encoder", mimeType.replace('/', '-'));
|
||||||
if (isDecoder) {
|
configureShadowMediaCodec(
|
||||||
ShadowMediaCodec.addDecoder(codecName, codecConfig);
|
codecName,
|
||||||
} else {
|
mimeType,
|
||||||
ShadowMediaCodec.addEncoder(codecName, codecConfig);
|
!isDecoder,
|
||||||
}
|
/* profileLevels= */ ImmutableList.of(),
|
||||||
|
colorFormats,
|
||||||
MediaFormat mediaFormat = new MediaFormat();
|
codecConfig);
|
||||||
mediaFormat.setString(MediaFormat.KEY_MIME, mimeType);
|
|
||||||
MediaCodecInfoBuilder.CodecCapabilitiesBuilder codecCapabilities =
|
|
||||||
MediaCodecInfoBuilder.CodecCapabilitiesBuilder.newBuilder()
|
|
||||||
.setMediaFormat(mediaFormat)
|
|
||||||
.setIsEncoder(!isDecoder);
|
|
||||||
|
|
||||||
if (!colorFormats.isEmpty()) {
|
|
||||||
codecCapabilities.setColorFormats(Ints.toArray(colorFormats));
|
|
||||||
}
|
|
||||||
|
|
||||||
ShadowMediaCodecList.addCodec(
|
|
||||||
MediaCodecInfoBuilder.newBuilder()
|
|
||||||
.setName(codecName)
|
|
||||||
.setIsEncoder(!isDecoder)
|
|
||||||
.setCapabilities(codecCapabilities.build())
|
|
||||||
.build());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user