高通camera架构 (二)

原创 2012年03月28日 11:23:55

2、android_hardware_Camera_getCameraInfo(JNI)

static void android_hardware_Camera_getCameraInfo(JNIEnv *env, jobject thiz,
    jint cameraId, jobject info_obj)
{
    CameraInfo cameraInfo;
    status_t rc = Camera::getCameraInfo(cameraId, &cameraInfo);

    if (rc != NO_ERROR) {
        jniThrowException(env, "java/lang/RuntimeException",
                          "Fail to get camera info");
        return;
    }
    env->SetIntField(info_obj, fields.facing, cameraInfo.facing);
    env->SetIntField(info_obj, fields.mode, cameraInfo.mode);
    env->SetIntField(info_obj, fields.orientation, cameraInfo.orientation);
}

此处getCameraInfo调到/framework/base/libs/camera/camera.cpp 中接口。

status_t Camera::getCameraInfo(int cameraId,
                               struct CameraInfo* cameraInfo) {
    const sp<ICameraService>& cs = getCameraService();
    if (cs == 0) return UNKNOWN_ERROR;
    return cs->getCameraInfo(cameraId, cameraInfo);
}

此处调用到/framework/base/service/camera/libcameraservice/cameraservice.cpp中接口。

status_t CameraService::getCameraInfo(int cameraId,
                                      struct CameraInfo* cameraInfo) {
    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
        return BAD_VALUE;
    }

    HAL_getCameraInfo(cameraId, cameraInfo);
    return OK;
}

HAL_getCameraInfo函数,调用\vendor\qcom\android-open\libcamera2\QualcommCameraHardware.cpp中的接口。

 

extern "C" void HAL_getCameraInfo(int cameraId, struct CameraInfo* cameraInfo)
{
    int i;
    char mDeviceName[PROPERTY_VALUE_MAX];
    if(cameraInfo == NULL) {
        LOGE("cameraInfo is NULL");
        return;
    }

    property_get("ro.product.device",mDeviceName," "); //获取系统属性

    for(i = 0; i < HAL_numOfCameras; i++) {
        if(i == cameraId) {
            LOGI("Found a matching camera info for ID %d", cameraId);
            cameraInfo->facing = (HAL_cameraInfo[i].position == BACK_CAMERA)?
                                   CAMERA_FACING_BACK : CAMERA_FACING_FRONT;
            // App Orientation not needed for 7x27 , sensor mount angle 0 is
            // enough.
            if(cameraInfo->facing == CAMERA_FACING_FRONT)
                cameraInfo->orientation = HAL_cameraInfo[i].sensor_mount_angle;
            else if( !strncmp(mDeviceName, "msm7625a", 8))
                cameraInfo->orientation = HAL_cameraInfo[i].sensor_mount_angle;
            else if( !strncmp(mDeviceName, "msm7627a", 8))
                cameraInfo->orientation = HAL_cameraInfo[i].sensor_mount_angle;
            else if( !strncmp(mDeviceName, "msm7627", 7))
                cameraInfo->orientation = HAL_cameraInfo[i].sensor_mount_angle;
            else if( !strncmp(mDeviceName, "msm8660", 7))
                cameraInfo->orientation = HAL_cameraInfo[i].sensor_mount_angle;
            else
                cameraInfo->orientation = ((APP_ORIENTATION - HAL_cameraInfo[i].sensor_mount_angle) + 360)%360;

            LOGI("%s: orientation = %d", __FUNCTION__, cameraInfo->orientation);
            cameraInfo->mode = 0;
            if(HAL_cameraInfo[i].modes_supported & CAMERA_MODE_2D)
                cameraInfo->mode |= CAMERA_SUPPORT_MODE_2D;
            if(HAL_cameraInfo[i].modes_supported & CAMERA_MODE_3D)
                cameraInfo->mode |= CAMERA_SUPPORT_MODE_3D;
            if((HAL_cameraInfo[i].position == BACK_CAMERA )&&
                !strncmp(mDeviceName, "msm8660", 7)){
                cameraInfo->mode |= CAMERA_ZSL_MODE;
            } else{
                cameraInfo->mode |= CAMERA_NONZSL_MODE;
            }

            LOGI("%s: modes supported = %d", __FUNCTION__, cameraInfo->mode);

            return;
        }
    }
    LOGE("Unable to find matching camera info for ID %d", cameraId);
}

}; // namespace android

在这里,应为前面在获取camera number时已经获得了HAL_cameraInfo相关信息,所以这里只是做了一些相关的配置。

===============================================================================================================

三 android_hardware_Camera_native_setup(JNI)

