Camera显示之Hal层的适配二Word文件下载.docx
- 文档编号:17293713
- 上传时间:2022-12-01
- 格式:DOCX
- 页数:6
- 大小:20.40KB
Camera显示之Hal层的适配二Word文件下载.docx
《Camera显示之Hal层的适配二Word文件下载.docx》由会员分享,可在线阅读,更多相关《Camera显示之Hal层的适配二Word文件下载.docx(6页珍藏版)》请在冰豆网上搜索。
就是结构体:
struct:
typedefstructpreview_stream_ops{int(*dequeue_buffer)(structpreview_stream_ops*w,buffer_handle_t**buffer,int*stride);
int(*enqueue_buffer)(structpreview_stream_ops*w,buffer_handle_t*buffer);
int(*cancel_buffer)(structpreview_stream_ops*w,buffer_handle_t*buffer);
int(*set_buffer_count)(structpreview_stream_ops*w,intcount);
int(*set_buffers_geometry)(structpreview_stream_ops*pw,intw,inth,intformat);
int(*set_crop)(structpreview_stream_ops*w,intleft,inttop,intright,intbottom);
int(*set_usage)(structpreview_stream_ops*w,intusage);
int(*set_swap_interval)(structpreview_stream_ops*w,intinterval);
int(*get_min_undequeued_buffer_count)(conststructpreview_stream_ops*w,int*count);
int(*lock_buffer)(structpreview_stream_ops*w,buffer_handle_t*buffer);
//Timestampsaremeasuredinnanoseconds,andmustbecomparable//andmonotonicallyincreasingbetweentwoframesinthesame//previewstream.Theydonotneedtobecomparablebetween//consecutiveorparallelpreviewstreams,cameras,orappruns.int(*set_timestamp)(structpreview_stream_ops*w,int64_ttimestamp);
对显示流的操作都是通过这些函数实现的,而mHalPreviewWindow中实现了具体操的方法,在这些方法的实现中实现对作ANativeWindow的操作。
而在hal端就是通过mHalPreviewWindow.nw进行对ANativeWindow的具体操作。
基本类图关系:
2.继续1中的:
我已经知道了mHalPreviewWindow.nw为传入的一个重要参数mHalPreviewWindow.nw为preview_stream_ops。
继续看看set_preview_window这个方法。
我们有上篇文章知道ops是ICamDevice的一个成员gCameraDevOps,类型为camera_device_ops_t:
可以看到:
staticcamera_device_ops_tconstgCameraDevOps={set_preview_window:
camera_set_preview_window,set_callbacks:
camera_set_callbacks,enable_msg_type:
camera_enable_msg_type,disable_msg_type:
camera_disable_msg_type,msg_type_enabled:
camera_msg_type_enabled,start_preview:
camera_start_preview,stop_preview:
camera_stop_preview,preview_enabled:
camera_preview_enabled,store_meta_data_in_buffers:
camera_store_meta_data_in_buffers,start_recording:
camera_start_recording,stop_recording:
camera_stop_recording,recording_enabled:
camera_recording_enabled,release_recording_frame:
camera_release_recording_frame,auto_focus:
camera_auto_focus,cancel_auto_focus:
camera_cancel_auto_focus,take_picture:
camera_take_picture,cancel_picture:
camera_cancel_picture,set_parameters:
camera_set_parameters,get_parameters:
camera_get_parameters,put_parameters:
camera_put_parameters,send_command:
camera_send_command,release:
camera_release,dump:
camera_dump,};
gCameraDevOps中的函数地址映射到ICamDevice中的函数实现。
所以:
0)就对应到ICamDevice:
:
camera_set_preview_window的发发调用。
staticintcamera_set_preview_window(structcamera_device*device,structpreview_stream_ops*window){interr=-EINVAL;
//ICamDevice*constpDev=ICamDevice:
getIDev(device);
if(pDev){err=pDev->
}//returnerr;
}staticinlineICamDevice*getIDev(camera_device*constdevice){return(NULL==device)?
NULL:
reinterpret_cast(device->
priv);
//得到device->
priv由上篇文章:
知道device->
pri实际上是在创建实例的时候指向的自己:
ICamDevice:
ICamDevice():
camera_device_t(),RefBase(),mDevOps()//,mMtxLock()//{MY_LOGD('
ctor'
);
:
memset(static_cast(this),0,sizeof(camera_device_t));
this->
priv=this;
//用priv指针保存自己。
ops=&
mDevOps;
//ops指向了mDevOpsmDevOps=gCameraDevOps;
//mDevOps为gCameraDevOps指向的结构体}
继续回到pDev->
在ICamDevice中没有对setPreviewWindow具体的实现,而是在其子类CamDevice对ICamDevice进行了具体的实现;
随意代码定位到CamDevice:
status_tCamDevice:
setPreviewWindow(preview_stream_ops*window){MY_LOGI('
+window(%p)'
window);
//status_tstatus=initDisplayClient(window);
//开始初始化DisplayClientif(OK==status&
&
previewEnabled()&
mpDisplayClient!
=0){status=enableDisplayClient();
//时能DisplayClient端}//returnstatus;
}status_tCamDevice:
initDisplayClient(preview_stream_ops*window){#if'
1'
!
=MTKCAM_HAVE_DISPLAY_CLIENT#warning'
NotBuildDisplayClient'
MY_LOGD('
.........................../[3.1]createaDisplayClient.mpDisplayClient=IDisplayClient:
createInstance();
if(mpDisplayClient==0){MY_LOGE('
CannotcreatempDisplayClient'
status=NO_MEMORY;
gotolbExit;
}//[3.2]initializethenewly-createdDisplayClient.if(!
mpDisplayClient->
init()){MY_LOGE('
mpDisplayClientinit()failed'
uninit();
mpDisplayClient.clear();
}//[3.3]setpreview_stream_ops&
relatedwindowinfo.if(!
setWindow(window,previewSize.width,previewSize.height,queryDisplayBufCount()))//绑定window{status=INVALID_OPERATION;
}//[3.4]setImageBufferProviderClientifitexist.if(mpCamAdapter!
=0&
!
setImgBufProviderClient(mpCamAdapter))//重要!
设置流数据的Buffer提供者。
{status=INVALID_OPERATION;
}....................................
enableDisplayClient(){status_tstatus=OK;
SizepreviewSize;
////[1]Getpreviewsize.if(!
queryPreviewSize(previewSize.width,previewSize.height)){MY_LOGE('
queryPreviewSize'
status=DEAD_OBJECT;
}////[2]Enableif(!
enableDisplay(previewSize.width,previewSize.height,queryDisplayBufCount(),mpCamAdapter))//设置了预览数据的尺寸和Buffer提供者相关的数据{MY_LOGE('
mpDisplayClient(%p)->
enableDisplay()'
mpDisplayClient.get());
status=INVALID_OPERATION;
}//status=OK;
lbExit:
returnstatus;
}3.定位到DisplayClient中:
enableDisplay(int32_tconsti4Width,int32_tconsti4Height,int32_tconsti4BufCount,spconst&
rpClient){boolret=false;
preview_stream_ops*pStreamOps=mpStreamOps;
////[1]Re-configuratethisinstanceifanysettingchanges.if(!
checkConfig(i4Width,i4Height,i4BufCount,rpClient)){MY_LOGW('
UninitthecurrentDisplayClient(%p)andre-config...'
this);
////[.1]uninitializeuninit();
////[.2]initializeif(!
init()){MY_LOGE('
re-init()failed'
}////[.3]setrelatedwindowinfo.if(!
setWindow(pStreamOps,i4Width,i4Height,i4BufCount))//window的尺寸和预览数据的大小一致{gotolbExit;
}////[.4]setImageBufferProviderClient.if(!
setImgBufProviderClient(rpClient))//Buffer的数据提供者为mpCamAdapter,就是CamAdapter,后面的预览数据元都是通过它来提供。
{gotolbExit;
}}////[2]Enable.if(!
enableDisplay())//开始进行数据的获取和显示{gotolbExit;
}//ret=true;
returnret;
}
先来看看第一个关键函数:
setWindow(pStreamOps,i4Width,i4Height,i4BufCount)
boolDisplayClient:
setWindow(preview_stream_ops*constwindow,int32_tconstwndWidth,int32_tconstwndHeight,int32_tconsti4MaxImgBufCount){MY_LOGI('
+window(%p),WxH=%dx%d,count(%d)'
window,wndWidth,wndHeight,i4MaxImgBufCount);
//if(!
window){MY_LOGE('
NULLwindowpassedinto'
returnfalse;
}//if(0>
=wndWidth||0>
=wndHeight||0>
=i4MaxImgBufCount){MY_LOGE('
badarguments-WxH=%dx%d,count(%d)'
wndWidth,wndHeight,i4MaxImgBufCount);
}////Mutex:
Autolock_l(mModuleMtx);
returnset_preview_stream_ops(window,wndWidth,wndHeight,i4MaxImgBufCount);
//}oolDisplayClient:
set_preview_stream_ops(preview_stream_ops*constwindow,int32_tconstwndWidth,int32_tconstwndHeight,int32_tconsti4MaxImgBufCount){CamProfileprofile(__FUNCTION__,'
DisplayClient'
//boolret=false;
status_terr=0;
int32_tmin_undequeued_buf_count=0;
////
(2)Checkif(!
mStreamBufList.empty()){MY_LOGE('
lockedbuffercount(%d)!
=0,'
'
callersmustreturnalldequeuedbuffers,'
//'
andthencallcleanupQueue()'
mStreamBufList.size());
dumpDebug(mStreamBufList,__FUNCTION__);
}////(3)Savainfo.mpStreamImgInfo.clear();
//mpStreamImgInfo封装的视屏数据流的基本信息。
mpStreamImgInfo=newImgInfo(wndWidth,wndHeight,CAMERA_DISPLAY_FORMAT,CAMERA_DISPLAY_FORMAT_HAL,'
Camera@Display'
//设置了Stream的宽高和显示类型。
mpStreamOps=window;
//mpStreamOps保存了上层传进来的对象指针。
后面就通过它和显示方进行交互。
mi4MaxImgBufCount=i4MaxImgBufCount;
................................................err=mpStreamOps->
set_buffer_count(mpStreamOps,mi4MaxImgBufCount+min_undequeued_buf_count);
if(err){MY_LOGE('
set_buffer_countfailed:
status[%s(%d)]'
:
strerror(-err),-err);
if(ENODEV==err){MY_LOGD('
Previewsurfaceabandoned!
'
mpStreamOps=NULL;
}gotolbExit;
}////(4.4)Setwindowgeometryerr=mpStreamOps->
set_buffers_geometry(//设置基本的流信息mpStreamOps,mpStreamImgInfo->
mu4ImgWidth,mpStreamImgInfo->
mu4ImgHeight,mpStreamImgInfo->
mi4ImgFormat);
通过上面的代码片段和分析,确定了上层传递下来的对象指针保存在mpStreamOps,与显示相关的交互都将通过mpStreamOps来进行操作。
而mpStreamImgInfo封装了流数据的大小和格式等。
再来看看第二个关键函数:
setImgBufProviderClient(rpClient):
setImgBufProviderClient(spconst&
//MY_LOGD('
+ImgBufProviderClient(%p),mpImgBufQueue.get(%p)'
rpClient.get(),mpImgBufQueue.get());
//if(rpClient==0){MY_LOGE('
NULLImgBufProviderClient'
mpImgBufPvdrClient=NULL;
}//if(mpImgBufQueue!
=0){if(!
rpClient->
onImgBufProviderCreated(mpImgBufQueue))//通知Provider端(Buffer数据提供者端),我这边已经建好Buffer队列,后面你就填充数据到对应的Buffer供我使用。
}mpImgBufPvdrClient=rpClient;
//用mpImgBufPvdrClient保存provider的对象指针,方便使用。
-'
};
再来看看第三个关键函数
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Camera 显示 Hal 适配二