diff --git a/tests/tests/media/libmediandkjni/Android.mk b/tests/tests/media/libmediandkjni/Android.mk
index 2d2033f..59ff7bb 100644
--- a/tests/tests/media/libmediandkjni/Android.mk
+++ b/tests/tests/media/libmediandkjni/Android.mk
@@ -20,7 +20,9 @@
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_SRC_FILES := native-media-jni.cpp
+LOCAL_SRC_FILES := \
+	native-media-jni.cpp \
+	codec-utils-jni.cpp
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 
diff --git a/tests/tests/media/libmediandkjni/codec-utils-jni.cpp b/tests/tests/media/libmediandkjni/codec-utils-jni.cpp
new file mode 100644
index 0000000..f99f1c8
--- /dev/null
+++ b/tests/tests/media/libmediandkjni/codec-utils-jni.cpp
@@ -0,0 +1,307 @@
+/*
+ * 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.
+ */
+
+/* Original code copied from NDK Native-media sample code */
+
+#undef NDEBUG
+//#define LOG_NDEBUG 0
+#include <stdint.h>
+#include <sys/types.h>
+#include <jni.h>
+
+#include <ScopedLocalRef.h>
+#include <JNIHelp.h>
+
+typedef ssize_t offs_t;
+
+// for __android_log_print(ANDROID_LOG_INFO, "YourApp", "formatted message");
+#include <android/log.h>
+#define TAG "CodecUtilsJNI"
+#define __ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
+#if LOG_NDEBUG
+#define ALOGV(...) do { if (0) { __ALOGV(__VA_ARGS__); } } while (0)
+#else
+#define ALOGV(...) __ALOGV(__VA_ARGS__)
+#endif
+#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
+#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
+#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__)
+#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
+
+struct NativeImage {
+    struct crop {
+        int left;
+        int top;
+        int right;
+        int bottom;
+    } crop;
+    struct plane {
+        const uint8_t *buffer;
+        size_t size;
+        ssize_t colInc;
+        ssize_t rowInc;
+        offs_t cropOffs;
+        size_t cropWidth;
+        size_t cropHeight;
+    } plane[3];
+    int width;
+    int height;
+    int format;
+    long timestamp;
+    size_t numPlanes;
+};
+
+struct ChecksumAlg {
+    virtual void init() = 0;
+    virtual void update(uint8_t c) = 0;
+    virtual uint32_t checksum() = 0;
+    virtual size_t length() = 0;
+protected:
+    virtual ~ChecksumAlg() {}
+};
+
+struct Adler32 : ChecksumAlg {
+    Adler32() {
+        init();
+    }
+    void init() {
+        a = 1;
+        len = b = 0;
+    }
+    void update(uint8_t c) {
+        a += c;
+        b += a;
+        ++len;
+    }
+    uint32_t checksum() {
+        return (a % 65521) + ((b % 65521) << 16);
+    }
+    size_t length() {
+        return len;
+    }
+private:
+    uint32_t a, b;
+    size_t len;
+};
+
+static struct ImageFieldsAndMethods {
+    // android.graphics.ImageFormat
+    int YUV_420_888;
+    // android.media.Image
+    jmethodID methodWidth;
+    jmethodID methodHeight;
+    jmethodID methodFormat;
+    jmethodID methodTimestamp;
+    jmethodID methodPlanes;
+    jmethodID methodCrop;
+    // android.media.Image.Plane
+    jmethodID methodBuffer;
+    jmethodID methodPixelStride;
+    jmethodID methodRowStride;
+    // android.graphics.Rect
+    jfieldID fieldLeft;
+    jfieldID fieldTop;
+    jfieldID fieldRight;
+    jfieldID fieldBottom;
+} gFields;
+static bool gFieldsInitialized = false;
+
+void initializeGlobalFields(JNIEnv *env) {
+    if (gFieldsInitialized) {
+        return;
+    }
+    {   // ImageFormat
+        jclass imageFormatClazz = env->FindClass("android/graphics/ImageFormat");
+        const jfieldID fieldYUV420888 = env->GetStaticFieldID(imageFormatClazz, "YUV_420_888", "I");
+        gFields.YUV_420_888 = env->GetStaticIntField(imageFormatClazz, fieldYUV420888);
+        env->DeleteLocalRef(imageFormatClazz);
+        imageFormatClazz = NULL;
+    }
+
+    {   // Image
+        jclass imageClazz = env->FindClass("android/media/Image");
+        gFields.methodWidth  = env->GetMethodID(imageClazz, "getWidth", "()I");
+        gFields.methodHeight = env->GetMethodID(imageClazz, "getHeight", "()I");
+        gFields.methodFormat = env->GetMethodID(imageClazz, "getFormat", "()I");
+        gFields.methodTimestamp = env->GetMethodID(imageClazz, "getTimestamp", "()J");
+        gFields.methodPlanes = env->GetMethodID(
+                imageClazz, "getPlanes", "()[Landroid/media/Image$Plane;");
+        gFields.methodCrop   = env->GetMethodID(
+                imageClazz, "getCropRect", "()Landroid/graphics/Rect;");
+        env->DeleteLocalRef(imageClazz);
+        imageClazz = NULL;
+    }
+
+    {   // Image.Plane
+        jclass planeClazz = env->FindClass("android/media/Image$Plane");
+        gFields.methodBuffer = env->GetMethodID(planeClazz, "getBuffer", "()Ljava/nio/ByteBuffer;");
+        gFields.methodPixelStride = env->GetMethodID(planeClazz, "getPixelStride", "()I");
+        gFields.methodRowStride = env->GetMethodID(planeClazz, "getRowStride", "()I");
+        env->DeleteLocalRef(planeClazz);
+        planeClazz = NULL;
+    }
+
+    {   // Rect
+        jclass rectClazz = env->FindClass("android/graphics/Rect");
+        gFields.fieldLeft   = env->GetFieldID(rectClazz, "left", "I");
+        gFields.fieldTop    = env->GetFieldID(rectClazz, "top", "I");
+        gFields.fieldRight  = env->GetFieldID(rectClazz, "right", "I");
+        gFields.fieldBottom = env->GetFieldID(rectClazz, "bottom", "I");
+        env->DeleteLocalRef(rectClazz);
+        rectClazz = NULL;
+    }
+    gFieldsInitialized = true;
+}
+
+NativeImage *getNativeImage(JNIEnv *env, jobject image) {
+    if (image == NULL) {
+        jniThrowNullPointerException(env, "image is null");
+        return NULL;
+    }
+
+    initializeGlobalFields(env);
+
+    NativeImage *img = new NativeImage;
+    img->format = env->CallIntMethod(image, gFields.methodFormat);
+    img->width  = env->CallIntMethod(image, gFields.methodWidth);
+    img->height = env->CallIntMethod(image, gFields.methodHeight);
+    img->timestamp = env->CallLongMethod(image, gFields.methodTimestamp);
+
+    jobject cropRect = env->CallObjectMethod(image, gFields.methodCrop);
+    img->crop.left   = env->GetIntField(cropRect, gFields.fieldLeft);
+    img->crop.top    = env->GetIntField(cropRect, gFields.fieldTop);
+    img->crop.right  = env->GetIntField(cropRect, gFields.fieldRight);
+    img->crop.bottom = env->GetIntField(cropRect, gFields.fieldBottom);
+    if (img->crop.right == 0 && img->crop.bottom == 0) {
+        img->crop.right  = img->width;
+        img->crop.bottom = img->height;
+    }
+    env->DeleteLocalRef(cropRect);
+    cropRect = NULL;
+
+    if (img->format != gFields.YUV_420_888) {
+        jniThrowException(
+                env, "java/lang/UnsupportedOperationException",
+                "only support YUV_420_888 images");
+        delete img;
+        img = NULL;
+        return NULL;
+    }
+    img->numPlanes = 3;
+
+    ScopedLocalRef<jobjectArray> planesArray(
+            env, (jobjectArray)env->CallObjectMethod(image, gFields.methodPlanes));
+    int xDecim = 0;
+    int yDecim = 0;
+    for (size_t ix = 0; ix < img->numPlanes; ++ix) {
+        ScopedLocalRef<jobject> plane(
+                env, env->GetObjectArrayElement(planesArray.get(), (jsize)ix));
+        img->plane[ix].colInc = env->CallIntMethod(plane.get(), gFields.methodPixelStride);
+        img->plane[ix].rowInc = env->CallIntMethod(plane.get(), gFields.methodRowStride);
+        ScopedLocalRef<jobject> buffer(
+                env, env->CallObjectMethod(plane.get(), gFields.methodBuffer));
+
+        img->plane[ix].buffer = (const uint8_t *)env->GetDirectBufferAddress(buffer.get());
+        img->plane[ix].size = env->GetDirectBufferCapacity(buffer.get());
+
+        img->plane[ix].cropOffs =
+            (img->crop.left >> xDecim) * img->plane[ix].colInc
+                    + (img->crop.top >> yDecim) * img->plane[ix].rowInc;
+        img->plane[ix].cropHeight =
+            ((img->crop.bottom + (1 << yDecim) - 1) >> yDecim) - (img->crop.top >> yDecim);
+        img->plane[ix].cropWidth =
+            ((img->crop.right + (1 << xDecim) - 1) >> xDecim) - (img->crop.left >> xDecim);
+
+        // sanity check on increments
+        ssize_t widthOffs =
+            (((img->width + (1 << xDecim) - 1) >> xDecim) - 1) * img->plane[ix].colInc;
+        ssize_t heightOffs =
+            (((img->height + (1 << yDecim) - 1) >> yDecim) - 1) * img->plane[ix].rowInc;
+        if (widthOffs < 0 || heightOffs < 0
+                || widthOffs + heightOffs >= (ssize_t)img->plane[ix].size) {
+            jniThrowException(
+                    env, "java/lang/IndexOutOfBoundsException", "plane exceeds bytearray");
+            delete img;
+            img = NULL;
+            return NULL;
+        }
+        xDecim = yDecim = 1;
+    }
+    return img;
+}
+
+extern "C" jint Java_android_media_cts_CodecUtils_getImageChecksum(JNIEnv *env,
+        jclass /*clazz*/, jobject image)
+{
+    NativeImage *img = getNativeImage(env, image);
+    if (img == NULL) {
+        return 0;
+    }
+
+    Adler32 adler;
+    for (size_t ix = 0; ix < img->numPlanes; ++ix) {
+        const uint8_t *row = img->plane[ix].buffer + img->plane[ix].cropOffs;
+        for (size_t y = img->plane[ix].cropHeight; y > 0; --y) {
+            const uint8_t *col = row;
+            ssize_t colInc = img->plane[ix].colInc;
+            for (size_t x = img->plane[ix].cropWidth; x > 0; --x) {
+                adler.update(*col);
+                col += colInc;
+            }
+            row += img->plane[ix].rowInc;
+        }
+    }
+    ALOGV("adler %zu/%u", adler.length(), adler.checksum());
+    return adler.checksum();
+}
+
+/* tiled copy that loops around source image boundary */
+extern "C" void Java_android_media_cts_CodecUtils_copyFlexYUVImage(JNIEnv *env,
+        jclass /*clazz*/, jobject target, jobject source)
+{
+    NativeImage *tgt = getNativeImage(env, target);
+    NativeImage *src = getNativeImage(env, source);
+    if (tgt != NULL && src != NULL) {
+        ALOGV("copyFlexYUVImage %dx%d (%d,%d..%d,%d) (%zux%zu) %+zd%+zd %+zd%+zd %+zd%+zd <= "
+                "%dx%d (%d, %d..%d, %d) (%zux%zu) %+zd%+zd %+zd%+zd %+zd%+zd",
+                tgt->width, tgt->height,
+                tgt->crop.left, tgt->crop.top, tgt->crop.right, tgt->crop.bottom,
+                tgt->plane[0].cropWidth, tgt->plane[0].cropHeight,
+                tgt->plane[0].rowInc, tgt->plane[0].colInc,
+                tgt->plane[1].rowInc, tgt->plane[1].colInc,
+                tgt->plane[2].rowInc, tgt->plane[2].colInc,
+                src->width, src->height,
+                src->crop.left, src->crop.top, src->crop.right, src->crop.bottom,
+                src->plane[0].cropWidth, src->plane[0].cropHeight,
+                src->plane[0].rowInc, src->plane[0].colInc,
+                src->plane[1].rowInc, src->plane[1].colInc,
+                src->plane[2].rowInc, src->plane[2].colInc);
+        for (size_t ix = 0; ix < tgt->numPlanes; ++ix) {
+            uint8_t *row = const_cast<uint8_t *>(tgt->plane[ix].buffer) + tgt->plane[ix].cropOffs;
+            for (size_t y = 0; y < tgt->plane[ix].cropHeight; ++y) {
+                uint8_t *col = row;
+                ssize_t colInc = tgt->plane[ix].colInc;
+                const uint8_t *srcRow = (src->plane[ix].buffer + src->plane[ix].cropOffs
+                        + src->plane[ix].rowInc * (y % src->plane[ix].cropHeight));
+                for (size_t x = 0; x < tgt->plane[ix].cropWidth; ++x) {
+                    *col = srcRow[src->plane[ix].colInc * (x % src->plane[ix].cropWidth)];
+                    col += colInc;
+                }
+                row += tgt->plane[ix].rowInc;
+            }
+        }
+    }
+}
diff --git a/tests/tests/media/res/raw/video_480x360_mp4_h264_871kbps_30fps.mp4 b/tests/tests/media/res/raw/video_480x360_mp4_h264_871kbps_30fps.mp4
new file mode 100644
index 0000000..55a83e7
--- /dev/null
+++ b/tests/tests/media/res/raw/video_480x360_mp4_h264_871kbps_30fps.mp4
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/CodecUtils.java b/tests/tests/media/src/android/media/cts/CodecUtils.java
new file mode 100644
index 0000000..3c3576f
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/CodecUtils.java
@@ -0,0 +1,35 @@
+/*
+ * 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 android.media.Image;
+import android.util.Log;
+
+public class CodecUtils  {
+    private static final String TAG = "CodecUtils";
+
+    /** Load jni on initialization */
+    static {
+        Log.i(TAG, "before loadlibrary");
+        System.loadLibrary("ctsmediacodec_jni");
+        Log.i(TAG, "after loadlibrary");
+    }
+
+    public native static int getImageChecksum(Image image);
+    public native static void copyFlexYUVImage(Image target, Image source);
+}
+
diff --git a/tests/tests/media/src/android/media/cts/OutputSurface.java b/tests/tests/media/src/android/media/cts/OutputSurface.java
index fc8ad9c..c87326d 100644
--- a/tests/tests/media/src/android/media/cts/OutputSurface.java
+++ b/tests/tests/media/src/android/media/cts/OutputSurface.java
@@ -70,7 +70,7 @@
         eglSetup(width, height);
         makeCurrent();
 
