Android2.3.4 camera解析

来源:互联网 发布:ip地址端口号监控上网 编辑:程序博客网 时间:2024/06/08 11:09

一、Camera架构图

 

Android Camera的代码结构

AndroidCamera代码主要在以下的目录中:

CameraJAVA部分

packages/apps/Camera/。其中Camera.java是主要实现的文件。这部分内容编译成为目标是Camera.apk

com.android.camera这个包,几个主要的类文件如下:

PhotoViewerGalleryPicker.java(所有图片集)--->ImageGallery.java(某个Folder下图片列表)--->ViewImage.java(看某张具体图片)

VideoPlayerGalleryPicker.java(所有视频集) --->MovieView.java(看某一个视频)

CameraCamera.javaCamera取景及拍照)

VideoCameraVideoCamera.javaVideoCamera取景及摄像)

Cameraframework供上层应用调用的部分

base/core/java/android/hardware/Camera.java

这部分目标是framework.jar

CameraJNI部分

frameworks/base/core/jni/android_hardware_Camera.cpp

这部分内容编译成为目标是libandroid_runtime.so

Camera UI库部分

frameworks/base/libs/ui/camera

这部分的内容被编译成库libcamera_client.so

Camera服务部分

frameworks/base/camera/libcameraservice/

这部分内容被编译成库libcameraservice.so

Camera HAL层部分

hardware/msm7k/libcamera

vendor/qcom/android-open/libcamera2

为了实现一个具体功能的Camera,在HAL层需要一个硬件相关的Camera库(例如通过调用video for linux驱动程序和Jpeg编码程序实现或者直接用各个chip厂商实现的私有库来实现,比如Qualcomm实现的libcamera.solibqcamera.so),实现CameraHardwareInterface规定的接口,来调用相关的库,驱动相关的driver,实现对camera硬件的操作。这个库将被Camera的服务库libcameraservice.so调用。

 

 

二、注册camera服务

Init.rc  启动Main_MediaServer的主函数

 

service media /system/bin/mediaserver

    user media

    group systemaudio camera graphics inet net_bt net_bt_admin net_raw

    ioprio rt 4

 

Main_MediaServer.cpp main函数中初始化注册camera服务

 

intmain(int argc, char** argv)

{

    sp<ProcessState>proc(ProcessState::self());

    sp<IServiceManager> sm =defaultServiceManager();

    LOGI("ServiceManager: %p",sm.get());

    AudioFlinger::instantiate();

    MediaPlayerService::instantiate();

    CameraService::instantiate();

    AudioPolicyService::instantiate();

    ProcessState::self()->startThreadPool();

   IPCThreadState::self()->joinThreadPool();

}

 

 

在CameraService中找不到instantiate函数,需要到他的一个父类BinderService

àbinderService.h文件中

 

template<typename SERVICE>        //  这里SERVICE是指CameraService

class BinderService

{

public:

   static status_t publish() {

       sp<IServiceManager> sm(defaultServiceManager());

       return sm->addService(String16(SERVICE::getServiceName()), newSERVICE());

    }

 

   static void publishAndJoinThreadPool() {

       sp<ProcessState> proc(ProcessState::self());

       sp<IServiceManager> sm(defaultServiceManager());

       sm->addService(String16(SERVICE::getServiceName()), new SERVICE());

       ProcessState::self()->startThreadPool();

       IPCThreadState::self()->joinThreadPool();

    }

 

    static voidinstantiate() { publish(); }

 

   static status_t shutdown() {

       return NO_ERROR;

    }

};

 

此时服务注册添加完成。

 

 

三、camera client连接service过程

Package/app àCamera.java中的OnCreate()

 

将启动一个新线程

       Thread startPreviewThread = new Thread(new Runnable() {

           public void run() {

                try {

                    mStartPreviewFail = false;

                    startPreview();

                } catch(CameraHardwareException e) {

                    // In eng build, we throw theexception so that test tool

                    // can detect it and reportit

                    if("eng".equals(Build.TYPE)) {

                        throw newRuntimeException(e);

                    }

                    mStartPreviewFail = true;

                }

           }

       });

       startPreviewThread.start();

 

 

 

进入到

   private void startPreview() throws CameraHardwareException {

       if (mPausing || isFinishing()) return;

 

       ensureCameraDevice();

        … …

    }

 

