camera hardware module

ICS 中 沿用了linux驱动模块化的方式,把camera hal 形成一个hardware module,这点跟HC明显不同。

打开camera时, cameraservice 会先打开camera hw_moudle, 如下代码所示:

void CameraService::onFirstRef()
    {
        BnCameraService::onFirstRef();
        if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,      //获得camera 模块,
                    (const hw_module_t **)&mModule) < 0) {    //&mModule 应该就是camera.medfield.so.
            LOGE("Could not load camera HAL module");
            mNumberOfCameras = 0;
        }
        else {
            mNumberOfCameras = mModule->get_number_of_cameras();  //调用camera hal 层函数。
            if (mNumberOfCameras > MAX_CAMERAS) {
                LOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
                        mNumberOfCameras, MAX_CAMERAS);
                mNumberOfCameras = MAX_CAMERAS;
            }
            for (int i = 0; i < mNumberOfCameras; i++) {
                setCameraFree(i);
            }
        }
        // Read the system property to determine if we have to use the
        // AUDIO_STREAM_ENFORCED_AUDIBLE type.
        char value[PROPERTY_VALUE_MAX];
        property_get("ro.camera.sound.forced", value, "0");
        if (strcmp(value, "0") != 0) {
            mAudioStreamType = AUDIO_STREAM_ENFORCED_AUDIBLE;
        } else {
            mAudioStreamType = AUDIO_STREAM_MUSIC;
        }
    }
1. 这里的
hw_get_module(CAMERA_HARDWARE_MODULE_ID,
(const hw_module_t **)&mModule)
调用了hardware/libhardware/hardware.c
int hw_get_module(const char *id, const struct hw_module_t **module)
    {
        return hw_get_module_by_class(id, NULL, module);
    }

const char *id ------- 应该是module name
const struct hw_module_t **module -----应该是module模块地址。

    int hw_get_module_by_class(const char *class_id, const char *inst,
                               const struct hw_module_t **module)
    {
        int status;
        int i;
        const struct hw_module_t *hmi = NULL;
        char prop[PATH_MAX];
        char path[PATH_MAX];
        char name[PATH_MAX];
        if (inst)
            snprintf(name, PATH_MAX, "%s.%s", class_id, inst);  // 这里class_id 是camera,inst 应该是medfield,
        else
            strlcpy(name, class_id, PATH_MAX);
        /*
         * Here we rely on the fact that calling dlopen multiple times on
         * the same .so will simply increment a refcount (and not load
         * a new copy of the library).
         * We also assume that dlopen() is thread-safe.
         */
        
        /* Loop through the configuration variants looking for a module */
        for (i=0 ; i<HAL_VARIANT_KEYS_COUNT+1 ; i++) {
            if (i < HAL_VARIANT_KEYS_COUNT) {
                if (property_get(variant_keys[i], prop, NULL) == 0) {
                    continue;
                }
                snprintf(path, sizeof(path), "%s/%s.%s.so",
                         HAL_LIBRARY_PATH2, name, prop);
                if (access(path, R_OK) == 0) break;
                snprintf(path, sizeof(path), "%s/%s.%s.so",
                         HAL_LIBRARY_PATH1, name, prop);
                if (access(path, R_OK) == 0) break;
            } else {
                snprintf(path, sizeof(path), "%s/%s.default.so",
                         HAL_LIBRARY_PATH1, name);
                if (access(path, R_OK) == 0) break;
            }
        }
        
        status = -ENOENT;
        if (i < HAL_VARIANT_KEYS_COUNT+1) {
            /* load the module, if this fails, we're doomed, and we should not try
             * to load a different variant. */
            status = load(class_id, path, module);
        }
        
        return status;
    }
