MTK 平台,部分三方应用相机预览界面做缩放时走的是MtkDefaultCamAdapter.Zoom.cpp 的startSmoothZoom函数,下面就这部分机制做详细分析。
这个功能中有个重要的标志位mStopped,标示缩放流程的开始和结速。
先贴出几个重要函数:
status_t
CamAdapter::startSmoothZoom(int32_t arg1)
{
MY_LOGD("+ (%d)", arg1);
if(!gZoomCallback.mStopped){//进来判断mstopped是否为false,是则直接返回表示上次缩放还没有结束
MY_LOGE("startSmoothZoom should have stopped.");
return OK;
// return INVALID_OPERATION; //
}
// (0) initial setting
gZoomCallback.setUser(mpCamMsgCbInfo, mpParamsMgr);//缩放初始化准备,这里会设置mstopped为ture
int32_t curIdx = mpParamsMgr->getInt(CameraParameters::KEY_ZOOM);
if( arg1 < 0 || arg1 > mpParamsMgr->getInt(CameraParameters::KEY_MAX_ZOOM) )
{
MY_LOGE("return fail: smooth zoom(%d)", arg1);
return BAD_VALUE;
}
if( arg1 == curIdx )
{
MY_LOGE("smooth zoom(%d) equals to current", arg1);
return OK;
}
gZoomCallback.setZoomTarget(curIdx, arg1);
// (1) once callback has been set to PreviewCmdQueThread,
// it contains this pointer forever,
mpPreviewCmdQueThread->setZoomCallback(&gZoomCallback);
while( mpPreviewCmdQueThread->popZoom() != -1 );
// (3)
if (curIdx < arg1)
{
for (int32_t i = curIdx+1; i <= arg1; i++)
{
mpPreviewCmdQueThread->pushZoom((uint32_t)i);
}
}
else if (curIdx > arg1)
{
for (int32_t i = curIdx-1; i >= arg1; i--)
{
mpPreviewCmdQueThread->pushZoom((uint32_t)i);
}
}
gZoomCallback.mStopped = false;//缩放结速设置mstopped为false ,回调函数判断达到预定缩放值时会重新设置为true通知上层缩放完成
MY_LOGD("- curIdx(%d)", curIdx);
return OK;
}
回调函数
void
ZoomCallBack::
doNotifyCb(
int32_t _msgType,
int32_t _ext1,
int32_t _ext2,
int32_t _ext3
)
{
if( mspCamMsgCbInfo == 0 || mspParamsMgr == 0)
{
CAM_LOGW("mspCamMsgCbInfo == 0 || mspParamsMgr == 0");
return;
}
if (mPrevIdx == _ext1)
{
CAM_LOGW("same as previous idx, drop!");
return;
}
if(mStopped){
CAM_LOGW("should stop");
return;
}
if ( _ext1 == mIniIdx ){
CAM_LOGW("do not callback current zoom index(%d)", mIniIdx);
return;
}
mStopped = (mRequestStop)||(_ext1 == mTargetIdx);//达到缩放值,mstopped设置为true,通知上层缩放完成
if ( _msgType == IPreviewCmdQueCallBack::eID_NOTIFY_Zoom )
{
CAM_LOGD("smoothZoom cb(#%d): (%d, %d)", mCBcnt++, _ext1, mStopped);
{
Mutex::Autolock lock(mLock);
mspParamsMgr->set(CameraParameters::KEY_ZOOM, _ext1);
mspCamMsgCbInfo->mNotifyCb(CAMERA_MSG_ZOOM, _ext1, mStopped, mspCamMsgCbInfo->mCbCookie);
}
mPrevIdx = _ext1;
}
//
if ( mStopped ) {// destroy criteria (1)&(2)
reset();
}
}
接下来看看Log:
46159 03-31 21:19:38.249773 344 344 D MtkCam/CamAdapter: (344)(Default)[startSmoothZoom] + (5)
46160 03-31 21:19:38.250127 344 344 E MtkCam/CamAdapter: (344)(Default)[startSmoothZoom] smooth zoom(5) equals to current (startSmoothZoom)
46279 03-31 21:19:38.308410 344 2480 D MtkCam/CamAdapter: (2480)(Default)[startSmoothZoom] + (9)
46286 03-31 21:19:38.310395 344 2480 D MtkCam/CamAdapter: (2480)(Default)[startSmoothZoom] - curIdx(5)
46363 03-31 21:19:38.351881 344 1371 D MtkCam/CamAdapter: (1371)(Default)[startSmoothZoom] + (9)
46364 03-31 21:19:38.352159 344 1371 E MtkCam/CamAdapter: (1371)(Default)[startSmoothZoom] startSmoothZoom should have stopped. (startSmoothZoom)
46430 03-31 21:19:38.377687 344 4668 D MtkCam/CamAdapter: smoothZoom cb(#0): (6, 0)
46569 03-31 21:19:38.440506 344 4668 D MtkCam/CamAdapter: smoothZoom cb(#1): (7, 0)
46656 03-31 21:19:38.490923 344 4668 D MtkCam/CamAdapter: smoothZoom cb(#2): (8, 0)
46722 03-31 21:19:38.515692 344 4668 D MtkCam/CamAdapter: smoothZoom cb(#3): (9, 1)
初始状态缩放值为5,要放大到最大值9,经过4步完成,每步都会执行doNotifyCb函数,当达到目标值9后,doNotifyCb函数返回的第二个参数值为mStopped=1,通知上层缩放完成。
log中第“startSmoothZoom should have stopped“ 是个报错信息,从缩放函数startSmoothZoom打印出来,条件是mStopped=0,说明是在上次没有缩放完成又下达了缩放操作命令,所以对这种情况再底层采取直接返回OK,不做处理。