/*
 * Copyright 2015 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.content.Context;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.cts.util.MediaUtils;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaSync;
import android.media.MediaTimestamp;
import android.media.PlaybackParams;
import android.media.SyncParams;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;

import java.io.IOException;
import java.lang.Long;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.List;
import java.util.LinkedList;

/**
 * Tests for the MediaSync API and local video/audio playback.
 *
 * <p>The file in res/raw used by all tests are (c) copyright 2008,
 * Blender Foundation / www.bigbuckbunny.org, and are licensed under the Creative Commons
 * Attribution 3.0 License at http://creativecommons.org/licenses/by/3.0/us/.
 */
public class MediaSyncTest extends ActivityInstrumentationTestCase2<MediaStubActivity> {
    private static final String LOG_TAG = "MediaSyncTest";

    private final long NO_TIMESTAMP = -1;
    private final int PLAYBACK_RATE_TOLERANCE_PERCENT = 2;
    private final long TIME_MEASUREMENT_TOLERANCE_US = 20000;
    final int INPUT_RESOURCE_ID =
            R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_192kbps_44100hz;
    private final int APPLICATION_AUDIO_PERIOD_MS = 200;
    private final int TEST_MAX_SPEED = 2;
    private static final float FLOAT_TOLERANCE = .00001f;

    private Context mContext;
    private Resources mResources;

    private MediaStubActivity mActivity;

    private MediaSync mMediaSync = null;
    private Surface mSurface = null;
    private AudioTrack mAudioTrack = null;

    private Decoder mDecoderVideo = null;
    private Decoder mDecoderAudio = null;
    private boolean mHasAudio = false;
    private boolean mHasVideo = false;
    private boolean mEosAudio = false;
    private boolean mEosVideo = false;
    private final Object mConditionEos = new Object();
    private final Object mConditionEosAudio = new Object();

    private int mNumBuffersReturned = 0;

    public MediaSyncTest() {
        super(MediaStubActivity.class);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mActivity = getActivity();
        getInstrumentation().waitForIdleSync();
        try {
            runTestOnUiThread(new Runnable() {
                public void run() {
                    mMediaSync = new MediaSync();
                }
            });
        } catch (Throwable e) {
            e.printStackTrace();
            fail();
        }
        mContext = getInstrumentation().getTargetContext();
        mResources = mContext.getResources();
        mDecoderVideo = new Decoder(this, mMediaSync, false);
        mDecoderAudio = new Decoder(this, mMediaSync, true);
    }

    @Override
    protected void tearDown() throws Exception {
        if (mMediaSync != null) {
            mMediaSync.release();
            mMediaSync = null;
        }
        if (mDecoderAudio != null) {
            mDecoderAudio.release();
            mDecoderAudio = null;
        }
        if (mDecoderVideo != null) {
            mDecoderVideo.release();
            mDecoderVideo = null;
        }
        if (mSurface != null) {
            mSurface.release();
            mSurface = null;
        }
        mActivity = null;
        super.tearDown();
    }

    private boolean reachedEos_l() {
        return ((!mHasVideo || mEosVideo) && (!mHasAudio || mEosAudio));
    }

    public void onEos(Decoder decoder) {
        synchronized(mConditionEosAudio) {
            if (decoder == mDecoderAudio) {
                mEosAudio = true;
                mConditionEosAudio.notify();
            }
        }

        synchronized(mConditionEos) {
            if (decoder == mDecoderVideo) {
                mEosVideo = true;
            }
            if (reachedEos_l()) {
                mConditionEos.notify();
            }
        }
    }

