/*
 * Copyright (C) 2019-2020 Intel Corporation
 *
 * 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_TAG "PipeLiteExecutor"

#include <algorithm>

#include "PipeLiteExecutor.h"
#include "PSysDAG.h"

#include "FormatUtils.h"
#include "iutils/CameraDump.h"
#include "SyncManager.h"

// CIPF backends
extern "C" {
#include <ia_cipf_css/ia_cipf_css.h>
#include <ia_pal_types_isp_ids_autogen.h>
}

using std::vector;
using std::string;
using std::map;
using std::shared_ptr;

namespace icamera {

static const int32_t sStatKernels[] = {
    ia_pal_uuid_isp_bxt_awbstatistics,
    ia_pal_uuid_isp_awbstatistics_2_0,
    ia_pal_uuid_isp_bxt_dvsstatistics
};

static const int32_t sSisKernels[] = {
    ia_pal_uuid_isp_sis_1_0_a
};

PipeLiteExecutor::PipeLiteExecutor(int cameraId, const ExecutorPolicy &policy,
                                   vector<string> exclusivePGs, PSysDAG *psysDag,
                                   shared_ptr<IGraphConfig> gc)
      : mCameraId(cameraId),
        mStreamId(-1),
        mName(policy.exeName),
        mPGNames(policy.pgList),
        mOpModes(policy.opModeList),
        mGraphConfig(gc),
        mIsInputEdge(false),
        mIsOutputEdge(false),
        mNotifyPolicy(POLICY_FRAME_FIRST),
        mAdaptor(nullptr),
        mPolicyManager(nullptr),
        mShareReferPool(nullptr),
        mLastStatsSequence(-1),
        mExclusivePGs(exclusivePGs),
        mPSysDag(psysDag),
        mkernelsCountWithStats(0)
{
}

PipeLiteExecutor::~PipeLiteExecutor()
{
    while (!mPGExecutors.empty()) {
        ExecutorUnit& unit = mPGExecutors.back();
        if (unit.pg.get()) {
            unit.pg->deInit();
        }
        mPGExecutors.pop_back();
    }

    releaseBuffers();
}

int PipeLiteExecutor::initPipe()
{
    LOG1("@%s:%s", __func__, getName());
    CheckError(mGraphConfig == nullptr, BAD_VALUE, "%s, the graph config is NULL, BUG!", __func__);

    NodesPtrVector programGroups;
    vector<IGraphType::PipelineConnection> connVector;

    int ret = mGraphConfig->pipelineGetConnections(mPGNames, &connVector);
    CheckError(connVector.empty(), ret, "Failed to get connections for executor:%s", mName.c_str());

    ret = createPGs();
    CheckError(ret != OK, ret, "Failed to create PGs for executor: %s", ret, mName.c_str());

    ret = analyzeConnections(connVector);
    CheckError(ret != OK, ret, "Failed to analyze connections for executor: %s", ret, mName.c_str());

    ret = configurePGs();
    CheckError(ret != OK, ret, "Failed to configure connections for executor: %s", ret, mName.c_str());

    assignDefaultPortsForTerminals();
    return OK;
}

int PipeLiteExecutor::analyzeConnections(const vector<IGraphType::PipelineConnection>& connVector)
{
    ia_uid firstStageId = mPGExecutors.front().stageId;
    ia_uid lastStageId = mPGExecutors.back().stageId;

    for (auto const& connection : connVector) {
        LOG2("%s: terminal %d (%d): %dx%d, 0x%x", getName(),
             connection.portFormatSettings.terminalId, connection.portFormatSettings.enabled,
             connection.portFormatSettings.width, connection.portFormatSettings.height,
             connection.portFormatSettings.fourcc);
        LOG2("%s:     connection source %d, %d, %d, has edge %d", getName(),
             connection.connectionConfig.mSourceStage, connection.connectionConfig.mSourceTerminal,
             connection.connectionConfig.mSourceIteration, connection.hasEdgePort);
        LOG2("%s:     connection sink %d, %d, %d, type %d", getName(),
             connection.connectionConfig.mSinkStage, connection.connectionConfig.mSinkTerminal,
             connection.connectionConfig.mSinkIteration, connection.connectionConfig.mConnectionType);

        storeTerminalInfo(connection);

        if (connection.portFormatSettings.enabled == 0) {
            // No actions are needed for the disabled connections.
            continue;
        }

        // If the connection's sink stage is same as the first stage/pg id in this executor,
        // then it means the connection belongs to input terminal pairs.
        if (connection.connectionConfig.mSinkStage == firstStageId && connection.hasEdgePort) {
            mIsInputEdge = true;
        }

        // If the connection's source stage is same as the last stage/pg id in this executor,
        // then it means the connection belongs to output terminal pairs.
        // SIS is output terminal but it doesn't belong to any stream, so it is not real edge output.
        if (connection.connectionConfig.mSourceStage == lastStageId
            && connection.hasEdgePort
            && connection.connectionConfig.mSourceTerminal != connection.connectionConfig.mSinkTerminal) {
            mIsOutputEdge = true;
        }
    }

    return OK;
}

int PipeLiteExecutor::storeTerminalInfo(const IGraphType::PipelineConnection& connection)
{
    FrameInfo info;
    info.mWidth = connection.portFormatSettings.width;
    info.mHeight = connection.portFormatSettings.height;
    info.mFormat = connection.portFormatSettings.fourcc;

    ia_uid curTerminal    = connection.portFormatSettings.terminalId;
    ia_uid sinkTerminal   = connection.connectionConfig.mSinkTerminal;
    ia_uid sourceTerminal = connection.connectionConfig.mSourceTerminal;
    ia_uid sinkStage      = connection.connectionConfig.mSinkStage;
    ia_uid sourceStage    = connection.connectionConfig.mSourceStage;

    TerminalDescriptor desc;
    desc.terminal       = 0;
    desc.stageId        = 0;
    desc.sinkTerminal   = sinkTerminal;
    desc.sourceTerminal = sourceTerminal;
    desc.sinkStage      = sinkStage;
    desc.sourceStage    = sourceStage;
    desc.frameDesc      = info;
    desc.enabled        = true;
    desc.hasConnection  = true;
    desc.assignedPort   = INVALID_PORT;
    desc.usrStreamId   = connection.stream ? connection.stream->streamId() : -1;

    if (connection.portFormatSettings.enabled) {
        mConnectionMap[sinkTerminal]= sourceTerminal;
    }

    // Check if there is new input terminal
    if (sinkStage && mTerminalsDesc.find(sinkTerminal) == mTerminalsDesc.end()) {
        ExecutorUnit* unit = findPGExecutor(sinkStage);
        if (unit) {
            desc.terminal = sinkTerminal;
            desc.stageId = sinkStage;
            mTerminalsDesc[desc.terminal] = desc;
            unit->inputTerminals.push_back(desc.terminal);
        }
    }
    // Check if there is new output terminal
    if (sourceStage && mTerminalsDesc.find(sourceTerminal) == mTerminalsDesc.end()) {
        ExecutorUnit* unit = findPGExecutor(sourceStage);
        if (unit) {
            desc.terminal = sourceTerminal;
            desc.stageId = sourceStage;
            desc.hasConnection = (sinkTerminal != sourceTerminal);
            mTerminalsDesc[desc.terminal] = desc;
            unit->outputTerminals.push_back(desc.terminal);
        }
    }

    if (mTerminalsDesc.find(curTerminal) != mTerminalsDesc.end()) {
        mTerminalsDesc[curTerminal].enabled = connection.portFormatSettings.enabled;
    }

    return OK;
}

int PipeLiteExecutor::createPGs()
{
    for (auto const& pgName : mPGNames) {
        int pgId = mGraphConfig->getPgIdByPgName(pgName);
        CheckError(pgId == -1, BAD_VALUE, "Cannot get PG ID for %s", pgName.c_str());

        ExecutorUnit pgUnit;
        pgUnit.pgId = pgId;
        pgUnit.stageId = psys_2600_pg_uid(pgId);
        pgUnit.pg = std::shared_ptr<PGCommon>(new PGCommon(pgId, pgName, pgUnit.stageId + 1));
        // Please refer to ia_cipf_css.h for terminalBaseUid
        pgUnit.pg->setShareReferPool(mShareReferPool);
        mPGExecutors.push_back(pgUnit);
        int ret = pgUnit.pg->init();
        CheckError(ret != OK, UNKNOWN_ERROR, "create PG %d error", pgId);
    }
    return OK;
}

int PipeLiteExecutor::configurePGs()
{
    mkernelsCountWithStats = 0;
    for (auto &unit : mPGExecutors) {
        map<ia_uid, FrameInfo> inputInfos;
        map<ia_uid, FrameInfo> outputInfos;
        vector<ia_uid> disabledTerminals;

        getTerminalFrameInfos(unit.inputTerminals, inputInfos);
        getTerminalFrameInfos(unit.outputTerminals, outputInfos);
        getDisabledTerminalsForPG(unit.stageId, disabledTerminals);

        unit.pg->setInputInfo(inputInfos);
        unit.pg->setOutputInfo(outputInfos);
        unit.pg->setDisabledTerminals(disabledTerminals);

        IGraphType::StageAttr stageAttr;
        if (mGraphConfig->getPgRbmValue(unit.pg->getName(), &stageAttr) == OK) {
            LOG1("%s: Set rbm for pgId %d, pgName: %s bytes %d",
                 __func__, unit.pgId, unit.pg->getName(), stageAttr.rbm_bytes);
            unit.pg->setRoutingBitmap(stageAttr.rbm, stageAttr.rbm_bytes);
        }
        unit.pg->prepare(mAdaptor, mStreamId);

        int statsCount = getStatKernels(unit.pgId, unit.statKernelUids);
        mkernelsCountWithStats += statsCount;

        statsCount = getSisKernels(unit.pgId, unit.sisKernelUids);
        mkernelsCountWithStats += statsCount;
    }

    return OK;
}

/**
 * Assign ports for terminals as internal default value
 * Input ports may be overwritten with output ports of producer in setInputTerminals()
 */
