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