/*
 * 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_FormatYUV420Flexible;
import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUVP010;
import static android.media.MediaCodecInfo.CodecProfileLevel.*;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaMuxer;
import android.mediav2.common.cts.EncoderConfigParams;
import android.mediav2.common.cts.EncoderTestBase;
import android.mediav2.common.cts.OutputManager;
import android.util.Log;
import android.util.Pair;

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

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.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

/**
 * EncoderProfileLevelTest validates the profile, level information advertised by the component
 * in its codec capabilities. The test sets profile and level keys in media format and uses it
 * during encoder configuration. Upon successful configuration, frames are queued for encoding
 * (byte buffer mode) and the encoded output (bitstream) is expected to contain the same profile
 * and level information that was used during configure.
 * <p>
 * NOTE: The test configures profile, level information basing on standard guidelines, not
 * arbitrarily so encoders ARE expected to place these values in the bitstream as-is.
 * <p>
 * The test additionally checks if the output format returned by component contains same profile
 * and level information. Having output format contain this information is useful during muxing
 * <p>
 * As per cdd, if a device contains an encoder capable of encoding a profile/level combination
 * then it should contain a decoder capable of decoding the same profile/level combination. This
 * is verified.
 * <p>
 * If device implementations support encoding in a media type, then as per cdd they are expected to
 * handle certain profile and level configurations. This is verified as well.
 */
@RunWith(Parameterized.class)
public class EncoderProfileLevelTest extends EncoderTestBase {
    private static final String LOG_TAG = EncoderProfileLevelTest.class.getSimpleName();
    private static final HashMap<String, Pair<int[], Integer>> PROFILE_LEVEL_CDD = new HashMap<>();

    public EncoderProfileLevelTest(String encoder, String mediaType,
            EncoderConfigParams[] encCfgParams, @SuppressWarnings("unused") String testLabel,
            String allTestParams) {
        super(encoder, mediaType, encCfgParams, allTestParams);
    }

    private static EncoderConfigParams[] getVideoEncoderCfgParams(String mediaType, int bitRate,
            int width, int height, int frameRate, int colorFormat, int maxBframe, int[] profiles) {
        ArrayList<EncoderConfigParams> cfgParams = new ArrayList<>();
        for (int profile : profiles) {
            int level = getMinLevel(mediaType, width, height, frameRate, bitRate, profile);
            if (mediaType.equals(MediaFormat.MIMETYPE_VIDEO_AVC)
                    && maxBframe != 0
                    && (profile == AVCProfileBaseline
                    || profile == AVCProfileConstrainedBaseline)) {
                continue;
            }
            cfgParams.add(new EncoderConfigParams.Builder(mediaType)
                    .setBitRate(bitRate)
                    .setWidth(width)
                    .setHeight(height)
                    .setFrameRate(frameRate)
                    .setMaxBFrames(maxBframe)
                    .setProfile(profile)
                    .setLevel(level)
                    .setColorFormat(colorFormat)
                    .build());
        }
        return cfgParams.toArray(new EncoderConfigParams[0]);
    }

    private static EncoderConfigParams[] getAudioEncoderCfgParams(String mediaType, int bitRate,
            int sampleRate, int channelCount, int[] profiles) {
        EncoderConfigParams[] cfgParams = new EncoderConfigParams[profiles.length];
        for (int i = 0; i < profiles.length; i++) {
            cfgParams[i] = new EncoderConfigParams.Builder(mediaType)
                    .setBitRate(bitRate)
                    .setSampleRate(sampleRate)
                    .setChannelCount(channelCount)
                    .setProfile(profiles[i])
                    .build();
        }
        return cfgParams;
    }

