CAMERA数据的分析(二)------- 数据的向上传输

这篇博客深入分析了Android摄像头数据从bufProvider如何通过DisplayClient进行处理,并最终传递到ANativeWindow显示的过程。详细探讨了DisplayClient的初始化、线程创建、数据缓冲区管理以及窗口设置等关键步骤,揭示了数据从获取到显示的完整路径。
摘要由CSDN通过智能技术生成

CAMERA数据的分析(二)-------

数据的向上传输

 

接着上一篇的分析,数据获取后,获取到的数据放在下面bufProvider里面:

Step 4.2.6:

\vendor\mediatek\proprietary\hardware\mtkcam\legacy\platform\mt8127\v1\hal\adapter\MtkDefault\Preview\PreviewBufMgr.cpp

 

 case eBuf_Disp:

       {

           sp<IImgBufProvider>bufProvider =mspImgBufProvidersMgr->getDisplayPvdr();

           if(bufProvider != 0)

           {

               bufProvider->enqueProvider(node);

           }

       }

 

现在需要搞清楚的是这个bufProvider到底是谁。我们看看getDisplayPvdr这个的定义:

 

//  get [Display] ImageBuffer Provider

sp<IImgBufProvider>             getDisplayPvdr() const  { return getProvider(IImgBufProvider::eID_DISPLAY);}

 

这个bufProvider是从mspImgBufProvidersMgr中获取到了eID_DISPLAYbufProvider。而这个bufProvider是在前面的分析中我们创建的。是否还记得!

\vendor\mediatek\proprietary\hardware\mtkcam\legacy\v1\client\DisplayClient\DisplayClient.cpp

bool

DisplayClient::

init()

{

   bool ret = false;

   //

   MY_LOGD("+");

   //

   ret =   createDisplayThread()

       &&  createImgBufQueue()

           ;

   //

   MY_LOGD("- ret(%d)", ret);

   return  ret;

}

 

bool

DisplayClient::

createImgBufQueue()

{

   bool ret = false;

   //

   MY_LOGD("+");

   //

    {

       Mutex::Autolock _l(mModuleMtx);

       mpImgBufQueue = newImgBufQueue(IImgBufProvider::eID_DISPLAY, "CameraDisplay@ImgBufQue");

       if  ( mpImgBufQueue == 0 )

       {

           MY_LOGE("Fail to new ImgBufQueue");

           goto lbExit;

       }

    }

   //

   mpExtImgProc = ExtImgProc::createInstance();

   if(mpExtImgProc != NULL)

    {

       mpExtImgProc->init();

    }

   //

   ret = true;

lbExit:

   MY_LOGD("-");

   return  ret;

}

 

对了,就是在DisplayClient的初始化的时候创建的这个eID_DISPLAYIImgBufProvider,后面把这个IImgBufProvider在调用DisplayClient::

enableDisplay的时候:setImgBufProviderClient(rpClient),而这个rpClient传进来的参数就是mpCamAdapter,如下:

mpDisplayClient->enableDisplay(previewSize.width,previewSize.height, queryDisplayBufCount(), mpCamAdapter),还是一步不的跟进下吧,这样跟清晰些,就从setPreviewWindow说起吧,setPreviewWindow前面的调用请参照之前文章的说明。

step 1:

\vendor\mediatek\proprietary\hardware\mtkcam\legacy\v1\device\Cam1DeviceBase.cpp

status_t

Cam1DeviceBase::

setPreviewWindow(preview_stream_ops* window)

{

   CAM_TRACE_CALL();

   MY_LOGI("+ window(%p)", window);

   //

   status_t status = initDisplayClient(window);

   if  ( OK == status &&previewEnabled() && mpDisplayClient != 0 )

    {

       status = enableDisplayClient();

       if(mbWindowReady)

       {

           waitStartPreviewDone();

       }

    }

   //

   return  status;

}

 

Step 2:

\vendor\mediatek\proprietary\hardware\mtkcam\legacy\v1\device\Cam1DeviceBase.cpp

 

status_t

Cam1DeviceBase::

enableDisplayClient()

{

   status_t status = OK;

   Size previewSize;

   //

   MY_LOGD("+");

   //

   //  [1] Get preview size.

   if  ( !queryPreviewSize(previewSize.width, previewSize.height) )

    {

       MY_LOGE("queryPreviewSize");

       status = DEAD_OBJECT;

       goto lbExit;

    }

   //

   if(mpParamsMgr->getIfFirstPreviewFrameAsBlack())

    {

       mpDisplayClient->setFirstFrameBlack();

       mpParamsMgr->set(MtkCameraParameters::KEY_FIRST_PREVIEW_FRAME_BLACK,0);

    }

   //  [2] Enable

   if  ( ! mpDisplayClient->enableDisplay(previewSize.width,previewSize.height, queryDisplayBufCount(), mpCamAdapter) )

    {

       MY_LOGE("mpDisplayClient(%p)->enableDisplay()",mpDisplayClient.get());

       status = INVALID_OPERATION;

       goto lbExit;

    }

   //

   status = OK;

lbExit:

   MY_LOGD("- status(%d)",status);

   return  status;

}

 

