/*
 * Copyright (C) 2020 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_FormatYUV420Flexible;
import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUVP010;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import android.media.MediaCodec;
import android.media.MediaCodecList;
import android.media.MediaFormat;
import android.mediav2.common.cts.CodecDecoderTestBase;
import android.mediav2.common.cts.CodecEncoderTestBase;
import android.mediav2.common.cts.CodecTestBase;
import android.mediav2.common.cts.EncoderConfigParams;
import android.mediav2.common.cts.OutputManager;
import android.opengl.GLES20;
import android.os.Build;
import android.util.Log;
import android.util.Pair;
import android.view.Surface;

import androidx.test.filters.SmallTest;

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

import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * Color Primaries, Color Standard and Color Transfer are essential information to display the
 * decoded YUV on an RGB display accurately. These 3 parameters can be signalled via containers
 * (mp4, mkv, ...) and some video standards also allow signalling this information in elementary
 * stream. Avc, Hevc, Av1, ... allow signalling this information in elementary stream, vpx relies
 * on webm/mkv or some other container for signalling.
 * <p>
 * If the encoder is configured with color aspects, then it is expected to place this information
 * in the elementary stream as-is if possible. The same goes for container as well. The test
 * validates this.
 * <p>
 * Hybrid log gamma transfer characteristics are applicable for high bit depth profiles. Standard
 * gamma curve characteristics are applicable for standard dynamic ranges. The test doesn't
 * exhaustively try all combinations of primaries, standard, transfer on all encoding profiles.
 * SDR specific characteristics are restricted to sdr profiles and HLG/HDR specific profiles are
 * restricted to HLG/HDR profiles.
 */
@RunWith(Parameterized.class)
public class EncoderColorAspectsTest extends CodecEncoderTestBase {
    private static final String LOG_TAG = EncoderColorAspectsTest.class.getSimpleName();

    private Surface mInpSurface;
    private EGLWindowSurface mEGLWindowInpSurface;

    private int mLatency;
    private boolean mReviseLatency;

    private static final ArrayList<String> IGNORE_COLOR_BOX_LIST = new ArrayList<>();

    static {
        IGNORE_COLOR_BOX_LIST.add(MediaFormat.MIMETYPE_VIDEO_AVC);
        IGNORE_COLOR_BOX_LIST.add(MediaFormat.MIMETYPE_VIDEO_HEVC);
    }

    private static boolean sIsAtLeastR = ApiLevelUtil.isAtLeast(Build.VERSION_CODES.R);

    public EncoderColorAspectsTest(String encoder, String mediaType,
            EncoderConfigParams encCfgParams, @SuppressWarnings("unused") String testLabel,
            String allTestParams) {
        super(encoder, mediaType, new EncoderConfigParams[]{encCfgParams}, allTestParams);
        mLatency = encCfgParams.mMaxBFrames;
    }

    private static void prepareArgsList(List<Object[]> exhaustiveArgsList, String[] mediaTypes,
            int[] ranges, int[] standards, int[] transfers, int colorFormat, int bitDepth) {
        // Assuming all combinations are supported by the standard which is true for AVC, HEVC, AV1,
        // VP8 and VP9.
        int[] maxBFrames = {0, 2};
        for (String mediaType : mediaTypes) {
            for (int range : ranges) {
                for (int standard : standards) {
                    for (int transfer : transfers) {
                        for (int maxBFrame : maxBFrames) {
                            if (!mediaType.equals(MediaFormat.MIMETYPE_VIDEO_AVC)
                                    && !mediaType.equals((MediaFormat.MIMETYPE_VIDEO_HEVC))
                                    && maxBFrame != 0) {
                                continue;
                            }
                            Object[] testArgs = new Object[3];
                            testArgs[0] = mediaType;
                            EncoderConfigParams cfg = new EncoderConfigParams.Builder(mediaType)
                                    .setRange(range)
                                    .setStandard(standard)
                                    .setTransfer(transfer)
                                    .setMaxBFrames(maxBFrame)
                                    .setColorFormat(colorFormat)
                                    .setInputBitDepth(bitDepth)
                                    .build();
                            testArgs[1] = cfg;
                            testArgs[2] = String.format("%s:%s:%s:%s:%d-bframes",
                                    rangeToString(range),
                                    colorStandardToString(standard),
                                    colorTransferToString(transfer),
                                    colorFormatToString(colorFormat, bitDepth),
                                    maxBFrame);
                            exhaustiveArgsList.add(testArgs);
                        }
                    }
                }
            }
        }
    }