load(class_id, path, module) 代码如下:
/**
     * Load the file defined by the variant and if successful
     * return the dlopen handle and the hmi.
     * @return 0 = success, !0 = failure.
     */
    static int load(const char *id,
            const char *path,
            const struct hw_module_t **pHmi)
    {
        int status;
        void *handle;
        struct hw_module_t *hmi;
        /*
         * load the symbols resolving undefined symbols before
         * dlopen returns. Since RTLD_GLOBAL is not or'd in with
         * RTLD_NOW the external symbols will not be global
         */
        handle = dlopen(path, RTLD_NOW);
        if (handle == NULL) {
            char const *err_str = dlerror();
            LOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");
            status = -EINVAL;
            goto done;
        }
        /* Get the address of the struct hal_module_info. */
        const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
        hmi = (struct hw_module_t *)dlsym(handle, sym);
        if (hmi == NULL) {
            LOGE("load: couldn't find symbol %s", sym);
            status = -EINVAL;
            goto done;
        }
        /* Check that the id matches */
        if (strcmp(id, hmi->id) != 0) {
            LOGE("load: id=%s != hmi->id=%s", id, hmi->id);
            status = -EINVAL;
            goto done;
        }
        hmi->dso = handle;
        /* success */
        status = 0;
        done:
        if (status != 0) {
            hmi = NULL;
            if (handle != NULL) {
                dlclose(handle);
                handle = NULL;
            }
        } else {
            LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",
                    id, path, *pHmi, handle);
        }
        *pHmi = hmi;
        return status;
    }
2.  mNumberOfCameras = mModule->get_number_of_cameras();
调用了 hardware/intel/libcamera/IntelCameraHAL.cpp 中的
camera_module_t HAL_MODULE_INFO_SYM = {
        common: {
             tag: HARDWARE_MODULE_TAG,
             version_major: 1,
             version_minor: 0,
             id: CAMERA_HARDWARE_MODULE_ID,
             name: "Intel CameraHardware Module",
             author: "Intel",
             methods: &camera_module_methods,     //这里面定义了各种函数接口。
             dso: NULL, /* remove compilation warnings */
             reserved: {0}, /* remove compilation warnings */
        },
        get_number_of_cameras: HAL_GetNumberOfCameras,   //cameraservice 中会调用这两个函数。
        get_camera_info: HAL_GetCameraInfo,
    };
a.  get_number_of_cameras: HAL_GetNumberOfCameras,
int HAL_GetNumberOfCameras(void)
    {
        return android::CameraHardware::getNumberOfCameras();
    }

    /* This function will be called when the camera service is created.
     * Do some init work in this function.
     */
    int CameraHardware::getNumberOfCameras()
    {
        LogEntry(LOG_TAG, __FUNCTION__);
        if (num_cameras != 0)
            return num_cameras;
        int ret;
        struct v4l2_input input;
        int fd = -1;
        char *dev_name = "/dev/video0";
        fd = open(dev_name, O_RDWR);
        if (fd <= 0) {
            LogError("Error opening video device %s: %s",
                 dev_name, strerror(errno));
            return 0;
        }
        int i;
        for (i = 0; i < MAX_CAMERAS; i++) {
            memset(&input, 0, sizeof(input));
            input.index = i;
            ret = ioctl(fd, VIDIOC_ENUMINPUT, &input);  //从kernel 获得相应信息,枚举input通道信息。
            if (ret < 0) {
                break;
            }
            camInfo[i].port = input.reserved[1];
            strncpy(camInfo[i].name, (const char *)input.name, MAX_SENSOR_NAME_LENGTH);
        }
        close(fd);
        num_cameras = i;
        return num_cameras;
    }
b. get_camera_info: HAL_GetCameraInfo,
int HAL_GetCameraInfo(int camera_id, struct camera_info *info)
    {
        return android::CameraHardware::getCameraInfo(camera_id, info);
    }

    int CameraHardware::getCameraInfo(int cameraId, struct camera_info* cameraInfo)
    {
        LogEntry(LOG_TAG, __FUNCTION__);
        if (cameraId >= MAX_CAMERAS)
            return -EINVAL;
        memcpy(cameraInfo, &HAL_cameraInfo[cameraId], sizeof(camera_info));  //从HAL_cameraInfo[cameraId] 中获得信息。
        return 0;
    }
HAL_cameraInfo[cameraId] 定义如下:
static camera_info HAL_cameraInfo[MAX_CAMERAS] = {
        {
            CAMERA_FACING_FRONT,
            180,
        },
        {
            CAMERA_FACING_BACK,
            0,
        }
    };
c. methods: &camera_module_methods,     //这里面定义了各种函数接口。
static struct hw_module_methods_t camera_module_methods = {
        open: HAL_OpenCameraHardware   // 也就是这个函数
    };