进入到此函数

   private void ensureCameraDevice() throws CameraHardwareException {

       if (mCameraDevice == null) {

           mCameraDevice =CameraHolder.instance().open(mCameraId);

           mInitialParams = mCameraDevice.getParameters();

       }

    }

 

 

mCameraDevice是android.hardware.Camera类型,将调用framework  camera.java中的 open()方法。

 

   public static Camera open(int cameraId) {

       return new Camera(cameraId);

}

 

 

查看Camera构造函数

   Camera(int cameraId) {

       … …

       native_setup(new WeakReference<Camera>(this), cameraId);

    }

 

查看native_setup发现为

private native final voidnative_setup(Object camera_this, int cameraId);

需要通过JNI调用C++中的函数。

à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);

   …  …

   // We use a weak reference so the Camera object can be garbagecollected.

   // The reference is only used as a proxy for callbacks.

    sp<JNICameraContext> context = newJNICameraContext(env, weak_this, clazz, camera);

   context->incStrong(thiz);

   camera->setListener(context);

 

   // save context in opaque field

   env->SetIntField(thiz, fields.context, (int)context.get());

}

 

在JNI中客户端调用connect函数向server发送连接请求。JNICameraContext用于处理底层camera回调函数传来的数据和消息(它是一个监听类)。

 

---------------------------------------------------------------------------------------------------------------------------------

 

先看下client的connect函数

àFramework/camera.cpp

sp<Camera> Camera::connect(intcameraId)

{

   LOGV("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;

}

const sp<ICameraService>& cs =getCameraService();获取CameraService实例。

 

进入getCameraService()中

// establish binder interface to cameraservice

const sp<ICameraService>&Camera::getCameraService()

{

   Mutex::Autolock _l(mLock);

    ……

       mCameraService =interface_cast<ICameraService>(binder);

}

 

CameraService实例通过binder获取的,mCameraService即为CameraService的实例。

 

回到sp<Camera> Camera::connect(int cameraId)中

 

c->mCamera = cs->connect(c, cameraId);

即:执行server的connect()函数,并且返回ICamera对象,赋值给Camera的mCamera,服务端connect()返回的是他内部类的一个实例。

 

在framework/CameraService.cpp中

 

sp<ICamera> CameraService::connect(

       const sp<ICameraClient>& cameraClient, int cameraId) {

   int callingPid = getCallingPid();

   LOG1("CameraService::connect E (pid %d, id %d)", callingPid,cameraId);

 

    sp<CameraHardwareInterface> hardware = HAL_openCameraHardware(cameraId);

   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;

}

 

实例化Camera Hal接口 hardware,hardware调用initialize()进入HAL层打开Camear驱动。

 

代码如下:

àdevice\samsung\crespo\libcamera\SecCameraHWInterface.cpp

 

extern "C"sp<CameraHardwareInterface> HAL_openCameraHardware(int cameraId)

{

   return CameraHardwareSec::createInstance(cameraId);

}

然后调用

 

 

 

sp<CameraHardwareInterface> CameraHardwareSec::createInstance(intcameraId)

{

   LOGV("%s :", __func__);

   if (singleton != 0) {

       sp<CameraHardwareInterface> hardware = singleton.promote();

       if (hardware != 0) {

           return hardware;

       }

    }

    sp<CameraHardwareInterface> hardware(newCameraHardwareSec(cameraId));

   singleton = hardware;

   return hardware;

}

将进入

CameraHardwareSec::CameraHardwareSec(intcameraId)

:mCaptureInProgress(false),mParameters(),mPreviewHeap(0),mRawHeap(0),mRecordH  … …

{

    LOGV("%s :", __func__);

   int ret = 0;

…….

   mSecCamera = SecCamera::createInstance();

 

   if (mSecCamera == NULL) {

       LOGE("ERR(%s):Fail on mSecCamera object creation", __func__);

    }

 

    ret =mSecCamera->initCamera(cameraId);

   if (ret < 0) {

       LOGE("ERR(%s):Fail on mSecCamera init", __func__);

    }

         ……

}

 

int SecCamera::initCamera(int index)

{

   LOGV("%s :", __func__);

   int ret = 0;

… ...

   m_cam_fd = open(CAMERA_DEV_NAME, O_RDWR);

    ……

    return-1;

}

 

自此打开CAM驱动设备。

 


原创粉丝点击