int PipeLiteExecutor::assignDefaultPortsForTerminals()
{
    Port portTable[] = {MAIN_PORT, SECOND_PORT, THIRD_PORT, FORTH_PORT, INVALID_PORT};
    for (auto &unit : mPGExecutors) {
        int outPortIndex = 0;
        for (auto terminal : unit.outputTerminals) {
            TerminalDescriptor& termDesc = mTerminalsDesc[terminal];
            if (termDesc.enabled && termDesc.hasConnection) {
                CheckError(portTable[outPortIndex] == INVALID_PORT, BAD_VALUE,
                    "Port unavailable for output term %d:%d", unit.pgId, terminal);
                termDesc.assignedPort = portTable[outPortIndex];
                outPortIndex++;
            }
        }

        int inPortIndex = 0;
        for (auto terminal : unit.inputTerminals) {
            TerminalDescriptor& termDesc = mTerminalsDesc[terminal];
            if (termDesc.enabled && termDesc.hasConnection) {
                CheckError(portTable[inPortIndex] == INVALID_PORT, BAD_VALUE,
                    "Port unavailable for input term %d", terminal);
                termDesc.assignedPort = portTable[inPortIndex];
                inPortIndex++;
            }
        }
    }

    return OK;
}

void PipeLiteExecutor::getOutputTerminalPorts(std::map<ia_uid, Port>& terminals) const
{
    getTerminalPorts(mPGExecutors.back().outputTerminals, terminals);
}

