1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.mediapc.cts; 18 19 import static android.mediapc.cts.CodecTestBase.codecFilter; 20 import static android.mediapc.cts.CodecTestBase.codecPrefix; 21 import static android.mediapc.cts.CodecTestBase.mediaTypePrefix; 22 23 import android.media.MediaFormat; 24 import android.mediapc.cts.common.CodecMetrics; 25 import android.mediapc.cts.common.PerformanceClassEvaluator; 26 import android.mediapc.cts.common.Utils; 27 import android.util.Pair; 28 29 import androidx.test.filters.LargeTest; 30 31 import com.android.compatibility.common.util.CddTest; 32 33 import org.junit.Assume; 34 import org.junit.Rule; 35 import org.junit.Test; 36 import org.junit.rules.TestName; 37 import org.junit.runner.RunWith; 38 import org.junit.runners.Parameterized; 39 40 import java.util.ArrayList; 41 import java.util.Collection; 42 import java.util.List; 43 import java.util.Map; 44 45 /** 46 * The following test class validates the maximum number of concurrent decode sessions that it can 47 * support by the hardware decoders calculated via the CodecCapabilities.getMaxSupportedInstances() 48 * and VideoCapabilities.getSupportedPerformancePoints() methods. And also ensures that the maximum 49 * supported sessions succeed in decoding with meeting the expected frame rate. 50 */ 51 @RunWith(Parameterized.class) 52 public class MultiDecoderPerfTest extends MultiCodecPerfTestBase { 53 private static final String LOG_TAG = MultiDecoderPerfTest.class.getSimpleName(); 54 55 private final String mDecoderName; 56 MultiDecoderPerfTest(String mediaType, String decoderName, boolean isAsync)57 public MultiDecoderPerfTest(String mediaType, String decoderName, boolean isAsync) { 58 super(mediaType, null, isAsync); 59 mDecoderName = decoderName; 60 } 61 62 @Rule 63 public final TestName mTestName = new TestName(); 64 65 // Returns the params list with the mediaType and corresponding hardware decoders in 66 // both sync and async modes. 67 // Parameters {0}_{1}_{2} -- MediaType_DecoderName_isAsync 68 @Parameterized.Parameters(name = "{index}_{0}_{1}_{2}") inputParams()69 public static Collection<Object[]> inputParams() { 70 final List<Object[]> argsList = new ArrayList<>(); 71 for (String mediaType : mMediaTypeList) { 72 if (mediaTypePrefix != null && !mediaType.startsWith(mediaTypePrefix)) { 73 continue; 74 } 75 ArrayList<String> listOfDecoders = 76 getHardwareCodecsForMediaTypes(mediaType, false, true); 77 for (String decoder : listOfDecoders) { 78 if ((codecPrefix != null && !decoder.startsWith(codecPrefix)) 79 || (codecFilter != null && !codecFilter.matcher(decoder).matches())) { 80 continue; 81 } 82 for (boolean isAsync : boolStates) { 83 argsList.add(new Object[]{mediaType, decoder, isAsync}); 84 } 85 } 86 } 87 return argsList; 88 } 89 90 /** 91 * This test validates that the decoder can support at least 6 concurrent 720p 30fps 92 * decoder instances. Also ensures that all the concurrent sessions succeed in decoding 93 * with meeting the expected frame rate. 94 */ 95 @LargeTest 96 @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS) 97 @CddTest(requirements = {"2.2.7.1/5.1/H-1-1", "2.2.7.1/5.1/H-1-2"}) test720p()98 public void test720p() throws Exception { 99 Assume.assumeTrue(Utils.isSPerfClass() || Utils.isRPerfClass() || !Utils.isPerfClass()); 100 Assume.assumeFalse("Skipping regular performance tests for secure codecs", 101 isSecureSupportedCodec(mDecoderName, mMediaType)); 102 boolean hasVP9 = mMediaType.equals(MediaFormat.MIMETYPE_VIDEO_VP9); 103 int requiredMinInstances = getRequiredMinConcurrentInstances720p(hasVP9); 104 testCodec(m720pTestFiles, 720, 1280, requiredMinInstances); 105 } 106 107 /** 108 * This test validates that the decoder can support at least 6 non-secure/2 secure concurrent 109 * 1080p 30fps decoder instances. Also ensures that all the concurrent sessions succeed in 110 * decoding with meeting the expected frame rate. 111 */ 112 @LargeTest 113 @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS) 114 @CddTest(requirements = { 115 "2.2.7.1/5.1/H-1-1", 116 "2.2.7.1/5.1/H-1-2", 117 "2.2.7.1/5.1/H-1-9",}) test1080p()118 public void test1080p() throws Exception { 119 Assume.assumeTrue(Utils.isTPerfClass() || !Utils.isPerfClass()); 120 if (isSecureSupportedCodec(mDecoderName, mMediaType)) { 121 testCodec(m1080pWidevineTestFiles, 1080, 1920, 122 REQUIRED_MIN_CONCURRENT_SECURE_INSTANCES); 123 } else { 124 testCodec(m1080pTestFiles, 1080, 1920, REQUIRED_MIN_CONCURRENT_INSTANCES); 125 } 126 } 127 128 /** 129 * This test validates that the decoder can support at least 6 SDR non-secure concurrent 130 * instances with 3 sessions at 1080p 30 fps and 3 sessions at 4k 30fps / 2 SDR secure 131 * concurrent instances at 4k 30 fps. Also ensures that all the concurrent sessions succeed 132 * in decoding with meeting the expected frame rate. 133 */ 134 @LargeTest 135 @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS) 136 @CddTest(requirements = { 137 "2.2.7.1/5.1/H-1-1", 138 "2.2.7.1/5.1/H-1-2", 139 "2.2.7.1/5.1/H-1-9",}) test4k()140 public void test4k() throws Exception { 141 Assume.assumeTrue(Utils.isUPerfClass() || Utils.isVPerfClass() || !Utils.isPerfClass()); 142 143 if (isSecureSupportedCodec(mDecoderName, mMediaType)) { 144 testCodec(m2160pPc14WidevineTestFiles, 2160, 3840, 145 REQUIRED_MIN_CONCURRENT_SECURE_INSTANCES); 146 } else { 147 testCodec(m2160pPc14TestFiles, 2160, 3840, REQUIRED_MIN_CONCURRENT_INSTANCES); 148 } 149 } 150 151 /** 152 * This test validates that the decoder can support at least 2 HDR secure concurrent instances 153 * at 4k 30 fps. Also ensures that all the concurrent sessions succeed in decoding with 154 * meeting the expected frame rate. 155 */ 156 @LargeTest 157 @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS) 158 @CddTest(requirements = {"2.2.7.1/5.1/H-1-9"}) test4kHbd()159 public void test4kHbd() throws Exception { 160 Assume.assumeTrue(Utils.isUPerfClass() || Utils.isVPerfClass() || !Utils.isPerfClass()); 161 Assume.assumeTrue("Skipping regular performance tests for non-secure codecs", 162 isSecureSupportedCodec(mDecoderName, mMediaType)); 163 testCodec(m2160pPc1410bitWidevineTestFiles, 2160, 3840, 164 REQUIRED_MIN_CONCURRENT_SECURE_INSTANCES); 165 } 166 testCodec(Map<String, String> testFiles, int height, int width, int requiredMinInstances)167 private void testCodec(Map<String, String> testFiles, int height, int width, 168 int requiredMinInstances) throws Exception { 169 mTestFile = testFiles.get(mMediaType); 170 Assume.assumeTrue("Add test vector for mediaType: " + mMediaType, mTestFile != null); 171 ArrayList<Pair<String, String>> mediaTypeDecoderPairs = new ArrayList<>(); 172 mediaTypeDecoderPairs.add(Pair.create(mMediaType, mDecoderName)); 173 boolean isSecure = isSecureSupportedCodec(mDecoderName, mMediaType); 174 int maxInstances = checkAndGetMaxSupportedInstancesForCodecCombinations(height, width, 175 mediaTypeDecoderPairs, false, requiredMinInstances); 176 double achievedFrameRate = 0.0; 177 double frameDropsPerSec = 0.0; 178 boolean meetsPreconditions = isSecure ? meetsSecureDecodePreconditions() : true; 179 180 if (meetsPreconditions && maxInstances >= requiredMinInstances) { 181 List<Decode> testList = new ArrayList<>(); 182 if (height > 1080 && !isSecure) { 183 int halfMaxInstances = maxInstances / 2; 184 String testFile1080p = m1080pTestFiles.get(mMediaType); 185 for (int i = 0; i < halfMaxInstances; i++) { 186 testList.add(new Decode(mMediaType, testFile1080p, mDecoderName, mIsAsync, 187 isSecure)); 188 testList.add(new Decode(mMediaType, mTestFile, mDecoderName, mIsAsync, 189 isSecure)); 190 } 191 } else { 192 for (int i = 0; i < maxInstances; i++) { 193 testList.add(new Decode(mMediaType, mTestFile, mDecoderName, mIsAsync, 194 isSecure)); 195 } 196 } 197 CodecMetrics result = invokeWithThread(maxInstances, testList); 198 achievedFrameRate = result.fps(); 199 frameDropsPerSec = result.fdps(); 200 } 201 202 PerformanceClassEvaluator pce = new PerformanceClassEvaluator(this.mTestName); 203 if (isSecure) { 204 PerformanceClassEvaluator.ConcurrentCodecRequirement r5_1__H_1_9; 205 if(height > 1080){ 206 r5_1__H_1_9 = pce.addR5_1__H_1_9_4k(); 207 r5_1__H_1_9.setConcurrentFps(achievedFrameRate); 208 r5_1__H_1_9.setFrameDropsPerSecond(frameDropsPerSec); 209 } else { 210 r5_1__H_1_9 = pce.addR5_1__H_1_9_1080p(); 211 r5_1__H_1_9.setConcurrentFps(achievedFrameRate); 212 } 213 } else { 214 PerformanceClassEvaluator.ConcurrentCodecRequirement r5_1__H_1_1; 215 PerformanceClassEvaluator.ConcurrentCodecRequirement r5_1__H_1_2; 216 if (height > 1080) { 217 r5_1__H_1_1 = pce.addR5_1__H_1_1_4k(); 218 r5_1__H_1_2 = pce.addR5_1__H_1_2_4k(); 219 r5_1__H_1_1.setConcurrentInstances(maxInstances); 220 r5_1__H_1_2.setConcurrentFps(achievedFrameRate); 221 r5_1__H_1_2.setFrameDropsPerSecond(frameDropsPerSec); 222 } else if (height == 1080) { 223 r5_1__H_1_1 = pce.addR5_1__H_1_1_1080p(); 224 r5_1__H_1_2 = pce.addR5_1__H_1_2_1080p(); 225 r5_1__H_1_1.setConcurrentInstances(maxInstances); 226 r5_1__H_1_2.setConcurrentFps(achievedFrameRate); 227 } else { 228 r5_1__H_1_1 = pce.addR5_1__H_1_1_720p(mMediaType, mMediaType, height); 229 r5_1__H_1_2 = pce.addR5_1__H_1_2_720p(mMediaType, mMediaType, height); 230 r5_1__H_1_1.setConcurrentInstances(maxInstances); 231 r5_1__H_1_2.setConcurrentFps(achievedFrameRate); 232 } 233 } 234 pce.submitAndCheck(); 235 } 236 } 237