camera的startpreview流程
来源:互联网 发布:022型导弹艇知乎 编辑:程序博客网 时间:2024/04/28 00:12
一、概述
本文从framework中的camera native接口开始分析preview流程,文中的…..表示部分代码省略。
二、camera CS简易框图
三、preview调用过程
2.1 camera.java
public native final void startPreview();
camera进行预览时,APP最终调用的是startPreview,而startPreview是Java本地方法,其具体的实现是在jni中体现的。
2.2 android_hardware_Camera.cpp
static JNINativeMethod camMethods[] = {.......{ "startPreview", "()V", (void *)android_hardware_Camera_startPreview },.......};
通过查看注册的jni native方法映射表可知,Java中调用startpreview对应的具体实现是android_hardware_Camera_startPreview 方法
static void android_hardware_Camera_startPreview(JNIEnv *env, jobject thiz){ ALOGV("startPreview"); sp<Camera> camera = get_native_camera(env, thiz, NULL);//camera 是连接服务后创建的代理类 if (camera == 0) return; if (camera->startPreview() != NO_ERROR) { jniThrowRuntimeException(env, "startPreview failed"); return; }}
获取camera代理类,通过代理类调用接口startpreview
2.3 Camera.cpp
status_t Camera::startPreview(){ ALOGV("startPreview"); sp <ICamera> c = mCamera; if (c == 0) return NO_INIT; return c->startPreview();}
2.4 ICamera.cpp
virtual status_t startPreview() = 0;
这是个纯虚函数,其实现在它的子类BpCamera中。
status_t startPreview(){ ALOGV("startPreview"); Parcel data, reply; data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); remote()->transact(START_PREVIEW, data, &reply);//通过binder远程调用 return reply.readInt32();}
通过binder远程调用,最终会调用BnCamera::onTransact方法
status_t BnCamera::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ switch(code) { ............... case START_PREVIEW: { ALOGV("START_PREVIEW"); CHECK_INTERFACE(ICamera, data, reply); reply->writeInt32(startPreview()); return NO_ERROR; } break; ............... default: return BBinder::onTransact(code, data, reply, flags); }}
此处reply->writeInt32(startPreview());其实是省略了this指针,另外它也是继承ICamera类,声明也是纯虚函数,故它调用的是子类(CameraClient)的实现方法。
2.5 CameraClient.cpp
status_t CameraClient::startPreview() { LOG1("startPreview (pid %d)", getCallingPid()); //开始预览模式 return startCameraMode(CAMERA_PREVIEW_MODE);}
status_t CameraClient::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 set yet."); // still able to start preview in this case. } return startPreviewMode(); case CAMERA_RECORDING_MODE://录制模式 if (mSurface == 0 && mPreviewWindow == 0) { ALOGE("mSurface or mPreviewWindow must be set before startRecordingMode."); return INVALID_OPERATION; } return startRecordingMode(); default: return UNKNOWN_ERROR; }}
status_t CameraClient::startPreviewMode() { LOG1("startPreviewMode"); status_t result = NO_ERROR; // 如果预览已启用,则不需任何操作直接返回 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;}
2.6 CameraHardwareInterface.h
status_t startPreview(){ ALOGV("%s(%s)", __FUNCTION__, mName.string()); if (mDevice->ops->start_preview) return mDevice->ops->start_preview(mDevice); return INVALID_OPERATION;}
2.7 CameraHal_Module.cpp
int camera_start_preview(struct camera_device * device){ CAMHAL_LOG_MODULE_FUNCTION_NAME; int rv = -EINVAL; ti_camera_device_t* ti_dev = NULL; if(!device) return rv; ti_dev = (ti_camera_device_t*) device; rv = gCameraHals[ti_dev->cameraid]->startPreview(); return rv;}
2.8 CameraHal.cpp
status_t CameraHal::startPreview() { LOG_FUNCTION_NAME; ///Enable the display adapter if present, actual overlay enable happens when we post the buffer if(mDisplayAdapter.get() != NULL) { CAMHAL_LOGDA("Enabling display"); int width, height; mParameters.getPreviewSize(&width, &height); //设置显示窗口使能#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS ret = mDisplayAdapter->enableDisplay(width, height, &mStartPreview);#else ret = mDisplayAdapter->enableDisplay(width, height, NULL);#endif } ///Send START_PREVIEW command to adapter CAMHAL_LOGDA("Starting CameraAdapter preview mode"); ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_PREVIEW); mPreviewEnabled = true; mPreviewStartInProgress = false; return ret;}
2.9 BaseCameraAdapter.cpp
status_t BaseCameraAdapter::sendCommand(CameraCommands operation, int value1, int value2, int value3, int value4) { status_t ret = NO_ERROR; struct timeval *refTimestamp; BuffersDescriptor *desc = NULL; CameraFrame *frame = NULL; switch ( operation ) { ......... case CameraAdapter::CAMERA_START_PREVIEW: { CAMHAL_LOGDA("Start Preview"); if ( ret == NO_ERROR ) { ret = setState(operation); } if ( ret == NO_ERROR ) { ret = startPreview(); } if ( ret == NO_ERROR ) { ret = commitState(); } else { ret |= rollbackState(); } break; } ......... default: CAMHAL_LOGEB("Command 0x%x unsupported!", operation); break; }; LOG_FUNCTION_NAME_EXIT; return ret;}
2.10 V4LCameraAdapter.cpp
status_t V4LCameraAdapter::startPreview(){ status_t ret = NO_ERROR; LOG_FUNCTION_NAME; android::AutoMutex lock(mPreviewBufsLock); if(mPreviewing) { ret = BAD_VALUE; goto EXIT; } for (int i = 0; i < mPreviewBufferCountQueueable; i++) { mVideoInfo->buf.index = i; mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; mVideoInfo->buf.memory = V4L2_MEMORY_MMAP; ret = v4lIoctl(mCameraHandle, VIDIOC_QBUF, &mVideoInfo->buf); if (ret < 0) { CAMHAL_LOGEA("VIDIOC_QBUF Failed"); goto EXIT; } nQueued++; } ret = v4lStartStreaming(); // Create and start preview thread for receiving buffers from V4L Camera if(!mCapturing) { mPreviewThread = new PreviewThread(this); CAMHAL_LOGDA("Created preview thread"); } //Update the flag to indicate we are previewing mPreviewing = true; mCapturing = false;EXIT: LOG_FUNCTION_NAME_EXIT; return ret;}
status_t V4LCameraAdapter::v4lIoctl (int fd, int req, void* argp) { status_t ret = NO_ERROR; errno = 0; do { ret = ioctl (fd, req, argp);//与驱动交互 }while (-1 == ret && EINTR == errno); return ret;}
四、preview时序图
阅读全文
0 0
- camera的startpreview流程
- Android Camera fw学习(三)-startPreview流程分析
- Android Camera Subsystem - startPreview
- Android Camera 流程学习记录(四)—— Camera.startPreview() flow
- Android4.4 Camera HAL startpreview的具体过程
- Android Camera 系统架构源码分析(2)---->Camera的startPreview和setPreviewCallback
- Android Camera 系统架构源码分析(2)---->Camera的startPreview和setPreviewCallback
- Android5.1.1Camera 系统架构源码分析(2)---->Camera的startPreview和setPreviewCallback
- Android开发遇到Camera StartPreview Failed 错误
- 抄的camera流程
- Android中Camera的调用流程
- walle和普通camera的流程总结
- android Camera 应用流程 --Camera
- Camera启动基本流程
- camera 控制流程
- Android Camera调用流程
- QRD7xxx camera调用流程
- camera启动调用流程
- BZOJ 1051-受欢迎的牛(强连通)
- postfix中限制认证用户使用的sender address
- 【自组织网】【笔记】阅读之GAODV论文及其OPNET实现
- BJOI2014 想法
- WAMPServer集成环境安装
- camera的startpreview流程
- Jetson TX2 之 JetPack 3.0 安装小记
- C语言有无符号数据运算错误
- 申嵌mini6410_tiny6410入门篇
- String,StringBuffer与StringBuilder的区别??
- 【自组织网】【笔记】阅读之GeoAODV的OPNET实现
- 【mongoDB实战】mongoDB数据备份和还原
- 1002.等价二叉树
- ubuntu上eclipse快捷方式配置