mirror of
https://github.com/samsonjs/media.git
synced 2026-04-12 12:25:47 +00:00
Add MediaCodecInfoTest
PiperOrigin-RevId: 339107784
This commit is contained in:
parent
949e26d1ba
commit
959851b190
2 changed files with 254 additions and 8 deletions
|
|
@ -24,6 +24,7 @@ import android.media.MediaCodecInfo.VideoCapabilities;
|
|||
import android.util.Pair;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
|
|
@ -152,11 +153,13 @@ public final class MediaCodecInfo {
|
|||
hardwareAccelerated,
|
||||
softwareOnly,
|
||||
vendor,
|
||||
forceDisableAdaptive,
|
||||
forceSecure);
|
||||
/* adaptive= */ !forceDisableAdaptive && capabilities != null && isAdaptive(capabilities),
|
||||
/* tunneling= */ capabilities != null && isTunneling(capabilities),
|
||||
/* secure= */ forceSecure || (capabilities != null && isSecure(capabilities)));
|
||||
}
|
||||
|
||||
private MediaCodecInfo(
|
||||
@VisibleForTesting
|
||||
/* package */ MediaCodecInfo(
|
||||
String name,
|
||||
String mimeType,
|
||||
String codecMimeType,
|
||||
|
|
@ -164,8 +167,9 @@ public final class MediaCodecInfo {
|
|||
boolean hardwareAccelerated,
|
||||
boolean softwareOnly,
|
||||
boolean vendor,
|
||||
boolean forceDisableAdaptive,
|
||||
boolean forceSecure) {
|
||||
boolean adaptive,
|
||||
boolean tunneling,
|
||||
boolean secure) {
|
||||
this.name = Assertions.checkNotNull(name);
|
||||
this.mimeType = mimeType;
|
||||
this.codecMimeType = codecMimeType;
|
||||
|
|
@ -173,9 +177,9 @@ public final class MediaCodecInfo {
|
|||
this.hardwareAccelerated = hardwareAccelerated;
|
||||
this.softwareOnly = softwareOnly;
|
||||
this.vendor = vendor;
|
||||
adaptive = !forceDisableAdaptive && capabilities != null && isAdaptive(capabilities);
|
||||
tunneling = capabilities != null && isTunneling(capabilities);
|
||||
secure = forceSecure || (capabilities != null && isSecure(capabilities));
|
||||
this.adaptive = adaptive;
|
||||
this.tunneling = tunneling;
|
||||
this.secure = secure;
|
||||
isVideo = MimeTypes.isVideo(mimeType);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.mediacodec;
|
||||
|
||||
import static com.google.android.exoplayer2.util.MimeTypes.AUDIO_AAC;
|
||||
import static com.google.android.exoplayer2.util.MimeTypes.VIDEO_AV1;
|
||||
import static com.google.android.exoplayer2.util.MimeTypes.VIDEO_H264;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.video.ColorInfo;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/** Unit tests for {@link MediaCodecInfo}. */
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public final class MediaCodecInfoTest {
|
||||
|
||||
private static final Format FORMAT_H264_HD =
|
||||
new Format.Builder()
|
||||
.setSampleMimeType(VIDEO_H264)
|
||||
.setWidth(1024)
|
||||
.setHeight(768)
|
||||
.setInitializationData(ImmutableList.of(new byte[] {1, 0, 2, 4}))
|
||||
.build();
|
||||
private static final Format FORMAT_H264_4K =
|
||||
new Format.Builder()
|
||||
.setSampleMimeType(VIDEO_H264)
|
||||
.setWidth(3840)
|
||||
.setHeight(2160)
|
||||
.setInitializationData(ImmutableList.of(new byte[] {3, 8, 4, 0}))
|
||||
.build();
|
||||
private static final Format FORMAT_AAC_STEREO =
|
||||
new Format.Builder()
|
||||
.setSampleMimeType(AUDIO_AAC)
|
||||
.setChannelCount(2)
|
||||
.setSampleRate(44100)
|
||||
.setAverageBitrate(2000)
|
||||
.setInitializationData(ImmutableList.of(new byte[] {4, 4, 1, 0, 0}))
|
||||
.build();
|
||||
private static final Format FORMAT_AAC_SURROUND =
|
||||
new Format.Builder()
|
||||
.setSampleMimeType(AUDIO_AAC)
|
||||
.setChannelCount(5)
|
||||
.setSampleRate(44100)
|
||||
.setAverageBitrate(5000)
|
||||
.setInitializationData(ImmutableList.of(new byte[] {4, 4, 1, 0, 0}))
|
||||
.build();
|
||||
|
||||
@Test
|
||||
public void isSeamlessAdaptationSupported_withDifferentMimeType_returnsFalse() {
|
||||
MediaCodecInfo codecInfo = buildH264CodecInfo(/* adaptive= */ true);
|
||||
|
||||
Format hdAv1Format = FORMAT_H264_HD.buildUpon().setSampleMimeType(VIDEO_AV1).build();
|
||||
assertThat(
|
||||
codecInfo.isSeamlessAdaptationSupported(
|
||||
FORMAT_H264_HD, hdAv1Format, /* isNewFormatComplete= */ true))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSeamlessAdaptationSupported_withRotation_returnsFalse() {
|
||||
MediaCodecInfo codecInfo = buildH264CodecInfo(/* adaptive= */ true);
|
||||
|
||||
Format hdRotatedFormat = FORMAT_H264_HD.buildUpon().setRotationDegrees(90).build();
|
||||
assertThat(
|
||||
codecInfo.isSeamlessAdaptationSupported(
|
||||
FORMAT_H264_HD, hdRotatedFormat, /* isNewFormatComplete= */ true))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSeamlessAdaptationSupported_withResolutionChange_adaptiveCodec_returnsTrue() {
|
||||
MediaCodecInfo codecInfo = buildH264CodecInfo(/* adaptive= */ true);
|
||||
|
||||
assertThat(
|
||||
codecInfo.isSeamlessAdaptationSupported(
|
||||
FORMAT_H264_HD, FORMAT_H264_4K, /* isNewFormatComplete= */ true))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSeamlessAdaptationSupported_withResolutionChange_nonAdaptiveCodec_returnsFalse() {
|
||||
MediaCodecInfo codecInfo = buildH264CodecInfo(/* adaptive= */ false);
|
||||
|
||||
assertThat(
|
||||
codecInfo.isSeamlessAdaptationSupported(
|
||||
FORMAT_H264_HD, FORMAT_H264_4K, /* isNewFormatComplete= */ true))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSeamlessAdaptationSupported_noResolutionChange_nonAdaptiveCodec_returnsTrue() {
|
||||
MediaCodecInfo codecInfo = buildH264CodecInfo(/* adaptive= */ false);
|
||||
|
||||
Format hdVariantFormat =
|
||||
FORMAT_H264_HD.buildUpon().setInitializationData(ImmutableList.of(new byte[] {0})).build();
|
||||
assertThat(
|
||||
codecInfo.isSeamlessAdaptationSupported(
|
||||
FORMAT_H264_HD, hdVariantFormat, /* isNewFormatComplete= */ true))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSeamlessAdaptationSupported_colorInfoOmittedFromCompleteNewFormat_returnsFalse() {
|
||||
MediaCodecInfo codecInfo = buildH264CodecInfo(/* adaptive= */ false);
|
||||
|
||||
Format hdrVariantFormat =
|
||||
FORMAT_H264_4K.buildUpon().setColorInfo(buildColorInfo(C.COLOR_SPACE_BT601)).build();
|
||||
assertThat(
|
||||
codecInfo.isSeamlessAdaptationSupported(
|
||||
hdrVariantFormat, FORMAT_H264_4K, /* isNewFormatComplete= */ true))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSeamlessAdaptationSupported_colorInfoOmittedFromIncompleteNewFormat_returnsTrue() {
|
||||
MediaCodecInfo codecInfo = buildH264CodecInfo(/* adaptive= */ false);
|
||||
|
||||
Format hdrVariantFormat =
|
||||
FORMAT_H264_4K.buildUpon().setColorInfo(buildColorInfo(C.COLOR_SPACE_BT601)).build();
|
||||
assertThat(
|
||||
codecInfo.isSeamlessAdaptationSupported(
|
||||
hdrVariantFormat, FORMAT_H264_4K, /* isNewFormatComplete= */ false))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSeamlessAdaptationSupported_colorInfoOmittedFromOldFormat_returnsFalse() {
|
||||
MediaCodecInfo codecInfo = buildH264CodecInfo(/* adaptive= */ false);
|
||||
|
||||
Format hdrVariantFormat =
|
||||
FORMAT_H264_4K.buildUpon().setColorInfo(buildColorInfo(C.COLOR_SPACE_BT601)).build();
|
||||
assertThat(
|
||||
codecInfo.isSeamlessAdaptationSupported(
|
||||
FORMAT_H264_4K, hdrVariantFormat, /* isNewFormatComplete= */ true))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSeamlessAdaptationSupported_colorInfoChange_returnsFalse() {
|
||||
MediaCodecInfo codecInfo = buildH264CodecInfo(/* adaptive= */ false);
|
||||
|
||||
Format hdrVariantFormat1 =
|
||||
FORMAT_H264_4K.buildUpon().setColorInfo(buildColorInfo(C.COLOR_SPACE_BT601)).build();
|
||||
Format hdrVariantFormat2 =
|
||||
FORMAT_H264_4K.buildUpon().setColorInfo(buildColorInfo(C.COLOR_SPACE_BT709)).build();
|
||||
assertThat(
|
||||
codecInfo.isSeamlessAdaptationSupported(
|
||||
hdrVariantFormat1, hdrVariantFormat2, /* isNewFormatComplete= */ true))
|
||||
.isFalse();
|
||||
assertThat(
|
||||
codecInfo.isSeamlessAdaptationSupported(
|
||||
hdrVariantFormat1, hdrVariantFormat2, /* isNewFormatComplete= */ false))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSeamlessAdaptationSupported_audioWithDifferentChannelCounts_returnsFalse() {
|
||||
MediaCodecInfo codecInfo = buildAacCodecInfo();
|
||||
|
||||
assertThat(
|
||||
codecInfo.isSeamlessAdaptationSupported(
|
||||
FORMAT_AAC_STEREO, FORMAT_AAC_SURROUND, /* isNewFormatComplete= */ true))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSeamlessAdaptationSupported_audioWithSameChannelCounts_returnsFalse() {
|
||||
MediaCodecInfo codecInfo = buildAacCodecInfo();
|
||||
|
||||
Format stereoVariantFormat = FORMAT_AAC_STEREO.buildUpon().setAverageBitrate(100).build();
|
||||
assertThat(
|
||||
codecInfo.isSeamlessAdaptationSupported(
|
||||
FORMAT_AAC_STEREO, stereoVariantFormat, /* isNewFormatComplete= */ true))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSeamlessAdaptationSupported_audioWithDifferentInitializationData_returnsFalse() {
|
||||
MediaCodecInfo codecInfo = buildAacCodecInfo();
|
||||
|
||||
Format stereoVariantFormat =
|
||||
FORMAT_AAC_STEREO
|
||||
.buildUpon()
|
||||
.setInitializationData(ImmutableList.of(new byte[] {0}))
|
||||
.build();
|
||||
assertThat(
|
||||
codecInfo.isSeamlessAdaptationSupported(
|
||||
FORMAT_AAC_STEREO, stereoVariantFormat, /* isNewFormatComplete= */ true))
|
||||
.isFalse();
|
||||
}
|
||||
|
||||
private static MediaCodecInfo buildH264CodecInfo(boolean adaptive) {
|
||||
return new MediaCodecInfo(
|
||||
"h264",
|
||||
VIDEO_H264,
|
||||
VIDEO_H264,
|
||||
/* capabilities= */ null,
|
||||
/* hardwareAccelerated= */ true,
|
||||
/* softwareOnly= */ false,
|
||||
/* vendor= */ true,
|
||||
adaptive,
|
||||
/* tunneling= */ false,
|
||||
/* secure= */ false);
|
||||
}
|
||||
|
||||
private static MediaCodecInfo buildAacCodecInfo() {
|
||||
return new MediaCodecInfo(
|
||||
"aac",
|
||||
AUDIO_AAC,
|
||||
AUDIO_AAC,
|
||||
/* capabilities= */ null,
|
||||
/* hardwareAccelerated= */ false,
|
||||
/* softwareOnly= */ true,
|
||||
/* vendor= */ false,
|
||||
/* adaptive= */ false,
|
||||
/* tunneling= */ false,
|
||||
/* secure= */ false);
|
||||
}
|
||||
|
||||
private static ColorInfo buildColorInfo(@C.ColorSpace int colorSpace) {
|
||||
return new ColorInfo(
|
||||
colorSpace, C.COLOR_RANGE_FULL, C.COLOR_TRANSFER_HLG, /* hdrStaticInfo= */ null);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue