/*
 * Copyright (C) 2021 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.mediav2.cts;

import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_Format32bitABGR2101010;
import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUVP010;
import static android.mediav2.common.cts.CodecEncoderTestBase.colorFormatToString;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;

import android.media.MediaCodec;
import android.media.MediaFormat;
import android.mediav2.common.cts.CodecAsyncHandler;
import android.mediav2.common.cts.CodecDecoderTestBase;
import android.mediav2.common.cts.CodecTestBase;
import android.mediav2.common.cts.EncoderConfigParams;
import android.mediav2.common.cts.OutputManager;
import android.opengl.GLES20;
import android.opengl.GLES30;
import android.util.Log;
import android.util.Pair;
import android.view.Surface;

import androidx.test.filters.LargeTest;

import com.android.compatibility.common.util.ApiTest;
import com.android.compatibility.common.util.MediaUtils;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.microedition.khronos.opengles.GL10;

/**
 * Color Primaries, Color Standard and Color Transfer are essential information to display the
 * decoded YUV on an RGB display accurately. Tests
 * {@link EncoderColorAspectsTest#testColorAspects()} and
 * {@link DecoderColorAspectsTest#testColorAspects()} checks if the encoder and decoder
 * components are signalling the configured color aspects correctly.
 * This test verifies if the device decoder/display is using this color aspects correctly
 * <p>
 * Test pipeline:
 * <pre> [[ Input RGB frames -> encoder -> muxer -> decoder -> display -> Output RGB frames ]]
 * </pre>
 * Assuming no quantization losses, the test verifies if the input rgb pixel values and output
 * rgb pixel values are within tolerance limits.
 */
@RunWith(Parameterized.class)
public class EncodeDecodeAccuracyTest extends CodecDecoderTestBase {
    private final String LOG_TAG = EncodeDecodeAccuracyTest.class.getSimpleName();
    // The bitrates are configured to large values. The content has zero motion, so in-time the
    // qp of the encoded clips shall drop down to < 10. Further the color bands are aligned to 2,
    // so from downsampling rgb24 to yuv420p, even if bilinear filters are used as opposed to
    // skipping samples, we may not see large color loss. Hence allowable tolerance is kept to 5.
    // until QP stabilizes, the tolerance is set at 7. For devices upgrading to T, thresholds are
    // relaxed to 8 and 10.
    private static final int TRANSIENT_STATE_COLOR_DELTA = FIRST_SDK_IS_AT_LEAST_T ? 7 : 10;
    private static final int STEADY_STATE_COLOR_DELTA = FIRST_SDK_IS_AT_LEAST_T ? 5 : 8;
    private final int[][] mColorBars = new int[][]{
            {66, 133, 244},
            {219, 68, 55},
            {244, 180, 0},
            {15, 157, 88},
            {186, 85, 211},
            {119, 136, 153},
            {225, 179, 120},
            {224, 204, 151},
            {236, 121, 154},
            {159, 2, 81},
            {120, 194, 87}
    };
    private final int FRAMES_TO_ENCODE = 30;
    private final int STEADY_STATE_FRAME_INDEX = 20;

    private final String mCompName;
    private final EncoderConfigParams mEncCfgParams;

    private final CodecAsyncHandler mAsyncHandleEncoder;
    private MediaCodec mEncoder;
    private Surface mInpSurface;
    private EGLWindowSurface mEGLWindowInpSurface;
    private OutputSurface mEGLWindowOutSurface;
    private boolean mSawInputEOSEnc;
    private boolean mSawOutputEOSEnc;
    private int mLatency;
    private boolean mReviseLatency;
    private int mInputCountEnc;
    private int mOutputCountEnc;
    private boolean mSaveToMemEnc;
    private OutputManager mOutputBuffEnc;
    ArrayList<MediaCodec.BufferInfo> mInfoListEnc;

    private final int mColorBarWidth;
    private final int xOffset;
    private final int yOffset = 64;
    private int mLargestColorDelta;
    private int mBadFrames;

    @After
    public void tearDown() {
        if (mEGLWindowInpSurface != null) {
            mEGLWindowInpSurface.release();
            mEGLWindowInpSurface = null;
        }
        if (mInpSurface != null) {
            mInpSurface.release();
            mInpSurface = null;
        }
        if (mEncoder != null) {
            mEncoder.release();
            mEncoder = null;
        }
        mSurface = null;
        if (mEGLWindowOutSurface != null) {
            mEGLWindowOutSurface.release();
            mEGLWindowOutSurface = null;
        }
    }

