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