void PipeLiteExecutor::getInputTerminalPorts(std::map<ia_uid, Port>& terminals) const
{
    getTerminalPorts(mPGExecutors.front().inputTerminals, terminals);
}

int PipeLiteExecutor::setInputTerminals(const std::map<ia_uid, Port>& sourceTerminals)
{
    // In edge PGs accepts input ports arrangement from external
    ExecutorUnit& inUnit = mPGExecutors.front();
    for (auto sinkTerminal : inUnit.inputTerminals) {
        if (mConnectionMap.find(sinkTerminal) == mConnectionMap.end()) {
            continue;
        }

        ia_uid sourceTerminal = mConnectionMap[sinkTerminal];
        if (sourceTerminals.find(sourceTerminal) != sourceTerminals.end()) {
            mTerminalsDesc[sinkTerminal].assignedPort = sourceTerminals.at(sourceTerminal);
            LOG2("pg %s get external %d -> input %d, port %d", getName(),
                 sourceTerminal, sinkTerminal, mTerminalsDesc[sinkTerminal].assignedPort);
        }
    }

    // Link internal PGs (sink PG accepts input ports arrangement from source PG (output ports)
    // source PG(output ports) -> (input ports)sink PG
    for (unsigned int i = 1; i < mPGExecutors.size(); i++) {
        for (auto sinkTerminal : mPGExecutors[i].inputTerminals) {
            if (!mTerminalsDesc[sinkTerminal].enabled) {
                continue;
            }
            if (mConnectionMap.find(sinkTerminal) != mConnectionMap.end()) {
                ia_uid sourceTerminal = mConnectionMap[sinkTerminal];
                mTerminalsDesc[sinkTerminal].assignedPort = mTerminalsDesc[sourceTerminal].assignedPort;
            }
        }
    }

    // Set frame info to BufferQueue
    map<Port, stream_t> inputInfo;
    map<Port, stream_t> outputInfo;
    ExecutorUnit& outUnit = mPGExecutors.back();
    for (auto terminal : inUnit.inputTerminals) {
        if (mTerminalsDesc[terminal].assignedPort == INVALID_PORT) {
            continue;
        }

        stream_t inputConfig;
        CLEAR(inputConfig);
        inputConfig.width = mTerminalsDesc[terminal].frameDesc.mWidth;
        inputConfig.height = mTerminalsDesc[terminal].frameDesc.mHeight;
        inputConfig.format = mTerminalsDesc[terminal].frameDesc.mFormat;
        inputConfig.id = mTerminalsDesc[terminal].usrStreamId;
        inputInfo[mTerminalsDesc[terminal].assignedPort] = inputConfig;
    }
    for (auto terminal : outUnit.outputTerminals) {
        if (mTerminalsDesc[terminal].assignedPort == INVALID_PORT) {
            continue;
        }

        stream_t outputConfig;
        CLEAR(outputConfig);
        outputConfig.width = mTerminalsDesc[terminal].frameDesc.mWidth;
        outputConfig.height = mTerminalsDesc[terminal].frameDesc.mHeight;
        outputConfig.format = mTerminalsDesc[terminal].frameDesc.mFormat;
        outputConfig.id = mTerminalsDesc[terminal].usrStreamId;
        outputInfo[mTerminalsDesc[terminal].assignedPort] = outputConfig;
    }
    BufferQueue::setFrameInfo(inputInfo, outputInfo);

    return OK;
}

int PipeLiteExecutor::start()
{
    LOG1("%s executor:%s", __func__, mName.c_str());
    mProcessThread = new ProcessThread(this);
    AutoMutex   l(mBufferQueueLock);

    allocBuffers();
    dumpPGs();

    mLastStatsSequence = -1;

    mThreadRunning = true;
    mProcessThread->run(mName.c_str(), PRIORITY_NORMAL);

    return OK;
}

void PipeLiteExecutor::stop()
{
    LOG1("%s executor:%s", __func__, mName.c_str());

    mProcessThread->requestExitAndWait();

    // Thread is not running. It is safe to clear the Queue
    clearBufferQueues();
    delete mProcessThread;
}

void PipeLiteExecutor::notifyStop()
{
    LOG1("%s executor:%s", __func__, mName.c_str());

    mProcessThread->requestExit();
    {
        AutoMutex l(mBufferQueueLock);
        mThreadRunning = false;
        // Wakeup the thread to exit
        mFrameAvailableSignal.signal();
        mOutputAvailableSignal.signal();
    }
}

int PipeLiteExecutor::releaseStatsBuffer(const shared_ptr<CameraBuffer> &statsBuf)
{
    LOG3A("%s executor:%s", __func__, mName.c_str());
    AutoMutex lock(mStatsBuffersLock);

    mStatsBuffers.push(statsBuf);

    return OK;
}

bool PipeLiteExecutor::hasOutputTerminal(ia_uid sinkTerminal)
{
    if (mConnectionMap.find(sinkTerminal) == mConnectionMap.end()) {
        return false;
    }

    ExecutorUnit& unit = mPGExecutors.back();
    for (auto sourceTerminal : unit.outputTerminals) {
        if (mConnectionMap[sinkTerminal] == sourceTerminal) {
            return true;
        }
    }
    return false;
}

