Android Camera 调用流程及调试
2013-08-29 09:14 白居不易 阅读(2518) 评论(0) 编辑 收藏 举报1、应用.java中
camera = Camera.open(0);
java框架base/core/java/android/hardware/Camera.java
public static Camera open(int cameraId) { return new Camera(cameraId); }
Camera(int cameraId) { //定义回调函数 Looper looper; //定义处理函数
native_setup(new WeakReference<Camera>(this), cameraId); }
Camera JNI:base/core/jni/android_hardware_Camera.cpp
// connect to camera service static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, jobject weak_this, jint cameraId) { sp<Camera> camera = Camera::connect(cameraId); if (camera == NULL) { jniThrowRuntimeException(env, "Fail to connect to camera service"); return; } // make sure camera hardware is alive if (camera->getStatus() != NO_ERROR) { jniThrowRuntimeException(env, "Camera initialization failed"); return; } jclass clazz = env->GetObjectClass(thiz); if (clazz == NULL) { jniThrowRuntimeException(env, "Can't find android/hardware/Camera"); return; } // We use a weak reference so the Camera object can be garbage collected. // The reference is only used as a proxy for callbacks. sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera); context->incStrong(thiz); camera->setListener(context); // save context in opaque field env->SetIntField(thiz, fields.context, (int)context.get()); }
Camera::connect:
av/camera/Camera.cpp
sp<Camera> Camera::connect(int cameraId) { ALOGV("connect"); sp<Camera> c = new Camera(); const sp<ICameraService>& cs = getCameraService(); if (cs != 0) { c->mCamera = cs->connect(c, cameraId); } if (c->mCamera != 0) { c->mCamera->asBinder()->linkToDeath(c); c->mStatus = NO_ERROR; } else { c.clear(); } return c; }
cs->connect(c, cameraId) ---------》》av/services/camera/libcameraservice/CameraService.cpp
sp<ICamera> CameraService::connect( const sp<ICameraClient>& cameraClient, int cameraId) { int callingPid = getCallingPid(); sp<CameraHardwareInterface> hardware = NULL; ...
struct camera_info info;
if (mModule->get_camera_info(cameraId, &info) != OK) {// 重要
ALOGE("Invalid camera id %d", cameraId);
return NULL;
}
hardware = new CameraHardwareInterface(camera_device_name); // 没什么, if (hardware->initialize(&mModule->common) != OK) { //重要 hardware.clear(); return NULL; }
mModule->get_camera_info(cameraId, &info) ----------》》
int camera_get_camera_info(int camera_id, struct camera_info *info) { // this going to be the first call from camera service // initialize camera properties here... if(gCameraProperties.initialize() != android::NO_ERROR) {} //Get camera properties for camera index if(gCameraProperties.getProperties(camera_id, &properties) < 0) { }
gCameraProperties.initialize()--------》》CameraProperties.cpp
// Initializes the CameraProperties class status_t CameraProperties::initialize() { #ifdef AMLOGIC_USB_CAMERA_SUPPORT mCamerasSupported = 0; ret = loadProperties(); mInitialized = 0; #else ret = loadProperties(); mInitialized = 1; #endif }
///Loads all the Camera related properties status_t CameraProperties::loadProperties() {
// adapter updates capabilities and we update camera count mCamerasSupported = CameraAdapter_Capabilities(mCameraProps, mCamerasSupported, CameraAdapter_CameraNum()); for (unsigned int i = 0; i < mCamerasSupported; i++) { mCameraProps[i].set(CAMERA_SENSOR_INDEX, i); mCameraProps[i].dump(); } }
mCameraProps[i].dump();将所有的属性打印出来
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - preferred-preview-size-for-video = 1280x720 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-antibanding-default = off D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-antibanding-values = off,50hz,60hz, D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-auto-exposure-lock = false D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-auto-whitebalance-lock = false D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-brightness-default = 50 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-camera-name = Camera D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-contrast-default = 100 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-effect-default = none D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-effect-values = none,negative,sepia D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-ev-compensation-default = 0 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-ev-compensation-max = 4 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-ev-compensation-min = -4 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-ev-compensation-step = 1 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-exif-make = MBX D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-exif-model = MBX reference board (goer) D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-exposure-mode-default = auto D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-exposure-mode-values = auto D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-facing = front D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-focal-length = 4.31 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-focus-mode-default = fixed D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-focus-mode-values = fixed D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-framerate-range-default = 5000,26623 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-framerate-range-image-default = 10000,15000 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-framerate-range-values = (5000,26623) D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-framerate-range-video-default = 10000,15000 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-gbce-default = disable D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-horizontal-angle = 54.8 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-ipp-default = ldc-nsf D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-ipp-values = ldc-nsf D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-iso-mode-default = auto D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-iso-mode-values = auto D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-jpeg-quality-default = 90 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-jpeg-thumbnail-quality-default = 90 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-jpeg-thumbnail-size-default = 180x160 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-jpeg-thumbnail-size-values = 180x160,0x0 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-max-fd-hw-faces = 0 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-max-fd-sw-faces = 0 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-orientation = 270 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-picture-format-default = jpeg D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-picture-format-values = jpeg D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-picture-size-default = 1280x720 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-picture-size-values = 640x480,160x120,320x240,640x360,384x216,352x288,1280x720,960x720,800x448,800x600,160x90,320x180 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-preview-format-default = yuv420sp D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-preview-format-values = yuv420sp,yuv420p, mjpeg D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-preview-frame-rate-default = 15 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-preview-frame-rate-values = 10,15 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-preview-size-default = 1280x720 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-preview-size-values = 640x480,160x120,320x240,640x360,384x216,352x288,1280x720,960x720,800x448,800x600,160x90,320x180 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-required-image-bufs = 1 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-required-preview-bufs = 6 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-saturation-default = 100 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-scene-mode-default = auto D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-scene-mode-values = auto D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-sensor-index = 0 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-sharpness-default = 100 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-smooth-zoom-supported = false D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-vertical-angle = 42.5 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-video-snapshot-supported = false D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-vstab-default = false D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-vstab-supported = true D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-whitebalance-default = auto D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-whitebalance-values = auto D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-zoom-default = 0 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-zoom-ratios = 100 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-zoom-stages = 0 D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - prop-zoom-supported = false D/CameraParameters( 2270): hardware/amlogic/camera/CameraParameters.cpp:169 dump - video-size = 1280x720
mCamerasSupported = CameraAdapter_Capabilities(mCameraProps, mCamerasSupported, CameraAdapter_CameraNum()); -------》》V4LCameraAdapter/V4LCameraAdapter.cpp
extern "C" int CameraAdapter_Capabilities(CameraProperties::Properties* properties_array, const unsigned int starting_camera, const unsigned int camera_num) { loadCaps(starting_camera + num_cameras_supported, properties); }
loadCaps(starting_camera + num_cameras_supported, properties);
此函数主要是初始化所有的参数,实现中会根据具体的camera设备来设置相关参数,使用open("/dev/video0")之类,得到当前camera所支持的所有参数。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
extern "C" void loadCaps(int camera_id, CameraProperties::Properties* params) { const char DEFAULT_BRIGHTNESS[] = "50"; const char DEFAULT_CONTRAST[] = "100"; const char DEFAULT_IPP[] = "ldc-nsf"; const char DEFAULT_GBCE[] = "disable"; const char DEFAULT_ISO_MODE[] = "auto"; const char DEFAULT_PICTURE_FORMAT[] = "jpeg"; const char DEFAULT_PICTURE_SIZE[] = "640x480"; const char PREVIEW_FORMAT_420SP[] = "yuv420sp"; const char PREVIEW_FORMAT_422I[] = "yuv422i-yuyv"; const char DEFAULT_PREVIEW_SIZE[] = "640x480"; const char DEFAULT_NUM_PREV_BUFS[] = "6"; const char DEFAULT_NUM_PIC_BUFS[] = "1"; const char DEFAULT_MAX_FOCUS_AREAS[] = "1"; const char DEFAULT_SATURATION[] = "100"; const char DEFAULT_SCENE_MODE[] = "auto"; const char DEFAULT_SHARPNESS[] = "100"; const char DEFAULT_VSTAB[] = "false"; const char DEFAULT_VSTAB_SUPPORTED[] = "true"; const char DEFAULT_MAX_FD_HW_FACES[] = "0"; const char DEFAULT_MAX_FD_SW_FACES[] = "0"; const char DEFAULT_FOCAL_LENGTH_PRIMARY[] = "4.31"; const char DEFAULT_FOCAL_LENGTH_SECONDARY[] = "1.95"; const char DEFAULT_HOR_ANGLE[] = "54.8"; const char DEFAULT_VER_ANGLE[] = "42.5"; const char DEFAULT_AE_LOCK[] = "false"; const char DEFAULT_AWB_LOCK[] = "false"; const char DEFAULT_MAX_NUM_METERING_AREAS[] = "0"; const char DEFAULT_LOCK_SUPPORTED[] = "true"; const char DEFAULT_LOCK_UNSUPPORTED[] = "false"; const char DEFAULT_VIDEO_SIZE[] = "640x480"; const char DEFAULT_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[] = "640x480"; bool bFrontCam = false; int camera_fd = -1; if (camera_id == 0) { #ifdef AMLOGIC_BACK_CAMERA_SUPPORT bFrontCam = false; #elif defined(AMLOGIC_FRONT_CAMERA_SUPPORT) bFrontCam = true; #elif defined(AMLOGIC_USB_CAMERA_SUPPORT) bFrontCam = true; #else//defined nothing, we try by ourself.we assume, the 0 is front camera, 1 is back camera bFrontCam = true; #endif } else if (camera_id == 1) { #if defined(AMLOGIC_BACK_CAMERA_SUPPORT) && defined(AMLOGIC_FRONT_CAMERA_SUPPORT) bFrontCam = true; #else//defined nothing, we try to by ourself bFrontCam = false; #endif } //should changed while the screen orientation changed. int degree = -1; char property[64]; memset(property,0,sizeof(property)); if(bFrontCam == true) { params->set(CameraProperties::FACING_INDEX, ExCameraParameters::FACING_FRONT); if(getCameraOrientation(bFrontCam,property)>=0){ params->set(CameraProperties::ORIENTATION_INDEX,property); }else{ #ifdef AMLOGIC_USB_CAMERA_SUPPORT params->set(CameraProperties::ORIENTATION_INDEX,"0"); #else params->set(CameraProperties::ORIENTATION_INDEX,"270"); #endif } } else { params->set(CameraProperties::FACING_INDEX, ExCameraParameters::FACING_BACK); if(getCameraOrientation(bFrontCam,property)>=0){ params->set(CameraProperties::ORIENTATION_INDEX,property); }else{ #ifdef AMLOGIC_USB_CAMERA_SUPPORT params->set(CameraProperties::ORIENTATION_INDEX,"180"); #else params->set(CameraProperties::ORIENTATION_INDEX,"90"); #endif } } params->set(CameraProperties::SUPPORTED_PREVIEW_FORMATS,"yuv420sp,yuv420p, mjpeg"); //yuv420p for cts //leon add mjpeg if(DEFAULT_PREVIEW_PIXEL_FORMAT == V4L2_PIX_FMT_YUYV){ // 422I //params->set(CameraProperties::SUPPORTED_PREVIEW_FORMATS,PREVIEW_FORMAT_422I); params->set(CameraProperties::PREVIEW_FORMAT,PREVIEW_FORMAT_422I); }else if(DEFAULT_PREVIEW_PIXEL_FORMAT == V4L2_PIX_FMT_NV21){ //420sp //params->set(CameraProperties::SUPPORTED_PREVIEW_FORMATS,PREVIEW_FORMAT_420SP); params->set(CameraProperties::PREVIEW_FORMAT,PREVIEW_FORMAT_420SP); }else{ //default case //params->set(CameraProperties::SUPPORTED_PREVIEW_FORMATS,PREVIEW_FORMAT_420SP); params->set(CameraProperties::PREVIEW_FORMAT,PREVIEW_FORMAT_420SP); } //get preview size & set char *sizes = (char *) calloc (1, 1024); if(!sizes){ CAMHAL_LOGEA("Alloc string buff error!"); return; } #ifdef AMLOGIC_USB_CAMERA_SUPPORT #ifdef AMLOGIC_TWO_CH_UVC int main_id = -1; if(NO_ERROR == getVideodevId( camera_id,main_id )){ if ((camera_fd = open(DEVICE_PATH(camera_id), O_RDWR)) != -1) { CAMHAL_LOGDB("open %s success to loadCaps\n", DEVICE_PATH(camera_id)); } } #else while( camera_id < (int)ARRAY_SIZE(SENSOR_PATH)){ if ((camera_fd = open(DEVICE_PATH(camera_id), O_RDWR)) != -1) { CAMHAL_LOGDB("open %s success when loadCaps!\n", DEVICE_PATH(camera_id)); break; } camera_id++; } if(camera_id >= (int)ARRAY_SIZE(SENSOR_PATH)){ CAMHAL_LOGEB("failed to opening Camera when loadCaps: %s", strerror(errno)); } #endif #else camera_fd = open(DEVICE_PATH(camera_id), O_RDWR); #endif if(camera_fd<0) CAMHAL_LOGEB("open camera %d error when loadcaps",camera_id); #ifdef AMLOGIC_CAMERA_NONBLOCK_SUPPORT int fps=0, fps_num=0; int ret; char *fpsrange=(char *)calloc(32,sizeof(char)); ret = enumFramerate(camera_fd, &fps, &fps_num); if((fpsrange != NULL)&&(NO_ERROR == ret) && ( 0 !=fps_num )){ sprintf(fpsrange,"%s%d","10,",fps/fps_num); CAMHAL_LOGDA("O_NONBLOCK operation to do previewThread\n"); params->set(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES, fpsrange); params->set(CameraProperties::PREVIEW_FRAME_RATE, fps/fps_num); memset( fpsrange, 0, 32*sizeof(char)); sprintf(fpsrange,"%s%d","10000,",fps*1000/fps_num); params->set(CameraProperties::FRAMERATE_RANGE_IMAGE, fpsrange); params->set(CameraProperties::FRAMERATE_RANGE_VIDEO, fpsrange); memset( fpsrange, 0, 32*sizeof(char)); sprintf(fpsrange,"(%s%d)","5000,",fps*1000/fps_num); params->set(CameraProperties::FRAMERATE_RANGE_SUPPORTED, fpsrange); memset( fpsrange, 0, 32*sizeof(char)); sprintf(fpsrange,"%s%d","5000,",fps*1000/fps_num); params->set(CameraProperties::FRAMERATE_RANGE, fpsrange); }else{ if(NO_ERROR != ret) CAMHAL_LOGDA("sensor driver need to implement VIDIOC_G_PARM!!!\n"); params->set(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES, "10,15"); params->set(CameraProperties::PREVIEW_FRAME_RATE, "15"); params->set(CameraProperties::FRAMERATE_RANGE_SUPPORTED, "(5000,26623)"); params->set(CameraProperties::FRAMERATE_RANGE, "5000,26623"); params->set(CameraProperties::FRAMERATE_RANGE_IMAGE, "10000,15000"); params->set(CameraProperties::FRAMERATE_RANGE_VIDEO, "10000,15000"); } #else params->set(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES, "10,15"); params->set(CameraProperties::PREVIEW_FRAME_RATE, "15"); params->set(CameraProperties::FRAMERATE_RANGE_SUPPORTED, "(5000,26623)"); params->set(CameraProperties::FRAMERATE_RANGE, "5000,26623"); params->set(CameraProperties::FRAMERATE_RANGE_IMAGE, "10000,15000"); params->set(CameraProperties::FRAMERATE_RANGE_VIDEO, "10000,15000"); #endif memset(sizes,0,1024); uint32_t preview_format = DEFAULT_PREVIEW_PIXEL_FORMAT; #ifdef AMLOGIC_USB_CAMERA_SUPPORT preview_format = V4L2_PIX_FMT_YUYV; #endif if (!getValidFrameSize(camera_fd, preview_format, sizes)) { int len = strlen(sizes); unsigned int supported_w = 0, supported_h = 0,w = 0,h = 0; if(len>1){ if(sizes[len-1] == ',') sizes[len-1] = '\0'; } #ifndef AMLOGIC_USB_CAMERA_SUPPORT char small_size[8] = "176x144"; //for cts if(strstr(sizes,small_size)==NULL){ if((len+sizeof(small_size))<(1024-1)){ strcat(sizes,","); strcat(sizes,small_size); } } #endif params->set(CameraProperties::SUPPORTED_PREVIEW_SIZES, sizes); char * b = (char *)sizes; while(b != NULL){ if (sscanf(b, "%dx%d", &supported_w, &supported_h) != 2){ break; } if((supported_w*supported_h)>(w*h)){ w = supported_w; h = supported_h; } b = strchr(b, ','); if(b) b++; } if((w>0)&&(h>0)){ memset(sizes, 0, 1024); sprintf(sizes,"%dx%d",w,h); } //char * b = strrchr(sizes, ','); //if (b) // b++; //else // b = sizes; params->set(CameraProperties::PREVIEW_SIZE, sizes); } else { #ifdef AMLOGIC_USB_CAMERA_SUPPORT params->set(CameraProperties::SUPPORTED_PREVIEW_SIZES, "320x240,176x144,160x120"); params->set(CameraProperties::PREVIEW_SIZE,"320x240"); #else params->set(CameraProperties::SUPPORTED_PREVIEW_SIZES, "640x480,352x288,176x144"); params->set(CameraProperties::PREVIEW_SIZE,"640x480"); #endif } params->set(CameraProperties::SUPPORTED_PICTURE_FORMATS, DEFAULT_PICTURE_FORMAT); params->set(CameraProperties::PICTURE_FORMAT,DEFAULT_PICTURE_FORMAT); params->set(CameraProperties::JPEG_QUALITY, 90); //must have >2 sizes and contain "0x0" params->set(CameraProperties::SUPPORTED_THUMBNAIL_SIZES, "180x160,0x0"); params->set(CameraProperties::JPEG_THUMBNAIL_SIZE, "180x160"); params->set(CameraProperties::JPEG_THUMBNAIL_QUALITY, 90); //get & set picture size memset(sizes,0,1024); uint32_t picture_format = DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT; #ifdef AMLOGIC_USB_CAMERA_SUPPORT picture_format = V4L2_PIX_FMT_YUYV; #endif if (!getValidFrameSize(camera_fd, picture_format, sizes)) { int len = strlen(sizes); unsigned int supported_w = 0, supported_h = 0,w = 0,h = 0; if(len>1){ if(sizes[len-1] == ',') sizes[len-1] = '\0'; } params->set(CameraProperties::SUPPORTED_PICTURE_SIZES, sizes); char * b = (char *)sizes; while(b != NULL){ if (sscanf(b, "%dx%d", &supported_w, &supported_h) != 2){ break; } if((supported_w*supported_h)>(w*h)){ w = supported_w; h = supported_h; } b = strchr(b, ','); if(b) b++; } if((w>0)&&(h>0)){ memset(sizes, 0, 1024); sprintf(sizes,"%dx%d",w,h); } //char * b = strrchr(sizes, ','); //if (b) // b++; //else // b = sizes; params->set(CameraProperties::PICTURE_SIZE, sizes); } else { #ifdef AMLOGIC_USB_CAMERA_SUPPORT params->set(CameraProperties::SUPPORTED_PICTURE_SIZES, "320x240"); params->set(CameraProperties::PICTURE_SIZE,"320x240"); #else params->set(CameraProperties::SUPPORTED_PICTURE_SIZES, "640x480"); params->set(CameraProperties::PICTURE_SIZE,"640x480"); #endif } free(sizes); char *focus_mode = (char *) calloc (1, 256); char * def_focus_mode = (char *) calloc (1, 64); if((focus_mode)&&(def_focus_mode)){ memset(focus_mode,0,256); memset(def_focus_mode,0,64); if(getCameraAutoFocus(camera_fd, focus_mode,def_focus_mode)) { params->set(CameraProperties::SUPPORTED_FOCUS_MODES, focus_mode); params->set(CameraProperties::FOCUS_MODE, def_focus_mode); }else { params->set(CameraProperties::SUPPORTED_FOCUS_MODES, "fixed"); params->set(CameraProperties::FOCUS_MODE, "fixed"); } }else{ params->set(CameraProperties::SUPPORTED_FOCUS_MODES, "fixed"); params->set(CameraProperties::FOCUS_MODE, "fixed"); } if(focus_mode){ free(focus_mode); focus_mode = NULL; } if(def_focus_mode){ free(def_focus_mode); def_focus_mode = NULL; } char *banding_mode = (char *) calloc (1, 256); char *def_banding_mode = (char *) calloc (1, 64); if((banding_mode)&&(def_banding_mode)){ memset(banding_mode,0,256); memset(def_banding_mode,0,64); getCameraBanding(camera_fd, banding_mode, def_banding_mode); params->set(CameraProperties::SUPPORTED_ANTIBANDING, banding_mode); params->set(CameraProperties::ANTIBANDING, def_banding_mode); }else{ params->set(CameraProperties::SUPPORTED_ANTIBANDING, "50hz,60hz"); params->set(CameraProperties::ANTIBANDING, "50hz"); } if(banding_mode){ free(banding_mode); banding_mode = NULL; } if(def_banding_mode){ free(def_banding_mode); def_banding_mode = NULL; } params->set(CameraProperties::FOCAL_LENGTH, "4.31"); params->set(CameraProperties::HOR_ANGLE,"54.8"); params->set(CameraProperties::VER_ANGLE,"42.5"); #ifdef AMLOGIC_USB_CAMERA_SUPPORT params->set(CameraProperties::SUPPORTED_WHITE_BALANCE, "auto"); params->set(CameraProperties::WHITEBALANCE, "auto"); #else char *wb_mode = (char *) calloc (1, 256); char *def_wb_mode = (char *) calloc (1, 64); if( wb_mode && def_wb_mode){ memset(wb_mode, 0, 256); memset(def_wb_mode, 0, 64); getCameraWhiteBalance(camera_fd, wb_mode, def_wb_mode); params->set(CameraProperties::SUPPORTED_WHITE_BALANCE, wb_mode); params->set(CameraProperties::WHITEBALANCE, def_wb_mode); }else{ params->set(CameraProperties::SUPPORTED_WHITE_BALANCE, "auto,daylight,incandescent,fluorescent"); params->set(CameraProperties::WHITEBALANCE, "auto"); } if(wb_mode){ free(wb_mode); wb_mode = NULL; } if(def_wb_mode){ free(def_wb_mode); def_wb_mode = NULL; } #endif params->set(CameraProperties::AUTO_WHITEBALANCE_LOCK, DEFAULT_AWB_LOCK); params->set(CameraProperties::SUPPORTED_EFFECTS, "none,negative,sepia"); params->set(CameraProperties::EFFECT, "none"); char *flash_mode = (char *) calloc (1, 256); char *def_flash_mode = (char *) calloc (1, 64); if((flash_mode)&&(def_flash_mode)){ memset(flash_mode,0,256); memset(def_flash_mode,0,64); if (get_flash_mode(camera_fd, flash_mode,def_flash_mode)) { params->set(CameraProperties::SUPPORTED_FLASH_MODES, flash_mode); params->set(CameraProperties::FLASH_MODE, def_flash_mode); CAMHAL_LOGDB("def_flash_mode=%s, flash_mode=%s\n", def_flash_mode, flash_mode); } } if (flash_mode) { free(flash_mode); flash_mode = NULL; } if (def_flash_mode) { free(def_flash_mode); def_flash_mode = NULL; } //params->set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,"auto,night,snow"); //params->set(CameraParameters::KEY_SCENE_MODE,"auto"); params->set(CameraProperties::EXPOSURE_MODE, "auto"); params->set(CameraProperties::SUPPORTED_EXPOSURE_MODES, "auto"); params->set(CameraProperties::AUTO_EXPOSURE_LOCK, DEFAULT_AE_LOCK); int min=0, max =0, def=0, step =0; getCameraExposureValue( camera_fd, min, max, step, def); params->set(CameraProperties::SUPPORTED_EV_MAX, max); params->set(CameraProperties::SUPPORTED_EV_MIN, min); params->set(CameraProperties::EV_COMPENSATION, def); params->set(CameraProperties::SUPPORTED_EV_STEP, step); //don't support digital zoom now #ifndef AMLOGIC_USB_CAMERA_SUPPORT int zoom_level = -1; char *zoom_str = (char *) calloc (1, 256); if(zoom_str) memset(zoom_str,0,256); zoom_level = get_supported_zoom(camera_fd,zoom_str); if(zoom_level>0){ //new interface by v4l ioctl params->set(CameraProperties::ZOOM_SUPPORTED,"true"); params->set(CameraProperties::SMOOTH_ZOOM_SUPPORTED,"false"); params->set(CameraProperties::SUPPORTED_ZOOM_RATIOS,zoom_str); params->set(CameraProperties::SUPPORTED_ZOOM_STAGES,zoom_level); //think the zoom ratios as a array, the max zoom is the max index params->set(CameraProperties::ZOOM, 0);//default should be 0 }else{ // by set video layer zoom sys params->set(CameraProperties::ZOOM_SUPPORTED,"true"); params->set(CameraProperties::SMOOTH_ZOOM_SUPPORTED,"false"); params->set(CameraProperties::SUPPORTED_ZOOM_RATIOS,"100,120,140,160,180,200,220,280,300"); params->set(CameraProperties::SUPPORTED_ZOOM_STAGES,8); //think the zoom ratios as a array, the max zoom is the max index params->set(CameraProperties::ZOOM, 0);//default should be 0 } if(zoom_str) free(zoom_str); #else params->set(CameraProperties::ZOOM_SUPPORTED,"false"); params->set(CameraProperties::SMOOTH_ZOOM_SUPPORTED,"false"); params->set(CameraProperties::SUPPORTED_ZOOM_RATIOS,"100"); params->set(CameraProperties::SUPPORTED_ZOOM_STAGES,0); //think the zoom ratios as a array, the max zoom is the max index params->set(CameraProperties::ZOOM, 0);//default should be 0 #endif params->set(CameraProperties::SUPPORTED_ISO_VALUES, "auto"); params->set(CameraProperties::ISO_MODE, DEFAULT_ISO_MODE); params->set(CameraProperties::SUPPORTED_IPP_MODES, DEFAULT_IPP); params->set(CameraProperties::IPP, DEFAULT_IPP); params->set(CameraProperties::SUPPORTED_SCENE_MODES, "auto"); params->set(CameraProperties::SCENE_MODE, DEFAULT_SCENE_MODE); params->set(CameraProperties::BRIGHTNESS, DEFAULT_BRIGHTNESS); params->set(CameraProperties::CONTRAST, DEFAULT_CONTRAST); params->set(CameraProperties::GBCE, DEFAULT_GBCE); params->set(CameraProperties::SATURATION, DEFAULT_SATURATION); params->set(CameraProperties::SHARPNESS, DEFAULT_SHARPNESS); params->set(CameraProperties::VSTAB, DEFAULT_VSTAB); params->set(CameraProperties::VSTAB_SUPPORTED, DEFAULT_VSTAB_SUPPORTED); params->set(CameraProperties::MAX_FD_HW_FACES, DEFAULT_MAX_FD_HW_FACES); params->set(CameraProperties::MAX_FD_SW_FACES, DEFAULT_MAX_FD_SW_FACES); params->set(CameraProperties::REQUIRED_PREVIEW_BUFS, DEFAULT_NUM_PREV_BUFS); params->set(CameraProperties::REQUIRED_IMAGE_BUFS, DEFAULT_NUM_PIC_BUFS); #ifdef AMLOGIC_ENABLE_VIDEO_SNAPSHOT params->set(CameraProperties::VIDEO_SNAPSHOT_SUPPORTED, "true"); #else params->set(CameraProperties::VIDEO_SNAPSHOT_SUPPORTED, "false"); #endif #ifdef AMLOGIC_USB_CAMERA_SUPPORT params->set(CameraProperties::VIDEO_SIZE,params->get(CameraProperties::PREVIEW_SIZE)); params->set(CameraProperties::PREFERRED_PREVIEW_SIZE_FOR_VIDEO,params->get(CameraProperties::PREVIEW_SIZE)); #else params->set(CameraProperties::VIDEO_SIZE, DEFAULT_VIDEO_SIZE); params->set(CameraProperties::PREFERRED_PREVIEW_SIZE_FOR_VIDEO, DEFAULT_PREFERRED_PREVIEW_SIZE_FOR_VIDEO); #endif if(camera_fd>=0) close(camera_fd); }
int camera_get_camera_info(int camera_id, struct camera_info *info)中的另一个函数gCameraProperties.getProperties(camera_id, &properties)
此函数是获取到对应camera_id的属性,因为在上一函数中已经遍历了所有的Camera设备,所以此函数实现较为简单:
// Returns the properties class for a specific Camera // Each value is indexed by the CameraProperties::CameraPropertyIndex enum int CameraProperties::getProperties(int cameraIndex, CameraProperties::Properties** properties) {*properties = mCameraProps+cameraIndex; return 0; }
camera_get_camera_info分析分析完了,其实现的主要功能:获取所有Camera的属性参数并保存在参数列表的数组中,并使用当前的Camera_id获取当前Camera的属性。
回到sp<ICamera> CameraService::connect(中的第二个调用的函数
hardware = new CameraHardwareInterface(camera_device_name); if (hardware->initialize(&mModule->common) != OK) { hardware.clear(); return NULL; }
hardware->initialize(&mModule->common)
status_t initialize(hw_module_t *module) { ALOGI("Opening camera %s", mName.string()); int rc = module->methods->open(module, mName.string(), (hw_device_t **)&mDevice); if (rc != OK) { ALOGE("Could not open camera %s: %d", mName.string(), rc); return rc; } initHalPreviewWindow(); return rc; }
int camera_device_open(const hw_module_t* module, const char* name,hw_device_t** device)
/******************************************************************* * implementation of camera_module functions *******************************************************************/ /* open device handle to one of the cameras * * assume camera service will keep singleton of each camera * so this function will always only be called once per camera instance */ int camera_device_open(const hw_module_t* module, const char* name,hw_device_t** device) { aml_camera_device_t* camera_device = NULL; camera_device_ops_t* camera_ops = NULL; android::CameraHal* camera = NULL; android::CameraProperties::Properties* properties = NULL; android::Mutex::Autolock lock(gCameraHalDeviceLock); LOGI("camera_device open"); /* ...状态检查,camera_ops初始化及函数赋值 */ // -------- vendor specific stuff -------- if(gCameraProperties.getProperties(cameraid, &properties) < 0)// 再次通过cameraid得到属性 { LOGE("Couldn't get camera properties"); } camera = new android::CameraHal(cameraid);// 没什么,主要是变量初始化及video系统的变更设置,关闭video播放 if(properties && (camera->initialize(properties) != android::NO_ERROR)) { LOGE("Couldn't initialize camera instance"); } gCameraHals[cameraid] = camera; gCamerasOpen++; } .... return rv; }
properties && (camera->initialize(properties)
/** @brief Initialize the Camera HAL Creates CameraAdapter, AppCallbackNotifier, DisplayAdapter and MemoryManager @param None @return NO_ERROR - On success NO_MEMORY - On failure to allocate memory for any of the objects @remarks Camera Hal internal function */ status_t CameraHal::initialize(CameraProperties::Properties* properties) { // Get my camera properties mCameraProperties = properties; // Dump the properties of this Camera // will only print if DEBUG macro is defined mCameraProperties->dump();// 再次打印所有属性 if (strcmp(CameraProperties::DEFAULT_VALUE, mCameraProperties->get(CameraProperties::CAMERA_SENSOR_INDEX)) != 0 ) { sensor_index = atoi(mCameraProperties->get(CameraProperties::CAMERA_SENSOR_INDEX)); } CAMHAL_LOGDB("Sensor index %d", sensor_index);// 得到cameraindex mCameraAdapter = CameraAdapter_Factory(sensor_index);// 创建CameraAdapter,重要,但简单 if ( ( NULL == mCameraAdapter ) || (mCameraAdapter->initialize(properties)!=NO_ERROR)) { CAMHAL_LOGEA("Unable to create or initialize CameraAdapter"); mCameraAdapter = NULL; goto fail_loop; } mCameraAdapter->incStrong(mCameraAdapter); mCameraAdapter->registerImageReleaseCallback(releaseImageBuffers, (void *) this);// 注册回调函数,释放buffer mCameraAdapter->registerEndCaptureCallback(endImageCapture, (void *)this); if(!mAppCallbackNotifier.get()) { /// Create the callback notifier mAppCallbackNotifier = new AppCallbackNotifier();// 创建AppCallbackNotifier if( ( NULL == mAppCallbackNotifier.get() ) || ( mAppCallbackNotifier->initialize() != NO_ERROR)) { CAMHAL_LOGEA("Unable to create or initialize AppCallbackNotifier"); goto fail_loop; } } if(!mMemoryManager.get()) { /// Create Memory Manager mMemoryManager = new MemoryManager(); if( ( NULL == mMemoryManager.get() ) || ( mMemoryManager->initialize() != NO_ERROR)) { CAMHAL_LOGEA("Unable to create or initialize MemoryManager"); goto fail_loop; } } ///Setup the class dependencies... ///AppCallbackNotifier has to know where to get the Camera frames and the events like auto focus lock etc from. ///CameraAdapter is the one which provides those events ///Set it as the frame and event providers for AppCallbackNotifier ///@remarks setEventProvider API takes in a bit mask of events for registering a provider for the different events /// That way, if events can come from DisplayAdapter in future, we will be able to add it as provider /// for any event mAppCallbackNotifier->setEventProvider(eventMask, mCameraAdapter);// 重要,看注释 mAppCallbackNotifier->setFrameProvider(mCameraAdapter); ///Any dynamic errors that happen during the camera use case has to be propagated back to the application ///via CAMERA_MSG_ERROR. AppCallbackNotifier is the class that notifies such errors to the application ///Set it as the error handler for CameraAdapter mCameraAdapter->setErrorHandler(mAppCallbackNotifier.get());// 重要,看注释 ///Start the callback notifier if(mAppCallbackNotifier->start() != NO_ERROR) { CAMHAL_LOGEA("Couldn't start AppCallbackNotifier"); goto fail_loop; } CAMHAL_LOGDA("Started AppCallbackNotifier.."); mAppCallbackNotifier->setMeasurements(mMeasurementEnabled); ///Initialize default parameters //leon initDefaultParameters();// 重要 if ( setParameters(mParameters) != NO_ERROR )// 非常重要 { CAMHAL_LOGEA("Failed to set default parameters?!"); }return NO_ERROR; fail_loop: return NO_MEMORY; }
注视中已说明创建ameraAdapter, AppCallbackNotifier, DisplayAdapter and MemoryManager等,除了上述的创建,还有两个重要函数,初始化默认的参数,及设置初始化的参数
initDefaultParameters();分析参数是否可用,并将设置默认参数mParameters。
setParameters(mParameters)
/** @brief Set the camera parameters. @param[in] params Camera parameters to configure the camera @return NO_ERROR @todo Define error codes */ int CameraHal::setParameters(const CameraParameters& params) { ...//依然是设置各种参数,与Prop中的允许的参数对比,
// Only send parameters to adapter if preview is already // enabled or doesSetParameterNeedUpdate says so. Initial setParameters to camera adapter, // will be called in startPreview() // TODO(XXX): Need to identify other parameters that need update from camera adapter ...//只有在startPreview enabled或者doesSetParameterNeedUpdate为true时才将parameters发送到adapter中。在startPreview时设置。
}
最后sp<ICamera> CameraService::connect 创建Client并将之返回。
av/camera/Camera.cpp中sp<Camera> Camera::connect(int cameraId)会将new Camera返回给JNI;
JNI返回给base/core/java/android/hardware/Camera.java的New Camera;
这样,Camera就被创建成功
V4LCameraAdapter::setParameters函数是对一些zoom 曝光之类的参数进行设置。而真正的关于分辨率 fmt之类的参数是在startPreview时设置的,调用函数UseBuffersPreview进行设置。
hardware->initialize(&mModule->common) -------------------》》 av/services/camera/libcameraservice/CameraHardwareInterface.h
status_t initialize(hw_module_t *module) { ALOGI("Opening camera %s", mName.string()); int rc = module->methods->open(module, mName.string(), (hw_device_t **)&mDevice); if (rc != OK) { ALOGE("Could not open camera %s: %d", mName.string(), rc); return rc; } initHalPreviewWindow(); return rc; }
不去追究细节,module->methods->open -----------》》 CameraHal_Module.cpp
static struct hw_module_methods_t camera_module_methods = { open: camera_device_open };
;// 重要,看注释