diff --git a/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java b/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
new file mode 100644
index 0000000..db6ce30
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
@@ -0,0 +1,1103 @@
+/*
+ * Copyright (C) 2013 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.annotation.TargetApi;
+import android.content.res.AssetFileDescriptor;
+import android.media.MediaCodec;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecList;
+import android.media.MediaExtractor;
+import android.media.MediaFormat;
+import android.media.MediaMuxer;
+import android.os.Environment;
+import android.test.AndroidTestCase;
+import android.util.Log;
+import android.view.Surface;
+
+import com.android.cts.media.R;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Test for the integration of MediaMuxer and MediaCodec's encoder.
+ *
+ * <p>It uses MediaExtractor to get frames from a test stream, decodes them to a surface, uses a
+ * shader to edit them, encodes them from the resulting surface, and then uses MediaMuxer to write
+ * them into a file.
+ *
+ * <p>It does not currently check whether the result file is correct, but makes sure that nothing
+ * fails along the way.
+ *
+ * <p>It also tests the way the codec config buffers need to be passed from the MediaCodec to the
+ * MediaMuxer.
+ */
+@TargetApi(18)
+public class ExtractDecodeEditEncodeMuxTest extends AndroidTestCase {
+
+    private static final String TAG = ExtractDecodeEditEncodeMuxTest.class.getSimpleName();
+    private static final boolean VERBOSE = false; // lots of logging
+
+    /** How long to wait for the next buffer to become available. */
+    private static final int TIMEOUT_USEC = 10000;
+
+    /** Where to output the test files. */
+    private static final File OUTPUT_FILENAME_DIR = Environment.getExternalStorageDirectory();
+
+    // parameters for the video encoder
+    private static final String OUTPUT_VIDEO_MIME_TYPE = "video/avc"; // H.264 Advanced Video Coding
+    private static final int OUTPUT_VIDEO_BIT_RATE = 2000000; // 2Mbps
+    private static final int OUTPUT_VIDEO_FRAME_RATE = 15; // 15fps
+    private static final int OUTPUT_VIDEO_IFRAME_INTERVAL = 10; // 10 seconds between I-frames
+    private static final int OUTPUT_VIDEO_COLOR_FORMAT =
+            MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
+
+    // parameters for the audio encoder
+    private static final String OUTPUT_AUDIO_MIME_TYPE = "audio/mp4a-latm"; // Advanced Audio Coding
+    private static final int OUTPUT_AUDIO_CHANNEL_COUNT = 2; // Must match the input stream.
+    private static final int OUTPUT_AUDIO_BIT_RATE = 128 * 1024;
+    private static final int OUTPUT_AUDIO_AAC_PROFILE =
+            MediaCodecInfo.CodecProfileLevel.AACObjectHE;
+    private static final int OUTPUT_AUDIO_SAMPLE_RATE_HZ = 44100; // Must match the input stream.
+
+    /**
+     * Used for editing the frames.
+     *
+     * <p>Swaps green and blue channels by storing an RBGA color in an RGBA buffer.
+     */
+    private static final String FRAGMENT_SHADER =
+            "#extension GL_OES_EGL_image_external : require\n" +
+            "precision mediump float;\n" +
+            "varying vec2 vTextureCoord;\n" +
+            "uniform samplerExternalOES sTexture;\n" +
+            "void main() {\n" +
+            "  gl_FragColor = texture2D(sTexture, vTextureCoord).rbga;\n" +
+            "}\n";
+
+    /** Whether to copy the video from the test video. */
+    private boolean mCopyVideo;
+    /** Whether to copy the audio from the test video. */
+    private boolean mCopyAudio;
+    /** Width of the output frames. */
+    private int mWidth = -1;
+    /** Height of the output frames. */
+    private int mHeight = -1;
+
+    /** The raw resource used as the input file. */
+    private int mSourceResId;
+
+    /** The destination file for the encoded output. */
+    private String mOutputFile;
+
+    public void testExtractDecodeEditEncodeMuxQCIF() throws Throwable {
+        setSize(176, 144);
+        setSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
+        setCopyVideo();
+        TestWrapper.runTest(this);
+    }
+
+    public void testExtractDecodeEditEncodeMuxQVGA() throws Throwable {
+        setSize(320, 240);
+        setSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
+        setCopyVideo();
+        TestWrapper.runTest(this);
+    }
+
+    public void testExtractDecodeEditEncodeMux720p() throws Throwable {
+        setSize(1280, 720);
+        setSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
+        setCopyVideo();
+        TestWrapper.runTest(this);
+    }
+
+    public void testExtractDecodeEditEncodeMuxAudio() throws Throwable {
+        setSize(1280, 720);
+        setSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
+        setCopyAudio();
+        TestWrapper.runTest(this);
+    }
+
+    public void testExtractDecodeEditEncodeMuxAudioVideo() throws Throwable {
+        setSize(1280, 720);
+        setSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
+        setCopyAudio();
+        setCopyVideo();
+        TestWrapper.runTest(this);
+    }
+
+    /** Wraps testExtractDecodeEditEncodeMux() */
+    private static class TestWrapper implements Runnable {
+        private Throwable mThrowable;
+        private ExtractDecodeEditEncodeMuxTest mTest;
+
+        private TestWrapper(ExtractDecodeEditEncodeMuxTest test) {
+            mTest = test;
+        }
+
+        @Override
+        public void run() {
+            try {
+                mTest.extractDecodeEditEncodeMux();
+            } catch (Throwable th) {
+                mThrowable = th;
+            }
+        }
+
+        /**
+         * Entry point.
+         */
+        public static void runTest(ExtractDecodeEditEncodeMuxTest test) throws Throwable {
+            test.setOutputFile();
+            TestWrapper wrapper = new TestWrapper(test);
+            Thread th = new Thread(wrapper, "codec test");
+            th.start();
+            th.join();
+            if (wrapper.mThrowable != null) {
+                throw wrapper.mThrowable;
+            }
+        }
+    }
+
+    /**
+     * Sets the test to copy the video stream.
+     */
+    private void setCopyVideo() {
+        mCopyVideo = true;
+    }
+
+    /**
+     * Sets the test to copy the video stream.
+     */
+    private void setCopyAudio() {
+        mCopyAudio = true;
+    }
+
+    /**
+     * Sets the desired frame size.
+     */
+    private void setSize(int width, int height) {
+        if ((width % 16) != 0 || (height % 16) != 0) {
+            Log.w(TAG, "WARNING: width or height not multiple of 16");
+        }
+        mWidth = width;
+        mHeight = height;
+    }
+
+    /**
+     * Sets the raw resource used as the source video.
+     */
+    private void setSource(int resId) {
+        mSourceResId = resId;
+    }
+
+    /**
+     * Sets the name of the output file based on the other parameters.
+     *
+     * <p>Must be called after {@link #setSize(int, int)} and {@link #setSource(int)}.
+     */
+    private void setOutputFile() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(OUTPUT_FILENAME_DIR.getAbsolutePath());
+        sb.append("/cts-media-");
+        sb.append(getClass().getSimpleName());
+        assertTrue("should have called setSource() first", mSourceResId != -1);
+        sb.append('-');
+        sb.append(mSourceResId);
+        if (mCopyVideo) {
+            assertTrue("should have called setSize() first", mWidth != -1);
+            assertTrue("should have called setSize() first", mHeight != -1);
+            sb.append('-');
+            sb.append("video");
+            sb.append('-');
+            sb.append(mWidth);
+            sb.append('x');
+            sb.append(mHeight);
+        }
+        if (mCopyAudio) {
+            sb.append('-');
+            sb.append("audio");
+        }
+        sb.append(".mp4");
+        mOutputFile = sb.toString();
+    }
+
+    /**
+     * Tests encoding and subsequently decoding video from frames generated into a buffer.
+     * <p>
+     * We encode several frames of a video test pattern using MediaCodec, then decode the output
+     * with MediaCodec and do some simple checks.
+     */
+    private void extractDecodeEditEncodeMux() throws Exception {
+        // Exception that may be thrown during release.
+        Exception exception = null;
+
+        MediaCodecInfo videoCodecInfo = selectCodec(OUTPUT_VIDEO_MIME_TYPE);
+        if (videoCodecInfo == null) {
+            // Don't fail CTS if they don't have an AVC codec (not here, anyway).
+            Log.e(TAG, "Unable to find an appropriate codec for " + OUTPUT_VIDEO_MIME_TYPE);
+            return;
+        }
+        if (VERBOSE) Log.d(TAG, "video found codec: " + videoCodecInfo.getName());
+
+        MediaCodecInfo audioCodecInfo = selectCodec(OUTPUT_AUDIO_MIME_TYPE);
+        if (audioCodecInfo == null) {
+            // Don't fail CTS if they don't have an AAC codec (not here, anyway).
+            Log.e(TAG, "Unable to find an appropriate codec for " + OUTPUT_AUDIO_MIME_TYPE);
+            return;
+        }
+        if (VERBOSE) Log.d(TAG, "audio found codec: " + audioCodecInfo.getName());
+
+        MediaExtractor videoExtractor = null;
+        MediaExtractor audioExtractor = null;
+        OutputSurface outputSurface = null;
+        MediaCodec videoDecoder = null;
+        MediaCodec audioDecoder = null;
+        MediaCodec videoEncoder = null;
+        MediaCodec audioEncoder = null;
+        MediaMuxer muxer = null;
+
+        InputSurface inputSurface = null;
+
+        try {
+            if (mCopyVideo) {
+                videoExtractor = createExtractor();
+                int videoInputTrack = getAndSelectVideoTrackIndex(videoExtractor);
+                assertTrue("missing video track in test video", videoInputTrack != -1);
+                MediaFormat inputFormat = videoExtractor.getTrackFormat(videoInputTrack);
+
+                // We avoid the device-specific limitations on width and height by using values
+                // that are multiples of 16, which all tested devices seem to be able to handle.
+                MediaFormat outputVideoFormat =
+                        MediaFormat.createVideoFormat(OUTPUT_VIDEO_MIME_TYPE, mWidth, mHeight);
+
+                // Set some properties. Failing to specify some of these can cause the MediaCodec
+                // configure() call to throw an unhelpful exception.
+                outputVideoFormat.setInteger(
+                        MediaFormat.KEY_COLOR_FORMAT, OUTPUT_VIDEO_COLOR_FORMAT);
+                outputVideoFormat.setInteger(MediaFormat.KEY_BIT_RATE, OUTPUT_VIDEO_BIT_RATE);
+                outputVideoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, OUTPUT_VIDEO_FRAME_RATE);
+                outputVideoFormat.setInteger(
+                        MediaFormat.KEY_I_FRAME_INTERVAL, OUTPUT_VIDEO_IFRAME_INTERVAL);
+                if (VERBOSE) Log.d(TAG, "video format: " + outputVideoFormat);
+
+                // Create a MediaCodec for the desired codec, then configure it as an encoder with
+                // our desired properties. Request a Surface to use for input.
+                AtomicReference<Surface> inputSurfaceReference = new AtomicReference<Surface>();
+                videoEncoder = createVideoEncoder(
+                        videoCodecInfo, outputVideoFormat, inputSurfaceReference);
+                inputSurface = new InputSurface(inputSurfaceReference.get());
+                inputSurface.makeCurrent();
+                // Create a MediaCodec for the decoder, based on the extractor's format.
+                outputSurface = new OutputSurface();
+                outputSurface.changeFragmentShader(FRAGMENT_SHADER);
+                videoDecoder = createVideoDecoder(inputFormat, outputSurface.getSurface());
+            }
+
+            if (mCopyAudio) {
+                audioExtractor = createExtractor();
+                int audioInputTrack = getAndSelectAudioTrackIndex(audioExtractor);
+                assertTrue("missing audio track in test video", audioInputTrack != -1);
+                MediaFormat inputFormat = audioExtractor.getTrackFormat(audioInputTrack);
+
+                MediaFormat outputAudioFormat =
+                        MediaFormat.createAudioFormat(
+                                OUTPUT_AUDIO_MIME_TYPE, OUTPUT_AUDIO_SAMPLE_RATE_HZ,
+                                OUTPUT_AUDIO_CHANNEL_COUNT);
+                outputAudioFormat.setInteger(MediaFormat.KEY_BIT_RATE, OUTPUT_AUDIO_BIT_RATE);
+                outputAudioFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, OUTPUT_AUDIO_AAC_PROFILE);
+
+                // Create a MediaCodec for the desired codec, then configure it as an encoder with
+                // our desired properties. Request a Surface to use for input.
+                audioEncoder = createAudioEncoder(audioCodecInfo, outputAudioFormat);
+                // Create a MediaCodec for the decoder, based on the extractor's format.
+                audioDecoder = createAudioDecoder(inputFormat);
+            }
+
+            // Creates a muxer but do not start or add tracks just yet.
+            muxer = createMuxer();
+
+            doExtractDecodeEditEncodeMux(
+                    videoExtractor,
+                    audioExtractor,
+                    videoDecoder,
+                    videoEncoder,
+                    audioDecoder,
+                    audioEncoder,
+                    muxer,
+                    inputSurface,
+                    outputSurface);
+        } finally {
+            if (VERBOSE) Log.d(TAG, "releasing extractor, decoder, encoder, and muxer");
+            // Try to release everything we acquired, even if one of the releases fails, in which
+            // case we save the first exception we got and re-throw at the end (unless something
+            // other exception has already been thrown). This guarantees the first exception thrown
+            // is reported as the cause of the error, everything is (attempted) to be released, and
+            // all other exceptions appear in the logs.
+            try {
+                if (videoExtractor != null) {
+                    videoExtractor.release();
+                }
+            } catch(Exception e) {
+                Log.e(TAG, "error while releasing videoExtractor", e);
+                if (exception == null) {
+                    exception = e;
+                }
+            }
+            try {
+                if (audioExtractor != null) {
+                    audioExtractor.release();
+                }
+            } catch(Exception e) {
+                Log.e(TAG, "error while releasing audioExtractor", e);
+                if (exception == null) {
+                    exception = e;
+                }
+            }
+            try {
+                if (videoDecoder != null) {
+                    videoDecoder.stop();
+                    videoDecoder.release();
+                }
+            } catch(Exception e) {
+                Log.e(TAG, "error while releasing videoDecoder", e);
+                if (exception == null) {
+                    exception = e;
+                }
+            }
+            try {
+                if (outputSurface != null) {
+                    outputSurface.release();
+                }
+            } catch(Exception e) {
+                Log.e(TAG, "error while releasing outputSurface", e);
+                if (exception == null) {
+                    exception = e;
+                }
+            }
+            try {
+                if (videoEncoder != null) {
+                    videoEncoder.stop();
+                    videoEncoder.release();
+                }
+            } catch(Exception e) {
+                Log.e(TAG, "error while releasing videoEncoder", e);
+                if (exception == null) {
+                    exception = e;
+                }
+            }
+            try {
+                if (audioDecoder != null) {
+                    audioDecoder.stop();
+                    audioDecoder.release();
+                }
+            } catch(Exception e) {
+                Log.e(TAG, "error while releasing audioDecoder", e);
+                if (exception == null) {
+                    exception = e;
+                }
+            }
+            try {
+                if (audioEncoder != null) {
+                    audioEncoder.stop();
+                    audioEncoder.release();
+                }
+            } catch(Exception e) {
+                Log.e(TAG, "error while releasing audioEncoder", e);
+                if (exception == null) {
+                    exception = e;
+                }
+            }
+            try {
+                if (muxer != null) {
+                    muxer.stop();
+                    muxer.release();
+                }
+            } catch(Exception e) {
+                Log.e(TAG, "error while releasing muxer", e);
+                if (exception == null) {
+                    exception = e;
+                }
+            }
+            try {
+                if (inputSurface != null) {
+                    inputSurface.release();
+                }
+            } catch(Exception e) {
+                Log.e(TAG, "error while releasing inputSurface", e);
+                if (exception == null) {
+                    exception = e;
+                }
+            }
+        }
+        if (exception != null) {
+            throw exception;
+        }
+    }
+
+    /**
+     * Creates an extractor that reads its frames from {@link #mSourceResId}.
+     */
+    private MediaExtractor createExtractor() throws IOException {
+        MediaExtractor extractor;
+        AssetFileDescriptor srcFd = getContext().getResources().openRawResourceFd(mSourceResId);
+        extractor = new MediaExtractor();
+        extractor.setDataSource(srcFd.getFileDescriptor(), srcFd.getStartOffset(),
+                srcFd.getLength());
+        return extractor;
+    }
+
+    /**
+     * Creates a decoder for the given format, which outputs to the given surface.
+     *
+     * @param inputFormat the format of the stream to decode
+     * @param surface into which to decode the frames
+     */
+    private MediaCodec createVideoDecoder(MediaFormat inputFormat, Surface surface) {
+        MediaCodec decoder = MediaCodec.createDecoderByType(getMimeTypeFor(inputFormat));
+        decoder.configure(inputFormat, surface, null, 0);
+        decoder.start();
+        return decoder;
+    }
+
+    /**
+     * Creates an encoder for the given format using the specified codec, taking input from a
+     * surface.
+     *
+     * <p>The surface to use as input is stored in the given reference.
+     *
+     * @param codecInfo of the codec to use
+     * @param format of the stream to be produced
+     * @param surfaceReference to store the surface to use as input
+     */
+    private MediaCodec createVideoEncoder(
+            MediaCodecInfo codecInfo,
+            MediaFormat format,
+            AtomicReference<Surface> surfaceReference) {
+        MediaCodec encoder = MediaCodec.createByCodecName(codecInfo.getName());
+        encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
+        // Must be called before start() is.
+        surfaceReference.set(encoder.createInputSurface());
+        encoder.start();
+        return encoder;
+    }
+
+    /**
+     * Creates a decoder for the given format.
+     *
+     * @param inputFormat the format of the stream to decode
+     */
+    private MediaCodec createAudioDecoder(MediaFormat inputFormat) {
+        MediaCodec decoder = MediaCodec.createDecoderByType(getMimeTypeFor(inputFormat));
+        decoder.configure(inputFormat, null, null, 0);
+        decoder.start();
+        return decoder;
+    }
+
+    /**
+     * Creates an encoder for the given format using the specified codec.
+     *
+     * @param codecInfo of the codec to use
+     * @param format of the stream to be produced
+     */
+    private MediaCodec createAudioEncoder(MediaCodecInfo codecInfo, MediaFormat format) {
+        MediaCodec encoder = MediaCodec.createByCodecName(codecInfo.getName());
+        encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
+        encoder.start();
+        return encoder;
+    }
+
+    /**
+     * Creates a muxer to write the encoded frames.
+     *
+     * <p>The muxer is not started as it needs to be started only after all streams have been added.
+     */
+    private MediaMuxer createMuxer() throws IOException {
+        return new MediaMuxer(mOutputFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
+    }
+
+    private int getAndSelectVideoTrackIndex(MediaExtractor extractor) {
+        for (int index = 0; index < extractor.getTrackCount(); ++index) {
+            if (VERBOSE) {
+                Log.d(TAG, "format for track " + index + " is "
+                        + getMimeTypeFor(extractor.getTrackFormat(index)));
+            }
+            if (isVideoFormat(extractor.getTrackFormat(index))) {
+                extractor.selectTrack(index);
+                return index;
+            }
+        }
+        return -1;
+    }
+
+    private int getAndSelectAudioTrackIndex(MediaExtractor extractor) {
+        for (int index = 0; index < extractor.getTrackCount(); ++index) {
+            if (VERBOSE) {
+                Log.d(TAG, "format for track " + index + " is "
+                        + getMimeTypeFor(extractor.getTrackFormat(index)));
+            }
+            if (isAudioFormat(extractor.getTrackFormat(index))) {
+                extractor.selectTrack(index);
+                return index;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Does the actual work for extracting, decoding, encoding and muxing.
+     */
+    private void doExtractDecodeEditEncodeMux(
+            MediaExtractor videoExtractor,
+            MediaExtractor audioExtractor,
+            MediaCodec videoDecoder,
+            MediaCodec videoEncoder,
+            MediaCodec audioDecoder,
+            MediaCodec audioEncoder,
+            MediaMuxer muxer,
+            InputSurface inputSurface,
+            OutputSurface outputSurface) {
+        ByteBuffer[] videoDecoderInputBuffers = null;
+        ByteBuffer[] videoDecoderOutputBuffers = null;
+        ByteBuffer[] videoEncoderOutputBuffers = null;
+        MediaCodec.BufferInfo videoDecoderOutputBufferInfo = null;
+        MediaCodec.BufferInfo videoEncoderOutputBufferInfo = null;
+        if (mCopyVideo) {
+            videoDecoderInputBuffers = videoDecoder.getInputBuffers();
+            videoDecoderOutputBuffers = videoDecoder.getOutputBuffers();
+            videoEncoderOutputBuffers = videoEncoder.getOutputBuffers();
+            videoDecoderOutputBufferInfo = new MediaCodec.BufferInfo();
+            videoEncoderOutputBufferInfo = new MediaCodec.BufferInfo();
+        }
+        ByteBuffer[] audioDecoderInputBuffers = null;
+        ByteBuffer[] audioDecoderOutputBuffers = null;
+        ByteBuffer[] audioEncoderInputBuffers = null;
+        ByteBuffer[] audioEncoderOutputBuffers = null;
+        MediaCodec.BufferInfo audioDecoderOutputBufferInfo = null;
+        MediaCodec.BufferInfo audioEncoderOutputBufferInfo = null;
+        if (mCopyAudio) {
+            audioDecoderInputBuffers = audioDecoder.getInputBuffers();
+            audioDecoderOutputBuffers =  audioDecoder.getOutputBuffers();
+            audioEncoderInputBuffers = audioEncoder.getInputBuffers();
+            audioEncoderOutputBuffers = audioEncoder.getOutputBuffers();
+            audioDecoderOutputBufferInfo = new MediaCodec.BufferInfo();
+            audioEncoderOutputBufferInfo = new MediaCodec.BufferInfo();
+        }
+        // We will get these from the decoders when notified of a format change.
+        MediaFormat decoderOutputVideoFormat = null;
+        MediaFormat decoderOutputAudioFormat = null;
+        // We will get these from the encoders when notified of a format change.
+        MediaFormat encoderOutputVideoFormat = null;
+        MediaFormat encoderOutputAudioFormat = null;
+        // We will determine these once we have the output format.
+        int outputVideoTrack = -1;
+        int outputAudioTrack = -1;
+        // Whether things are done on the video side.
+        boolean videoExtractorDone = false;
+        boolean videoDecoderDone = false;
+        boolean videoEncoderDone = false;
+        // Whether things are done on the audio side.
+        boolean audioExtractorDone = false;
+        boolean audioDecoderDone = false;
+        boolean audioEncoderDone = false;
+        // The audio decoder output buffer to process, -1 if none.
+        int pendingAudioDecoderOutputBufferIndex = -1;
+
+        boolean muxing = false;
+
+        int videoExtractedFrameCount = 0;
+        int videoDecodedFrameCount = 0;
+        int videoEncodedFrameCount = 0;
+
+        int audioExtractedFrameCount = 0;
+        int audioDecodedFrameCount = 0;
+        int audioEncodedFrameCount = 0;
+
+        while ((mCopyVideo && !videoEncoderDone) || (mCopyAudio && !audioEncoderDone)) {
+            if (VERBOSE) {
+                Log.d(TAG, String.format(
+                        "loop: "
+
+                        + "V(%b){"
+                        + "extracted:%d(done:%b) "
+                        + "decoded:%d(done:%b) "
+                        + "encoded:%d(done:%b)} "
+
+                        + "A(%b){"
+                        + "extracted:%d(done:%b) "
+                        + "decoded:%d(done:%b) "
+                        + "encoded:%d(done:%b) "
+                        + "pending:%d} "
+
+                        + "muxing:%b(V:%d,A:%d)",
+
+                        mCopyVideo,
+                        videoExtractedFrameCount, videoExtractorDone,
+                        videoDecodedFrameCount, videoDecoderDone,
+                        videoEncodedFrameCount, videoEncoderDone,
+
+                        mCopyAudio,
+                        audioExtractedFrameCount, audioExtractorDone,
+                        audioDecodedFrameCount, audioDecoderDone,
+                        audioEncodedFrameCount, audioEncoderDone,
+                        pendingAudioDecoderOutputBufferIndex,
+
+                        muxing, outputVideoTrack, outputAudioTrack));
+            }
+
+            // Extract video from file and feed to decoder.
+            // Do not extract video if we have determined the output format but we are not yet
+            // ready to mux the frames.
+            while (mCopyVideo && !videoExtractorDone
+                    && (encoderOutputVideoFormat == null || muxing)) {
+                int decoderInputBufferIndex = videoDecoder.dequeueInputBuffer(TIMEOUT_USEC);
+                if (decoderInputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
+                    if (VERBOSE) Log.d(TAG, "no video decoder input buffer");
+                    break;
+                }
+                if (VERBOSE) {
+                    Log.d(TAG, "video decoder: returned input buffer: " + decoderInputBufferIndex);
+                }
+                ByteBuffer decoderInputBuffer = videoDecoderInputBuffers[decoderInputBufferIndex];
+                int size = videoExtractor.readSampleData(decoderInputBuffer, 0);
+                long presentationTime = videoExtractor.getSampleTime();
+                if (VERBOSE) {
+                    Log.d(TAG, "video extractor: returned buffer of size " + size);
+                    Log.d(TAG, "video extractor: returned buffer for time " + presentationTime);
+                }
+                if (size >= 0) {
+                    videoDecoder.queueInputBuffer(
+                            decoderInputBufferIndex,
+                            0,
+                            size,
+                            presentationTime,
+                            videoExtractor.getSampleFlags());
+                }
+                videoExtractorDone = !videoExtractor.advance();
+                if (videoExtractorDone) {
+                    if (VERBOSE) Log.d(TAG, "video extractor: EOS");
+                    videoDecoder.queueInputBuffer(
+                            decoderInputBufferIndex,
+                            0,
+                            0,
+                            0,
+                            MediaCodec.BUFFER_FLAG_END_OF_STREAM);
+                }
+                videoExtractedFrameCount++;
+                // We extracted a frame, let's try something else next.
+                break;
+            }
+
+            // Extract audio from file and feed to decoder.
+            // Do not extract audio if we have determined the output format but we are not yet
+            // ready to mux the frames.
+            while (mCopyAudio && !audioExtractorDone
+                    && (encoderOutputAudioFormat == null || muxing)) {
+                int decoderInputBufferIndex = audioDecoder.dequeueInputBuffer(TIMEOUT_USEC);
+                if (decoderInputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
+                    if (VERBOSE) Log.d(TAG, "no audio decoder input buffer");
+                    break;
+                }
+                if (VERBOSE) {
+                    Log.d(TAG, "audio decoder: returned input buffer: " + decoderInputBufferIndex);
+                }
+                ByteBuffer decoderInputBuffer = audioDecoderInputBuffers[decoderInputBufferIndex];
+                int size = audioExtractor.readSampleData(decoderInputBuffer, 0);
+                long presentationTime = audioExtractor.getSampleTime();
+                if (VERBOSE) {
+                    Log.d(TAG, "audio extractor: returned buffer of size " + size);
+                    Log.d(TAG, "audio extractor: returned buffer for time " + presentationTime);
+                }
+                if (size >= 0) {
+                    audioDecoder.queueInputBuffer(
+                            decoderInputBufferIndex,
+                            0,
+                            size,
+                            presentationTime,
+                            audioExtractor.getSampleFlags());
+                }
+                audioExtractorDone = !audioExtractor.advance();
+                if (audioExtractorDone) {
+                    if (VERBOSE) Log.d(TAG, "audio extractor: EOS");
+                    audioDecoder.queueInputBuffer(
+                            decoderInputBufferIndex,
+                            0,
+                            0,
+                            0,
+                            MediaCodec.BUFFER_FLAG_END_OF_STREAM);
+                }
+                audioExtractedFrameCount++;
+                // We extracted a frame, let's try something else next.
+                break;
+            }
+
+            // Poll output frames from the video decoder and feed the encoder.
+            while (mCopyVideo && !videoDecoderDone
+                    && (encoderOutputVideoFormat == null || muxing)) {
+                int decoderOutputBufferIndex =
+                        videoDecoder.dequeueOutputBuffer(
+                                videoDecoderOutputBufferInfo, TIMEOUT_USEC);
+                if (decoderOutputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
+                    if (VERBOSE) Log.d(TAG, "no video decoder output buffer");
+                    break;
+                }
+                if (decoderOutputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
+                    if (VERBOSE) Log.d(TAG, "video decoder: output buffers changed");
+                    videoDecoderOutputBuffers = videoDecoder.getOutputBuffers();
+                    break;
+                }
+                if (decoderOutputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+                    decoderOutputVideoFormat = videoDecoder.getOutputFormat();
+                    if (VERBOSE) {
+                        Log.d(TAG, "video decoder: output format changed: "
+                                + decoderOutputVideoFormat);
+                    }
+                    break;
+                }
+                if (VERBOSE) {
+                    Log.d(TAG, "video decoder: returned output buffer: "
+                            + decoderOutputBufferIndex);
+                    Log.d(TAG, "video decoder: returned buffer of size "
+                            + videoDecoderOutputBufferInfo.size);
+                }
+                ByteBuffer decoderOutputBuffer =
+                        videoDecoderOutputBuffers[decoderOutputBufferIndex];
+                if ((videoDecoderOutputBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG)
+                        != 0) {
+                    if (VERBOSE) Log.d(TAG, "video decoder: codec config buffer");
+                    videoDecoder.releaseOutputBuffer(decoderOutputBufferIndex, false);
+                    break;
+                }
+                if (VERBOSE) {
+                    Log.d(TAG, "video decoder: returned buffer for time "
+                            + videoDecoderOutputBufferInfo.presentationTimeUs);
+                }
+                boolean render = videoDecoderOutputBufferInfo.size != 0;
+                videoDecoder.releaseOutputBuffer(decoderOutputBufferIndex, render);
+                if (render) {
+                    if (VERBOSE) Log.d(TAG, "output surface: await new image");
+                    outputSurface.awaitNewImage();
+                    // Edit the frame and send it to the encoder.
+                    if (VERBOSE) Log.d(TAG, "output surface: draw image");
+                    outputSurface.drawImage();
+                    inputSurface.setPresentationTime(
+                            videoDecoderOutputBufferInfo.presentationTimeUs);
+                    if (VERBOSE) Log.d(TAG, "input surface: swap buffers");
+                    inputSurface.swapBuffers();
+                    if (VERBOSE) Log.d(TAG, "video encoder: notified of new frame");
+                }
+                if ((videoDecoderOutputBufferInfo.flags
+                        & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+                    if (VERBOSE) Log.d(TAG, "video decoder: EOS");
+                    videoDecoderDone = true;
+                    videoEncoder.signalEndOfInputStream();
+                }
+                videoDecodedFrameCount++;
+                // We extracted a pending frame, let's try something else next.
+                break;
+            }
+
+            // Poll output frames from the audio decoder.
+            // Do not poll if we already have a pending buffer to feed to the encoder.
+            while (mCopyAudio && !audioDecoderDone && pendingAudioDecoderOutputBufferIndex == -1
+                    && (encoderOutputAudioFormat == null || muxing)) {
+                int decoderOutputBufferIndex =
+                        audioDecoder.dequeueOutputBuffer(
+                                audioDecoderOutputBufferInfo, TIMEOUT_USEC);
+                if (decoderOutputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
+                    if (VERBOSE) Log.d(TAG, "no audio decoder output buffer");
+                    break;
+                }
+                if (decoderOutputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
+                    if (VERBOSE) Log.d(TAG, "audio decoder: output buffers changed");
+                    audioDecoderOutputBuffers = audioDecoder.getOutputBuffers();
+                    break;
+                }
+                if (decoderOutputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+                    decoderOutputAudioFormat = audioDecoder.getOutputFormat();
+                    if (VERBOSE) {
+                        Log.d(TAG, "audio decoder: output format changed: "
+                                + decoderOutputAudioFormat);
+                    }
+                    break;
+                }
+                if (VERBOSE) {
+                    Log.d(TAG, "audio decoder: returned output buffer: "
+                            + decoderOutputBufferIndex);
+                }
+                if (VERBOSE) {
+                    Log.d(TAG, "audio decoder: returned buffer of size "
+                            + audioDecoderOutputBufferInfo.size);
+                }
+                ByteBuffer decoderOutputBuffer =
+                        audioDecoderOutputBuffers[decoderOutputBufferIndex];
+                if ((audioDecoderOutputBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG)
+                        != 0) {
+                    if (VERBOSE) Log.d(TAG, "audio decoder: codec config buffer");
+                    audioDecoder.releaseOutputBuffer(decoderOutputBufferIndex, false);
+                    break;
+                }
+                if (VERBOSE) {
+                    Log.d(TAG, "audio decoder: returned buffer for time "
+                            + audioDecoderOutputBufferInfo.presentationTimeUs);
+                }
+                if (VERBOSE) {
+                    Log.d(TAG, "audio decoder: output buffer is now pending: "
+                            + pendingAudioDecoderOutputBufferIndex);
+                }
+                pendingAudioDecoderOutputBufferIndex = decoderOutputBufferIndex;
+                audioDecodedFrameCount++;
+                // We extracted a pending frame, let's try something else next.
+                break;
+            }
+
+            // Feed the pending decoded audio buffer to the audio encoder.
+            while (mCopyAudio && pendingAudioDecoderOutputBufferIndex != -1) {
+                if (VERBOSE) {
+                    Log.d(TAG, "audio decoder: attempting to process pending buffer: "
+                            + pendingAudioDecoderOutputBufferIndex);
+                }
+                int encoderInputBufferIndex = audioEncoder.dequeueInputBuffer(TIMEOUT_USEC);
+                if (encoderInputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
+                    if (VERBOSE) Log.d(TAG, "no audio encoder input buffer");
+                    break;
+                }
+                if (VERBOSE) {
+                    Log.d(TAG, "audio encoder: returned input buffer: " + encoderInputBufferIndex);
+                }
+                ByteBuffer encoderInputBuffer = audioEncoderInputBuffers[encoderInputBufferIndex];
+                int size = audioDecoderOutputBufferInfo.size;
+                long presentationTime = audioDecoderOutputBufferInfo.presentationTimeUs;
+                if (VERBOSE) {
+                    Log.d(TAG, "audio decoder: processing pending buffer: "
+                            + pendingAudioDecoderOutputBufferIndex);
+                }
+                if (VERBOSE) {
+                    Log.d(TAG, "audio decoder: pending buffer of size " + size);
+                    Log.d(TAG, "audio decoder: pending buffer for time " + presentationTime);
+                }
+                if (size >= 0) {
+                    ByteBuffer decoderOutputBuffer =
+                            audioDecoderOutputBuffers[pendingAudioDecoderOutputBufferIndex]
+                                    .duplicate();
+                    decoderOutputBuffer.position(audioDecoderOutputBufferInfo.offset);
+                    decoderOutputBuffer.limit(audioDecoderOutputBufferInfo.offset + size);
+                    encoderInputBuffer.position(0);
+                    encoderInputBuffer.put(decoderOutputBuffer);
+
+                    audioEncoder.queueInputBuffer(
+                            encoderInputBufferIndex,
+                            0,
+                            size,
+                            presentationTime,
+                            audioDecoderOutputBufferInfo.flags);
+                }
+                audioDecoder.releaseOutputBuffer(pendingAudioDecoderOutputBufferIndex, false);
+                pendingAudioDecoderOutputBufferIndex = -1;
+                if ((audioDecoderOutputBufferInfo.flags
+                        & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+                    if (VERBOSE) Log.d(TAG, "audio decoder: EOS");
+                    audioDecoderDone = true;
+                }
+                // We enqueued a pending frame, let's try something else next.
+                break;
+            }
+
+            // Poll frames from the video encoder and send them to the muxer.
+            while (mCopyVideo && !videoEncoderDone
+                    && (encoderOutputVideoFormat == null || muxing)) {
+                int encoderOutputBufferIndex = videoEncoder.dequeueOutputBuffer(
+                        videoEncoderOutputBufferInfo, TIMEOUT_USEC);
+                if (encoderOutputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
+                    if (VERBOSE) Log.d(TAG, "no video encoder output buffer");
+                    break;
+                }
+                if (encoderOutputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
+                    if (VERBOSE) Log.d(TAG, "video encoder: output buffers changed");
+                    videoEncoderOutputBuffers = videoEncoder.getOutputBuffers();
+                    break;
+                }
+                if (encoderOutputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+                    if (VERBOSE) Log.d(TAG, "video encoder: output format changed");
+                    if (outputVideoTrack >= 0) {
+                        fail("video encoder changed its output format again?");
+                    }
+                    encoderOutputVideoFormat = videoEncoder.getOutputFormat();
+                    break;
+                }
+                assertTrue("should have added track before processing output", muxing);
+                if (VERBOSE) {
+                    Log.d(TAG, "video encoder: returned output buffer: "
+                            + encoderOutputBufferIndex);
+                    Log.d(TAG, "video encoder: returned buffer of size "
+                            + videoEncoderOutputBufferInfo.size);
+                }
+                ByteBuffer encoderOutputBuffer =
+                        videoEncoderOutputBuffers[encoderOutputBufferIndex];
+                if ((videoEncoderOutputBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG)
+                        != 0) {
+                    if (VERBOSE) Log.d(TAG, "video encoder: codec config buffer");
+                    // Simply ignore codec config buffers.
+                    videoEncoder.releaseOutputBuffer(encoderOutputBufferIndex, false);
+                    break;
+                }
+                if (VERBOSE) {
+                    Log.d(TAG, "video encoder: returned buffer for time "
+                            + videoEncoderOutputBufferInfo.presentationTimeUs);
+                }
+                if (videoEncoderOutputBufferInfo.size != 0) {
+                    muxer.writeSampleData(
+                            outputVideoTrack, encoderOutputBuffer, videoEncoderOutputBufferInfo);
+                }
+                if ((videoEncoderOutputBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM)
+                        != 0) {
+                    if (VERBOSE) Log.d(TAG, "video encoder: EOS");
+                    videoEncoderDone = true;
+                }
+                videoEncoder.releaseOutputBuffer(encoderOutputBufferIndex, false);
+                videoEncodedFrameCount++;
+                // We enqueued an encoded frame, let's try something else next.
+                break;
+            }
+
+            // Poll frames from the audio encoder and send them to the muxer.
+            while (mCopyAudio && !audioEncoderDone
+                    && (encoderOutputAudioFormat == null || muxing)) {
+                int encoderOutputBufferIndex = audioEncoder.dequeueOutputBuffer(
+                        audioEncoderOutputBufferInfo, TIMEOUT_USEC);
+                if (encoderOutputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
+                    if (VERBOSE) Log.d(TAG, "no audio encoder output buffer");
+                    break;
+                }
+                if (encoderOutputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
+                    if (VERBOSE) Log.d(TAG, "audio encoder: output buffers changed");
+                    audioEncoderOutputBuffers = audioEncoder.getOutputBuffers();
+                    break;
+                }
+                if (encoderOutputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+                    if (VERBOSE) Log.d(TAG, "audio encoder: output format changed");
+                    if (outputAudioTrack >= 0) {
+                        fail("audio encoder changed its output format again?");
+                    }
+
+                    encoderOutputAudioFormat = audioEncoder.getOutputFormat();
+                    break;
+                }
+                assertTrue("should have added track before processing output", muxing);
+                if (VERBOSE) {
+                    Log.d(TAG, "audio encoder: returned output buffer: "
+                            + encoderOutputBufferIndex);
+                    Log.d(TAG, "audio encoder: returned buffer of size "
+                            + audioEncoderOutputBufferInfo.size);
+                }
+                ByteBuffer encoderOutputBuffer =
+                        audioEncoderOutputBuffers[encoderOutputBufferIndex];
+                if ((audioEncoderOutputBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG)
+                        != 0) {
+                    if (VERBOSE) Log.d(TAG, "audio encoder: codec config buffer");
+                    // Simply ignore codec config buffers.
+                    audioEncoder.releaseOutputBuffer(encoderOutputBufferIndex, false);
+                    break;
+                }
+                if (VERBOSE) {
+                    Log.d(TAG, "audio encoder: returned buffer for time "
+                            + audioEncoderOutputBufferInfo.presentationTimeUs);
+                }
+                if (audioEncoderOutputBufferInfo.size != 0) {
+                    muxer.writeSampleData(
+                            outputAudioTrack, encoderOutputBuffer, audioEncoderOutputBufferInfo);
+                }
+                if ((audioEncoderOutputBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM)
+                        != 0) {
+                    if (VERBOSE) Log.d(TAG, "audio encoder: EOS");
+                    audioEncoderDone = true;
+                }
+                audioEncoder.releaseOutputBuffer(encoderOutputBufferIndex, false);
+                audioEncodedFrameCount++;
+                // We enqueued an encoded frame, let's try something else next.
+                break;
+            }
+
+            if (!muxing
+                    && (!mCopyAudio || encoderOutputAudioFormat != null)
+                    && (!mCopyVideo || encoderOutputVideoFormat != null)) {
+                if (mCopyVideo) {
+                    Log.d(TAG, "muxer: adding video track.");
+                    outputVideoTrack = muxer.addTrack(encoderOutputVideoFormat);
+                }
+                if (mCopyAudio) {
+                    Log.d(TAG, "muxer: adding audio track.");
+                    outputAudioTrack = muxer.addTrack(encoderOutputAudioFormat);
+                }
+                Log.d(TAG, "muxer: starting");
+                muxer.start();
+                muxing = true;
+            }
+        }
+
+        // Basic sanity checks.
+        if (mCopyVideo) {
+            assertEquals("encoded and decoded video frame counts should match",
+                    videoDecodedFrameCount, videoEncodedFrameCount);
+            assertTrue("decoded frame count should be less than extracted frame count",
+                    videoDecodedFrameCount <= videoExtractedFrameCount);
+        }
+        if (mCopyAudio) {
+            assertEquals("no frame should be pending", -1, pendingAudioDecoderOutputBufferIndex);
+        }
+
+        // TODO: Check the generated output file.
+    }
+
+    private static boolean isVideoFormat(MediaFormat format) {
+        return getMimeTypeFor(format).startsWith("video/");
+    }
+
+    private static boolean isAudioFormat(MediaFormat format) {
+        return getMimeTypeFor(format).startsWith("audio/");
+    }
+
+    private static String getMimeTypeFor(MediaFormat format) {
+        return format.getString(MediaFormat.KEY_MIME);
+    }
+
+    /**
+     * Returns the first codec capable of encoding the specified MIME type, or null if no match was
+     * found.
+     */
+    private static MediaCodecInfo selectCodec(String mimeType) {
+        int numCodecs = MediaCodecList.getCodecCount();
+        for (int i = 0; i < numCodecs; i++) {
+            MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
+
+            if (!codecInfo.isEncoder()) {
+                continue;
+            }
+
+            String[] types = codecInfo.getSupportedTypes();
+            for (int j = 0; j < types.length; j++) {
+                if (types[j].equalsIgnoreCase(mimeType)) {
+                    return codecInfo;
+                }
+            }
+        }
+        return null;
+    }
+
+}