    /**
     * Tests setPlaybackParams is handled correctly for wrong rate.
     */
    public void testSetPlaybackParamsFail() throws InterruptedException {
        final float rate = -1.0f;
        try {
            mMediaSync.setPlaybackParams(new PlaybackParams().setSpeed(rate));
            fail("playback rate " + rate + " is not handled correctly");
        } catch (IllegalArgumentException e) {
        }

        assertTrue("The stream in test file can not be decoded",
                mDecoderAudio.setup(INPUT_RESOURCE_ID, null, Long.MAX_VALUE));

        // get audio track.
        mAudioTrack = mDecoderAudio.getAudioTrack();

        mMediaSync.setAudioTrack(mAudioTrack);

        try {
            mMediaSync.setPlaybackParams(new PlaybackParams().setSpeed(rate));
            fail("With audio track set, playback rate " + rate
                    + " is not handled correctly");
        } catch (IllegalArgumentException e) {
        }
    }

    /**
     * Tests setPlaybackParams is handled correctly for good rate without audio track set.
     * The case for good rate with audio track set is tested in testPlaybackRate*.
     */
    public void testSetPlaybackParamsSucceed() throws InterruptedException {
        final float rate = (float)TEST_MAX_SPEED;
        try {
            mMediaSync.setPlaybackParams(new PlaybackParams().setSpeed(rate));
            PlaybackParams pbp = mMediaSync.getPlaybackParams();
            assertEquals(rate, pbp.getSpeed(), FLOAT_TOLERANCE);
        } catch (IllegalArgumentException e) {
            fail("playback rate " + rate + " is not handled correctly");
        }
    }

    /**
     * Tests returning audio buffers correctly.
     */
    public void testAudioBufferReturn() throws InterruptedException {
        final int timeOutMs = 10000;
        boolean completed = runCheckAudioBuffer(INPUT_RESOURCE_ID, timeOutMs);
        if (!completed) {
            throw new RuntimeException("timed out waiting for audio buffer return");
        }
    }

    private PlaybackParams PAUSED_RATE = new PlaybackParams().setSpeed(0.f);
    private PlaybackParams NORMAL_RATE = new PlaybackParams().setSpeed(1.f);

    private boolean runCheckAudioBuffer(int inputResourceId, int timeOutMs) {
        final int NUM_LOOPS = 10;
        final Object condition = new Object();

        mHasAudio = true;
        if (mDecoderAudio.setup(inputResourceId, null, Long.MAX_VALUE) == false) {
            return true;
        }

        // get audio track.
        mAudioTrack = mDecoderAudio.getAudioTrack();

        mMediaSync.setAudioTrack(mAudioTrack);

        mMediaSync.setCallback(new MediaSync.Callback() {
            @Override
            public void onAudioBufferConsumed(
                    MediaSync sync, ByteBuffer byteBuffer, int bufferIndex) {
                Decoder decoderAudio = mDecoderAudio;
                if (decoderAudio != null) {
                    decoderAudio.checkReturnedAudioBuffer(byteBuffer, bufferIndex);
                    decoderAudio.releaseOutputBuffer(bufferIndex, NO_TIMESTAMP);
                    synchronized (condition) {
                        ++mNumBuffersReturned;
                        if (mNumBuffersReturned >= NUM_LOOPS) {
                            condition.notify();
                        }
                    }
                }
            }
        }, null);

        mMediaSync.setPlaybackParams(NORMAL_RATE);

        synchronized (condition) {
            mDecoderAudio.start();

            try {
                condition.wait(timeOutMs);
            } catch (InterruptedException e) {
            }
            return (mNumBuffersReturned >= NUM_LOOPS);
        }
    }

    /**
     * Tests flush.
     */
    public void testFlush() throws InterruptedException {
        final int timeOutMs = 5000;
        boolean completed = runFlush(INPUT_RESOURCE_ID, timeOutMs);
        if (!completed) {
            throw new RuntimeException("timed out waiting for flush");
        }
    }