int PipeLiteExecutor::getStatKernels(int pgId, vector<ia_uid>& kernels)
{
    kernels.clear();
    for (unsigned int i = 0; i < ARRAY_SIZE(sStatKernels); i++) {
        int pgIdOfKernel = -1;
        int status = mGraphConfig->getPgIdForKernel(mStreamId, sStatKernels[i], &pgIdOfKernel);
        if (status == OK && pgIdOfKernel == pgId) {
             kernels.push_back(sStatKernels[i]);
        }
    }

    LOG1("pg %d has %d stat kernels", pgId, kernels.size());
    return kernels.size();
}

int PipeLiteExecutor::getSisKernels(int pgId, vector<ia_uid>& kernels)
{
    kernels.clear();
    for (unsigned int i = 0; i < ARRAY_SIZE(sSisKernels); i++) {
        int pgIdOfKernel = -1;
        int status = mGraphConfig->getPgIdForKernel(mStreamId, sSisKernels[i], &pgIdOfKernel);
        if (status == OK && pgIdOfKernel == pgId) {
             kernels.push_back(sSisKernels[i]);
        }
    }

    LOG1("pg %d has %d sis kernels", pgId, kernels.size());
    return kernels.size();
}

bool PipeLiteExecutor::isSameStreamConfig(const stream_t& internal, const stream_t& external,
                                          ConfigMode configMode, bool checkStreamId) const
{
    // The internal format is ia_fourcc based format, so need to convert it to V4L2 format.
    int internalFormat = graphconfig::utils::getV4L2Format(internal.format);
    int internalStride = CameraUtils::getStride(internalFormat, internal.width);
    int externalStride = CameraUtils::getStride(external.format, external.width);

    LOG1("%s: %s, id:%d, internal: %s(%dx%d: %d)(id %d), external: %s(%dx%d: %d) (id %d) usage:%d",
          __func__, mName.c_str(), mStreamId,
          CameraUtils::format2string(internalFormat).c_str(),
          internal.width, internal.height, internalStride, internal.id,
          CameraUtils::format2string(external.format).c_str(),
          external.width, external.height, externalStride, external.id, external.usage);

    if (checkStreamId && internal.id >= 0) {
        return internal.id == external.id;
    }

    /*
     * WA: PG accept GRBG format but actual input data is of RGGB format,
     *     PG use its kernel to crop to GRBG
     */
    if ((internalFormat == V4L2_PIX_FMT_SGRBG10 || internalFormat == V4L2_PIX_FMT_SGRBG12)
         && (external.format == V4L2_PIX_FMT_SRGGB10 || external.format == V4L2_PIX_FMT_SRGGB12)) {
         return true;
    }

    bool sameHeight = internal.height == external.height ||
                      internal.height == ALIGN_32(external.height);
    if (internalFormat == external.format && sameHeight &&
        (internal.width == external.width || internalStride == externalStride)) {
        return true;
    }

    return false;
}

/**
 * Check if there is any valid buffer(not null) in the given port/buffer pairs.
 *
 * return true if there is at least one not null buffer.
 */
bool PipeLiteExecutor::hasValidBuffers(const CameraBufferPortMap& buffers)
{
    for (const auto& item : buffers) {
        if (item.second) return true;
    }

    return false;
}