static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
    jobject weak_this, jint cameraId, jint mode)
{
    sp<Camera> camera = Camera::connect(cameraId, mode);

    if (camera == NULL) {
        jniThrowException(env, "java/lang/RuntimeException",
                          "Fail to connect to camera service");
        return;
    }

    // make sure camera hardware is alive
    if (camera->getStatus() != NO_ERROR) {
        jniThrowException(env, "java/lang/RuntimeException", "Camera initialization failed");
        return;
    }

    jclass clazz = env->GetObjectClass(thiz);
    if (clazz == NULL) {
        jniThrowException(env, "java/lang/RuntimeException", "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());
}

接下来我们看看connect 和 getstatus做了些什么。代码路径同上 

sp<Camera> Camera::connect(int cameraId, int mode)
{
    LOGV("connect");
    sp<Camera> c = new Camera();
    const sp<ICameraService>& cs = getCameraService();
    if (cs != 0) {
        c->mCamera = cs->connect(c, cameraId, mode);
    }
    if (c->mCamera != 0) {
        c->mCamera->asBinder()->linkToDeath(c);
        c->mStatus = NO_ERROR;
    } else {
        c.clear();
    }
    return c;
}

sp<ICamera> CameraService::connect(
        const sp<ICameraClient>& cameraClient, int cameraId, int mode) {
    int callingPid = getCallingPid();
    LOG1("CameraService::connect E (pid %d, id %d mode %d)", callingPid, cameraId, mode);

    sp<Client> client;
    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
        LOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
            callingPid, cameraId);
        return NULL;
    }

    Mutex::Autolock lock(mServiceLock);
    if (mClient[cameraId] != 0) {
        client = mClient[cameraId].promote();
        if (client != 0) {
            if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
                LOG1("CameraService::connect X (pid %d) (the same client)",
                    callingPid);
                return client;
            } else {
                LOGW("CameraService::connect X (pid %d) rejected (existing client).",
                    callingPid);
                return NULL;
            }
        }
        mClient[cameraId].clear();
    }

    if (mBusy[cameraId]) {
        LOGW("CameraService::connect X (pid %d) rejected"
             " (camera %d is still busy).", callingPid, cameraId);
        return NULL;
    }

    sp<CameraHardwareInterface> hardware = HAL_openCameraHardware(cameraId, mode);
    if (hardware == NULL) {
        LOGE("Fail to open camera hardware (id=%d)", cameraId);
        return NULL;
    }
    CameraInfo info;
    HAL_getCameraInfo(cameraId, &info);
    client = new Client(this, cameraClient, hardware, cameraId, info.facing,
                        callingPid);
    mClient[cameraId] = client;
    LOG1("CameraService::connect X");
    return client;
}

\vendor\qcom\android-open\libcamera2\QualcommCameraHardware.cpp

extern "C" sp<CameraHardwareInterface> HAL_openCameraHardware(int cameraId, int mode)
{
    int i;
    LOGI("openCameraHardware: call createInstance");
    for(i = 0; i < HAL_numOfCameras; i++) {
        if(HAL_cameraInfo[i].camera_id == cameraId) {
            LOGI("openCameraHardware:Valid camera ID %d", cameraId);
            LOGI("openCameraHardware:camera mode %d", mode);
            parameter_string_initialized = false;
            HAL_currentCameraId = cameraId;
            HAL_currentCameraMode = CAMERA_MODE_2D;
            /* The least significant two bits of mode parameter indicates the sensor mode
               of 2D or 3D. The next two bits indicates the snapshot mode of
               ZSL or NONZSL
               */
            int sensorModeMask = 0x03 & mode;
            if(sensorModeMask & HAL_cameraInfo[i].modes_supported){
                HAL_currentCameraMode = sensorModeMask;
            }else{
                LOGE("openCameraHardware:Invalid camera mode (%d) requested", mode);
                return NULL;
            }
            HAL_currentSnapshotMode = CAMERA_SNAPSHOT_NONZSL;
            //Remove values set by app other than  supported values
            mode = mode & HAL_cameraInfo[cameraId].modes_supported;
            if((mode & CAMERA_SNAPSHOT_ZSL) == CAMERA_SNAPSHOT_ZSL)
                HAL_currentSnapshotMode = CAMERA_SNAPSHOT_ZSL;
            LOGI("%s: HAL_currentSnapshotMode = %d", __FUNCTION__, HAL_currentSnapshotMode);

            return QualcommCameraHardware::createInstance(); //重点在这句
        }
    }
    LOGE("openCameraHardware:Invalid camera ID %d", cameraId);
    return NULL;
}

