预览数据流分析(一) 数据的获取
mCameraDevice.startPreview();
/*
上篇文章已经有知道这个mCameraDevice就是对应的CameraClient的客户端,所以这个的startPreview就是CameraClient::startPreview()
*/
Step 1:
\frameworks\av\services\camera\libcameraservice\api1\CameraClient.cpp
// start preview mode
status_t CameraClient::startPreview() {
LOG1("startPreview (pid %d)", getCallingPid());
return startCameraMode(CAMERA_PREVIEW_MODE);
}
Step 2:
\frameworks\av\services\camera\libcameraservice\api1\CameraClient.cpp
// start preview or recording
status_tCameraClient::startCameraMode(camera_mode mode) {
LOG1("startCameraMode(%d)", mode);
Mutex::Autolock lock(mLock);
status_t result = checkPidAndHardware();
if (result != NO_ERROR) return result;
switch(mode) {
case CAMERA_PREVIEW_MODE:
if (mSurface == 0 && mPreviewWindow == 0) {
LOG1("mSurface is not setyet.");
// still able to startpreview in this case.
}
return startPreviewMode();
case CAMERA_RECORDING_MODE:
if (mSurface == 0 && mPreviewWindow == 0) {
ALOGE("mSurface ormPreviewWindow must be set before startRecordingMode.");
return INVALID_OPERATION;
}
return startRecordingMode();
default:
return UNKNOWN_ERROR;
}
}
Step 3:
\frameworks\av\services\camera\libcameraservice\api1\CameraClient.cpp
status_t CameraClient::startPreviewMode() {
LOG1("startPreviewMode");
status_t result = NO_ERROR;
// if preview has been enabled, nothing needs to be done
if (mHardware->previewEnabled()) {
return NO_ERROR;
}
if (mPreviewWindow != 0) {
native_window_set_scaling_mode(mPreviewWindow.get(),
NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
native_window_set_buffers_transform(mPreviewWindow.get(),
mOrientation);
}
mHardware->setPreviewWindow(mPreviewWindow);
result = mHardware->startPreview();
return result;
}
/*
主要分析这两个接口:
1, mHardware->setPreviewWindow
2, mHardware->startPreview();
mHardware前面已经有说明说,对应的就是Cam1Device类,而其具体的实现则是在其父类Cam1DeviceBase中实现的。所以mHardware->setPreviewWindow
对应就是Cam1DeviceBase::
setPreviewWindow(preview_stream_ops*window)
mHardware->startPreview();对应的是status_t
Cam1DeviceBase::
startPreview()
*/
Step 4.1.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);
/*
这里主要是初始化了一个DisplayClient的类。具体这个DisplayClient的功能。后面再分析。
DisplayClient创建的时候,生成了一个createDisplayThread的线程,用来处理displayclient发送过来的消息,
createImgBufQueue 则用于存储数据,具体如何运作的待分析。
bool
DisplayClient::
init()
{
bool ret =false;
//
MY_LOGD("+");
//
ret = createDisplayThread()
&& createImgBufQueue()
;
//
MY_LOGD("-ret(%d)", ret);
return ret;
}
*/
status_t status = initDisplayClient(window);
if ( OK == status &&previewEnabled() && mpDisplayClient != 0 )
{
status = enableDisplayClient();
if(mbWindowReady)
{
waitStartPreviewDone();
}
}
//
return status;
}
Step 4.1.2:
status_t
Cam1DeviceBase::
initDisplayClient(preview_stream_ops*window)
{
CAM_TRACE_CALL();
#if '1'!=MTKCAM_HAVE_DISPLAY_CLIENT
#warning "Not Build Display Client"
MY_LOGD("Not Build Display Client");
return OK;
#else
status_t status = OK;
Size previewSize;
//
MY_LOGD("+ window(%p)", window);
//
//
// [1] Check to see whether thepassed window is NULL or not.
if ( ! window )
{
MY_LOGW("NULL window is passed into...");
mbWindowReady = false;
//
if ( mpDisplayClient != 0 )
{
MY_LOGW("destroy the current display client(%p)...",mpDisplayClient.get());
mpDisplayClient->un