    public EncodeDecodeAccuracyTest(String encoder, String mediaType,
            EncoderConfigParams encCfgParams, @SuppressWarnings("unused") String testLabel,
            String allTestParams) {
        super(null, mediaType, null, allTestParams);
        mCompName = encoder;
        mEncCfgParams = encCfgParams;
        mAsyncHandleEncoder = new CodecAsyncHandler();
        mLatency = 0;
        mReviseLatency = false;
        mInfoListEnc = new ArrayList<>();
        int barWidth = (mEncCfgParams.mWidth + mColorBars.length - 1) / mColorBars.length;
        // aligning color bands to 2 is done because, during chroma subsampling of rgb24 to yuv420p,
        // simple skipping alternate samples or bilinear filter would have same effect.
        mColorBarWidth = (barWidth % 2 == 0) ? barWidth : barWidth + 1;
        assertTrue(mColorBarWidth >= 16);
        xOffset = mColorBarWidth >> 2;
    }

    @Before
    public void setUp() throws IOException {
        // Few cuttlefish specific color conversion issues were fixed after Android T.
        if (MediaUtils.onCuttlefish()) {
            assumeTrue("Color conversion related tests are not valid on cuttlefish releases "
                    + "through android T", IS_AT_LEAST_U);
        }
        if (mEncCfgParams.mInputBitDepth == 10) {
            assumeTrue("Codec doesn't support ABGR2101010",
                    hasSupportForColorFormat(mCompName, mMime, COLOR_Format32bitABGR2101010));
            assumeTrue("Codec doesn't support high bit depth profile encoding",
                    doesCodecSupportHDRProfile(mCompName, mMime));
        }
    }

    private static EncoderConfigParams getVideoEncoderCfgParams(String mediaType, int width,
            int height, int frameRate, int bitRate, int range, int standard, int transfer,
            int colorFormat, int bitDepth) {
        return new EncoderConfigParams.Builder(mediaType)
                .setWidth(width)
                .setHeight(height)
                .setBitRate(bitRate)
                .setFrameRate(frameRate)
                .setRange(range)
                .setStandard(standard)
                .setTransfer(transfer)
                .setColorFormat(colorFormat)
                .setInputBitDepth(bitDepth)
                .build();
    }