int PipeLiteExecutor::processNewFrame()
{
    PERF_CAMERA_ATRACE();

    int ret = OK;
    CameraBufferPortMap inBuffers, outBuffers;
    // Wait frame buffers.
    {
        ConditionLock lock(mBufferQueueLock);
        ret = waitFreeBuffersInQueue(lock, inBuffers, outBuffers);
        // Already stopped
        if (!mThreadRunning) return -1;

        if (ret != OK) return OK; // Wait frame buffer error should not involve thread exit.

        CheckError(inBuffers.empty() || outBuffers.empty(),
              UNKNOWN_ERROR, "Failed to get input or output buffers.");

        for (auto& output: mOutputQueue) {
            output.second.pop();
        }

        for (auto& input: mInputQueue) {
            input.second.pop();
        }
    }

    // Check if the executor needs to run the actual pipeline.
    // It only needs to run when there is at least one valid output buffer.
    if (!hasValidBuffers(outBuffers)) {
        // Return buffers if the executor is NOT an input edge.
        if (!mIsInputEdge) {
            for (const auto& item : inBuffers) {
                mBufferProducer->qbuf(item.first, item.second);
            }
        }
        return OK;
    }

    // Fill real buffer to run pipe
    for (auto &item : outBuffers) {
        if (item.second.get() == nullptr) {
            item.second = mInternalOutputBuffers[item.first];
        }
    }

    vector<shared_ptr<CameraBuffer>> outStatsBuffers;
    vector<EventType> eventType;
    // Should find first not none input buffer instead of always use the first one.
    shared_ptr<CameraBuffer> inBuf = inBuffers.begin()->second;
    CheckError(!inBuf, UNKNOWN_ERROR, "@%s: no valid input buffer", __func__);
    long inBufSequence = inBuf->getSequence();
    v4l2_buffer_t inV4l2Buf = *inBuf->getV4L2Buffer().Get();
    TuningMode tuningMode = mPSysDag->getTuningMode(inBufSequence);

    LOG2("%s:Id:%d run pipe start for buffer:%ld", mName.c_str(), mCameraId, inBufSequence);

    if (PlatformData::isEnableFrameSyncCheck(mCameraId)) {
        shared_ptr<CameraBuffer> cInBuffer = inBuffers[MAIN_PORT];
        int vc = cInBuffer->getVirtualChannel();

        while ((!SyncManager::getInstance()->vcSynced(vc)) && mThreadRunning)
            usleep(1);

        if (gLogLevel & CAMERA_DEBUG_LOG_VC_SYNC) {
            int seq = cInBuffer->getSequence();
            SyncManager::getInstance()->printVcSyncCount();
            LOGVCSYNC("[start runPipe], CPU-timestamp:%lu, sequence:%d, vc:%d, kernel-timestamp:%.3lfms, endl",
                      CameraUtils::systemTime(),
                      seq,
                      cInBuffer->getVirtualChannel(),
                      cInBuffer->getTimestamp().tv_sec*1000.0 + cInBuffer->getTimestamp().tv_usec/1000.0);
        }

        SyncManager::getInstance()->updateVcSyncCount(vc);

        // Run pipe with buffers
        ret = runPipe(inBuffers, outBuffers, outStatsBuffers, eventType);
        LOGVCSYNC("[done runPipe], CPU-timestamp:%lu, sequence:%ld, vc:%d, kernel-timestamp:%.3lfms, endl",
                  CameraUtils::systemTime(),
                  cInBuffer->getSequence(),
                  cInBuffer->getVirtualChannel(),
                  cInBuffer->getTimestamp().tv_sec*1000.0 + cInBuffer->getTimestamp().tv_usec/1000.0);
    } else {
        // Run pipe with buffers
        ret = runPipe(inBuffers, outBuffers, outStatsBuffers, eventType);
    }
    CheckError((ret != OK), UNKNOWN_ERROR, "@%s: failed to run pipe", __func__);
    LOG2("%s:Id:%d run pipe end for buffer:%ld", mName.c_str(), mCameraId, inBufSequence);

    // Remove internal output buffers
    for (auto &item : outBuffers) {
        if (item.second.get() == mInternalOutputBuffers[item.first].get()) {
            item.second = nullptr;
        }
    }

    if (mNotifyPolicy == POLICY_FRAME_FIRST) {
        // For general case, notify frame prior to stats to make sure its consumers can get
        // the frame buffers as early as possible.
        notifyFrameDone(inV4l2Buf, outBuffers);
        notifyStatsDone(tuningMode, inV4l2Buf, outStatsBuffers, eventType);
    } else if (mNotifyPolicy == POLICY_STATS_FIRST) {
        // Notify stats first and then handle frame buffers to make sure the next executor
        // can get this executor's IQ result.
        notifyStatsDone(tuningMode, inV4l2Buf, outStatsBuffers, eventType);

        // After the stats notified, we need to update the IPU parameters as well to get the
        // latest AIQ result.
        mPSysDag->prepareIpuParams(inBufSequence, true);

        notifyFrameDone(inV4l2Buf, outBuffers);
    } else {
        LOGW("Invalid notify policy:%d, should never happen.", mNotifyPolicy);
    }

    // Return buffers for the executor which is NOT an input edge
    if (!mIsInputEdge) {
        for (auto const& portBufferPair : inBuffers) {
            // Queue buffer to producer
            mBufferProducer->qbuf(portBufferPair.first, portBufferPair.second);
        }
    }

    return OK;
}

int PipeLiteExecutor::registerInBuffers(Port port, const shared_ptr<CameraBuffer> &inBuf)
{
    return OK;
}

int PipeLiteExecutor::registerOutBuffers(Port port, const shared_ptr<CameraBuffer> &camBuffer)
{
    return OK;
}

int PipeLiteExecutor::runPipe(map<Port, shared_ptr<CameraBuffer> > &inBuffers,
                              map<Port, shared_ptr<CameraBuffer> > &outBuffers,
                              vector<shared_ptr<CameraBuffer> > &outStatsBuffers,
                              vector<EventType> &eventType)
{
    PERF_CAMERA_ATRACE();

    CheckError((inBuffers.empty() || outBuffers.empty()), BAD_VALUE,
        "Error in pipe iteration input/output bufs");

    int ret = OK;
    if (mPolicyManager) {
        // Check if need to wait other executors.
        ret = mPolicyManager->wait(mName);
    }

    // Accept external buffers for in/out edge PGs
    getTerminalBuffersFromExternal(mPGExecutors.front().inputTerminals, inBuffers,
                                   mPGExecutors.front().inputBuffers);
    getTerminalBuffersFromExternal(mPGExecutors.back().outputTerminals, outBuffers,
                                   mPGExecutors.back().outputBuffers);

    // Get ISP parameters
    const ia_binary_data *ipuParameters = nullptr;
    long sequence = inBuffers.begin()->second ? inBuffers.begin()->second->getSequence() : -1;
    TRACE_LOG_PROCESS(mName.c_str(), "runPipe", MAKE_COLOR(sequence), sequence);
    if (mAdaptor) {
        ipuParameters = mAdaptor->getIpuParameter(sequence, mStreamId);
        if (!ipuParameters) {
            LOG1("%s: executor %s doesn't run for sequence %ld due to no pal",
                 __func__, mName.c_str(), sequence);
            return OK;
        }
    }

    LOG2("%s: Executor %s run with input: %zu, output: %zu, sequence: %ld",
         __func__, mName.c_str(), inBuffers.size(), outBuffers.size(), sequence);

    outStatsBuffers.clear();
    eventType.clear();
    int statTotalNum = 0;
    for (unsigned int pgIndex = 0; pgIndex < mPGExecutors.size(); pgIndex++) {
        ExecutorUnit& unit = mPGExecutors[pgIndex];

        // Prepare stats buffers for 3A/sis
        vector<ia_binary_data*> pgStatsDatas;
        // For 3A stats
        unsigned int statsCount = unit.statKernelUids.size();
        for (unsigned int counter = 0; counter < statsCount; counter++) {
            if (mStatsBuffers.empty()) {
                LOGW("No available stats buffer.");
                break;
            }
            outStatsBuffers.push_back(mStatsBuffers.front());
            eventType.push_back(EVENT_PSYS_STATS_BUF_READY);
            ia_binary_data* buffer = (ia_binary_data*)mStatsBuffers.front()->getBufferAddr();
            CheckError(buffer == nullptr, BAD_VALUE, "buffer is null pointer.");
            buffer->size = 0; // Clear it, then the stats memory is from p2p
            buffer->data = 0;
            pgStatsDatas.push_back(buffer);
            mStatsBuffers.pop();
        }
        unsigned int sisCount = unit.sisKernelUids.size();
        for (unsigned int counter = 0; counter < sisCount; counter++) {
            if (mStatsBuffers.empty()) {
                LOGW("No available stats buffer.");
                break;
            }
            outStatsBuffers.push_back(mStatsBuffers.front());
            eventType.push_back(EVENT_PSYS_STATS_SIS_BUF_READY);
            ia_binary_data* buffer = (ia_binary_data*)mStatsBuffers.front()->getBufferAddr();
            pgStatsDatas.push_back(buffer);
            mStatsBuffers.pop();
        }

        // Run PGs
        // Update sequence only for the 1st input buffer currently
        unit.inputBuffers.begin()->second->setSequence(sequence);
        ret = unit.pg->iterate(unit.inputBuffers,
                               unit.outputBuffers,
                               (statsCount > 0) ? pgStatsDatas[0] : nullptr, // Currently PG handles one stats buffer only
                               ipuParameters);
        CheckError((ret != OK), ret, "%s: error in pipe iteration with %d", mName.c_str(), ret);

        statTotalNum += statsCount;
        if (sisCount > 0) {
            handleSisStats(unit.outputBuffers, outStatsBuffers[statTotalNum]); // Currently handle one sis output only
        }
        statTotalNum += sisCount;
    }

    return OK;
}

