/*
 * 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 "NativeMediaCommon.h"

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

    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 deleteParams();
    bool configureCodec(AMediaFormat* format, bool isAsync, bool signalEOSWithLastFrame,
                        bool isEncoder) override;
    void resetContext(bool isAsync, bool signalEOSWithLastFrame) override;
    bool enqueueInput(size_t bufferIndex) override;
    bool dequeueOutput(size_t bufferIndex, AMediaCodecBufferInfo* bufferInfo) override;
    bool doWork(int frameLimit) override;
    bool isTestStateValid() override;
    bool 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, const char* cfgParams, const char* cfgReconfigParams,
                     const char* separator);
    ~CodecEncoderTest();

    bool testSimpleEncode(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, const char* cfgParams,
                                   const char* cfgReconfigParams, const char* separator)
    : CodecTestBase(mime) {
    mFormats.push_back(deSerializeMediaFormat(cfgParams, separator));
    if (cfgReconfigParams) {
        mFormats.push_back(deSerializeMediaFormat(cfgReconfigParams, separator));
    }
    if (mIsVideo && mFormats[0] != nullptr) {
        AMediaFormat_getInt32(mFormats[0], AMEDIAFORMAT_KEY_COLOR_FORMAT, &mColorFormat);
    }
    mInputData = nullptr;
    mInputLength = 0;
    mInputBufferReadOffset = 0;
    mNumBytesSubmitted = 0;
    mLoopBackFrameLimit = 0;
    mIsLoopBack = false;
    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::deleteParams() {
    for (auto format : mFormats) AMediaFormat_delete(format);
    mFormats.clear();
}

bool CodecEncoderTest::configureCodec(AMediaFormat* format, bool isAsync,
                                      bool signalEOSWithLastFrame, bool isEncoder) {
    if (!initFormat(format)) return false;
    return CodecTestBase::configureCodec(format, isAsync, signalEOSWithLastFrame, isEncoder);
}

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

void CodecEncoderTest::fillByteBuffer(uint8_t* inputBuffer) {
    int width, height, tileWidth, tileHeight;
    int offset = 0, frmOffset = mInputBufferReadOffset;
    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 (mInputBufferReadOffset >= mInputLength) {
        if (!mIsLoopBack) return enqueueEOS(bufferIndex);
        mInputBufferReadOffset = 0; // loop back to beginning
    }
    {
        int size = 0;
        int flags = 0;
        int64_t pts = mInputOffsetPts;
        size_t buffSize;
        uint8_t* inputBuffer = AMediaCodec_getInputBuffer(mCodec, bufferIndex, &buffSize);
        RETURN_IF_NULL(inputBuffer, std::string{"AMediaCodec_getInputBuffer returned nullptr"})
        if (mIsAudio) {
            pts += mNumBytesSubmitted * 1000000LL / (2 * mChannels * mSampleRate);
            size = std::min(buffSize, mInputLength - mInputBufferReadOffset);
            memcpy(inputBuffer, mInputData + mInputBufferReadOffset, size);
            if (mSignalEOSWithLastFrame) {
                if (mIsLoopBack ? (mInputCount + 1 >= mLoopBackFrameLimit)
                                : (mInputBufferReadOffset + size >= mInputLength)) {
                    flags |= AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM;
                    mSawInputEOS = true;
                }
            }
            mInputBufferReadOffset += size;
        } else {
            pts += mInputCount * 1000000LL / mDefFrameRate;
            size = mWidth * mHeight * 3 / 2;
            int frmSize = kInpFrmWidth * kInpFrmHeight * 3 / 2;
            RETURN_IF_TRUE(mInputBufferReadOffset + frmSize > mInputLength,
                           std::string{"received partial frame to encode"})
            RETURN_IF_TRUE(size > buffSize,
                           StringFormat("frame size exceeds buffer capacity of input buffer %d %zu",
                                        size, buffSize))
            if (mWidth == kInpFrmWidth && mHeight == kInpFrmHeight) {
                memcpy(inputBuffer, mInputData + mInputBufferReadOffset, size);
            } else {
                fillByteBuffer(inputBuffer);
            }
            if (mSignalEOSWithLastFrame) {
                if (mIsLoopBack ? (mInputCount + 1 >= mLoopBackFrameLimit)
                                : (mInputBufferReadOffset + frmSize >= mInputLength)) {
                    flags |= AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM;
                    mSawInputEOS = true;
                }
            }
            mInputBufferReadOffset += frmSize;
        }
        mNumBytesSubmitted += size;
        RETURN_IF_FAIL(AMediaCodec_queueInputBuffer(mCodec, bufferIndex, 0, size, pts, flags),
                       "AMediaCodec_queueInputBuffer failed")
        ALOGV("input: id: %zu  size: %d  pts: %" PRId64 "  flags: %d", bufferIndex, size, 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);
            RETURN_IF_NULL(buf, std::string{"AMediaCodec_getOutputBuffer returned nullptr"})
            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: %" PRId64 "  flags: %d", bufferIndex, info->size,
          info->presentationTimeUs, info->flags);
    RETURN_IF_FAIL(AMediaCodec_releaseOutputBuffer(mCodec, bufferIndex, false),
                   "AMediaCodec_releaseOutputBuffer failed")
    return !hasSeenError();
}

bool CodecEncoderTest::doWork(int frameLimit) {
    mLoopBackFrameLimit = frameLimit;
    return CodecTestBase::doWork(frameLimit);
}

bool CodecEncoderTest::isTestStateValid() {
    if (!CodecTestBase::isTestStateValid()) return false;
    RETURN_IF_TRUE((mIsAudio || (mIsVideo && mMaxBFrames == 0)) &&
                           !mOutputBuff->isPtsStrictlyIncreasing(mPrevOutputPts),
                   std::string{"Output timestamps are not strictly increasing \n"}.append(
                           mOutputBuff->getErrorMsg()))
    RETURN_IF_TRUE(mIsVideo && !mOutputBuff->isOutPtsListIdenticalToInpPtsList(mMaxBFrames != 0),
                   std::string{"Input pts list and Output pts list are not identical \n"}.append(
                           mOutputBuff->getErrorMsg()))
    return true;
}

bool CodecEncoderTest::initFormat(AMediaFormat* format) {
    if (mIsAudio) {
        RETURN_IF_FALSE(AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, &mSampleRate),
                        StringFormat("format does not have key %s", AMEDIAFORMAT_KEY_SAMPLE_RATE))
        RETURN_IF_FALSE(AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &mChannels),
                        StringFormat("format does not have key %s", AMEDIAFORMAT_KEY_CHANNEL_COUNT))
    } else {
        RETURN_IF_FALSE(AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &mWidth),
                        StringFormat("format does not have key %s", AMEDIAFORMAT_KEY_WIDTH))
        RETURN_IF_FALSE(AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &mHeight),
                        StringFormat("format does not have key %s", AMEDIAFORMAT_KEY_HEIGHT))
        RETURN_IF_FALSE(AMediaFormat_getInt32(format, TBD_AMEDIACODEC_PARAMETER_KEY_MAX_B_FRAMES,
                                              &mMaxBFrames),
                        StringFormat("format does not have key %s",
                                     TBD_AMEDIACODEC_PARAMETER_KEY_MAX_B_FRAMES))
        RETURN_IF_FALSE(AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_FRAME_RATE, &mDefFrameRate),
                        StringFormat("format does not have key %s", AMEDIAFORMAT_KEY_FRAME_RATE))
        RETURN_IF_FALSE(AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_COLOR_FORMAT, &mColorFormat),
                        StringFormat("format does not have key %s", AMEDIAFORMAT_KEY_COLOR_FORMAT))
    }
    return true;
}

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);
    RETURN_IF_NULL(mCodec, StringFormat("unable to create codec by name %s \n", encoder))
    setUpSource(file);
    RETURN_IF_NULL(mInputData, StringFormat("unable to open input file %s", file))
    if (!configureCodec(format, false, true, true)) return false;
    RETURN_IF_FAIL(AMediaCodec_start(mCodec), "AMediaCodec_start failed")
    if (!doWork(frameLimit)) return false;
    if (!queueEOS()) return false;
    if (!waitForAllOutputs()) return false;
    RETURN_IF_FAIL(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed")
    RETURN_IF_FAIL(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) {
    setUpSource(srcPath);
    RETURN_IF_NULL(mInputData, StringFormat("unable to open input file %s", srcPath))
    /* TODO(b/149027258) */
    if (true) mSaveToMem = false;
    else mSaveToMem = true;
    auto ref = mRefBuff;
    auto test = mTestBuff;
    const bool boolStates[]{true, false};
    for (auto format : mFormats) {
        RETURN_IF_NULL(format,
                       std::string{"encountered error during deserialization of media format"})
        int loopCounter = 0;
        for (auto eosType : boolStates) {
            for (auto isAsync : boolStates) {
                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);
                RETURN_IF_NULL(mCodec, StringFormat("unable to create codec %s", encoder))
                char* name = nullptr;
                RETURN_IF_FAIL(AMediaCodec_getName(mCodec, &name), "AMediaCodec_getName failed")
                RETURN_IF_NULL(name, std::string{"AMediaCodec_getName returned null"})
                auto res = strcmp(name, encoder) != 0;
                AMediaCodec_releaseName(mCodec, name);
                RETURN_IF_TRUE(res,
                               StringFormat("Codec name mismatch act/got: %s/%s", encoder, name))
                if (!configureCodec(format, isAsync, eosType, true)) return false;
                RETURN_IF_FAIL(AMediaCodec_start(mCodec), "AMediaCodec_start failed")
                if (!doWork(INT32_MAX)) return false;
                if (!queueEOS()) return false;
                if (!waitForAllOutputs()) return false;
                RETURN_IF_FAIL(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed")
                RETURN_IF_FAIL(AMediaCodec_delete(mCodec), "AMediaCodec_delete failed")
                mCodec = nullptr;
                RETURN_IF_TRUE((loopCounter != 0 && !ref->equals(test)),
                               std::string{"Encoder output is not consistent across runs \n"}
                                       .append(test->getErrorMsg()))
                loopCounter++;
            }
        }
    }
    return true;
}