    @Parameterized.Parameters(name = "{index}({0}_{1}_{3})")
    public static Collection<Object[]> input() {
        final boolean isEncoder = true;
        final boolean needAudio = false;
        final boolean needVideo = true;
        final Object[][] baseArgsList = new Object[][]{
                // "video/*", width, height, framerate, bitrate, range, standard, transfer,
                // useHighBitDepth
                {720, 480, 30, 3000000, MediaFormat.COLOR_RANGE_LIMITED,
                        MediaFormat.COLOR_STANDARD_BT601_NTSC,
                        MediaFormat.COLOR_TRANSFER_SDR_VIDEO, false},
                {720, 576, 30, 3000000, MediaFormat.COLOR_RANGE_LIMITED,
                        MediaFormat.COLOR_STANDARD_BT601_PAL, MediaFormat.COLOR_TRANSFER_SDR_VIDEO,
                        false},
                {720, 480, 30, 3000000, MediaFormat.COLOR_RANGE_FULL,
                        MediaFormat.COLOR_STANDARD_BT2020,
                        MediaFormat.COLOR_TRANSFER_ST2084, true},

                {720, 480, 30, 3000000, MediaFormat.COLOR_RANGE_LIMITED,
                    MediaFormat.COLOR_STANDARD_BT2020, MediaFormat.COLOR_TRANSFER_ST2084, true},
                {720, 480, 30, 3000000, MediaFormat.COLOR_RANGE_LIMITED,
                    MediaFormat.COLOR_STANDARD_BT709, MediaFormat.COLOR_TRANSFER_SDR_VIDEO, true},
                // TODO (b/186511593)
                /*
                {1280, 720, 30, 3000000, MediaFormat.COLOR_RANGE_LIMITED,
                        MediaFormat.COLOR_STANDARD_BT709, MediaFormat.COLOR_TRANSFER_SDR_VIDEO},
                {720, 480, 30, 3000000, MediaFormat.COLOR_RANGE_FULL,
                        MediaFormat.COLOR_STANDARD_BT601_NTSC,
                        MediaFormat.COLOR_TRANSFER_SDR_VIDEO},
                {720, 576, 30, 3000000, MediaFormat.COLOR_RANGE_FULL,
                        MediaFormat.COLOR_STANDARD_BT601_PAL, MediaFormat.COLOR_TRANSFER_SDR_VIDEO},
                {1280, 720, 30, 3000000, MediaFormat.COLOR_RANGE_FULL,
                        MediaFormat.COLOR_STANDARD_BT709, MediaFormat.COLOR_TRANSFER_SDR_VIDEO},

                {720, 480, 30, 3000000, MediaFormat.COLOR_RANGE_LIMITED,
                        MediaFormat.COLOR_STANDARD_BT709,
                        MediaFormat.COLOR_TRANSFER_SDR_VIDEO},
                {720, 576, 30, 3000000, MediaFormat.COLOR_RANGE_LIMITED,
                        MediaFormat.COLOR_STANDARD_BT709, MediaFormat.COLOR_TRANSFER_SDR_VIDEO},
                {1280, 720, 30, 3000000, MediaFormat.COLOR_RANGE_LIMITED,
                        MediaFormat.COLOR_STANDARD_BT601_PAL, MediaFormat.COLOR_TRANSFER_SDR_VIDEO},
                {720, 480, 30, 3000000, MediaFormat.COLOR_RANGE_FULL,
                        MediaFormat.COLOR_STANDARD_BT709,
                        MediaFormat.COLOR_TRANSFER_SDR_VIDEO},
                {720, 576, 30, 3000000, MediaFormat.COLOR_RANGE_FULL,
                        MediaFormat.COLOR_STANDARD_BT709, MediaFormat.COLOR_TRANSFER_SDR_VIDEO},
                {1280, 720, 30, 3000000, MediaFormat.COLOR_RANGE_FULL,
                        MediaFormat.COLOR_STANDARD_BT601_PAL, MediaFormat.COLOR_TRANSFER_SDR_VIDEO},
                 */
        };
        // Note: although vp8 and vp9 donot contain fields to signal color aspects properly, this
        // information can be muxed in to containers of mkv and mp4. So even those clips
        // should pass these tests
        final String[] mediaTypes =
                {MediaFormat.MIMETYPE_VIDEO_AVC, MediaFormat.MIMETYPE_VIDEO_HEVC,
                        MediaFormat.MIMETYPE_VIDEO_VP8, MediaFormat.MIMETYPE_VIDEO_VP9,
                        MediaFormat.MIMETYPE_VIDEO_AV1};
        final List<Object[]> exhaustiveArgsList = new ArrayList<>();
        for (String mediaType : mediaTypes) {
            for (Object[] obj : baseArgsList) {
                final int width = (int) obj[0];
                final int height = (int) obj[1];
                final int fps = (int) obj[2];
                final int br = (int) obj[3];
                final int range = (int) obj[4];
                final int std = (int) obj[5];
                final int tfr = (int) obj[6];
                final int bd = (boolean) obj[7] ? 10 : 8;

                Object[] testArgs = new Object[3];
                testArgs[0] = mediaType;
                testArgs[1] = getVideoEncoderCfgParams(mediaType, width, height, fps, br, range,
                        std, tfr, COLOR_FormatSurface, bd);
                testArgs[2] = String.format("%d_%d_%dkbps_%dfps_%d_%d_%d_%s", width, height,
                        br / 1000, fps, range, std, tfr,
                        colorFormatToString(COLOR_FormatSurface, bd));
                exhaustiveArgsList.add(testArgs);
            }
        }
        return CodecTestBase.prepareParamList(exhaustiveArgsList, isEncoder, needAudio, needVideo,
                false);
    }

    private void resetContext(boolean isAsync) {
        super.resetContext(isAsync, false);
        mAsyncHandleEncoder.resetContext();
        mSawInputEOSEnc = false;
        mSawOutputEOSEnc = false;
        mLatency = 0;
        mReviseLatency = false;
        mInputCountEnc = 0;
        mOutputCountEnc = 0;
        mInfoListEnc.clear();
        mLargestColorDelta = 0;
        mBadFrames = 0;
    }