    @Parameterized.Parameters(name = "{index}({0}_{1}_{3})")
    public static Collection<Object[]> input() {
        final boolean isEncoder = true;
        final boolean needAudio = true;
        final boolean needVideo = true;
        final Object[][] exhaustiveArgsList = new Object[][]{
                // Audio - CodecMime, bit-rate, sample rate, channel count
                {MediaFormat.MIMETYPE_AUDIO_AAC, 64000, 48000, 1, -1},
                {MediaFormat.MIMETYPE_AUDIO_AAC, 128000, 48000, 2, -1},
                // Video - CodecMime, bit-rate, height, width, frame-rate
                // TODO (b/151423508)
                /*{MediaFormat.MIMETYPE_VIDEO_AVC, 64000, 176, 144, 15},
                {MediaFormat.MIMETYPE_VIDEO_AVC, 128000, 176, 144, 15},
                {MediaFormat.MIMETYPE_VIDEO_AVC, 192000, 352, 288, 7},
                {MediaFormat.MIMETYPE_VIDEO_AVC, 384000, 352, 288, 15},*/
                {MediaFormat.MIMETYPE_VIDEO_AVC, 768000, 352, 288, 30},
                {MediaFormat.MIMETYPE_VIDEO_AVC, 2000000, 352, 288, 30},
                // TODO (b/151423508)
                /*{MediaFormat.MIMETYPE_VIDEO_AVC, 4000000, 352, 576, 25},
                {MediaFormat.MIMETYPE_VIDEO_AVC, 4000000, 720, 576, 12},
                {MediaFormat.MIMETYPE_VIDEO_AVC, 10000000, 720, 576, 25},*/
                {MediaFormat.MIMETYPE_VIDEO_AVC, 14000000, 1280, 720, 30},
                {MediaFormat.MIMETYPE_VIDEO_AVC, 20000000, 1280, 1024, 42},
                {MediaFormat.MIMETYPE_VIDEO_AVC, 20000000, 2048, 1024, 30},
                {MediaFormat.MIMETYPE_VIDEO_AVC, 50000000, 2048, 1024, 30},
                {MediaFormat.MIMETYPE_VIDEO_AVC, 50000000, 2048, 1080, 60},
                {MediaFormat.MIMETYPE_VIDEO_AVC, 135000000, 3672, 1536, 25},
                {MediaFormat.MIMETYPE_VIDEO_AVC, 240000000, 4096, 2304, 25},
                {MediaFormat.MIMETYPE_VIDEO_AVC, 240000000, 4096, 2304, 50},
                {MediaFormat.MIMETYPE_VIDEO_AVC, 240000000, 8192, 4320, 30},
                {MediaFormat.MIMETYPE_VIDEO_AVC, 480000000, 8192, 4320, 60},
                {MediaFormat.MIMETYPE_VIDEO_AVC, 800000000, 8192, 4320, 120},

                {MediaFormat.MIMETYPE_VIDEO_MPEG2, 4000000, 352, 288, 30},
                {MediaFormat.MIMETYPE_VIDEO_MPEG2, 15000000, 720, 576, 30},
                {MediaFormat.MIMETYPE_VIDEO_MPEG2, 60000000, 1440, 1088, 60},
                {MediaFormat.MIMETYPE_VIDEO_MPEG2, 80000000, 1920, 1088, 60},
                {MediaFormat.MIMETYPE_VIDEO_MPEG2, 80000000, 1920, 1088, 60},

                {MediaFormat.MIMETYPE_VIDEO_MPEG4, 64000, 176, 144, 15},
                {MediaFormat.MIMETYPE_VIDEO_MPEG4, 64000, 176, 144, 30},
                {MediaFormat.MIMETYPE_VIDEO_MPEG4, 128000, 176, 144, 15},
                {MediaFormat.MIMETYPE_VIDEO_MPEG4, 128000, 352, 288, 30},
                {MediaFormat.MIMETYPE_VIDEO_MPEG4, 384000, 352, 288, 30},
                {MediaFormat.MIMETYPE_VIDEO_MPEG4, 4000000, 640, 480, 30},
                {MediaFormat.MIMETYPE_VIDEO_MPEG4, 8000000, 720, 576, 30},
                {MediaFormat.MIMETYPE_VIDEO_MPEG4, 12000000, 1280, 720, 30},
                {MediaFormat.MIMETYPE_VIDEO_MPEG4, 128000, 176, 144, 30},
                {MediaFormat.MIMETYPE_VIDEO_MPEG4, 384000, 352, 288, 30},
                {MediaFormat.MIMETYPE_VIDEO_MPEG4, 768000, 352, 288, 30},
                {MediaFormat.MIMETYPE_VIDEO_MPEG4, 1500000, 352, 288, 30},
                {MediaFormat.MIMETYPE_VIDEO_MPEG4, 3000000, 704, 576, 30},
                {MediaFormat.MIMETYPE_VIDEO_MPEG4, 8000000, 720, 576, 30},

                // TODO (b/151430764)
                /*{MediaFormat.MIMETYPE_VIDEO_VP9, 200000, 256, 144, 15},
                {MediaFormat.MIMETYPE_VIDEO_VP9, 8000000, 384, 192, 30},
                {MediaFormat.MIMETYPE_VIDEO_VP9, 1800000, 480, 256, 30},
                {MediaFormat.MIMETYPE_VIDEO_VP9, 3600000, 640, 384, 30},
                {MediaFormat.MIMETYPE_VIDEO_VP9, 7200000, 1080, 512, 30},*/
                {MediaFormat.MIMETYPE_VIDEO_VP9, 12000000, 1280, 768, 30},
                {MediaFormat.MIMETYPE_VIDEO_VP9, 18000000, 2048, 1088, 30},
                {MediaFormat.MIMETYPE_VIDEO_VP9, 30000000, 2048, 1088, 60},
                {MediaFormat.MIMETYPE_VIDEO_VP9, 60000000, 4096, 2176, 30},
                {MediaFormat.MIMETYPE_VIDEO_VP9, 120000000, 4096, 2176, 60},
                {MediaFormat.MIMETYPE_VIDEO_VP9, 180000000, 4096, 2176, 120},
                {MediaFormat.MIMETYPE_VIDEO_VP9, 180000000, 8192, 4352, 30},
                {MediaFormat.MIMETYPE_VIDEO_VP9, 240000000, 8192, 4352, 60},
                {MediaFormat.MIMETYPE_VIDEO_VP9, 480000000, 8192, 4352, 120},

                {MediaFormat.MIMETYPE_VIDEO_H263, 64000, 176, 144, 15},
                {MediaFormat.MIMETYPE_VIDEO_H263, 128000, 176, 144, 15},
                {MediaFormat.MIMETYPE_VIDEO_H263, 128000, 176, 144, 30},
                {MediaFormat.MIMETYPE_VIDEO_H263, 128000, 352, 288, 15},
                {MediaFormat.MIMETYPE_VIDEO_H263, 384000, 352, 288, 30},
                {MediaFormat.MIMETYPE_VIDEO_H263, 2048000, 352, 288, 30},
                {MediaFormat.MIMETYPE_VIDEO_H263, 4096000, 352, 240, 60},
                {MediaFormat.MIMETYPE_VIDEO_H263, 4096000, 352, 288, 50},
                {MediaFormat.MIMETYPE_VIDEO_H263, 8192000, 720, 240, 60},
                {MediaFormat.MIMETYPE_VIDEO_H263, 8192000, 720, 288, 50},
                {MediaFormat.MIMETYPE_VIDEO_H263, 16384000, 720, 480, 60},
                {MediaFormat.MIMETYPE_VIDEO_H263, 16384000, 720, 576, 50},

                {MediaFormat.MIMETYPE_VIDEO_HEVC, 128000, 176, 144, 15},
                {MediaFormat.MIMETYPE_VIDEO_HEVC, 1500000, 352, 288, 30},
                // TODO (b/152576008) - Limit HEVC Encoder test to 512x512
                {MediaFormat.MIMETYPE_VIDEO_HEVC, 3000000, 512, 512, 30},
                //{MediaFormat.MIMETYPE_VIDEO_HEVC, 3000000, 640, 360, 30},
                //{MediaFormat.MIMETYPE_VIDEO_HEVC, 6000000, 960, 540, 30},
                {MediaFormat.MIMETYPE_VIDEO_HEVC, 10000000, 1280, 720, 33},
                {MediaFormat.MIMETYPE_VIDEO_HEVC, 12000000, 2048, 1080, 30},
                {MediaFormat.MIMETYPE_VIDEO_HEVC, 20000000, 2048, 1080, 60},
                {MediaFormat.MIMETYPE_VIDEO_HEVC, 25000000, 4096, 2160, 30},
                {MediaFormat.MIMETYPE_VIDEO_HEVC, 40000000, 4096, 2160, 60},
                {MediaFormat.MIMETYPE_VIDEO_HEVC, 60000000, 4096, 2160, 120},
                {MediaFormat.MIMETYPE_VIDEO_HEVC, 60000000, 8192, 4320, 30},
                {MediaFormat.MIMETYPE_VIDEO_HEVC, 120000000, 8192, 4320, 60},
                {MediaFormat.MIMETYPE_VIDEO_HEVC, 240000000, 8192, 4320, 120},

                {MediaFormat.MIMETYPE_VIDEO_AV1, 1500000, 426, 240, 30},
                {MediaFormat.MIMETYPE_VIDEO_AV1, 3000000, 640, 360, 30},
                {MediaFormat.MIMETYPE_VIDEO_AV1, 6000000, 854, 480, 30},
                {MediaFormat.MIMETYPE_VIDEO_AV1, 10000000, 1280, 720, 30},
                {MediaFormat.MIMETYPE_VIDEO_AV1, 12000000, 1920, 1080, 30},
                {MediaFormat.MIMETYPE_VIDEO_AV1, 20000000, 1920, 1080, 60},
                {MediaFormat.MIMETYPE_VIDEO_AV1, 30000000, 3840, 2160, 30},
                {MediaFormat.MIMETYPE_VIDEO_AV1, 40000000, 3840, 2160, 60},
                {MediaFormat.MIMETYPE_VIDEO_AV1, 60000000, 3840, 2160, 120},
                {MediaFormat.MIMETYPE_VIDEO_AV1, 60000000, 7680, 4320, 30},
                {MediaFormat.MIMETYPE_VIDEO_AV1, 100000000, 7680, 4320, 60},
                {MediaFormat.MIMETYPE_VIDEO_AV1, 160000000, 7680, 4320, 120},

                {MediaFormat.MIMETYPE_VIDEO_VP8, 512000, 176, 144, 20},
                {MediaFormat.MIMETYPE_VIDEO_VP8, 512000, 480, 360, 20},
        };
        final List<Object[]> argsList = new ArrayList<>();
        final int[] maxBFrames = {0, 2};
        for (Object[] arg : exhaustiveArgsList) {
            final String mediaType = (String) arg[0];
            boolean isVideo = mediaType.startsWith("video/");
            final int br = (int) arg[1];
            final int param1 = (int) arg[2];
            final int param2 = (int) arg[3];
            final int fps = (int) arg[4];
            Object[] testArgs = new Object[3];
            testArgs[0] = arg[0];
            if (isVideo) {
                for (int maxBframe : maxBFrames) {
                    if (maxBframe != 0) {
                        if (!mediaType.equals(MediaFormat.MIMETYPE_VIDEO_AVC)
                                && !mediaType.equals(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
                            continue;
                        }
                    }
                    testArgs[1] = getVideoEncoderCfgParams(mediaType, br, param1, param2, fps,
                            COLOR_FormatYUV420Flexible, maxBframe,
                            Objects.requireNonNull(PROFILE_SDR_MAP.get(mediaType)));
                    testArgs[2] = String.format("%dkbps_%dx%d_%dfps_%s_%d-bframes", br / 1000,
                            param1, param2, fps, colorFormatToString(COLOR_FormatYUV420Flexible, 8),
                            maxBframe);
                    argsList.add(testArgs);
                }
            } else {
                testArgs[1] = getAudioEncoderCfgParams(mediaType, br, param1, param2,
                        Objects.requireNonNull(PROFILE_SDR_MAP.get(mediaType)));
                testArgs[2] = String.format("%dkbps_%dkHz_%dch", br / 1000, param1 / 1000, param2);
                argsList.add(testArgs);
            }

            // P010 support was added in Android T, hence limit the following tests to Android
            // T and above
            if (IS_AT_LEAST_T && PROFILE_HLG_MAP.get(mediaType) != null) {
                for (int maxBframe : maxBFrames) {
                    if (maxBframe != 0) {
                        if (!mediaType.equals(MediaFormat.MIMETYPE_VIDEO_HEVC)
                                && !mediaType.equals(MediaFormat.MIMETYPE_VIDEO_AVC)) {
                            continue;
                        }
                    }
                    testArgs = new Object[3];
                    testArgs[0] = arg[0];
                    testArgs[1] = getVideoEncoderCfgParams(mediaType, br, param1, param2, fps,
                            COLOR_FormatYUVP010, maxBframe,
                            Objects.requireNonNull(PROFILE_HLG_MAP.get(mediaType)));
                    testArgs[2] = String.format("%dkbps_%dx%d_%dfps_%s_%d-bframes", br / 1000,
                            param1, param2, fps, colorFormatToString(COLOR_FormatYUVP010, 10),
                            maxBframe);
                    argsList.add(testArgs);
                }
            }
        }
        return prepareParamList(argsList, isEncoder, needAudio, needVideo, false);
    }

    static {
        PROFILE_LEVEL_CDD.put(MediaFormat.MIMETYPE_AUDIO_AAC,
                new Pair<>(new int[]{AACObjectLC, AACObjectHE, AACObjectELD}, -1));
        PROFILE_LEVEL_CDD.put(MediaFormat.MIMETYPE_VIDEO_H263,
                new Pair<>(new int[]{H263ProfileBaseline}, H263Level45));
        PROFILE_LEVEL_CDD.put(MediaFormat.MIMETYPE_VIDEO_AVC,
                new Pair<>(new int[]{AVCProfileBaseline}, AVCLevel3));
        PROFILE_LEVEL_CDD.put(MediaFormat.MIMETYPE_VIDEO_HEVC,
                new Pair<>(new int[]{HEVCProfileMain}, HEVCMainTierLevel3));
        PROFILE_LEVEL_CDD.put(MediaFormat.MIMETYPE_VIDEO_VP8,
                new Pair<>(new int[]{VP8ProfileMain}, VP8Level_Version0));
        PROFILE_LEVEL_CDD.put(MediaFormat.MIMETYPE_VIDEO_VP9,
                new Pair<>(new int[]{VP9Profile0}, VP9Level3));
    }

    private static int getMinLevel(String mime, int width, int height, int frameRate, int bitrate,
            int profile) {
        switch (mime) {
            case MediaFormat.MIMETYPE_VIDEO_AVC:
                return getMinLevelAVC(width, height, frameRate, bitrate);
            case MediaFormat.MIMETYPE_VIDEO_HEVC:
                return getMinLevelHEVC(width, height, frameRate, bitrate);
            case MediaFormat.MIMETYPE_VIDEO_H263:
                return getMinLevelH263(width, height, frameRate, bitrate);
            case MediaFormat.MIMETYPE_VIDEO_MPEG2:
                return getMinLevelMPEG2(width, height, frameRate, bitrate);
            case MediaFormat.MIMETYPE_VIDEO_MPEG4:
                return getMinLevelMPEG4(width, height, frameRate, bitrate, profile);
            // complex features disabled in VP8 Level/Version 0
            case MediaFormat.MIMETYPE_VIDEO_VP8:
                return VP8Level_Version0;
            case MediaFormat.MIMETYPE_VIDEO_VP9:
                return getMinLevelVP9(width, height, frameRate, bitrate);
            case MediaFormat.MIMETYPE_VIDEO_AV1:
                return getMinLevelAV1(width, height, frameRate, bitrate);
            default:
                return -1;
        }
    }

    private static int getMinLevelAVC(int width, int height, int frameRate, int bitrate) {
        class LevelLimitAVC {
            private LevelLimitAVC(int level, int mbsPerSec, long mbs, int bitrate) {
                this.level = level;
                this.mbsPerSec = mbsPerSec;
                this.mbs = mbs;
                this.bitrate = bitrate;
            }

            private final int level;
            private final int mbsPerSec;
            private final long mbs;
            private final int bitrate;
        }
        LevelLimitAVC[] limitsAVC = {
                new LevelLimitAVC(AVCLevel1, 1485, 99, 64000),
                new LevelLimitAVC(AVCLevel1b, 1485, 99, 128000),
                new LevelLimitAVC(AVCLevel11, 3000, 396, 192000),
                new LevelLimitAVC(AVCLevel12, 6000, 396, 384000),
                new LevelLimitAVC(AVCLevel13, 11880, 396, 768000),
                new LevelLimitAVC(AVCLevel2, 11880, 396, 2000000),
                new LevelLimitAVC(AVCLevel21, 19800, 792, 4000000),
                new LevelLimitAVC(AVCLevel22, 20250, 1620, 4000000),
                new LevelLimitAVC(AVCLevel3, 40500, 1620, 10000000),
                new LevelLimitAVC(AVCLevel31, 108000, 3600, 14000000),
                new LevelLimitAVC(AVCLevel32, 216000, 5120, 20000000),
                new LevelLimitAVC(AVCLevel4, 245760, 8192, 20000000),
                new LevelLimitAVC(AVCLevel41, 245760, 8192, 50000000),
                new LevelLimitAVC(AVCLevel42, 522240, 8704, 50000000),
                new LevelLimitAVC(AVCLevel5, 589824, 22080, 135000000),
                new LevelLimitAVC(AVCLevel51, 983040, 36864, 240000000),
                new LevelLimitAVC(AVCLevel52, 2073600, 36864, 240000000),
                new LevelLimitAVC(AVCLevel6, 4177920, 139264, 240000000),
                new LevelLimitAVC(AVCLevel61, 8355840, 139264, 480000000),
                new LevelLimitAVC(AVCLevel62, 16711680, 139264, 800000000),
        };
        int mbs = ((width + 15) / 16) * ((height + 15) / 16);
        float mbsPerSec = mbs * frameRate;
        for (LevelLimitAVC levelLimitsAVC : limitsAVC) {
            if (mbs <= levelLimitsAVC.mbs && mbsPerSec <= levelLimitsAVC.mbsPerSec
                    && bitrate <= levelLimitsAVC.bitrate) {
                return levelLimitsAVC.level;
            }
        }
        // if none of the levels suffice, select the highest level
        return AVCLevel62;
    }

    private static int getMinLevelHEVC(int width, int height, int frameRate, int bitrate) {
        class LevelLimitHEVC {
            private LevelLimitHEVC(int level, int frameRate, long samples, int bitrate) {
                this.level = level;
                this.frameRate = frameRate;
                this.samples = samples;
                this.bitrate = bitrate;
            }

            private final int level;
            private final int frameRate;
            private final long samples;
            private final int bitrate;
        }
        LevelLimitHEVC[] limitsHEVC = {
                new LevelLimitHEVC(HEVCMainTierLevel1, 15, 36864, 128000),
                new LevelLimitHEVC(HEVCMainTierLevel2, 30, 122880, 1500000),
                new LevelLimitHEVC(HEVCMainTierLevel21, 30, 245760, 3000000),
                new LevelLimitHEVC(HEVCMainTierLevel3, 30, 552960, 6000000),
                new LevelLimitHEVC(HEVCMainTierLevel31, 30, 983040, 10000000),
                new LevelLimitHEVC(HEVCMainTierLevel4, 30, 2228224, 12000000),
                new LevelLimitHEVC(HEVCHighTierLevel4, 30, 2228224, 30000000),
                new LevelLimitHEVC(HEVCMainTierLevel41, 60, 2228224, 20000000),
                new LevelLimitHEVC(HEVCHighTierLevel41, 60, 2228224, 50000000),
                new LevelLimitHEVC(HEVCMainTierLevel5, 30, 8912896, 25000000),
                new LevelLimitHEVC(HEVCHighTierLevel5, 30, 8912896, 100000000),
                new LevelLimitHEVC(HEVCMainTierLevel51, 60, 8912896, 40000000),
                new LevelLimitHEVC(HEVCHighTierLevel51, 60, 8912896, 160000000),
                new LevelLimitHEVC(HEVCMainTierLevel52, 120, 8912896, 60000000),
                new LevelLimitHEVC(HEVCHighTierLevel52, 120, 8912896, 240000000),
                new LevelLimitHEVC(HEVCMainTierLevel6, 30, 35651584, 60000000),
                new LevelLimitHEVC(HEVCHighTierLevel6, 30, 35651584, 240000000),
                new LevelLimitHEVC(HEVCMainTierLevel61, 60, 35651584, 120000000),
                new LevelLimitHEVC(HEVCHighTierLevel61, 60, 35651584, 480000000),
                new LevelLimitHEVC(HEVCMainTierLevel62, 120, 35651584, 240000000),
                new LevelLimitHEVC(HEVCHighTierLevel62, 120, 35651584, 800000000),
        };
        int samples = width * height;
        for (LevelLimitHEVC levelLimitsHEVC : limitsHEVC) {
            if (samples <= levelLimitsHEVC.samples && frameRate <= levelLimitsHEVC.frameRate
                    && bitrate <= levelLimitsHEVC.bitrate) {
                return levelLimitsHEVC.level;
            }
        }
        // if none of the levels suffice, select the highest level
        return HEVCHighTierLevel62;
    }

    private static int getMinLevelH263(int width, int height, int frameRate, int bitrate) {
        class LevelLimitH263 {
            private LevelLimitH263(int level, int height, int width, int frameRate,
                    int bitrate) {
                this.level = level;
                this.height = height;
                this.width = width;
                this.frameRate = frameRate;
                this.bitrate = bitrate;
            }

            private final int level;
            private final int height;
            private final int width;
            private final int frameRate;
            private final int bitrate;
        }
        LevelLimitH263[] limitsH263 = {
                new LevelLimitH263(H263Level10, 176, 144, 15, 64000),
                new LevelLimitH263(H263Level45, 176, 144, 15, 128000),
                new LevelLimitH263(H263Level20, 176, 144, 30, 128000),
                new LevelLimitH263(H263Level20, 352, 288, 15, 128000),
                new LevelLimitH263(H263Level30, 352, 288, 30, 384000),
                new LevelLimitH263(H263Level40, 352, 288, 30, 2048000),
                new LevelLimitH263(H263Level50, 352, 240, 60, 4096000),
                new LevelLimitH263(H263Level50, 352, 288, 50, 4096000),
                new LevelLimitH263(H263Level60, 720, 240, 60, 8192000),
                new LevelLimitH263(H263Level60, 720, 288, 50, 8192000),
                new LevelLimitH263(H263Level70, 720, 480, 60, 16384000),
                new LevelLimitH263(H263Level70, 720, 576, 50, 16384000),
        };
        for (LevelLimitH263 levelLimitsH263 : limitsH263) {
            if (height <= levelLimitsH263.height && width <= levelLimitsH263.width &&
                    frameRate <= levelLimitsH263.frameRate && bitrate <= levelLimitsH263.bitrate) {
                return levelLimitsH263.level;
            }
        }
        // if none of the levels suffice, select the highest level
        return H263Level70;
    }

    private static int getMinLevelVP9(int width, int height, int frameRate, int bitrate) {
        class LevelLimitVP9 {
            private LevelLimitVP9(int level, long sampleRate, int size, int breadth,
                    int bitrate) {
                this.level = level;
                this.sampleRate = sampleRate;
                this.size = size;
                this.breadth = breadth;
                this.bitrate = bitrate;
            }

            private final int level;
            private final long sampleRate;
            private final int size;
            private final int breadth;
            private final int bitrate;
        }
        LevelLimitVP9[] limitsVP9 = {
                new LevelLimitVP9(VP9Level1, 829440, 36864, 512, 200000),
                new LevelLimitVP9(VP9Level11, 2764800, 73728, 768, 800000),
                new LevelLimitVP9(VP9Level2, 4608000, 122880, 960, 1800000),
                new LevelLimitVP9(VP9Level21, 9216000, 245760, 1344, 3600000),
                new LevelLimitVP9(VP9Level3, 20736000, 552960, 2048, 7200000),
                new LevelLimitVP9(VP9Level31, 36864000, 983040, 2752, 12000000),
                new LevelLimitVP9(VP9Level4, 83558400, 2228224, 4160, 18000000),
                new LevelLimitVP9(VP9Level41, 160432128, 2228224, 4160, 30000000),
                new LevelLimitVP9(VP9Level5, 311951360, 8912896, 8384, 60000000),
                new LevelLimitVP9(VP9Level51, 588251136, 8912896, 8384, 120000000),
                new LevelLimitVP9(VP9Level52, 1176502272, 8912896, 8384, 180000000),
                new LevelLimitVP9(VP9Level6, 1176502272, 35651584, 16832, 180000000),
                new LevelLimitVP9(VP9Level61, 2353004544L, 35651584, 16832, 240000000),
                new LevelLimitVP9(VP9Level62, 4706009088L, 35651584, 16832, 480000000),
        };
        int size = width * height;
        int sampleRate = size * frameRate;
        int breadth = Math.max(width, height);
        for (LevelLimitVP9 levelLimitsVP9 : limitsVP9) {
            if (sampleRate <= levelLimitsVP9.sampleRate && size <= levelLimitsVP9.size &&
                    breadth <= levelLimitsVP9.breadth && bitrate <= levelLimitsVP9.bitrate) {
                return levelLimitsVP9.level;
            }
        }
        // if none of the levels suffice, select the highest level
        return VP9Level62;
    }

    private static int getMinLevelMPEG2(int width, int height, int frameRate, int bitrate) {
        class LevelLimitMPEG2 {
            private LevelLimitMPEG2(int level, long sampleRate, int width, int height,
                    int frameRate, int bitrate) {
                this.level = level;
                this.sampleRate = sampleRate;
                this.width = width;
                this.height = height;
                this.frameRate = frameRate;
                this.bitrate = bitrate;
            }

            private final int level;
            private final long sampleRate;
            private final int width;
            private final int height;
            private final int frameRate;
            private final int bitrate;
        }
        // main profile limits, higher profiles will also support selected level
        LevelLimitMPEG2[] limitsMPEG2 = {
                new LevelLimitMPEG2(MPEG2LevelLL, 3041280, 352, 288, 30, 4000000),
                new LevelLimitMPEG2(MPEG2LevelML, 10368000, 720, 576, 30, 15000000),
                new LevelLimitMPEG2(MPEG2LevelH14, 47001600, 1440, 1088, 60, 60000000),
                new LevelLimitMPEG2(MPEG2LevelHL, 62668800, 1920, 1088, 60, 80000000),
                new LevelLimitMPEG2(MPEG2LevelHP, 125337600, 1920, 1088, 60, 80000000),
        };
        int size = width * height;
        int sampleRate = size * frameRate;
        for (LevelLimitMPEG2 levelLimitsMPEG2 : limitsMPEG2) {
            if (sampleRate <= levelLimitsMPEG2.sampleRate && width <= levelLimitsMPEG2.width &&
                    height <= levelLimitsMPEG2.height && frameRate <= levelLimitsMPEG2.frameRate &&
                    bitrate <= levelLimitsMPEG2.bitrate) {
                return levelLimitsMPEG2.level;
            }
        }
        // if none of the levels suffice, select the highest level
        return MPEG2LevelHP;
    }

    private static int getMinLevelMPEG4(int width, int height, int frameRate, int bitrate,
            int profile) {
        class LevelLimitMPEG4 {
            private LevelLimitMPEG4(int profile, int level, long sampleRate, int width,
                    int height, int frameRate, int bitrate) {
                this.profile = profile;
                this.level = level;
                this.sampleRate = sampleRate;
                this.width = width;
                this.height = height;
                this.frameRate = frameRate;
                this.bitrate = bitrate;
            }

            private final int profile;
            private final int level;
            private final long sampleRate;
            private final int width;
            private final int height;
            private final int frameRate;
            private final int bitrate;
        }
        // simple profile limits, higher profiles will also support selected level
        LevelLimitMPEG4[] limitsMPEG4 = {
                new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level0, 380160, 176, 144, 15, 64000),
                new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level1, 380160, 176, 144, 30, 64000),
                new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level0b, 380160, 176, 144, 15, 128000),
                new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level2, 1520640, 352, 288, 30, 128000),
                new LevelLimitMPEG4(MPEG4ProfileSimple, MPEG4Level3, 3041280, 352, 288, 30, 384000),
                new LevelLimitMPEG4(
                        MPEG4ProfileSimple, MPEG4Level4a, 9216000, 640, 480, 30, 4000000),
                new LevelLimitMPEG4(
                        MPEG4ProfileSimple, MPEG4Level5, 10368000, 720, 576, 30, 8000000),
                new LevelLimitMPEG4(
                        MPEG4ProfileSimple, MPEG4Level6, 27648000, 1280, 720, 30, 12000000),
                new LevelLimitMPEG4(
                        MPEG4ProfileAdvancedSimple, MPEG4Level1, 760320, 176, 144, 30, 128000),
                new LevelLimitMPEG4(
                        MPEG4ProfileAdvancedSimple, MPEG4Level2, 1520640, 352, 288, 30, 384000),
                new LevelLimitMPEG4(
                        MPEG4ProfileAdvancedSimple, MPEG4Level3, 3041280, 352, 288, 30, 768000),
                new LevelLimitMPEG4(
                        MPEG4ProfileAdvancedSimple, MPEG4Level3b, 3041280, 352, 288, 30, 1500000),
                new LevelLimitMPEG4(
                        MPEG4ProfileAdvancedSimple, MPEG4Level4, 3041280, 704, 576, 30, 3000000),
                new LevelLimitMPEG4(
                        MPEG4ProfileAdvancedSimple, MPEG4Level5, 3041280, 720, 576, 30, 8000000),
        };
        int size = width * height;
        int sampleRate = size * frameRate;
        for (LevelLimitMPEG4 levelLimitsMPEG4 : limitsMPEG4) {
            if (((profile & (MPEG4ProfileAdvancedSimple | MPEG4ProfileSimple)) != 0) &&
                    profile != levelLimitsMPEG4.profile) continue;
            if (sampleRate <= levelLimitsMPEG4.sampleRate && width <= levelLimitsMPEG4.width &&
                    height <= levelLimitsMPEG4.height && frameRate <= levelLimitsMPEG4.frameRate &&
                    bitrate <= levelLimitsMPEG4.bitrate) {
                return levelLimitsMPEG4.level;
            }
        }
        // if none of the levels suffice, select the highest level
        return MPEG4Level6;
    }

    private static int getMinLevelAV1(int width, int height, int frameRate, int bitrate) {
        class LevelLimitAV1 {
            private LevelLimitAV1(int level, int size, int width, int height, long sampleRate,
                    int bitrate) {
                this.level = level;
                this.size = size;
                this.width = width;
                this.height = height;
                this.sampleRate = sampleRate;
                this.bitrate = bitrate;
            }

            private final int level;
            private final int size;
            private final int width;
            private final int height;
            private final long sampleRate;
            private final int bitrate;
        }
        // taking bitrate from main profile, will also be supported by high profile
        LevelLimitAV1[] limitsAV1 = {
                new LevelLimitAV1(AV1Level2, 147456, 2048, 1152, 4423680, 1500000),
                new LevelLimitAV1(AV1Level21, 278784, 2816, 1584, 8363520, 3000000),
                new LevelLimitAV1(AV1Level3, 665856, 4352, 2448, 19975680, 6000000),
                new LevelLimitAV1(AV1Level31, 1065024, 5504, 3096, 31950720, 10000000),
                new LevelLimitAV1(AV1Level4, 2359296, 6144, 3456, 70778880, 12000000),
                new LevelLimitAV1(AV1Level41, 2359296, 6144, 3456, 141557760, 20000000),
                new LevelLimitAV1(AV1Level5, 8912896, 8192, 4352, 267386880, 30000000),
                new LevelLimitAV1(AV1Level51, 8912896, 8192, 4352, 534773760, 40000000),
                new LevelLimitAV1(AV1Level52, 8912896, 8192, 4352, 1069547520, 60000000),
                new LevelLimitAV1(AV1Level53, 8912896, 8192, 4352, 1069547520, 60000000),
                new LevelLimitAV1(AV1Level6, 35651584, 16384, 8704, 1069547520, 60000000),
                new LevelLimitAV1(AV1Level61, 35651584, 16384, 8704, 2139095040, 100000000),
                new LevelLimitAV1(AV1Level62, 35651584, 16384, 8704, 4278190080L, 160000000),
                new LevelLimitAV1(AV1Level63, 35651584, 16384, 8704, 4278190080L, 160000000),
        };
        int size = width * height;
        int sampleRate = size * frameRate;
        for (LevelLimitAV1 levelLimitsAV1 : limitsAV1) {
            if (size <= levelLimitsAV1.size && width <= levelLimitsAV1.width &&
                    height <= levelLimitsAV1.height && sampleRate <= levelLimitsAV1.sampleRate &&
                    bitrate <= levelLimitsAV1.bitrate) {
                return levelLimitsAV1.level;
            }
        }
        // if none of the levels suffice or high profile, select the highest level
        return AV1Level73;
    }

    private int getAacProfile(MediaFormat format) {
        int aacProfile = format.getInteger(MediaFormat.KEY_AAC_PROFILE, -1);
        int profile = format.getInteger(MediaFormat.KEY_PROFILE, -1);

        if (aacProfile != -1 && profile != -1) {
            assertEquals(String.format("aac-profile :- %d and profile :- %d are different.",
                    aacProfile, profile), aacProfile, profile);
            return aacProfile;
        } else if (aacProfile != -1) {
            return aacProfile;
        } else if (profile != -1) {
            return profile;
        } else {
            Log.e(LOG_TAG, "format doesn't contain either KEY_AAC_PROFILE or KEY_PROFILE");
            return -1;
        }
    }

    @Override
    public boolean isFormatSimilar(MediaFormat inpFormat, MediaFormat outFormat) {
        if (!super.isFormatSimilar(inpFormat, outFormat)) {
            Log.e(LOG_TAG, "Basic channel-rate/resolution comparisons failed");
            return false;
        }
        String inpMime = inpFormat.getString(MediaFormat.KEY_MIME);
        String outMime = outFormat.getString(MediaFormat.KEY_MIME);
        assertEquals(String.format("input mime :- %s and output mime :- %s are different.", inpMime,
                outMime), inpMime, outMime);
        if (outMime.startsWith("audio/")) {
            if (outFormat.getString(MediaFormat.KEY_MIME).equals(MediaFormat.MIMETYPE_AUDIO_AAC)) {
                int inputProfileKey, outputProfileKey;
                outputProfileKey = getAacProfile(outFormat);
                inputProfileKey = getAacProfile(inpFormat);
                if (outputProfileKey != inputProfileKey) {
                    Log.e(LOG_TAG, "aac-profile in output " + outputProfileKey +
                            " doesn't match configured input " + inputProfileKey);
                    return false;
                }
            }
        } else if (outMime.startsWith("video/")) {
            if (!outFormat.containsKey(MediaFormat.KEY_PROFILE)) {
                Log.e(LOG_TAG, "Output format doesn't contain profile key");
                //TODO (b/151398466)
                if (true) return true;
                return false;
            }
            if (!outFormat.containsKey(MediaFormat.KEY_LEVEL)) {
                Log.e(LOG_TAG, "Output format doesn't contain level key");
                //TODO (b/151398466)
                if (true) return true;
                return false;
            }
            if (!inpFormat.containsKey(MediaFormat.KEY_PROFILE)) {
                Log.e(LOG_TAG, "Input format doesn't contain profile key");
                return false;
            }
            if (!inpFormat.containsKey(MediaFormat.KEY_LEVEL)) {
                Log.e(LOG_TAG, "Input format doesn't contain level key");
                return false;
            }
            if (outFormat.getInteger(MediaFormat.KEY_PROFILE)
                    != inpFormat.getInteger(MediaFormat.KEY_PROFILE)) {
                Log.e(LOG_TAG, "profile in output doesn't match configured input");
                return false;
            }
            if (outFormat.getInteger(MediaFormat.KEY_LEVEL)
                    != inpFormat.getInteger(MediaFormat.KEY_LEVEL)) {
                Log.e(LOG_TAG, "level key in output doesn't match configured input");
                return false;
            }
        } else {
            Log.w(LOG_TAG, "non media mime:" + outMime);
        }
        return true;
    }

    /**
     * @see EncoderProfileLevelTest
     * Besides the above, the test muxes the encoder output in all supported container formats
     * and checks if muxers and extractors on device are signalling profile/level information
     * correctly
     */
    @CddTest(requirements = {"2.2.2/5.1/H-0-3", "2.2.2/5.1/H-0-4", "2.2.2/5.1/H-0-5", "5/C-0-3",
            "5.2.1/C-1-1", "5.2.2/C-2-1", "5.2.3/C-2-1", "5.2.4/C-1-2",
            "5.2.5/C-1-1"})
    @ApiTest(apis = {"android.media.MediaFormat#KEY_PROFILE",
            "android.media.MediaFormat#KEY_AAC_PROFILE",
            "android.media.MediaFormat#KEY_LEVEL"})
    @Test(timeout = PER_TEST_TIMEOUT_LARGE_TEST_MS)
    public void testValidateProfileLevel() throws IOException, InterruptedException {
        if (mEncCfgParams[0].mInputBitDepth != 8) {
            Assume.assumeTrue(mCodecName + " doesn't support " + colorFormatToString(
                            mEncCfgParams[0].mColorFormat, mEncCfgParams[0].mInputBitDepth),
                    hasSupportForColorFormat(mCodecName, mMime, mEncCfgParams[0].mColorFormat));
        }
        boolean cddSupportedMime = PROFILE_LEVEL_CDD.get(mMime) != null;
        int[] profileCdd = new int[0];
        int levelCdd = 0;
        if (cddSupportedMime) {
            Pair<int[], Integer> cddProfileLevel = PROFILE_LEVEL_CDD.get(mMime);
            profileCdd = cddProfileLevel.first;
            levelCdd = cddProfileLevel.second;
        }

        {
            mActiveRawRes = EncoderInput.getRawResource(mEncCfgParams[0]);
            assertNotNull("no raw resource found for testing config : "
                    + mActiveEncCfg + mTestConfig + mTestEnv, mActiveRawRes);
            setUpSource(mActiveRawRes.mFileName);
            mSaveToMem = true;
            mOutputBuff = new OutputManager();
            mCodec = MediaCodec.createByCodecName(mCodecName);
            MediaCodecInfo.CodecCapabilities codecCapabilities =
                    mCodec.getCodecInfo().getCapabilitiesForType(mMime);
            for (EncoderConfigParams cfg : mEncCfgParams) {
                mActiveEncCfg = cfg;
                MediaFormat format = cfg.getFormat();
                if (!codecCapabilities.isFormatSupported(format)) {
                    if (cddSupportedMime) {
                        boolean shallSupportProfileLevel = false;
                        if (mIsAudio) {
                            for (int cddProfile : profileCdd) {
                                if (cfg.mProfile == cddProfile) {
                                    shallSupportProfileLevel = true;
                                    break;
                                }
                            }
                        } else if (cfg.mProfile == profileCdd[0] && cfg.mLevel <= levelCdd) {
                            shallSupportProfileLevel = true;
                        }
                        if (shallSupportProfileLevel) {
                            ArrayList<MediaFormat> formats = new ArrayList<>();
                            formats.add(format);
                            assertFalse(String.format("No components present on the device supports"
                                    + " cdd required profile:- %d, level:- %d, encode format:- %s",
                                    cfg.mProfile, cfg.mLevel, format),
                                    selectCodecs(mMime, formats, null, false).isEmpty());
                        }
                        Log.d(LOG_TAG, mCodecName + " doesn't support format: " + format);
                    }
                    continue;
                }

                // Verify if device has an equivalent decoder for the current format
                {
                    ArrayList<MediaFormat> formatList = new ArrayList<>();
                    formatList.add(format);
                    assertTrue("Device advertises support for encoding " + format
                                    + " but cannot decode it. \n" + mTestConfig + mTestEnv,
                            selectCodecs(mMime, formatList, null, false).size() > 0);
                }

                mOutputBuff.reset();
                configureCodec(format, false, true, true);
                mCodec.start();
                doWork(5);
                queueEOS();
                waitForAllOutputs();
                MediaFormat outFormat = mCodec.getOutputFormat();
                /* TODO(b/147348711) */
                if (false) mCodec.stop();
                else mCodec.reset();

                // TODO (b/151398466)
                if (mMime.equals(MediaFormat.MIMETYPE_AUDIO_AAC)) {
                    Assume.assumeTrue("neither KEY_AAC_PROFILE nor KEY_PROFILE are present",
                            outFormat.containsKey(MediaFormat.KEY_AAC_PROFILE) ||
                                    outFormat.containsKey(MediaFormat.KEY_PROFILE));
                } else {
                    Assume.assumeTrue("KEY_PROFILE not present",
                            outFormat.containsKey(MediaFormat.KEY_PROFILE));
                    Assume.assumeTrue(outFormat.containsKey(MediaFormat.KEY_LEVEL));
                }
                // TODO (b/166300446) avc mime fails validation
                if (mMime.equals(MediaFormat.MIMETYPE_VIDEO_AVC)) {
                    Log.w(LOG_TAG, "Skip validation for mime = " + mMime);
                    continue;
                }
                // TODO (b/166305723) hevc mime fails validation
                if (mMime.equals(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
                    Log.w(LOG_TAG, "Skip validation for mime = " + mMime);
                    continue;
                }
                // TODO (b/166300448) h263 and mpeg4 mimes fails validation
                if (mMime.equals(MediaFormat.MIMETYPE_VIDEO_H263) ||
                        mMime.equals(MediaFormat.MIMETYPE_VIDEO_MPEG4)) {
                    Log.w(LOG_TAG, "Skip validation for mime = " + mMime);
                    continue;
                }
                // TODO (b/184889671) aac for profile AACObjectHE fails validation
                // TODO (b/184890155) aac for profile AACObjectLD, AACObjectELD fails validation
                if (mMime.equals(MediaFormat.MIMETYPE_AUDIO_AAC)) {
                    if (cfg.mProfile == AACObjectHE || cfg.mProfile == AACObjectELD
                            || cfg.mProfile == AACObjectLD) {
                        Log.w(LOG_TAG, "Skip validation for mime = " + mMime + " profile "
                                + cfg.mProfile);
                        continue;
                    }
                }
                String msg = String.format("Configured input format and received output format are "
                        + "not similar. \nConfigured Input format is :- %s \nReceived Output "
                        + "format is :- %s \n", format, outFormat);
                assertTrue(msg + mTestConfig + mTestEnv, isFormatSimilar(format, outFormat));

                for (int muxerFormat = MediaMuxer.OutputFormat.MUXER_OUTPUT_FIRST;
                     muxerFormat <= MediaMuxer.OutputFormat.MUXER_OUTPUT_LAST; muxerFormat++) {
                    if (!isMediaTypeContainerPairValid(mMime, muxerFormat)) continue;
                    ByteBuffer mBuff = mOutputBuff.getBuffer();
                    String tmpPath = getTempFilePath((cfg.mInputBitDepth == 10) ? "10bit" : "");
                    muxOutput(tmpPath, muxerFormat, outFormat, mBuff, mInfoList);
                    MediaExtractor extractor = new MediaExtractor();
                    extractor.setDataSource(tmpPath);
                    assertEquals("Should be only 1 track \n" + mTestConfig + mTestEnv, 1,
                            extractor.getTrackCount());
                    MediaFormat extractedFormat = extractor.getTrackFormat(0);
                    if (!isFormatSimilar(outFormat, extractedFormat)) {
                        msg = " Input format and extracted format are not similar. "
                                + "\n Muxer input format :- " + outFormat
                                + "\n Extracted format :- " + extractedFormat
                                + "\n Muxer writer :- " + muxerFormat + "\n" + mTestConfig
                                + mTestEnv;
                        fail(msg);
                    }
                    extractor.release();
                    new File(tmpPath).delete();
                }
            }
            mCodec.release();
        }
    }
}
