1 /*
2  * Copyright (C) 2020 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.mediav2.cts;
18 
19 import android.media.MediaCodec;
20 import android.media.MediaCodecInfo;
21 import android.media.MediaFormat;
22 import android.util.Log;
23 import android.util.Pair;
24 
25 import org.junit.Test;
26 import org.junit.runner.RunWith;
27 import org.junit.runners.Parameterized;
28 
29 import java.io.IOException;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Collection;
33 import java.util.HashMap;
34 import java.util.List;
35 
36 import static android.media.MediaCodecInfo.CodecProfileLevel.*;
37 import static org.junit.Assert.assertFalse;
38 import static org.junit.Assert.assertTrue;
39 
40 /**
41  * Validate profile and level configuration for listed encoder components
42  */
43 @RunWith(Parameterized.class)
44 public class EncoderProfileLevelTest extends CodecEncoderTestBase {
45     private static final String LOG_TAG = EncoderProfileLevelTest.class.getSimpleName();
46     private static final HashMap<String, int[]> mProfileMap = new HashMap<>();
47     private static final HashMap<String, Pair<int[], Integer>> mProfileLevelCdd = new HashMap<>();
48 
49     private MediaFormat mConfigFormat;
50 
EncoderProfileLevelTest(String mime, int bitrate, int encoderInfo1, int encoderInfo2, int frameRate)51     public EncoderProfileLevelTest(String mime, int bitrate, int encoderInfo1, int encoderInfo2,
52             int frameRate) {
53         super(mime);
54         mConfigFormat = new MediaFormat();
55         mConfigFormat.setString(MediaFormat.KEY_MIME, mMime);
56         mConfigFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
57         if (mIsAudio) {
58             mSampleRate = encoderInfo1;
59             mChannels = encoderInfo2;
60             mConfigFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE, mSampleRate);
61             mConfigFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, mChannels);
62         } else {
63             mWidth = encoderInfo1;
64             mHeight = encoderInfo2;
65             mFrameRate = frameRate;
66             mConfigFormat.setInteger(MediaFormat.KEY_WIDTH, mWidth);
67             mConfigFormat.setInteger(MediaFormat.KEY_HEIGHT, mHeight);
68             mConfigFormat.setInteger(MediaFormat.KEY_FRAME_RATE, mFrameRate);
69             mConfigFormat.setFloat(MediaFormat.KEY_I_FRAME_INTERVAL, 1.0f);
70             mConfigFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
71                     MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible);
72         }
73     }
74 
75     @Parameterized.Parameters(name = "{index}({0})")
input()76     public static Collection<Object[]> input() {
77         ArrayList<String> cddRequiredMimeList = new ArrayList<>();
78         if (isHandheld() || isTv() || isAutomotive()) {
79             // sec 2.2.2, 2.3.2, 2.5.2
80             cddRequiredMimeList.add(MediaFormat.MIMETYPE_AUDIO_AAC);
81             cddRequiredMimeList.add(MediaFormat.MIMETYPE_VIDEO_AVC);
82             cddRequiredMimeList.add(MediaFormat.MIMETYPE_VIDEO_VP8);
83         }
84         final List<Object[]> exhaustiveArgsList = Arrays.asList(new Object[][]{
85                 // Audio - CodecMime, bit-rate, sample rate, channel count
86                 {MediaFormat.MIMETYPE_AUDIO_AAC, 64000, 48000, 1, -1},
87                 {MediaFormat.MIMETYPE_AUDIO_AAC, 128000, 48000, 2, -1},
88 
89                 // Video - CodecMime, bit-rate, height, width, frame-rate
90                 // TODO (b/151423508)
91                 /*{MediaFormat.MIMETYPE_VIDEO_AVC, 64000, 176, 144, 15},
92                 {MediaFormat.MIMETYPE_VIDEO_AVC, 128000, 176, 144, 15},
93                 {MediaFormat.MIMETYPE_VIDEO_AVC, 192000, 352, 288, 7},
94                 {MediaFormat.MIMETYPE_VIDEO_AVC, 384000, 352, 288, 15},*/
95                 {MediaFormat.MIMETYPE_VIDEO_AVC, 768000, 352, 288, 30},
96                 {MediaFormat.MIMETYPE_VIDEO_AVC, 2000000, 352, 288, 30},
97                 // TODO (b/151423508)
98                 /*{MediaFormat.MIMETYPE_VIDEO_AVC, 4000000, 352, 576, 25},
99                 {MediaFormat.MIMETYPE_VIDEO_AVC, 4000000, 720, 576, 12},
100                 {MediaFormat.MIMETYPE_VIDEO_AVC, 10000000, 720, 576, 25},*/
101                 {MediaFormat.MIMETYPE_VIDEO_AVC, 14000000, 1280, 720, 30},
102                 {MediaFormat.MIMETYPE_VIDEO_AVC, 20000000, 1280, 1024, 42},
103                 {MediaFormat.MIMETYPE_VIDEO_AVC, 20000000, 2048, 1024, 30},
104                 {MediaFormat.MIMETYPE_VIDEO_AVC, 50000000, 2048, 1024, 30},
105                 {MediaFormat.MIMETYPE_VIDEO_AVC, 50000000, 2048, 1080, 60},
106                 {MediaFormat.MIMETYPE_VIDEO_AVC, 135000000, 3672, 1536, 25},
107                 {MediaFormat.MIMETYPE_VIDEO_AVC, 240000000, 4096, 2304, 25},
108                 {MediaFormat.MIMETYPE_VIDEO_AVC, 240000000, 4096, 2304, 50},
109                 {MediaFormat.MIMETYPE_VIDEO_AVC, 240000000, 8192, 4320, 30},
110                 {MediaFormat.MIMETYPE_VIDEO_AVC, 480000000, 8192, 4320, 60},
111                 {MediaFormat.MIMETYPE_VIDEO_AVC, 800000000, 8192, 4320, 120},
112 
113                 {MediaFormat.MIMETYPE_VIDEO_MPEG2, 4000000, 352, 288, 30},
114                 {MediaFormat.MIMETYPE_VIDEO_MPEG2, 15000000, 720, 576, 30},
115                 {MediaFormat.MIMETYPE_VIDEO_MPEG2, 60000000, 1440, 1088, 60},
116                 {MediaFormat.MIMETYPE_VIDEO_MPEG2, 80000000, 1920, 1088, 60},
117                 {MediaFormat.MIMETYPE_VIDEO_MPEG2, 80000000, 1920, 1088, 60},
118 
119                 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 64000, 176, 144, 15},
120                 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 64000, 176, 144, 30},
121                 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 128000, 176, 144, 15},
122                 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 128000, 352, 288, 30},
123                 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 384000, 352, 288, 30},
124                 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 4000000, 640, 480, 30},
125                 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 8000000, 720, 576, 30},
126                 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 12000000, 1280, 720, 30},
127                 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 128000, 176, 144, 30},
128                 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 384000, 352, 288, 30},
129                 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 768000, 352, 288, 30},
130                 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 1500000, 352, 288, 30},
131                 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 3000000, 704, 576, 30},
132                 {MediaFormat.MIMETYPE_VIDEO_MPEG4, 8000000, 720, 576, 30},
133 
134                 // TODO (b/151430764)
135                 /*{MediaFormat.MIMETYPE_VIDEO_VP9, 200000, 256, 144, 15},
136                 {MediaFormat.MIMETYPE_VIDEO_VP9, 8000000, 384, 192, 30},
137                 {MediaFormat.MIMETYPE_VIDEO_VP9, 1800000, 480, 256, 30},
138                 {MediaFormat.MIMETYPE_VIDEO_VP9, 3600000, 640, 384, 30},
139                 {MediaFormat.MIMETYPE_VIDEO_VP9, 7200000, 1080, 512, 30},*/
140                 {MediaFormat.MIMETYPE_VIDEO_VP9, 12000000, 1280, 768, 30},
141                 {MediaFormat.MIMETYPE_VIDEO_VP9, 18000000, 2048, 1088, 30},
142                 {MediaFormat.MIMETYPE_VIDEO_VP9, 30000000, 2048, 1088, 60},
143                 {MediaFormat.MIMETYPE_VIDEO_VP9, 60000000, 4096, 2176, 30},
144                 {MediaFormat.MIMETYPE_VIDEO_VP9, 120000000, 4096, 2176, 60},
145                 {MediaFormat.MIMETYPE_VIDEO_VP9, 180000000, 4096, 2176, 120},
146                 {MediaFormat.MIMETYPE_VIDEO_VP9, 180000000, 8192, 4352, 30},
147                 {MediaFormat.MIMETYPE_VIDEO_VP9, 240000000, 8192, 4352, 60},
148                 {MediaFormat.MIMETYPE_VIDEO_VP9, 480000000, 8192, 4352, 120},
149 
150                 {MediaFormat.MIMETYPE_VIDEO_H263, 64000, 176, 144, 15},
151                 {MediaFormat.MIMETYPE_VIDEO_H263, 128000, 176, 144, 15},
152                 {MediaFormat.MIMETYPE_VIDEO_H263, 128000, 176, 144, 30},
153                 {MediaFormat.MIMETYPE_VIDEO_H263, 128000, 352, 288, 15},
154                 {MediaFormat.MIMETYPE_VIDEO_H263, 384000, 352, 288, 30},
155                 {MediaFormat.MIMETYPE_VIDEO_H263, 2048000, 352, 288, 30},
156                 {MediaFormat.MIMETYPE_VIDEO_H263, 4096000, 352, 240, 60},
157                 {MediaFormat.MIMETYPE_VIDEO_H263, 4096000, 352, 288, 50},
158                 {MediaFormat.MIMETYPE_VIDEO_H263, 8192000, 720, 240, 60},
159                 {MediaFormat.MIMETYPE_VIDEO_H263, 8192000, 720, 288, 50},
160                 {MediaFormat.MIMETYPE_VIDEO_H263, 16384000, 720, 480, 60},
161                 {MediaFormat.MIMETYPE_VIDEO_H263, 16384000, 720, 576, 50},
162 
163                 // TODO (b/151429828)
164                 //{MediaFormat.MIMETYPE_VIDEO_HEVC, 128000, 176, 144, 15},
165                 {MediaFormat.MIMETYPE_VIDEO_HEVC, 1500000, 352, 288, 30},
166                 // TODO (b/152576008) - Limit HEVC Encoder test to 512x512
167                 {MediaFormat.MIMETYPE_VIDEO_HEVC, 3000000, 512, 512, 30},
168                 //{MediaFormat.MIMETYPE_VIDEO_HEVC, 3000000, 640, 360, 30},
169                 //{MediaFormat.MIMETYPE_VIDEO_HEVC, 6000000, 960, 540, 30},
170                 {MediaFormat.MIMETYPE_VIDEO_HEVC, 10000000, 1280, 720, 33},
171                 {MediaFormat.MIMETYPE_VIDEO_HEVC, 12000000, 2048, 1080, 30},
172                 {MediaFormat.MIMETYPE_VIDEO_HEVC, 20000000, 2048, 1080, 60},
173                 {MediaFormat.MIMETYPE_VIDEO_HEVC, 25000000, 4096, 2160, 30},
174                 {MediaFormat.MIMETYPE_VIDEO_HEVC, 40000000, 4096, 2160, 60},
175                 {MediaFormat.MIMETYPE_VIDEO_HEVC, 60000000, 4096, 2160, 120},
176                 {MediaFormat.MIMETYPE_VIDEO_HEVC, 60000000, 8192, 4320, 30},
177                 {MediaFormat.MIMETYPE_VIDEO_HEVC, 120000000, 8192, 4320, 60},
178                 {MediaFormat.MIMETYPE_VIDEO_HEVC, 240000000, 8192, 4320, 120},
179 
180                 {MediaFormat.MIMETYPE_VIDEO_AV1, 1500000, 426, 240, 30},
181                 {MediaFormat.MIMETYPE_VIDEO_AV1, 3000000, 640, 360, 30},
182                 {MediaFormat.MIMETYPE_VIDEO_AV1, 6000000, 854, 480, 30},
183                 {MediaFormat.MIMETYPE_VIDEO_AV1, 10000000, 1280, 720, 30},
184                 {MediaFormat.MIMETYPE_VIDEO_AV1, 12000000, 1920, 1080, 30},
185                 {MediaFormat.MIMETYPE_VIDEO_AV1, 20000000, 1920, 1080, 60},
186                 {MediaFormat.MIMETYPE_VIDEO_AV1, 30000000, 3840, 2160, 30},
187                 {MediaFormat.MIMETYPE_VIDEO_AV1, 40000000, 3840, 2160, 60},
188                 {MediaFormat.MIMETYPE_VIDEO_AV1, 60000000, 3840, 2160, 120},
189                 {MediaFormat.MIMETYPE_VIDEO_AV1, 60000000, 7680, 4320, 30},
190                 {MediaFormat.MIMETYPE_VIDEO_AV1, 100000000, 7680, 4320, 60},
191                 {MediaFormat.MIMETYPE_VIDEO_AV1, 160000000, 7680, 4320, 120},
192 
193                 {MediaFormat.MIMETYPE_VIDEO_VP8, 512000, 176, 144, 20},
194                 {MediaFormat.MIMETYPE_VIDEO_VP8, 512000, 480, 360, 20},
195         });
196         return prepareParamList(cddRequiredMimeList, exhaustiveArgsList, true);
197     }
198 
199     static {
mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_AVC, new int[]{AVCProfileBaseline, AVCProfileMain, AVCProfileExtended, AVCProfileHigh, AVCProfileHigh10, AVCProfileHigh422, AVCProfileHigh444, AVCProfileConstrainedBaseline, AVCProfileConstrainedHigh})200         mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_AVC,
201                 new int[]{AVCProfileBaseline, AVCProfileMain, AVCProfileExtended, AVCProfileHigh,
202                         AVCProfileHigh10, AVCProfileHigh422, AVCProfileHigh444,
203                         AVCProfileConstrainedBaseline, AVCProfileConstrainedHigh});
mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_HEVC, new int[]{HEVCProfileMain, HEVCProfileMain10, HEVCProfileMainStill, HEVCProfileMain10HDR10, HEVCProfileMain10HDR10Plus})204         mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_HEVC,
205                 new int[]{HEVCProfileMain, HEVCProfileMain10, HEVCProfileMainStill,
206                         HEVCProfileMain10HDR10, HEVCProfileMain10HDR10Plus});
mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_H263, new int[]{H263ProfileBaseline, H263ProfileH320Coding, H263ProfileBackwardCompatible, H263ProfileISWV2, H263ProfileISWV3, H263ProfileHighCompression, H263ProfileInternet, H263ProfileInterlace, H263ProfileHighLatency})207         mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_H263,
208                 new int[]{H263ProfileBaseline, H263ProfileH320Coding,
209                         H263ProfileBackwardCompatible, H263ProfileISWV2, H263ProfileISWV3,
210                         H263ProfileHighCompression, H263ProfileInternet, H263ProfileInterlace,
211                         H263ProfileHighLatency});
mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_MPEG2, new int[]{MPEG2ProfileSimple, MPEG2ProfileMain, MPEG2Profile422, MPEG2ProfileSNR, MPEG2ProfileSpatial, MPEG2ProfileHigh})212         mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_MPEG2,
213                 new int[]{MPEG2ProfileSimple, MPEG2ProfileMain, MPEG2Profile422, MPEG2ProfileSNR,
214                         MPEG2ProfileSpatial, MPEG2ProfileHigh});
mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_MPEG4, new int[]{MPEG4ProfileSimple, MPEG4ProfileSimpleScalable, MPEG4ProfileCore, MPEG4ProfileMain, MPEG4ProfileNbit, MPEG4ProfileScalableTexture, MPEG4ProfileSimpleFace, MPEG4ProfileSimpleFBA, MPEG4ProfileBasicAnimated, MPEG4ProfileHybrid, MPEG4ProfileAdvancedRealTime, MPEG4ProfileCoreScalable, MPEG4ProfileAdvancedCoding, MPEG4ProfileAdvancedCore, MPEG4ProfileAdvancedScalable, MPEG4ProfileAdvancedSimple})215         mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_MPEG4,
216                 new int[]{MPEG4ProfileSimple, MPEG4ProfileSimpleScalable, MPEG4ProfileCore,
217                         MPEG4ProfileMain, MPEG4ProfileNbit, MPEG4ProfileScalableTexture,
218                         MPEG4ProfileSimpleFace, MPEG4ProfileSimpleFBA, MPEG4ProfileBasicAnimated,
219                         MPEG4ProfileHybrid, MPEG4ProfileAdvancedRealTime,
220                         MPEG4ProfileCoreScalable, MPEG4ProfileAdvancedCoding,
221                         MPEG4ProfileAdvancedCore, MPEG4ProfileAdvancedScalable,
222                         MPEG4ProfileAdvancedSimple});
mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_VP8, new int[]{VP8ProfileMain})223         mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_VP8, new int[]{VP8ProfileMain});
mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_VP9, new int[]{VP9Profile0, VP9Profile1, VP9Profile2, VP9Profile3, VP9Profile2HDR, VP9Profile3HDR, VP9Profile2HDR10Plus, VP9Profile3HDR10Plus})224         mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_VP9,
225                 new int[]{VP9Profile0, VP9Profile1, VP9Profile2, VP9Profile3, VP9Profile2HDR,
226                         VP9Profile3HDR, VP9Profile2HDR10Plus, VP9Profile3HDR10Plus});
mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_AV1, new int[]{AV1ProfileMain8, AV1ProfileMain10, AV1ProfileMain10HDR10, AV1ProfileMain10HDR10Plus})227         mProfileMap.put(MediaFormat.MIMETYPE_VIDEO_AV1,
228                 new int[]{AV1ProfileMain8, AV1ProfileMain10, AV1ProfileMain10HDR10,
229                         AV1ProfileMain10HDR10Plus});
mProfileMap.put(MediaFormat.MIMETYPE_AUDIO_AAC, new int[]{AACObjectMain, AACObjectLC, AACObjectSSR, AACObjectLTP, AACObjectHE, AACObjectScalable, AACObjectERLC, AACObjectERScalable, AACObjectLD, AACObjectELD, AACObjectXHE})230         mProfileMap.put(MediaFormat.MIMETYPE_AUDIO_AAC,
231                 new int[]{AACObjectMain, AACObjectLC, AACObjectSSR, AACObjectLTP, AACObjectHE,
232                         AACObjectScalable, AACObjectERLC, AACObjectERScalable, AACObjectLD,
233                         AACObjectELD, AACObjectXHE});
234     }
235 
236     static {
mProfileLevelCdd.put(MediaFormat.MIMETYPE_AUDIO_AAC, new Pair<>(new int[]{AACObjectLC, AACObjectHE, AACObjectELD}, -1))237         mProfileLevelCdd.put(MediaFormat.MIMETYPE_AUDIO_AAC,
238                 new Pair<>(new int[]{AACObjectLC, AACObjectHE, AACObjectELD}, -1));
mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_H263, new Pair<>(new int[]{H263ProfileBaseline}, H263Level45))239         mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_H263,
240                 new Pair<>(new int[]{H263ProfileBaseline}, H263Level45));
mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_AVC, new Pair<>(new int[]{AVCProfileBaseline}, AVCLevel3))241         mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_AVC,
242                 new Pair<>(new int[]{AVCProfileBaseline}, AVCLevel3));
mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_HEVC, new Pair<>(new int[]{HEVCProfileMain}, HEVCMainTierLevel3))243         mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_HEVC,
244                 new Pair<>(new int[]{HEVCProfileMain}, HEVCMainTierLevel3));
mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_VP8, new Pair<>(new int[]{VP8ProfileMain}, VP8Level_Version0))245         mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_VP8,
246                 new Pair<>(new int[]{VP8ProfileMain}, VP8Level_Version0));
mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_VP9, new Pair<>(new int[]{VP9Profile0}, VP9Level3))247         mProfileLevelCdd.put(MediaFormat.MIMETYPE_VIDEO_VP9,
248                 new Pair<>(new int[]{VP9Profile0}, VP9Level3));
249     }
250 
getMinLevel(String mime, int width, int height, int frameRate, int bitrate, int profile)251     private int getMinLevel(String mime, int width, int height, int frameRate, int bitrate,
252             int profile) {
253         switch (mime) {
254             case MediaFormat.MIMETYPE_VIDEO_AVC:
255                 return getMinLevelAVC(width, height, frameRate, bitrate);
256             case MediaFormat.MIMETYPE_VIDEO_HEVC:
257                 return getMinLevelHEVC(width, height, frameRate, bitrate);
258             case MediaFormat.MIMETYPE_VIDEO_H263:
259                 return getMinLevelH263(width, height, frameRate, bitrate);
260             case MediaFormat.MIMETYPE_VIDEO_MPEG2:
261                 return getMinLevelMPEG2(width, height, frameRate, bitrate);
262             case MediaFormat.MIMETYPE_VIDEO_MPEG4:
263                 return getMinLevelMPEG4(width, height, frameRate, bitrate, profile);
264             // complex features disabled in VP8 Level/Version 0
265             case MediaFormat.MIMETYPE_VIDEO_VP8:
266                 return VP8Level_Version0;
267             case MediaFormat.MIMETYPE_VIDEO_VP9:
268                 return getMinLevelVP9(width, height, frameRate, bitrate);
269             case MediaFormat.MIMETYPE_VIDEO_AV1:
270                 return getMinLevelAV1(width, height, frameRate, bitrate);
271             default:
272                 return -1;
273         }
274     }
275 
getMinLevelAVC(int width, int height, int frameRate, int bitrate)276     private int getMinLevelAVC(int width, int height, int frameRate, int bitrate) {
277         class LevelLimitAVC {
278             private LevelLimitAVC(int level, int mbsPerSec, long mbs, int bitrate) {
279                 this.level = level;
280                 this.mbsPerSec = mbsPerSec;
281                 this.mbs = mbs;
282                 this.bitrate = bitrate;
283             }
284 
285             private final int level;
286             private final int mbsPerSec;
287             private final long mbs;
288             private final int bitrate;
289         }
290         LevelLimitAVC[] limitsAVC = {
291                 new LevelLimitAVC(AVCLevel1, 1485, 99, 64000),
292                 new LevelLimitAVC(AVCLevel1b, 1485, 99, 128000),
293                 new LevelLimitAVC(AVCLevel11, 3000, 396, 192000),
294                 new LevelLimitAVC(AVCLevel12, 6000, 396, 384000),
295                 new LevelLimitAVC(AVCLevel13, 11880, 396, 768000),
296                 new LevelLimitAVC(AVCLevel2, 11880, 396, 2000000),
297                 new LevelLimitAVC(AVCLevel21, 19800, 792, 4000000),
298                 new LevelLimitAVC(AVCLevel22, 20250, 1620, 4000000),
299                 new LevelLimitAVC(AVCLevel3, 40500, 1620, 10000000),
300                 new LevelLimitAVC(AVCLevel31, 108000, 3600, 14000000),
301                 new LevelLimitAVC(AVCLevel32, 216000, 5120, 20000000),
302                 new LevelLimitAVC(AVCLevel4, 245760, 8192, 20000000),
303                 new LevelLimitAVC(AVCLevel41, 245760, 8192, 50000000),
304                 new LevelLimitAVC(AVCLevel42, 522240, 8704, 50000000),
305                 new LevelLimitAVC(AVCLevel5, 589824, 22080, 135000000),
306                 new LevelLimitAVC(AVCLevel51, 983040, 36864, 240000000),
307                 new LevelLimitAVC(AVCLevel52, 2073600, 36864, 240000000),
308                 new LevelLimitAVC(AVCLevel6, 4177920, 139264, 240000000),
309                 new LevelLimitAVC(AVCLevel61, 8355840, 139264, 480000000),
310                 new LevelLimitAVC(AVCLevel62, 16711680, 139264, 800000000),
311         };
312         long mbs = ((width + 15) / 16) * ((height + 15) / 16);
313         float mbsPerSec = mbs * frameRate;
314         for (LevelLimitAVC levelLimitsAVC : limitsAVC) {
315             if (mbs <= levelLimitsAVC.mbs && mbsPerSec <= levelLimitsAVC.mbsPerSec
316                     && bitrate <= levelLimitsAVC.bitrate) {
317                 return levelLimitsAVC.level;
318             }
319         }
320         // if none of the levels suffice, select the highest level
321         return AVCLevel62;
322     }
323 
getMinLevelHEVC(int width, int height, int frameRate, int bitrate)324     private int getMinLevelHEVC(int width, int height, int frameRate, int bitrate) {
325         class LevelLimitHEVC {
326             private LevelLimitHEVC(int level, int frameRate, long samples, int bitrate) {
327                 this.level = level;
328                 this.frameRate = frameRate;
329                 this.samples = samples;
330                 this.bitrate = bitrate;
331             }
332 
333             private final int level;
334             private final int frameRate;
335             private final long samples;
336             private final int bitrate;
337         }
338         LevelLimitHEVC[] limitsHEVC = {
339                 new LevelLimitHEVC(HEVCMainTierLevel1, 15, 36864, 128000),
340                 new LevelLimitHEVC(HEVCMainTierLevel2, 30, 122880, 1500000),
341                 new LevelLimitHEVC(HEVCMainTierLevel21, 30, 245760, 3000000),
342                 new LevelLimitHEVC(HEVCMainTierLevel3, 30, 552960, 6000000),
343                 new LevelLimitHEVC(HEVCMainTierLevel31, 30, 983040, 10000000),
344                 new LevelLimitHEVC(HEVCMainTierLevel4, 30, 2228224, 12000000),
345                 new LevelLimitHEVC(HEVCHighTierLevel4, 30, 2228224, 30000000),
346                 new LevelLimitHEVC(HEVCMainTierLevel41, 60, 2228224, 20000000),
347                 new LevelLimitHEVC(HEVCHighTierLevel41, 60, 2228224, 50000000),
348                 new LevelLimitHEVC(HEVCMainTierLevel5, 30, 8912896, 25000000),
349                 new LevelLimitHEVC(HEVCHighTierLevel5, 30, 8912896, 100000000),
350                 new LevelLimitHEVC(HEVCMainTierLevel51, 60, 8912896, 40000000),
351                 new LevelLimitHEVC(HEVCHighTierLevel51, 60, 8912896, 160000000),
352                 new LevelLimitHEVC(HEVCMainTierLevel52, 120, 8912896, 60000000),
353                 new LevelLimitHEVC(HEVCHighTierLevel52, 120, 8912896, 240000000),
354                 new LevelLimitHEVC(HEVCMainTierLevel6, 30, 35651584, 60000000),
355                 new LevelLimitHEVC(HEVCHighTierLevel6, 30, 35651584, 240000000),
356                 new LevelLimitHEVC(HEVCMainTierLevel61, 60, 35651584, 120000000),
357                 new LevelLimitHEVC(HEVCHighTierLevel61, 60, 35651584, 480000000),
358                 new LevelLimitHEVC(HEVCMainTierLevel62, 120, 35651584, 240000000),
359                 new LevelLimitHEVC(HEVCHighTierLevel62, 120, 35651584, 800000000),
360         };
361         long samples = width * height;
362         for (LevelLimitHEVC levelLimitsHEVC : limitsHEVC) {
363             if (samples <= levelLimitsHEVC.samples && frameRate <= levelLimitsHEVC.frameRate
364                     && bitrate <= levelLimitsHEVC.bitrate) {
365                 return levelLimitsHEVC.level;
366             }
367         }
368         // if none of the levels suffice, select the highest level
369         return HEVCHighTierLevel62;
370     }
371 
getMinLevelH263(int width, int height, int frameRate, int bitrate)372     private int getMinLevelH263(int width, int height, int frameRate, int bitrate) {
373         class LevelLimitH263 {
374             private LevelLimitH263(int level, int height, int width, int frameRate,
375                     int bitrate) {
376                 this.level = level;
377                 this.height = height;
378                 this.width = width;
379                 this.frameRate = frameRate;
380                 this.bitrate = bitrate;
381             }
382 
383             private final int level;
384             private final int height;
385             private final int width;
386             private final int frameRate;
387             private final int bitrate;
388         }
389         LevelLimitH263[] limitsH263 = {
390                 new LevelLimitH263(H263Level10, 176, 144, 15, 64000),
391                 new LevelLimitH263(H263Level45, 176, 144, 15, 128000),
392                 new LevelLimitH263(H263Level20, 176, 144, 30, 128000),
393                 new LevelLimitH263(H263Level20, 352, 288, 15, 128000),
394                 new LevelLimitH263(H263Level30, 352, 288, 30, 384000),
395                 new LevelLimitH263(H263Level40, 352, 288, 30, 2048000),
396                 new LevelLimitH263(H263Level50, 352, 240, 60, 4096000),
397                 new LevelLimitH263(H263Level50, 352, 288, 50, 4096000),
398                 new LevelLimitH263(H263Level60, 720, 240, 60, 8192000),
399                 new LevelLimitH263(H263Level60, 720, 288, 50, 8192000),
400                 new LevelLimitH263(H263Level70, 720, 480, 60, 16384000),
401                 new LevelLimitH263(H263Level70, 720, 576, 50, 16384000),
402         };
403         for (LevelLimitH263 levelLimitsH263 : limitsH263) {
404             if (height <= levelLimitsH263.height && width <= levelLimitsH263.width &&
405                     frameRate <= levelLimitsH263.frameRate && bitrate <= levelLimitsH263.bitrate) {
406                 return levelLimitsH263.level;
407             }
408         }
409         // if none of the levels suffice, select the highest level
410         return H263Level70;
411     }
412 
getMinLevelVP9(int width, int height, int frameRate, int bitrate)413     private int getMinLevelVP9(int width, int height, int frameRate, int bitrate) {
414         class LevelLimitVP9 {
415             private LevelLimitVP9(int level, long sampleRate, int size, int breadth,
416                     int bitrate) {
417                 this.level = level;
418                 this.sampleRate = sampleRate;
419                 this.size = size;
420                 this.breadth = breadth;
421                 this.bitrate = bitrate;
422             }
423 
424             private final int level;
425             private final long sampleRate;
426             private final int size;
427             private final int breadth;
428             private final int bitrate;
429         }
430         LevelLimitVP9[] limitsVP9 = {
431                 new LevelLimitVP9(VP9Level1, 829440, 36864, 512, 200000),
432                 new LevelLimitVP9(VP9Level11, 2764800, 73728, 768, 800000),
433                 new LevelLimitVP9(VP9Level2, 4608000, 122880, 960, 1800000),
434                 new LevelLimitVP9(VP9Level21, 9216000, 245760, 1344, 3600000),
435                 new LevelLimitVP9(VP9Level3, 20736000, 552960, 2048, 7200000),
436                 new LevelLimitVP9(VP9Level31, 36864000, 983040, 2752, 12000000),
437                 new LevelLimitVP9(VP9Level4, 83558400, 2228224, 4160, 18000000),
438                 new LevelLimitVP9(VP9Level41, 160432128, 2228224, 4160, 30000000),
439                 new LevelLimitVP9(VP9Level5, 311951360, 8912896, 8384, 60000000),
440                 new LevelLimitVP9(VP9Level51, 588251136, 8912896, 8384, 120000000),
441                 new LevelLimitVP9(VP9Level52, 1176502272, 8912896, 8384, 180000000),
442                 new LevelLimitVP9(VP9Level6, 1176502272, 35651584, 16832, 180000000),
443                 new LevelLimitVP9(VP9Level61, 2353004544L, 35651584, 16832, 240000000),
444                 new LevelLimitVP9(VP9Level62, 4706009088L, 35651584, 16832, 480000000),
445         };
446         int size = width * height;
447         int sampleRate = size * frameRate;
448         int breadth = Math.max(width, height);
449         for (LevelLimitVP9 levelLimitsVP9 : limitsVP9) {
450             if (sampleRate <= levelLimitsVP9.sampleRate && size <= levelLimitsVP9.size &&
451                     breadth <= levelLimitsVP9.breadth && bitrate <= levelLimitsVP9.bitrate) {
452                 return levelLimitsVP9.level;
453             }
454         }
455         // if none of the levels suffice, select the highest level
456         return VP9Level62;
457     }
458 
getMinLevelMPEG2(int width, int height, int frameRate, int bitrate)459     private int getMinLevelMPEG2(int width, int height, int frameRate, int bitrate) {
460         class LevelLimitMPEG2 {
461             private LevelLimitMPEG2(int level, long sampleRate, int width, int height,
462                     int frameRate, int bitrate) {
463                 this.level = level;
464                 this.sampleRate = sampleRate;
465                 this.width = width;
466                 this.height = height;
467                 this.frameRate = frameRate;
468                 this.bitrate = bitrate;
469             }
470 
471             private final int level;
472             private final long sampleRate;
473             private final int width;
474             private final int height;
475             private final int frameRate;
476             private final int bitrate;
477         }
478         // main profile limits, higher profiles will also support selected level
479         LevelLimitMPEG2[] limitsMPEG2 = {
480                 new LevelLimitMPEG2(MPEG2LevelLL, 3041280, 352, 288, 30, 4000000),
481                 new LevelLimitMPEG2(MPEG2LevelML, 10368000, 720, 576, 30, 15000000),
482                 new LevelLimitMPEG2(MPEG2LevelH14, 47001600, 1440, 1088, 60, 60000000),
483                 new LevelLimitMPEG2(MPEG2LevelHL, 62668800, 1920, 1088, 60, 80000000),
484                 new LevelLimitMPEG2(MPEG2LevelHP, 125337600, 1920, 1088, 60, 80000000),
485         };
486         int size = width * height;
487         int sampleRate = size * frameRate;
488         for (LevelLimitMPEG2 levelLimitsMPEG2 : limitsMPEG2) {
489             if (sampleRate <= levelLimitsMPEG2.sampleRate && width <= levelLimitsMPEG2.width &&
490                     height <= levelLimitsMPEG2.height && frameRate <= levelLimitsMPEG2.frameRate &&
491                     bitrate <= levelLimitsMPEG2.bitrate) {
492                 return levelLimitsMPEG2.level;
493             }
494         }
495         // if none of the levels suffice, select the highest level
496         return MPEG2LevelHP;
497     }
498 
getMinLevelMPEG4(int width, int height, int frameRate, int bitrate, int profile)499     private int getMinLevelMPEG4(int width, int height, int frameRate, int bitrate, int profile) {
500         class LevelLimitMPEG4 {
501             private LevelLimitMPEG4(int profile, int level, long sampleRate, int width,
502                     int height, int frameRate, int bitrate) {
503                 this.profile = profile;
504                 this.level = level;
505                 this.sampleRate = sampleRate;
506                 this.width = width;
507                 this.height = height;
508                 this.frameRate = frameRate;
509                 this.bitrate = bitrate;
510             }
511 
512             private final int profile;
513             private final int level;
514             private final long sampleRate;
515             private final int width;
516             private final int height;
517             private final int frameRate;
518             private final int bitrate;
519         }
520         // simple profile limits, higher profiles will also support selected level
521         LevelLimitMPEG4[] limitsMPEG4 = {
522                 new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level0, 380160, 176, 144, 15, 64000),
523                 new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level1, 380160, 176, 144, 30, 64000),
524                 new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level0b, 380160, 176, 144, 15, 128000),
525                 new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level2, 1520640, 352, 288, 30, 128000),
526                 new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level3, 3041280, 352, 288, 30, 384000),
527                 new LevelLimitMPEG4(
528                         MPEG4ProfileSimple, MPEG4Level4a, 9216000, 640, 480, 30, 4000000),
529                 new LevelLimitMPEG4(
530                         MPEG4ProfileSimple, MPEG4Level5, 10368000, 720, 576, 30, 8000000),
531                 new LevelLimitMPEG4(
532                         MPEG4ProfileSimple, MPEG4Level6, 27648000, 1280, 720, 30, 12000000),
533                 new LevelLimitMPEG4(
534                         MPEG4ProfileAdvancedSimple, MPEG4Level1, 760320, 176, 144, 30, 128000),
535                 new LevelLimitMPEG4(
536                         MPEG4ProfileAdvancedSimple, MPEG4Level2, 1520640, 352, 288, 30, 384000),
537                 new LevelLimitMPEG4(
538                         MPEG4ProfileAdvancedSimple, MPEG4Level3, 3041280, 352, 288, 30, 768000),
539                 new LevelLimitMPEG4(
540                         MPEG4ProfileAdvancedSimple, MPEG4Level3b, 3041280, 352, 288, 30, 1500000),
541                 new LevelLimitMPEG4(
542                         MPEG4ProfileAdvancedSimple, MPEG4Level4, 3041280, 704, 576, 30, 3000000),
543                 new LevelLimitMPEG4(
544                         MPEG4ProfileAdvancedSimple, MPEG4Level5, 3041280, 720, 576, 30, 8000000),
545         };
546         int size = width * height;
547         int sampleRate = size * frameRate;
548         for (LevelLimitMPEG4 levelLimitsMPEG4 : limitsMPEG4) {
549             if (((profile & (MPEG4ProfileAdvancedSimple | MPEG4ProfileSimple)) != 0) &&
550                     profile != levelLimitsMPEG4.profile) continue;
551             if (sampleRate <= levelLimitsMPEG4.sampleRate && width <= levelLimitsMPEG4.width &&
552                     height <= levelLimitsMPEG4.height && frameRate <= levelLimitsMPEG4.frameRate &&
553                     bitrate <= levelLimitsMPEG4.bitrate) {
554                 return levelLimitsMPEG4.level;
555             }
556         }
557         // if none of the levels suffice, select the highest level
558         return MPEG4Level6;
559     }
560 
getMinLevelAV1(int width, int height, int frameRate, int bitrate)561     private int getMinLevelAV1(int width, int height, int frameRate, int bitrate) {
562         class LevelLimitAV1 {
563             private LevelLimitAV1(int level, int size, int width, int height, long sampleRate,
564                     int bitrate) {
565                 this.level = level;
566                 this.size = size;
567                 this.width = width;
568                 this.height = height;
569                 this.sampleRate = sampleRate;
570                 this.bitrate = bitrate;
571             }
572 
573             private final int level;
574             private final int size;
575             private final int width;
576             private final int height;
577             private final long sampleRate;
578             private final int bitrate;
579         }
580         // taking bitrate from main profile, will also be supported by high profile
581         LevelLimitAV1[] limitsAV1 = {
582                 new LevelLimitAV1(AV1Level2, 147456, 2048, 1152, 4423680, 1500000),
583                 new LevelLimitAV1(AV1Level21, 278784, 2816, 1584, 8363520, 3000000),
584                 new LevelLimitAV1(AV1Level3, 665856, 4352, 2448, 19975680, 6000000),
585                 new LevelLimitAV1(AV1Level31, 1065024, 5504, 3096, 31950720, 10000000),
586                 new LevelLimitAV1(AV1Level4, 2359296, 6144, 3456, 70778880, 12000000),
587                 new LevelLimitAV1(AV1Level41, 2359296, 6144, 3456, 141557760, 20000000),
588                 new LevelLimitAV1(AV1Level5, 8912896, 8192, 4352, 267386880, 30000000),
589                 new LevelLimitAV1(AV1Level51, 8912896, 8192, 4352, 534773760, 40000000),
590                 new LevelLimitAV1(AV1Level52, 8912896, 8192, 4352, 1069547520, 60000000),
591                 new LevelLimitAV1(AV1Level53, 8912896, 8192, 4352, 1069547520, 60000000),
592                 new LevelLimitAV1(AV1Level6, 35651584, 16384, 8704, 1069547520, 60000000),
593                 new LevelLimitAV1(AV1Level61, 35651584, 16384, 8704, 2139095040, 100000000),
594                 new LevelLimitAV1(AV1Level62, 35651584, 16384, 8704, 4278190080L, 160000000),
595                 new LevelLimitAV1(AV1Level63, 35651584, 16384, 8704, 4278190080L, 160000000),
596         };
597         int size = width * height;
598         int sampleRate = size * frameRate;
599         for (LevelLimitAV1 levelLimitsAV1 : limitsAV1) {
600             if (size <= levelLimitsAV1.size && width <= levelLimitsAV1.width &&
601                     height <= levelLimitsAV1.height && sampleRate <= levelLimitsAV1.sampleRate &&
602                     bitrate <= levelLimitsAV1.bitrate) {
603                 return levelLimitsAV1.level;
604             }
605         }
606         // if none of the levels suffice or high profile, select the highest level
607         return AV1Level73;
608     }
609 
610     @Override
isFormatSimilar(MediaFormat inpFormat, MediaFormat outFormat)611     boolean isFormatSimilar(MediaFormat inpFormat, MediaFormat outFormat) {
612         if (!super.isFormatSimilar(inpFormat, outFormat)) {
613             Log.e(LOG_TAG, "Basic channel-rate/resolution comparisons failed");
614             return false;
615         }
616         String inpMime = inpFormat.getString(MediaFormat.KEY_MIME);
617         String outMime = outFormat.getString(MediaFormat.KEY_MIME);
618         assertTrue("Input and Output mimes are different.", inpMime.equals(outMime));
619         if (outMime.startsWith("audio/")) {
620             if (outFormat.getString(MediaFormat.KEY_MIME).equals(MediaFormat.MIMETYPE_AUDIO_AAC)) {
621                 if (!outFormat.containsKey(MediaFormat.KEY_AAC_PROFILE)) {
622                     Log.e(LOG_TAG, "Output format doesn't contain aac-profile key");
623                     //TODO (b/151429829)
624                     if (true) return true;
625                     return false;
626                 }
627                 if (!inpFormat.containsKey(MediaFormat.KEY_AAC_PROFILE)) {
628                     Log.e(LOG_TAG, "Input format doesn't contain aac-profile key");
629                     return false;
630                 }
631                 if (outFormat.getInteger(MediaFormat.KEY_AAC_PROFILE)
632                         != inpFormat.getInteger(MediaFormat.KEY_AAC_PROFILE)) {
633                     Log.e(LOG_TAG, "aac-profile in output doesn't match configured input");
634                     return false;
635                 }
636             }
637         } else if (outMime.startsWith("video/")) {
638             if (!outFormat.containsKey(MediaFormat.KEY_PROFILE)) {
639                 Log.e(LOG_TAG, "Output format doesn't contain profile key");
640                 //TODO (b/151398466)
641                 if (true) return true;
642                 return false;
643             }
644             if (!outFormat.containsKey(MediaFormat.KEY_LEVEL)) {
645                 Log.e(LOG_TAG, "Output format doesn't contain level key");
646                 //TODO (b/151398466)
647                 if (true) return true;
648                 return false;
649             }
650             if (!inpFormat.containsKey(MediaFormat.KEY_PROFILE)) {
651                 Log.e(LOG_TAG, "Input format doesn't contain profile key");
652                 return false;
653             }
654             if (!inpFormat.containsKey(MediaFormat.KEY_LEVEL)) {
655                 Log.e(LOG_TAG, "Input format doesn't contain level key");
656                 return false;
657             }
658             if (outFormat.getInteger(MediaFormat.KEY_PROFILE)
659                     != inpFormat.getInteger(MediaFormat.KEY_PROFILE)) {
660                 Log.e(LOG_TAG, "profile in output doesn't match configured input");
661                 return false;
662             }
663             if (outFormat.getInteger(MediaFormat.KEY_LEVEL)
664                     != inpFormat.getInteger(MediaFormat.KEY_LEVEL)) {
665                 Log.e(LOG_TAG, "level key in output doesn't match configured input");
666                 return false;
667             }
668         } else {
669             Log.w(LOG_TAG, "non media mime:" + outMime);
670         }
671         return true;
672     }
673 
674     /**
675      * Sets profile and level keys in config format for encoder and validates the keys in output
676      * format if component supports the configuration and also verifies whether cdd mandated
677      * (profile, level) combination is supported
678      */
679     @Test(timeout = PER_TEST_TIMEOUT_LARGE_TEST_MS)
testValidateProfileLevel()680     public void testValidateProfileLevel() throws IOException, InterruptedException {
681         ArrayList<String> listOfEncoders = selectCodecs(mMime, null, null, true);
682         assertFalse("no suitable codecs found for mime: " + mMime, listOfEncoders.isEmpty());
683         int[] profiles = mProfileMap.get(mMime);
684         assertTrue("no profile entry found for mime" + mMime, profiles != null);
685         // cdd check initialization
686         boolean cddSupportedMime = mProfileLevelCdd.get(mMime) != null;
687         int[] profileCdd = new int[0];
688         int levelCdd = 0;
689         if (cddSupportedMime) {
690             Pair<int[], Integer> cddProfileLevel = mProfileLevelCdd.get(mMime);
691             profileCdd = cddProfileLevel.first;
692             levelCdd = cddProfileLevel.second;
693         }
694         boolean[] boolStates = {true, false};
695         MediaFormat format = mConfigFormat;
696         mOutputBuff = new OutputManager();
697         setUpSource(mInputFile);
698         int supportedCddCount = listOfEncoders.size() * (cddSupportedMime ? profileCdd.length : 1);
699         for (String encoder : listOfEncoders) {
700             mCodec = MediaCodec.createByCodecName(encoder);
701             MediaCodecInfo.CodecCapabilities codecCapabilities =
702                     mCodec.getCodecInfo().getCapabilitiesForType(mMime);
703             for (int profile : profiles) {
704                 format.setInteger(mIsAudio ? MediaFormat.KEY_AAC_PROFILE : MediaFormat.KEY_PROFILE,
705                         profile);
706                 int level = mIsAudio ? 0 : getMinLevel(mMime, mWidth, mHeight,
707                         format.getInteger(MediaFormat.KEY_FRAME_RATE),
708                         format.getInteger(MediaFormat.KEY_BIT_RATE), profile);
709                 assertTrue("no min level found for mime" + mMime, level != -1);
710                 if (!mIsAudio) format.setInteger(MediaFormat.KEY_LEVEL, level);
711                 if (!codecCapabilities.isFormatSupported(format)) {
712                     if (cddSupportedMime) {
713                         if (mIsAudio) {
714                             for (int cddProfile : profileCdd) {
715                                 if (profile == cddProfile) supportedCddCount--;
716                             }
717                         } else if (profile == profileCdd[0] && level == levelCdd) {
718                             supportedCddCount--;
719                         }
720                         Log.w(LOG_TAG,
721                                 "Component: " + encoder + " doesn't support cdd format: " + format);
722                     }
723                     continue;
724                 }
725                 for (boolean isAsync : boolStates) {
726                     configureCodec(format, isAsync, true, true);
727                     mCodec.start();
728                     doWork(1);
729                     queueEOS();
730                     waitForAllOutputs();
731                     MediaFormat outFormat = mCodec.getOutputFormat();
732                     /* TODO(b/147348711) */
733                     if (false) mCodec.stop();
734                     else mCodec.reset();
735                     String log =
736                             String.format("format: %s \n codec: %s, mode: %s:: ", format, encoder,
737                                     (isAsync ? "async" : "sync"));
738                     assertFalse(log + " unexpected error", mAsyncHandle.hasSeenError());
739                     assertTrue(log + "configured format and output format are not similar." +
740                                     (ENABLE_LOGS ? "\n output format:" + outFormat : ""),
741                             isFormatSimilar(format, outFormat));
742                 }
743             }
744             mCodec.release();
745         }
746         assertFalse("No components support cdd requirement profile level for mime: " + mMime,
747                 supportedCddCount == 0);
748     }
749 }
750