    private boolean runFlush(int inputResourceId, int timeOutMs) {
        final int INDEX_BEFORE_FLUSH = 1;
        final int INDEX_AFTER_FLUSH = 2;
        final int BUFFER_SIZE = 1024;
        final int[] returnedIndex = new int[1];
        final Object condition = new Object();

        returnedIndex[0] = -1;

        mHasAudio = true;
        if (mDecoderAudio.setup(inputResourceId, null, Long.MAX_VALUE) == false) {
            return true;
        }

        // get audio track.
        mAudioTrack = mDecoderAudio.getAudioTrack();

        mMediaSync.setAudioTrack(mAudioTrack);

        mMediaSync.setCallback(new MediaSync.Callback() {
            @Override
            public void onAudioBufferConsumed(
                    MediaSync sync, ByteBuffer byteBuffer, int bufferIndex) {
                synchronized (condition) {
                    if (returnedIndex[0] == -1) {
                        returnedIndex[0] = bufferIndex;
                        condition.notify();
                    }
                }
            }
        }, null);

        mMediaSync.setOnErrorListener(new MediaSync.OnErrorListener() {
            @Override
            public void onError(MediaSync sync, int what, int extra) {
                fail("got error from media sync (" + what + ", " + extra + ")");
            }
        }, null);

        mMediaSync.setPlaybackParams(PAUSED_RATE);

        ByteBuffer buffer1 = ByteBuffer.allocate(BUFFER_SIZE);
        ByteBuffer buffer2 = ByteBuffer.allocate(BUFFER_SIZE);
        mMediaSync.queueAudio(buffer1, INDEX_BEFORE_FLUSH, 0 /* presentationTimeUs */);
        mMediaSync.flush();
        mMediaSync.queueAudio(buffer2, INDEX_AFTER_FLUSH, 0 /* presentationTimeUs */);

        synchronized (condition) {
            mMediaSync.setPlaybackParams(NORMAL_RATE);

            try {
                condition.wait(timeOutMs);
            } catch (InterruptedException e) {
            }
            return (returnedIndex[0] == INDEX_AFTER_FLUSH);
        }
    }

    /**
     * Tests playing back audio successfully.
     */
    public void testPlayVideo() throws InterruptedException {
        playAV(INPUT_RESOURCE_ID, 5000 /* lastBufferTimestampMs */,
               false /* audio */, true /* video */, 10000 /* timeOutMs */);
    }

    /**
     * Tests playing back video successfully.
     */
    public void testPlayAudio() throws InterruptedException {
        playAV(INPUT_RESOURCE_ID, 5000 /* lastBufferTimestampMs */,
               true /* audio */, false /* video */, 10000 /* timeOutMs */);
    }

    /**
     * Tests playing back audio and video successfully.
     */
    public void testPlayAudioAndVideo() throws InterruptedException {
        playAV(INPUT_RESOURCE_ID, 5000 /* lastBufferTimestampMs */,
               true /* audio */, true /* video */, 10000 /* timeOutMs */);
    }

    /**
     * Tests playing at specified playback rate successfully.
     */
    public void testPlaybackRateQuarter() throws InterruptedException {
        playAV(INPUT_RESOURCE_ID, 2000 /* lastBufferTimestampMs */,
               true /* audio */, true /* video */, 10000 /* timeOutMs */,
               0.25f /* playbackRate */);
    }
    public void testPlaybackRateHalf() throws InterruptedException {
        playAV(INPUT_RESOURCE_ID, 4000 /* lastBufferTimestampMs */,
               true /* audio */, true /* video */, 10000 /* timeOutMs */,
               0.5f /* playbackRate */);
    }
    public void testPlaybackRateDouble() throws InterruptedException {
        playAV(INPUT_RESOURCE_ID, 8000 /* lastBufferTimestampMs */,
               true /* audio */, true /* video */, 10000 /* timeOutMs */,
               (float)TEST_MAX_SPEED /* playbackRate */);
    }

    private void playAV(
            final int inputResourceId,
            final long lastBufferTimestampMs,
            final boolean audio,
            final boolean video,
            int timeOutMs) throws InterruptedException {
        playAV(inputResourceId, lastBufferTimestampMs, audio, video, timeOutMs, 1.0f);
    }