    private void configureCodec(MediaFormat encFormat, boolean isAsync) {
        resetContext(isAsync);
        mAsyncHandleEncoder.setCallBack(mEncoder, isAsync);
        mEncoder.configure(encFormat, null, MediaCodec.CONFIGURE_FLAG_ENCODE, null);
        if (mEncoder.getInputFormat().containsKey(MediaFormat.KEY_LATENCY)) {
            mReviseLatency = true;
            mLatency = mEncoder.getInputFormat().getInteger(MediaFormat.KEY_LATENCY);
        }
        mInpSurface = mEncoder.createInputSurface();
        assertTrue("Surface is not valid \n" + mTestConfig + mTestEnv, mInpSurface.isValid());
        mEGLWindowInpSurface =
                new EGLWindowSurface(mInpSurface, mEncCfgParams.mInputBitDepth == 10);
        if (ENABLE_LOGS) {
            Log.v(LOG_TAG, "codec configured");
        }
    }

    private void dequeueEncoderOutput(int bufferIndex, MediaCodec.BufferInfo info) {
        if (ENABLE_LOGS) {
            Log.v(LOG_TAG, "encoder output: id: " + bufferIndex + " flags: " + info.flags +
                    " size: " + info.size + " timestamp: " + info.presentationTimeUs);
        }
        if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
            mSawOutputEOSEnc = true;
        }
        if (info.size > 0) {
            if (mSaveToMemEnc) {
                ByteBuffer buf = mEncoder.getOutputBuffer(bufferIndex);
                MediaCodec.BufferInfo copy = new MediaCodec.BufferInfo();
                copy.set(mOutputBuffEnc.getOutStreamSize(), info.size, info.presentationTimeUs,
                        info.flags);
                mInfoListEnc.add(copy);
                mOutputBuffEnc.saveToMemory(buf, info);
            }
            if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
                mOutputBuffEnc.saveOutPTS(info.presentationTimeUs);
                mOutputCountEnc++;
            }
        }
        mEncoder.releaseOutputBuffer(bufferIndex, false);
    }

    private void tryEncoderOutput(long timeOutUs) throws InterruptedException {
        if (mIsCodecInAsyncMode) {
            if (!mAsyncHandleEncoder.hasSeenError() && !mSawOutputEOSEnc) {
                int retry = 0;
                while (mReviseLatency) {
                    if (mAsyncHandleEncoder.hasOutputFormatChanged()) {
                        mReviseLatency = false;
                        int actualLatency = mAsyncHandleEncoder.getOutputFormat()
                                .getInteger(MediaFormat.KEY_LATENCY, mLatency);
                        if (mLatency < actualLatency) {
                            mLatency = actualLatency;
                            return;
                        }
                    } else {
                        if (retry > CodecTestBase.RETRY_LIMIT) {
                            throw new InterruptedException("did not receive output format " +
                                    "changed for encoder after " + CodecTestBase.Q_DEQ_TIMEOUT_US *
                                    CodecTestBase.RETRY_LIMIT + " us");
                        }
                        Thread.sleep(CodecTestBase.Q_DEQ_TIMEOUT_US / 1000);
                        retry++;
                    }
                }
                Pair<Integer, MediaCodec.BufferInfo> element = mAsyncHandleEncoder.getOutput();
                if (element != null) {
                    dequeueEncoderOutput(element.first, element.second);
                }
            }
        } else {
            MediaCodec.BufferInfo outInfo = new MediaCodec.BufferInfo();
            if (!mSawOutputEOSEnc) {
                int outputBufferId = mEncoder.dequeueOutputBuffer(outInfo, timeOutUs);
                if (outputBufferId >= 0) {
                    dequeueEncoderOutput(outputBufferId, outInfo);
                } else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                    mLatency = mEncoder.getOutputFormat()
                            .getInteger(MediaFormat.KEY_LATENCY, mLatency);
                }
            }
        }
    }

    private void waitForAllEncoderOutputs() throws InterruptedException {
        if (mIsCodecInAsyncMode) {
            while (!mAsyncHandleEncoder.hasSeenError() && !mSawOutputEOSEnc) {
                tryEncoderOutput(CodecTestBase.Q_DEQ_TIMEOUT_US);
            }
        } else {
            while (!mSawOutputEOSEnc) {
                tryEncoderOutput(CodecTestBase.Q_DEQ_TIMEOUT_US);
            }
        }
    }

    private void queueEOSEnc() {
        if (!mAsyncHandleEncoder.hasSeenError() && !mSawInputEOSEnc) {
            mEncoder.signalEndOfInputStream();
            mSawInputEOSEnc = true;
            if (ENABLE_LOGS) Log.d(LOG_TAG, "signalled end of stream");
        }
    }

    private void doWorkEnc(int frameLimit) throws InterruptedException {
        while (!mAsyncHandleEncoder.hasSeenError() && !mSawInputEOSEnc &&
                mInputCountEnc < frameLimit) {
            if (mInputCountEnc - mOutputCountEnc > mLatency) {
                tryEncoderOutput(CodecTestBase.Q_DEQ_TIMEOUT_US);
            }
            mEGLWindowInpSurface.makeCurrent();
            generateSurfaceFrame();
            mEGLWindowInpSurface
                    .setPresentationTime(computePresentationTime(mInputCountEnc) * 1000);
            if (ENABLE_LOGS) Log.d(LOG_TAG, "inputSurface swapBuffers");
            mEGLWindowInpSurface.swapBuffers();
            mInputCountEnc++;
        }
    }

    private long computePresentationTime(int frameIndex) {
        return frameIndex * 1000000L / mEncCfgParams.mFrameRate;
    }

    private void generateSurfaceFrame() {
        GLES20.glViewport(0, 0, mEncCfgParams.mWidth, mEncCfgParams.mHeight);
        GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
        for (int i = 0; i < mColorBars.length; i++) {
            int startX = i * mColorBarWidth;
            int endX = Math.min(startX + mColorBarWidth, mEncCfgParams.mWidth);
            GLES20.glScissor(startX, 0, endX, mEncCfgParams.mHeight);
            GLES20.glClearColor(mColorBars[i][0] / 255.0f, mColorBars[i][1] / 255.0f,
                    mColorBars[i][2] / 255.0f, 1.0f);
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
        }
    }

    boolean isColorClose(int actual, int expected) {
        int delta = Math.abs(actual - expected);
        if (delta > mLargestColorDelta) mLargestColorDelta = delta;
        int maxAllowedDelta = (mOutputCount >= STEADY_STATE_FRAME_INDEX ? STEADY_STATE_COLOR_DELTA :
                TRANSIENT_STATE_COLOR_DELTA);
        return (delta <= maxAllowedDelta);
    }

    private boolean checkSurfaceFrame(int frameIndex) {
        ByteBuffer pixelBuf = ByteBuffer.allocateDirect(4);
        boolean frameFailed = false;
        for (int i = 0; i < mColorBars.length; i++) {
            int x = mColorBarWidth * i + xOffset;
            int y = yOffset;
            int r, g, b;
            if (mEncCfgParams.mInputBitDepth == 10) {
                GLES30.glReadPixels(x, y, 1, 1, GL10.GL_RGBA, GLES30.GL_UNSIGNED_INT_2_10_10_10_REV,
                        pixelBuf);
                r = (pixelBuf.get(1) & 0x03) << 8 | (pixelBuf.get(0) & 0xFF);
                g = (pixelBuf.get(2) & 0x0F) << 6 | ((pixelBuf.get(1) >> 2) & 0x3F);
                b = (pixelBuf.get(3) & 0x3F) << 4 | ((pixelBuf.get(2) >> 4) & 0x0F);
                // Convert the values to 8 bit as comparisons later are with 8 bit RGB values
                r = (r + 2) >> 2;
                g = (g + 2) >> 2;
                b = (b + 2) >> 2;
            } else {
                GLES20.glReadPixels(x, y, 1, 1, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixelBuf);
                r = pixelBuf.get(0) & 0xFF;
                g = pixelBuf.get(1) & 0xFF;
                b = pixelBuf.get(2) & 0xFF;
            }
            if (!(isColorClose(r, mColorBars[i][0]) && isColorClose(g, mColorBars[i][1]) &&
                    isColorClose(b, mColorBars[i][2]))) {
                Log.w(LOG_TAG, "Bad frame " + frameIndex + " (rect={" + x + " " + y + "} :rgb=" +
                        r + "," + g + "," + b + " vs. expected " + mColorBars[i][0] +
                        "," + mColorBars[i][1] + "," + mColorBars[i][2] + ")");
                frameFailed = true;
            }
        }
        return frameFailed;
    }

    protected void dequeueOutput(int bufferIndex, MediaCodec.BufferInfo info) {
        if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
            mSawOutputEOS = true;
        }
        if (ENABLE_LOGS) {
            Log.v(LOG_TAG, "output: id: " + bufferIndex + " flags: " + info.flags + " size: " +
                    info.size + " timestamp: " + info.presentationTimeUs);
        }
        if (info.size > 0 && (info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
            mOutputBuff.saveOutPTS(info.presentationTimeUs);
            mOutputCount++;
        }
        mCodec.releaseOutputBuffer(bufferIndex, mSurface != null);
        if (info.size > 0) {
            mEGLWindowOutSurface.awaitNewImage();
            mEGLWindowOutSurface.drawImage();
            if (checkSurfaceFrame(mOutputCount - 1)) mBadFrames++;
        }
    }

    private void decodeElementaryStream(MediaFormat format)
            throws IOException, InterruptedException {
        mEGLWindowOutSurface = new OutputSurface(mEncCfgParams.mWidth, mEncCfgParams.mHeight,
                mEncCfgParams.mInputBitDepth == 10);
        mSurface = mEGLWindowOutSurface.getSurface();
        ArrayList<MediaFormat> formats = new ArrayList<>();
        formats.add(format);
        ArrayList<String> listOfDecoders =
                CodecDecoderTestBase.selectCodecs(mMime, formats, null, false);
        assertFalse("no suitable codecs found for : " + format + "\n" + mTestConfig + mTestEnv,
                listOfDecoders.isEmpty());
        for (String decoder : listOfDecoders) {
            if (mEncCfgParams.mInputBitDepth == 10
                    && !hasSupportForColorFormat(decoder, mMime, COLOR_FormatYUVP010)
                    && !hasSupportForColorFormat(decoder, mMime, COLOR_Format32bitABGR2101010)) {
                continue;
            }
            mCodec = MediaCodec.createByCodecName(decoder);
            configureCodec(format, true, true, false);
            mOutputBuff = new OutputManager();
            mCodec.start();
            doWork(mOutputBuffEnc.getBuffer(), mInfoListEnc);
            queueEOS();
            waitForAllOutputs();
            mCodec.stop();
            mCodec.release();
        }
        mSurface = null;
        mEGLWindowOutSurface.release();
        mEGLWindowOutSurface = null;
    }

    /**
     * Check description of class {@link EncodeDecodeAccuracyTest}
     */
    @ApiTest(apis = {"android.media.MediaFormat#KEY_COLOR_RANGE",
            "android.media.MediaFormat#KEY_COLOR_STANDARD",
            "android.media.MediaFormat#KEY_COLOR_TRANSFER"})
    @LargeTest
    @Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
    public void testEncodeDecodeAccuracyRGB() throws IOException, InterruptedException {
        MediaFormat format = mEncCfgParams.getFormat();
        final boolean isAsync = true;
        mSaveToMemEnc = true;
        mOutputBuffEnc = new OutputManager();
        {
            mEncoder = MediaCodec.createByCodecName(mCompName);
            mOutputBuffEnc.reset();
            mInfoListEnc.clear();
            configureCodec(format, isAsync);
            mEncoder.start();
            doWorkEnc(FRAMES_TO_ENCODE);
            queueEOSEnc();
            waitForAllEncoderOutputs();
            MediaFormat outputFormat = mEncoder.getOutputFormat();
            assertTrue(outputFormat.containsKey(MediaFormat.KEY_COLOR_RANGE));
            assertTrue(outputFormat.containsKey(MediaFormat.KEY_COLOR_STANDARD));
            assertTrue(outputFormat.containsKey(MediaFormat.KEY_COLOR_TRANSFER));
            if (mMime.equals(MediaFormat.MIMETYPE_VIDEO_AVC) ||
                    mMime.equals(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
                outputFormat.removeKey(MediaFormat.KEY_COLOR_RANGE);
                outputFormat.removeKey(MediaFormat.KEY_COLOR_STANDARD);
                outputFormat.removeKey(MediaFormat.KEY_COLOR_TRANSFER);
            }
            mEGLWindowInpSurface.release();
            mEGLWindowInpSurface = null;
            mInpSurface.release();
            mInpSurface = null;
            mEncoder.reset();
            mEncoder.release();
            decodeElementaryStream(outputFormat);
            assertEquals("color difference exceeds allowed tolerance in " + mBadFrames + " out of "
                    + FRAMES_TO_ENCODE + " frames \n" + mTestConfig + mTestEnv, 0, mBadFrames);
        }
    }
}

