MBOOL
StereoNodeImpl::
onReturnBuffer(MUINT32 const data, MUINTPTR const buf, MUINT32 const ext)
{
    MBOOL ret = MTRUE;
    CAM_TRACE_CALL();
    if ( data != STEREO_FEO )
    {
        ICamBufHandler* pBufHdl = getBufferHandler(data);
        if( !pBufHdl )
        {
            MY_LOGE("no buffer hdl for data %d, buf 0x%x", data, buf);
            return MFALSE;
        }
        ret = pBufHdl->enqueBuffer(data, (IImageBuffer*)buf);
        if( !ret )
        {
            MY_LOGE("enque fail: data %d, buf 0x%x", data, buf);
        }
        MY_LOGD("data %d, buf 0x%x", data, buf);
    }
    else
    {
        Mutex::Autolock lock(mLock);
        IMEM_BUF_INFO feo = *(IMEM_BUF_INFO*)buf;
        mlFeBufQueue.push_back(feo);
        MY_LOGD("size(%d) data %d, buf(0x%x) ID(%d) VA(0x%x)",
                mlFeBufQueue.size(), data, buf, feo.memID, feo.virtAddr);
    }
    return MTRUE;
}
MBOOL
Pass2NodeImpl::
getDstBuffer(
    MUINT32         nodeData,
    ImgRequest*     pImgReq)
{
    MBOOL ret = MFALSE;
    ICamBufHandler* pBufHdl = getBufferHandler(nodeData);
    if(pBufHdl && pBufHdl->dequeBuffer(nodeData, pImgReq))
    {
        //MY_LOGD("dstDataType(%d)",dstDataType);
        ret = MTRUE;
    }
    return ret;
}
MBOOL 
Pass2NodeImpl::
onReturnBuffer(MUINT32 const data, MUINT32 const buf, MUINT32 const ext)
{
    MY_LOGV("data %d, buf 0x%x", data, buf);
    ICamBufHandler* pBufHdl = getBufferHandler(data);
    if( !pBufHdl )
    {
        MY_LOGE("no buffer hdl for data %d, buf 0x%x", data, buf);
        return MFALSE;
    }

    MBOOL ret = pBufHdl->enqueBuffer(data, (IImageBuffer*)buf);
    if( !ret )
    {
        MY_LOGE("enque fail: data %d, buf 0x%x", data, buf);
    }
    //FUNC_END;
    return MTRUE; //return status?
}
MBOOL
StereoNodeImpl::
enquePass2(MUINT32 const data, IImageBuffer* const buf, MUINT32 const ext)
{
    CAM_TRACE_CALL();
    // get output bufffers
    MUINT32 dstCount = 0, dstDataType[MAX_DST_PORT_NUM];
    ImgRequest outRequest[MAX_DST_PORT_NUM];
    IMEM_BUF_INFO feoRequest;
    vector<MUINT32> vDataDst = getDataConnected();
    MSize const srcImgSize = buf->getImgSize();
    MSize const dstImgSize = getAlgoImgSize();
    //
    for(MUINT32 i = 0; i < vDataDst.size(); i++)
    {
        if ( STEREO_FEO != vDataDst[i] )
        {
            ICamBufHandler* pBufHdl = getBufferHandler( vDataDst[i] );
            if( pBufHdl && pBufHdl->dequeBuffer( vDataDst[i], &outRequest[dstCount]) )
            {
                dstDataType[dstCount] = vDataDst[i];
                dstCount++;
            }
            else
            {
                MY_LOGE("no dst buf (0x%x)", vDataDst[i]);
            }
        }
        else
        {
            Mutex::Autolock lock(mLock);
            if( mlFeBufQueue.size() == 0 )
            {
                MY_LOGE("no feo buf");
            }
            else
            {
                feoRequest = mlFeBufQueue.front();
                mlFeBufQueue.pop_front();
                //
                dstDataType[dstCount] = vDataDst[i];
                dstCount++;
            }
        }
    }
    if( dstCount == 0 )
    {
        MY_LOGW("no dst buffer, skip data(%d), buf(0x%x)", data, buf);
        handleReturnBuffer(data, (MUINTPTR)buf);
        return MTRUE;
    }

    QParams enqueParams;
    StaData feoData;

    MUINT32 magicNum = 0;
    MVOID*  pPrivateData = NULL;
    MUINT32 privateDataSize = 0;
    MCropRect p2InCrop;
    MSize feSize = getFEImgSize();

    MINT64 timestamp = 0;
    //input
    {
        IImageBuffer const*  pSrcBuf = buf;
        Input src;
        //
        src.mPortID = mapToPortID(data);
        src.mBuffer = const_cast<IImageBuffer*>(pSrcBuf);
        //
        mpIspSyncCtrlHw->getPass2Info(
                            src.mBuffer,
                            srcImgSize,
                            magicNum,
                            pPrivateData,
                            privateDataSize,
                            p2InCrop);
        //
        enqueParams.mpPrivaData = pPrivateData;
        enqueParams.mFrameNo = magicNum;
        //
        timestamp = pSrcBuf->getTimestamp();

        enqueParams.mvIn.push_back(src);

    }
    //
    MCrpRsInfo crop1;
    crop1.mGroupID      = 1;
    crop1.mCropRect     = p2InCrop;
    crop1.mResizeDst    = dstImgSize;
    //
    MCrpRsInfo crop2;
    crop2.mGroupID      = 2;
    crop2.mCropRect.s   = dstImgSize;

    MY_LOGD("data %d, buf 0x%x,va/pa(0x%x/0x%x),size(%dx%d),crop(%d,%d,%d,%d) # 0x%X, cnt %d; crop1(%d,%d,%d,%d)(%dx%d), crop2(%d,%d,%d,%d)(%dx%d)", 
            data, buf, buf->getBufVA(0), buf->getBufPA(0), buf->getImgSize().w, buf->getImgSize().h,
            p2InCrop.p_integral.x, p2InCrop.p_integral.y, p2InCrop.s.w, p2InCrop.s.h, magicNum, muEnqFrameCnt,
            crop1.mCropRect.p_integral.x, crop1.mCropRect.p_integral.y, crop1.mCropRect.s.w, crop1.mCropRect.s.h, crop1.mResizeDst.w, crop1.mResizeDst.h,
            crop2.mCropRect.p_integral.x, crop2.mCropRect.p_integral.y, crop2.mCropRect.s.w, crop2.mCropRect.s.h, crop2.mResizeDst.w, crop2.mResizeDst.h);
    //
    // output
    for( MUINT32 i = 0 ; i < dstCount ; i++ )
    {
        if(dstDataType[i] != STEREO_FEO)
        {
            IImageBuffer const* pDstBuf = outRequest[i].mBuffer;
            MY_LOGD("data %d, buf 0x%x, va/pa(0x%x/0x%x), size(%dx%d), tans %d", 
                    dstDataType[i], pDstBuf, 
                    pDstBuf->getBufVA(0), pDstBuf->getBufPA(0),
                    pDstBuf->getImgSize().w, pDstBuf->getImgSize().h,
                    outRequest[i].mTransform);

            Output dst;
            dst.mPortID     = mapToPortID(dstDataType[i]);
            dst.mBuffer     = const_cast<IImageBuffer*>(pDstBuf);
            dst.mTransform  = outRequest[i].mTransform;           
            dst.mBuffer->setTimestamp(timestamp);
            //
            enqueParams.mvOut.push_back(dst);
        }
        else
        {
            MINT32 idx = muEnqFrameCnt%BUF_COUNT;
            mpStaParam[idx]->bufInfo.size        = feoRequest.size;
            mpStaParam[idx]->bufInfo.memID       = feoRequest.memID;
            mpStaParam[idx]->bufInfo.virtAddr    = feoRequest.virtAddr;
            mpStaParam[idx]->bufInfo.phyAddr     = feoRequest.phyAddr;
            mpStaParam[idx]->bufInfo.bufSecu     = 0;
            mpStaParam[idx]->bufInfo.bufCohe     = 0;
            mpStaParam[idx]->bufInfo.useNoncache = 0;
            mpStaParam[idx]->w                   = feSize.w;
            mpStaParam[idx]->h                   = feSize.h;
            mpStaParam[idx]->stride              = feSize.w;
            mpStaParam[idx]->port_idx            = FEO.index;
            mpStaParam[idx]->port_type           = FEO.type;
            mpStaParam[idx]->port_inout          = FEO.inout;

/*
            feoData.bufInfo.size        = feoRequest.size;
            feoData.bufInfo.memID       = feoRequest.memID;
            feoData.bufInfo.virtAddr    = feoRequest.virtAddr;
            feoData.bufInfo.phyAddr     = feoRequest.phyAddr;
            feoData.bufInfo.bufSecu     = 0;
            feoData.bufInfo.bufCohe     = 0;
            feoData.bufInfo.useNoncache = 0;
            feoData.w                   = FE_W;
            feoData.h                   = FE_H;
            feoData.stride              = FE_W;
            feoData.port_idx            = FEO.index;
            feoData.port_type           = FEO.type;
            feoData.port_inout          = FEO.inout;

            MY_LOGD("(0x%x)FEO:Size(%d),ID(%d),S(%dx%d,%d),VA(%p)PA(%p),Port(%d/%d/%d)",
                    &feoData,
                    feoData.bufInfo.size,
                    feoData.bufInfo.memID,
                    feoData.w,
                    feoData.h,
                    feoData.stride,
                    feoData.bufInfo.virtAddr,
                    feoData.bufInfo.phyAddr,
                    feoData.port_idx,
                    feoData.port_type,
                    feoData.port_inout);*/

            ModuleInfo feoInfo;
            feoInfo.moduleTag    = (MINT32)(EFeatureModule_STA_FEO);
            feoInfo.moduleStruct = reinterpret_cast<MVOID*>(mpStaParam[idx]);
            enqueParams.mvModuleData.push_back(feoInfo);

            mpSrzParam[idx]->in_w    = crop1.mResizeDst.w;
            mpSrzParam[idx]->in_h    = crop1.mResizeDst.h;
            mpSrzParam[idx]->out_w   = getFEImgSize().w;
            mpSrzParam[idx]->out_h   = getFEImgSize().h;

            ModuleInfo srzInfo;
            srzInfo.moduleTag = (MINT32)(EFeatureModule_SRZ1);
            srzInfo.moduleStruct = reinterpret_cast<MVOID*>(mpSrzParam[idx]);
            enqueParams.mvModuleData.push_back(srzInfo); 

            MY_LOGD("[0x%x]FEO:Size(%d),ID(%d),S(%dx%d,%d),VA(%p)PA(%p),Port(%d/%d/%d);[0x%x]SRZ:in(%dx%d),out(%dx%d)",
                    mpStaParam[idx],
                    mpStaParam[idx]->bufInfo.size, mpStaParam[idx]->bufInfo.memID,
                    mpStaParam[idx]->w, mpStaParam[idx]->h, mpStaParam[idx]->stride,
                    mpStaParam[idx]->bufInfo.virtAddr, mpStaParam[idx]->bufInfo.phyAddr,
                    mpStaParam[idx]->port_idx, mpStaParam[idx]->port_type, mpStaParam[idx]->port_inout,
                    mpSrzParam[idx],
                    mpSrzParam[idx]->in_w, mpSrzParam[idx]->in_h, mpSrzParam[idx]->out_w, mpSrzParam[idx]->out_h);

        }
    }
    //
    enqueParams.mvCropRsInfo.push_back( crop1 ); 
    enqueParams.mvCropRsInfo.push_back( crop2 ); 
    //
    enqueParams.mpfnCallback = pass2CbFunc;
    enqueParams.mpCookie = this;
    //
    if( !mpIspSyncCtrlHw->lockHw(IspSyncControlHw::HW_PASS2) )
    {
        MY_LOGE("isp sync lock pass2 failed");
        return MFALSE;
    }
    //
    CAM_TRACE_FMT_BEGIN("enqP2:%d", muEnqFrameCnt);
    if( !mpPostProcPipe->enque(enqueParams) )
    {
        CAM_TRACE_FMT_END();
        MY_LOGE("enque pass2 failed");
        AEE_ASSERT("ISP pass2 enque fail");

        if( !mpIspSyncCtrlHw->unlockHw(IspSyncControlHw::HW_PASS2) )
        {
            MY_LOGE("isp sync unlock pass2 failed");
        }
        return MFALSE;
    }
    CAM_TRACE_FMT_END();

    muEnqFrameCnt++;

    FUNC_END;
    return MTRUE;
}
MBOOL
StereoNodeImpl::
allocBuffers(vector<HwPortConfig_t> & lPortCfg)
{
    FUNC_START;
    MBOOL ret = MFALSE;
    //
    vector< HwPortConfig_t >::const_iterator pConfig = lPortCfg.begin();
    IMemDrv* pIMemDrv =  IMemDrv::createInstance();
    if ( !pIMemDrv || !pIMemDrv->init() ) {
        MY_LOGE("pIMemDrv->init() error");
        goto lbExit;
    }
    for(MUINT32 i = 0; i < BUF_COUNT; ++i)
    {
        IMEM_BUF_INFO bufInfo;
        bufInfo.size = getHWFESize().size();
        if(pIMemDrv->allocVirtBuf(&bufInfo) < 0)
        {
            MY_LOGE("pIMemDrv->allocVirtBuf() error, i(%d)",i);
            goto lbExit;
        }
        if(pIMemDrv->mapPhyAddr(&bufInfo) < 0)
        {
            MY_LOGE("pIMemDrv->mapPhyAddr() error, i(%d)",i);
            goto lbExit;
        }
        mlFeBufQueue.push_back(bufInfo);
    }
    //
    while( pConfig != lPortCfg.end() )
    {
        MUINT32 nodedatatype = mapToNodeDataType(pConfig->mPortID);
        ICamBufHandler* pBufHdl = getBufferHandler(nodedatatype);
        MY_LOGD("handle(%p) data(%d) S(%dx%d)F(0x%x)", pBufHdl, nodedatatype, pConfig->mSize.w, pConfig->mSize.h, pConfig->mFmt);
        if( !pBufHdl )
        {
            MY_LOGE("no buffer hdl for data(%d)", nodedatatype);
            goto lbExit;
        }
        //alloc buffer
        AllocInfo allocinfo(pConfig->mSize.w, pConfig->mSize.h, pConfig->mFmt,
                eBUFFER_USAGE_SW_MASK | eBUFFER_USAGE_HW_MASK);

        if( nodedatatype == STEREO_IMG )
        {
            if ( !mDebugDumpGB )
                allocinfo.usage     = eBUFFER_USAGE_HW_RENDER|eBUFFER_USAGE_HW_TEXTURE|eBUFFER_USAGE_SW_WRITE_RARELY;
            else
                allocinfo.usage     = eBUFFER_USAGE_HW_RENDER|eBUFFER_USAGE_HW_TEXTURE|eBUFFER_USAGE_SW_WRITE_RARELY|eBUFFER_USAGE_SW_READ_RARELY;
            allocinfo.isGralloc = MTRUE;
        }

        for(MUINT32 i = 0; i < BUF_COUNT ; i++ )
        {
            if( !pBufHdl->requestBuffer(nodedatatype, allocinfo) )
            {
                MY_LOGE("request buffer failed: data %d", nodedatatype);
                goto lbExit;
            }
        }
        //
        pConfig++;
    }
    //
    ret = MTRUE;
lbExit:
    if ( !pIMemDrv ) {
        pIMemDrv->uninit();
        pIMemDrv->destroyInstance();
    }
    if( !ret ) {
        MY_LOGE("allocBuffers failed");
    }
    FUNC_END;
    return ret;
}