blob: 2c20d233a4fcd3536f12dfec9de7b7c1ca3c007a [file] [log] [blame]
/*
* 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 android.mediav2.cts;
import static android.mediav2.common.cts.CodecTestBase.SupportClass.CODEC_ALL;
import static android.mediav2.common.cts.CodecTestBase.SupportClass.CODEC_ANY;
import static android.mediav2.common.cts.CodecTestBase.SupportClass.CODEC_OPTIONAL;
import android.media.MediaFormat;
import android.mediav2.common.cts.CodecDecoderTestBase;
import android.mediav2.common.cts.CodecTestActivity;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.filters.SmallTest;
import com.android.compatibility.common.util.ApiTest;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
* Color Primaries, Color Standard and Color Transfer are essential information to display the
* decoded YUV on an RGB display accurately. These 3 parameters can be signalled via containers
* (mp4, mkv, ...) and some video standards also allow signalling this information in elementary
* stream. Avc, Hevc, Av1, ... allow signalling this information in elementary stream, vpx relies
* on webm/mkv or some other container for signalling.
* <p>
* The test checks if the muxer and/or decoder propagates this information from file to application
* correctly on their own. Whether this information is used by the device during display is
* beyond the scope of this test.
*/
@RunWith(Parameterized.class)
public class DecoderColorAspectsTest extends CodecDecoderTestBase {
private static final String LOG_TAG = DecoderColorAspectsTest.class.getSimpleName();
private static final String MEDIA_DIR = WorkDir.getMediaDirString();
private final int mColorRange;
private final int mColorStandard;
private final int mColorTransferCurve;
private final boolean mCanIgnoreColorBox;
private final SupportClass mSupportRequirements;
private ArrayList<String> mCheckESList;
public DecoderColorAspectsTest(String decoderName, String mime, String testFile, int range,
int standard, int transferCurve, boolean canIgnoreColorBox,
SupportClass supportRequirements, String allTestParams) {
super(decoderName, mime, MEDIA_DIR + testFile, allTestParams);
mColorRange = range;
mColorStandard = standard;
mColorTransferCurve = transferCurve;
mCheckESList = new ArrayList<>();
mCheckESList.add(MediaFormat.MIMETYPE_VIDEO_AVC);
mCheckESList.add(MediaFormat.MIMETYPE_VIDEO_HEVC);
/* TODO (b/165492703) Mpeg2 has problems in signalling color
aspects information via elementary stream. */
// mCheckESList.add(MediaFormat.MIMETYPE_VIDEO_MPEG2);
mCheckESList.add(MediaFormat.MIMETYPE_VIDEO_AV1);
mCanIgnoreColorBox = canIgnoreColorBox;
mSupportRequirements = supportRequirements;
}
@Parameterized.Parameters(name = "{index}({0}_{1}_{3}_{4}_{5})")
public static Collection<Object[]> input() {
final boolean isEncoder = false;
final boolean needAudio = true;
final boolean needVideo = true;
// mediatype, testClip, colorRange, colorStandard, colorTransfer, areColorAspectsInStream
final List<Object[]> exhaustiveArgsList = Arrays.asList(new Object[][]{
// h264 clips
{MediaFormat.MIMETYPE_VIDEO_AVC, "bbb_qcif_color_bt709_lr_sdr_avc.mp4",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT709,
MediaFormat.COLOR_TRANSFER_SDR_VIDEO, true, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_AVC, "bbb_qcif_color_bt601_625_fr_gamma22_avc.mp4",
MediaFormat.COLOR_RANGE_FULL, MediaFormat.COLOR_STANDARD_BT601_PAL,
/* MediaFormat.COLOR_TRANSFER_GAMMA2_2 */ 4, true, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_AVC, "bbb_qcif_color_bt601_525_lr_gamma28_avc.mp4",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT601_NTSC,
/* MediaFormat.COLOR_TRANSFER_GAMMA2_8 */ 5, true, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_AVC, "bbb_qcif_color_bt709_lr_srgb_avc.mp4",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT709,
/* MediaFormat.COLOR_TRANSFER_SRGB */ 2, true, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_AVC, "bbb_qcif_color_unspcfd_avc.mp4",
UNSPECIFIED, UNSPECIFIED, UNSPECIFIED, true, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_AVC, "bbb_qcif_color_bt470m_linear_fr_avc.mp4",
MediaFormat.COLOR_RANGE_FULL, /* MediaFormat.COLOR_STANDARD_BT470M */ 8,
MediaFormat.COLOR_TRANSFER_LINEAR, true, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_AVC,
"bikes_qcif_color_bt2020_smpte2084_bt2020Ncl_lr_avc.mp4",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT2020,
MediaFormat.COLOR_TRANSFER_ST2084, true, CODEC_OPTIONAL},
{MediaFormat.MIMETYPE_VIDEO_AVC,
"bikes_qcif_color_bt2020_smpte2086Hlg_bt2020Ncl_fr_avc.mp4",
MediaFormat.COLOR_RANGE_FULL, MediaFormat.COLOR_STANDARD_BT2020,
MediaFormat.COLOR_TRANSFER_HLG, true, CODEC_OPTIONAL},
// h265 clips
{MediaFormat.MIMETYPE_VIDEO_HEVC, "bbb_qcif_color_bt709_lr_sdr_hevc.mp4",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT709,
MediaFormat.COLOR_TRANSFER_SDR_VIDEO, true, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_HEVC, "bbb_qcif_color_bt601_625_fr_gamma22_hevc.mp4",
MediaFormat.COLOR_RANGE_FULL, MediaFormat.COLOR_STANDARD_BT601_PAL,
/* MediaFormat.COLOR_TRANSFER_GAMMA2_2 */ 4, true, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_HEVC, "bbb_qcif_color_bt601_525_lr_gamma28_hevc.mp4",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT601_NTSC,
/* MediaFormat.COLOR_TRANSFER_GAMMA2_8 */ 5, true, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_HEVC, "bbb_qcif_color_bt709_lr_srgb_hevc.mp4",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT709,
/* MediaFormat.COLOR_TRANSFER_SRGB */ 2, true, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_HEVC, "bbb_qcif_color_unspcfd_hevc.mp4",
UNSPECIFIED, UNSPECIFIED, UNSPECIFIED, true, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_HEVC, "bbb_qcif_color_bt470m_linear_fr_hevc.mp4",
MediaFormat.COLOR_RANGE_FULL, /* MediaFormat.COLOR_STANDARD_BT470M */ 8,
MediaFormat.COLOR_TRANSFER_LINEAR, true, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_HEVC,
"bikes_qcif_color_bt2020_smpte2084_bt2020Ncl_lr_hevc.mp4",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT2020,
MediaFormat.COLOR_TRANSFER_ST2084, true, CODEC_OPTIONAL},
{MediaFormat.MIMETYPE_VIDEO_HEVC,
"bikes_qcif_color_bt2020_smpte2086Hlg_bt2020Ncl_fr_hevc.mp4",
MediaFormat.COLOR_RANGE_FULL, MediaFormat.COLOR_STANDARD_BT2020,
MediaFormat.COLOR_TRANSFER_HLG, true, CODEC_OPTIONAL},
// Mpeg2 clips
{MediaFormat.MIMETYPE_VIDEO_MPEG2, "bbb_qcif_color_bt709_lr_sdr_mpeg2.mp4",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT709,
MediaFormat.COLOR_TRANSFER_SDR_VIDEO, true, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_MPEG2, "bbb_qcif_color_bt601_625_lr_gamma22_mpeg2.mp4",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT601_PAL,
/* MediaFormat.COLOR_TRANSFER_GAMMA2_2 */ 4, true, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_MPEG2, "bbb_qcif_color_bt601_525_lr_gamma28_mpeg2.mp4",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT601_NTSC,
/* MediaFormat.COLOR_TRANSFER_GAMMA2_8 */ 5, true, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_MPEG2, "bbb_qcif_color_bt709_lr_srgb_mpeg2.mp4",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT709,
/* MediaFormat.COLOR_TRANSFER_SRGB */ 2, true, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_MPEG2, "bbb_qcif_color_unspcfd_lr_mpeg2.mp4",
UNSPECIFIED, UNSPECIFIED, UNSPECIFIED, true, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_MPEG2, "bbb_qcif_color_bt470m_linear_lr_mpeg2.mp4",
MediaFormat.COLOR_RANGE_LIMITED, /* MediaFormat.COLOR_STANDARD_BT470M */ 8,
MediaFormat.COLOR_TRANSFER_LINEAR, true, CODEC_ALL},
// Mpeg4 clips
{MediaFormat.MIMETYPE_VIDEO_MPEG4, "bbb_qcif_color_bt709_lr_sdr_mpeg4.mp4",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT709,
MediaFormat.COLOR_TRANSFER_SDR_VIDEO, false, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_MPEG4, "bbb_qcif_color_bt601_625_fr_gamma22_mpeg4.mp4",
MediaFormat.COLOR_RANGE_FULL, MediaFormat.COLOR_STANDARD_BT601_PAL,
/* MediaFormat.COLOR_TRANSFER_GAMMA2_2 */ 4, false, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_MPEG4, "bbb_qcif_color_bt601_525_lr_gamma28_mpeg4.mp4",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT601_NTSC,
/* MediaFormat.COLOR_TRANSFER_GAMMA2_8 */ 5, false, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_MPEG4, "bbb_qcif_color_bt709_lr_srgb_mpeg4.mp4",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT709,
/* MediaFormat.COLOR_TRANSFER_SRGB */ 2, false, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_MPEG4, "bbb_qcif_color_unspcfd_mpeg4.mp4",
UNSPECIFIED, UNSPECIFIED, UNSPECIFIED, false, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_MPEG4, "bbb_qcif_color_bt470m_linear_fr_mpeg4.mp4",
MediaFormat.COLOR_RANGE_FULL, /* MediaFormat.COLOR_STANDARD_BT470M */ 8,
MediaFormat.COLOR_TRANSFER_LINEAR, false, CODEC_ALL},
// Vp8 clips
{MediaFormat.MIMETYPE_VIDEO_VP8, "bbb_qcif_color_bt709_lr_sdr_vp8.webm",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT709,
MediaFormat.COLOR_TRANSFER_SDR_VIDEO, false, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_VP8, "bbb_qcif_color_bt601_625_fr_gamma22_vp8.mkv",
MediaFormat.COLOR_RANGE_FULL, MediaFormat.COLOR_STANDARD_BT601_PAL,
/* MediaFormat.COLOR_TRANSFER_GAMMA2_2 */ 4, false, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_VP8, "bbb_qcif_color_bt601_525_lr_gamma28_vp8.mkv",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT601_NTSC,
/* MediaFormat.COLOR_TRANSFER_GAMMA2_8 */ 5, false, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_VP8, "bbb_qcif_color_bt709_lr_srgb_vp8.mkv",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT709,
/* MediaFormat.COLOR_TRANSFER_SRGB */ 2, false, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_VP8, "bbb_qcif_color_unspcfd_vp8.mkv",
UNSPECIFIED, UNSPECIFIED, UNSPECIFIED, false, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_VP8, "bbb_qcif_color_bt470m_linear_fr_vp8.mkv",
MediaFormat.COLOR_RANGE_FULL, /* MediaFormat.COLOR_STANDARD_BT470M */ 8,
MediaFormat.COLOR_TRANSFER_LINEAR, false, CODEC_ALL},
// Vp9 clips
{MediaFormat.MIMETYPE_VIDEO_VP9, "bbb_qcif_color_bt709_lr_sdr_vp9.webm",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT709,
MediaFormat.COLOR_TRANSFER_SDR_VIDEO, false, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_VP9, "bbb_qcif_color_bt601_625_fr_gamma22_vp9.mkv",
MediaFormat.COLOR_RANGE_FULL, MediaFormat.COLOR_STANDARD_BT601_PAL,
/* MediaFormat.COLOR_TRANSFER_GAMMA2_2 */ 4, false, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_VP9, "bbb_qcif_color_smpte170_lr_gamma28_vp9.mkv",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT601_NTSC,
/* MediaFormat.COLOR_TRANSFER_GAMMA2_8 */ 5, false, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_VP9, "bbb_qcif_color_bt709_lr_srgb_vp9.mkv",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT709,
/* MediaFormat.COLOR_TRANSFER_SRGB */ 2, false, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_VP9, "bbb_qcif_color_unspcfd_vp9.mkv",
UNSPECIFIED, UNSPECIFIED, UNSPECIFIED, false, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_VP9, "bbb_qcif_color_bt470m_linear_fr_vp9.mkv",
MediaFormat.COLOR_RANGE_FULL, /* MediaFormat.COLOR_STANDARD_BT470M */ 8,
MediaFormat.COLOR_TRANSFER_LINEAR, false, CODEC_ALL},
{MediaFormat.MIMETYPE_VIDEO_VP9,
"bikes_qcif_color_bt2020_smpte2084_bt2020Ncl_lr_vp9.mkv",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT2020,
MediaFormat.COLOR_TRANSFER_ST2084, false, CODEC_ANY},
{MediaFormat.MIMETYPE_VIDEO_VP9,
"bikes_qcif_color_bt2020_smpte2086Hlg_bt2020Ncl_fr_vp9.mkv",
MediaFormat.COLOR_RANGE_FULL, MediaFormat.COLOR_STANDARD_BT2020,
MediaFormat.COLOR_TRANSFER_HLG, false, CODEC_ANY},
// AV1 clips
{MediaFormat.MIMETYPE_VIDEO_AV1, "bbb_qcif_color_bt709_lr_sdr_av1.mp4",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT709,
MediaFormat.COLOR_TRANSFER_SDR_VIDEO, true, CODEC_OPTIONAL},
{MediaFormat.MIMETYPE_VIDEO_AV1, "bbb_qcif_color_bt601_625_fr_gamma22_av1.mp4",
MediaFormat.COLOR_RANGE_FULL, MediaFormat.COLOR_STANDARD_BT601_PAL,
/* MediaFormat.COLOR_TRANSFER_GAMMA2_2 */ 4, true, CODEC_OPTIONAL},
{MediaFormat.MIMETYPE_VIDEO_AV1, "bbb_qcif_color_bt601_525_lr_gamma28_av1.mp4",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT601_NTSC,
/* MediaFormat.COLOR_TRANSFER_GAMMA2_8 */ 5, true, CODEC_OPTIONAL},
{MediaFormat.MIMETYPE_VIDEO_AV1, "bbb_qcif_color_bt709_lr_srgb_av1.mp4",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT709,
/* MediaFormat.COLOR_TRANSFER_SRGB */ 2, true, CODEC_OPTIONAL},
{MediaFormat.MIMETYPE_VIDEO_AV1, "bbb_qcif_color_unspcfd_av1.mp4",
UNSPECIFIED, UNSPECIFIED, UNSPECIFIED, true, CODEC_OPTIONAL},
{MediaFormat.MIMETYPE_VIDEO_AV1, "bbb_qcif_color_bt470m_linear_fr_av1.mp4",
MediaFormat.COLOR_RANGE_FULL, /* MediaFormat.COLOR_STANDARD_BT470M */ 8,
MediaFormat.COLOR_TRANSFER_LINEAR, true, CODEC_OPTIONAL},
{MediaFormat.MIMETYPE_VIDEO_AV1,
"bikes_qcif_color_bt2020_smpte2084_bt2020Ncl_lr_av1.mp4",
MediaFormat.COLOR_RANGE_LIMITED, MediaFormat.COLOR_STANDARD_BT2020,
MediaFormat.COLOR_TRANSFER_ST2084, true, CODEC_OPTIONAL},
{MediaFormat.MIMETYPE_VIDEO_AV1,
"bikes_qcif_color_bt2020_smpte2086Hlg_bt2020Ncl_fr_av1.mp4",
MediaFormat.COLOR_RANGE_FULL, MediaFormat.COLOR_STANDARD_BT2020,
MediaFormat.COLOR_TRANSFER_HLG, true, CODEC_OPTIONAL},
});
return prepareParamList(exhaustiveArgsList, isEncoder, needAudio, needVideo, false);
}
@Rule
public ActivityScenarioRule<CodecTestActivity> mActivityRule =
new ActivityScenarioRule<>(CodecTestActivity.class);
@Before
public void setUp() throws IOException, InterruptedException {
mActivityRule.getScenario().onActivity(activity -> mActivity = activity);
setUpSurface(mActivity);
}
/**
* Check description of class {@link DecoderColorAspectsTest}
*/
@ApiTest(apis = {"android.media.MediaFormat#KEY_COLOR_RANGE",
"android.media.MediaFormat#KEY_COLOR_STANDARD",
"android.media.MediaFormat#KEY_COLOR_TRANSFER"})
@SmallTest
@Test(timeout = PER_TEST_TIMEOUT_SMALL_TEST_MS)
public void testColorAspects() throws IOException, InterruptedException {
MediaFormat format = setUpSource(mTestFile);
mExtractor.release();
ArrayList<MediaFormat> formats = new ArrayList<>();
formats.add(format);
if (doesAnyFormatHaveHDRProfile(mMime, formats)) {
Assume.assumeTrue(canDisplaySupportHDRContent());
}
checkFormatSupport(mCodecName, mMime, false, formats, null, mSupportRequirements);
mActivity.setScreenParams(getWidth(format), getHeight(format), true);
{
validateColorAspects(mColorRange, mColorStandard, mColorTransferCurve, false);
// If color metadata can also be signalled via elementary stream, then verify if the
// elementary stream contains color aspects as expected
if (mCanIgnoreColorBox && mCheckESList.contains(mMime)) {
validateColorAspects(mColorRange, mColorStandard, mColorTransferCurve, true);
}
}
}
}