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