    private void playAV(
            final int inputResourceId,
            final long lastBufferTimestampMs,
            final boolean audio,
            final boolean video,
            int timeOutMs,
            final float playbackRate) throws InterruptedException {
        final AtomicBoolean completed = new AtomicBoolean();
        Thread decodingThread = new Thread(new Runnable() {
            @Override
            public void run() {
                completed.set(runPlayAV(inputResourceId, lastBufferTimestampMs * 1000,
                        audio, video, playbackRate));
            }
        });
        decodingThread.start();
        decodingThread.join(timeOutMs);
        if (!completed.get()) {
            throw new RuntimeException("timed out decoding to end-of-stream");
        }
    }

    private boolean runPlayAV(
            int inputResourceId,
            long lastBufferTimestampUs,
            boolean audio,
            boolean video,
            float playbackRate) {
        // allow 250ms for playback to get to stable state.
        final int PLAYBACK_RAMP_UP_TIME_MS = 250;

        final Object conditionFirstAudioBuffer = new Object();

        if (video) {
            mMediaSync.setSurface(mActivity.getSurfaceHolder().getSurface());
            mSurface = mMediaSync.createInputSurface();

            if (mDecoderVideo.setup(
                    inputResourceId, mSurface, lastBufferTimestampUs) == false) {
                return true;
            }
            mHasVideo = true;
        }

        if (audio) {
            if (mDecoderAudio.setup(inputResourceId, null, lastBufferTimestampUs) == false) {
                return true;
            }

            // get audio track.
            mAudioTrack = mDecoderAudio.getAudioTrack();

            mMediaSync.setAudioTrack(mAudioTrack);

            mMediaSync.setCallback(new MediaSync.Callback() {
                @Override
                public void onAudioBufferConsumed(
                        MediaSync sync, ByteBuffer byteBuffer, int bufferIndex) {
                    Decoder decoderAudio = mDecoderAudio;
                    if (decoderAudio != null) {
                        decoderAudio.releaseOutputBuffer(bufferIndex, NO_TIMESTAMP);
                    }
                    synchronized (conditionFirstAudioBuffer) {
                        conditionFirstAudioBuffer.notify();
                    }
                }
            }, null);

            mHasAudio = true;
        }

        SyncParams sync = new SyncParams().allowDefaults();
        mMediaSync.setSyncParams(sync);
        sync = mMediaSync.getSyncParams();

        mMediaSync.setPlaybackParams(new PlaybackParams().setSpeed(playbackRate));

        synchronized (conditionFirstAudioBuffer) {
            if (video) {
                mDecoderVideo.start();
            }
            if (audio) {
                mDecoderAudio.start();

                // wait for the first audio output buffer returned by media sync.
                try {
                    conditionFirstAudioBuffer.wait();
                } catch (InterruptedException e) {
                    Log.i(LOG_TAG, "worker thread is interrupted.");
                    return true;
                }
            }
        }

        if (audio) {
            try {
                Thread.sleep(PLAYBACK_RAMP_UP_TIME_MS);
            } catch (InterruptedException e) {
                Log.i(LOG_TAG, "worker thread is interrupted during sleeping.");
                return true;
            }

            MediaTimestamp mediaTimestamp = mMediaSync.getTimestamp();
            assertTrue("No timestamp available for starting", mediaTimestamp != null);
            long checkStartTimeRealUs = System.nanoTime() / 1000;
            long checkStartTimeMediaUs = mediaTimestamp.mediaTimeUs;

            synchronized (mConditionEosAudio) {
                if (!mEosAudio) {
                    try {
                        mConditionEosAudio.wait();
                    } catch (InterruptedException e) {
                        Log.i(LOG_TAG, "worker thread is interrupted when waiting for audio EOS.");
                        return true;
                    }
                }
            }
            mediaTimestamp = mMediaSync.getTimestamp();
            assertTrue("No timestamp available for ending", mediaTimestamp != null);
            long playTimeUs = System.nanoTime() / 1000 - checkStartTimeRealUs;
            long mediaDurationUs = mediaTimestamp.mediaTimeUs - checkStartTimeMediaUs;
            assertEquals("Mediasync had error in playback rate " + playbackRate
                    + ", play time is " + playTimeUs + " vs expected " + mediaDurationUs,
                    mediaDurationUs,
                    playTimeUs * playbackRate,
                    // sync.getTolerance() is MediaSync's tolerance of the playback rate, whereas
                    // PLAYBACK_RATE_TOLERANCE_PERCENT / 100 is our test's tolerance.
                    // We need to add both to get an upperbound for allowable error.
                    mediaDurationUs * (sync.getTolerance() + PLAYBACK_RATE_TOLERANCE_PERCENT / 100.)
                            + TIME_MEASUREMENT_TOLERANCE_US);
        }

        boolean completed = false;
        synchronized (mConditionEos) {
            if (!reachedEos_l()) {
                try {
                    mConditionEos.wait();
                } catch (InterruptedException e) {
                }
            }
            completed = reachedEos_l();
        }
        return completed;
    }

