Android Camera 调用流程及调试

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();将所有的属性打印出来
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
View Code
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所支持的所有参数。
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
", 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!
", 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
");

            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!!!
");
            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] = '';
        }

#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] = '';
        }

        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
",
                            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);
}
View Code

 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       
};
 



 
;// 重要,看注释
原文地址:https://www.cnblogs.com/leino11121/p/3288366.html