int PipeLiteExecutor::handleSisStats(map<ia_uid, shared_ptr<CameraBuffer>>& frameBuffers, const shared_ptr<CameraBuffer> &outStatsBuffers)
{
    LOG2("%s:", __func__);
    ia_binary_data* statBuf = (ia_binary_data*)outStatsBuffers->getBufferAddr();
    CheckError((statBuf == nullptr), BAD_VALUE, "Error getting buffer for sis a stats");
    statBuf->data = nullptr;
    statBuf->size = 0;

    for (auto iterm : frameBuffers) {
        ia_uid uid = iterm.first;
        if (uid == psys_ipu6_isa_lb_output_sis_a_uid) {
            statBuf->data = iterm.second->getBufferAddr();
            statBuf->size = iterm.second->getBufferSize();
            outStatsBuffers->setUserBufferInfo(-1, iterm.second->getWidth(), iterm.second->getHeight());
            return OK;
        }
    }

    return UNKNOWN_ERROR;
}

int PipeLiteExecutor::notifyFrameDone(const v4l2_buffer_t& inV4l2Buf, const CameraBufferPortMap& outBuf)
{
    PERF_CAMERA_ATRACE();
    for (auto const& portBufferPair : outBuf) {
        shared_ptr<CameraBuffer> outBuf = portBufferPair.second;
        Port port = portBufferPair.first;
        // If the output buffer is nullptr, that means user doesn't request that buffer,
        // so it doesn't need to be handled here.
        if (!outBuf) continue;

        outBuf->updateV4l2Buffer(inV4l2Buf);

        // If it's output edge, the buffer should be returned to PSysDag,
        // otherwise they should be returned to its consumer.
        if (mIsOutputEdge) {
            mPSysDag->onFrameDone(port, outBuf);
        } else {
            for (auto &it : mBufferConsumerList) {
                it->onFrameAvailable(port, outBuf);
            }
        }
    }

    return OK;
}

int PipeLiteExecutor::notifyStatsDone(TuningMode tuningMode,
                                      const v4l2_buffer_t& inV4l2Buf,
                                      const vector<shared_ptr<CameraBuffer>> &outStatsBuffers,
                                      const vector<EventType> &eventType)
{
    PERF_CAMERA_ATRACE();

    // The executor does not produce stats, so no need to notify.
    if (outStatsBuffers.empty()) return OK;

    /**
     * Notice for EVENT_PSYS_STATS_BUF_READY:
     * dvs stat & 3a stat come from different PG, and they are decoded separately
     * in decodeStatsData().
     * Fortunately stats data are stored in aiqResultStorage separately,
     * and user will get them from storage instead of EventData.
     * So here we can send one event after all stat buffers are decoded/stored/released.
     */
    int psysStatBufferCount = 0;
    for (auto type : eventType) {
        if (type == EVENT_PSYS_STATS_BUF_READY) {
            psysStatBufferCount++;
        }
    }

    int statsIndex = 0;
    for (auto statsBuf : outStatsBuffers) {
        if (!statsBuf) continue;

        if (mStreamId == STILL_STREAM_ID) {
            LOG2("%s: No statistics data for still pipe in buffer", __func__);
            releaseStatsBuffer(statsBuf);
            continue;
        } else if (inV4l2Buf.sequence <= mLastStatsSequence) {
            // Ignore old statistics for Raw reprocessing
            LOG2("%s: new sequence %d is less than last sequence %ld", __func__,
                 inV4l2Buf.sequence, mLastStatsSequence);
            releaseStatsBuffer(statsBuf);
            continue;
        }

        ia_binary_data *hwStatsData = (ia_binary_data *)(statsBuf->getBufferAddr());
        if (hwStatsData->data == nullptr || hwStatsData->size == 0) {
            LOGW("%s: No statistics data in buffer", __func__);
            releaseStatsBuffer(statsBuf);
            continue;
        }

        statsBuf->updateV4l2Buffer(inV4l2Buf);

        // Decode the statistics data
        if (eventType[statsIndex] == EVENT_PSYS_STATS_BUF_READY) {
            mAdaptor->decodeStatsData(tuningMode, statsBuf, mGraphConfig);
            psysStatBufferCount--;
        }

        // Notify listeners after all buffers done for type STATS_BUF_READY
        // Notify immediately for other types
        if (eventType[statsIndex] != EVENT_PSYS_STATS_BUF_READY
            || !psysStatBufferCount) {
            EventDataStatsReady statsReadyData;
            statsReadyData.sequence = statsBuf->getSequence();
            statsReadyData.timestamp.tv_sec = statsBuf->getTimestamp().tv_sec;
            statsReadyData.timestamp.tv_usec = statsBuf->getTimestamp().tv_usec;
            EventData eventData;
            eventData.type = eventType[statsIndex];
            eventData.buffer = statsBuf;
            eventData.data.statsReady = statsReadyData;
            notifyListeners(eventData);
        }

        releaseStatsBuffer(statsBuf);
        statsIndex++;
    }

    if (mStreamId == VIDEO_STREAM_ID && inV4l2Buf.sequence > mLastStatsSequence) {
        mLastStatsSequence = inV4l2Buf.sequence;
    }

    return OK;
}