    private class Decoder extends MediaCodec.Callback {
        private final int NO_SAMPLE_RATE = -1;
        private final int NO_BUFFER_INDEX = -1;

        private MediaSyncTest mMediaSyncTest = null;
        private MediaSync mMediaSync = null;
        private boolean mIsAudio = false;
        private long mLastBufferTimestampUs = 0;

        private Surface mSurface = null;

        private AudioTrack mAudioTrack = null;

        private final Object mConditionCallback = new Object();
        private MediaExtractor mExtractor = null;
        private MediaCodec mDecoder = null;

        private final Object mAudioBufferLock = new Object();
        private List<AudioBuffer> mAudioBuffers = new LinkedList<AudioBuffer>();

        // accessed only on callback thread.
        private boolean mEos = false;
        private boolean mSignaledEos = false;

        private class AudioBuffer {
            public ByteBuffer mByteBuffer;
            public int mBufferIndex;

            public AudioBuffer(ByteBuffer byteBuffer, int bufferIndex) {
                mByteBuffer = byteBuffer;
                mBufferIndex = bufferIndex;
            }
        }

        Decoder(MediaSyncTest test, MediaSync sync, boolean isAudio) {
            mMediaSyncTest = test;
            mMediaSync = sync;
            mIsAudio = isAudio;
        }

        public boolean setup(int inputResourceId, Surface surface, long lastBufferTimestampUs) {
            if (!mIsAudio) {
                mSurface = surface;
            }
            mLastBufferTimestampUs = lastBufferTimestampUs;
            try {
                // get extrator.
                String type = mIsAudio ? "audio/" : "video/";
                mExtractor = MediaUtils.createMediaExtractorForMimeType(
                        mContext, inputResourceId, type);

                // get decoder.
                MediaFormat mediaFormat =
                    mExtractor.getTrackFormat(mExtractor.getSampleTrackIndex());
                String mimeType = mediaFormat.getString(MediaFormat.KEY_MIME);
                if (!MediaUtils.hasDecoder(mimeType)) {
                    Log.i(LOG_TAG, "No decoder found for mimeType= " + mimeType);
                    return false;
                }
                mDecoder = MediaCodec.createDecoderByType(mimeType);
                mDecoder.configure(mediaFormat, mSurface, null, 0);
                mDecoder.setCallback(this);

                return true;
            } catch (IOException e) {
                throw new RuntimeException("error reading input resource", e);
            }
        }

        public void start() {
            if (mDecoder != null) {
                mDecoder.start();
            }
        }

        public void release() {
            synchronized (mConditionCallback) {
                if (mDecoder != null) {
                    try {
                        mDecoder.stop();
                    } catch (IllegalStateException e) {
                    }
                    mDecoder.release();
                    mDecoder = null;
                }
                if (mExtractor != null) {
                    mExtractor.release();
                    mExtractor = null;
                }
            }

            if (mAudioTrack != null) {
                mAudioTrack.release();
                mAudioTrack = null;
            }
        }