Step 3:

\vendor\mediatek\proprietary\hardware\mtkcam\legacy\v1\client\DisplayClient\DisplayClient.c

bool

DisplayClient::

enableDisplay(

   int32_t const   i4Width,

   int32_t const   i4Height,

   int32_t const   i4BufCount,

   sp<IImgBufProviderClient>const& rpClient

)

{

   bool ret = false;

   preview_stream_ops* pStreamOps = mpStreamOps;

   //

   //  [1] Re-configurate thisinstance if any setting changes.

   if  ( ! checkConfig(i4Width,i4Height, i4BufCount, rpClient) )

    {

       MY_LOGW("<Config Change> Uninit the current DisplayClient(%p)and re-config...", this);

       //

       //  [.1] uninitialize

        uninit();

       //

       //  [.2] initialize

       if  ( ! init() )

       {

           MY_LOGE("re-init() failed");

           goto lbExit;

       }

       //

       //  [.3] set related window info.

       if  ( ! setWindow(pStreamOps,i4Width, i4Height, i4BufCount) )

       {

           goto lbExit;

       }

       //

       //  [.4] set Image Buffer ProviderClient.

       if  ( ! setImgBufProviderClient(rpClient))

       {

           goto lbExit;

       }

    }

   //

   //  [2] Enable.

   if  ( ! enableDisplay() )

    {

       goto lbExit;

    }

   //

   ret = true;

lbExit:

   return  ret;

}

 

Step 4:

\vendor\mediatek\proprietary\hardware\mtkcam\legacy\v1\client\DisplayClient\DisplayClient.c

 

bool

DisplayClient::

setImgBufProviderClient(sp<IImgBufProviderClient>const&rpClient)

{

   bool ret = false;

   //

   MY_LOGD("+ ImgBufProviderClient(%p), mpImgBufQueue.get(%p)",rpClient.get(), mpImgBufQueue.get());

   //

   if  ( rpClient == 0 )

    {

       MY_LOGE("NULL ImgBufProviderClient");

       mpImgBufPvdrClient = NULL;

       goto lbExit;

    }

   //

   if  ( mpImgBufQueue != 0 )

{

/*

这个mpImgBufQueue就是最开始我们说的,eID_DISPLAYbufProvider,是在DisplayClientinit里面创建起来的。

rpClient传递进来的参数是mpCamAdapter,所以就是看mpCamAdapter中的onImgBufProviderCreated方法了。

*/

       if  ( ! rpClient->onImgBufProviderCreated(mpImgBufQueue))

       {

           goto lbExit;

       }

       mpImgBufPvdrClient = rpClient;

    }

   //

   ret = true;

lbExit:

   MY_LOGD("-");

   return  ret;

};

 

Step 5:

\vendor\mediatek\proprietary\hardware\mtkcam\legacy\platform\mt8127\v1\hal\adapter\BaseCamAdapter.cpp

 

bool

BaseCamAdapter::

onImgBufProviderCreated(sp<IImgBufProvider>const& rpProvider)

{

   if  ( rpProvider == 0 )

    {

       MY_LOGW("NULL provider");

       return  false;

    }

//

/*

这里的rpProvider就是mpImgBufQueue,所以rpProvider->getProviderId()获取到的就是eID_DISPLAY了。

*/

    int32_t consti4ProviderId = rpProvider->getProviderId();

   if  ( (size_t)i4ProviderId >=mpImgBufProvidersMgr->getProvidersSize() )

    {

       MY_LOGE("bad ProviderId=%x >= %d", i4ProviderId,mpImgBufProvidersMgr->getProvidersSize());

       return  false;

    }

//

/*

rpProvider就是mpImgBufQueue放入到mpImgBufProvidersMgr里面去。

*/

    mpImgBufProvidersMgr->setProvider(i4ProviderId,rpProvider);

   //

   //

   MY_LOGI("- id=%d, ImgBufProvider=%p", i4ProviderId,rpProvider.get());

   return  true;

}

 

这样就重要与第一篇中的获取到的数据放入到bufProvider =mspImgBufProvidersMgr->getDisplayPvdr();中对于上了。getDisplayPvdr()获取的就是eID_DISPLAY。所以第一篇中获取到的数据,实际上就是获取到了DisplayClient中的mpImgBufQueue里面去了。下面继续看看这个

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值