int PipeLiteExecutor::allocBuffers()
{
    LOG1("%s executor:%s", __func__, mName.c_str());

    releaseBuffers();

    // Allocate buffer between PGs (internal)
    for (auto const& item : mTerminalsDesc) {
        const TerminalDescriptor& termDesc = item.second;
        if (!termDesc.enabled) {
            continue;
        }

        if (termDesc.assignedPort != INVALID_PORT
            && !(findPGExecutor(termDesc.sinkStage) && findPGExecutor(termDesc.sourceStage))) {
            // Don't allocate buffer here for external connection (has valid port)
            continue;
        }

        // Allocated already
        if (mPGBuffers.find(termDesc.terminal) != mPGBuffers.end()) {
            continue;
        }

        int srcFmt = termDesc.frameDesc.mFormat;
        int srcWidth = termDesc.frameDesc.mWidth;
        int srcHeight = termDesc.frameDesc.mHeight;
        int size = PGCommon::getFrameSize(srcFmt, srcWidth, srcHeight, true);
        shared_ptr<CameraBuffer> buf = CameraBuffer::create(mCameraId,
                     BUFFER_USAGE_PSYS_INPUT, V4L2_MEMORY_USERPTR, size, 0, srcFmt, srcWidth, srcHeight);
        CheckError(!buf, NO_MEMORY, "@%s: Allocate producer buffer failed", __func__);
        mPGBuffers[termDesc.sinkTerminal] = buf;
        mPGBuffers[termDesc.sourceTerminal] = buf;
    }

    for (auto &unit : mPGExecutors) {
        // Assign internal buffers for terminals of PGs according to connection
        for (auto &terminal : unit.inputTerminals) {
            if (mPGBuffers.find(terminal) != mPGBuffers.end()) {
                unit.inputBuffers[terminal] = mPGBuffers[terminal];
            }
        }
        for (auto &terminal : unit.outputTerminals) {
            if (mPGBuffers.find(terminal) != mPGBuffers.end()) {
                unit.outputBuffers[terminal] = mPGBuffers[terminal];
            }
        }

        // Allocate stats buffers if needed.
        unsigned int statsBufferCount = unit.statKernelUids.size();
        if (!statsBufferCount) {
            continue;
        }
        for (unsigned int i = 0; i < MAX_BUFFER_COUNT * statsBufferCount; i++) {
            shared_ptr<CameraBuffer> statsBuf = CameraBuffer::create(mCameraId,
                         BUFFER_USAGE_PSYS_STATS, V4L2_MEMORY_USERPTR, sizeof(ia_binary_data), i);
            CheckError(!statsBuf, NO_MEMORY, "Executor %s: Allocate stats buffer failed", mName.c_str());

            AutoMutex lock(mStatsBuffersLock);
            mStatsBuffers.push(statsBuf);
        }
    }

    // Allocate buffers for producer executor (external)
    // Ignore input edge due to no producer
    if (!mIsInputEdge) {
        for (auto const& terminal : mPGExecutors.front().inputTerminals) {
            Port inputPort = mTerminalsDesc[terminal].assignedPort;

            int srcFmt = mTerminalsDesc[terminal].frameDesc.mFormat;
            int srcWidth = mTerminalsDesc[terminal].frameDesc.mWidth;
            int srcHeight = mTerminalsDesc[terminal].frameDesc.mHeight;
            // Get frame size with aligned height taking in count for internal buffers.
            // To garantee PSYS kernel like GDC always get enough buffer size to process.
            int size = PGCommon::getFrameSize(srcFmt, srcWidth, srcHeight, true);
            for (int i = 0; i < MAX_BUFFER_COUNT; i++) {
                // Prepare internal frame buffer for its producer.
                shared_ptr<CameraBuffer> buf = CameraBuffer::create(mCameraId,
                             BUFFER_USAGE_PSYS_INPUT, V4L2_MEMORY_USERPTR, size, i, srcFmt, srcWidth, srcHeight);
                CheckError(!buf, NO_MEMORY, "@%s: Allocate producer buffer failed", __func__);
                mInternalBuffers[inputPort].push_back(buf);

                mBufferProducer->qbuf(inputPort, buf);
            }
        }
    }

    // Allocate internal output buffers to support pipe execution without user output buffer
    for (auto const &item : mOutputFrameInfo) {
        int fmt = item.second.format;
        int width = item.second.width;
        int height = item.second.height;
        int size = CameraUtils::getFrameSize(fmt, width, height, true);
        shared_ptr<CameraBuffer> buf = CameraBuffer::create(mCameraId,
                     BUFFER_USAGE_PSYS_INPUT, V4L2_MEMORY_USERPTR, size, 0, fmt, width, height);
        CheckError(!buf, NO_MEMORY, "@%s: Allocate internal output buffer failed", __func__);
        mInternalOutputBuffers[item.first]= buf;
    }

    return OK;
}