        public AudioTrack getAudioTrack() {
            if (!mIsAudio) {
                throw new RuntimeException("can not create audio track for video");
            }

            if (mExtractor == null) {
                throw new RuntimeException("extrator is null");
            }

            if (mAudioTrack == null) {
                MediaFormat mediaFormat =
                    mExtractor.getTrackFormat(mExtractor.getSampleTrackIndex());
                int sampleRateInHz = mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);
                int channelConfig = (mediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT) == 1 ?
                        AudioFormat.CHANNEL_OUT_MONO : AudioFormat.CHANNEL_OUT_STEREO);
                int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
                int minBufferSizeInBytes = AudioTrack.getMinBufferSize(
                        sampleRateInHz,
                        channelConfig,
                        audioFormat);
                final int frameCount = APPLICATION_AUDIO_PERIOD_MS * sampleRateInHz / 1000;
                final int frameSizeInBytes = Integer.bitCount(channelConfig)
                        * AudioFormat.getBytesPerSample(audioFormat);
                // ensure we consider application requirements for writing audio data
                minBufferSizeInBytes = TEST_MAX_SPEED /* speed influences buffer size */
                        * Math.max(minBufferSizeInBytes, frameCount * frameSizeInBytes);
                mAudioTrack = new AudioTrack(
                        AudioManager.STREAM_MUSIC,
                        sampleRateInHz,
                        channelConfig,
                        audioFormat,
                        minBufferSizeInBytes,
                        AudioTrack.MODE_STREAM);
            }

            return mAudioTrack;
        }

        public void releaseOutputBuffer(int bufferIndex, long renderTimestampNs) {
            synchronized (mConditionCallback) {
                if (mDecoder != null) {
                    if (renderTimestampNs == NO_TIMESTAMP) {
                        mDecoder.releaseOutputBuffer(bufferIndex, false /* render */);
                    } else {
                        mDecoder.releaseOutputBuffer(bufferIndex, renderTimestampNs);
                    }
                }
            }
        }

        @Override
        public void onError(MediaCodec codec, MediaCodec.CodecException e) {
        }

        @Override
        public void onInputBufferAvailable(MediaCodec codec, int index) {
            synchronized (mConditionCallback) {
                if (mExtractor == null || mExtractor.getSampleTrackIndex() == -1
                        || mSignaledEos || mDecoder != codec) {
                    return;
                }

                ByteBuffer buffer = codec.getInputBuffer(index);
                int size = mExtractor.readSampleData(buffer, 0);
                long timestampUs = mExtractor.getSampleTime();
                mExtractor.advance();
                mSignaledEos = mExtractor.getSampleTrackIndex() == -1
                        || timestampUs >= mLastBufferTimestampUs;
                codec.queueInputBuffer(
                        index,
                        0,
                        size,
                        timestampUs,
                        mSignaledEos ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
            }
        }

        @Override
        public void onOutputBufferAvailable(
                MediaCodec codec, int index, MediaCodec.BufferInfo info) {
            synchronized (mConditionCallback) {
                if (mEos || mDecoder != codec) {
                    return;
                }

                mEos = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;

                if (info.size > 0) {
                    if (mIsAudio) {
                        ByteBuffer outputByteBuffer = codec.getOutputBuffer(index);
                        synchronized(mAudioBufferLock) {
                            mAudioBuffers.add(new AudioBuffer(outputByteBuffer, index));
                        }
                        mMediaSync.queueAudio(
                                outputByteBuffer,
                                index,
                                info.presentationTimeUs);
                    } else {
                        codec.releaseOutputBuffer(index, info.presentationTimeUs * 1000);
                    }
                } else {
                    codec.releaseOutputBuffer(index, false);
                }
            }

            if (mEos) {
                mMediaSyncTest.onEos(this);
            }
        }

        @Override
        public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) {
        }

        public void checkReturnedAudioBuffer(ByteBuffer byteBuffer, int bufferIndex) {
            synchronized(mAudioBufferLock) {
                AudioBuffer audioBuffer = mAudioBuffers.get(0);
                if (audioBuffer.mByteBuffer != byteBuffer
                        || audioBuffer.mBufferIndex != bufferIndex) {
                    fail("returned buffer doesn't match what's sent");
                }
                mAudioBuffers.remove(0);
            }
        }
    }
}