bool CodecEncoderTest::testReconfigure(const char* encoder, const char* srcPath) {
    setUpSource(srcPath);
    RETURN_IF_NULL(mInputData, StringFormat("unable to open input file %s", srcPath))
    auto configRef = mReconfBuff;
    if (mFormats.size() > 1) {
        auto format = mFormats[1];
        RETURN_IF_NULL(format,
                       std::string{"encountered error during deserialization of media format"})
        RETURN_IF_FALSE(encodeToMemory(srcPath, encoder, INT32_MAX, format, configRef),
                        StringFormat("encodeToMemory failed for file: %s codec: %s \n format: %s",
                                     srcPath, encoder, AMediaFormat_toString(format)))
    }
    auto format = mFormats[0];
    RETURN_IF_NULL(format, std::string{"encountered error during deserialization of media format"})
    auto ref = mRefBuff;
    RETURN_IF_FALSE(encodeToMemory(srcPath, encoder, INT32_MAX, format, ref),
                    StringFormat("encodeToMemory failed for file: %s codec: %s \n format: %s",
                                 srcPath, encoder, AMediaFormat_toString(format)))

    auto test = mTestBuff;
    mOutputBuff = test;
    const bool boolStates[]{true, false};
    for (auto isAsync : boolStates) {
        /* 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);
        RETURN_IF_NULL(mCodec, StringFormat("unable to create codec %s", encoder))
        if (!configureCodec(format, isAsync, true, true)) return false;
        /* test reconfigure in init state */
        if (!reConfigureCodec(format, !isAsync, false, true)) return false;
        RETURN_IF_FAIL(AMediaCodec_start(mCodec), "AMediaCodec_start failed")

        /* test reconfigure in running state before queuing input */
        if (!reConfigureCodec(format, !isAsync, false, true)) return false;
        RETURN_IF_FAIL(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;
        RETURN_IF_FAIL(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;
        RETURN_IF_FAIL(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed")
        RETURN_IF_TRUE(!ref->equals(test),
                       std::string{"Encoder output is not consistent across runs \n"}.append(
                               test->getErrorMsg()))

        /* test reconfigure codec at eos state */
        if (!reConfigureCodec(format, !isAsync, false, true)) return false;
        RETURN_IF_FAIL(AMediaCodec_start(mCodec), "AMediaCodec_start failed")
        test->reset();
        if (!doWork(INT32_MAX)) return false;
        if (!queueEOS()) return false;
        if (!waitForAllOutputs()) return false;
        RETURN_IF_FAIL(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed")
        RETURN_IF_TRUE(!ref->equals(test),
                       std::string{"Encoder output is not consistent across runs \n"}.append(
                               test->getErrorMsg()))

        /* test reconfigure codec for new format */
        if (mFormats.size() > 1) {
            if (!reConfigureCodec(mFormats[1], isAsync, false, true)) return false;
            RETURN_IF_FAIL(AMediaCodec_start(mCodec), "AMediaCodec_start failed")
            test->reset();
            if (!doWork(INT32_MAX)) return false;
            if (!queueEOS()) return false;
            if (!waitForAllOutputs()) return false;
            RETURN_IF_FAIL(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed")
            RETURN_IF_TRUE(!configRef->equals(test),
                           std::string{"Encoder output is not consistent across runs \n"}.append(
                                   test->getErrorMsg()))
        }
        mSaveToMem = false;
        RETURN_IF_FAIL(AMediaCodec_delete(mCodec), "AMediaCodec_delete failed")
        mCodec = nullptr;
    }
    return true;
}

bool CodecEncoderTest::testOnlyEos(const char* encoder) {
    /* 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];
    RETURN_IF_NULL(format,
                   std::string{"encountered error during deserialization of media format"})
    int loopCounter = 0;
    for (auto isAsync : boolStates) {
        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);
        RETURN_IF_NULL(mCodec, StringFormat("unable to create codec by name %s", encoder))
        if (!configureCodec(format, isAsync, false, true)) return false;
        RETURN_IF_FAIL(AMediaCodec_start(mCodec), "AMediaCodec_start failed")
        if (!queueEOS()) return false;
        if (!waitForAllOutputs()) return false;
        RETURN_IF_FAIL(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed")
        RETURN_IF_FAIL(AMediaCodec_delete(mCodec), "AMediaCodec_delete failed")
        mCodec = nullptr;
        RETURN_IF_TRUE((loopCounter != 0 && !ref->equals(test)),
                       std::string{"Encoder output is not consistent across runs \n"}.append(
                               test->getErrorMsg()))
        loopCounter++;
    }
    return true;
}

bool CodecEncoderTest::testSetForceSyncFrame(const char* encoder, const char* srcPath) {
    setUpSource(srcPath);
    RETURN_IF_NULL(mInputData, StringFormat("unable to open input file %s", srcPath))
    AMediaFormat* format = mFormats[0];
    RETURN_IF_NULL(format,
                   std::string{"encountered error during deserialization of media format"})
    RETURN_IF_FALSE(AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_FRAME_RATE, &mDefFrameRate),
                    StringFormat("format does not have key %s", AMEDIAFORMAT_KEY_FRAME_RATE))
    // 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) {
        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);
        RETURN_IF_NULL(mCodec, StringFormat("unable to create codec by name%s", encoder))
        if (!configureCodec(format, isAsync, false, true)) return false;
        RETURN_IF_FAIL(AMediaCodec_start(mCodec), "AMediaCodec_start failed")
        for (int i = 0; i < kNumKeyFrameRequests; i++) {
            if (!doWork(kKeyFramePos)) return false;
            RETURN_IF_TRUE(mSawInputEOS,
                           StringFormat("Unable to encode %d frames as the input resource contains "
                                        "only %d frames \n",
                                        kKeyFramePos, mInputCount))
            forceSyncFrame(params);
            mInputBufferReadOffset = 0;
        }
        if (!queueEOS()) return false;
        if (!waitForAllOutputs()) return false;
        RETURN_IF_FAIL(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed")
        RETURN_IF_FAIL(AMediaCodec_delete(mCodec), "AMediaCodec_delete failed")
        mCodec = nullptr;
        RETURN_IF_TRUE((mNumSyncFramesReceived < kNumKeyFrameRequests),
                       StringFormat("Received only %d key frames for %d key frame requests \n",
                                    mNumSyncFramesReceived, kNumKeyFrameRequests))
        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 true;
}

bool CodecEncoderTest::testAdaptiveBitRate(const char* encoder, const char* srcPath) {
    setUpSource(srcPath);
    RETURN_IF_NULL(mInputData, StringFormat("unable to open input file %s", srcPath))
    AMediaFormat* format = mFormats[0];
    RETURN_IF_NULL(format,
                   std::string{"encountered error during deserialization of media format"})
    RETURN_IF_FALSE(AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_FRAME_RATE, &mDefFrameRate),
                    StringFormat("format does not have key %s", AMEDIAFORMAT_KEY_FRAME_RATE))
    int kAdaptiveBitrateInterval = 3;  // change bitrate every 3 seconds.
    int kAdaptiveBitrateDurationFrame = mDefFrameRate * kAdaptiveBitrateInterval;
    int kBitrateChangeRequests = 7;
    // TODO(b/251265293) Reduce the allowed deviation after improving the test conditions
    float kMaxBitrateDeviation = 60.0; // allowed bitrate deviation in %
    AMediaFormat* params = AMediaFormat_new();
    mFormats.push_back(params);
    mOutputBuff = mTestBuff;
    mSaveToMem = true;
    const bool boolStates[]{true, false};
    for (auto isAsync : boolStates) {
        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);
        RETURN_IF_NULL(mCodec, StringFormat("unable to create codec by name %s", encoder))
        if (!configureCodec(format, isAsync, false, true)) return false;
        RETURN_IF_FAIL(AMediaCodec_start(mCodec), "AMediaCodec_start failed")
        int expOutSize = 0;
        int bitrate;
        RETURN_IF_FALSE(AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, &bitrate),
                       StringFormat("format does not have key %s", AMEDIAFORMAT_KEY_BIT_RATE))
        for (int i = 0; i < kBitrateChangeRequests; i++) {
            if (!doWork(kAdaptiveBitrateDurationFrame)) return false;
            RETURN_IF_TRUE(mSawInputEOS,
                           StringFormat("Unable to encode %d frames as the input resource contains "
                                        "only %d frames \n",
                                        kAdaptiveBitrateDurationFrame, mInputCount))
            expOutSize += kAdaptiveBitrateInterval * bitrate;
            if ((i & 1) == 1) bitrate *= 2;
            else bitrate /= 2;
            updateBitrate(params, bitrate);
            mInputBufferReadOffset = 0;
        }
        if (!queueEOS()) return false;
        if (!waitForAllOutputs()) return false;
        RETURN_IF_FAIL(AMediaCodec_stop(mCodec), "AMediaCodec_stop failed")
        RETURN_IF_FAIL(AMediaCodec_delete(mCodec), "AMediaCodec_delete failed")
        mCodec = nullptr;
        /* 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;
        RETURN_IF_TRUE(brDev > kMaxBitrateDeviation,
                       StringFormat("Relative Bitrate error is too large : %f %%\n", brDev))
    }
    return true;
}

static jboolean nativeTestSimpleEncode(JNIEnv* env, jobject, jstring jEncoder, jstring jsrcPath,
                                       jstring jMime, jstring jCfgParams, jstring jSeparator,
                                       jobject jRetMsg) {
    const char* csrcPath = env->GetStringUTFChars(jsrcPath, nullptr);
    const char* cmime = env->GetStringUTFChars(jMime, nullptr);
    const char* cEncoder = env->GetStringUTFChars(jEncoder, nullptr);
    const char* cCfgParams = env->GetStringUTFChars(jCfgParams, nullptr);
    const char* cSeparator = env->GetStringUTFChars(jSeparator, nullptr);
    auto codecEncoderTest = new CodecEncoderTest(cmime, cCfgParams, nullptr, cSeparator);
    bool isPass = codecEncoderTest->testSimpleEncode(cEncoder, csrcPath);
    std::string msg = isPass ? std::string{} : codecEncoderTest->getErrorMsg();
    delete codecEncoderTest;
    jclass clazz = env->GetObjectClass(jRetMsg);
    jmethodID mId =
            env->GetMethodID(clazz, "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
    env->CallObjectMethod(jRetMsg, mId, env->NewStringUTF(msg.c_str()));
    env->ReleaseStringUTFChars(jCfgParams, cCfgParams);
    env->ReleaseStringUTFChars(jSeparator, cSeparator);
    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, jstring jCfgParams, jstring jReconfigCfgParams,
                                      jstring jSeparator, jobject jRetMsg) {
    bool isPass;
    const char* csrcPath = env->GetStringUTFChars(jsrcPath, nullptr);
    const char* cmime = env->GetStringUTFChars(jMime, nullptr);
    const char* cEncoder = env->GetStringUTFChars(jEncoder, nullptr);
    const char* cCfgParams = env->GetStringUTFChars(jCfgParams, nullptr);
    const char* cReconfigCfgParams = jReconfigCfgParams != nullptr
                                             ? env->GetStringUTFChars(jReconfigCfgParams, nullptr)
                                             : nullptr;
    const char* cSeparator = env->GetStringUTFChars(jSeparator, nullptr);
    auto codecEncoderTest = new CodecEncoderTest(cmime, cCfgParams, cReconfigCfgParams, cSeparator);
    isPass = codecEncoderTest->testReconfigure(cEncoder, csrcPath);
    std::string msg = isPass ? std::string{} : codecEncoderTest->getErrorMsg();
    delete codecEncoderTest;
    jclass clazz = env->GetObjectClass(jRetMsg);
    jmethodID mId =
            env->GetMethodID(clazz, "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
    env->CallObjectMethod(jRetMsg, mId, env->NewStringUTF(msg.c_str()));
    env->ReleaseStringUTFChars(jCfgParams, cCfgParams);
    if (cReconfigCfgParams != nullptr) {
        env->ReleaseStringUTFChars(jReconfigCfgParams, cReconfigCfgParams);
    }
    env->ReleaseStringUTFChars(jSeparator, cSeparator);
    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, jstring jCfgParams,
                                            jstring jSeparator, jobject jRetMsg) {
    const char* csrcPath = env->GetStringUTFChars(jsrcPath, nullptr);
    const char* cmime = env->GetStringUTFChars(jMime, nullptr);
    const char* cEncoder = env->GetStringUTFChars(jEncoder, nullptr);
    const char* cCfgParams = env->GetStringUTFChars(jCfgParams, nullptr);
    const char* cSeparator = env->GetStringUTFChars(jSeparator, nullptr);
    auto codecEncoderTest = new CodecEncoderTest(cmime, cCfgParams, nullptr, cSeparator);
    bool isPass = codecEncoderTest->testSetForceSyncFrame(cEncoder, csrcPath);
    std::string msg = isPass ? std::string{} : codecEncoderTest->getErrorMsg();
    delete codecEncoderTest;
    jclass clazz = env->GetObjectClass(jRetMsg);
    jmethodID mId =
            env->GetMethodID(clazz, "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
    env->CallObjectMethod(jRetMsg, mId, env->NewStringUTF(msg.c_str()));
    env->ReleaseStringUTFChars(jCfgParams, cCfgParams);
    env->ReleaseStringUTFChars(jSeparator, cSeparator);
    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, jstring jCfgParams, jstring jSeparator,
                                          jobject jRetMsg) {
    const char* csrcPath = env->GetStringUTFChars(jsrcPath, nullptr);
    const char* cmime = env->GetStringUTFChars(jMime, nullptr);
    const char* cEncoder = env->GetStringUTFChars(jEncoder, nullptr);
    const char* cCfgParams = env->GetStringUTFChars(jCfgParams, nullptr);
    const char* cSeparator = env->GetStringUTFChars(jSeparator, nullptr);
    auto codecEncoderTest = new CodecEncoderTest(cmime, cCfgParams, nullptr, cSeparator);
    bool isPass = codecEncoderTest->testAdaptiveBitRate(cEncoder, csrcPath);
    std::string msg = isPass ? std::string{} : codecEncoderTest->getErrorMsg();
    delete codecEncoderTest;
    jclass clazz = env->GetObjectClass(jRetMsg);
    jmethodID mId =
            env->GetMethodID(clazz, "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
    env->CallObjectMethod(jRetMsg, mId, env->NewStringUTF(msg.c_str()));
    env->ReleaseStringUTFChars(jCfgParams, cCfgParams);
    env->ReleaseStringUTFChars(jSeparator, cSeparator);
    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,
                                  jstring jCfgParams, jstring jSeparator, jobject jRetMsg) {
    const char* cmime = env->GetStringUTFChars(jMime, nullptr);
    const char* cEncoder = env->GetStringUTFChars(jEncoder, nullptr);
    const char* cCfgParams = env->GetStringUTFChars(jCfgParams, nullptr);
    const char* cSeparator = env->GetStringUTFChars(jSeparator, nullptr);
    auto codecEncoderTest = new CodecEncoderTest(cmime, cCfgParams, nullptr, cSeparator);
    bool isPass = codecEncoderTest->testOnlyEos(cEncoder);
    std::string msg = isPass ? std::string{} : codecEncoderTest->getErrorMsg();
    delete codecEncoderTest;
    jclass clazz = env->GetObjectClass(jRetMsg);
    jmethodID mId =
            env->GetMethodID(clazz, "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
    env->CallObjectMethod(jRetMsg, mId, env->NewStringUTF(msg.c_str()));
    env->ReleaseStringUTFChars(jCfgParams, cCfgParams);
    env->ReleaseStringUTFChars(jSeparator, cSeparator);
    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;Ljava/lang/String;Ljava/lang/"
             "String;Ljava/lang/StringBuilder;)Z",
             (void*)nativeTestSimpleEncode},
            {"nativeTestReconfigure",
             "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/"
             "String;Ljava/lang/String;Ljava/lang/StringBuilder;)Z",
             (void*)nativeTestReconfigure},
            {"nativeTestSetForceSyncFrame",
             "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/"
             "String;Ljava/lang/StringBuilder;)Z",
             (void*)nativeTestSetForceSyncFrame},
            {"nativeTestAdaptiveBitRate",
             "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/"
             "String;Ljava/lang/StringBuilder;)Z",
             (void*)nativeTestAdaptiveBitRate},
            {"nativeTestOnlyEos",
             "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/"
             "StringBuilder;)Z",
             (void*)nativeTestOnlyEos},
    };
    jclass c = env->FindClass("android/mediav2/cts/CodecEncoderTest");
    return env->RegisterNatives(c, methodTable, sizeof(methodTable) / sizeof(JNINativeMethod));
}

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 (registerAndroidMediaV2CtsEncoderTest(env) != JNI_OK) return JNI_ERR;
    return JNI_VERSION_1_6;
}
