/*
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.media.cts;

import com.android.cts.media.R;

import android.media.cts.CodecUtils;

import android.cts.util.MediaUtils;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.media.Image;
import android.media.MediaCodec;
import android.media.MediaCodec.BufferInfo;
import android.media.MediaCodecInfo;
import android.media.MediaCodecInfo.CodecCapabilities;
import android.media.MediaCodecInfo.VideoCapabilities;
import android.media.MediaCodecList;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.net.Uri;
import android.util.Log;
import android.util.Pair;
import android.util.Range;
import android.util.Size;
import android.view.Surface;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;

public class VideoEncoderTest extends MediaPlayerTestBase {
    private static final int MAX_SAMPLE_SIZE = 256 * 1024;
    private static final String TAG = "VideoEncoderTest";
    private static final long FRAME_TIMEOUT_MS = 1000;

    private static final String SOURCE_URL =
        "android.resource://com.android.cts.media/raw/video_480x360_mp4_h264_871kbps_30fps";

    private final boolean DEBUG = false;

    class VideoStorage {
        private LinkedList<Pair<ByteBuffer, BufferInfo>> mStream;
        private MediaFormat mFormat;
        private int mInputBufferSize;

        public VideoStorage() {
            mStream = new LinkedList<Pair<ByteBuffer, BufferInfo>>();
        }

        public void setFormat(MediaFormat format) {
            mFormat = format;
        }

        public void addBuffer(ByteBuffer buffer, BufferInfo info) {
            ByteBuffer savedBuffer = ByteBuffer.allocate(info.size);
            savedBuffer.put(buffer);
            if (info.size > mInputBufferSize) {
                mInputBufferSize = info.size;
            }
            BufferInfo savedInfo = new BufferInfo();
            savedInfo.set(0, savedBuffer.position(), info.presentationTimeUs, info.flags);
            mStream.addLast(Pair.create(savedBuffer, savedInfo));
        }

        private void play(MediaCodec decoder, Surface surface) {
            decoder.reset();
            final Object condition = new Object();
            final Iterator<Pair<ByteBuffer, BufferInfo>> it = mStream.iterator();
            decoder.setCallback(new MediaCodec.Callback() {
                public void onOutputBufferAvailable(MediaCodec codec, int ix, BufferInfo info) {
                    codec.releaseOutputBuffer(ix, info.size > 0);
                    if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                        synchronized (condition) {
                            condition.notifyAll();
                        }
                    }
                }
                public void onInputBufferAvailable(MediaCodec codec, int ix) {
                    if (it.hasNext()) {
                        Pair<ByteBuffer, BufferInfo> el = it.next();
                        el.first.clear();
                        try {
                            codec.getInputBuffer(ix).put(el.first);
                        } catch (java.nio.BufferOverflowException e) {
                            Log.e(TAG, "cannot fit " + el.first.limit()
                                    + "-byte encoded buffer into "
                                    + codec.getInputBuffer(ix).remaining()
                                    + "-byte input buffer of " + codec.getName()
                                    + " configured for " + codec.getInputFormat());
                            throw e;
                        }
                        BufferInfo info = el.second;
                        codec.queueInputBuffer(
                                ix, 0, info.size, info.presentationTimeUs, info.flags);
                    }
                }
                public void onError(MediaCodec codec, MediaCodec.CodecException e) {
                    Log.i(TAG, "got codec exception", e);
                    fail("received codec error during decode" + e);
                }
                public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) {
                    Log.i(TAG, "got output format " + format);
                }
            });
            mFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, mInputBufferSize);
            decoder.configure(mFormat, surface, null /* crypto */, 0 /* flags */);
            decoder.start();
            synchronized (condition) {
                try {
                    condition.wait();
                } catch (InterruptedException e) {
                    fail("playback interrupted");
                }
            }
            decoder.stop();
        }

        public void playAll(Surface surface) {
            if (mFormat == null) {
                Log.i(TAG, "no stream to play");
                return;
            }
            String mime = mFormat.getString(MediaFormat.KEY_MIME);
            MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
            for (MediaCodecInfo info : mcl.getCodecInfos()) {
                if (info.isEncoder()) {
                    continue;
                }
                MediaCodec codec = null;
                try {
                    CodecCapabilities caps = info.getCapabilitiesForType(mime);
                    if (!caps.isFormatSupported(mFormat)) {
                        continue;
                    }
                    codec = MediaCodec.createByCodecName(info.getName());
                } catch (IllegalArgumentException | IOException e) {
                    continue;
                }
                play(codec, surface);
                codec.release();
            }
        }
    }

    abstract class VideoProcessorBase extends MediaCodec.Callback {
        private static final String TAG = "VideoProcessorBase";

        private MediaExtractor mExtractor;
        private ByteBuffer mBuffer = ByteBuffer.allocate(MAX_SAMPLE_SIZE);
        private int mTrackIndex = -1;
        private boolean mSignaledDecoderEOS;

        protected boolean mCompleted;
        protected final Object mCondition = new Object();

        protected MediaFormat mDecFormat;
        protected MediaCodec mDecoder, mEncoder;

        private VideoStorage mEncodedStream;
        protected int mFrameRate = 0;
        protected int mBitRate = 0;

        protected void open(String path) throws IOException {
            mExtractor = new MediaExtractor();
            if (path.startsWith("android.resource://")) {
                mExtractor.setDataSource(mContext, Uri.parse(path), null);
            } else {
                mExtractor.setDataSource(path);
            }

            for (int i = 0; i < mExtractor.getTrackCount(); i++) {
                MediaFormat fmt = mExtractor.getTrackFormat(i);
                String mime = fmt.getString(MediaFormat.KEY_MIME).toLowerCase();
                if (mime.startsWith("video/")) {
                    mTrackIndex = i;
                    mDecFormat = fmt;
                    mExtractor.selectTrack(i);
                    break;
                }
            }
            mEncodedStream = new VideoStorage();
            assertTrue("file " + path + " has no video", mTrackIndex >= 0);
        }

        // returns true if encoder supports the size
        protected boolean initCodecsAndConfigureEncoder(
                String videoEncName, String outMime, int width, int height, int colorFormat)
                        throws IOException {
            mDecFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);

            MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
            String videoDecName = mcl.findDecoderForFormat(mDecFormat);
            Log.i(TAG, "decoder for " + mDecFormat + " is " + videoDecName);
            mDecoder = MediaCodec.createByCodecName(videoDecName);
            mEncoder = MediaCodec.createByCodecName(videoEncName);

            mDecoder.setCallback(this);
            mEncoder.setCallback(this);

            VideoCapabilities encCaps =
                mEncoder.getCodecInfo().getCapabilitiesForType(outMime).getVideoCapabilities();
            if (!encCaps.isSizeSupported(width, height)) {
                Log.i(TAG, videoEncName + " does not support size: " + width + "x" + height);
                return false;
            }

            MediaFormat outFmt = MediaFormat.createVideoFormat(outMime, width, height);

            {
                int maxWidth = encCaps.getSupportedWidths().getUpper();
                int maxHeight = encCaps.getSupportedHeightsFor(maxWidth).getUpper();
                int frameRate = mFrameRate;
                if (frameRate <= 0) {
                    int maxRate =
                        encCaps.getSupportedFrameRatesFor(maxWidth, maxHeight)
                        .getUpper().intValue();
                    frameRate = Math.min(30, maxRate);
                }
                outFmt.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);

                int bitRate = mBitRate;
                if (bitRate <= 0) {
                    bitRate = encCaps.getBitrateRange().clamp(
                        (int)(encCaps.getBitrateRange().getUpper() /
                                Math.sqrt((double)maxWidth * maxHeight / width / height)));
                }
                outFmt.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);

                Log.d(TAG, "frame rate = " + frameRate + ", bit rate = " + bitRate);
            }
            outFmt.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
            outFmt.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
            mEncoder.configure(outFmt, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
            Log.i(TAG, "encoder input format " + mEncoder.getInputFormat() + " from " + outFmt);
            return true;
        }

        protected void close() {
            if (mDecoder != null) {
                mDecoder.release();
                mDecoder = null;
            }
            if (mEncoder != null) {
                mEncoder.release();
                mEncoder = null;
            }
            if (mExtractor != null) {
                mExtractor.release();
                mExtractor = null;
            }
        }

        // returns true if filled buffer
        protected boolean fillDecoderInputBuffer(int ix) {
            if (DEBUG) Log.v(TAG, "decoder received input #" + ix);
            while (!mSignaledDecoderEOS) {
                int track = mExtractor.getSampleTrackIndex();
                if (track >= 0 && track != mTrackIndex) {
                    mExtractor.advance();
                    continue;
                }
                int size = mExtractor.readSampleData(mBuffer, 0);
                if (size < 0) {
                    // queue decoder input EOS
                    if (DEBUG) Log.v(TAG, "queuing decoder EOS");
                    mDecoder.queueInputBuffer(
                            ix, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                    mSignaledDecoderEOS = true;
                } else {
                    mBuffer.limit(size);
                    mBuffer.position(0);
                    BufferInfo info = new BufferInfo();
                    info.set(
                            0, mBuffer.limit(), mExtractor.getSampleTime(),
                            mExtractor.getSampleFlags());
                    mDecoder.getInputBuffer(ix).put(mBuffer);
                    if (DEBUG) Log.v(TAG, "queing input #" + ix + " for decoder with timestamp "
                            + info.presentationTimeUs);
                    mDecoder.queueInputBuffer(
                            ix, 0, mBuffer.limit(), info.presentationTimeUs, 0);
                }
                mExtractor.advance();
                return true;
            }
            return false;
        }

        protected void emptyEncoderOutputBuffer(int ix, BufferInfo info) {
            if (DEBUG) Log.v(TAG, "encoder received output #" + ix
                     + " (sz=" + info.size + ", f=" + info.flags
                     + ", ts=" + info.presentationTimeUs + ")");
            mEncodedStream.addBuffer(mEncoder.getOutputBuffer(ix), info);
            if (!mCompleted) {
                mEncoder.releaseOutputBuffer(ix, false);
                if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                    Log.d(TAG, "encoder received output EOS");
                    synchronized(mCondition) {
                        mCompleted = true;
                        mCondition.notifyAll(); // condition is always satisfied
                    }
                }
            }
        }

        protected void saveEncoderFormat(MediaFormat format) {
            mEncodedStream.setFormat(format);
        }

        public void playBack(Surface surface) {
            mEncodedStream.playAll(surface);
        }

        public void setFrameAndBitRates(int frameRate, int bitRate) {
            mFrameRate = frameRate;
            mBitRate = bitRate;
        }

        public abstract boolean processLoop(
                String path, String outMime, String videoEncName,
                int width, int height, boolean optional);
    };

    class VideoProcessor extends VideoProcessorBase {
        private static final String TAG = "VideoProcessor";
        private boolean mWorkInProgress;
        private boolean mGotDecoderEOS;
        private boolean mSignaledEncoderEOS;

        private LinkedList<Pair<Integer, BufferInfo>> mBuffersToRender =
            new LinkedList<Pair<Integer, BufferInfo>>();
        private LinkedList<Integer> mEncInputBuffers = new LinkedList<Integer>();

        private int mEncInputBufferSize = -1;

        @Override
        public boolean processLoop(
                 String path, String outMime, String videoEncName,
                 int width, int height, boolean optional) {
            boolean skipped = true;
            try {
                open(path);
                if (!initCodecsAndConfigureEncoder(
                        videoEncName, outMime, width, height,
                        CodecCapabilities.COLOR_FormatYUV420Flexible)) {
                    assertTrue("could not configure encoder for supported size", optional);
                    return !skipped;
                }
                skipped = false;

                mDecoder.configure(mDecFormat, null /* surface */, null /* crypto */, 0);

                mDecoder.start();
                mEncoder.start();

                // main loop - process GL ops as only main thread has GL context
                while (!mCompleted) {
                    Pair<Integer, BufferInfo> decBuffer = null;
                    int encBuffer = -1;
                    synchronized (mCondition) {
                        try {
                            // wait for an encoder input buffer and a decoder output buffer
                            // Use a timeout to avoid stalling the test if it doesn't arrive.
                            if (!haveBuffers() && !mCompleted) {
                                mCondition.wait(FRAME_TIMEOUT_MS);
                            }
                        } catch (InterruptedException ie) {
                            fail("wait interrupted");  // shouldn't happen
                        }
                        if (mCompleted) {
                            break;
                        }
                        if (!haveBuffers()) {
                            fail("timed out after " + mBuffersToRender.size()
                                    + " decoder output and " + mEncInputBuffers.size()
                                    + " encoder input buffers");
                        }

                        if (DEBUG) Log.v(TAG, "got image");
                        decBuffer = mBuffersToRender.removeFirst();
                        encBuffer = mEncInputBuffers.removeFirst();
                        if (isEOSOnlyBuffer(decBuffer)) {
                            queueEncoderEOS(decBuffer, encBuffer);
                            continue;
                        }
                        mWorkInProgress = true;
                    }

                    if (mWorkInProgress) {
                        renderDecodedBuffer(decBuffer, encBuffer);
                        synchronized(mCondition) {
                            mWorkInProgress = false;
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                fail("received exception " + e);
            } finally {
                close();
            }
            return !skipped;
        }

        @Override
        public void onInputBufferAvailable(MediaCodec mediaCodec, int ix) {
            if (mediaCodec == mDecoder) {
                // fill input buffer from extractor
                fillDecoderInputBuffer(ix);
            } else if (mediaCodec == mEncoder) {
                synchronized(mCondition) {
                    mEncInputBuffers.addLast(ix);
                    tryToPropagateEOS();
                    if (haveBuffers()) {
                        mCondition.notifyAll();
                    }
                }
            } else {
                fail("received input buffer on " + mediaCodec.getName());
            }
        }

        @Override
        public void onOutputBufferAvailable(
                MediaCodec mediaCodec, int ix, BufferInfo info) {
            if (mediaCodec == mDecoder) {
                if (DEBUG) Log.v(TAG, "decoder received output #" + ix
                         + " (sz=" + info.size + ", f=" + info.flags
                         + ", ts=" + info.presentationTimeUs + ")");
                // render output buffer from decoder
                if (!mGotDecoderEOS) {
                    boolean eos = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
                    // can release empty buffers now
                    if (info.size == 0) {
                        mDecoder.releaseOutputBuffer(ix, false /* render */);
                        ix = -1; // dummy index used by render to not render
                    }
                    synchronized(mCondition) {
                        if (ix < 0 && eos && mBuffersToRender.size() > 0) {
                            // move lone EOS flag to last buffer to be rendered
                            mBuffersToRender.peekLast().second.flags |=
                                MediaCodec.BUFFER_FLAG_END_OF_STREAM;
                        } else if (ix >= 0 || eos) {
                            mBuffersToRender.addLast(Pair.create(ix, info));
                        }
                        if (eos) {
                            tryToPropagateEOS();
                            mGotDecoderEOS = true;
                        }
                        if (haveBuffers()) {
                            mCondition.notifyAll();
                        }
                    }
                }
            } else if (mediaCodec == mEncoder) {
                emptyEncoderOutputBuffer(ix, info);
            } else {
                fail("received output buffer on " + mediaCodec.getName());
            }
        }

        private void renderDecodedBuffer(Pair<Integer, BufferInfo> decBuffer, int encBuffer) {
            // process heavyweight actions under instance lock
            Image encImage = mEncoder.getInputImage(encBuffer);
            Image decImage = mDecoder.getOutputImage(decBuffer.first);
            assertNotNull("could not get encoder image for " + mEncoder.getInputFormat(), encImage);
            assertNotNull("could not get decoder image for " + mDecoder.getInputFormat(), decImage);
            assertEquals("incorrect decoder format",decImage.getFormat(), ImageFormat.YUV_420_888);
            assertEquals("incorrect encoder format", encImage.getFormat(), ImageFormat.YUV_420_888);

            CodecUtils.copyFlexYUVImage(encImage, decImage);

            // TRICKY: need this for queueBuffer
            if (mEncInputBufferSize < 0) {
                mEncInputBufferSize = mEncoder.getInputBuffer(encBuffer).capacity();
            }
            Log.d(TAG, "queuing output #" + encBuffer + " for encoder (sz="
                    + mEncInputBufferSize + ", f=" + decBuffer.second.flags
                    + ", ts=" + decBuffer.second.presentationTimeUs + ")");
            mEncoder.queueInputBuffer(
                    encBuffer, 0, mEncInputBufferSize, decBuffer.second.presentationTimeUs,
                    decBuffer.second.flags);
            if ((decBuffer.second.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                mSignaledEncoderEOS = true;
            }
            mDecoder.releaseOutputBuffer(decBuffer.first, false /* render */);
        }

        @Override
        public void onError(MediaCodec mediaCodec, MediaCodec.CodecException e) {
            fail("received error on " + mediaCodec.getName() + ": " + e);
        }

        @Override
        public void onOutputFormatChanged(MediaCodec mediaCodec, MediaFormat mediaFormat) {
            Log.i(TAG, mediaCodec.getName() + " got new output format " + mediaFormat);
            if (mediaCodec == mEncoder) {
                saveEncoderFormat(mediaFormat);
            }
        }

        // next methods are synchronized on mCondition
        private boolean haveBuffers() {
            return mEncInputBuffers.size() > 0 && mBuffersToRender.size() > 0
                    && !mSignaledEncoderEOS;
        }

        private boolean isEOSOnlyBuffer(Pair<Integer, BufferInfo> decBuffer) {
            return decBuffer.first < 0 || decBuffer.second.size == 0;
        }

        protected void tryToPropagateEOS() {
            if (!mWorkInProgress && haveBuffers() && isEOSOnlyBuffer(mBuffersToRender.getFirst())) {
                Pair<Integer, BufferInfo> decBuffer = mBuffersToRender.removeFirst();
                int encBuffer = mEncInputBuffers.removeFirst();
                queueEncoderEOS(decBuffer, encBuffer);
            }
        }

        void queueEncoderEOS(Pair<Integer, BufferInfo> decBuffer, int encBuffer) {
            Log.d(TAG, "signaling encoder EOS");
            mEncoder.queueInputBuffer(encBuffer, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
            mSignaledEncoderEOS = true;
            if (decBuffer.first >= 0) {
                mDecoder.releaseOutputBuffer(decBuffer.first, false /* render */);
            }
        }
    }


    class SurfaceVideoProcessor extends VideoProcessorBase
            implements SurfaceTexture.OnFrameAvailableListener {
        private static final String TAG = "SurfaceVideoProcessor";
        private boolean mFrameAvailable;
        private boolean mGotDecoderEOS;
        private boolean mSignaledEncoderEOS;

        private InputSurface mEncSurface;
        private OutputSurface mDecSurface;
        private BufferInfo mInfoOnSurface;

        private LinkedList<Pair<Integer, BufferInfo>> mBuffersToRender =
            new LinkedList<Pair<Integer, BufferInfo>>();

        @Override
        public boolean processLoop(
                String path, String outMime, String videoEncName,
                int width, int height, boolean optional) {
            boolean skipped = true;
            try {
                open(path);
                if (!initCodecsAndConfigureEncoder(
                        videoEncName, outMime, width, height,
                        CodecCapabilities.COLOR_FormatSurface)) {
                    assertTrue("could not configure encoder for supported size", optional);
                    return !skipped;
                }
                skipped = false;

                mEncSurface = new InputSurface(mEncoder.createInputSurface());
                mEncSurface.makeCurrent();

                mDecSurface = new OutputSurface(this);
                //mDecSurface.changeFragmentShader(FRAGMENT_SHADER);
                mDecoder.configure(mDecFormat, mDecSurface.getSurface(), null /* crypto */, 0);

                mDecoder.start();
                mEncoder.start();

                // main loop - process GL ops as only main thread has GL context
                while (!mCompleted) {
                    BufferInfo info = null;
                    synchronized (mCondition) {
                        try {
                            // wait for mFrameAvailable, which is set by onFrameAvailable().
                            // Use a timeout to avoid stalling the test if it doesn't arrive.
                            if (!mFrameAvailable && !mCompleted) {
                                mCondition.wait(FRAME_TIMEOUT_MS);
                            }
                        } catch (InterruptedException ie) {
                            fail("wait interrupted");  // shouldn't happen
                        }
                        if (mCompleted) {
                            break;
                        }
                        assertTrue("still waiting for image", mFrameAvailable);
                        if (DEBUG) Log.v(TAG, "got image");
                        info = mInfoOnSurface;
                    }
                    if (info == null) {
                        continue;
                    }
                    if (info.size > 0) {
                        mDecSurface.latchImage();
                        if (DEBUG) Log.v(TAG, "latched image");
                        mFrameAvailable = false;

                        mDecSurface.drawImage();
                        Log.d(TAG, "encoding frame at " + info.presentationTimeUs * 1000);

                        mEncSurface.setPresentationTime(info.presentationTimeUs * 1000);
                        mEncSurface.swapBuffers();
                    }
                    if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                        mSignaledEncoderEOS = true;
                        Log.d(TAG, "signaling encoder EOS");
                        mEncoder.signalEndOfInputStream();
                    }

                    synchronized (mCondition) {
                        mInfoOnSurface = null;
                        if (mBuffersToRender.size() > 0 && mInfoOnSurface == null) {
                            if (DEBUG) Log.v(TAG, "handling postponed frame");
                            Pair<Integer, BufferInfo> nextBuffer = mBuffersToRender.removeFirst();
                            renderDecodedBuffer(nextBuffer.first, nextBuffer.second);
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                fail("received exception " + e);
            } finally {
                close();
                if (mEncSurface != null) {
                    mEncSurface.release();
                    mEncSurface = null;
                }
                if (mDecSurface != null) {
                    mDecSurface.release();
                    mDecSurface = null;
                }
            }
            return !skipped;
        }

        @Override
        public void onFrameAvailable(SurfaceTexture st) {
            if (DEBUG) Log.v(TAG, "new frame available");
            synchronized (mCondition) {
                assertFalse("mFrameAvailable already set, frame could be dropped", mFrameAvailable);
                mFrameAvailable = true;
                mCondition.notifyAll();
            }
        }

        @Override
        public void onInputBufferAvailable(MediaCodec mediaCodec, int ix) {
            if (mediaCodec == mDecoder) {
                // fill input buffer from extractor
                fillDecoderInputBuffer(ix);
            } else {
                fail("received input buffer on " + mediaCodec.getName());
            }
        }

        @Override
        public void onOutputBufferAvailable(
                MediaCodec mediaCodec, int ix, BufferInfo info) {
            if (mediaCodec == mDecoder) {
                if (DEBUG) Log.v(TAG, "decoder received output #" + ix
                         + " (sz=" + info.size + ", f=" + info.flags
                         + ", ts=" + info.presentationTimeUs + ")");
                // render output buffer from decoder
                if (!mGotDecoderEOS) {
                    boolean eos = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
                    if (eos) {
                        mGotDecoderEOS = true;
                    }
                    // can release empty buffers now
                    if (info.size == 0) {
                        mDecoder.releaseOutputBuffer(ix, false /* render */);
                        ix = -1; // dummy index used by render to not render
                    }
                    if (eos || info.size > 0) {
                        synchronized(mCondition) {
                            if (mInfoOnSurface != null || mBuffersToRender.size() > 0) {
                                if (DEBUG) Log.v(TAG, "postponing render, surface busy");
                                mBuffersToRender.addLast(Pair.create(ix, info));
                            } else {
                                renderDecodedBuffer(ix, info);
                            }
                        }
                    }
                }
            } else if (mediaCodec == mEncoder) {
                emptyEncoderOutputBuffer(ix, info);
            } else {
                fail("received output buffer on " + mediaCodec.getName());
            }
        }

        private void renderDecodedBuffer(int ix, BufferInfo info) {
            boolean eos = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
            mInfoOnSurface = info;
            if (info.size > 0) {
                Log.d(TAG, "rendering frame #" + ix + " at " + info.presentationTimeUs * 1000
                        + (eos ? " with EOS" : ""));
                mDecoder.releaseOutputBuffer(ix, info.presentationTimeUs * 1000);
            }

            if (eos && info.size == 0) {
                if (DEBUG) Log.v(TAG, "decoder output EOS available");
                mFrameAvailable = true;
                mCondition.notifyAll();
            }
        }

        @Override
        public void onError(MediaCodec mediaCodec, MediaCodec.CodecException e) {
            fail("received error on " + mediaCodec.getName() + ": " + e);
        }

        @Override
        public void onOutputFormatChanged(MediaCodec mediaCodec, MediaFormat mediaFormat) {
            Log.i(TAG, mediaCodec.getName() + " got new output format " + mediaFormat);
            if (mediaCodec == mEncoder) {
                saveEncoderFormat(mediaFormat);
            }
        }
    }

    class Encoder {
        final private String mName;
        final private String mMime;
        final private VideoCapabilities mCaps;

        final private Map<Size, Set<Size>> mMinMax;     // extreme sizes
        final private Map<Size, Set<Size>> mNearMinMax; // sizes near extreme
        final private Set<Size> mArbitrary;             // arbitrary sizes in the middle
        final private Set<Size> mSizes;                 // all non-specifically tested sizes

        final private int xAlign;
        final private int yAlign;

        Encoder(String name, String mime, CodecCapabilities caps) {
            mName = name;
            mMime = mime;
            mCaps = caps.getVideoCapabilities();

            /* calculate min/max sizes */
            mMinMax = new HashMap<Size, Set<Size>>();
            mNearMinMax = new HashMap<Size, Set<Size>>();
            mArbitrary = new HashSet<Size>();
            mSizes = new HashSet<Size>();

            xAlign = mCaps.getWidthAlignment();
            yAlign = mCaps.getHeightAlignment();

            initializeSizes();
        }

        private void initializeSizes() {
            for (int x = 0; x < 2; ++x) {
                for (int y = 0; y < 2; ++y) {
                    addExtremeSizesFor(x, y);
                }
            }

            // initialize arbitrary sizes
            for (int i = 1; i <= 7; ++i) {
                int j = ((7 * i) % 11) + 1;
                int width = alignedPointInRange(i * 0.125, xAlign, mCaps.getSupportedWidths());
                int height = alignedPointInRange(
                        j * 0.077, yAlign, mCaps.getSupportedHeightsFor(width));
                mArbitrary.add(new Size(width, height));

                height = alignedPointInRange(i * 0.125, yAlign, mCaps.getSupportedHeights());
                width = alignedPointInRange(j * 0.077, xAlign, mCaps.getSupportedWidthsFor(height));
                mArbitrary.add(new Size(width, height));
            }
            mArbitrary.removeAll(mSizes);
            mSizes.addAll(mArbitrary);
            if (DEBUG) Log.i(TAG, "arbitrary=" + mArbitrary);
        }

        private void addExtremeSizesFor(int x, int y) {
            Set<Size> minMax = new HashSet<Size>();
            Set<Size> nearMinMax = new HashSet<Size>();

            for (int dx = 0; dx <= xAlign; dx += xAlign) {
                for (int dy = 0; dy <= yAlign; dy += yAlign) {
                    Set<Size> bucket = (dx + dy == 0) ? minMax : nearMinMax;
                    try {
                        int width = getExtreme(mCaps.getSupportedWidths(), x, dx);
                        int height = getExtreme(mCaps.getSupportedHeightsFor(width), y, dy);
                        bucket.add(new Size(width, height));

                        // try max max with more reasonable ratio if too skewed
                        if (x + y == 2 && width >= 4 * height) {
                            Size wideScreen = getLargestSizeForRatio(16, 9);
                            width = getExtreme(
                                    mCaps.getSupportedWidths()
                                            .intersect(0, wideScreen.getWidth()), x, dx);
                            height = getExtreme(mCaps.getSupportedHeightsFor(width), y, 0);
                            bucket.add(new Size(width, height));
                        }
                    } catch (IllegalArgumentException e) {
                    }

                    try {
                        int height = getExtreme(mCaps.getSupportedHeights(), y, dy);
                        int width = getExtreme(mCaps.getSupportedWidthsFor(height), x, dx);
                        bucket.add(new Size(width, height));

                        // try max max with more reasonable ratio if too skewed
                        if (x + y == 2 && height >= 4 * width) {
                            Size wideScreen = getLargestSizeForRatio(9, 16);
                            height = getExtreme(
                                    mCaps.getSupportedHeights()
                                            .intersect(0, wideScreen.getHeight()), y, dy);
                            width = getExtreme(mCaps.getSupportedWidthsFor(height), x, dx);
                            bucket.add(new Size(width, height));
                        }
                    } catch (IllegalArgumentException e) {
                    }
                }
            }

            // keep unique sizes
            minMax.removeAll(mSizes);
            mSizes.addAll(minMax);
            nearMinMax.removeAll(mSizes);
            mSizes.addAll(nearMinMax);

            mMinMax.put(new Size(x, y), minMax);
            mNearMinMax.put(new Size(x, y), nearMinMax);
            if (DEBUG) Log.i(TAG, x + "x" + y + ": minMax=" + mMinMax + ", near=" + mNearMinMax);
        }

        private int alignInRange(double value, int align, Range<Integer> range) {
            return range.clamp(align * (int)Math.round(value / align));
        }

        /* point should be between 0. and 1. */
        private int alignedPointInRange(double point, int align, Range<Integer> range) {
            return alignInRange(
                    range.getLower() + point * (range.getUpper() - range.getLower()), align, range);
        }

        private int getExtreme(Range<Integer> range, int i, int delta) {
            int dim = i == 1 ? range.getUpper() - delta : range.getLower() + delta;
            if (delta == 0
                    || (dim > range.getLower() && dim < range.getUpper())) {
                return dim;
            }
            throw new IllegalArgumentException();
        }

        private Size getLargestSizeForRatio(int x, int y) {
            Range<Integer> widthRange = mCaps.getSupportedWidths();
            Range<Integer> heightRange = mCaps.getSupportedHeightsFor(widthRange.getUpper());
            final int xAlign = mCaps.getWidthAlignment();
            final int yAlign = mCaps.getHeightAlignment();

            // scale by alignment
            int width = alignInRange(
                    Math.sqrt(widthRange.getUpper() * heightRange.getUpper() * (double)x / y),
                    xAlign, widthRange);
            int height = alignInRange(
                    width * (double)y / x, yAlign, mCaps.getSupportedHeightsFor(width));
            return new Size(width, height);
        }


        public boolean testExtreme(int x, int y, boolean flexYUV, boolean near) {
            boolean skipped = true;
            for (Size s : (near ? mNearMinMax : mMinMax).get(new Size(x, y))) {
                if (test(s.getWidth(), s.getHeight(), false /* optional */, flexYUV)) {
                    skipped = false;
                }
            }
            return !skipped;
        }

        public boolean testArbitrary(boolean flexYUV) {
            boolean skipped = true;
            for (Size s : mArbitrary) {
                if (test(s.getWidth(), s.getHeight(), false /* optional */, flexYUV)) {
                    skipped = false;
                }
            }
            return !skipped;
        }

        public boolean testSpecific(int width, int height, boolean flexYUV) {
            // already tested by one of the min/max tests
            if (mSizes.contains(new Size(width, height))) {
                return false;
            }
            return test(width, height, true /* optional */, flexYUV);
        }

        public boolean testDetailed(
                int width, int height, int frameRate, int bitRate, boolean flexYUV) {
            return test(width, height, frameRate, bitRate, true /* optional */, flexYUV);
        }

        public boolean testSupport(int width, int height, int frameRate, int bitRate) {
            return mCaps.areSizeAndRateSupported(width, height, frameRate) &&
                    mCaps.getBitrateRange().contains(bitRate);
        }

        private boolean test(int width, int height, boolean optional, boolean flexYUV) {
            return test(width, height, 0 /* frameRate */, 0 /* bitRate */, optional, flexYUV);
        }

        private boolean test(int width, int height, int frameRate, int bitRate,
                boolean optional, boolean flexYUV) {
            Log.i(TAG, "testing " + mMime + " on " + mName + " for " + width + "x" + height
                    + (flexYUV ? " flexYUV" : " surface"));

            VideoProcessorBase processor =
                flexYUV ? new VideoProcessor() : new SurfaceVideoProcessor();

            processor.setFrameAndBitRates(frameRate, bitRate);

            // We are using a resource URL as an example
            boolean success = processor.processLoop(
                    SOURCE_URL, mMime, mName, width, height, optional);
            if (success) {
                processor.playBack(getActivity().getSurfaceHolder().getSurface());
            }
            return success;
        }
    }

    private Encoder[] googH265()  { return goog(MediaFormat.MIMETYPE_VIDEO_HEVC); }
    private Encoder[] googH264()  { return goog(MediaFormat.MIMETYPE_VIDEO_AVC); }
    private Encoder[] googH263()  { return goog(MediaFormat.MIMETYPE_VIDEO_H263); }
    private Encoder[] googMpeg4() { return goog(MediaFormat.MIMETYPE_VIDEO_MPEG4); }
    private Encoder[] googVP8()   { return goog(MediaFormat.MIMETYPE_VIDEO_VP8); }
    private Encoder[] googVP9()   { return goog(MediaFormat.MIMETYPE_VIDEO_VP9); }

    private Encoder[] otherH265()  { return other(MediaFormat.MIMETYPE_VIDEO_HEVC); }
    private Encoder[] otherH264()  { return other(MediaFormat.MIMETYPE_VIDEO_AVC); }
    private Encoder[] otherH263()  { return other(MediaFormat.MIMETYPE_VIDEO_H263); }
    private Encoder[] otherMpeg4() { return other(MediaFormat.MIMETYPE_VIDEO_MPEG4); }
    private Encoder[] otherVP8()   { return other(MediaFormat.MIMETYPE_VIDEO_VP8); }
    private Encoder[] otherVP9()   { return other(MediaFormat.MIMETYPE_VIDEO_VP9); }

    private Encoder[] goog(String mime) {
        return encoders(mime, true /* goog */);
    }

    private Encoder[] other(String mime) {
        return encoders(mime, false /* goog */);
    }

    private Encoder[] combineArray(Encoder[] a, Encoder[] b) {
        Encoder[] all = new Encoder[a.length + b.length];
        System.arraycopy(a, 0, all, 0, a.length);
        System.arraycopy(b, 0, all, a.length, b.length);
        return all;
    }

    private Encoder[] h264()  {
        return combineArray(googH264(), otherH264());
    }

    private Encoder[] vp8()  {
        return combineArray(googVP8(), otherVP8());
    }

    private Encoder[] encoders(String mime, boolean goog) {
        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
        ArrayList<Encoder> result = new ArrayList<Encoder>();

        for (MediaCodecInfo info : mcl.getCodecInfos()) {
            if (!info.isEncoder()
                    || info.getName().toLowerCase().startsWith("omx.google.") != goog) {
                continue;
            }
            try {
                CodecCapabilities caps = info.getCapabilitiesForType(mime);
                result.add(new Encoder(info.getName(), mime, caps));
            } catch (IllegalArgumentException e) { // mime is not supported
            }
        }
        return result.toArray(new Encoder[result.size()]);
    }

    public void testGoogH265FlexMinMin()   { minmin(googH265(),   true /* flex */); }
    public void testGoogH265SurfMinMin()   { minmin(googH265(),   false /* flex */); }
    public void testGoogH264FlexMinMin()   { minmin(googH264(),   true /* flex */); }
    public void testGoogH264SurfMinMin()   { minmin(googH264(),   false /* flex */); }
    public void testGoogH263FlexMinMin()   { minmin(googH263(),   true /* flex */); }
    public void testGoogH263SurfMinMin()   { minmin(googH263(),   false /* flex */); }
    public void testGoogMpeg4FlexMinMin()  { minmin(googMpeg4(),  true /* flex */); }
    public void testGoogMpeg4SurfMinMin()  { minmin(googMpeg4(),  false /* flex */); }
    public void testGoogVP8FlexMinMin()    { minmin(googVP8(),    true /* flex */); }
    public void testGoogVP8SurfMinMin()    { minmin(googVP8(),    false /* flex */); }
    public void testGoogVP9FlexMinMin()    { minmin(googVP9(),    true /* flex */); }
    public void testGoogVP9SurfMinMin()    { minmin(googVP9(),    false /* flex */); }

    public void testOtherH265FlexMinMin()  { minmin(otherH265(),  true /* flex */); }
    public void testOtherH265SurfMinMin()  { minmin(otherH265(),  false /* flex */); }
    public void testOtherH264FlexMinMin()  { minmin(otherH264(),  true /* flex */); }
    public void testOtherH264SurfMinMin()  { minmin(otherH264(),  false /* flex */); }
    public void testOtherH263FlexMinMin()  { minmin(otherH263(),  true /* flex */); }
    public void testOtherH263SurfMinMin()  { minmin(otherH263(),  false /* flex */); }
    public void testOtherMpeg4FlexMinMin() { minmin(otherMpeg4(), true /* flex */); }
    public void testOtherMpeg4SurfMinMin() { minmin(otherMpeg4(), false /* flex */); }
    public void testOtherVP8FlexMinMin()   { minmin(otherVP8(),   true /* flex */); }
    public void testOtherVP8SurfMinMin()   { minmin(otherVP8(),   false /* flex */); }
    public void testOtherVP9FlexMinMin()   { minmin(otherVP9(),   true /* flex */); }
    public void testOtherVP9SurfMinMin()   { minmin(otherVP9(),   false /* flex */); }

    public void testGoogH265FlexMinMax()   { minmax(googH265(),   true /* flex */); }
    public void testGoogH265SurfMinMax()   { minmax(googH265(),   false /* flex */); }
    public void testGoogH264FlexMinMax()   { minmax(googH264(),   true /* flex */); }
    public void testGoogH264SurfMinMax()   { minmax(googH264(),   false /* flex */); }
    public void testGoogH263FlexMinMax()   { minmax(googH263(),   true /* flex */); }
    public void testGoogH263SurfMinMax()   { minmax(googH263(),   false /* flex */); }
    public void testGoogMpeg4FlexMinMax()  { minmax(googMpeg4(),  true /* flex */); }
    public void testGoogMpeg4SurfMinMax()  { minmax(googMpeg4(),  false /* flex */); }
    public void testGoogVP8FlexMinMax()    { minmax(googVP8(),    true /* flex */); }
    public void testGoogVP8SurfMinMax()    { minmax(googVP8(),    false /* flex */); }
    public void testGoogVP9FlexMinMax()    { minmax(googVP9(),    true /* flex */); }
    public void testGoogVP9SurfMinMax()    { minmax(googVP9(),    false /* flex */); }

    public void testOtherH265FlexMinMax()  { minmax(otherH265(),  true /* flex */); }
    public void testOtherH265SurfMinMax()  { minmax(otherH265(),  false /* flex */); }
    public void testOtherH264FlexMinMax()  { minmax(otherH264(),  true /* flex */); }
    public void testOtherH264SurfMinMax()  { minmax(otherH264(),  false /* flex */); }
    public void testOtherH263FlexMinMax()  { minmax(otherH263(),  true /* flex */); }
    public void testOtherH263SurfMinMax()  { minmax(otherH263(),  false /* flex */); }
    public void testOtherMpeg4FlexMinMax() { minmax(otherMpeg4(), true /* flex */); }
    public void testOtherMpeg4SurfMinMax() { minmax(otherMpeg4(), false /* flex */); }
    public void testOtherVP8FlexMinMax()   { minmax(otherVP8(),   true /* flex */); }
    public void testOtherVP8SurfMinMax()   { minmax(otherVP8(),   false /* flex */); }
    public void testOtherVP9FlexMinMax()   { minmax(otherVP9(),   true /* flex */); }
    public void testOtherVP9SurfMinMax()   { minmax(otherVP9(),   false /* flex */); }

    public void testGoogH265FlexMaxMin()   { maxmin(googH265(),   true /* flex */); }
    public void testGoogH265SurfMaxMin()   { maxmin(googH265(),   false /* flex */); }
    public void testGoogH264FlexMaxMin()   { maxmin(googH264(),   true /* flex */); }
    public void testGoogH264SurfMaxMin()   { maxmin(googH264(),   false /* flex */); }
    public void testGoogH263FlexMaxMin()   { maxmin(googH263(),   true /* flex */); }
    public void testGoogH263SurfMaxMin()   { maxmin(googH263(),   false /* flex */); }
    public void testGoogMpeg4FlexMaxMin()  { maxmin(googMpeg4(),  true /* flex */); }
    public void testGoogMpeg4SurfMaxMin()  { maxmin(googMpeg4(),  false /* flex */); }
    public void testGoogVP8FlexMaxMin()    { maxmin(googVP8(),    true /* flex */); }
    public void testGoogVP8SurfMaxMin()    { maxmin(googVP8(),    false /* flex */); }
    public void testGoogVP9FlexMaxMin()    { maxmin(googVP9(),    true /* flex */); }
    public void testGoogVP9SurfMaxMin()    { maxmin(googVP9(),    false /* flex */); }

    public void testOtherH265FlexMaxMin()  { maxmin(otherH265(),  true /* flex */); }
    public void testOtherH265SurfMaxMin()  { maxmin(otherH265(),  false /* flex */); }
    public void testOtherH264FlexMaxMin()  { maxmin(otherH264(),  true /* flex */); }
    public void testOtherH264SurfMaxMin()  { maxmin(otherH264(),  false /* flex */); }
    public void testOtherH263FlexMaxMin()  { maxmin(otherH263(),  true /* flex */); }
    public void testOtherH263SurfMaxMin()  { maxmin(otherH263(),  false /* flex */); }
    public void testOtherMpeg4FlexMaxMin() { maxmin(otherMpeg4(), true /* flex */); }
    public void testOtherMpeg4SurfMaxMin() { maxmin(otherMpeg4(), false /* flex */); }
    public void testOtherVP8FlexMaxMin()   { maxmin(otherVP8(),   true /* flex */); }
    public void testOtherVP8SurfMaxMin()   { maxmin(otherVP8(),   false /* flex */); }
    public void testOtherVP9FlexMaxMin()   { maxmin(otherVP9(),   true /* flex */); }
    public void testOtherVP9SurfMaxMin()   { maxmin(otherVP9(),   false /* flex */); }

    public void testGoogH265FlexMaxMax()   { maxmax(googH265(),   true /* flex */); }
    public void testGoogH265SurfMaxMax()   { maxmax(googH265(),   false /* flex */); }
    public void testGoogH264FlexMaxMax()   { maxmax(googH264(),   true /* flex */); }
    public void testGoogH264SurfMaxMax()   { maxmax(googH264(),   false /* flex */); }
    public void testGoogH263FlexMaxMax()   { maxmax(googH263(),   true /* flex */); }
    public void testGoogH263SurfMaxMax()   { maxmax(googH263(),   false /* flex */); }
    public void testGoogMpeg4FlexMaxMax()  { maxmax(googMpeg4(),  true /* flex */); }
    public void testGoogMpeg4SurfMaxMax()  { maxmax(googMpeg4(),  false /* flex */); }
    public void testGoogVP8FlexMaxMax()    { maxmax(googVP8(),    true /* flex */); }
    public void testGoogVP8SurfMaxMax()    { maxmax(googVP8(),    false /* flex */); }
    public void testGoogVP9FlexMaxMax()    { maxmax(googVP9(),    true /* flex */); }
    public void testGoogVP9SurfMaxMax()    { maxmax(googVP9(),    false /* flex */); }

    public void testOtherH265FlexMaxMax()  { maxmax(otherH265(),  true /* flex */); }
    public void testOtherH265SurfMaxMax()  { maxmax(otherH265(),  false /* flex */); }
    public void testOtherH264FlexMaxMax()  { maxmax(otherH264(),  true /* flex */); }
    public void testOtherH264SurfMaxMax()  { maxmax(otherH264(),  false /* flex */); }
    public void testOtherH263FlexMaxMax()  { maxmax(otherH263(),  true /* flex */); }
    public void testOtherH263SurfMaxMax()  { maxmax(otherH263(),  false /* flex */); }
    public void testOtherMpeg4FlexMaxMax() { maxmax(otherMpeg4(), true /* flex */); }
    public void testOtherMpeg4SurfMaxMax() { maxmax(otherMpeg4(), false /* flex */); }
    public void testOtherVP8FlexMaxMax()   { maxmax(otherVP8(),   true /* flex */); }
    public void testOtherVP8SurfMaxMax()   { maxmax(otherVP8(),   false /* flex */); }
    public void testOtherVP9FlexMaxMax()   { maxmax(otherVP9(),   true /* flex */); }
    public void testOtherVP9SurfMaxMax()   { maxmax(otherVP9(),   false /* flex */); }

    public void testGoogH265FlexNearMinMin()   { nearminmin(googH265(),   true /* flex */); }
    public void testGoogH265SurfNearMinMin()   { nearminmin(googH265(),   false /* flex */); }
    public void testGoogH264FlexNearMinMin()   { nearminmin(googH264(),   true /* flex */); }
    public void testGoogH264SurfNearMinMin()   { nearminmin(googH264(),   false /* flex */); }
    public void testGoogH263FlexNearMinMin()   { nearminmin(googH263(),   true /* flex */); }
    public void testGoogH263SurfNearMinMin()   { nearminmin(googH263(),   false /* flex */); }
    public void testGoogMpeg4FlexNearMinMin()  { nearminmin(googMpeg4(),  true /* flex */); }
    public void testGoogMpeg4SurfNearMinMin()  { nearminmin(googMpeg4(),  false /* flex */); }
    public void testGoogVP8FlexNearMinMin()    { nearminmin(googVP8(),    true /* flex */); }
    public void testGoogVP8SurfNearMinMin()    { nearminmin(googVP8(),    false /* flex */); }
    public void testGoogVP9FlexNearMinMin()    { nearminmin(googVP9(),    true /* flex */); }
    public void testGoogVP9SurfNearMinMin()    { nearminmin(googVP9(),    false /* flex */); }

    public void testOtherH265FlexNearMinMin()  { nearminmin(otherH265(),  true /* flex */); }
    public void testOtherH265SurfNearMinMin()  { nearminmin(otherH265(),  false /* flex */); }
    public void testOtherH264FlexNearMinMin()  { nearminmin(otherH264(),  true /* flex */); }
    public void testOtherH264SurfNearMinMin()  { nearminmin(otherH264(),  false /* flex */); }
    public void testOtherH263FlexNearMinMin()  { nearminmin(otherH263(),  true /* flex */); }
    public void testOtherH263SurfNearMinMin()  { nearminmin(otherH263(),  false /* flex */); }
    public void testOtherMpeg4FlexNearMinMin() { nearminmin(otherMpeg4(), true /* flex */); }
    public void testOtherMpeg4SurfNearMinMin() { nearminmin(otherMpeg4(), false /* flex */); }
    public void testOtherVP8FlexNearMinMin()   { nearminmin(otherVP8(),   true /* flex */); }
    public void testOtherVP8SurfNearMinMin()   { nearminmin(otherVP8(),   false /* flex */); }
    public void testOtherVP9FlexNearMinMin()   { nearminmin(otherVP9(),   true /* flex */); }
    public void testOtherVP9SurfNearMinMin()   { nearminmin(otherVP9(),   false /* flex */); }

    public void testGoogH265FlexNearMinMax()   { nearminmax(googH265(),   true /* flex */); }
    public void testGoogH265SurfNearMinMax()   { nearminmax(googH265(),   false /* flex */); }
    public void testGoogH264FlexNearMinMax()   { nearminmax(googH264(),   true /* flex */); }
    public void testGoogH264SurfNearMinMax()   { nearminmax(googH264(),   false /* flex */); }
    public void testGoogH263FlexNearMinMax()   { nearminmax(googH263(),   true /* flex */); }
    public void testGoogH263SurfNearMinMax()   { nearminmax(googH263(),   false /* flex */); }
    public void testGoogMpeg4FlexNearMinMax()  { nearminmax(googMpeg4(),  true /* flex */); }
    public void testGoogMpeg4SurfNearMinMax()  { nearminmax(googMpeg4(),  false /* flex */); }
    public void testGoogVP8FlexNearMinMax()    { nearminmax(googVP8(),    true /* flex */); }
    public void testGoogVP8SurfNearMinMax()    { nearminmax(googVP8(),    false /* flex */); }
    public void testGoogVP9FlexNearMinMax()    { nearminmax(googVP9(),    true /* flex */); }
    public void testGoogVP9SurfNearMinMax()    { nearminmax(googVP9(),    false /* flex */); }

    public void testOtherH265FlexNearMinMax()  { nearminmax(otherH265(),  true /* flex */); }
    public void testOtherH265SurfNearMinMax()  { nearminmax(otherH265(),  false /* flex */); }
    public void testOtherH264FlexNearMinMax()  { nearminmax(otherH264(),  true /* flex */); }
    public void testOtherH264SurfNearMinMax()  { nearminmax(otherH264(),  false /* flex */); }
    public void testOtherH263FlexNearMinMax()  { nearminmax(otherH263(),  true /* flex */); }
    public void testOtherH263SurfNearMinMax()  { nearminmax(otherH263(),  false /* flex */); }
    public void testOtherMpeg4FlexNearMinMax() { nearminmax(otherMpeg4(), true /* flex */); }
    public void testOtherMpeg4SurfNearMinMax() { nearminmax(otherMpeg4(), false /* flex */); }
    public void testOtherVP8FlexNearMinMax()   { nearminmax(otherVP8(),   true /* flex */); }
    public void testOtherVP8SurfNearMinMax()   { nearminmax(otherVP8(),   false /* flex */); }
    public void testOtherVP9FlexNearMinMax()   { nearminmax(otherVP9(),   true /* flex */); }
    public void testOtherVP9SurfNearMinMax()   { nearminmax(otherVP9(),   false /* flex */); }

    public void testGoogH265FlexNearMaxMin()   { nearmaxmin(googH265(),   true /* flex */); }
    public void testGoogH265SurfNearMaxMin()   { nearmaxmin(googH265(),   false /* flex */); }
    public void testGoogH264FlexNearMaxMin()   { nearmaxmin(googH264(),   true /* flex */); }
    public void testGoogH264SurfNearMaxMin()   { nearmaxmin(googH264(),   false /* flex */); }
    public void testGoogH263FlexNearMaxMin()   { nearmaxmin(googH263(),   true /* flex */); }
    public void testGoogH263SurfNearMaxMin()   { nearmaxmin(googH263(),   false /* flex */); }
    public void testGoogMpeg4FlexNearMaxMin()  { nearmaxmin(googMpeg4(),  true /* flex */); }
    public void testGoogMpeg4SurfNearMaxMin()  { nearmaxmin(googMpeg4(),  false /* flex */); }
    public void testGoogVP8FlexNearMaxMin()    { nearmaxmin(googVP8(),    true /* flex */); }
    public void testGoogVP8SurfNearMaxMin()    { nearmaxmin(googVP8(),    false /* flex */); }
    public void testGoogVP9FlexNearMaxMin()    { nearmaxmin(googVP9(),    true /* flex */); }
    public void testGoogVP9SurfNearMaxMin()    { nearmaxmin(googVP9(),    false /* flex */); }

    public void testOtherH265FlexNearMaxMin()  { nearmaxmin(otherH265(),  true /* flex */); }
    public void testOtherH265SurfNearMaxMin()  { nearmaxmin(otherH265(),  false /* flex */); }
    public void testOtherH264FlexNearMaxMin()  { nearmaxmin(otherH264(),  true /* flex */); }
    public void testOtherH264SurfNearMaxMin()  { nearmaxmin(otherH264(),  false /* flex */); }
    public void testOtherH263FlexNearMaxMin()  { nearmaxmin(otherH263(),  true /* flex */); }
    public void testOtherH263SurfNearMaxMin()  { nearmaxmin(otherH263(),  false /* flex */); }
    public void testOtherMpeg4FlexNearMaxMin() { nearmaxmin(otherMpeg4(), true /* flex */); }
    public void testOtherMpeg4SurfNearMaxMin() { nearmaxmin(otherMpeg4(), false /* flex */); }
    public void testOtherVP8FlexNearMaxMin()   { nearmaxmin(otherVP8(),   true /* flex */); }
    public void testOtherVP8SurfNearMaxMin()   { nearmaxmin(otherVP8(),   false /* flex */); }
    public void testOtherVP9FlexNearMaxMin()   { nearmaxmin(otherVP9(),   true /* flex */); }
    public void testOtherVP9SurfNearMaxMin()   { nearmaxmin(otherVP9(),   false /* flex */); }

    public void testGoogH265FlexNearMaxMax()   { nearmaxmax(googH265(),   true /* flex */); }
    public void testGoogH265SurfNearMaxMax()   { nearmaxmax(googH265(),   false /* flex */); }
    public void testGoogH264FlexNearMaxMax()   { nearmaxmax(googH264(),   true /* flex */); }
    public void testGoogH264SurfNearMaxMax()   { nearmaxmax(googH264(),   false /* flex */); }
    public void testGoogH263FlexNearMaxMax()   { nearmaxmax(googH263(),   true /* flex */); }
    public void testGoogH263SurfNearMaxMax()   { nearmaxmax(googH263(),   false /* flex */); }
    public void testGoogMpeg4FlexNearMaxMax()  { nearmaxmax(googMpeg4(),  true /* flex */); }
    public void testGoogMpeg4SurfNearMaxMax()  { nearmaxmax(googMpeg4(),  false /* flex */); }
    public void testGoogVP8FlexNearMaxMax()    { nearmaxmax(googVP8(),    true /* flex */); }
    public void testGoogVP8SurfNearMaxMax()    { nearmaxmax(googVP8(),    false /* flex */); }
    public void testGoogVP9FlexNearMaxMax()    { nearmaxmax(googVP9(),    true /* flex */); }
    public void testGoogVP9SurfNearMaxMax()    { nearmaxmax(googVP9(),    false /* flex */); }

    public void testOtherH265FlexNearMaxMax()  { nearmaxmax(otherH265(),  true /* flex */); }
    public void testOtherH265SurfNearMaxMax()  { nearmaxmax(otherH265(),  false /* flex */); }
    public void testOtherH264FlexNearMaxMax()  { nearmaxmax(otherH264(),  true /* flex */); }
    public void testOtherH264SurfNearMaxMax()  { nearmaxmax(otherH264(),  false /* flex */); }
    public void testOtherH263FlexNearMaxMax()  { nearmaxmax(otherH263(),  true /* flex */); }
    public void testOtherH263SurfNearMaxMax()  { nearmaxmax(otherH263(),  false /* flex */); }
    public void testOtherMpeg4FlexNearMaxMax() { nearmaxmax(otherMpeg4(), true /* flex */); }
    public void testOtherMpeg4SurfNearMaxMax() { nearmaxmax(otherMpeg4(), false /* flex */); }
    public void testOtherVP8FlexNearMaxMax()   { nearmaxmax(otherVP8(),   true /* flex */); }
    public void testOtherVP8SurfNearMaxMax()   { nearmaxmax(otherVP8(),   false /* flex */); }
    public void testOtherVP9FlexNearMaxMax()   { nearmaxmax(otherVP9(),   true /* flex */); }
    public void testOtherVP9SurfNearMaxMax()   { nearmaxmax(otherVP9(),   false /* flex */); }

    public void testGoogH265FlexArbitrary()   { arbitrary(googH265(),   true /* flex */); }
    public void testGoogH265SurfArbitrary()   { arbitrary(googH265(),   false /* flex */); }
    public void testGoogH264FlexArbitrary()   { arbitrary(googH264(),   true /* flex */); }
    public void testGoogH264SurfArbitrary()   { arbitrary(googH264(),   false /* flex */); }
    public void testGoogH263FlexArbitrary()   { arbitrary(googH263(),   true /* flex */); }
    public void testGoogH263SurfArbitrary()   { arbitrary(googH263(),   false /* flex */); }
    public void testGoogMpeg4FlexArbitrary()  { arbitrary(googMpeg4(),  true /* flex */); }
    public void testGoogMpeg4SurfArbitrary()  { arbitrary(googMpeg4(),  false /* flex */); }
    public void testGoogVP8FlexArbitrary()    { arbitrary(googVP8(),    true /* flex */); }
    public void testGoogVP8SurfArbitrary()    { arbitrary(googVP8(),    false /* flex */); }
    public void testGoogVP9FlexArbitrary()    { arbitrary(googVP9(),    true /* flex */); }
    public void testGoogVP9SurfArbitrary()    { arbitrary(googVP9(),    false /* flex */); }

    public void testOtherH265FlexArbitrary()  { arbitrary(otherH265(),  true /* flex */); }
    public void testOtherH265SurfArbitrary()  { arbitrary(otherH265(),  false /* flex */); }
    public void testOtherH264FlexArbitrary()  { arbitrary(otherH264(),  true /* flex */); }
    public void testOtherH264SurfArbitrary()  { arbitrary(otherH264(),  false /* flex */); }
    public void testOtherH263FlexArbitrary()  { arbitrary(otherH263(),  true /* flex */); }
    public void testOtherH263SurfArbitrary()  { arbitrary(otherH263(),  false /* flex */); }
    public void testOtherMpeg4FlexArbitrary() { arbitrary(otherMpeg4(), true /* flex */); }
    public void testOtherMpeg4SurfArbitrary() { arbitrary(otherMpeg4(), false /* flex */); }
    public void testOtherVP8FlexArbitrary()   { arbitrary(otherVP8(),   true /* flex */); }
    public void testOtherVP8SurfArbitrary()   { arbitrary(otherVP8(),   false /* flex */); }
    public void testOtherVP9FlexArbitrary()   { arbitrary(otherVP9(),   true /* flex */); }
    public void testOtherVP9SurfArbitrary()   { arbitrary(otherVP9(),   false /* flex */); }

    public void testGoogH265FlexQCIF()   { specific(googH265(),   176, 144, true /* flex */); }
    public void testGoogH265SurfQCIF()   { specific(googH265(),   176, 144, false /* flex */); }
    public void testGoogH264FlexQCIF()   { specific(googH264(),   176, 144, true /* flex */); }
    public void testGoogH264SurfQCIF()   { specific(googH264(),   176, 144, false /* flex */); }
    public void testGoogH263FlexQCIF()   { specific(googH263(),   176, 144, true /* flex */); }
    public void testGoogH263SurfQCIF()   { specific(googH263(),   176, 144, false /* flex */); }
    public void testGoogMpeg4FlexQCIF()  { specific(googMpeg4(),  176, 144, true /* flex */); }
    public void testGoogMpeg4SurfQCIF()  { specific(googMpeg4(),  176, 144, false /* flex */); }
    public void testGoogVP8FlexQCIF()    { specific(googVP8(),    176, 144, true /* flex */); }
    public void testGoogVP8SurfQCIF()    { specific(googVP8(),    176, 144, false /* flex */); }
    public void testGoogVP9FlexQCIF()    { specific(googVP9(),    176, 144, true /* flex */); }
    public void testGoogVP9SurfQCIF()    { specific(googVP9(),    176, 144, false /* flex */); }

    public void testOtherH265FlexQCIF()  { specific(otherH265(),  176, 144, true /* flex */); }
    public void testOtherH265SurfQCIF()  { specific(otherH265(),  176, 144, false /* flex */); }
    public void testOtherH264FlexQCIF()  { specific(otherH264(),  176, 144, true /* flex */); }
    public void testOtherH264SurfQCIF()  { specific(otherH264(),  176, 144, false /* flex */); }
    public void testOtherH263FlexQCIF()  { specific(otherH263(),  176, 144, true /* flex */); }
    public void testOtherH263SurfQCIF()  { specific(otherH263(),  176, 144, false /* flex */); }
    public void testOtherMpeg4FlexQCIF() { specific(otherMpeg4(), 176, 144, true /* flex */); }
    public void testOtherMpeg4SurfQCIF() { specific(otherMpeg4(), 176, 144, false /* flex */); }
    public void testOtherVP8FlexQCIF()   { specific(otherVP8(),   176, 144, true /* flex */); }
    public void testOtherVP8SurfQCIF()   { specific(otherVP8(),   176, 144, false /* flex */); }
    public void testOtherVP9FlexQCIF()   { specific(otherVP9(),   176, 144, true /* flex */); }
    public void testOtherVP9SurfQCIF()   { specific(otherVP9(),   176, 144, false /* flex */); }

    public void testGoogH265Flex480p()   { specific(googH265(),   720, 480, true /* flex */); }
    public void testGoogH265Surf480p()   { specific(googH265(),   720, 480, false /* flex */); }
    public void testGoogH264Flex480p()   { specific(googH264(),   720, 480, true /* flex */); }
    public void testGoogH264Surf480p()   { specific(googH264(),   720, 480, false /* flex */); }
    public void testGoogH263Flex480p()   { specific(googH263(),   720, 480, true /* flex */); }
    public void testGoogH263Surf480p()   { specific(googH263(),   720, 480, false /* flex */); }
    public void testGoogMpeg4Flex480p()  { specific(googMpeg4(),  720, 480, true /* flex */); }
    public void testGoogMpeg4Surf480p()  { specific(googMpeg4(),  720, 480, false /* flex */); }
    public void testGoogVP8Flex480p()    { specific(googVP8(),    720, 480, true /* flex */); }
    public void testGoogVP8Surf480p()    { specific(googVP8(),    720, 480, false /* flex */); }
    public void testGoogVP9Flex480p()    { specific(googVP9(),    720, 480, true /* flex */); }
    public void testGoogVP9Surf480p()    { specific(googVP9(),    720, 480, false /* flex */); }

    public void testOtherH265Flex480p()  { specific(otherH265(),  720, 480, true /* flex */); }
    public void testOtherH265Surf480p()  { specific(otherH265(),  720, 480, false /* flex */); }
    public void testOtherH264Flex480p()  { specific(otherH264(),  720, 480, true /* flex */); }
    public void testOtherH264Surf480p()  { specific(otherH264(),  720, 480, false /* flex */); }
    public void testOtherH263Flex480p()  { specific(otherH263(),  720, 480, true /* flex */); }
    public void testOtherH263Surf480p()  { specific(otherH263(),  720, 480, false /* flex */); }
    public void testOtherMpeg4Flex480p() { specific(otherMpeg4(), 720, 480, true /* flex */); }
    public void testOtherMpeg4Surf480p() { specific(otherMpeg4(), 720, 480, false /* flex */); }
    public void testOtherVP8Flex480p()   { specific(otherVP8(),   720, 480, true /* flex */); }
    public void testOtherVP8Surf480p()   { specific(otherVP8(),   720, 480, false /* flex */); }
    public void testOtherVP9Flex480p()   { specific(otherVP9(),   720, 480, true /* flex */); }
    public void testOtherVP9Surf480p()   { specific(otherVP9(),   720, 480, false /* flex */); }

    // even though H.263 and MPEG-4 are not defined for 720p or 1080p
    // test for it, in case device claims support for it.

    public void testGoogH265Flex720p()   { specific(googH265(),   1280, 720, true /* flex */); }
    public void testGoogH265Surf720p()   { specific(googH265(),   1280, 720, false /* flex */); }
    public void testGoogH264Flex720p()   { specific(googH264(),   1280, 720, true /* flex */); }
    public void testGoogH264Surf720p()   { specific(googH264(),   1280, 720, false /* flex */); }
    public void testGoogH263Flex720p()   { specific(googH263(),   1280, 720, true /* flex */); }
    public void testGoogH263Surf720p()   { specific(googH263(),   1280, 720, false /* flex */); }
    public void testGoogMpeg4Flex720p()  { specific(googMpeg4(),  1280, 720, true /* flex */); }
    public void testGoogMpeg4Surf720p()  { specific(googMpeg4(),  1280, 720, false /* flex */); }
    public void testGoogVP8Flex720p()    { specific(googVP8(),    1280, 720, true /* flex */); }
    public void testGoogVP8Surf720p()    { specific(googVP8(),    1280, 720, false /* flex */); }
    public void testGoogVP9Flex720p()    { specific(googVP9(),    1280, 720, true /* flex */); }
    public void testGoogVP9Surf720p()    { specific(googVP9(),    1280, 720, false /* flex */); }

    public void testOtherH265Flex720p()  { specific(otherH265(),  1280, 720, true /* flex */); }
    public void testOtherH265Surf720p()  { specific(otherH265(),  1280, 720, false /* flex */); }
    public void testOtherH264Flex720p()  { specific(otherH264(),  1280, 720, true /* flex */); }
    public void testOtherH264Surf720p()  { specific(otherH264(),  1280, 720, false /* flex */); }
    public void testOtherH263Flex720p()  { specific(otherH263(),  1280, 720, true /* flex */); }
    public void testOtherH263Surf720p()  { specific(otherH263(),  1280, 720, false /* flex */); }
    public void testOtherMpeg4Flex720p() { specific(otherMpeg4(), 1280, 720, true /* flex */); }
    public void testOtherMpeg4Surf720p() { specific(otherMpeg4(), 1280, 720, false /* flex */); }
    public void testOtherVP8Flex720p()   { specific(otherVP8(),   1280, 720, true /* flex */); }
    public void testOtherVP8Surf720p()   { specific(otherVP8(),   1280, 720, false /* flex */); }
    public void testOtherVP9Flex720p()   { specific(otherVP9(),   1280, 720, true /* flex */); }
    public void testOtherVP9Surf720p()   { specific(otherVP9(),   1280, 720, false /* flex */); }

    public void testGoogH265Flex1080p()   { specific(googH265(),   1920, 1080, true /* flex */); }
    public void testGoogH265Surf1080p()   { specific(googH265(),   1920, 1080, false /* flex */); }
    public void testGoogH264Flex1080p()   { specific(googH264(),   1920, 1080, true /* flex */); }
    public void testGoogH264Surf1080p()   { specific(googH264(),   1920, 1080, false /* flex */); }
    public void testGoogH263Flex1080p()   { specific(googH263(),   1920, 1080, true /* flex */); }
    public void testGoogH263Surf1080p()   { specific(googH263(),   1920, 1080, false /* flex */); }
    public void testGoogMpeg4Flex1080p()  { specific(googMpeg4(),  1920, 1080, true /* flex */); }
    public void testGoogMpeg4Surf1080p()  { specific(googMpeg4(),  1920, 1080, false /* flex */); }
    public void testGoogVP8Flex1080p()    { specific(googVP8(),    1920, 1080, true /* flex */); }
    public void testGoogVP8Surf1080p()    { specific(googVP8(),    1920, 1080, false /* flex */); }
    public void testGoogVP9Flex1080p()    { specific(googVP9(),    1920, 1080, true /* flex */); }
    public void testGoogVP9Surf1080p()    { specific(googVP9(),    1920, 1080, false /* flex */); }

    public void testOtherH265Flex1080p()  { specific(otherH265(),  1920, 1080, true /* flex */); }
    public void testOtherH265Surf1080p()  { specific(otherH265(),  1920, 1080, false /* flex */); }
    public void testOtherH264Flex1080p()  { specific(otherH264(),  1920, 1080, true /* flex */); }
    public void testOtherH264Surf1080p()  { specific(otherH264(),  1920, 1080, false /* flex */); }
    public void testOtherH263Flex1080p()  { specific(otherH263(),  1920, 1080, true /* flex */); }
    public void testOtherH263Surf1080p()  { specific(otherH263(),  1920, 1080, false /* flex */); }
    public void testOtherMpeg4Flex1080p() { specific(otherMpeg4(), 1920, 1080, true /* flex */); }
    public void testOtherMpeg4Surf1080p() { specific(otherMpeg4(), 1920, 1080, false /* flex */); }
    public void testOtherVP8Flex1080p()   { specific(otherVP8(),   1920, 1080, true /* flex */); }
    public void testOtherVP8Surf1080p()   { specific(otherVP8(),   1920, 1080, false /* flex */); }
    public void testOtherVP9Flex1080p()   { specific(otherVP9(),   1920, 1080, true /* flex */); }
    public void testOtherVP9Surf1080p()   { specific(otherVP9(),   1920, 1080, false /* flex */); }

    // Tests encoder profiles required by CDD.
    // H264
    public void testH264LowQualitySDSupport()   {
        support(h264(), 320, 240, 20, 384 * 1000);
    }

    public void testH264HighQualitySDSupport()   {
        support(h264(), 720, 480, 30, 2 * 1000000);
    }

    public void testH264FlexQVGA20fps384kbps()   {
        detailed(h264(), 320, 240, 20, 384 * 1000, true /* flex */);
    }

    public void testH264SurfQVGA20fps384kbps()   {
        detailed(h264(), 320, 240, 20, 384 * 1000, false /* flex */);
    }

    public void testH264Flex480p30fps2Mbps()   {
        detailed(h264(), 720, 480, 30, 2 * 1000000, true /* flex */);
    }

    public void testH264Surf480p30fps2Mbps()   {
        detailed(h264(), 720, 480, 30, 2 * 1000000, false /* flex */);
    }

    public void testH264Flex720p30fps4Mbps()   {
        detailed(h264(), 1280, 720, 30, 4 * 1000000, true /* flex */);
    }

    public void testH264Surf720p30fps4Mbps()   {
        detailed(h264(), 1280, 720, 30, 4 * 1000000, false /* flex */);
    }

    public void testH264Flex1080p30fps10Mbps()   {
        detailed(h264(), 1920, 1080, 30, 10 * 1000000, true /* flex */);
    }

    public void testH264Surf1080p30fps10Mbps()   {
        detailed(h264(), 1920, 1080, 30, 10 * 1000000, false /* flex */);
    }

    // VP8
    public void testVP8LowQualitySDSupport()   {
        support(vp8(), 320, 180, 30, 800 * 1000);
    }

    public void testVP8HighQualitySDSupport()   {
        support(vp8(), 640, 360, 30, 2 * 1000000);
    }

    public void testVP8Flex180p30fps800kbps()   {
        detailed(vp8(), 320, 180, 30, 800 * 1000, true /* flex */);
    }

    public void testVP8Surf180p30fps800kbps()   {
        detailed(vp8(), 320, 180, 30, 800 * 1000, false /* flex */);
    }

    public void testVP8Flex360p30fps2Mbps()   {
        detailed(vp8(), 640, 360, 30, 2 * 1000000, true /* flex */);
    }

    public void testVP8Surf360p30fps2Mbps()   {
        detailed(vp8(), 640, 360, 30, 2 * 1000000, false /* flex */);
    }

    public void testVP8Flex720p30fps4Mbps()   {
        detailed(vp8(), 1280, 720, 30, 4 * 1000000, true /* flex */);
    }

    public void testVP8Surf720p30fps4Mbps()   {
        detailed(vp8(), 1280, 720, 30, 4 * 1000000, false /* flex */);
    }

    public void testVP8Flex1080p30fps10Mbps()   {
        detailed(vp8(), 1920, 1080, 30, 10 * 1000000, true /* flex */);
    }

    public void testVP8Surf1080p30fps10Mbps()   {
        detailed(vp8(), 1920, 1080, 30, 10 * 1000000, false /* flex */);
    }

    private void minmin(Encoder[] encoders, boolean flexYUV) {
        extreme(encoders, 0 /* x */, 0 /* y */, flexYUV, false /* near */);
    }

    private void minmax(Encoder[] encoders, boolean flexYUV) {
        extreme(encoders, 0 /* x */, 1 /* y */, flexYUV, false /* near */);
    }

    private void maxmin(Encoder[] encoders, boolean flexYUV) {
        extreme(encoders, 1 /* x */, 0 /* y */, flexYUV, false /* near */);
    }

    private void maxmax(Encoder[] encoders, boolean flexYUV) {
        extreme(encoders, 1 /* x */, 1 /* y */, flexYUV, false /* near */);
    }

    private void nearminmin(Encoder[] encoders, boolean flexYUV) {
        extreme(encoders, 0 /* x */, 0 /* y */, flexYUV, true /* near */);
    }

    private void nearminmax(Encoder[] encoders, boolean flexYUV) {
        extreme(encoders, 0 /* x */, 1 /* y */, flexYUV, true /* near */);
    }

    private void nearmaxmin(Encoder[] encoders, boolean flexYUV) {
        extreme(encoders, 1 /* x */, 0 /* y */, flexYUV, true /* near */);
    }

    private void nearmaxmax(Encoder[] encoders, boolean flexYUV) {
        extreme(encoders, 1 /* x */, 1 /* y */, flexYUV, true /* near */);
    }

    private void extreme(Encoder[] encoders, int x, int y, boolean flexYUV, boolean near) {
        boolean skipped = true;
        if (encoders.length == 0) {
            MediaUtils.skipTest("no such encoder present");
            return;
        }
        for (Encoder encoder: encoders) {
            if (encoder.testExtreme(x, y, flexYUV, near)) {
                skipped = false;
            }
        }
        if (skipped) {
            MediaUtils.skipTest("duplicate resolution extreme");
        }
    }

    private void arbitrary(Encoder[] encoders, boolean flexYUV) {
        boolean skipped = true;
        if (encoders.length == 0) {
            MediaUtils.skipTest("no such encoder present");
            return;
        }
        for (Encoder encoder: encoders) {
            if (encoder.testArbitrary(flexYUV)) {
                skipped = false;
            }
        }
        if (skipped) {
            MediaUtils.skipTest("duplicate resolution");
        }
    }

    /* test specific size */
    private void specific(Encoder[] encoders, int width, int height, boolean flexYUV) {
        boolean skipped = true;
        if (encoders.length == 0) {
            MediaUtils.skipTest("no such encoder present");
            return;
        }
        for (Encoder encoder : encoders) {
            if (encoder.testSpecific(width, height, flexYUV)) {
                skipped = false;
            }
        }
        if (skipped) {
            MediaUtils.skipTest("duplicate or unsupported resolution");
        }
    }

    /* test size, frame rate and bit rate */
    private void detailed(
            Encoder[] encoders, int width, int height, int frameRate, int bitRate,
            boolean flexYUV) {
        if (encoders.length == 0) {
            MediaUtils.skipTest("no such encoder present");
            return;
        }
        boolean skipped = true;
        for (Encoder encoder : encoders) {
            if (encoder.testSupport(width, height, frameRate, bitRate)) {
                skipped = false;
                encoder.testDetailed(width, height, frameRate, bitRate, flexYUV);
            }
        }
        if (skipped) {
            MediaUtils.skipTest("unsupported resolution and rate");
        }
    }

    /* test size and rate are supported */
    private void support(Encoder[] encoders, int width, int height, int frameRate, int bitRate) {
        boolean supported = false;
        if (encoders.length == 0) {
            MediaUtils.skipTest("no such encoder present");
            return;
        }
        for (Encoder encoder : encoders) {
            if (encoder.testSupport(width, height, frameRate, bitRate)) {
                supported = true;
                break;
            }
        }
        if (!supported) {
            fail("unsupported format " + width + "x" + height + " " +
                    frameRate + "fps " + bitRate + "bps");
        }
    }
}