-        setup();
+        setup(this);
     }
 
     /**
@@ -78,14 +78,18 @@
      * new one).  Creates a Surface that can be passed to MediaCodec.configure().
      */
     public OutputSurface() {
-        setup();
+        setup(this);
+    }
+
+    public OutputSurface(final SurfaceTexture.OnFrameAvailableListener listener) {
+        setup(listener);
     }
 
     /**
      * Creates instances of TextureRender and SurfaceTexture, and a Surface associated
      * with the SurfaceTexture.
      */
-    private void setup() {
+    private void setup(SurfaceTexture.OnFrameAvailableListener listener) {
         mTextureRender = new TextureRender();
         mTextureRender.surfaceCreated();
 
@@ -107,7 +111,7 @@
         //
         // Java language note: passing "this" out of a constructor is generally unwise,
         // but we should be able to get away with it here.
-        mSurfaceTexture.setOnFrameAvailableListener(this);
+        mSurfaceTexture.setOnFrameAvailableListener(listener);
 
         mSurface = new Surface(mSurfaceTexture);
     }
@@ -285,6 +289,11 @@
         mTextureRender.drawFrame(mSurfaceTexture);
     }
 
+    public void latchImage() {
+        mTextureRender.checkGlError("before updateTexImage");
+        mSurfaceTexture.updateTexImage();
+    }
+
     @Override
     public void onFrameAvailable(SurfaceTexture st) {
         if (VERBOSE) Log.d(TAG, "new frame available");
diff --git a/tests/tests/media/src/android/media/cts/VideoEncoderTest.java b/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
new file mode 100644
index 0000000..f78f5f8
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
@@ -0,0 +1,1247 @@
+/*
+ * 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 java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+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;
+
+    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;
+
+        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;
+                }
+            }
+            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);
+
+            MediaCodecInfo.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 maxRate =
+                    encCaps.getSupportedFrameRatesFor(maxWidth, maxHeight).getUpper().intValue();
+                outFmt.setInteger(MediaFormat.KEY_FRAME_RATE, Math.min(30, maxRate));
+                int bitRate = encCaps.getBitrateRange().clamp(
+                        (int)(encCaps.getBitrateRange().getUpper() /
+                                Math.sqrt(maxWidth * maxHeight / width / height)));
+                Log.d(TAG, "max rate = " + maxRate + ", bit rate = " + bitRate);
+                outFmt.setInteger(MediaFormat.KEY_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 + ")");
+            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
+                    }
+                }
+            }
+        }
+
+        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);
+        }
+
+        // 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);
+        }
+    }
+
+    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);
+        }
+
+        private boolean test(int width, int height, 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();
+
+            // We are using a resource URL as an example
+            return processor.processLoop(
+                    SOURCE_URL, mMime, mName, width, height, optional);
+        }
+
+    }
+
+    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[] 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 */); }
+
+    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");
+        }
+    }
+}