open: HAL_OpenCameraHardware,

    int HAL_OpenCameraHardware(const hw_module_t* module, const char* name,
                    hw_device_t** device)
    {
        int rv = 0;
        int num_cameras = 0;
        int cameraid;
        intel_camera_device_t* camera_device = NULL;
        camera_device_ops_t* camera_ops = NULL;
        android::CameraHardware* camera = NULL;
        android::Mutex::Autolock lock(gCameraHalDeviceLock);
        LOGI("camera_device open");
        if (name != NULL) {
            cameraid = atoi(name);
            num_cameras = android::CameraHardware::getNumberOfCameras();
            if(cameraid > num_cameras)
            {
                LOGE("camera service provided cameraid out of bounds, "
                        "cameraid = %d, num supported = %d",
                        cameraid, num_cameras);
                rv = -EINVAL;
                goto fail;
            }
            if(gCamerasOpen >= MAX_CAMERAS)
            {
                LOGE("maximum number of cameras already open");
                rv = -ENOMEM;
                goto fail;
            }
            camera_device = (intel_camera_device_t*)malloc(sizeof(*camera_device));
            if(!camera_device)
            {
                LOGE("camera_device allocation fail");
                rv = -ENOMEM;
                goto fail;
            }
            camera_ops = (camera_device_ops_t*)malloc(sizeof(*camera_ops));
            if(!camera_ops)
            {
                LOGE("camera_ops allocation fail");
                rv = -ENOMEM;
                goto fail;
            }
            memset(camera_device, 0, sizeof(*camera_device));
            memset(camera_ops, 0, sizeof(*camera_ops));
            camera_device->device.common.tag = HARDWARE_DEVICE_TAG;
            camera_device->device.common.version = 0;
            camera_device->device.common.module = (hw_module_t *)(module);
            camera_device->device.common.close = HAL_CloseCameraHardware;
            camera_device->device.ops = camera_ops;
            camera_ops->set_preview_window = camera_set_preview_window;
            camera_ops->set_callbacks = camera_set_callbacks;
            camera_ops->enable_msg_type = camera_enable_msg_type;
            camera_ops->disable_msg_type = camera_disable_msg_type;
            camera_ops->msg_type_enabled = camera_msg_type_enabled;
            camera_ops->start_preview = camera_start_preview;
            camera_ops->stop_preview = camera_stop_preview;
            camera_ops->preview_enabled = camera_preview_enabled;
            camera_ops->store_meta_data_in_buffers = camera_store_meta_data_in_buffers;
            camera_ops->start_recording = camera_start_recording;
            camera_ops->stop_recording = camera_stop_recording;
            camera_ops->recording_enabled = camera_recording_enabled;
            camera_ops->release_recording_frame = camera_release_recording_frame;
            camera_ops->auto_focus = camera_auto_focus;
            camera_ops->cancel_auto_focus = camera_cancel_auto_focus;
            camera_ops->take_picture = camera_take_picture;
            camera_ops->cancel_picture = camera_cancel_picture;
            camera_ops->set_parameters = camera_set_parameters;
            camera_ops->get_parameters = camera_get_parameters;
            camera_ops->put_parameters = camera_put_parameters;
            camera_ops->send_command = camera_send_command;
            camera_ops->release = camera_release;
            camera_ops->dump = camera_dump;
            *device = &camera_device->device.common;
            camera_device->cameraId = cameraid;
            camera = new android::CameraHardware(cameraid);
            if(!camera)
            {
                LOGE("Couldn't create instance of CameraHardware class!");
                rv = -ENOMEM;
                goto fail;
            }
            gCameraHals[cameraid] = camera;
            gCamerasOpen++;
        }
        return rv;
    fail:
        if(camera_device) {
            free(camera_device);
            camera_device = NULL;
        }
        if(camera_ops) {
            free(camera_ops);
            camera_ops = NULL;
        }
        if(camera) {
            delete camera;
            camera = NULL;
        }
        *device = NULL;
        return rv;
    }
这个函数里 封装了一系列 camera interface。 但是cameraservice 并没有用到这些接口,还是老的调用方式,直接调用了 camerahardware, 而没经过这里的接口。
只有
HAL_GetCameraInfo HAL_GetNumberOfCameras 通过这些接口来调用。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值