/*
 * 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.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "NativeCodecEncoderTest"
#include <log/log.h>

#include <jni.h>
#include <sys/stat.h>

#include "NativeCodecTestBase.h"
#include "NativeMediaConstants.h"

class CodecEncoderTest final : CodecTestBase {
  private:
    uint8_t* mInputData;
    size_t mInputLength;
    int mNumBytesSubmitted;
    int64_t mInputOffsetPts;
    std::vector<AMediaFormat*> mFormats;
    int mNumSyncFramesReceived;
    std::vector<int> mSyncFramesPos;

    int32_t* mBitRates;
    int mLen0;
    int32_t* mEncParamList1;
    int mLen1;
    int32_t* mEncParamList2;
    int mLen2;

    int mWidth, mHeight;
    int mChannels;
    int mSampleRate;
    int mColorFormat;
    int mMaxBFrames;
    int mDefFrameRate;
    const int kInpFrmWidth = 352;
    const int kInpFrmHeight = 288;

    void convertyuv420ptoyuv420sp();
    void setUpSource(const char* srcPath);
    void deleteSource();
    void setUpParams(int limit);
    void deleteParams();
    bool flushCodec() override;
    void resetContext(bool isAsync, bool signalEOSWithLastFrame) override;
    bool enqueueInput(size_t bufferIndex) override;
    bool dequeueOutput(size_t bufferIndex, AMediaCodecBufferInfo* bufferInfo) override;
    void initFormat(AMediaFormat* format);
    bool encodeToMemory(const char* file, const char* encoder, int frameLimit, AMediaFormat* format,
                        OutputManager* ref);
    void fillByteBuffer(uint8_t* inputBuffer);
    void forceSyncFrame(AMediaFormat* format);
    void updateBitrate(AMediaFormat* format, int bitrate);

  public:
    CodecEncoderTest(const char* mime, int32_t* list0, int len0, int32_t* list1, int len1,
                     int32_t* list2, int len2, int colorFormat);
    ~CodecEncoderTest();

    bool testSimpleEncode(const char* encoder, const char* srcPath);
    bool testFlush(const char* encoder, const char* srcPath);
    bool testReconfigure(const char* encoder, const char* srcPath);
    bool testSetForceSyncFrame(const char* encoder, const char* srcPath);
    bool testAdaptiveBitRate(const char* encoder, const char* srcPath);
    bool testOnlyEos(const char* encoder);
};

CodecEncoderTest::CodecEncoderTest(const char* mime, int32_t* list0, int len0, int32_t* list1,
                                   int len1, int32_t* list2, int len2, int colorFormat)
    : CodecTestBase(mime),
      mBitRates{list0},
      mLen0{len0},
      mEncParamList1{list1},
      mLen1{len1},
      mEncParamList2{list2},
      mLen2{len2},
      mColorFormat{colorFormat} {
    mDefFrameRate = 30;
    if (!strcmp(mime, AMEDIA_MIMETYPE_VIDEO_H263)) mDefFrameRate = 12;
    else if (!strcmp(mime, AMEDIA_MIMETYPE_VIDEO_MPEG4)) mDefFrameRate = 12;
    mMaxBFrames = 0;
    mInputData = nullptr;
    mInputLength = 0;
    mNumBytesSubmitted = 0;
    mInputOffsetPts = 0;
}

CodecEncoderTest::~CodecEncoderTest() {
    deleteSource();
    deleteParams();
}

void CodecEncoderTest::convertyuv420ptoyuv420sp() {
    int ySize = kInpFrmWidth * kInpFrmHeight;
    int uSize = kInpFrmWidth * kInpFrmHeight / 4;
    int frameSize = ySize + uSize * 2;
    int totalFrames = mInputLength / frameSize;
    uint8_t* u = new uint8_t[uSize];
    uint8_t* v = new uint8_t[uSize];
    uint8_t* frameBase = mInputData;
    for (int i = 0; i < totalFrames; i++) {
        uint8_t* uvBase = frameBase + ySize;
        memcpy(u, uvBase, uSize);
        memcpy(v, uvBase + uSize, uSize);
        for (int j = 0, idx = 0; j < uSize; j++, idx += 2) {
            uvBase[idx] = u[j];
            uvBase[idx + 1] = v[j];
        }
        frameBase += frameSize;
    }
    delete[] u;
    delete[] v;
}

void CodecEncoderTest::setUpSource(const char* srcPath) {
    FILE* fp = fopen(srcPath, "rbe");
    struct stat buf {};
    if (fp && !fstat(fileno(fp), &buf)) {
        deleteSource();
        mInputLength = buf.st_size;
        mInputData = new uint8_t[mInputLength];
        fread(mInputData, sizeof(uint8_t), mInputLength, fp);
        if (mColorFormat == COLOR_FormatYUV420SemiPlanar) {
            convertyuv420ptoyuv420sp();
        }
    } else {
        ALOGE("unable to open input file %s", srcPath);
    }
    if (fp) fclose(fp);
}

void CodecEncoderTest::deleteSource() {
    if (mInputData) {
        delete[] mInputData;
        mInputData = nullptr;
    }
    mInputLength = 0;
}

void CodecEncoderTest::setUpParams(int limit) {
    int count = 0;
    for (int k = 0; k < mLen0; k++) {
        int bitrate = mBitRates[k];
        if (mIsAudio) {
            for (int j = 0; j < mLen1; j++) {
                int rate = mEncParamList1[j];
                for (int i = 0; i < mLen2; i++) {
                    int channels = mEncParamList2[i];
                    AMediaFormat* format = AMediaFormat_new();
                    AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, mMime);
                    AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, bitrate);
                    AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, rate);
                    AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, channels);
                    mFormats.push_back(format);
                    count++;
                    if (count >= limit) break;
                }
            }
        } else {
            for (int j = 0; j < mLen1; j++) {
                int width = mEncParamList1[j];
                int height = mEncParamList2[j];
                AMediaFormat* format = AMediaFormat_new();
                AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, mMime);
                AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, bitrate);
                AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_WIDTH, width);
                AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_HEIGHT, height);
                AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_FRAME_RATE, mDefFrameRate);
                AMediaFormat_setInt32(format, TBD_AMEDIACODEC_PARAMETER_KEY_MAX_B_FRAMES,
                                      mMaxBFrames);
                AMediaFormat_setFloat(format, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, 1.0F);
                AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_COLOR_FORMAT, mColorFormat);
                mFormats.push_back(format);
                count++;
                if (count >= limit) break;
            }
        }
    }
}

void CodecEncoderTest::deleteParams() {
    for (auto format : mFormats) AMediaFormat_delete(format);
    mFormats.clear();
}

void CodecEncoderTest::resetContext(bool isAsync, bool signalEOSWithLastFrame) {
    CodecTestBase::resetContext(isAsync, signalEOSWithLastFrame);
    mNumBytesSubmitted = 0;
    mInputOffsetPts = 0;
    mNumSyncFramesReceived = 0;
    mSyncFramesPos.clear();
}

bool CodecEncoderTest::flushCodec() {
    bool isOk = CodecTestBase::flushCodec();
    if (mIsAudio) {
        mInputOffsetPts = (mNumBytesSubmitted + 1024) * 1000000L / (2 * mChannels * mSampleRate);
    } else {
        mInputOffsetPts = (mInputCount + 5) * 1000000L / mDefFrameRate;
    }
    mPrevOutputPts = mInputOffsetPts - 1;
    mNumBytesSubmitted = 0;
    mNumSyncFramesReceived = 0;
    mSyncFramesPos.clear();
    return isOk;
}

void CodecEncoderTest::fillByteBuffer(uint8_t* inputBuffer) {
    int width, height, tileWidth, tileHeight;
    int offset = 0, frmOffset = mNumBytesSubmitted;
    int numOfPlanes;
    if (mColorFormat == COLOR_FormatYUV420SemiPlanar) {
        numOfPlanes = 2;
    } else {
        numOfPlanes = 3;
    }
    for (int plane = 0; plane < numOfPlanes; plane++) {
        if (plane == 0) {
            width = mWidth;
            height = mHeight;
            tileWidth = kInpFrmWidth;
            tileHeight = kInpFrmHeight;
        } else {
            if (mColorFormat == COLOR_FormatYUV420SemiPlanar) {
                width = mWidth;
                tileWidth = kInpFrmWidth;
            } else {
                width = mWidth / 2;
                tileWidth = kInpFrmWidth / 2;
            }
            height = mHeight / 2;
            tileHeight = kInpFrmHeight / 2;
        }
        for (int k = 0; k < height; k += tileHeight) {
            int rowsToCopy = std::min(height - k, tileHeight);
            for (int j = 0; j < rowsToCopy; j++) {
                for (int i = 0; i < width; i += tileWidth) {
                    int colsToCopy = std::min(width - i, tileWidth);
                    memcpy(inputBuffer + (offset + (k + j) * width + i),
                           mInputData + (frmOffset + j * tileWidth), colsToCopy);
                }
            }
        }
        offset += width * height;
        frmOffset += tileWidth * tileHeight;
    }
}

bool CodecEncoderTest::enqueueInput(size_t bufferIndex) {
    if (mNumBytesSubmitted >= mInputLength) {
        return enqueueEOS(bufferIndex);
    } else {
        int size = 0;
        int flags = 0;
        int64_t pts = mInputOffsetPts;
        size_t buffSize;
        uint8_t* inputBuffer = AMediaCodec_getInputBuffer(mCodec, bufferIndex, &buffSize);
        if (mIsAudio) {
            pts += mNumBytesSubmitted * 1000000L / (2 * mChannels * mSampleRate);
            size = std::min(buffSize, mInputLength - mNumBytesSubmitted);
            memcpy(inputBuffer, mInputData + mNumBytesSubmitted, size);
            if (mNumBytesSubmitted + size >= mInputLength && mSignalEOSWithLastFrame) {
                flags |= AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM;
                mSawInputEOS = true;
            }
            mNumBytesSubmitted += size;
        } else {
            pts += mInputCount * 1000000L / mDefFrameRate;
            size = mWidth * mHeight * 3 / 2;
            int frmSize = kInpFrmWidth * kInpFrmHeight * 3 / 2;
            if (mNumBytesSubmitted + frmSize > mInputLength) {
                ALOGE("received partial frame to encode");
                return false;
            } else if (size > buffSize) {
                ALOGE("frame size exceeds buffer capacity of input buffer %d %zu", size, buffSize);
                return false;
            } else {
                if (mWidth == kInpFrmWidth && mHeight == kInpFrmHeight) {
                    memcpy(inputBuffer, mInputData + mNumBytesSubmitted, size);
                } else {
                    fillByteBuffer(inputBuffer);
                }
            }
            if (mNumBytesSubmitted + frmSize >= mInputLength && mSignalEOSWithLastFrame) {
                flags |= AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM;
                mSawInputEOS = true;
            }
            mNumBytesSubmitted += frmSize;
        }
        CHECK_STATUS(AMediaCodec_queueInputBuffer(mCodec, bufferIndex, 0, size, pts, flags),
                     "AMediaCodec_queueInputBuffer failed");
        ALOGV("input: id: %zu  size: %d  pts: %d  flags: %d", bufferIndex, size, (int)pts, flags);
        mOutputBuff->saveInPTS(pts);
        mInputCount++;
    }
    return !hasSeenError();
}

bool CodecEncoderTest::dequeueOutput(size_t bufferIndex, AMediaCodecBufferInfo* info) {
    if ((info->flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) != 0) {
        mSawOutputEOS = true;
    }
    if (info->size > 0) {
        if (mSaveToMem) {
            size_t buffSize;
            uint8_t* buf = AMediaCodec_getOutputBuffer(mCodec, bufferIndex, &buffSize);
            mOutputBuff->saveToMemory(buf, info);
        }
        if ((info->flags & TBD_AMEDIACODEC_BUFFER_FLAG_KEY_FRAME) != 0) {
            mNumSyncFramesReceived += 1;
            mSyncFramesPos.push_back(mOutputCount);
        }
        if ((info->flags & AMEDIACODEC_BUFFER_FLAG_CODEC_CONFIG) == 0) {
            mOutputBuff->saveOutPTS(info->presentationTimeUs);
            mOutputCount++;
        }
    }
    ALOGV("output: id: %zu  size: %d  pts: %d  flags: %d", bufferIndex, info->size,
          (int)info->presentationTimeUs, info->flags);
    CHECK_STATUS(AMediaCodec_releaseOutputBuffer(mCodec, bufferIndex, false),
                 "AMediaCodec_releaseOutputBuffer failed");
    return !hasSeenError();
}

void CodecEncoderTest::initFormat(AMediaFormat* format) {
    if (mIsAudio) {
        AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, &mSampleRate);
        AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &mChannels);
    } else {
        AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &mWidth);
        AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &mHeight);
    }
}

bool CodecEncoderTest::encodeToMemory(const char* file, const char* encoder, int32_t frameLimit,
                                      AMediaFormat* format, OutputManager* ref) {
    /* TODO(b/149027258) */
    if (true) mSaveToMem = false;
    else mSaveToMem = true;
    mOutputBuff = ref;
    mCodec = AMediaCodec_createCodecByName(encoder);
    if (!mCodec) {
        ALOGE("unable to create codec %s", encoder);
        return false;
    }
    setUpSource(file);
    if (!mInputData) return false;
    if (!configureCodec(format, false, true, true)) return false;
    initFormat(format);
    CHECK_STATUS(AMediaCodec_start(mCodec), "AMediaCodec_start failed");
    if (!doWork(frameLimit)) return false;
    if (!queueEOS()) return false;
    if (!waitForAllOutputs()) return false;
    CHECK_STATUS(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed");
    CHECK_STATUS(AMediaCodec_delete(mCodec), "AMediaCodec_delete failed");
    mCodec = nullptr;
    mSaveToMem = false;
    return !hasSeenError();
}