    @Parameterized.Parameters(name = "{index}({0}_{1}_{3})")
    public static Collection<Object[]> input() {
        final boolean isEncoder = true;
        final boolean needAudio = false;
        final boolean needVideo = true;

        List<Object[]> exhaustiveArgsList = new ArrayList<>();

        String[] mediaTypes = {MediaFormat.MIMETYPE_VIDEO_AVC,
                MediaFormat.MIMETYPE_VIDEO_HEVC,
                MediaFormat.MIMETYPE_VIDEO_VP8,
                MediaFormat.MIMETYPE_VIDEO_VP9};
        // ColorAspects for SDR profiles
        int[] ranges = {-1,
                UNSPECIFIED,
                MediaFormat.COLOR_RANGE_FULL,
                MediaFormat.COLOR_RANGE_LIMITED};
        int[] standards = {-1,
                UNSPECIFIED,
                MediaFormat.COLOR_STANDARD_BT709,
                MediaFormat.COLOR_STANDARD_BT601_PAL,
                MediaFormat.COLOR_STANDARD_BT601_NTSC};
        int[] transfers = {-1,
                UNSPECIFIED,
                MediaFormat.COLOR_TRANSFER_LINEAR,
                MediaFormat.COLOR_TRANSFER_SDR_VIDEO};

        prepareArgsList(exhaustiveArgsList, mediaTypes, ranges, standards, transfers,
                COLOR_FormatYUV420Flexible, -1);
        prepareArgsList(exhaustiveArgsList, mediaTypes, ranges, standards, transfers,
                COLOR_FormatSurface, 8);
        // P010 support was added in Android T, hence limit the following tests to Android T and
        // above
        if (IS_AT_LEAST_T) {
            // ColorAspects for HDR profiles
            String[] mediaTypesHighBitDepth = {MediaFormat.MIMETYPE_VIDEO_AVC,
                    MediaFormat.MIMETYPE_VIDEO_HEVC,
                    MediaFormat.MIMETYPE_VIDEO_VP9};
            int[] standardsHighBitDepth = {-1,
                    UNSPECIFIED,
                    MediaFormat.COLOR_STANDARD_BT709,
                    MediaFormat.COLOR_STANDARD_BT2020};
            int[] transfersHighBitDepth = {-1,
                    UNSPECIFIED,
                    MediaFormat.COLOR_TRANSFER_HLG,
                    MediaFormat.COLOR_TRANSFER_ST2084};

            prepareArgsList(exhaustiveArgsList, mediaTypesHighBitDepth, ranges,
                    standardsHighBitDepth, transfersHighBitDepth, COLOR_FormatYUVP010, -1);
            prepareArgsList(exhaustiveArgsList, mediaTypesHighBitDepth, ranges,
                    standardsHighBitDepth, transfersHighBitDepth, COLOR_FormatSurface, 10);
        }
        return prepareParamList(exhaustiveArgsList, isEncoder, needAudio, needVideo, false);
    }

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

    private void generateSurfaceFrame() {
        GLES20.glViewport(0, 0, mActiveEncCfg.mWidth, mActiveEncCfg.mHeight);
        GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
        GLES20.glClearColor(128.0f, 128.0f, 128.0f, 1.0f);
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    }

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

    protected void queueEOS() throws InterruptedException {
        if (mActiveEncCfg.mColorFormat != COLOR_FormatSurface) {
            super.queueEOS();
        } else {
            if (!mAsyncHandle.hasSeenError() && !mSawInputEOS) {
                mCodec.signalEndOfInputStream();
                mSawInputEOS = true;
                if (ENABLE_LOGS) Log.d(LOG_TAG, "signalled end of stream");
            }
        }
    }

    protected void doWork(int frameLimit) throws IOException, InterruptedException {
        if (mActiveEncCfg.mColorFormat != COLOR_FormatSurface) {
            super.doWork(frameLimit);
        } else {
            while (!mAsyncHandle.hasSeenError() && !mSawInputEOS &&
                    mInputCount < frameLimit) {
                if (mInputCount - mOutputCount > mLatency) {
                    tryEncoderOutput(CodecTestBase.Q_DEQ_TIMEOUT_US);
                }
                mEGLWindowInpSurface.makeCurrent();
                generateSurfaceFrame();
                long pts = computePresentationTime(mInputCount);
                mEGLWindowInpSurface.setPresentationTime(pts * 1000);
                if (ENABLE_LOGS) Log.d(LOG_TAG, "inputSurface swapBuffers");
                mEGLWindowInpSurface.swapBuffers();
                mOutputBuff.saveInPTS(pts);
                mInputCount++;
            }
        }
    }

