Beispiel #1
0
MBOOL
JpegCodec::
encode(
    IImageBuffer const *pSrcBufInfo, 
    IImageBuffer const *pDstBufInfo, 
    MUINT32 const u4Quality, 
    MUINT32 const u4IsSOI, 
    MUINT32 const eCodecType,
    MUINT32 const u4TimeoutMs//,
    //MUINT32 &u4EncSize
)
{
    FUNCTION_LOG_START;
    //MtkCamUtils::CamProfile profile("encode", "JpegCodec");
    MBOOL ret = MTRUE; 
#ifdef JPEG_HAL_SUPPORT
    JpgEncHal* pJpgEncoder = new JpgEncHal();
    CHECK_OBJECT(pJpgEncoder);

    MUINT32 planenum = 0;
    MUINT32 encfmt = JpgEncHal:: kENC_YUY2_Format;
    MUINT32 plane[3] = {0};
    JpgEncHal::EncLockType lockType = JpgEncHal::JPEG_ENC_LOCK_HW_FIRST;
    switch(eCodecType)
    {
        case JPEGENC_HW_FIRST:
            lockType = JpgEncHal::JPEG_ENC_LOCK_HW_FIRST;
            break;
        case JPEGENC_SW:
            lockType = JpgEncHal::JPEG_ENC_LOCK_SW_ONLY;
            break;
        default:
            break;
    }

    // (1). Lock 
    if(!pJpgEncoder->LevelLock(lockType))
    {
        MY_LOGE("can't lock jpeg resource");        
        goto EXIT; 
    }

    if( !mapToJpgFmt(pSrcBufInfo->getImgFormat(), &encfmt, &planenum) )
    {
        MY_LOGE("map to jpeg fmt failed: 0x%x", pSrcBufInfo->getImgFormat());        
        goto EXIT; 
    }

    // (2). size, format, addr 
    if ( planenum == 1 )
    {
        ret = pJpgEncoder->setEncSize(pSrcBufInfo->getImgSize().w, 
                                      pSrcBufInfo->getImgSize().h, 
                                      static_cast<JpgEncHal::EncFormat>(encfmt)) 
            && pJpgEncoder->setSrcAddr((void *)pSrcBufInfo->getBufVA(0), (void *)NULL) 
            && pJpgEncoder->setSrcBufSize(pJpgEncoder->getSrcBufMinStride(), 
                                          pSrcBufInfo->getBufSizeInBytes(0),
                                          0);

    }
    else if ( planenum == 2 ) 
    {
        ret = pJpgEncoder->setEncSize(pSrcBufInfo->getImgSize().w, 
                                      pSrcBufInfo->getImgSize().h, 
                                      static_cast<JpgEncHal::EncFormat>(encfmt)) 
            && pJpgEncoder->setSrcAddr((void *)pSrcBufInfo->getBufVA(0), 
                                       (void *)pSrcBufInfo->getBufVA(1)) 
            && pJpgEncoder->setSrcBufSize(pJpgEncoder->getSrcBufMinStride(), 
                                          pSrcBufInfo->getBufSizeInBytes(0), 
                                          pSrcBufInfo->getBufSizeInBytes(1));
    } 
    else if ( planenum == 3 ) 
    {
        ret = pJpgEncoder->setEncSize(pSrcBufInfo->getImgSize().w, 
                                      pSrcBufInfo->getImgSize().h, 
                                      static_cast<JpgEncHal::EncFormat>(encfmt)) 
            // workaround for YV12
            && pJpgEncoder->setSrcAddr((void *)pSrcBufInfo->getBufVA(0), 
                                       (void *)pSrcBufInfo->getBufVA(2), 
                                       (void *)pSrcBufInfo->getBufVA(1)) 
            && pJpgEncoder->setSrcBufSize(pJpgEncoder->getSrcBufMinStride(), 
                                          pSrcBufInfo->getBufSizeInBytes(0), 
                                          pSrcBufInfo->getBufSizeInBytes(1),
                                          pSrcBufInfo->getBufSizeInBytes(2));
    } 
    else 
    {
        MY_LOGE("Not support image format:0x%x", (NSCam::EImageFormat)pSrcBufInfo->getImgFormat()); 
        goto EXIT; 
    }

    // (3). set quality
    ret = ret && pJpgEncoder->setQuality(u4Quality) 
    // (4). dst addr, size 
          && pJpgEncoder->setDstAddr((void *)pDstBufInfo->getBufVA(0)) 
          && pJpgEncoder->setDstSize(pDstBufInfo->getBufSizeInBytes(0));

    // (5). ion mode
    {
        MINT32 srcfd_count = pSrcBufInfo->getFDCount();
        MINT32 dstfd_count = pDstBufInfo->getFDCount();
        // set Ion mode
        // jpeg encoder doesn't support 3 plane yet
        if( planenum < 3 && srcfd_count && dstfd_count )
        {
            MINT srcfd0 = -1, srcfd1 = -1;

            //MY_LOGD("ion mode(1)");
            pJpgEncoder->setIonMode(1);

            if ( planenum == 2 ) 
            {
                if( srcfd_count == 1 ) 
                    srcfd0 = srcfd1 = pSrcBufInfo->getFD(0);
                else
                {
                    srcfd0 = pSrcBufInfo->getFD(0);
                    srcfd1 = pSrcBufInfo->getFD(1);
                }
            }
            else
            {
                srcfd0 = pSrcBufInfo->getFD(0);
            }

            MY_LOGD("set src fd %d, %d", srcfd0, srcfd1);
            pJpgEncoder->setSrcFD(srcfd0, srcfd1);
            pJpgEncoder->setDstFD(pDstBufInfo->getFD(0));
        }
        else if ( planenum == 3 || (!srcfd_count && !dstfd_count) )
        {
            //MY_LOGD("ion mode(0)");
            pJpgEncoder->setIonMode(0);
        }
        else
        {
            ret = MFALSE;
            MY_LOGE("not support yet src fd count %d, dst fd count %d", srcfd_count, dstfd_count);
        }
    }
    
    // (6). set SOI 
    pJpgEncoder->enableSOI((u4IsSOI > 0) ? 1 : 0);

    // (7).  Start 

    MUINT32 u4EncSize;
    if (pJpgEncoder->start(&u4EncSize))
    {
        MY_LOGD("Jpeg encode done, size = %d", u4EncSize); 
        ret = (const_cast<IImageBuffer*>(pDstBufInfo))->setBitstreamSize(u4EncSize);
    }
    else 
    {
        MY_LOGE("encode start failed");
        ret = MFALSE;
        pJpgEncoder->unlock(); 
        goto EXIT; 
    }
  
    pJpgEncoder->unlock();
    //profile.print();
    
EXIT:

    if(!ret)
    {
        //dump settings
        MY_LOGE("lock type 0x%x", eCodecType);
        MUINT32 plane = queryPlaneCount(pSrcBufInfo->getImgFormat());
        MY_LOGE("fmt 0x%x, wxh %dx%d, va 0x%x/0x%x, pa 0x%x/0x%x fd %d/%d, size %d/%d",
                pSrcBufInfo->getImgFormat(),
                pSrcBufInfo->getImgSize().w       , pSrcBufInfo->getImgSize().h                       ,
                pSrcBufInfo->getBufVA(0)          , plane>1 ? pSrcBufInfo->getBufVA(1) : 0            ,
                pSrcBufInfo->getBufPA(0)          , plane>1 ? pSrcBufInfo->getBufPA(1) : 0            ,
                pSrcBufInfo->getFD(0)             , plane>1 ? pSrcBufInfo->getFD(1) : 0               ,
                pSrcBufInfo->getBufSizeInBytes(0) , plane>1 ? pSrcBufInfo->getBufSizeInBytes(1) : 0);
        MY_LOGE("quality %u, dstV/P 0x%x/0x%x, size %d, soi %d",
                 u4Quality, 
                 pDstBufInfo->getBufVA(0), pDstBufInfo->getBufPA(0),
                 pDstBufInfo->getBufSizeInBytes(0),
                 u4IsSOI );
    }
    delete pJpgEncoder;

    FUNCTION_LOG_END;
#else
#warning [jpeg hal not ready yet]
#endif
    return ret;
}
//-----------------------------------------------------------------------------
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;
}