void CodecEncoderTest::forceSyncFrame(AMediaFormat* format) {
    AMediaFormat_setInt32(format, TBD_AMEDIACODEC_PARAMETER_KEY_REQUEST_SYNC_FRAME, 0);
    ALOGV("requesting key frame");
    AMediaCodec_setParameters(mCodec, format);
}

void CodecEncoderTest::updateBitrate(AMediaFormat* format, int bitrate) {
    AMediaFormat_setInt32(format, TBD_AMEDIACODEC_PARAMETER_KEY_VIDEO_BITRATE, bitrate);
    ALOGV("requesting bitrate to be changed to %d", bitrate);
    AMediaCodec_setParameters(mCodec, format);
}

bool CodecEncoderTest::testSimpleEncode(const char* encoder, const char* srcPath) {
    bool isPass = true;
    setUpSource(srcPath);
    if (!mInputData) return false;
    setUpParams(INT32_MAX);
    /* TODO(b/149027258) */
    if (true) mSaveToMem = false;
    else mSaveToMem = true;
    auto ref = &mRefBuff;
    auto test = &mTestBuff;
    const bool boolStates[]{true, false};
    for (int i = 0; i < mFormats.size() && isPass; i++) {
        AMediaFormat* format = mFormats[i];
        initFormat(format);
        int loopCounter = 0;
        for (auto eosType : boolStates) {
            if (!isPass) break;
            for (auto isAsync : boolStates) {
                if (!isPass) break;
                char log[1000];
                snprintf(log, sizeof(log),
                         "format: %s \n codec: %s, file: %s, mode: %s, eos type: %s:: ",
                         AMediaFormat_toString(format), encoder, srcPath,
                         (isAsync ? "async" : "sync"),
                         (eosType ? "eos with last frame" : "eos separate"));
                mOutputBuff = loopCounter == 0 ? ref : test;
                mOutputBuff->reset();
                /* TODO(b/147348711) */
                /* Instead of create and delete codec at every iteration, we would like to create
                 * once and use it for all iterations and delete before exiting */
                mCodec = AMediaCodec_createCodecByName(encoder);
                if (!mCodec) {
                    ALOGE("%s unable to create media codec by name %s", log, encoder);
                    isPass = false;
                    continue;
                }
                char* name = nullptr;
                if (AMEDIA_OK == AMediaCodec_getName(mCodec, &name)) {
                    if (!name || strcmp(name, encoder) != 0) {
                        ALOGE("%s error codec-name act/got: %s/%s", log, name, encoder);
                        if (name) AMediaCodec_releaseName(mCodec, name);
                        return false;
                    }
                } else {
                    ALOGE("AMediaCodec_getName failed unexpectedly");
                    return false;
                }
                if (name) AMediaCodec_releaseName(mCodec, name);
                if (!configureCodec(format, isAsync, eosType, true)) return false;
                CHECK_STATUS(AMediaCodec_start(mCodec), "AMediaCodec_start failed");
                if (!doWork(INT32_MAX)) return false;
                if (!queueEOS()) return false;
                if (!waitForAllOutputs()) return false;
                CHECK_STATUS(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed");
                CHECK_STATUS(AMediaCodec_delete(mCodec), "AMediaCodec_delete failed");
                mCodec = nullptr;
                CHECK_ERR((hasSeenError()), log, "has seen error", isPass);
                CHECK_ERR((0 == mInputCount), log, "queued 0 inputs", isPass);
                CHECK_ERR((0 == mOutputCount), log, "received 0 outputs", isPass);
                CHECK_ERR((!mIsAudio && mInputCount != mOutputCount), log,
                          "input cnt != output cnt", isPass);
                CHECK_ERR((loopCounter != 0 && !ref->equals(test)), log, "output is flaky", isPass);
                CHECK_ERR((loopCounter == 0 && mIsAudio &&
                           !ref->isPtsStrictlyIncreasing(mPrevOutputPts)),
                          log, "pts is not strictly increasing", isPass);
                CHECK_ERR((loopCounter == 0 && !mIsAudio &&
                           !ref->isOutPtsListIdenticalToInpPtsList(mMaxBFrames != 0)),
                          log, "input pts list and output pts list are not identical", isPass);
                loopCounter++;
            }
        }
    }
    return isPass;
}

bool CodecEncoderTest::testFlush(const char* encoder, const char* srcPath) {
    bool isPass = true;
    setUpSource(srcPath);
    if (!mInputData) return false;
    setUpParams(1);
    mOutputBuff = &mTestBuff;
    AMediaFormat* format = mFormats[0];
    initFormat(format);
    const bool boolStates[]{true, false};
    for (auto isAsync : boolStates) {
        if (!isPass) break;
        char log[1000];
        snprintf(log, sizeof(log),
                 "format: %s \n codec: %s, file: %s, mode: %s:: ", AMediaFormat_toString(format),
                 encoder, srcPath, (isAsync ? "async" : "sync"));
        /* TODO(b/147348711) */
        /* Instead of create and delete codec at every iteration, we would like to create
         * once and use it for all iterations and delete before exiting */
        mCodec = AMediaCodec_createCodecByName(encoder);
        if (!mCodec) {
            ALOGE("unable to create media codec by name %s", encoder);
            isPass = false;
            continue;
        }
        if (!configureCodec(format, isAsync, true, true)) return false;
        CHECK_STATUS(AMediaCodec_start(mCodec), "AMediaCodec_start failed");

        /* test flush in running state before queuing input */
        if (!flushCodec()) return false;
        mOutputBuff->reset();
        if (mIsCodecInAsyncMode) {
            CHECK_STATUS(AMediaCodec_start(mCodec), "AMediaCodec_start failed");
        }
        if (!doWork(23)) return false;
        CHECK_ERR((!mOutputBuff->isPtsStrictlyIncreasing(mPrevOutputPts)), log,
                  "pts is not strictly increasing", isPass);
        if (!isPass) continue;

        /* test flush in running state */
        if (!flushCodec()) return false;
        mOutputBuff->reset();
        if (mIsCodecInAsyncMode) {
            CHECK_STATUS(AMediaCodec_start(mCodec), "AMediaCodec_start failed");
        }
        if (!doWork(INT32_MAX)) return false;
        if (!queueEOS()) return false;
        if (!waitForAllOutputs()) return false;
        CHECK_ERR((hasSeenError()), log, "has seen error", isPass);
        CHECK_ERR((0 == mInputCount), log, "queued 0 inputs", isPass);
        CHECK_ERR((0 == mOutputCount), log, "received 0 outputs", isPass);
        CHECK_ERR((mIsAudio && !mOutputBuff->isPtsStrictlyIncreasing(mPrevOutputPts)), log,
                  "pts is not strictly increasing", isPass);
        CHECK_ERR((!mIsAudio && mInputCount != mOutputCount), log, "input cnt != output cnt",
                  isPass);
        CHECK_ERR((!mIsAudio && !mOutputBuff->isOutPtsListIdenticalToInpPtsList(mMaxBFrames != 0)),
                  log, "input pts list and output pts list are not identical", isPass);
        if (!isPass) continue;

        /* test flush in eos state */
        if (!flushCodec()) return false;
        mOutputBuff->reset();
        if (mIsCodecInAsyncMode) {
            CHECK_STATUS(AMediaCodec_start(mCodec), "AMediaCodec_start failed");
        }
        if (!doWork(INT32_MAX)) return false;
        if (!queueEOS()) return false;
        if (!waitForAllOutputs()) return false;
        CHECK_ERR((hasSeenError()), log, "has seen error", isPass);
        CHECK_ERR((0 == mInputCount), log, "queued 0 inputs", isPass);
        CHECK_ERR((0 == mOutputCount), log, "received 0 outputs", isPass);
        CHECK_ERR((mIsAudio && !mOutputBuff->isPtsStrictlyIncreasing(mPrevOutputPts)), log,
                  "pts is not strictly increasing", isPass);
        CHECK_ERR(!mIsAudio && (mInputCount != mOutputCount), log, "input cnt != output cnt",
                  isPass);
        CHECK_ERR(!mIsAudio && (!mOutputBuff->isOutPtsListIdenticalToInpPtsList(mMaxBFrames != 0)),
                  log, "input pts list and output pts list are not identical", isPass);
        CHECK_STATUS(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed");
        CHECK_STATUS(AMediaCodec_delete(mCodec), "AMediaCodec_delete failed");
        mCodec = nullptr;
    }
    return isPass;
}

bool CodecEncoderTest::testReconfigure(const char* encoder, const char* srcPath) {
    bool isPass = true;
    setUpSource(srcPath);
    if (!mInputData) return false;
    setUpParams(2);
    auto configRef = &mReconfBuff;
    if (mFormats.size() > 1) {
        auto format = mFormats[1];
        if (!encodeToMemory(srcPath, encoder, INT32_MAX, format, configRef)) {
            ALOGE("encodeToMemory failed for file: %s codec: %s \n format: %s", srcPath, encoder,
                  AMediaFormat_toString(format));
            return false;
        }
        CHECK_ERR(mIsAudio && (!configRef->isPtsStrictlyIncreasing(mPrevOutputPts)), "",
                  "pts is not strictly increasing", isPass);
        CHECK_ERR(!mIsAudio && (!configRef->isOutPtsListIdenticalToInpPtsList(mMaxBFrames != 0)),
                  "", "input pts list and output pts list are not identical", isPass);
        if (!isPass) return false;
    }
    auto format = mFormats[0];
    auto ref = &mRefBuff;
    if (!encodeToMemory(srcPath, encoder, INT32_MAX, format, ref)) {
        ALOGE("encodeToMemory failed for file: %s codec: %s \n format: %s", srcPath, encoder,
              AMediaFormat_toString(format));
        return false;
    }
    CHECK_ERR(mIsAudio && (!ref->isPtsStrictlyIncreasing(mPrevOutputPts)), "",
              "pts is not strictly increasing", isPass);
    CHECK_ERR(!mIsAudio && (!ref->isOutPtsListIdenticalToInpPtsList(mMaxBFrames != 0)), "",
              "input pts list and output pts list are not identical", isPass);
    if (!isPass) return false;

    auto test = &mTestBuff;
    mOutputBuff = test;
    const bool boolStates[]{true, false};
    for (auto isAsync : boolStates) {
        if (!isPass) break;
        char log[1000];
        snprintf(log, sizeof(log),
                 "format: %s \n codec: %s, file: %s, mode: %s:: ", AMediaFormat_toString(format),
                 encoder, srcPath, (isAsync ? "async" : "sync"));
        /* TODO(b/147348711) */
        /* Instead of create and delete codec at every iteration, we would like to create
         * once and use it for all iterations and delete before exiting */
        mCodec = AMediaCodec_createCodecByName(encoder);
        if (!mCodec) {
            ALOGE("%s unable to create media codec by name %s", log, encoder);
            isPass = false;
            continue;
        }
        if (!configureCodec(format, isAsync, true, true)) return false;
        /* test reconfigure in init state */
        if (!reConfigureCodec(format, !isAsync, false, true)) return false;
        CHECK_STATUS(AMediaCodec_start(mCodec), "AMediaCodec_start failed");

        /* test reconfigure in running state before queuing input */
        if (!reConfigureCodec(format, !isAsync, false, true)) return false;
        CHECK_STATUS(AMediaCodec_start(mCodec), "AMediaCodec_start failed");
        if (!doWork(23)) return false;

        /* test reconfigure codec in running state */
        if (!reConfigureCodec(format, isAsync, true, true)) return false;
        CHECK_STATUS(AMediaCodec_start(mCodec), "AMediaCodec_start failed");

        /* TODO(b/149027258) */
        if (true) mSaveToMem = false;
        else mSaveToMem = true;
        test->reset();
        if (!doWork(INT32_MAX)) return false;
        if (!queueEOS()) return false;
        if (!waitForAllOutputs()) return false;
        CHECK_STATUS(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed");
        CHECK_ERR((hasSeenError()), log, "has seen error", isPass);
        CHECK_ERR((0 == mInputCount), log, "queued 0 inputs", isPass);
        CHECK_ERR((0 == mOutputCount), log, "received 0 outputs", isPass);
        CHECK_ERR((!mIsAudio && mInputCount != mOutputCount), log, "input cnt != output cnt",
                  isPass);
        CHECK_ERR((!ref->equals(test)), log, "output is flaky", isPass);
        if (!isPass) continue;

        /* test reconfigure codec at eos state */
        if (!reConfigureCodec(format, !isAsync, false, true)) return false;
        CHECK_STATUS(AMediaCodec_start(mCodec), "AMediaCodec_start failed");
        test->reset();
        if (!doWork(INT32_MAX)) return false;
        if (!queueEOS()) return false;
        if (!waitForAllOutputs()) return false;
        CHECK_STATUS(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed");
        CHECK_ERR((hasSeenError()), log, "has seen error", isPass);
        CHECK_ERR((0 == mInputCount), log, "queued 0 inputs", isPass);
        CHECK_ERR((0 == mOutputCount), log, "received 0 outputs", isPass);
        CHECK_ERR((!mIsAudio && mInputCount != mOutputCount), log, "input cnt != output cnt",
                  isPass);
        CHECK_ERR((!ref->equals(test)), log, "output is flaky", isPass);

        /* test reconfigure codec for new format */
        if (mFormats.size() > 1) {
            if (!reConfigureCodec(mFormats[1], isAsync, false, true)) return false;
            CHECK_STATUS(AMediaCodec_start(mCodec), "AMediaCodec_start failed");
            test->reset();
            if (!doWork(INT32_MAX)) return false;
            if (!queueEOS()) return false;
            if (!waitForAllOutputs()) return false;
            CHECK_STATUS(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed");
            CHECK_ERR((hasSeenError()), log, "has seen error", isPass);
            CHECK_ERR((0 == mInputCount), log, "queued 0 inputs", isPass);
            CHECK_ERR((0 == mOutputCount), log, "received 0 outputs", isPass);
            CHECK_ERR((!mIsAudio && mInputCount != mOutputCount), log, "input cnt != output cnt",
                      isPass);
            CHECK_ERR((!configRef->equals(test)), log, "output is flaky", isPass);
        }
        mSaveToMem = false;
        CHECK_STATUS(AMediaCodec_delete(mCodec), "AMediaCodec_delete failed");
        mCodec = nullptr;
    }
    return isPass;
}

bool CodecEncoderTest::testOnlyEos(const char* encoder) {
    bool isPass = true;
    setUpParams(1);
    /* TODO(b/149027258) */
    if (true) mSaveToMem = false;
    else mSaveToMem = true;
    auto ref = &mRefBuff;
    auto test = &mTestBuff;
    const bool boolStates[]{true, false};
    AMediaFormat* format = mFormats[0];
    int loopCounter = 0;
    for (int k = 0; (k < (sizeof(boolStates) / sizeof(boolStates[0]))) && isPass; k++) {
        bool isAsync = boolStates[k];
        char log[1000];
        snprintf(log, sizeof(log),
                 "format: %s \n codec: %s, mode: %s:: ", AMediaFormat_toString(format), encoder,
                 (isAsync ? "async" : "sync"));
        mOutputBuff = loopCounter == 0 ? ref : test;
        mOutputBuff->reset();
        /* TODO(b/147348711) */
        /* Instead of create and delete codec at every iteration, we would like to create
         * once and use it for all iterations and delete before exiting */
        mCodec = AMediaCodec_createCodecByName(encoder);
        if (!mCodec) {
            ALOGE("unable to create media codec by name %s", encoder);
            isPass = false;
            continue;
        }
        if (!configureCodec(format, isAsync, false, true)) return false;
        CHECK_STATUS(AMediaCodec_start(mCodec), "AMediaCodec_start failed");
        if (!queueEOS()) return false;
        if (!waitForAllOutputs()) return false;
        CHECK_STATUS(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed");
        CHECK_STATUS(AMediaCodec_delete(mCodec), "AMediaCodec_delete failed");
        mCodec = nullptr;
        CHECK_ERR((hasSeenError()), log, "has seen error", isPass);
        CHECK_ERR(loopCounter != 0 && (!ref->equals(test)), log, "output is flaky", isPass);
        CHECK_ERR(loopCounter == 0 && mIsAudio && (!ref->isPtsStrictlyIncreasing(mPrevOutputPts)),
                  log, "pts is not strictly increasing", isPass);
        CHECK_ERR(loopCounter == 0 && !mIsAudio &&
                  (!ref->isOutPtsListIdenticalToInpPtsList(mMaxBFrames != 0)),
                  log, "input pts list and output pts list are not identical", isPass);
        loopCounter++;
    }
    return isPass;
}

bool CodecEncoderTest::testSetForceSyncFrame(const char* encoder, const char* srcPath) {
    bool isPass = true;
    setUpSource(srcPath);
    if (!mInputData) return false;
    setUpParams(1);
    AMediaFormat* format = mFormats[0];
    AMediaFormat_setFloat(format, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, 500.f);
    AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &mWidth);
    AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &mHeight);
    // Maximum allowed key frame interval variation from the target value.
    int kMaxKeyFrameIntervalVariation = 3;
    int kKeyFrameInterval = 2;  // force key frame every 2 seconds.
    int kKeyFramePos = mDefFrameRate * kKeyFrameInterval;
    int kNumKeyFrameRequests = 7;
    AMediaFormat* params = AMediaFormat_new();
    mFormats.push_back(params);
    mOutputBuff = &mTestBuff;
    const bool boolStates[]{true, false};
    for (auto isAsync : boolStates) {
        if (!isPass) break;
        char log[1000];
        snprintf(log, sizeof(log),
                 "format: %s \n codec: %s, file: %s, mode: %s:: ", AMediaFormat_toString(format),
                 encoder, srcPath, (isAsync ? "async" : "sync"));
        mOutputBuff->reset();
        /* TODO(b/147348711) */
        /* Instead of create and delete codec at every iteration, we would like to create
         * once and use it for all iterations and delete before exiting */
        mCodec = AMediaCodec_createCodecByName(encoder);
        if (!mCodec) {
            ALOGE("%s unable to create media codec by name %s", log, encoder);
            isPass = false;
            continue;
        }
        if (!configureCodec(format, isAsync, false, true)) return false;
        CHECK_STATUS(AMediaCodec_start(mCodec), "AMediaCodec_start failed");
        for (int i = 0; i < kNumKeyFrameRequests; i++) {
            if (!doWork(kKeyFramePos)) return false;
            assert(!mSawInputEOS);
            forceSyncFrame(params);
            mNumBytesSubmitted = 0;
        }
        if (!queueEOS()) return false;
        if (!waitForAllOutputs()) return false;
        CHECK_STATUS(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed");
        CHECK_STATUS(AMediaCodec_delete(mCodec), "AMediaCodec_delete failed");
        mCodec = nullptr;
        CHECK_ERR((hasSeenError()), log, "has seen error", isPass);
        CHECK_ERR((0 == mInputCount), log, "queued 0 inputs", isPass);
        CHECK_ERR((0 == mOutputCount), log, "received 0 outputs", isPass);
        CHECK_ERR((!mIsAudio && mInputCount != mOutputCount), log, "input cnt != output cnt",
                  isPass);
        CHECK_ERR((!mOutputBuff->isOutPtsListIdenticalToInpPtsList(mMaxBFrames != 0)), log,
                  "input pts list and output pts list are not identical", isPass);
        CHECK_ERR((mNumSyncFramesReceived < kNumKeyFrameRequests), log,
                  "Num Sync Frames Received != Num Key Frame Requested", isPass);
        ALOGD("mNumSyncFramesReceived %d", mNumSyncFramesReceived);
        for (int i = 0, expPos = 0, index = 0; i < kNumKeyFrameRequests; i++) {
            int j = index;
            for (; j < mSyncFramesPos.size(); j++) {
                // Check key frame intervals:
                // key frame position should not be greater than target value + 3
                // key frame position should not be less than target value - 3
                if (abs(expPos - mSyncFramesPos.at(j)) <= kMaxKeyFrameIntervalVariation) {
                    index = j;
                    break;
                }
            }
            if (j == mSyncFramesPos.size()) {
                ALOGW("requested key frame at frame index %d none found near by", expPos);
            }
            expPos += kKeyFramePos;
        }
    }
    return isPass;
}

bool CodecEncoderTest::testAdaptiveBitRate(const char* encoder, const char* srcPath) {
    bool isPass = true;
    setUpSource(srcPath);
    if (!mInputData) return false;
    setUpParams(1);
    AMediaFormat* format = mFormats[0];
    AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &mWidth);
    AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &mHeight);
    int kAdaptiveBitrateInterval = 3;  // change bitrate every 3 seconds.
    int kAdaptiveBitrateDurationFrame = mDefFrameRate * kAdaptiveBitrateInterval;
    int kBitrateChangeRequests = 7;
    AMediaFormat* params = AMediaFormat_new();
    mFormats.push_back(params);
    // Setting in CBR Mode
    AMediaFormat_setInt32(format, TBD_AMEDIAFORMAT_KEY_BIT_RATE_MODE, kBitrateModeConstant);
    mOutputBuff = &mTestBuff;
    mSaveToMem = true;
    const bool boolStates[]{true, false};
    for (auto isAsync : boolStates) {
        if (!isPass) break;
        char log[1000];
        snprintf(log, sizeof(log),
                 "format: %s \n codec: %s, file: %s, mode: %s:: ", AMediaFormat_toString(format),
                 encoder, srcPath, (isAsync ? "async" : "sync"));
        mOutputBuff->reset();
        /* TODO(b/147348711) */
        /* Instead of create and delete codec at every iteration, we would like to create
         * once and use it for all iterations and delete before exiting */
        mCodec = AMediaCodec_createCodecByName(encoder);
        if (!mCodec) {
            ALOGE("%s unable to create media codec by name %s", log, encoder);
            isPass = false;
            continue;
        }
        if (!configureCodec(format, isAsync, false, true)) return false;
        CHECK_STATUS(AMediaCodec_start(mCodec), "AMediaCodec_start failed");
        int expOutSize = 0;
        int bitrate;
        AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, &bitrate);
        for (int i = 0; i < kBitrateChangeRequests; i++) {
            if (!doWork(kAdaptiveBitrateDurationFrame)) return false;
            assert(!mSawInputEOS);
            expOutSize += kAdaptiveBitrateInterval * bitrate;
            if ((i & 1) == 1) bitrate *= 2;
            else bitrate /= 2;
            updateBitrate(params, bitrate);
            mNumBytesSubmitted = 0;
        }
        if (!queueEOS()) return false;
        if (!waitForAllOutputs()) return false;
        CHECK_STATUS(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed");
        CHECK_STATUS(AMediaCodec_delete(mCodec), "AMediaCodec_delete failed");
        mCodec = nullptr;
        CHECK_ERR((hasSeenError()), log, "has seen error", isPass);
        CHECK_ERR((0 == mInputCount), log, "queued 0 inputs", isPass);
        CHECK_ERR((0 == mOutputCount), log, "received 0 outputs", isPass);
        CHECK_ERR((!mIsAudio && mInputCount != mOutputCount), log, "input cnt != output cnt",
                  isPass);
        CHECK_ERR((!mOutputBuff->isOutPtsListIdenticalToInpPtsList(mMaxBFrames != 0)), log,
                  "input pts list and output pts list are not identical", isPass);
        /* TODO: validate output br with sliding window constraints Sec 5.2 cdd */
        int outSize = mOutputBuff->getOutStreamSize() * 8;
        float brDev = abs(expOutSize - outSize) * 100.0f / expOutSize;
        ALOGD("%s relative bitrate error is %f %%", log, brDev);
        if (brDev > 50) {
            ALOGE("%s relative bitrate error is is too large %f %%", log, brDev);
            return false;
        }
    }
    return isPass;
}

static jboolean nativeTestSimpleEncode(JNIEnv* env, jobject, jstring jEncoder, jstring jsrcPath,
                                       jstring jMime, jintArray jList0, jintArray jList1,
                                       jintArray jList2, jint colorFormat) {
    const char* csrcPath = env->GetStringUTFChars(jsrcPath, nullptr);
    const char* cmime = env->GetStringUTFChars(jMime, nullptr);
    const char* cEncoder = env->GetStringUTFChars(jEncoder, nullptr);
    jsize cLen0 = env->GetArrayLength(jList0);
    jint* cList0 = env->GetIntArrayElements(jList0, nullptr);
    jsize cLen1 = env->GetArrayLength(jList1);
    jint* cList1 = env->GetIntArrayElements(jList1, nullptr);
    jsize cLen2 = env->GetArrayLength(jList2);
    jint* cList2 = env->GetIntArrayElements(jList2, nullptr);
    auto codecEncoderTest = new CodecEncoderTest(cmime, cList0, cLen0, cList1, cLen1, cList2, cLen2,
                                                 (int)colorFormat);
    bool isPass = codecEncoderTest->testSimpleEncode(cEncoder, csrcPath);
    delete codecEncoderTest;
    env->ReleaseIntArrayElements(jList0, cList0, 0);
    env->ReleaseIntArrayElements(jList1, cList1, 0);
    env->ReleaseIntArrayElements(jList2, cList2, 0);
    env->ReleaseStringUTFChars(jEncoder, cEncoder);
    env->ReleaseStringUTFChars(jMime, cmime);
    env->ReleaseStringUTFChars(jsrcPath, csrcPath);
    return static_cast<jboolean>(isPass);
}

static jboolean nativeTestFlush(JNIEnv* env, jobject, jstring jEncoder, jstring jsrcPath,
                                jstring jMime, jintArray jList0, jintArray jList1, jintArray jList2,
                                jint colorFormat) {
    const char* csrcPath = env->GetStringUTFChars(jsrcPath, nullptr);
    const char* cmime = env->GetStringUTFChars(jMime, nullptr);
    const char* cEncoder = env->GetStringUTFChars(jEncoder, nullptr);
    jsize cLen0 = env->GetArrayLength(jList0);
    jint* cList0 = env->GetIntArrayElements(jList0, nullptr);
    jsize cLen1 = env->GetArrayLength(jList1);
    jint* cList1 = env->GetIntArrayElements(jList1, nullptr);
    jsize cLen2 = env->GetArrayLength(jList2);
    jint* cList2 = env->GetIntArrayElements(jList2, nullptr);
    auto codecEncoderTest = new CodecEncoderTest(cmime, cList0, cLen0, cList1, cLen1, cList2, cLen2,
                                                 (int)colorFormat);
    bool isPass = codecEncoderTest->testFlush(cEncoder, csrcPath);
    delete codecEncoderTest;
    env->ReleaseIntArrayElements(jList0, cList0, 0);
    env->ReleaseIntArrayElements(jList1, cList1, 0);
    env->ReleaseIntArrayElements(jList2, cList2, 0);
    env->ReleaseStringUTFChars(jEncoder, cEncoder);
    env->ReleaseStringUTFChars(jMime, cmime);
    env->ReleaseStringUTFChars(jsrcPath, csrcPath);
    return static_cast<jboolean>(isPass);
}

static jboolean nativeTestReconfigure(JNIEnv* env, jobject, jstring jEncoder, jstring jsrcPath,
                                      jstring jMime, jintArray jList0, jintArray jList1,
                                      jintArray jList2, jint colorFormat) {
    bool isPass;
    const char* csrcPath = env->GetStringUTFChars(jsrcPath, nullptr);
    const char* cmime = env->GetStringUTFChars(jMime, nullptr);
    const char* cEncoder = env->GetStringUTFChars(jEncoder, nullptr);
    jsize cLen0 = env->GetArrayLength(jList0);
    jint* cList0 = env->GetIntArrayElements(jList0, nullptr);
    jsize cLen1 = env->GetArrayLength(jList1);
    jint* cList1 = env->GetIntArrayElements(jList1, nullptr);
    jsize cLen2 = env->GetArrayLength(jList2);
    jint* cList2 = env->GetIntArrayElements(jList2, nullptr);
    auto codecEncoderTest = new CodecEncoderTest(cmime, cList0, cLen0, cList1, cLen1, cList2, cLen2,
                                                 (int)colorFormat);
    isPass = codecEncoderTest->testReconfigure(cEncoder, csrcPath);
    delete codecEncoderTest;
    env->ReleaseIntArrayElements(jList0, cList0, 0);
    env->ReleaseIntArrayElements(jList1, cList1, 0);
    env->ReleaseIntArrayElements(jList2, cList2, 0);
    env->ReleaseStringUTFChars(jEncoder, cEncoder);
    env->ReleaseStringUTFChars(jMime, cmime);
    env->ReleaseStringUTFChars(jsrcPath, csrcPath);
    return static_cast<jboolean>(isPass);
}

static jboolean nativeTestSetForceSyncFrame(JNIEnv* env, jobject, jstring jEncoder,
                                            jstring jsrcPath, jstring jMime, jintArray jList0,
                                            jintArray jList1, jintArray jList2, jint colorFormat) {
    const char* csrcPath = env->GetStringUTFChars(jsrcPath, nullptr);
    const char* cmime = env->GetStringUTFChars(jMime, nullptr);
    const char* cEncoder = env->GetStringUTFChars(jEncoder, nullptr);
    jsize cLen0 = env->GetArrayLength(jList0);
    jint* cList0 = env->GetIntArrayElements(jList0, nullptr);
    jsize cLen1 = env->GetArrayLength(jList1);
    jint* cList1 = env->GetIntArrayElements(jList1, nullptr);
    jsize cLen2 = env->GetArrayLength(jList2);
    jint* cList2 = env->GetIntArrayElements(jList2, nullptr);
    auto codecEncoderTest = new CodecEncoderTest(cmime, cList0, cLen0, cList1, cLen1, cList2, cLen2,
                                                 (int)colorFormat);
    bool isPass = codecEncoderTest->testSetForceSyncFrame(cEncoder, csrcPath);
    delete codecEncoderTest;
    env->ReleaseIntArrayElements(jList0, cList0, 0);
    env->ReleaseIntArrayElements(jList1, cList1, 0);
    env->ReleaseIntArrayElements(jList2, cList2, 0);
    env->ReleaseStringUTFChars(jEncoder, cEncoder);
    env->ReleaseStringUTFChars(jMime, cmime);
    env->ReleaseStringUTFChars(jsrcPath, csrcPath);
    return static_cast<jboolean>(isPass);
}

static jboolean nativeTestAdaptiveBitRate(JNIEnv* env, jobject, jstring jEncoder, jstring jsrcPath,
                                          jstring jMime, jintArray jList0, jintArray jList1,
                                          jintArray jList2, jint colorFormat) {
    const char* csrcPath = env->GetStringUTFChars(jsrcPath, nullptr);
    const char* cmime = env->GetStringUTFChars(jMime, nullptr);
    const char* cEncoder = env->GetStringUTFChars(jEncoder, nullptr);
    jsize cLen0 = env->GetArrayLength(jList0);
    jint* cList0 = env->GetIntArrayElements(jList0, nullptr);
    jsize cLen1 = env->GetArrayLength(jList1);
    jint* cList1 = env->GetIntArrayElements(jList1, nullptr);
    jsize cLen2 = env->GetArrayLength(jList2);
    jint* cList2 = env->GetIntArrayElements(jList2, nullptr);
    auto codecEncoderTest = new CodecEncoderTest(cmime, cList0, cLen0, cList1, cLen1, cList2, cLen2,
                                                 (int)colorFormat);
    bool isPass = codecEncoderTest->testAdaptiveBitRate(cEncoder, csrcPath);
    delete codecEncoderTest;
    env->ReleaseIntArrayElements(jList0, cList0, 0);
    env->ReleaseIntArrayElements(jList1, cList1, 0);
    env->ReleaseIntArrayElements(jList2, cList2, 0);
    env->ReleaseStringUTFChars(jEncoder, cEncoder);
    env->ReleaseStringUTFChars(jMime, cmime);
    env->ReleaseStringUTFChars(jsrcPath, csrcPath);
    return static_cast<jboolean>(isPass);
}

static jboolean nativeTestOnlyEos(JNIEnv* env, jobject, jstring jEncoder, jstring jMime,
                                  jintArray jList0, jintArray jList1, jintArray jList2,
                                  jint colorFormat) {
    const char* cmime = env->GetStringUTFChars(jMime, nullptr);
    const char* cEncoder = env->GetStringUTFChars(jEncoder, nullptr);
    jsize cLen0 = env->GetArrayLength(jList0);
    jint* cList0 = env->GetIntArrayElements(jList0, nullptr);
    jsize cLen1 = env->GetArrayLength(jList1);
    jint* cList1 = env->GetIntArrayElements(jList1, nullptr);
    jsize cLen2 = env->GetArrayLength(jList2);
    jint* cList2 = env->GetIntArrayElements(jList2, nullptr);
    auto codecEncoderTest = new CodecEncoderTest(cmime, cList0, cLen0, cList1, cLen1, cList2, cLen2,
                                                 (int)colorFormat);
    bool isPass = codecEncoderTest->testOnlyEos(cEncoder);
    delete codecEncoderTest;
    env->ReleaseIntArrayElements(jList0, cList0, 0);
    env->ReleaseIntArrayElements(jList1, cList1, 0);
    env->ReleaseIntArrayElements(jList2, cList2, 0);
    env->ReleaseStringUTFChars(jEncoder, cEncoder);
    env->ReleaseStringUTFChars(jMime, cmime);
    return static_cast<jboolean>(isPass);
}

int registerAndroidMediaV2CtsEncoderTest(JNIEnv* env) {
    const JNINativeMethod methodTable[] = {
            {"nativeTestSimpleEncode",
             "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[I[I[II)Z",
             (void*)nativeTestSimpleEncode},
            {"nativeTestFlush", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[I[I[II)Z",
             (void*)nativeTestFlush},
            {"nativeTestReconfigure",
             "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[I[I[II)Z",
             (void*)nativeTestReconfigure},
            {"nativeTestSetForceSyncFrame",
             "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[I[I[II)Z",
             (void*)nativeTestSetForceSyncFrame},
            {"nativeTestAdaptiveBitRate",
             "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[I[I[II)Z",
             (void*)nativeTestAdaptiveBitRate},
            {"nativeTestOnlyEos", "(Ljava/lang/String;Ljava/lang/String;[I[I[II)Z",
             (void*)nativeTestOnlyEos},
    };
    jclass c = env->FindClass("android/mediav2/cts/CodecEncoderTest");
    return env->RegisterNatives(c, methodTable, sizeof(methodTable) / sizeof(JNINativeMethod));
}

extern int registerAndroidMediaV2CtsCodecUnitTest(JNIEnv* env);
extern int registerAndroidMediaV2CtsDecoderTest(JNIEnv* env);
extern int registerAndroidMediaV2CtsDecoderSurfaceTest(JNIEnv* env);
extern int registerAndroidMediaV2CtsEncoderSurfaceTest(JNIEnv* env);

extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
    JNIEnv* env;
    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) return JNI_ERR;
    if (registerAndroidMediaV2CtsCodecUnitTest(env) != JNI_OK) return JNI_ERR;
    if (registerAndroidMediaV2CtsEncoderTest(env) != JNI_OK) return JNI_ERR;
    if (registerAndroidMediaV2CtsDecoderTest(env) != JNI_OK) return JNI_ERR;
    if (registerAndroidMediaV2CtsDecoderSurfaceTest(env) != JNI_OK) return JNI_ERR;
    if (registerAndroidMediaV2CtsEncoderSurfaceTest(env) != JNI_OK) return JNI_ERR;
    return JNI_VERSION_1_6;
}