    /**
     * ColorAspects are passed to the encoder at the time of configuration. The encoder is
     * expected to pass this information to outputFormat() so that muxer can use this information
     * to populate color metadata. If the bitstream is capable of capturing color metadata
     * losslessly then encoder is also expected to use this information during bitstream
     * generation. Although a given media type can be muxed using many containers, the test does
     * not use all available ones. Instead the most preferred one is selected.
     * vpx streams are muxed using webm writer and others are muxed using mp4 writer.
     * Briefly, the test checks OMX/c2 framework, plugins, encoder, muxer ability to SIGNAL color
     * metadata.
     */
    @ApiTest(apis = {"android.media.MediaFormat#KEY_COLOR_RANGE",
            "android.media.MediaFormat#KEY_COLOR_STANDARD",
            "android.media.MediaFormat#KEY_COLOR_TRANSFER"})
    @SmallTest
    @Test(timeout = PER_TEST_TIMEOUT_SMALL_TEST_MS)
    public void testColorAspects() throws IOException, InterruptedException {
        Assume.assumeTrue("Test introduced with Android 11", sIsAtLeastR);

        mActiveEncCfg = mEncCfgParams[0];
        if (mActiveEncCfg.mInputBitDepth > 8) {
            // Check if encoder is capable of supporting HDR profiles.
            // Previous check doesn't verify this as profile isn't set in the format
            Assume.assumeTrue(mCodecName + " doesn't support HDR encoding",
                    CodecTestBase.doesCodecSupportHDRProfile(mCodecName, mMime));

            // Encoder surface mode tests are to be enabled only if an encoder supports
            // COLOR_Format32bitABGR2101010
            if (mActiveEncCfg.mColorFormat == COLOR_FormatSurface) {
                Assume.assumeTrue(mCodecName + " doesn't support RGBA1010102",
                        hasSupportForColorFormat(mCodecName, mMime, COLOR_Format32bitABGR2101010));
            } else {
                Assume.assumeTrue(mCodecName + " doesn't support " + colorFormatToString(
                                mActiveEncCfg.mColorFormat, mActiveEncCfg.mInputBitDepth),
                        hasSupportForColorFormat(mCodecName, mMime, mActiveEncCfg.mColorFormat));
            }
        }

        if (mActiveEncCfg.mColorFormat == COLOR_FormatSurface) {
            Assume.assumeTrue("Surface mode tests are limited to devices launching with Android T",
                    FIRST_SDK_IS_AT_LEAST_T && VNDK_IS_AT_LEAST_T);
            // Few cuttlefish specific color conversion issues were fixed after Android T.
            if (MediaUtils.onCuttlefish()) {
                Assume.assumeTrue("Color conversion related tests are not valid on cuttlefish "
                        + "releases through android T", IS_AT_LEAST_U);
            }
        } else {
            mActiveRawRes = EncoderInput.getRawResource(mActiveEncCfg);
            assertNotNull("no raw resource found for testing config : " + mActiveEncCfg
                    + mTestConfig + mTestEnv, mActiveRawRes);
            setUpSource(mActiveRawRes.mFileName);
        }

        {
            mSaveToMem = true;
            mOutputBuff = new OutputManager();
            mCodec = MediaCodec.createByCodecName(mCodecName);

            // When in surface mode, encoder needs to be configured in async mode
            boolean isAsync = mActiveEncCfg.mColorFormat == COLOR_FormatSurface;
            configureCodec(mActiveEncCfg.getFormat(), isAsync, true, true);

            if (mActiveEncCfg.mColorFormat == COLOR_FormatSurface) {
                mInpSurface = mCodec.createInputSurface();
                assertTrue("Surface is not valid \n" + mTestConfig + mTestEnv,
                        mInpSurface.isValid());
                mEGLWindowInpSurface =
                        new EGLWindowSurface(mInpSurface, mActiveEncCfg.mInputBitDepth == 10);
                if (mCodec.getInputFormat().containsKey(MediaFormat.KEY_LATENCY)) {
                    mReviseLatency = true;
                    mLatency = mCodec.getInputFormat().getInteger(MediaFormat.KEY_LATENCY);
                }
            }
            mCodec.start();
            doWork(4);
            queueEOS();
            waitForAllOutputs();

            if (mEGLWindowInpSurface != null) {
                mEGLWindowInpSurface.release();
                mEGLWindowInpSurface = null;
            }
            if (mInpSurface != null) {
                mInpSurface.release();
                mInpSurface = null;
            }

            // verify if the out fmt contains color aspects as expected
            MediaFormat fmt = mCodec.getOutputFormat();
            validateColorAspects(fmt, mActiveEncCfg.mRange, mActiveEncCfg.mStandard,
                    mActiveEncCfg.mTransfer);
            mCodec.stop();
            mCodec.release();

            int muxerFormat = getMuxerFormatForMediaType(mMime);
            String tmpPath = getTempFilePath((mActiveEncCfg.mInputBitDepth == 10) ? "10bit" : "");
            muxOutput(tmpPath, muxerFormat, fmt, mOutputBuff.getBuffer(), mInfoList);

            // verify if the muxed file contains color aspects as expected
            MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
            String decoder = codecList.findDecoderForFormat(mActiveEncCfg.getFormat());
            assertNotNull("Device advertises support for encoding " + mActiveEncCfg.getFormat()
                    + " but not decoding it. \n" + mTestConfig + mTestEnv, decoder);
            CodecDecoderTestBase cdtb = new CodecDecoderTestBase(decoder, mMime, tmpPath,
                    mAllTestParams);
            cdtb.validateColorAspects(mActiveEncCfg.mRange, mActiveEncCfg.mStandard,
                    mActiveEncCfg.mTransfer, false);

            // if color metadata can also be signalled via elementary stream then verify if the
            // elementary stream contains color aspects as expected
            if (IGNORE_COLOR_BOX_LIST.contains(mMime)) {
                cdtb.validateColorAspects(mActiveEncCfg.mRange, mActiveEncCfg.mStandard,
                        mActiveEncCfg.mTransfer, true);
            }
            new File(tmpPath).delete();
        }
    }
}
