//-----------------------------------------------------------------------------
MBOOL
VideoSnapshotScenario::
encodeJpg(
    JpgTypeEnum     jpgType,
    MemTypeEnum     srcMemType,
    MemTypeEnum     dstMemType,
    MUINT32         quality,
    MBOOL           enableSOI)
{
    FUNCTION_IN;
    //
    MBOOL result = MTRUE;
    MUINT32 timeout = 0;
    //
    MY_LOGD("jpgType(%d),srcMemType(%d),dstMemType(%d),quality(%d)",jpgType,srcMemType,dstMemType,quality);
    MY_LOGD("VA:Src(0x%08X~0x%08X),Dst(0x%08X~0x%08X)",
            mIMemBufInfo[srcMemType].virtAddr,
            mIMemBufInfo[srcMemType].virtAddr+mIMemBufInfo[srcMemType].size,
            mIMemBufInfo[dstMemType].virtAddr,
            mIMemBufInfo[dstMemType].virtAddr+mIMemBufInfo[dstMemType].size);
    MY_LOGD("PA:Src(0x%08X~0x%08X),Dst(0x%08X~0x%08X)",
            mIMemBufInfo[srcMemType].phyAddr,
            mIMemBufInfo[srcMemType].phyAddr+mIMemBufInfo[srcMemType].size,
            mIMemBufInfo[dstMemType].phyAddr,
            mIMemBufInfo[dstMemType].phyAddr+mIMemBufInfo[dstMemType].size);
    //
    JpgEncHal* pJpgEncoder = new JpgEncHal();
    // (1). Lock
    while(1)
    {
        if(pJpgEncoder->lock())
        {
            MY_LOGD("Lock OK");
            break;
        }
        //
        timeout++;
        if(timeout > JPG_LOCK_TIMEOUT_CNT)
        {
            MY_LOGE("Lock fail");
            goto EXIT;
        }
        usleep(JPG_LOCK_TIMEOUT_SLEEP);
    }
    // (2). size, format, addr
    pJpgEncoder->setEncSize(
                    mJpgInfo[jpgType].width,
                    mJpgInfo[jpgType].height,
                    JpgEncHal::kENC_YUY2_Format);
    pJpgEncoder->setSrcAddr(
                    (void*)(mIMemBufInfo[srcMemType].virtAddr),
                    (void*)NULL);
    pJpgEncoder->setSrcBufSize(
                    pJpgEncoder->getSrcBufMinStride(),
                    mIMemBufInfo[srcMemType].size,
                    0);
    // (3). set quality
    pJpgEncoder->setQuality(quality);
    // (4). dst addr, size
    pJpgEncoder->setDstAddr((void*)(mIMemBufInfo[dstMemType].virtAddr));
    pJpgEncoder->setDstSize(mIMemBufInfo[dstMemType].size);
    // (6). set SOI
    pJpgEncoder->enableSOI(enableSOI);
    // (7). ION mode
    if(mIMemBufInfo[dstMemType].memID >= 0)
    {
        pJpgEncoder->setIonMode(MTRUE);
    }
    else
    {
        pJpgEncoder->setIonMode(MFALSE);
    }
    pJpgEncoder->setSrcFD(
                    mIMemBufInfo[srcMemType].memID,
                    mIMemBufInfo[srcMemType].memID);
    pJpgEncoder->setDstFD(mIMemBufInfo[dstMemType].memID);
    // (8).  Start
    if(pJpgEncoder->start(&mJpgInfo[jpgType].bitStrSize))
    {
        MY_LOGD("Encode OK,size(%d)", mJpgInfo[jpgType].bitStrSize);
    }
    else
    {
        mJpgInfo[jpgType].bitStrSize = 0;
        MY_LOGE("Encode Fail");
    }
    //
    pJpgEncoder->unlock();
    //
    EXIT:
    delete pJpgEncoder;
    FUNCTION_OUT;
    return result;
}
MBOOL
PREFEATUREABSE::
createJpegImg(NSCamHW::ImgBufInfo const & rSrcBufInfo
      , MUINT32 quality
      , bool fIsAddSOI
      , NSCamHW::ImgBufInfo const & rDstBufInfo
      , MUINT32 & u4EncSize)
{
    MBOOL ret = MTRUE;
    // (0). debug
    MY_LOGD("[createJpegImg] - rSrcImgBufInfo.u4BufVA=0x%x", rSrcBufInfo.u4BufVA);
    MY_LOGD("[createJpegImg] - rSrcImgBufInfo.eImgFmt=%d", rSrcBufInfo.eImgFmt);
    MY_LOGD("[createJpegImg] - rSrcImgBufInfo.u4ImgWidth=%d", rSrcBufInfo.u4ImgWidth);
    MY_LOGD("[createJpegImg] - rSrcImgBufInfo.u4ImgHeight=%d", rSrcBufInfo.u4ImgHeight);
    MY_LOGD("[createJpegImg] - jpgQuality=%d", quality);
    //
    // (1). Create Instance
    JpgEncHal* pJpgEncoder = new JpgEncHal();
    // (1). Lock 
    if(!pJpgEncoder->lock())
    {
        MY_LOGE("can't lock jpeg resource");        
        goto EXIT; 
    }
    // (2). size, format, addr 
    if (eImgFmt_YUY2 == rSrcBufInfo.eImgFmt)
    {
        MY_LOGD("jpeg source YUY2");
        pJpgEncoder->setEncSize(rSrcBufInfo.u4ImgWidth, rSrcBufInfo.u4ImgHeight, 
                                JpgEncHal:: kENC_YUY2_Format); 
        pJpgEncoder->setSrcAddr((void *)rSrcBufInfo.u4BufVA, (void *)NULL);
        pJpgEncoder->setSrcBufSize(pJpgEncoder->getSrcBufMinStride() ,rSrcBufInfo.u4BufSize, 0);
    }
    else if (eImgFmt_NV21 == rSrcBufInfo.eImgFmt) 
    {
        MY_LOGD("jpeg source NV21"); 
        pJpgEncoder->setEncSize(rSrcBufInfo.u4ImgWidth, rSrcBufInfo.u4ImgHeight, 
                                JpgEncHal:: kENC_NV21_Format);   
        pJpgEncoder->setSrcAddr((void *)rSrcBufInfo.u4BufVA, (void *)(rSrcBufInfo.u4BufVA + rSrcBufInfo.u4ImgWidth * rSrcBufInfo.u4ImgHeight));
        pJpgEncoder->setSrcBufSize(pJpgEncoder->getSrcBufMinStride(), rSrcBufInfo.u4ImgWidth * rSrcBufInfo.u4ImgHeight, 
                                                 rSrcBufInfo.u4ImgWidth * rSrcBufInfo.u4ImgHeight / 2);
    } 
    else 
    {
        MY_LOGE("Not support image format:0x%x", rSrcBufInfo.eImgFmt); 
        goto EXIT; 
    }
    // (3). set quality
    pJpgEncoder->setQuality(quality);     
    // (4). dst addr, size 
    pJpgEncoder->setDstAddr((void *)rDstBufInfo.u4BufVA);
    pJpgEncoder->setDstSize(rDstBufInfo.u4BufSize);
    // (6). set SOI 
    pJpgEncoder->enableSOI((fIsAddSOI > 0) ? 1 : 0);     
    // (7). ION mode 
    if ( rSrcBufInfo.i4MemID > 0 )
    {
        pJpgEncoder->setIonMode(1); 
        pJpgEncoder->setSrcFD(rSrcBufInfo.i4MemID, rSrcBufInfo.i4MemID); 
        pJpgEncoder->setDstFD(rDstBufInfo.i4MemID); 
    }

    // (8).  Start 
    if (pJpgEncoder->start(&u4EncSize))
    {
        MY_LOGD("Jpeg encode done, size = %d", u4EncSize); 
        ret = MTRUE; 
    }
    else 
    {
        pJpgEncoder->unlock(); 
        goto EXIT; 
    }
  
    pJpgEncoder->unlock();
    
EXIT:
    delete pJpgEncoder;
    
    MY_LOGD("[init] - X. ret: %d.", ret);
    return ret;
}
MBOOL
JpegCodec::
encode(ImgBufInfo const rSrcBufInfo, ImgBufInfo const rDstBufInfo, MUINT32 const u4Quality, MUINT32 const u4IsSOI, MUINT32 &u4EncSize)
{
    FUNCTION_LOG_START;
    MtkCamUtils::CamProfile profile("encode", "JpegCodec");
    MBOOL ret = MFALSE; 
    JpgEncHal* pJpgEncoder = new JpgEncHal();
    // (1). Lock 
    if(!pJpgEncoder->lock())
    {
        MY_LOGE("can't lock jpeg resource");        
        goto EXIT; 
    }
    // (2). size, format, addr 
    if (eImgFmt_YUY2 == rSrcBufInfo.eImgFmt)
    {
        pJpgEncoder->setEncSize(rSrcBufInfo.u4ImgWidth, rSrcBufInfo.u4ImgHeight, 
                                JpgEncHal:: kENC_YUY2_Format); 
        pJpgEncoder->setSrcAddr((void *)rSrcBufInfo.u4BufVA, (void *)NULL);
        pJpgEncoder->setSrcBufSize(pJpgEncoder->getSrcBufMinStride() ,rSrcBufInfo.u4BufSize, 0);
    }
    else if (eImgFmt_NV21 == rSrcBufInfo.eImgFmt) 
    {
        pJpgEncoder->setEncSize(rSrcBufInfo.u4ImgWidth, rSrcBufInfo.u4ImgHeight, 
                                JpgEncHal:: kENC_NV12_Format);   
        pJpgEncoder->setSrcAddr((void *)rSrcBufInfo.u4BufVA, (void *)(rSrcBufInfo.u4BufVA + rSrcBufInfo.u4ImgWidth * rSrcBufInfo.u4ImgHeight));
        pJpgEncoder->setSrcBufSize(pJpgEncoder->getSrcBufMinStride(), rSrcBufInfo.u4ImgWidth * rSrcBufInfo.u4ImgHeight, 
                                                 rSrcBufInfo.u4ImgWidth * rSrcBufInfo.u4ImgHeight / 2);
    } 
    else 
    {
        MY_LOGE("Not support image format:0x%x", rSrcBufInfo.eImgFmt); 
        goto EXIT; 
    }
    // (3). set quality
    pJpgEncoder->setQuality(u4Quality);     
    // (4). dst addr, size 
    pJpgEncoder->setDstAddr((void *)rDstBufInfo.u4BufVA);
    pJpgEncoder->setDstSize(rDstBufInfo.u4BufSize);
    // (6). set SOI 
    pJpgEncoder->enableSOI((u4IsSOI > 0) ? 1 : 0);     
    // (7). ION mode 
    //if (eMemoryType_ION == rSrcBufInfo.eMemType)
    if ( rSrcBufInfo.i4MemID > 0 )
    {
        pJpgEncoder->setIonMode(1); 
        pJpgEncoder->setSrcFD(rSrcBufInfo.i4MemID, rSrcBufInfo.i4MemID); 
        pJpgEncoder->setDstFD(rDstBufInfo.i4MemID); 
    }

    // (8).  Start 
    if (pJpgEncoder->start(&u4EncSize))
    {
        MY_LOGD("Jpeg encode done, size = %d", u4EncSize); 
        ret = MTRUE; 
    }
    else 
    {
        pJpgEncoder->unlock(); 
        goto EXIT; 
    }
  
    pJpgEncoder->unlock();
    profile.print();
    
EXIT:
    delete pJpgEncoder;
    FUNCTION_LOG_END;
    return ret;
}