1 /* 2 * Copyright 2014 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.media.cts; 18 19 import android.media.cts.CodecUtils; 20 21 import android.graphics.ImageFormat; 22 import android.graphics.SurfaceTexture; 23 import android.media.Image; 24 import android.media.MediaCodec; 25 import android.media.MediaCodec.BufferInfo; 26 import android.media.MediaCodecInfo; 27 import android.media.MediaCodecInfo.CodecCapabilities; 28 import android.media.MediaCodecInfo.VideoCapabilities; 29 import android.media.MediaCodecList; 30 import android.media.MediaExtractor; 31 import android.media.MediaFormat; 32 import android.media.MediaMuxer; 33 import android.net.Uri; 34 import android.platform.test.annotations.AppModeFull; 35 import android.platform.test.annotations.Presubmit; 36 import android.platform.test.annotations.RequiresDevice; 37 import android.util.Log; 38 import android.util.Pair; 39 import android.util.Range; 40 import android.util.Size; 41 import android.view.Surface; 42 43 import androidx.test.filters.SmallTest; 44 45 import com.android.compatibility.common.util.MediaUtils; 46 47 import java.io.File; 48 import java.io.IOException; 49 import java.nio.ByteBuffer; 50 import java.util.ArrayList; 51 import java.util.concurrent.atomic.AtomicReference; 52 import java.util.function.Consumer; 53 import java.util.function.Function; 54 import java.util.HashMap; 55 import java.util.HashSet; 56 import java.util.Iterator; 57 import java.util.LinkedList; 58 import java.util.Map; 59 import java.util.Set; 60 61 @MediaHeavyPresubmitTest 62 @AppModeFull(reason = "TODO: evaluate and port to instant") 63 public class VideoEncoderTest extends MediaPlayerTestBase { 64 private static final int MAX_SAMPLE_SIZE = 256 * 1024; 65 private static final String TAG = "VideoEncoderTest"; 66 private static final long FRAME_TIMEOUT_MS = 1000; 67 // use larger delay before we get first frame, some encoders may need more time 68 private static final long INIT_TIMEOUT_MS = 2000; 69 70 static final String mInpPrefix = WorkDir.getMediaDirString(); 71 private static final String SOURCE_URL = 72 mInpPrefix + "video_480x360_mp4_h264_871kbps_30fps.mp4"; 73 74 private final boolean DEBUG = false; 75 76 class VideoStorage { 77 private LinkedList<Pair<ByteBuffer, BufferInfo>> mStream; 78 private MediaFormat mFormat; 79 private int mInputBufferSize; 80 // Media buffers(no CSD, no EOS) enqueued. 81 private int mMediaBuffersEnqueuedCount; 82 // Media buffers decoded. 83 private int mMediaBuffersDecodedCount; 84 private final AtomicReference<String> errorMsg = new AtomicReference(null); 85 VideoStorage()86 public VideoStorage() { 87 mStream = new LinkedList<Pair<ByteBuffer, BufferInfo>>(); 88 } 89 setFormat(MediaFormat format)90 public void setFormat(MediaFormat format) { 91 mFormat = format; 92 } 93 addBuffer(ByteBuffer buffer, BufferInfo info)94 public void addBuffer(ByteBuffer buffer, BufferInfo info) { 95 ByteBuffer savedBuffer = ByteBuffer.allocate(info.size); 96 savedBuffer.put(buffer); 97 if (info.size > mInputBufferSize) { 98 mInputBufferSize = info.size; 99 } 100 BufferInfo savedInfo = new BufferInfo(); 101 savedInfo.set(0, savedBuffer.position(), info.presentationTimeUs, info.flags); 102 mStream.addLast(Pair.create(savedBuffer, savedInfo)); 103 if (info.size > 0 && (info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) { 104 ++mMediaBuffersEnqueuedCount; 105 } 106 } 107 play(MediaCodec decoder, Surface surface)108 private void play(MediaCodec decoder, Surface surface) { 109 decoder.reset(); 110 final Object condition = new Object(); 111 final Iterator<Pair<ByteBuffer, BufferInfo>> it = mStream.iterator(); 112 decoder.setCallback(new MediaCodec.Callback() { 113 public void onOutputBufferAvailable(MediaCodec codec, int ix, BufferInfo info) { 114 if (info.size > 0) { 115 ++mMediaBuffersDecodedCount; 116 } 117 codec.releaseOutputBuffer(ix, info.size > 0); 118 if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { 119 synchronized (condition) { 120 condition.notifyAll(); 121 } 122 } 123 } 124 public void onInputBufferAvailable(MediaCodec codec, int ix) { 125 if (it.hasNext()) { 126 Pair<ByteBuffer, BufferInfo> el = it.next(); 127 el.first.clear(); 128 try { 129 codec.getInputBuffer(ix).put(el.first); 130 } catch (java.nio.BufferOverflowException e) { 131 Log.e(TAG, "cannot fit " + el.first.limit() 132 + "-byte encoded buffer into " 133 + codec.getInputBuffer(ix).remaining() 134 + "-byte input buffer of " + codec.getName() 135 + " configured for " + codec.getInputFormat()); 136 throw e; 137 } 138 BufferInfo info = el.second; 139 codec.queueInputBuffer( 140 ix, 0, info.size, info.presentationTimeUs, info.flags); 141 } 142 } 143 public void onError(MediaCodec codec, MediaCodec.CodecException e) { 144 Log.i(TAG, "got codec exception", e); 145 errorMsg.set("received codec error during decode" + e); 146 synchronized (condition) { 147 condition.notifyAll(); 148 } 149 } 150 public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) { 151 Log.i(TAG, "got output format " + format); 152 } 153 }); 154 mFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, mInputBufferSize); 155 decoder.configure(mFormat, surface, null /* crypto */, 0 /* flags */); 156 decoder.start(); 157 synchronized (condition) { 158 try { 159 condition.wait(); 160 } catch (InterruptedException e) { 161 fail("playback interrupted"); 162 } 163 } 164 decoder.stop(); 165 assertNull(errorMsg.get(), errorMsg.get()); 166 // All enqueued media data buffers should have got decoded. 167 if (mMediaBuffersEnqueuedCount != mMediaBuffersDecodedCount) { 168 Log.i(TAG, "mMediaBuffersEnqueuedCount:" + mMediaBuffersEnqueuedCount); 169 Log.i(TAG, "mMediaBuffersDecodedCount:" + mMediaBuffersDecodedCount); 170 fail("not all enqueued encoded media buffers were decoded"); 171 } 172 mMediaBuffersDecodedCount = 0; 173 } 174 playAll(Surface surface)175 public boolean playAll(Surface surface) { 176 boolean skipped = true; 177 if (mFormat == null) { 178 Log.i(TAG, "no stream to play"); 179 return !skipped; 180 } 181 String mime = mFormat.getString(MediaFormat.KEY_MIME); 182 MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS); 183 for (MediaCodecInfo info : mcl.getCodecInfos()) { 184 if (info.isEncoder() || info.isAlias()) { 185 continue; 186 } 187 MediaCodec codec = null; 188 try { 189 CodecCapabilities caps = info.getCapabilitiesForType(mime); 190 if (!caps.isFormatSupported(mFormat)) { 191 continue; 192 } 193 codec = MediaCodec.createByCodecName(info.getName()); 194 } catch (IllegalArgumentException | IOException e) { 195 continue; 196 } 197 play(codec, surface); 198 codec.release(); 199 skipped = false; 200 } 201 return !skipped; 202 } 203 } 204 205 abstract class VideoProcessorBase extends MediaCodec.Callback { 206 private static final String TAG = "VideoProcessorBase"; 207 208 /* 209 * Set this to true to save the encoding results to /data/local/tmp 210 * You will need to make /data/local/tmp writeable, run "setenforce 0", 211 * and remove files left from a previous run. 212 */ 213 private boolean mSaveResults = false; 214 private static final String FILE_DIR = "/data/local/tmp"; 215 protected int mMuxIndex = -1; 216 217 protected String mProcessorName = "VideoProcessor"; 218 private MediaExtractor mExtractor; 219 protected MediaMuxer mMuxer; 220 private ByteBuffer mBuffer = ByteBuffer.allocate(MAX_SAMPLE_SIZE); 221 protected int mTrackIndex = -1; 222 private boolean mSignaledDecoderEOS; 223 224 protected boolean mCompleted; 225 protected boolean mEncoderIsActive; 226 protected boolean mEncodeOutputFormatUpdated; 227 protected final Object mCondition = new Object(); 228 protected final Object mCodecLock = new Object(); 229 230 protected MediaFormat mDecFormat; 231 protected MediaCodec mDecoder, mEncoder; 232 233 private VideoStorage mEncodedStream; 234 protected int mFrameRate = 0; 235 protected int mBitRate = 0; 236 237 protected Function<MediaFormat, Boolean> mUpdateConfigFormatHook; 238 protected Function<MediaFormat, Boolean> mCheckOutputFormatHook; 239 setProcessorName(String name)240 public void setProcessorName(String name) { 241 mProcessorName = name; 242 } 243 setUpdateConfigHook(Function<MediaFormat, Boolean> hook)244 public void setUpdateConfigHook(Function<MediaFormat, Boolean> hook) { 245 mUpdateConfigFormatHook = hook; 246 } 247 setCheckOutputFormatHook(Function<MediaFormat, Boolean> hook)248 public void setCheckOutputFormatHook(Function<MediaFormat, Boolean> hook) { 249 mCheckOutputFormatHook = hook; 250 } 251 open(String path)252 protected void open(String path) throws IOException { 253 mExtractor = new MediaExtractor(); 254 if (path.startsWith("android.resource://")) { 255 mExtractor.setDataSource(mContext, Uri.parse(path), null); 256 } else { 257 mExtractor.setDataSource(path); 258 } 259 260 for (int i = 0; i < mExtractor.getTrackCount(); i++) { 261 MediaFormat fmt = mExtractor.getTrackFormat(i); 262 String mime = fmt.getString(MediaFormat.KEY_MIME).toLowerCase(); 263 if (mime.startsWith("video/")) { 264 mTrackIndex = i; 265 mDecFormat = fmt; 266 mExtractor.selectTrack(i); 267 break; 268 } 269 } 270 mEncodedStream = new VideoStorage(); 271 assertTrue("file " + path + " has no video", mTrackIndex >= 0); 272 } 273 274 // returns true if encoder supports the size initCodecsAndConfigureEncoder( String videoEncName, String outMime, int width, int height, int colorFormat)275 protected boolean initCodecsAndConfigureEncoder( 276 String videoEncName, String outMime, int width, int height, 277 int colorFormat) throws IOException { 278 mDecFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat); 279 280 MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS); 281 String videoDecName = mcl.findDecoderForFormat(mDecFormat); 282 Log.i(TAG, "decoder for " + mDecFormat + " is " + videoDecName); 283 mDecoder = MediaCodec.createByCodecName(videoDecName); 284 mEncoder = MediaCodec.createByCodecName(videoEncName); 285 286 mDecoder.setCallback(this); 287 mEncoder.setCallback(this); 288 289 VideoCapabilities encCaps = 290 mEncoder.getCodecInfo().getCapabilitiesForType(outMime).getVideoCapabilities(); 291 if (!encCaps.isSizeSupported(width, height)) { 292 Log.i(TAG, videoEncName + " does not support size: " + width + "x" + height); 293 return false; 294 } 295 296 MediaFormat outFmt = MediaFormat.createVideoFormat(outMime, width, height); 297 int bitRate = 0; 298 MediaUtils.setMaxEncoderFrameAndBitrates(encCaps, outFmt, 30); 299 if (mFrameRate > 0) { 300 outFmt.setInteger(MediaFormat.KEY_FRAME_RATE, mFrameRate); 301 } 302 if (mBitRate > 0) { 303 outFmt.setInteger(MediaFormat.KEY_BIT_RATE, mBitRate); 304 } 305 outFmt.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1); 306 outFmt.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat); 307 // Some extra configure before starting the encoder. 308 if (mUpdateConfigFormatHook != null) { 309 if (!mUpdateConfigFormatHook.apply(outFmt)) { 310 return false; 311 } 312 } 313 mEncoder.configure(outFmt, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); 314 Log.i(TAG, "encoder input format " + mEncoder.getInputFormat() + " from " + outFmt); 315 if (mSaveResults) { 316 try { 317 String outFileName = 318 FILE_DIR + mProcessorName + "_" + bitRate + "bps"; 319 if (outMime.equals(MediaFormat.MIMETYPE_VIDEO_VP8) || 320 outMime.equals(MediaFormat.MIMETYPE_VIDEO_VP9)) { 321 mMuxer = new MediaMuxer( 322 outFileName + ".webm", MediaMuxer.OutputFormat.MUXER_OUTPUT_WEBM); 323 } else { 324 mMuxer = new MediaMuxer( 325 outFileName + ".mp4", MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); 326 } 327 // The track can't be added until we have the codec specific data 328 } catch (Exception e) { 329 Log.i(TAG, "couldn't create muxer: " + e); 330 } 331 } 332 return true; 333 } 334 close()335 protected void close() { 336 synchronized (mCodecLock) { 337 if (mDecoder != null) { 338 mDecoder.release(); 339 mDecoder = null; 340 } 341 if (mEncoder != null) { 342 mEncoder.release(); 343 mEncoder = null; 344 } 345 } 346 if (mExtractor != null) { 347 mExtractor.release(); 348 mExtractor = null; 349 } 350 if (mMuxer != null) { 351 mMuxer.stop(); 352 mMuxer.release(); 353 mMuxer = null; 354 } 355 } 356 357 // returns true if filled buffer fillDecoderInputBuffer(int ix)358 protected boolean fillDecoderInputBuffer(int ix) { 359 if (DEBUG) Log.v(TAG, "decoder received input #" + ix); 360 while (!mSignaledDecoderEOS) { 361 int track = mExtractor.getSampleTrackIndex(); 362 if (track >= 0 && track != mTrackIndex) { 363 mExtractor.advance(); 364 continue; 365 } 366 int size = mExtractor.readSampleData(mBuffer, 0); 367 if (size < 0) { 368 // queue decoder input EOS 369 if (DEBUG) Log.v(TAG, "queuing decoder EOS"); 370 mDecoder.queueInputBuffer( 371 ix, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM); 372 mSignaledDecoderEOS = true; 373 } else { 374 mBuffer.limit(size); 375 mBuffer.position(0); 376 BufferInfo info = new BufferInfo(); 377 info.set( 378 0, mBuffer.limit(), mExtractor.getSampleTime(), 379 mExtractor.getSampleFlags()); 380 mDecoder.getInputBuffer(ix).put(mBuffer); 381 if (DEBUG) Log.v(TAG, "queing input #" + ix + " for decoder with timestamp " 382 + info.presentationTimeUs); 383 mDecoder.queueInputBuffer( 384 ix, 0, mBuffer.limit(), info.presentationTimeUs, 0); 385 } 386 mExtractor.advance(); 387 return true; 388 } 389 return false; 390 } 391 emptyEncoderOutputBuffer(int ix, BufferInfo info)392 protected void emptyEncoderOutputBuffer(int ix, BufferInfo info) { 393 if (DEBUG) Log.v(TAG, "encoder received output #" + ix 394 + " (sz=" + info.size + ", f=" + info.flags 395 + ", ts=" + info.presentationTimeUs + ")"); 396 ByteBuffer outputBuffer = mEncoder.getOutputBuffer(ix); 397 mEncodedStream.addBuffer(outputBuffer, info); 398 399 if (mMuxer != null) { 400 // reset position as addBuffer() modifies it 401 outputBuffer.position(info.offset); 402 outputBuffer.limit(info.offset + info.size); 403 mMuxer.writeSampleData(mMuxIndex, outputBuffer, info); 404 } 405 406 if (!mCompleted) { 407 mEncoder.releaseOutputBuffer(ix, false); 408 if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { 409 Log.d(TAG, "encoder received output EOS"); 410 synchronized(mCondition) { 411 mCompleted = true; 412 mCondition.notifyAll(); // condition is always satisfied 413 } 414 } else { 415 synchronized(mCondition) { 416 mEncoderIsActive = true; 417 } 418 } 419 } 420 } 421 saveEncoderFormat(MediaFormat format)422 protected void saveEncoderFormat(MediaFormat format) { 423 mEncodedStream.setFormat(format); 424 if (mCheckOutputFormatHook != null) { 425 mCheckOutputFormatHook.apply(format); 426 } 427 if (mMuxer != null) { 428 if (mMuxIndex < 0) { 429 mMuxIndex = mMuxer.addTrack(format); 430 mMuxer.start(); 431 } 432 } 433 } 434 playBack(Surface surface)435 public boolean playBack(Surface surface) { return mEncodedStream.playAll(surface); } 436 setFrameAndBitRates(int frameRate, int bitRate)437 public void setFrameAndBitRates(int frameRate, int bitRate) { 438 mFrameRate = frameRate; 439 mBitRate = bitRate; 440 } 441 442 @Override onInputBufferAvailable(MediaCodec mediaCodec, int ix)443 public void onInputBufferAvailable(MediaCodec mediaCodec, int ix) { 444 synchronized (mCodecLock) { 445 if (mEncoder != null && mDecoder != null) { 446 onInputBufferAvailableLocked(mediaCodec, ix); 447 } 448 } 449 } 450 451 @Override onOutputBufferAvailable( MediaCodec mediaCodec, int ix, BufferInfo info)452 public void onOutputBufferAvailable( 453 MediaCodec mediaCodec, int ix, BufferInfo info) { 454 synchronized (mCodecLock) { 455 if (mEncoder != null && mDecoder != null) { 456 onOutputBufferAvailableLocked(mediaCodec, ix, info); 457 } 458 } 459 } 460 processLoop( String path, String outMime, String videoEncName, int width, int height, boolean optional)461 public abstract boolean processLoop( 462 String path, String outMime, String videoEncName, 463 int width, int height, boolean optional); onInputBufferAvailableLocked( MediaCodec mediaCodec, int ix)464 protected abstract void onInputBufferAvailableLocked( 465 MediaCodec mediaCodec, int ix); onOutputBufferAvailableLocked( MediaCodec mediaCodec, int ix, BufferInfo info)466 protected abstract void onOutputBufferAvailableLocked( 467 MediaCodec mediaCodec, int ix, BufferInfo info); 468 } 469 470 class VideoProcessor extends VideoProcessorBase { 471 private static final String TAG = "VideoProcessor"; 472 private boolean mWorkInProgress; 473 private boolean mGotDecoderEOS; 474 private boolean mSignaledEncoderEOS; 475 476 private LinkedList<Pair<Integer, BufferInfo>> mBuffersToRender = 477 new LinkedList<Pair<Integer, BufferInfo>>(); 478 private LinkedList<Integer> mEncInputBuffers = new LinkedList<Integer>(); 479 480 private int mEncInputBufferSize = -1; 481 private final AtomicReference<String> errorMsg = new AtomicReference(null); 482 483 @Override processLoop( String path, String outMime, String videoEncName, int width, int height, boolean optional)484 public boolean processLoop( 485 String path, String outMime, String videoEncName, 486 int width, int height, boolean optional) { 487 boolean skipped = true; 488 try { 489 open(path); 490 if (!initCodecsAndConfigureEncoder( 491 videoEncName, outMime, width, height, 492 CodecCapabilities.COLOR_FormatYUV420Flexible)) { 493 assertTrue("could not configure encoder for supported size", optional); 494 return !skipped; 495 } 496 skipped = false; 497 498 mDecoder.configure(mDecFormat, null /* surface */, null /* crypto */, 0); 499 500 mDecoder.start(); 501 mEncoder.start(); 502 503 // main loop - process GL ops as only main thread has GL context 504 while (!mCompleted && errorMsg.get() == null) { 505 Pair<Integer, BufferInfo> decBuffer = null; 506 int encBuffer = -1; 507 synchronized (mCondition) { 508 try { 509 // wait for an encoder input buffer and a decoder output buffer 510 // Use a timeout to avoid stalling the test if it doesn't arrive. 511 if (!haveBuffers() && !mCompleted) { 512 mCondition.wait(mEncodeOutputFormatUpdated ? 513 FRAME_TIMEOUT_MS : INIT_TIMEOUT_MS); 514 } 515 } catch (InterruptedException ie) { 516 fail("wait interrupted"); // shouldn't happen 517 } 518 if (mCompleted) { 519 break; 520 } 521 if (!haveBuffers()) { 522 if (mEncoderIsActive) { 523 mEncoderIsActive = false; 524 Log.d(TAG, "No more input but still getting output from encoder."); 525 continue; 526 } 527 fail("timed out after " + mBuffersToRender.size() 528 + " decoder output and " + mEncInputBuffers.size() 529 + " encoder input buffers"); 530 } 531 532 if (DEBUG) Log.v(TAG, "got image"); 533 decBuffer = mBuffersToRender.removeFirst(); 534 encBuffer = mEncInputBuffers.removeFirst(); 535 if (isEOSOnlyBuffer(decBuffer)) { 536 queueEncoderEOS(decBuffer, encBuffer); 537 continue; 538 } 539 mWorkInProgress = true; 540 } 541 542 if (mWorkInProgress) { 543 renderDecodedBuffer(decBuffer, encBuffer); 544 synchronized(mCondition) { 545 mWorkInProgress = false; 546 } 547 } 548 } 549 } catch (IOException e) { 550 e.printStackTrace(); 551 fail("received exception " + e); 552 } finally { 553 close(); 554 } 555 assertNull(errorMsg.get(), errorMsg.get()); 556 return !skipped; 557 } 558 559 @Override onInputBufferAvailableLocked(MediaCodec mediaCodec, int ix)560 public void onInputBufferAvailableLocked(MediaCodec mediaCodec, int ix) { 561 if (mediaCodec == mDecoder) { 562 // fill input buffer from extractor 563 fillDecoderInputBuffer(ix); 564 } else if (mediaCodec == mEncoder) { 565 synchronized(mCondition) { 566 mEncInputBuffers.addLast(ix); 567 tryToPropagateEOS(); 568 if (haveBuffers()) { 569 mCondition.notifyAll(); 570 } 571 } 572 } else { 573 fail("received input buffer on " + mediaCodec.getName()); 574 } 575 } 576 577 @Override onOutputBufferAvailableLocked( MediaCodec mediaCodec, int ix, BufferInfo info)578 public void onOutputBufferAvailableLocked( 579 MediaCodec mediaCodec, int ix, BufferInfo info) { 580 if (mediaCodec == mDecoder) { 581 if (DEBUG) Log.v(TAG, "decoder received output #" + ix 582 + " (sz=" + info.size + ", f=" + info.flags 583 + ", ts=" + info.presentationTimeUs + ")"); 584 // render output buffer from decoder 585 if (!mGotDecoderEOS) { 586 boolean eos = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0; 587 // can release empty buffers now 588 if (info.size == 0) { 589 mDecoder.releaseOutputBuffer(ix, false /* render */); 590 ix = -1; // fake index used by render to not render 591 } 592 synchronized(mCondition) { 593 if (ix < 0 && eos && mBuffersToRender.size() > 0) { 594 // move lone EOS flag to last buffer to be rendered 595 mBuffersToRender.peekLast().second.flags |= 596 MediaCodec.BUFFER_FLAG_END_OF_STREAM; 597 } else if (ix >= 0 || eos) { 598 mBuffersToRender.addLast(Pair.create(ix, info)); 599 } 600 if (eos) { 601 tryToPropagateEOS(); 602 mGotDecoderEOS = true; 603 } 604 if (haveBuffers()) { 605 mCondition.notifyAll(); 606 } 607 } 608 } 609 } else if (mediaCodec == mEncoder) { 610 emptyEncoderOutputBuffer(ix, info); 611 } else { 612 fail("received output buffer on " + mediaCodec.getName()); 613 } 614 } 615 renderDecodedBuffer(Pair<Integer, BufferInfo> decBuffer, int encBuffer)616 private void renderDecodedBuffer(Pair<Integer, BufferInfo> decBuffer, int encBuffer) { 617 // process heavyweight actions under instance lock 618 Image encImage = mEncoder.getInputImage(encBuffer); 619 Image decImage = mDecoder.getOutputImage(decBuffer.first); 620 assertNotNull("could not get encoder image for " + mEncoder.getInputFormat(), encImage); 621 assertNotNull("could not get decoder image for " + mDecoder.getInputFormat(), decImage); 622 assertEquals("incorrect decoder format",decImage.getFormat(), ImageFormat.YUV_420_888); 623 assertEquals("incorrect encoder format", encImage.getFormat(), ImageFormat.YUV_420_888); 624 625 CodecUtils.copyFlexYUVImage(encImage, decImage); 626 627 // TRICKY: need this for queueBuffer 628 if (mEncInputBufferSize < 0) { 629 mEncInputBufferSize = mEncoder.getInputBuffer(encBuffer).capacity(); 630 } 631 Log.d(TAG, "queuing input #" + encBuffer + " for encoder (sz=" 632 + mEncInputBufferSize + ", f=" + decBuffer.second.flags 633 + ", ts=" + decBuffer.second.presentationTimeUs + ")"); 634 mEncoder.queueInputBuffer( 635 encBuffer, 0, mEncInputBufferSize, decBuffer.second.presentationTimeUs, 636 decBuffer.second.flags); 637 if ((decBuffer.second.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { 638 mSignaledEncoderEOS = true; 639 } 640 mDecoder.releaseOutputBuffer(decBuffer.first, false /* render */); 641 } 642 643 @Override onError(MediaCodec mediaCodec, MediaCodec.CodecException e)644 public void onError(MediaCodec mediaCodec, MediaCodec.CodecException e) { 645 String codecName = null; 646 try { 647 codecName = mediaCodec.getName(); 648 } catch (Exception ex) { 649 codecName = "(error getting codec name)"; 650 } 651 errorMsg.set("received error on " + codecName + ": " + e); 652 } 653 654 @Override onOutputFormatChanged(MediaCodec mediaCodec, MediaFormat mediaFormat)655 public void onOutputFormatChanged(MediaCodec mediaCodec, MediaFormat mediaFormat) { 656 Log.i(TAG, mediaCodec.getName() + " got new output format " + mediaFormat); 657 if (mediaCodec == mEncoder) { 658 mEncodeOutputFormatUpdated = true; 659 saveEncoderFormat(mediaFormat); 660 } 661 } 662 663 // next methods are synchronized on mCondition haveBuffers()664 private boolean haveBuffers() { 665 return mEncInputBuffers.size() > 0 && mBuffersToRender.size() > 0 666 && !mSignaledEncoderEOS; 667 } 668 isEOSOnlyBuffer(Pair<Integer, BufferInfo> decBuffer)669 private boolean isEOSOnlyBuffer(Pair<Integer, BufferInfo> decBuffer) { 670 return decBuffer.first < 0 || decBuffer.second.size == 0; 671 } 672 tryToPropagateEOS()673 protected void tryToPropagateEOS() { 674 if (!mWorkInProgress && haveBuffers() && isEOSOnlyBuffer(mBuffersToRender.getFirst())) { 675 Pair<Integer, BufferInfo> decBuffer = mBuffersToRender.removeFirst(); 676 int encBuffer = mEncInputBuffers.removeFirst(); 677 queueEncoderEOS(decBuffer, encBuffer); 678 } 679 } 680 queueEncoderEOS(Pair<Integer, BufferInfo> decBuffer, int encBuffer)681 void queueEncoderEOS(Pair<Integer, BufferInfo> decBuffer, int encBuffer) { 682 Log.d(TAG, "signaling encoder EOS"); 683 mEncoder.queueInputBuffer(encBuffer, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM); 684 mSignaledEncoderEOS = true; 685 if (decBuffer.first >= 0) { 686 mDecoder.releaseOutputBuffer(decBuffer.first, false /* render */); 687 } 688 } 689 } 690 691 692 class SurfaceVideoProcessor extends VideoProcessorBase 693 implements SurfaceTexture.OnFrameAvailableListener { 694 private static final String TAG = "SurfaceVideoProcessor"; 695 private boolean mFrameAvailable; 696 private boolean mGotDecoderEOS; 697 private boolean mSignaledEncoderEOS; 698 699 private InputSurface mEncSurface; 700 private OutputSurface mDecSurface; 701 private BufferInfo mInfoOnSurface; 702 703 private LinkedList<Pair<Integer, BufferInfo>> mBuffersToRender = 704 new LinkedList<Pair<Integer, BufferInfo>>(); 705 706 private final AtomicReference<String> errorMsg = new AtomicReference(null); 707 708 @Override processLoop( String path, String outMime, String videoEncName, int width, int height, boolean optional)709 public boolean processLoop( 710 String path, String outMime, String videoEncName, 711 int width, int height, boolean optional) { 712 boolean skipped = true; 713 try { 714 open(path); 715 if (!initCodecsAndConfigureEncoder( 716 videoEncName, outMime, width, height, 717 CodecCapabilities.COLOR_FormatSurface)) { 718 assertTrue("could not configure encoder for supported size", optional); 719 return !skipped; 720 } 721 skipped = false; 722 723 mEncSurface = new InputSurface(mEncoder.createInputSurface()); 724 mEncSurface.makeCurrent(); 725 726 mDecSurface = new OutputSurface(this); 727 //mDecSurface.changeFragmentShader(FRAGMENT_SHADER); 728 mDecoder.configure(mDecFormat, mDecSurface.getSurface(), null /* crypto */, 0); 729 730 mDecoder.start(); 731 mEncoder.start(); 732 733 // main loop - process GL ops as only main thread has GL context 734 while (!mCompleted && errorMsg.get() == null) { 735 BufferInfo info = null; 736 synchronized (mCondition) { 737 try { 738 // wait for mFrameAvailable, which is set by onFrameAvailable(). 739 // Use a timeout to avoid stalling the test if it doesn't arrive. 740 if (!mFrameAvailable && !mCompleted && !mEncoderIsActive) { 741 mCondition.wait(mEncodeOutputFormatUpdated ? 742 FRAME_TIMEOUT_MS : INIT_TIMEOUT_MS); 743 } 744 } catch (InterruptedException ie) { 745 fail("wait interrupted"); // shouldn't happen 746 } 747 if (mCompleted) { 748 break; 749 } 750 if (mEncoderIsActive) { 751 mEncoderIsActive = false; 752 if (DEBUG) Log.d(TAG, "encoder is still active, continue"); 753 continue; 754 } 755 assertTrue("still waiting for image", mFrameAvailable); 756 if (DEBUG) Log.v(TAG, "got image"); 757 info = mInfoOnSurface; 758 } 759 if (info == null) { 760 continue; 761 } 762 if (info.size > 0) { 763 mDecSurface.latchImage(); 764 if (DEBUG) Log.v(TAG, "latched image"); 765 mFrameAvailable = false; 766 767 mDecSurface.drawImage(); 768 Log.d(TAG, "encoding frame at " + info.presentationTimeUs * 1000); 769 770 mEncSurface.setPresentationTime(info.presentationTimeUs * 1000); 771 mEncSurface.swapBuffers(); 772 } 773 if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { 774 mSignaledEncoderEOS = true; 775 Log.d(TAG, "signaling encoder EOS"); 776 mEncoder.signalEndOfInputStream(); 777 } 778 779 synchronized (mCondition) { 780 mInfoOnSurface = null; 781 if (mBuffersToRender.size() > 0 && mInfoOnSurface == null) { 782 if (DEBUG) Log.v(TAG, "handling postponed frame"); 783 Pair<Integer, BufferInfo> nextBuffer = mBuffersToRender.removeFirst(); 784 renderDecodedBuffer(nextBuffer.first, nextBuffer.second); 785 } 786 } 787 } 788 } catch (IOException e) { 789 e.printStackTrace(); 790 fail("received exception " + e); 791 } finally { 792 close(); 793 if (mEncSurface != null) { 794 mEncSurface.release(); 795 mEncSurface = null; 796 } 797 if (mDecSurface != null) { 798 mDecSurface.release(); 799 mDecSurface = null; 800 } 801 } 802 assertNull(errorMsg.get(), errorMsg.get()); 803 return !skipped; 804 } 805 806 @Override onFrameAvailable(SurfaceTexture st)807 public void onFrameAvailable(SurfaceTexture st) { 808 if (DEBUG) Log.v(TAG, "new frame available"); 809 synchronized (mCondition) { 810 assertFalse("mFrameAvailable already set, frame could be dropped", mFrameAvailable); 811 mFrameAvailable = true; 812 mCondition.notifyAll(); 813 } 814 } 815 816 @Override onInputBufferAvailableLocked(MediaCodec mediaCodec, int ix)817 public void onInputBufferAvailableLocked(MediaCodec mediaCodec, int ix) { 818 if (mediaCodec == mDecoder) { 819 // fill input buffer from extractor 820 fillDecoderInputBuffer(ix); 821 } else { 822 fail("received input buffer on " + mediaCodec.getName()); 823 } 824 } 825 826 @Override onOutputBufferAvailableLocked( MediaCodec mediaCodec, int ix, BufferInfo info)827 public void onOutputBufferAvailableLocked( 828 MediaCodec mediaCodec, int ix, BufferInfo info) { 829 if (mediaCodec == mDecoder) { 830 if (DEBUG) Log.v(TAG, "decoder received output #" + ix 831 + " (sz=" + info.size + ", f=" + info.flags 832 + ", ts=" + info.presentationTimeUs + ")"); 833 // render output buffer from decoder 834 if (!mGotDecoderEOS) { 835 boolean eos = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0; 836 if (eos) { 837 mGotDecoderEOS = true; 838 } 839 // can release empty buffers now 840 if (info.size == 0) { 841 mDecoder.releaseOutputBuffer(ix, false /* render */); 842 ix = -1; // fake index used by render to not render 843 } 844 if (eos || info.size > 0) { 845 synchronized(mCondition) { 846 if (mInfoOnSurface != null || mBuffersToRender.size() > 0) { 847 if (DEBUG) Log.v(TAG, "postponing render, surface busy"); 848 mBuffersToRender.addLast(Pair.create(ix, info)); 849 } else { 850 renderDecodedBuffer(ix, info); 851 } 852 } 853 } 854 } 855 } else if (mediaCodec == mEncoder) { 856 emptyEncoderOutputBuffer(ix, info); 857 synchronized(mCondition) { 858 if (!mCompleted) { 859 mEncoderIsActive = true; 860 mCondition.notifyAll(); 861 } 862 } 863 } else { 864 fail("received output buffer on " + mediaCodec.getName()); 865 } 866 } 867 renderDecodedBuffer(int ix, BufferInfo info)868 private void renderDecodedBuffer(int ix, BufferInfo info) { 869 boolean eos = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0; 870 mInfoOnSurface = info; 871 if (info.size > 0) { 872 Log.d(TAG, "rendering frame #" + ix + " at " + info.presentationTimeUs * 1000 873 + (eos ? " with EOS" : "")); 874 mDecoder.releaseOutputBuffer(ix, info.presentationTimeUs * 1000); 875 } 876 877 if (eos && info.size == 0) { 878 if (DEBUG) Log.v(TAG, "decoder output EOS available"); 879 mFrameAvailable = true; 880 mCondition.notifyAll(); 881 } 882 } 883 884 @Override onError(MediaCodec mediaCodec, MediaCodec.CodecException e)885 public void onError(MediaCodec mediaCodec, MediaCodec.CodecException e) { 886 String codecName = null; 887 try { 888 codecName = mediaCodec.getName(); 889 } catch (Exception ex) { 890 codecName = "(error getting codec name)"; 891 } 892 errorMsg.set("received error on " + codecName + ": " + e); 893 } 894 895 @Override onOutputFormatChanged(MediaCodec mediaCodec, MediaFormat mediaFormat)896 public void onOutputFormatChanged(MediaCodec mediaCodec, MediaFormat mediaFormat) { 897 Log.i(TAG, mediaCodec.getName() + " got new output format " + mediaFormat); 898 if (mediaCodec == mEncoder) { 899 mEncodeOutputFormatUpdated = true; 900 saveEncoderFormat(mediaFormat); 901 } 902 } 903 } 904 905 class Encoder { 906 final private String mName; 907 final private String mMime; 908 final private CodecCapabilities mCaps; 909 final private VideoCapabilities mVideoCaps; 910 911 final private Map<Size, Set<Size>> mMinMax; // extreme sizes 912 final private Map<Size, Set<Size>> mNearMinMax; // sizes near extreme 913 final private Set<Size> mArbitraryW; // arbitrary widths in the middle 914 final private Set<Size> mArbitraryH; // arbitrary heights in the middle 915 final private Set<Size> mSizes; // all non-specifically tested sizes 916 917 final private int xAlign; 918 final private int yAlign; 919 Encoder(String name, String mime, CodecCapabilities caps)920 Encoder(String name, String mime, CodecCapabilities caps) { 921 mName = name; 922 mMime = mime; 923 mCaps = caps; 924 mVideoCaps = caps.getVideoCapabilities(); 925 926 /* calculate min/max sizes */ 927 mMinMax = new HashMap<Size, Set<Size>>(); 928 mNearMinMax = new HashMap<Size, Set<Size>>(); 929 mArbitraryW = new HashSet<Size>(); 930 mArbitraryH = new HashSet<Size>(); 931 mSizes = new HashSet<Size>(); 932 933 xAlign = mVideoCaps.getWidthAlignment(); 934 yAlign = mVideoCaps.getHeightAlignment(); 935 936 initializeSizes(); 937 } 938 initializeSizes()939 private void initializeSizes() { 940 for (int x = 0; x < 2; ++x) { 941 for (int y = 0; y < 2; ++y) { 942 addExtremeSizesFor(x, y); 943 } 944 } 945 946 // initialize arbitrary sizes 947 for (int i = 1; i <= 7; ++i) { 948 int j = ((7 * i) % 11) + 1; 949 int width, height; 950 try { 951 width = alignedPointInRange(i * 0.125, xAlign, mVideoCaps.getSupportedWidths()); 952 height = alignedPointInRange( 953 j * 0.077, yAlign, mVideoCaps.getSupportedHeightsFor(width)); 954 mArbitraryW.add(new Size(width, height)); 955 } catch (IllegalArgumentException e) { 956 } 957 958 try { 959 height = alignedPointInRange(i * 0.125, yAlign, mVideoCaps.getSupportedHeights()); 960 width = alignedPointInRange(j * 0.077, xAlign, mVideoCaps.getSupportedWidthsFor(height)); 961 mArbitraryH.add(new Size(width, height)); 962 } catch (IllegalArgumentException e) { 963 } 964 } 965 mArbitraryW.removeAll(mArbitraryH); 966 mArbitraryW.removeAll(mSizes); 967 mSizes.addAll(mArbitraryW); 968 mArbitraryH.removeAll(mSizes); 969 mSizes.addAll(mArbitraryH); 970 if (DEBUG) Log.i(TAG, "arbitrary=" + mArbitraryW + "/" + mArbitraryH); 971 } 972 addExtremeSizesFor(int x, int y)973 private void addExtremeSizesFor(int x, int y) { 974 Set<Size> minMax = new HashSet<Size>(); 975 Set<Size> nearMinMax = new HashSet<Size>(); 976 977 for (int dx = 0; dx <= xAlign; dx += xAlign) { 978 for (int dy = 0; dy <= yAlign; dy += yAlign) { 979 Set<Size> bucket = (dx + dy == 0) ? minMax : nearMinMax; 980 try { 981 int width = getExtreme(mVideoCaps.getSupportedWidths(), x, dx); 982 int height = getExtreme(mVideoCaps.getSupportedHeightsFor(width), y, dy); 983 bucket.add(new Size(width, height)); 984 985 // try max max with more reasonable ratio if too skewed 986 if (x + y == 2 && width >= 4 * height) { 987 Size wideScreen = getLargestSizeForRatio(16, 9); 988 width = getExtreme( 989 mVideoCaps.getSupportedWidths() 990 .intersect(0, wideScreen.getWidth()), x, dx); 991 height = getExtreme(mVideoCaps.getSupportedHeightsFor(width), y, 0); 992 bucket.add(new Size(width, height)); 993 } 994 } catch (IllegalArgumentException e) { 995 } 996 997 try { 998 int height = getExtreme(mVideoCaps.getSupportedHeights(), y, dy); 999 int width = getExtreme(mVideoCaps.getSupportedWidthsFor(height), x, dx); 1000 bucket.add(new Size(width, height)); 1001 1002 // try max max with more reasonable ratio if too skewed 1003 if (x + y == 2 && height >= 4 * width) { 1004 Size wideScreen = getLargestSizeForRatio(9, 16); 1005 height = getExtreme( 1006 mVideoCaps.getSupportedHeights() 1007 .intersect(0, wideScreen.getHeight()), y, dy); 1008 width = getExtreme(mVideoCaps.getSupportedWidthsFor(height), x, dx); 1009 bucket.add(new Size(width, height)); 1010 } 1011 } catch (IllegalArgumentException e) { 1012 } 1013 } 1014 } 1015 1016 // keep unique sizes 1017 minMax.removeAll(mSizes); 1018 mSizes.addAll(minMax); 1019 nearMinMax.removeAll(mSizes); 1020 mSizes.addAll(nearMinMax); 1021 1022 mMinMax.put(new Size(x, y), minMax); 1023 mNearMinMax.put(new Size(x, y), nearMinMax); 1024 if (DEBUG) Log.i(TAG, x + "x" + y + ": minMax=" + mMinMax + ", near=" + mNearMinMax); 1025 } 1026 alignInRange(double value, int align, Range<Integer> range)1027 private int alignInRange(double value, int align, Range<Integer> range) { 1028 return range.clamp(align * (int)Math.round(value / align)); 1029 } 1030 1031 /* point should be between 0. and 1. */ alignedPointInRange(double point, int align, Range<Integer> range)1032 private int alignedPointInRange(double point, int align, Range<Integer> range) { 1033 return alignInRange( 1034 range.getLower() + point * (range.getUpper() - range.getLower()), align, range); 1035 } 1036 getExtreme(Range<Integer> range, int i, int delta)1037 private int getExtreme(Range<Integer> range, int i, int delta) { 1038 int dim = i == 1 ? range.getUpper() - delta : range.getLower() + delta; 1039 if (delta == 0 1040 || (dim > range.getLower() && dim < range.getUpper())) { 1041 return dim; 1042 } 1043 throw new IllegalArgumentException(); 1044 } 1045 getLargestSizeForRatio(int x, int y)1046 private Size getLargestSizeForRatio(int x, int y) { 1047 Range<Integer> widthRange = mVideoCaps.getSupportedWidths(); 1048 Range<Integer> heightRange = mVideoCaps.getSupportedHeightsFor(widthRange.getUpper()); 1049 final int xAlign = mVideoCaps.getWidthAlignment(); 1050 final int yAlign = mVideoCaps.getHeightAlignment(); 1051 1052 // scale by alignment 1053 int width = alignInRange( 1054 Math.sqrt(widthRange.getUpper() * heightRange.getUpper() * (double)x / y), 1055 xAlign, widthRange); 1056 int height = alignInRange( 1057 width * (double)y / x, yAlign, mVideoCaps.getSupportedHeightsFor(width)); 1058 return new Size(width, height); 1059 } 1060 1061 testExtreme(int x, int y, boolean flexYUV, boolean near)1062 public boolean testExtreme(int x, int y, boolean flexYUV, boolean near) { 1063 boolean skipped = true; 1064 for (Size s : (near ? mNearMinMax : mMinMax).get(new Size(x, y))) { 1065 if (test(s.getWidth(), s.getHeight(), false /* optional */, flexYUV)) { 1066 skipped = false; 1067 } 1068 } 1069 return !skipped; 1070 } 1071 testArbitrary(boolean flexYUV, boolean widths)1072 public boolean testArbitrary(boolean flexYUV, boolean widths) { 1073 boolean skipped = true; 1074 for (Size s : (widths ? mArbitraryW : mArbitraryH)) { 1075 if (test(s.getWidth(), s.getHeight(), false /* optional */, flexYUV)) { 1076 skipped = false; 1077 } 1078 } 1079 return !skipped; 1080 } 1081 testSpecific(int width, int height, boolean flexYUV)1082 public boolean testSpecific(int width, int height, boolean flexYUV) { 1083 // already tested by one of the min/max tests 1084 if (mSizes.contains(new Size(width, height))) { 1085 return false; 1086 } 1087 return test(width, height, true /* optional */, flexYUV); 1088 } 1089 testIntraRefresh(int width, int height)1090 public boolean testIntraRefresh(int width, int height) { 1091 if (!mCaps.isFeatureSupported(CodecCapabilities.FEATURE_IntraRefresh)) { 1092 return false; 1093 } 1094 1095 final int refreshPeriod[] = new int[] {10, 13, 17, 22, 29, 38, 50, 60}; 1096 1097 // Test the support of refresh periods in the range of 10 - 60 frames 1098 for (int period : refreshPeriod) { 1099 Function<MediaFormat, Boolean> updateConfigFormatHook = 1100 new Function<MediaFormat, Boolean>() { 1101 public Boolean apply(MediaFormat fmt) { 1102 // set i-frame-interval to 10000 so encoded video only has 1 i-frame. 1103 fmt.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10000); 1104 fmt.setInteger(MediaFormat.KEY_INTRA_REFRESH_PERIOD, period); 1105 return true; 1106 } 1107 }; 1108 1109 Function<MediaFormat, Boolean> checkOutputFormatHook = 1110 new Function<MediaFormat, Boolean>() { 1111 public Boolean apply(MediaFormat fmt) { 1112 int intraPeriod = fmt.getInteger(MediaFormat.KEY_INTRA_REFRESH_PERIOD); 1113 // Make sure intra period is correct and carried in the output format. 1114 // intraPeriod must be larger than 0 and operate within 20% of refresh period. 1115 if (intraPeriod > 1.2 * period || intraPeriod < 0.8 * period) { 1116 throw new RuntimeException("Intra period mismatch"); 1117 } 1118 return true; 1119 } 1120 }; 1121 1122 String testName = 1123 mName + '_' + width + "x" + height + '_' + "flexYUV_intraRefresh"; 1124 1125 Consumer<VideoProcessorBase> configureVideoProcessor = 1126 new Consumer<VideoProcessorBase>() { 1127 public void accept(VideoProcessorBase processor) { 1128 processor.setProcessorName(testName); 1129 processor.setUpdateConfigHook(updateConfigFormatHook); 1130 processor.setCheckOutputFormatHook(checkOutputFormatHook); 1131 } 1132 }; 1133 1134 if (!test(width, height, 0 /* frameRate */, 0 /* bitRate */, true /* optional */, 1135 true /* flex */, configureVideoProcessor)) { 1136 return false; 1137 } 1138 } 1139 1140 return true; 1141 } 1142 testDetailed( int width, int height, int frameRate, int bitRate, boolean flexYUV)1143 public boolean testDetailed( 1144 int width, int height, int frameRate, int bitRate, boolean flexYUV) { 1145 String testName = 1146 mName + '_' + width + "x" + height + '_' + (flexYUV ? "flexYUV" : " surface"); 1147 Consumer<VideoProcessorBase> configureVideoProcessor = 1148 new Consumer<VideoProcessorBase>() { 1149 public void accept(VideoProcessorBase processor) { 1150 processor.setProcessorName(testName); 1151 } 1152 }; 1153 return test(width, height, frameRate, bitRate, true /* optional */, flexYUV, 1154 configureVideoProcessor); 1155 } 1156 testSupport(int width, int height, int frameRate, int bitRate)1157 public boolean testSupport(int width, int height, int frameRate, int bitRate) { 1158 return mVideoCaps.areSizeAndRateSupported(width, height, frameRate) && 1159 mVideoCaps.getBitrateRange().contains(bitRate); 1160 } 1161 test( int width, int height, boolean optional, boolean flexYUV)1162 private boolean test( 1163 int width, int height, boolean optional, boolean flexYUV) { 1164 String testName = 1165 mName + '_' + width + "x" + height + '_' + (flexYUV ? "flexYUV" : " surface"); 1166 Consumer<VideoProcessorBase> configureVideoProcessor = 1167 new Consumer<VideoProcessorBase>() { 1168 public void accept(VideoProcessorBase processor) { 1169 processor.setProcessorName(testName); 1170 } 1171 }; 1172 return test(width, height, 0 /* frameRate */, 0 /* bitRate */, 1173 optional, flexYUV, configureVideoProcessor); 1174 } 1175 test( int width, int height, int frameRate, int bitRate, boolean optional, boolean flexYUV, Consumer<VideoProcessorBase> configureVideoProcessor)1176 private boolean test( 1177 int width, int height, int frameRate, int bitRate, boolean optional, 1178 boolean flexYUV, Consumer<VideoProcessorBase> configureVideoProcessor) { 1179 Log.i(TAG, "testing " + mMime + " on " + mName + " for " + width + "x" + height 1180 + (flexYUV ? " flexYUV" : " surface")); 1181 1182 Preconditions.assertTestFileExists(SOURCE_URL); 1183 1184 VideoProcessorBase processor = 1185 flexYUV ? new VideoProcessor() : new SurfaceVideoProcessor(); 1186 1187 processor.setFrameAndBitRates(frameRate, bitRate); 1188 configureVideoProcessor.accept(processor); 1189 1190 // We are using a resource URL as an example 1191 boolean success = processor.processLoop( 1192 SOURCE_URL, mMime, mName, width, height, optional); 1193 if (success) { 1194 success = processor.playBack(getActivity().getSurfaceHolder().getSurface()); 1195 } 1196 return success; 1197 } 1198 } 1199 googH265()1200 private Encoder[] googH265() { return goog(MediaFormat.MIMETYPE_VIDEO_HEVC); } googH264()1201 private Encoder[] googH264() { return goog(MediaFormat.MIMETYPE_VIDEO_AVC); } googH263()1202 private Encoder[] googH263() { return goog(MediaFormat.MIMETYPE_VIDEO_H263); } googMpeg4()1203 private Encoder[] googMpeg4() { return goog(MediaFormat.MIMETYPE_VIDEO_MPEG4); } googVP8()1204 private Encoder[] googVP8() { return goog(MediaFormat.MIMETYPE_VIDEO_VP8); } googVP9()1205 private Encoder[] googVP9() { return goog(MediaFormat.MIMETYPE_VIDEO_VP9); } 1206 otherH265()1207 private Encoder[] otherH265() { return other(MediaFormat.MIMETYPE_VIDEO_HEVC); } otherH264()1208 private Encoder[] otherH264() { return other(MediaFormat.MIMETYPE_VIDEO_AVC); } otherH263()1209 private Encoder[] otherH263() { return other(MediaFormat.MIMETYPE_VIDEO_H263); } otherMpeg4()1210 private Encoder[] otherMpeg4() { return other(MediaFormat.MIMETYPE_VIDEO_MPEG4); } otherVP8()1211 private Encoder[] otherVP8() { return other(MediaFormat.MIMETYPE_VIDEO_VP8); } otherVP9()1212 private Encoder[] otherVP9() { return other(MediaFormat.MIMETYPE_VIDEO_VP9); } 1213 goog(String mime)1214 private Encoder[] goog(String mime) { 1215 return encoders(mime, true /* goog */); 1216 } 1217 other(String mime)1218 private Encoder[] other(String mime) { 1219 return encoders(mime, false /* goog */); 1220 } 1221 combineArray(Encoder[] a, Encoder[] b)1222 private Encoder[] combineArray(Encoder[] a, Encoder[] b) { 1223 Encoder[] all = new Encoder[a.length + b.length]; 1224 System.arraycopy(a, 0, all, 0, a.length); 1225 System.arraycopy(b, 0, all, a.length, b.length); 1226 return all; 1227 } 1228 h264()1229 private Encoder[] h264() { 1230 return combineArray(googH264(), otherH264()); 1231 } 1232 vp8()1233 private Encoder[] vp8() { 1234 return combineArray(googVP8(), otherVP8()); 1235 } 1236 encoders(String mime, boolean goog)1237 private Encoder[] encoders(String mime, boolean goog) { 1238 MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS); 1239 ArrayList<Encoder> result = new ArrayList<Encoder>(); 1240 1241 for (MediaCodecInfo info : mcl.getCodecInfos()) { 1242 if (!info.isEncoder() || !info.isVendor() != goog || info.isAlias()) { 1243 continue; 1244 } 1245 CodecCapabilities caps = null; 1246 try { 1247 caps = info.getCapabilitiesForType(mime); 1248 } catch (IllegalArgumentException e) { // mime is not supported 1249 continue; 1250 } 1251 assertNotNull(info.getName() + " capabilties for " + mime + " returned null", caps); 1252 result.add(new Encoder(info.getName(), mime, caps)); 1253 } 1254 return result.toArray(new Encoder[result.size()]); 1255 } 1256 testGoogH265FlexMinMin()1257 public void testGoogH265FlexMinMin() { minmin(googH265(), true /* flex */); } testGoogH265SurfMinMin()1258 public void testGoogH265SurfMinMin() { minmin(googH265(), false /* flex */); } testGoogH264FlexMinMin()1259 public void testGoogH264FlexMinMin() { minmin(googH264(), true /* flex */); } testGoogH264SurfMinMin()1260 public void testGoogH264SurfMinMin() { minmin(googH264(), false /* flex */); } testGoogH263FlexMinMin()1261 public void testGoogH263FlexMinMin() { minmin(googH263(), true /* flex */); } testGoogH263SurfMinMin()1262 public void testGoogH263SurfMinMin() { minmin(googH263(), false /* flex */); } testGoogMpeg4FlexMinMin()1263 public void testGoogMpeg4FlexMinMin() { minmin(googMpeg4(), true /* flex */); } testGoogMpeg4SurfMinMin()1264 public void testGoogMpeg4SurfMinMin() { minmin(googMpeg4(), false /* flex */); } testGoogVP8FlexMinMin()1265 public void testGoogVP8FlexMinMin() { minmin(googVP8(), true /* flex */); } testGoogVP8SurfMinMin()1266 public void testGoogVP8SurfMinMin() { minmin(googVP8(), false /* flex */); } testGoogVP9FlexMinMin()1267 public void testGoogVP9FlexMinMin() { minmin(googVP9(), true /* flex */); } testGoogVP9SurfMinMin()1268 public void testGoogVP9SurfMinMin() { minmin(googVP9(), false /* flex */); } 1269 1270 @NonMediaMainlineTest testOtherH265FlexMinMin()1271 public void testOtherH265FlexMinMin() { minmin(otherH265(), true /* flex */); } 1272 @NonMediaMainlineTest testOtherH265SurfMinMin()1273 public void testOtherH265SurfMinMin() { minmin(otherH265(), false /* flex */); } 1274 @NonMediaMainlineTest testOtherH264FlexMinMin()1275 public void testOtherH264FlexMinMin() { minmin(otherH264(), true /* flex */); } 1276 @NonMediaMainlineTest testOtherH264SurfMinMin()1277 public void testOtherH264SurfMinMin() { minmin(otherH264(), false /* flex */); } 1278 @NonMediaMainlineTest testOtherH263FlexMinMin()1279 public void testOtherH263FlexMinMin() { minmin(otherH263(), true /* flex */); } 1280 @NonMediaMainlineTest testOtherH263SurfMinMin()1281 public void testOtherH263SurfMinMin() { minmin(otherH263(), false /* flex */); } 1282 @NonMediaMainlineTest testOtherMpeg4FlexMinMin()1283 public void testOtherMpeg4FlexMinMin() { minmin(otherMpeg4(), true /* flex */); } 1284 @NonMediaMainlineTest testOtherMpeg4SurfMinMin()1285 public void testOtherMpeg4SurfMinMin() { minmin(otherMpeg4(), false /* flex */); } 1286 @NonMediaMainlineTest testOtherVP8FlexMinMin()1287 public void testOtherVP8FlexMinMin() { minmin(otherVP8(), true /* flex */); } 1288 @NonMediaMainlineTest testOtherVP8SurfMinMin()1289 public void testOtherVP8SurfMinMin() { minmin(otherVP8(), false /* flex */); } 1290 @NonMediaMainlineTest testOtherVP9FlexMinMin()1291 public void testOtherVP9FlexMinMin() { minmin(otherVP9(), true /* flex */); } 1292 @NonMediaMainlineTest testOtherVP9SurfMinMin()1293 public void testOtherVP9SurfMinMin() { minmin(otherVP9(), false /* flex */); } 1294 testGoogH265FlexMinMax()1295 public void testGoogH265FlexMinMax() { minmax(googH265(), true /* flex */); } testGoogH265SurfMinMax()1296 public void testGoogH265SurfMinMax() { minmax(googH265(), false /* flex */); } testGoogH264FlexMinMax()1297 public void testGoogH264FlexMinMax() { minmax(googH264(), true /* flex */); } testGoogH264SurfMinMax()1298 public void testGoogH264SurfMinMax() { minmax(googH264(), false /* flex */); } testGoogH263FlexMinMax()1299 public void testGoogH263FlexMinMax() { minmax(googH263(), true /* flex */); } testGoogH263SurfMinMax()1300 public void testGoogH263SurfMinMax() { minmax(googH263(), false /* flex */); } testGoogMpeg4FlexMinMax()1301 public void testGoogMpeg4FlexMinMax() { minmax(googMpeg4(), true /* flex */); } testGoogMpeg4SurfMinMax()1302 public void testGoogMpeg4SurfMinMax() { minmax(googMpeg4(), false /* flex */); } testGoogVP8FlexMinMax()1303 public void testGoogVP8FlexMinMax() { minmax(googVP8(), true /* flex */); } testGoogVP8SurfMinMax()1304 public void testGoogVP8SurfMinMax() { minmax(googVP8(), false /* flex */); } testGoogVP9FlexMinMax()1305 public void testGoogVP9FlexMinMax() { minmax(googVP9(), true /* flex */); } testGoogVP9SurfMinMax()1306 public void testGoogVP9SurfMinMax() { minmax(googVP9(), false /* flex */); } 1307 1308 @NonMediaMainlineTest testOtherH265FlexMinMax()1309 public void testOtherH265FlexMinMax() { minmax(otherH265(), true /* flex */); } 1310 @NonMediaMainlineTest testOtherH265SurfMinMax()1311 public void testOtherH265SurfMinMax() { minmax(otherH265(), false /* flex */); } 1312 @NonMediaMainlineTest testOtherH264FlexMinMax()1313 public void testOtherH264FlexMinMax() { minmax(otherH264(), true /* flex */); } 1314 @NonMediaMainlineTest testOtherH264SurfMinMax()1315 public void testOtherH264SurfMinMax() { minmax(otherH264(), false /* flex */); } 1316 @NonMediaMainlineTest testOtherH263FlexMinMax()1317 public void testOtherH263FlexMinMax() { minmax(otherH263(), true /* flex */); } 1318 @NonMediaMainlineTest testOtherH263SurfMinMax()1319 public void testOtherH263SurfMinMax() { minmax(otherH263(), false /* flex */); } 1320 @NonMediaMainlineTest testOtherMpeg4FlexMinMax()1321 public void testOtherMpeg4FlexMinMax() { minmax(otherMpeg4(), true /* flex */); } 1322 @NonMediaMainlineTest testOtherMpeg4SurfMinMax()1323 public void testOtherMpeg4SurfMinMax() { minmax(otherMpeg4(), false /* flex */); } 1324 @NonMediaMainlineTest testOtherVP8FlexMinMax()1325 public void testOtherVP8FlexMinMax() { minmax(otherVP8(), true /* flex */); } 1326 @NonMediaMainlineTest testOtherVP8SurfMinMax()1327 public void testOtherVP8SurfMinMax() { minmax(otherVP8(), false /* flex */); } 1328 @NonMediaMainlineTest testOtherVP9FlexMinMax()1329 public void testOtherVP9FlexMinMax() { minmax(otherVP9(), true /* flex */); } 1330 @NonMediaMainlineTest testOtherVP9SurfMinMax()1331 public void testOtherVP9SurfMinMax() { minmax(otherVP9(), false /* flex */); } 1332 testGoogH265FlexMaxMin()1333 public void testGoogH265FlexMaxMin() { maxmin(googH265(), true /* flex */); } testGoogH265SurfMaxMin()1334 public void testGoogH265SurfMaxMin() { maxmin(googH265(), false /* flex */); } testGoogH264FlexMaxMin()1335 public void testGoogH264FlexMaxMin() { maxmin(googH264(), true /* flex */); } testGoogH264SurfMaxMin()1336 public void testGoogH264SurfMaxMin() { maxmin(googH264(), false /* flex */); } testGoogH263FlexMaxMin()1337 public void testGoogH263FlexMaxMin() { maxmin(googH263(), true /* flex */); } testGoogH263SurfMaxMin()1338 public void testGoogH263SurfMaxMin() { maxmin(googH263(), false /* flex */); } testGoogMpeg4FlexMaxMin()1339 public void testGoogMpeg4FlexMaxMin() { maxmin(googMpeg4(), true /* flex */); } testGoogMpeg4SurfMaxMin()1340 public void testGoogMpeg4SurfMaxMin() { maxmin(googMpeg4(), false /* flex */); } testGoogVP8FlexMaxMin()1341 public void testGoogVP8FlexMaxMin() { maxmin(googVP8(), true /* flex */); } testGoogVP8SurfMaxMin()1342 public void testGoogVP8SurfMaxMin() { maxmin(googVP8(), false /* flex */); } testGoogVP9FlexMaxMin()1343 public void testGoogVP9FlexMaxMin() { maxmin(googVP9(), true /* flex */); } testGoogVP9SurfMaxMin()1344 public void testGoogVP9SurfMaxMin() { maxmin(googVP9(), false /* flex */); } 1345 1346 @NonMediaMainlineTest testOtherH265FlexMaxMin()1347 public void testOtherH265FlexMaxMin() { maxmin(otherH265(), true /* flex */); } 1348 @NonMediaMainlineTest testOtherH265SurfMaxMin()1349 public void testOtherH265SurfMaxMin() { maxmin(otherH265(), false /* flex */); } 1350 @NonMediaMainlineTest testOtherH264FlexMaxMin()1351 public void testOtherH264FlexMaxMin() { maxmin(otherH264(), true /* flex */); } 1352 @NonMediaMainlineTest testOtherH264SurfMaxMin()1353 public void testOtherH264SurfMaxMin() { maxmin(otherH264(), false /* flex */); } 1354 @NonMediaMainlineTest testOtherH263FlexMaxMin()1355 public void testOtherH263FlexMaxMin() { maxmin(otherH263(), true /* flex */); } 1356 @NonMediaMainlineTest testOtherH263SurfMaxMin()1357 public void testOtherH263SurfMaxMin() { maxmin(otherH263(), false /* flex */); } 1358 @NonMediaMainlineTest testOtherMpeg4FlexMaxMin()1359 public void testOtherMpeg4FlexMaxMin() { maxmin(otherMpeg4(), true /* flex */); } 1360 @NonMediaMainlineTest testOtherMpeg4SurfMaxMin()1361 public void testOtherMpeg4SurfMaxMin() { maxmin(otherMpeg4(), false /* flex */); } 1362 @NonMediaMainlineTest testOtherVP8FlexMaxMin()1363 public void testOtherVP8FlexMaxMin() { maxmin(otherVP8(), true /* flex */); } 1364 @NonMediaMainlineTest testOtherVP8SurfMaxMin()1365 public void testOtherVP8SurfMaxMin() { maxmin(otherVP8(), false /* flex */); } 1366 @NonMediaMainlineTest testOtherVP9FlexMaxMin()1367 public void testOtherVP9FlexMaxMin() { maxmin(otherVP9(), true /* flex */); } 1368 @NonMediaMainlineTest testOtherVP9SurfMaxMin()1369 public void testOtherVP9SurfMaxMin() { maxmin(otherVP9(), false /* flex */); } 1370 testGoogH265FlexMaxMax()1371 public void testGoogH265FlexMaxMax() { maxmax(googH265(), true /* flex */); } testGoogH265SurfMaxMax()1372 public void testGoogH265SurfMaxMax() { maxmax(googH265(), false /* flex */); } testGoogH264FlexMaxMax()1373 public void testGoogH264FlexMaxMax() { maxmax(googH264(), true /* flex */); } testGoogH264SurfMaxMax()1374 public void testGoogH264SurfMaxMax() { maxmax(googH264(), false /* flex */); } testGoogH263FlexMaxMax()1375 public void testGoogH263FlexMaxMax() { maxmax(googH263(), true /* flex */); } testGoogH263SurfMaxMax()1376 public void testGoogH263SurfMaxMax() { maxmax(googH263(), false /* flex */); } testGoogMpeg4FlexMaxMax()1377 public void testGoogMpeg4FlexMaxMax() { maxmax(googMpeg4(), true /* flex */); } testGoogMpeg4SurfMaxMax()1378 public void testGoogMpeg4SurfMaxMax() { maxmax(googMpeg4(), false /* flex */); } testGoogVP8FlexMaxMax()1379 public void testGoogVP8FlexMaxMax() { maxmax(googVP8(), true /* flex */); } testGoogVP8SurfMaxMax()1380 public void testGoogVP8SurfMaxMax() { maxmax(googVP8(), false /* flex */); } testGoogVP9FlexMaxMax()1381 public void testGoogVP9FlexMaxMax() { maxmax(googVP9(), true /* flex */); } testGoogVP9SurfMaxMax()1382 public void testGoogVP9SurfMaxMax() { maxmax(googVP9(), false /* flex */); } 1383 1384 @NonMediaMainlineTest testOtherH265FlexMaxMax()1385 public void testOtherH265FlexMaxMax() { maxmax(otherH265(), true /* flex */); } 1386 @NonMediaMainlineTest testOtherH265SurfMaxMax()1387 public void testOtherH265SurfMaxMax() { maxmax(otherH265(), false /* flex */); } 1388 @NonMediaMainlineTest testOtherH264FlexMaxMax()1389 public void testOtherH264FlexMaxMax() { maxmax(otherH264(), true /* flex */); } 1390 @NonMediaMainlineTest testOtherH264SurfMaxMax()1391 public void testOtherH264SurfMaxMax() { maxmax(otherH264(), false /* flex */); } 1392 @NonMediaMainlineTest testOtherH263FlexMaxMax()1393 public void testOtherH263FlexMaxMax() { maxmax(otherH263(), true /* flex */); } 1394 @NonMediaMainlineTest testOtherH263SurfMaxMax()1395 public void testOtherH263SurfMaxMax() { maxmax(otherH263(), false /* flex */); } 1396 @NonMediaMainlineTest testOtherMpeg4FlexMaxMax()1397 public void testOtherMpeg4FlexMaxMax() { maxmax(otherMpeg4(), true /* flex */); } 1398 @NonMediaMainlineTest testOtherMpeg4SurfMaxMax()1399 public void testOtherMpeg4SurfMaxMax() { maxmax(otherMpeg4(), false /* flex */); } 1400 @NonMediaMainlineTest testOtherVP8FlexMaxMax()1401 public void testOtherVP8FlexMaxMax() { maxmax(otherVP8(), true /* flex */); } 1402 @NonMediaMainlineTest testOtherVP8SurfMaxMax()1403 public void testOtherVP8SurfMaxMax() { maxmax(otherVP8(), false /* flex */); } 1404 @NonMediaMainlineTest testOtherVP9FlexMaxMax()1405 public void testOtherVP9FlexMaxMax() { maxmax(otherVP9(), true /* flex */); } 1406 @NonMediaMainlineTest testOtherVP9SurfMaxMax()1407 public void testOtherVP9SurfMaxMax() { maxmax(otherVP9(), false /* flex */); } 1408 testGoogH265FlexNearMinMin()1409 public void testGoogH265FlexNearMinMin() { nearminmin(googH265(), true /* flex */); } testGoogH265SurfNearMinMin()1410 public void testGoogH265SurfNearMinMin() { nearminmin(googH265(), false /* flex */); } testGoogH264FlexNearMinMin()1411 public void testGoogH264FlexNearMinMin() { nearminmin(googH264(), true /* flex */); } testGoogH264SurfNearMinMin()1412 public void testGoogH264SurfNearMinMin() { nearminmin(googH264(), false /* flex */); } testGoogH263FlexNearMinMin()1413 public void testGoogH263FlexNearMinMin() { nearminmin(googH263(), true /* flex */); } testGoogH263SurfNearMinMin()1414 public void testGoogH263SurfNearMinMin() { nearminmin(googH263(), false /* flex */); } testGoogMpeg4FlexNearMinMin()1415 public void testGoogMpeg4FlexNearMinMin() { nearminmin(googMpeg4(), true /* flex */); } testGoogMpeg4SurfNearMinMin()1416 public void testGoogMpeg4SurfNearMinMin() { nearminmin(googMpeg4(), false /* flex */); } testGoogVP8FlexNearMinMin()1417 public void testGoogVP8FlexNearMinMin() { nearminmin(googVP8(), true /* flex */); } testGoogVP8SurfNearMinMin()1418 public void testGoogVP8SurfNearMinMin() { nearminmin(googVP8(), false /* flex */); } testGoogVP9FlexNearMinMin()1419 public void testGoogVP9FlexNearMinMin() { nearminmin(googVP9(), true /* flex */); } testGoogVP9SurfNearMinMin()1420 public void testGoogVP9SurfNearMinMin() { nearminmin(googVP9(), false /* flex */); } 1421 1422 @NonMediaMainlineTest testOtherH265FlexNearMinMin()1423 public void testOtherH265FlexNearMinMin() { nearminmin(otherH265(), true /* flex */); } 1424 @NonMediaMainlineTest testOtherH265SurfNearMinMin()1425 public void testOtherH265SurfNearMinMin() { nearminmin(otherH265(), false /* flex */); } 1426 @NonMediaMainlineTest testOtherH264FlexNearMinMin()1427 public void testOtherH264FlexNearMinMin() { nearminmin(otherH264(), true /* flex */); } 1428 @NonMediaMainlineTest testOtherH264SurfNearMinMin()1429 public void testOtherH264SurfNearMinMin() { nearminmin(otherH264(), false /* flex */); } 1430 @NonMediaMainlineTest testOtherH263FlexNearMinMin()1431 public void testOtherH263FlexNearMinMin() { nearminmin(otherH263(), true /* flex */); } 1432 @NonMediaMainlineTest testOtherH263SurfNearMinMin()1433 public void testOtherH263SurfNearMinMin() { nearminmin(otherH263(), false /* flex */); } 1434 @NonMediaMainlineTest testOtherMpeg4FlexNearMinMin()1435 public void testOtherMpeg4FlexNearMinMin() { nearminmin(otherMpeg4(), true /* flex */); } 1436 @NonMediaMainlineTest testOtherMpeg4SurfNearMinMin()1437 public void testOtherMpeg4SurfNearMinMin() { nearminmin(otherMpeg4(), false /* flex */); } 1438 @NonMediaMainlineTest testOtherVP8FlexNearMinMin()1439 public void testOtherVP8FlexNearMinMin() { nearminmin(otherVP8(), true /* flex */); } 1440 @NonMediaMainlineTest testOtherVP8SurfNearMinMin()1441 public void testOtherVP8SurfNearMinMin() { nearminmin(otherVP8(), false /* flex */); } 1442 @NonMediaMainlineTest testOtherVP9FlexNearMinMin()1443 public void testOtherVP9FlexNearMinMin() { nearminmin(otherVP9(), true /* flex */); } 1444 @NonMediaMainlineTest testOtherVP9SurfNearMinMin()1445 public void testOtherVP9SurfNearMinMin() { nearminmin(otherVP9(), false /* flex */); } 1446 testGoogH265FlexNearMinMax()1447 public void testGoogH265FlexNearMinMax() { nearminmax(googH265(), true /* flex */); } testGoogH265SurfNearMinMax()1448 public void testGoogH265SurfNearMinMax() { nearminmax(googH265(), false /* flex */); } testGoogH264FlexNearMinMax()1449 public void testGoogH264FlexNearMinMax() { nearminmax(googH264(), true /* flex */); } testGoogH264SurfNearMinMax()1450 public void testGoogH264SurfNearMinMax() { nearminmax(googH264(), false /* flex */); } testGoogH263FlexNearMinMax()1451 public void testGoogH263FlexNearMinMax() { nearminmax(googH263(), true /* flex */); } testGoogH263SurfNearMinMax()1452 public void testGoogH263SurfNearMinMax() { nearminmax(googH263(), false /* flex */); } testGoogMpeg4FlexNearMinMax()1453 public void testGoogMpeg4FlexNearMinMax() { nearminmax(googMpeg4(), true /* flex */); } testGoogMpeg4SurfNearMinMax()1454 public void testGoogMpeg4SurfNearMinMax() { nearminmax(googMpeg4(), false /* flex */); } testGoogVP8FlexNearMinMax()1455 public void testGoogVP8FlexNearMinMax() { nearminmax(googVP8(), true /* flex */); } testGoogVP8SurfNearMinMax()1456 public void testGoogVP8SurfNearMinMax() { nearminmax(googVP8(), false /* flex */); } testGoogVP9FlexNearMinMax()1457 public void testGoogVP9FlexNearMinMax() { nearminmax(googVP9(), true /* flex */); } testGoogVP9SurfNearMinMax()1458 public void testGoogVP9SurfNearMinMax() { nearminmax(googVP9(), false /* flex */); } 1459 1460 @NonMediaMainlineTest testOtherH265FlexNearMinMax()1461 public void testOtherH265FlexNearMinMax() { nearminmax(otherH265(), true /* flex */); } 1462 @NonMediaMainlineTest testOtherH265SurfNearMinMax()1463 public void testOtherH265SurfNearMinMax() { nearminmax(otherH265(), false /* flex */); } 1464 @NonMediaMainlineTest testOtherH264FlexNearMinMax()1465 public void testOtherH264FlexNearMinMax() { nearminmax(otherH264(), true /* flex */); } 1466 @NonMediaMainlineTest testOtherH264SurfNearMinMax()1467 public void testOtherH264SurfNearMinMax() { nearminmax(otherH264(), false /* flex */); } 1468 @NonMediaMainlineTest testOtherH263FlexNearMinMax()1469 public void testOtherH263FlexNearMinMax() { nearminmax(otherH263(), true /* flex */); } 1470 @NonMediaMainlineTest testOtherH263SurfNearMinMax()1471 public void testOtherH263SurfNearMinMax() { nearminmax(otherH263(), false /* flex */); } 1472 @NonMediaMainlineTest testOtherMpeg4FlexNearMinMax()1473 public void testOtherMpeg4FlexNearMinMax() { nearminmax(otherMpeg4(), true /* flex */); } 1474 @NonMediaMainlineTest testOtherMpeg4SurfNearMinMax()1475 public void testOtherMpeg4SurfNearMinMax() { nearminmax(otherMpeg4(), false /* flex */); } 1476 @NonMediaMainlineTest testOtherVP8FlexNearMinMax()1477 public void testOtherVP8FlexNearMinMax() { nearminmax(otherVP8(), true /* flex */); } 1478 @NonMediaMainlineTest testOtherVP8SurfNearMinMax()1479 public void testOtherVP8SurfNearMinMax() { nearminmax(otherVP8(), false /* flex */); } 1480 @NonMediaMainlineTest testOtherVP9FlexNearMinMax()1481 public void testOtherVP9FlexNearMinMax() { nearminmax(otherVP9(), true /* flex */); } 1482 @NonMediaMainlineTest testOtherVP9SurfNearMinMax()1483 public void testOtherVP9SurfNearMinMax() { nearminmax(otherVP9(), false /* flex */); } 1484 testGoogH265FlexNearMaxMin()1485 public void testGoogH265FlexNearMaxMin() { nearmaxmin(googH265(), true /* flex */); } testGoogH265SurfNearMaxMin()1486 public void testGoogH265SurfNearMaxMin() { nearmaxmin(googH265(), false /* flex */); } testGoogH264FlexNearMaxMin()1487 public void testGoogH264FlexNearMaxMin() { nearmaxmin(googH264(), true /* flex */); } testGoogH264SurfNearMaxMin()1488 public void testGoogH264SurfNearMaxMin() { nearmaxmin(googH264(), false /* flex */); } testGoogH263FlexNearMaxMin()1489 public void testGoogH263FlexNearMaxMin() { nearmaxmin(googH263(), true /* flex */); } testGoogH263SurfNearMaxMin()1490 public void testGoogH263SurfNearMaxMin() { nearmaxmin(googH263(), false /* flex */); } testGoogMpeg4FlexNearMaxMin()1491 public void testGoogMpeg4FlexNearMaxMin() { nearmaxmin(googMpeg4(), true /* flex */); } testGoogMpeg4SurfNearMaxMin()1492 public void testGoogMpeg4SurfNearMaxMin() { nearmaxmin(googMpeg4(), false /* flex */); } testGoogVP8FlexNearMaxMin()1493 public void testGoogVP8FlexNearMaxMin() { nearmaxmin(googVP8(), true /* flex */); } testGoogVP8SurfNearMaxMin()1494 public void testGoogVP8SurfNearMaxMin() { nearmaxmin(googVP8(), false /* flex */); } testGoogVP9FlexNearMaxMin()1495 public void testGoogVP9FlexNearMaxMin() { nearmaxmin(googVP9(), true /* flex */); } testGoogVP9SurfNearMaxMin()1496 public void testGoogVP9SurfNearMaxMin() { nearmaxmin(googVP9(), false /* flex */); } 1497 1498 @NonMediaMainlineTest testOtherH265FlexNearMaxMin()1499 public void testOtherH265FlexNearMaxMin() { nearmaxmin(otherH265(), true /* flex */); } 1500 @NonMediaMainlineTest testOtherH265SurfNearMaxMin()1501 public void testOtherH265SurfNearMaxMin() { nearmaxmin(otherH265(), false /* flex */); } 1502 @NonMediaMainlineTest testOtherH264FlexNearMaxMin()1503 public void testOtherH264FlexNearMaxMin() { nearmaxmin(otherH264(), true /* flex */); } 1504 @NonMediaMainlineTest testOtherH264SurfNearMaxMin()1505 public void testOtherH264SurfNearMaxMin() { nearmaxmin(otherH264(), false /* flex */); } 1506 @NonMediaMainlineTest testOtherH263FlexNearMaxMin()1507 public void testOtherH263FlexNearMaxMin() { nearmaxmin(otherH263(), true /* flex */); } 1508 @NonMediaMainlineTest testOtherH263SurfNearMaxMin()1509 public void testOtherH263SurfNearMaxMin() { nearmaxmin(otherH263(), false /* flex */); } 1510 @NonMediaMainlineTest testOtherMpeg4FlexNearMaxMin()1511 public void testOtherMpeg4FlexNearMaxMin() { nearmaxmin(otherMpeg4(), true /* flex */); } 1512 @NonMediaMainlineTest testOtherMpeg4SurfNearMaxMin()1513 public void testOtherMpeg4SurfNearMaxMin() { nearmaxmin(otherMpeg4(), false /* flex */); } 1514 @NonMediaMainlineTest testOtherVP8FlexNearMaxMin()1515 public void testOtherVP8FlexNearMaxMin() { nearmaxmin(otherVP8(), true /* flex */); } 1516 @NonMediaMainlineTest testOtherVP8SurfNearMaxMin()1517 public void testOtherVP8SurfNearMaxMin() { nearmaxmin(otherVP8(), false /* flex */); } 1518 @NonMediaMainlineTest testOtherVP9FlexNearMaxMin()1519 public void testOtherVP9FlexNearMaxMin() { nearmaxmin(otherVP9(), true /* flex */); } 1520 @NonMediaMainlineTest testOtherVP9SurfNearMaxMin()1521 public void testOtherVP9SurfNearMaxMin() { nearmaxmin(otherVP9(), false /* flex */); } 1522 testGoogH265FlexNearMaxMax()1523 public void testGoogH265FlexNearMaxMax() { nearmaxmax(googH265(), true /* flex */); } testGoogH265SurfNearMaxMax()1524 public void testGoogH265SurfNearMaxMax() { nearmaxmax(googH265(), false /* flex */); } testGoogH264FlexNearMaxMax()1525 public void testGoogH264FlexNearMaxMax() { nearmaxmax(googH264(), true /* flex */); } testGoogH264SurfNearMaxMax()1526 public void testGoogH264SurfNearMaxMax() { nearmaxmax(googH264(), false /* flex */); } testGoogH263FlexNearMaxMax()1527 public void testGoogH263FlexNearMaxMax() { nearmaxmax(googH263(), true /* flex */); } testGoogH263SurfNearMaxMax()1528 public void testGoogH263SurfNearMaxMax() { nearmaxmax(googH263(), false /* flex */); } testGoogMpeg4FlexNearMaxMax()1529 public void testGoogMpeg4FlexNearMaxMax() { nearmaxmax(googMpeg4(), true /* flex */); } testGoogMpeg4SurfNearMaxMax()1530 public void testGoogMpeg4SurfNearMaxMax() { nearmaxmax(googMpeg4(), false /* flex */); } testGoogVP8FlexNearMaxMax()1531 public void testGoogVP8FlexNearMaxMax() { nearmaxmax(googVP8(), true /* flex */); } testGoogVP8SurfNearMaxMax()1532 public void testGoogVP8SurfNearMaxMax() { nearmaxmax(googVP8(), false /* flex */); } testGoogVP9FlexNearMaxMax()1533 public void testGoogVP9FlexNearMaxMax() { nearmaxmax(googVP9(), true /* flex */); } testGoogVP9SurfNearMaxMax()1534 public void testGoogVP9SurfNearMaxMax() { nearmaxmax(googVP9(), false /* flex */); } 1535 1536 @NonMediaMainlineTest testOtherH265FlexNearMaxMax()1537 public void testOtherH265FlexNearMaxMax() { nearmaxmax(otherH265(), true /* flex */); } 1538 @NonMediaMainlineTest testOtherH265SurfNearMaxMax()1539 public void testOtherH265SurfNearMaxMax() { nearmaxmax(otherH265(), false /* flex */); } 1540 @NonMediaMainlineTest testOtherH264FlexNearMaxMax()1541 public void testOtherH264FlexNearMaxMax() { nearmaxmax(otherH264(), true /* flex */); } 1542 @NonMediaMainlineTest testOtherH264SurfNearMaxMax()1543 public void testOtherH264SurfNearMaxMax() { nearmaxmax(otherH264(), false /* flex */); } 1544 @NonMediaMainlineTest testOtherH263FlexNearMaxMax()1545 public void testOtherH263FlexNearMaxMax() { nearmaxmax(otherH263(), true /* flex */); } 1546 @NonMediaMainlineTest testOtherH263SurfNearMaxMax()1547 public void testOtherH263SurfNearMaxMax() { nearmaxmax(otherH263(), false /* flex */); } 1548 @NonMediaMainlineTest testOtherMpeg4FlexNearMaxMax()1549 public void testOtherMpeg4FlexNearMaxMax() { nearmaxmax(otherMpeg4(), true /* flex */); } 1550 @NonMediaMainlineTest testOtherMpeg4SurfNearMaxMax()1551 public void testOtherMpeg4SurfNearMaxMax() { nearmaxmax(otherMpeg4(), false /* flex */); } 1552 @NonMediaMainlineTest testOtherVP8FlexNearMaxMax()1553 public void testOtherVP8FlexNearMaxMax() { nearmaxmax(otherVP8(), true /* flex */); } 1554 @NonMediaMainlineTest testOtherVP8SurfNearMaxMax()1555 public void testOtherVP8SurfNearMaxMax() { nearmaxmax(otherVP8(), false /* flex */); } 1556 @NonMediaMainlineTest testOtherVP9FlexNearMaxMax()1557 public void testOtherVP9FlexNearMaxMax() { nearmaxmax(otherVP9(), true /* flex */); } 1558 @NonMediaMainlineTest testOtherVP9SurfNearMaxMax()1559 public void testOtherVP9SurfNearMaxMax() { nearmaxmax(otherVP9(), false /* flex */); } 1560 testGoogH265FlexArbitraryW()1561 public void testGoogH265FlexArbitraryW() { arbitraryw(googH265(), true /* flex */); } testGoogH265SurfArbitraryW()1562 public void testGoogH265SurfArbitraryW() { arbitraryw(googH265(), false /* flex */); } testGoogH264FlexArbitraryW()1563 public void testGoogH264FlexArbitraryW() { arbitraryw(googH264(), true /* flex */); } testGoogH264SurfArbitraryW()1564 public void testGoogH264SurfArbitraryW() { arbitraryw(googH264(), false /* flex */); } testGoogH263FlexArbitraryW()1565 public void testGoogH263FlexArbitraryW() { arbitraryw(googH263(), true /* flex */); } testGoogH263SurfArbitraryW()1566 public void testGoogH263SurfArbitraryW() { arbitraryw(googH263(), false /* flex */); } testGoogMpeg4FlexArbitraryW()1567 public void testGoogMpeg4FlexArbitraryW() { arbitraryw(googMpeg4(), true /* flex */); } testGoogMpeg4SurfArbitraryW()1568 public void testGoogMpeg4SurfArbitraryW() { arbitraryw(googMpeg4(), false /* flex */); } testGoogVP8FlexArbitraryW()1569 public void testGoogVP8FlexArbitraryW() { arbitraryw(googVP8(), true /* flex */); } testGoogVP8SurfArbitraryW()1570 public void testGoogVP8SurfArbitraryW() { arbitraryw(googVP8(), false /* flex */); } testGoogVP9FlexArbitraryW()1571 public void testGoogVP9FlexArbitraryW() { arbitraryw(googVP9(), true /* flex */); } testGoogVP9SurfArbitraryW()1572 public void testGoogVP9SurfArbitraryW() { arbitraryw(googVP9(), false /* flex */); } 1573 1574 @NonMediaMainlineTest testOtherH265FlexArbitraryW()1575 public void testOtherH265FlexArbitraryW() { arbitraryw(otherH265(), true /* flex */); } 1576 @NonMediaMainlineTest testOtherH265SurfArbitraryW()1577 public void testOtherH265SurfArbitraryW() { arbitraryw(otherH265(), false /* flex */); } 1578 @NonMediaMainlineTest testOtherH264FlexArbitraryW()1579 public void testOtherH264FlexArbitraryW() { arbitraryw(otherH264(), true /* flex */); } 1580 @NonMediaMainlineTest testOtherH264SurfArbitraryW()1581 public void testOtherH264SurfArbitraryW() { arbitraryw(otherH264(), false /* flex */); } 1582 @NonMediaMainlineTest testOtherH263FlexArbitraryW()1583 public void testOtherH263FlexArbitraryW() { arbitraryw(otherH263(), true /* flex */); } 1584 @NonMediaMainlineTest testOtherH263SurfArbitraryW()1585 public void testOtherH263SurfArbitraryW() { arbitraryw(otherH263(), false /* flex */); } 1586 @NonMediaMainlineTest testOtherMpeg4FlexArbitraryW()1587 public void testOtherMpeg4FlexArbitraryW() { arbitraryw(otherMpeg4(), true /* flex */); } 1588 @NonMediaMainlineTest testOtherMpeg4SurfArbitraryW()1589 public void testOtherMpeg4SurfArbitraryW() { arbitraryw(otherMpeg4(), false /* flex */); } 1590 @NonMediaMainlineTest testOtherVP8FlexArbitraryW()1591 public void testOtherVP8FlexArbitraryW() { arbitraryw(otherVP8(), true /* flex */); } 1592 @NonMediaMainlineTest testOtherVP8SurfArbitraryW()1593 public void testOtherVP8SurfArbitraryW() { arbitraryw(otherVP8(), false /* flex */); } 1594 @NonMediaMainlineTest testOtherVP9FlexArbitraryW()1595 public void testOtherVP9FlexArbitraryW() { arbitraryw(otherVP9(), true /* flex */); } 1596 @NonMediaMainlineTest testOtherVP9SurfArbitraryW()1597 public void testOtherVP9SurfArbitraryW() { arbitraryw(otherVP9(), false /* flex */); } 1598 testGoogH265FlexArbitraryH()1599 public void testGoogH265FlexArbitraryH() { arbitraryh(googH265(), true /* flex */); } testGoogH265SurfArbitraryH()1600 public void testGoogH265SurfArbitraryH() { arbitraryh(googH265(), false /* flex */); } testGoogH264FlexArbitraryH()1601 public void testGoogH264FlexArbitraryH() { arbitraryh(googH264(), true /* flex */); } testGoogH264SurfArbitraryH()1602 public void testGoogH264SurfArbitraryH() { arbitraryh(googH264(), false /* flex */); } testGoogH263FlexArbitraryH()1603 public void testGoogH263FlexArbitraryH() { arbitraryh(googH263(), true /* flex */); } testGoogH263SurfArbitraryH()1604 public void testGoogH263SurfArbitraryH() { arbitraryh(googH263(), false /* flex */); } testGoogMpeg4FlexArbitraryH()1605 public void testGoogMpeg4FlexArbitraryH() { arbitraryh(googMpeg4(), true /* flex */); } testGoogMpeg4SurfArbitraryH()1606 public void testGoogMpeg4SurfArbitraryH() { arbitraryh(googMpeg4(), false /* flex */); } testGoogVP8FlexArbitraryH()1607 public void testGoogVP8FlexArbitraryH() { arbitraryh(googVP8(), true /* flex */); } testGoogVP8SurfArbitraryH()1608 public void testGoogVP8SurfArbitraryH() { arbitraryh(googVP8(), false /* flex */); } testGoogVP9FlexArbitraryH()1609 public void testGoogVP9FlexArbitraryH() { arbitraryh(googVP9(), true /* flex */); } testGoogVP9SurfArbitraryH()1610 public void testGoogVP9SurfArbitraryH() { arbitraryh(googVP9(), false /* flex */); } 1611 1612 @NonMediaMainlineTest testOtherH265FlexArbitraryH()1613 public void testOtherH265FlexArbitraryH() { arbitraryh(otherH265(), true /* flex */); } 1614 @NonMediaMainlineTest testOtherH265SurfArbitraryH()1615 public void testOtherH265SurfArbitraryH() { arbitraryh(otherH265(), false /* flex */); } 1616 @NonMediaMainlineTest testOtherH264FlexArbitraryH()1617 public void testOtherH264FlexArbitraryH() { arbitraryh(otherH264(), true /* flex */); } 1618 @NonMediaMainlineTest testOtherH264SurfArbitraryH()1619 public void testOtherH264SurfArbitraryH() { arbitraryh(otherH264(), false /* flex */); } 1620 @NonMediaMainlineTest testOtherH263FlexArbitraryH()1621 public void testOtherH263FlexArbitraryH() { arbitraryh(otherH263(), true /* flex */); } 1622 @NonMediaMainlineTest testOtherH263SurfArbitraryH()1623 public void testOtherH263SurfArbitraryH() { arbitraryh(otherH263(), false /* flex */); } 1624 @NonMediaMainlineTest testOtherMpeg4FlexArbitraryH()1625 public void testOtherMpeg4FlexArbitraryH() { arbitraryh(otherMpeg4(), true /* flex */); } 1626 @NonMediaMainlineTest testOtherMpeg4SurfArbitraryH()1627 public void testOtherMpeg4SurfArbitraryH() { arbitraryh(otherMpeg4(), false /* flex */); } 1628 @NonMediaMainlineTest testOtherVP8FlexArbitraryH()1629 public void testOtherVP8FlexArbitraryH() { arbitraryh(otherVP8(), true /* flex */); } 1630 @NonMediaMainlineTest testOtherVP8SurfArbitraryH()1631 public void testOtherVP8SurfArbitraryH() { arbitraryh(otherVP8(), false /* flex */); } 1632 @NonMediaMainlineTest testOtherVP9FlexArbitraryH()1633 public void testOtherVP9FlexArbitraryH() { arbitraryh(otherVP9(), true /* flex */); } 1634 @NonMediaMainlineTest testOtherVP9SurfArbitraryH()1635 public void testOtherVP9SurfArbitraryH() { arbitraryh(otherVP9(), false /* flex */); } 1636 testGoogH265FlexQCIF()1637 public void testGoogH265FlexQCIF() { specific(googH265(), 176, 144, true /* flex */); } testGoogH265SurfQCIF()1638 public void testGoogH265SurfQCIF() { specific(googH265(), 176, 144, false /* flex */); } 1639 @Presubmit 1640 @SmallTest testGoogH264FlexQCIF()1641 public void testGoogH264FlexQCIF() { specific(googH264(), 176, 144, true /* flex */); } 1642 @Presubmit 1643 @SmallTest testGoogH264SurfQCIF()1644 public void testGoogH264SurfQCIF() { specific(googH264(), 176, 144, false /* flex */); } testGoogH263FlexQCIF()1645 public void testGoogH263FlexQCIF() { specific(googH263(), 176, 144, true /* flex */); } testGoogH263SurfQCIF()1646 public void testGoogH263SurfQCIF() { specific(googH263(), 176, 144, false /* flex */); } testGoogMpeg4FlexQCIF()1647 public void testGoogMpeg4FlexQCIF() { specific(googMpeg4(), 176, 144, true /* flex */); } testGoogMpeg4SurfQCIF()1648 public void testGoogMpeg4SurfQCIF() { specific(googMpeg4(), 176, 144, false /* flex */); } testGoogVP8FlexQCIF()1649 public void testGoogVP8FlexQCIF() { specific(googVP8(), 176, 144, true /* flex */); } testGoogVP8SurfQCIF()1650 public void testGoogVP8SurfQCIF() { specific(googVP8(), 176, 144, false /* flex */); } testGoogVP9FlexQCIF()1651 public void testGoogVP9FlexQCIF() { specific(googVP9(), 176, 144, true /* flex */); } testGoogVP9SurfQCIF()1652 public void testGoogVP9SurfQCIF() { specific(googVP9(), 176, 144, false /* flex */); } 1653 1654 @NonMediaMainlineTest testOtherH265FlexQCIF()1655 public void testOtherH265FlexQCIF() { specific(otherH265(), 176, 144, true /* flex */); } 1656 @NonMediaMainlineTest testOtherH265SurfQCIF()1657 public void testOtherH265SurfQCIF() { specific(otherH265(), 176, 144, false /* flex */); } 1658 @NonMediaMainlineTest 1659 @RequiresDevice 1660 @Presubmit 1661 @SmallTest testOtherH264FlexQCIF()1662 public void testOtherH264FlexQCIF() { specific(otherH264(), 176, 144, true /* flex */); } 1663 @NonMediaMainlineTest 1664 @RequiresDevice 1665 @Presubmit 1666 @SmallTest testOtherH264SurfQCIF()1667 public void testOtherH264SurfQCIF() { specific(otherH264(), 176, 144, false /* flex */); } 1668 @NonMediaMainlineTest testOtherH263FlexQCIF()1669 public void testOtherH263FlexQCIF() { specific(otherH263(), 176, 144, true /* flex */); } 1670 @NonMediaMainlineTest testOtherH263SurfQCIF()1671 public void testOtherH263SurfQCIF() { specific(otherH263(), 176, 144, false /* flex */); } 1672 @NonMediaMainlineTest testOtherMpeg4FlexQCIF()1673 public void testOtherMpeg4FlexQCIF() { specific(otherMpeg4(), 176, 144, true /* flex */); } 1674 @NonMediaMainlineTest testOtherMpeg4SurfQCIF()1675 public void testOtherMpeg4SurfQCIF() { specific(otherMpeg4(), 176, 144, false /* flex */); } 1676 @NonMediaMainlineTest testOtherVP8FlexQCIF()1677 public void testOtherVP8FlexQCIF() { specific(otherVP8(), 176, 144, true /* flex */); } 1678 @NonMediaMainlineTest testOtherVP8SurfQCIF()1679 public void testOtherVP8SurfQCIF() { specific(otherVP8(), 176, 144, false /* flex */); } 1680 @NonMediaMainlineTest testOtherVP9FlexQCIF()1681 public void testOtherVP9FlexQCIF() { specific(otherVP9(), 176, 144, true /* flex */); } 1682 @NonMediaMainlineTest testOtherVP9SurfQCIF()1683 public void testOtherVP9SurfQCIF() { specific(otherVP9(), 176, 144, false /* flex */); } 1684 testGoogH265Flex480p()1685 public void testGoogH265Flex480p() { specific(googH265(), 720, 480, true /* flex */); } testGoogH265Surf480p()1686 public void testGoogH265Surf480p() { specific(googH265(), 720, 480, false /* flex */); } testGoogH264Flex480p()1687 public void testGoogH264Flex480p() { specific(googH264(), 720, 480, true /* flex */); } testGoogH264Surf480p()1688 public void testGoogH264Surf480p() { specific(googH264(), 720, 480, false /* flex */); } testGoogH263Flex480p()1689 public void testGoogH263Flex480p() { specific(googH263(), 720, 480, true /* flex */); } testGoogH263Surf480p()1690 public void testGoogH263Surf480p() { specific(googH263(), 720, 480, false /* flex */); } testGoogMpeg4Flex480p()1691 public void testGoogMpeg4Flex480p() { specific(googMpeg4(), 720, 480, true /* flex */); } testGoogMpeg4Surf480p()1692 public void testGoogMpeg4Surf480p() { specific(googMpeg4(), 720, 480, false /* flex */); } testGoogVP8Flex480p()1693 public void testGoogVP8Flex480p() { specific(googVP8(), 720, 480, true /* flex */); } testGoogVP8Surf480p()1694 public void testGoogVP8Surf480p() { specific(googVP8(), 720, 480, false /* flex */); } testGoogVP9Flex480p()1695 public void testGoogVP9Flex480p() { specific(googVP9(), 720, 480, true /* flex */); } testGoogVP9Surf480p()1696 public void testGoogVP9Surf480p() { specific(googVP9(), 720, 480, false /* flex */); } 1697 1698 @NonMediaMainlineTest testOtherH265Flex480p()1699 public void testOtherH265Flex480p() { specific(otherH265(), 720, 480, true /* flex */); } 1700 @NonMediaMainlineTest testOtherH265Surf480p()1701 public void testOtherH265Surf480p() { specific(otherH265(), 720, 480, false /* flex */); } 1702 @NonMediaMainlineTest testOtherH264Flex480p()1703 public void testOtherH264Flex480p() { specific(otherH264(), 720, 480, true /* flex */); } 1704 @NonMediaMainlineTest testOtherH264Surf480p()1705 public void testOtherH264Surf480p() { specific(otherH264(), 720, 480, false /* flex */); } 1706 @NonMediaMainlineTest testOtherH263Flex480p()1707 public void testOtherH263Flex480p() { specific(otherH263(), 720, 480, true /* flex */); } 1708 @NonMediaMainlineTest testOtherH263Surf480p()1709 public void testOtherH263Surf480p() { specific(otherH263(), 720, 480, false /* flex */); } 1710 @NonMediaMainlineTest testOtherMpeg4Flex480p()1711 public void testOtherMpeg4Flex480p() { specific(otherMpeg4(), 720, 480, true /* flex */); } 1712 @NonMediaMainlineTest testOtherMpeg4Surf480p()1713 public void testOtherMpeg4Surf480p() { specific(otherMpeg4(), 720, 480, false /* flex */); } 1714 @NonMediaMainlineTest testOtherVP8Flex480p()1715 public void testOtherVP8Flex480p() { specific(otherVP8(), 720, 480, true /* flex */); } 1716 @NonMediaMainlineTest testOtherVP8Surf480p()1717 public void testOtherVP8Surf480p() { specific(otherVP8(), 720, 480, false /* flex */); } 1718 @NonMediaMainlineTest testOtherVP9Flex480p()1719 public void testOtherVP9Flex480p() { specific(otherVP9(), 720, 480, true /* flex */); } 1720 @NonMediaMainlineTest testOtherVP9Surf480p()1721 public void testOtherVP9Surf480p() { specific(otherVP9(), 720, 480, false /* flex */); } 1722 1723 // even though H.263 and MPEG-4 are not defined for 720p or 1080p 1724 // test for it, in case device claims support for it. 1725 testGoogH265Flex720p()1726 public void testGoogH265Flex720p() { specific(googH265(), 1280, 720, true /* flex */); } testGoogH265Surf720p()1727 public void testGoogH265Surf720p() { specific(googH265(), 1280, 720, false /* flex */); } testGoogH264Flex720p()1728 public void testGoogH264Flex720p() { specific(googH264(), 1280, 720, true /* flex */); } testGoogH264Surf720p()1729 public void testGoogH264Surf720p() { specific(googH264(), 1280, 720, false /* flex */); } testGoogH263Flex720p()1730 public void testGoogH263Flex720p() { specific(googH263(), 1280, 720, true /* flex */); } testGoogH263Surf720p()1731 public void testGoogH263Surf720p() { specific(googH263(), 1280, 720, false /* flex */); } testGoogMpeg4Flex720p()1732 public void testGoogMpeg4Flex720p() { specific(googMpeg4(), 1280, 720, true /* flex */); } testGoogMpeg4Surf720p()1733 public void testGoogMpeg4Surf720p() { specific(googMpeg4(), 1280, 720, false /* flex */); } testGoogVP8Flex720p()1734 public void testGoogVP8Flex720p() { specific(googVP8(), 1280, 720, true /* flex */); } testGoogVP8Surf720p()1735 public void testGoogVP8Surf720p() { specific(googVP8(), 1280, 720, false /* flex */); } testGoogVP9Flex720p()1736 public void testGoogVP9Flex720p() { specific(googVP9(), 1280, 720, true /* flex */); } testGoogVP9Surf720p()1737 public void testGoogVP9Surf720p() { specific(googVP9(), 1280, 720, false /* flex */); } 1738 1739 @NonMediaMainlineTest testOtherH265Flex720p()1740 public void testOtherH265Flex720p() { specific(otherH265(), 1280, 720, true /* flex */); } 1741 @NonMediaMainlineTest testOtherH265Surf720p()1742 public void testOtherH265Surf720p() { specific(otherH265(), 1280, 720, false /* flex */); } 1743 @NonMediaMainlineTest testOtherH264Flex720p()1744 public void testOtherH264Flex720p() { specific(otherH264(), 1280, 720, true /* flex */); } 1745 @NonMediaMainlineTest testOtherH264Surf720p()1746 public void testOtherH264Surf720p() { specific(otherH264(), 1280, 720, false /* flex */); } 1747 @NonMediaMainlineTest testOtherH263Flex720p()1748 public void testOtherH263Flex720p() { specific(otherH263(), 1280, 720, true /* flex */); } 1749 @NonMediaMainlineTest testOtherH263Surf720p()1750 public void testOtherH263Surf720p() { specific(otherH263(), 1280, 720, false /* flex */); } 1751 @NonMediaMainlineTest testOtherMpeg4Flex720p()1752 public void testOtherMpeg4Flex720p() { specific(otherMpeg4(), 1280, 720, true /* flex */); } 1753 @NonMediaMainlineTest testOtherMpeg4Surf720p()1754 public void testOtherMpeg4Surf720p() { specific(otherMpeg4(), 1280, 720, false /* flex */); } 1755 @NonMediaMainlineTest testOtherVP8Flex720p()1756 public void testOtherVP8Flex720p() { specific(otherVP8(), 1280, 720, true /* flex */); } 1757 @NonMediaMainlineTest testOtherVP8Surf720p()1758 public void testOtherVP8Surf720p() { specific(otherVP8(), 1280, 720, false /* flex */); } 1759 @NonMediaMainlineTest testOtherVP9Flex720p()1760 public void testOtherVP9Flex720p() { specific(otherVP9(), 1280, 720, true /* flex */); } 1761 @NonMediaMainlineTest testOtherVP9Surf720p()1762 public void testOtherVP9Surf720p() { specific(otherVP9(), 1280, 720, false /* flex */); } 1763 testGoogH265Flex1080p()1764 public void testGoogH265Flex1080p() { specific(googH265(), 1920, 1080, true /* flex */); } testGoogH265Surf1080p()1765 public void testGoogH265Surf1080p() { specific(googH265(), 1920, 1080, false /* flex */); } testGoogH264Flex1080p()1766 public void testGoogH264Flex1080p() { specific(googH264(), 1920, 1080, true /* flex */); } testGoogH264Surf1080p()1767 public void testGoogH264Surf1080p() { specific(googH264(), 1920, 1080, false /* flex */); } testGoogH263Flex1080p()1768 public void testGoogH263Flex1080p() { specific(googH263(), 1920, 1080, true /* flex */); } testGoogH263Surf1080p()1769 public void testGoogH263Surf1080p() { specific(googH263(), 1920, 1080, false /* flex */); } testGoogMpeg4Flex1080p()1770 public void testGoogMpeg4Flex1080p() { specific(googMpeg4(), 1920, 1080, true /* flex */); } testGoogMpeg4Surf1080p()1771 public void testGoogMpeg4Surf1080p() { specific(googMpeg4(), 1920, 1080, false /* flex */); } testGoogVP8Flex1080p()1772 public void testGoogVP8Flex1080p() { specific(googVP8(), 1920, 1080, true /* flex */); } testGoogVP8Surf1080p()1773 public void testGoogVP8Surf1080p() { specific(googVP8(), 1920, 1080, false /* flex */); } testGoogVP9Flex1080p()1774 public void testGoogVP9Flex1080p() { specific(googVP9(), 1920, 1080, true /* flex */); } testGoogVP9Surf1080p()1775 public void testGoogVP9Surf1080p() { specific(googVP9(), 1920, 1080, false /* flex */); } 1776 1777 @NonMediaMainlineTest testOtherH265Flex1080p()1778 public void testOtherH265Flex1080p() { specific(otherH265(), 1920, 1080, true /* flex */); } 1779 @NonMediaMainlineTest testOtherH265Surf1080p()1780 public void testOtherH265Surf1080p() { specific(otherH265(), 1920, 1080, false /* flex */); } 1781 @NonMediaMainlineTest testOtherH264Flex1080p()1782 public void testOtherH264Flex1080p() { specific(otherH264(), 1920, 1080, true /* flex */); } 1783 @NonMediaMainlineTest testOtherH264Surf1080p()1784 public void testOtherH264Surf1080p() { specific(otherH264(), 1920, 1080, false /* flex */); } 1785 @NonMediaMainlineTest testOtherH263Flex1080p()1786 public void testOtherH263Flex1080p() { specific(otherH263(), 1920, 1080, true /* flex */); } 1787 @NonMediaMainlineTest testOtherH263Surf1080p()1788 public void testOtherH263Surf1080p() { specific(otherH263(), 1920, 1080, false /* flex */); } 1789 @NonMediaMainlineTest testOtherMpeg4Flex1080p()1790 public void testOtherMpeg4Flex1080p() { specific(otherMpeg4(), 1920, 1080, true /* flex */); } 1791 @NonMediaMainlineTest testOtherMpeg4Surf1080p()1792 public void testOtherMpeg4Surf1080p() { specific(otherMpeg4(), 1920, 1080, false /* flex */); } 1793 @NonMediaMainlineTest testOtherVP8Flex1080p()1794 public void testOtherVP8Flex1080p() { specific(otherVP8(), 1920, 1080, true /* flex */); } 1795 @NonMediaMainlineTest testOtherVP8Surf1080p()1796 public void testOtherVP8Surf1080p() { specific(otherVP8(), 1920, 1080, false /* flex */); } 1797 @NonMediaMainlineTest testOtherVP9Flex1080p()1798 public void testOtherVP9Flex1080p() { specific(otherVP9(), 1920, 1080, true /* flex */); } 1799 @NonMediaMainlineTest testOtherVP9Surf1080p()1800 public void testOtherVP9Surf1080p() { specific(otherVP9(), 1920, 1080, false /* flex */); } 1801 testGoogH265Flex360pWithIntraRefresh()1802 public void testGoogH265Flex360pWithIntraRefresh() { 1803 intraRefresh(googH265(), 480, 360); 1804 } 1805 testGoogH264Flex360pWithIntraRefresh()1806 public void testGoogH264Flex360pWithIntraRefresh() { 1807 intraRefresh(googH264(), 480, 360); 1808 } 1809 testGoogH263Flex360pWithIntraRefresh()1810 public void testGoogH263Flex360pWithIntraRefresh() { 1811 intraRefresh(googH263(), 480, 360); 1812 } 1813 testGoogMpeg4Flex360pWithIntraRefresh()1814 public void testGoogMpeg4Flex360pWithIntraRefresh() { 1815 intraRefresh(googMpeg4(), 480, 360); 1816 } 1817 testGoogVP8Flex360pWithIntraRefresh()1818 public void testGoogVP8Flex360pWithIntraRefresh() { 1819 intraRefresh(googVP8(), 480, 360); 1820 } 1821 1822 @NonMediaMainlineTest testOtherH265Flex360pWithIntraRefresh()1823 public void testOtherH265Flex360pWithIntraRefresh() { 1824 intraRefresh(otherH265(), 480, 360); 1825 } 1826 1827 @NonMediaMainlineTest testOtherH264Flex360pWithIntraRefresh()1828 public void testOtherH264Flex360pWithIntraRefresh() { 1829 intraRefresh(otherH264(), 480, 360); 1830 } 1831 1832 @NonMediaMainlineTest testOtherH263FlexQCIFWithIntraRefresh()1833 public void testOtherH263FlexQCIFWithIntraRefresh() { 1834 intraRefresh(otherH263(), 176, 120); 1835 } 1836 1837 @NonMediaMainlineTest testOtherMpeg4Flex360pWithIntraRefresh()1838 public void testOtherMpeg4Flex360pWithIntraRefresh() { 1839 intraRefresh(otherMpeg4(), 480, 360); 1840 } 1841 1842 @NonMediaMainlineTest testOtherVP8Flex360pWithIntraRefresh()1843 public void testOtherVP8Flex360pWithIntraRefresh() { 1844 intraRefresh(otherVP8(), 480, 360); 1845 } 1846 1847 // Tests encoder profiles required by CDD. 1848 // H264 1849 @NonMediaMainlineTest testH264LowQualitySDSupport()1850 public void testH264LowQualitySDSupport() { 1851 support(h264(), 320, 240, 20, 384 * 1000); 1852 } 1853 1854 @NonMediaMainlineTest testH264HighQualitySDSupport()1855 public void testH264HighQualitySDSupport() { 1856 support(h264(), 720, 480, 30, 2 * 1000000); 1857 } 1858 1859 @NonMediaMainlineTest testH264FlexQVGA20fps384kbps()1860 public void testH264FlexQVGA20fps384kbps() { 1861 detailed(h264(), 320, 240, 20, 384 * 1000, true /* flex */); 1862 } 1863 1864 @NonMediaMainlineTest testH264SurfQVGA20fps384kbps()1865 public void testH264SurfQVGA20fps384kbps() { 1866 detailed(h264(), 320, 240, 20, 384 * 1000, false /* flex */); 1867 } 1868 1869 @NonMediaMainlineTest testH264Flex480p30fps2Mbps()1870 public void testH264Flex480p30fps2Mbps() { 1871 detailed(h264(), 720, 480, 30, 2 * 1000000, true /* flex */); 1872 } 1873 1874 @NonMediaMainlineTest testH264Surf480p30fps2Mbps()1875 public void testH264Surf480p30fps2Mbps() { 1876 detailed(h264(), 720, 480, 30, 2 * 1000000, false /* flex */); 1877 } 1878 1879 @NonMediaMainlineTest testH264Flex720p30fps4Mbps()1880 public void testH264Flex720p30fps4Mbps() { 1881 detailed(h264(), 1280, 720, 30, 4 * 1000000, true /* flex */); 1882 } 1883 1884 @NonMediaMainlineTest testH264Surf720p30fps4Mbps()1885 public void testH264Surf720p30fps4Mbps() { 1886 detailed(h264(), 1280, 720, 30, 4 * 1000000, false /* flex */); 1887 } 1888 1889 @NonMediaMainlineTest testH264Flex1080p30fps10Mbps()1890 public void testH264Flex1080p30fps10Mbps() { 1891 detailed(h264(), 1920, 1080, 30, 10 * 1000000, true /* flex */); 1892 } 1893 1894 @NonMediaMainlineTest testH264Surf1080p30fps10Mbps()1895 public void testH264Surf1080p30fps10Mbps() { 1896 detailed(h264(), 1920, 1080, 30, 10 * 1000000, false /* flex */); 1897 } 1898 1899 // VP8 1900 @NonMediaMainlineTest testVP8LowQualitySDSupport()1901 public void testVP8LowQualitySDSupport() { 1902 support(vp8(), 320, 180, 30, 800 * 1000); 1903 } 1904 1905 @NonMediaMainlineTest testVP8HighQualitySDSupport()1906 public void testVP8HighQualitySDSupport() { 1907 support(vp8(), 640, 360, 30, 2 * 1000000); 1908 } 1909 1910 @NonMediaMainlineTest testVP8Flex180p30fps800kbps()1911 public void testVP8Flex180p30fps800kbps() { 1912 detailed(vp8(), 320, 180, 30, 800 * 1000, true /* flex */); 1913 } 1914 1915 @NonMediaMainlineTest testVP8Surf180p30fps800kbps()1916 public void testVP8Surf180p30fps800kbps() { 1917 detailed(vp8(), 320, 180, 30, 800 * 1000, false /* flex */); 1918 } 1919 1920 @NonMediaMainlineTest testVP8Flex360p30fps2Mbps()1921 public void testVP8Flex360p30fps2Mbps() { 1922 detailed(vp8(), 640, 360, 30, 2 * 1000000, true /* flex */); 1923 } 1924 1925 @NonMediaMainlineTest testVP8Surf360p30fps2Mbps()1926 public void testVP8Surf360p30fps2Mbps() { 1927 detailed(vp8(), 640, 360, 30, 2 * 1000000, false /* flex */); 1928 } 1929 1930 @NonMediaMainlineTest testVP8Flex720p30fps4Mbps()1931 public void testVP8Flex720p30fps4Mbps() { 1932 detailed(vp8(), 1280, 720, 30, 4 * 1000000, true /* flex */); 1933 } 1934 1935 @NonMediaMainlineTest testVP8Surf720p30fps4Mbps()1936 public void testVP8Surf720p30fps4Mbps() { 1937 detailed(vp8(), 1280, 720, 30, 4 * 1000000, false /* flex */); 1938 } 1939 1940 @NonMediaMainlineTest testVP8Flex1080p30fps10Mbps()1941 public void testVP8Flex1080p30fps10Mbps() { 1942 detailed(vp8(), 1920, 1080, 30, 10 * 1000000, true /* flex */); 1943 } 1944 1945 @NonMediaMainlineTest testVP8Surf1080p30fps10Mbps()1946 public void testVP8Surf1080p30fps10Mbps() { 1947 detailed(vp8(), 1920, 1080, 30, 10 * 1000000, false /* flex */); 1948 } 1949 minmin(Encoder[] encoders, boolean flexYUV)1950 private void minmin(Encoder[] encoders, boolean flexYUV) { 1951 extreme(encoders, 0 /* x */, 0 /* y */, flexYUV, false /* near */); 1952 } 1953 minmax(Encoder[] encoders, boolean flexYUV)1954 private void minmax(Encoder[] encoders, boolean flexYUV) { 1955 extreme(encoders, 0 /* x */, 1 /* y */, flexYUV, false /* near */); 1956 } 1957 maxmin(Encoder[] encoders, boolean flexYUV)1958 private void maxmin(Encoder[] encoders, boolean flexYUV) { 1959 extreme(encoders, 1 /* x */, 0 /* y */, flexYUV, false /* near */); 1960 } 1961 maxmax(Encoder[] encoders, boolean flexYUV)1962 private void maxmax(Encoder[] encoders, boolean flexYUV) { 1963 extreme(encoders, 1 /* x */, 1 /* y */, flexYUV, false /* near */); 1964 } 1965 nearminmin(Encoder[] encoders, boolean flexYUV)1966 private void nearminmin(Encoder[] encoders, boolean flexYUV) { 1967 extreme(encoders, 0 /* x */, 0 /* y */, flexYUV, true /* near */); 1968 } 1969 nearminmax(Encoder[] encoders, boolean flexYUV)1970 private void nearminmax(Encoder[] encoders, boolean flexYUV) { 1971 extreme(encoders, 0 /* x */, 1 /* y */, flexYUV, true /* near */); 1972 } 1973 nearmaxmin(Encoder[] encoders, boolean flexYUV)1974 private void nearmaxmin(Encoder[] encoders, boolean flexYUV) { 1975 extreme(encoders, 1 /* x */, 0 /* y */, flexYUV, true /* near */); 1976 } 1977 nearmaxmax(Encoder[] encoders, boolean flexYUV)1978 private void nearmaxmax(Encoder[] encoders, boolean flexYUV) { 1979 extreme(encoders, 1 /* x */, 1 /* y */, flexYUV, true /* near */); 1980 } 1981 extreme(Encoder[] encoders, int x, int y, boolean flexYUV, boolean near)1982 private void extreme(Encoder[] encoders, int x, int y, boolean flexYUV, boolean near) { 1983 boolean skipped = true; 1984 if (encoders.length == 0) { 1985 MediaUtils.skipTest("no such encoder present"); 1986 return; 1987 } 1988 for (Encoder encoder: encoders) { 1989 if (encoder.testExtreme(x, y, flexYUV, near)) { 1990 skipped = false; 1991 } 1992 } 1993 if (skipped) { 1994 MediaUtils.skipTest("duplicate resolution extreme"); 1995 } 1996 } 1997 arbitrary(Encoder[] encoders, boolean flexYUV, boolean widths)1998 private void arbitrary(Encoder[] encoders, boolean flexYUV, boolean widths) { 1999 boolean skipped = true; 2000 if (encoders.length == 0) { 2001 MediaUtils.skipTest("no such encoder present"); 2002 return; 2003 } 2004 for (Encoder encoder: encoders) { 2005 if (encoder.testArbitrary(flexYUV, widths)) { 2006 skipped = false; 2007 } 2008 } 2009 if (skipped) { 2010 MediaUtils.skipTest("duplicate resolution"); 2011 } 2012 } 2013 arbitraryw(Encoder[] encoders, boolean flexYUV)2014 private void arbitraryw(Encoder[] encoders, boolean flexYUV) { 2015 arbitrary(encoders, flexYUV, true /* widths */); 2016 } 2017 arbitraryh(Encoder[] encoders, boolean flexYUV)2018 private void arbitraryh(Encoder[] encoders, boolean flexYUV) { 2019 arbitrary(encoders, flexYUV, false /* widths */); 2020 } 2021 2022 /* test specific size */ specific(Encoder[] encoders, int width, int height, boolean flexYUV)2023 private void specific(Encoder[] encoders, int width, int height, boolean flexYUV) { 2024 boolean skipped = true; 2025 if (encoders.length == 0) { 2026 MediaUtils.skipTest("no such encoder present"); 2027 return; 2028 } 2029 for (Encoder encoder : encoders) { 2030 if (encoder.testSpecific(width, height, flexYUV)) { 2031 skipped = false; 2032 } 2033 } 2034 if (skipped) { 2035 MediaUtils.skipTest("duplicate or unsupported resolution"); 2036 } 2037 } 2038 2039 /* test intra refresh with flexYUV */ intraRefresh(Encoder[] encoders, int width, int height)2040 private void intraRefresh(Encoder[] encoders, int width, int height) { 2041 boolean skipped = true; 2042 if (encoders.length == 0) { 2043 MediaUtils.skipTest("no such encoder present"); 2044 return; 2045 } 2046 for (Encoder encoder : encoders) { 2047 if (encoder.testIntraRefresh(width, height)) { 2048 skipped = false; 2049 } 2050 } 2051 if (skipped) { 2052 MediaUtils.skipTest("intra-refresh unsupported"); 2053 } 2054 } 2055 2056 /* test size, frame rate and bit rate */ detailed( Encoder[] encoders, int width, int height, int frameRate, int bitRate, boolean flexYUV)2057 private void detailed( 2058 Encoder[] encoders, int width, int height, int frameRate, int bitRate, 2059 boolean flexYUV) { 2060 if (encoders.length == 0) { 2061 MediaUtils.skipTest("no such encoder present"); 2062 return; 2063 } 2064 boolean skipped = true; 2065 for (Encoder encoder : encoders) { 2066 if (encoder.testSupport(width, height, frameRate, bitRate)) { 2067 skipped = false; 2068 encoder.testDetailed(width, height, frameRate, bitRate, flexYUV); 2069 } 2070 } 2071 if (skipped) { 2072 MediaUtils.skipTest("unsupported resolution and rate"); 2073 } 2074 } 2075 2076 /* test size and rate are supported */ support(Encoder[] encoders, int width, int height, int frameRate, int bitRate)2077 private void support(Encoder[] encoders, int width, int height, int frameRate, int bitRate) { 2078 boolean supported = false; 2079 if (encoders.length == 0) { 2080 MediaUtils.skipTest("no such encoder present"); 2081 return; 2082 } 2083 for (Encoder encoder : encoders) { 2084 if (encoder.testSupport(width, height, frameRate, bitRate)) { 2085 supported = true; 2086 break; 2087 } 2088 } 2089 if (!supported) { 2090 fail("unsupported format " + width + "x" + height + " " + 2091 frameRate + "fps " + bitRate + "bps"); 2092 } 2093 } 2094 } 2095