void PipeLiteExecutor::releaseBuffers()
{
    LOG1("%s executor:%s", __func__, mName.c_str());

    // Release internel frame buffers
    mInternalOutputBuffers.clear();
    mInternalBuffers.clear();
    mPGBuffers.clear();

    // Release stats buffers
    {
        AutoMutex lock(mStatsBuffersLock);
        while (!mStatsBuffers.empty()) mStatsBuffers.pop();
    }
}

PipeLiteExecutor::ExecutorUnit* PipeLiteExecutor::findPGExecutor(ia_uid stageId)
{
    for (unsigned int i = 0; i < mPGExecutors.size(); i++) {
        if (mPGExecutors[i].stageId == stageId) {
            return &mPGExecutors[i];
        }
    }
    return nullptr;
}

void PipeLiteExecutor::getTerminalPorts(const vector<ia_uid>& terminals,
                                        map<ia_uid, Port>& terminalPortMap) const
{
    terminalPortMap.clear();
    for (auto terminal : terminals) {
        const TerminalDescriptor& termDesc = mTerminalsDesc.at(terminal);
        if (termDesc.enabled && termDesc.assignedPort != INVALID_PORT) {
            terminalPortMap[terminal] = termDesc.assignedPort;
        }
    }
}

void PipeLiteExecutor::getTerminalFrameInfos(const vector<ia_uid>& terminals,
                                             map<ia_uid, FrameInfo>& infoMap) const
{
    infoMap.clear();
    for (auto terminal : terminals) {
        const TerminalDescriptor& termDesc = mTerminalsDesc.at(terminal);
        if (termDesc.enabled) {
            infoMap[terminal] = termDesc.frameDesc;
        }
    }
}

void PipeLiteExecutor::getDisabledTerminalsForPG(ia_uid stageId, vector<ia_uid>& terminals) const
{
    terminals.clear();
    for (auto const item : mTerminalsDesc) {
        const TerminalDescriptor& termDesc = item.second;
        if (termDesc.stageId == stageId && !termDesc.enabled) {
            terminals.push_back(termDesc.terminal);
        }
    }
}

void PipeLiteExecutor::getTerminalBuffersFromExternal(
        const vector<ia_uid>& terminals,
        const map<Port, shared_ptr<CameraBuffer> >& externals,
        map<ia_uid, shared_ptr<CameraBuffer> >& internals) const
{
    for (auto &terminal : terminals) {
        Port port = mTerminalsDesc.at(terminal).assignedPort;
        if (externals.find(port) != externals.end()) {
            internals[terminal] = externals.at(port);
        }
    }
}

void PipeLiteExecutor::dumpPGs() const
{
    if (!Log::isDebugLevelEnable(CAMERA_DEBUG_LOG_LEVEL2)) return;

    LOG2("============= dump PGs for executor %s =================", getName());
    if (mIsInputEdge) {
        LOG2("This is input edge");
    }
    if (mIsOutputEdge) {
        LOG2("This is output edge");
    }
    for (auto const &unit : mPGExecutors) {
        ia_uid stageId = unit.stageId;
        LOG2("    PG: %d: %s, stageId %d",
             unit.pgId, unit.pg ? unit.pg->getName() : "GPU-TNR", stageId);

        LOG2("        InTerms: %zu", unit.inputTerminals.size());
        for (auto const &term : unit.inputTerminals) {
            shared_ptr<CameraBuffer> buffer= nullptr;
            if (mPGBuffers.find(term) != mPGBuffers.end()) {
                buffer = mPGBuffers.at(term);
            }

            const TerminalDescriptor& termDesc = mTerminalsDesc.at(term);
            if (termDesc.enabled) {
                LOG2("            %d: %dx%d, 0x%x, port %d, buf %p",
                     termDesc.terminal - termDesc.stageId - 1,
                     termDesc.frameDesc.mWidth, termDesc.frameDesc.mHeight,
                     termDesc.frameDesc.mFormat,
                     termDesc.assignedPort, buffer.get());
            } else {
                LOG2("            %d: %dx%d, 0x%x, disabled",
                     termDesc.terminal - termDesc.stageId - 1,
                     termDesc.frameDesc.mWidth, termDesc.frameDesc.mHeight,
                     termDesc.frameDesc.mFormat);
            }
        }

        LOG2("        OutTerms: %zu", unit.outputTerminals.size());
        for (auto const &term : unit.outputTerminals) {
            shared_ptr<CameraBuffer> buffer= nullptr;
            if (mPGBuffers.find(term) != mPGBuffers.end()) {
                buffer = mPGBuffers.at(term);
            }

            const TerminalDescriptor& termDesc = mTerminalsDesc.at(term);
            if (termDesc.enabled) {
                LOG2("            %d: %dx%d, 0x%x, port %d, buf %p",
                     termDesc.terminal - termDesc.stageId - 1,
                     termDesc.frameDesc.mWidth, termDesc.frameDesc.mHeight,
                     termDesc.frameDesc.mFormat,
                     termDesc.assignedPort, buffer.get());
            } else {
                LOG2("            %d: %dx%d, 0x%x, disabled",
                     termDesc.terminal - termDesc.stageId - 1,
                     termDesc.frameDesc.mWidth, termDesc.frameDesc.mHeight,
                     termDesc.frameDesc.mFormat);
            }
        }
    }
    LOG2("============= dump done for %s =================", getName());
}

}