sp<CameraHardwareInterface> QualcommCameraHardware::createInstance() // 创建一个实例对象,如果硬件已经存在,则还回当前对象的指针,如果没有,

                                                     //则创建一个硬件对象,并还回。
{
    LOGI("createInstance: E");

    singleton_lock.lock();

    // Wait until the previous release is done.
    while (singleton_releasing) {
        if((singleton_releasing_start_time != 0) &&
                (systemTime() - singleton_releasing_start_time) > SINGLETON_RELEASING_WAIT_TIME){
            LOGV("in createinstance system time is %lld %lld %lld ",
                    systemTime(), singleton_releasing_start_time, SINGLETON_RELEASING_WAIT_TIME);
            singleton_lock.unlock();
            LOGE("Previous singleton is busy and time out exceeded. Returning null");
            return NULL;
        }
        LOGI("Wait for previous release.");
        singleton_wait.waitRelative(singleton_lock, SINGLETON_RELEASING_RECHECK_TIMEOUT);
        LOGI("out of Wait for previous release.");
    }

    if (singleton != 0) {
        sp<CameraHardwareInterface> hardware = singleton.promote();
        if (hardware != 0) {
            LOGD("createInstance: X return existing hardware=%p", &(*hardware));
            singleton_lock.unlock();
            return hardware;
        }
    }

    {
        struct stat st;
        int rc = stat("/dev/oncrpc", &st);
        if (rc < 0) {
            LOGD("createInstance: X failed to create hardware: %s", strerror(errno));
            singleton_lock.unlock();
            return NULL;
        }
    }

    QualcommCameraHardware *cam = new QualcommCameraHardware();
    sp<QualcommCameraHardware> hardware(cam);
    singleton = hardware;

    LOGI("createInstance: created hardware=%p", &(*hardware));
    if (!cam->startCamera()) {
        LOGE("%s: startCamera failed!", __FUNCTION__);
        singleton_lock.unlock();
        return NULL;
    }

    cam->initDefaultParameters();
    singleton_lock.unlock();
    LOGI("createInstance: X");
    return hardware;
}


Android获得摄像头详细信息

Android获取摄像头详细信息 2011-01-05 10:15:26 来源:WEB开发网 【减小字体增大字体 】  关注杨恒飞的微博核心提示: 如何获取Android设备上的详细的摄像头信息呢...
  • raindrophust
  • raindrophust
  • 2011年02月24日 16:18
  • 10755

Camera安卓源码-高通mm_camera架构剖析

主要涉及三方面: 1. Camera open 2. Camera preview 3. Camera capture1. Camera Open mm_camera&mm_camera_o...
  • hbw1992322
  • hbw1992322
  • 2017年07月18日 14:01
  • 878

高通camera框架_流程浅析(1)

框架简介: 理解新事物总是需要一定的时间和过程,正如理解高通camera架构一样,最近一周由于需要从App下载参数到linux内核,才得以对camera框架有了进一步的了解,就好像上班一样,一波三折...
  • liwei16611
  • liwei16611
  • 2016年03月04日 16:25
  • 9272

高通camera架构讲解

转自:http://www.cnblogs.com/thjfk/p/4086001.html   Camera原理:外部光线穿过lens后,经过color filter滤波后照射到senso...
  • jhyworkspace
  • jhyworkspace
  • 2017年04月03日 16:33
  • 2133

高通camera框架之如何打通App-Hardware经络

许久未更新博客,今天再次重磅推出鄙人的浅显的一些总结,以供参考,该文主要是基于camera一个小功能来详细讲解java层接口如何步步调用至hardware层接口,涉及到一些机制的简单介绍,希望可以为您...
  • liwei16611
  • liwei16611
  • 2016年08月14日 22:24
  • 2699

Android Camera架构浅析 && Qualcomm 8X camera daemon进程浅析

转自:http://www.cokco.cn/thread-7779-1-1.html Camera 先看一下抽象层的主要流程: 首先启动一个守护进程 Main()(cam...
  • richu123
  • richu123
  • 2016年06月30日 19:14
  • 1045

Qualcomm Camera基础

高通将android的camera模块重新修改了一下,与原生的方式存在一些差异。这里将前段时间学习的一些零散知识进行一下总结,便于以后查阅。 1.整个模块主要巡行三个主线程:control、conf...
  • qq69696698
  • qq69696698
  • 2012年03月27日 16:54
  • 18484

高通camera vendor层logic

目录 3 1. Introduction 4 2. 高通Camera架构之模块简介 5 2.1 定义Camera模块结构 6 2.2 Camera模块代码结构 6 3. ISP模块 ...
  • liwei16611
  • liwei16611
  • 2017年02月03日 19:05
  • 2383

高通平台Camera框架部分浅谈--Camera C/S 的init流程

Android 高通平台 Camera C/S init 流程
  • Mr_ZJC
  • Mr_ZJC
  • 2015年11月01日 18:11
  • 2216

浅析Android Camera架构

本博文是基于Android 4.4讲解   1、application 层:                当我们Android工程师想打开camera时通常直接调用Camera.java中的  Ca...
  • jingzailongxin
  • jingzailongxin
  • 2016年08月23日 12:01
  • 2679
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:高通camera架构 (二)
举报原因:
原因补充:

(最多只允许输入30个字)