学习Android camera笔记 & 调用流程

参考:http://blog.csdn.net/xingyu19871124/article/details/7750189
     http://blog.csdn.net/BonderWu/article/details/5814278
     http://blog.chinaunix.net/uid-2630593-id-3307176.html
     http://zhidao.baidu.com/question/388864295.html
     等

注:把本文内容复制到source insight中查看效果较好

    
    
     线程与进程:子进程和父进程有不同的代码和数据空间,而多个线程则共享数据空间,每个线程有自己的执行堆栈和程序计数器为其执行上下文。
    
     Handler与线程:  其实Handler并不是开辟新线程的概念,Android主要的考虑到更新界面的问题,一般情况下,更新界面(Activity)都是在主线程中更新的,
     这样就遇到了一个问题,比方说:在下载文件时候我们需要进度条显示下载进度,界面需要更新(数据是不断变的,也就是下载的大小是不断变的,要是直接
     在主线程中更新,就会造成程序的堵塞,程序很容易崩溃,通常这样联网耗时的工作需要开辟另外一个线程的,这样就不会影响主程序了),好了,到这里联
     网操作一般都需要开辟新线程了吧。
     接下来就来说Handler了,刚刚我说了Handler不是开辟新线程,在我看来,Handler更像是主线程的秘书,是一个触发器,负责管理从子线程中得到更新的数据,
     然后在主线程中更新界面。简单说下进度条的那个:  下载了多少的数据都是在子线程中得到的,在子线程中通过Handler的sendMessage()方法发送得到的下载
     的数据,当你调用了sendMessage方法后,Handler就会回调(也就是自动调用)Handler中的 HandlerMessage方法。

     启动线程:Android启动线程和JAVA一样有两种方式,一种是直接Thread类的start方法,也就是一般写一个自己的类来继承Thread    类。
     另外一种方式其实和这个差不多啊! 那就是Runnable接口,然后把Runnable的子类对象传递给Thread类再创建Thread对象.总之都是需要创建Thread对象,
     然后调用Thread类的start方法启动线程。区别就是,一个是直接创建Thread对象,另外一个是需要implement了Runnable接口对象作为创建Thread对象的参数.    
     Runnable其实我们称为线程任务。
      第一种方式一般是这样用:
        Class MyThread extends Thread{
              public void run(){
               //你要实现的代码
             }
        }
         在主线程中启动这个线程:
        public class Test{
            public static void main(String[] args){
                new MyThread().start();//启动了我们的线程了
            }
        }
        2,第二种方式一般是这样用:
        public class MyRunnable implements Runnable{
            public void run(){
                //你需要实现的代码
            }
        }
        在主线程中启动这个线程:
        public class Test{
            public static void main(String[] args){
                 Thread t=new Thread(new MyRunnable());//这里比第一种创建线程对象多了个任务对象
                 t.start();
            }
        }
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
cpp:
LOGD("dyyr - log %s, %s", __FILE__, __FUNCTION__);


打开camera/唤醒camera    大致流程途径源文件:

    Camera.java            onCreate()     log1
                        开启一个新线程,在此线程中open camera

                        mCameraOpenThread的run()
                                    log2
                        运行构造函数中的run()
                        是上述两种开启线程方法中的第一种

                        Then do something about rotation and else.
                        在onCreate()中以mCameraOpenThread.join();这句等待该线程完成它的任务
                        再开启预览线程mCameraPreviewThread.start();

                        mCameraPreviewThread的run()
                1872                    log14

                        startPreview()
                                    log14.5
                                    mCameraDevice是在log4的位置定义的,是log5返回的一个android.hardware.Camera对象
                                    (因为log5源文件第一句:package android.hardware;)
                                    这个对象的startPreview方法声明在log5下面。481行
                                    而它在log15定义。

                                    

                                    
    Util.java            openCamera() log3            

    CameraHolder.java        open()         log4
                                                
                                                Applications
---------------------------------------------------------------------------------------------------------------------------
    Camera.java            open()         log5
    
                                                   Framework
---------------------------------------------------------------------------------------------------------------------------
    android_hardware_camera.cpp    
        android_hardware_Camera_native_setup()
                                    log6

        android_hardware_Camera_startPreview()
                                    log15

    Camera.cpp        connect()         log7

                    startPreview()    log16

    CameraService.cpp connect()         log8        IServiceManager.cpp        ServiceManager.java(comfirmed)
                                    log8.1
                                    log8.2

                    Client()            log8.3~8.8
                        怎么到下面的log9?
                    
                    startPreview()    log17
                    startCameraMode() log18
                    startPreviewMode()log19
                                                         JNI
---------------------------------------------------------------------------------------------------------------------------
                                                             进入camera之前(开机时),camera初始化
                                                              CameraHardwareDevice.cpp         Initialize()   log'1
ALCameraFactory.cpp device_open()       log9 (name=0)          V4L2CameraDevice.cpp            Initialize()   log'2
                  cameraDeviceOpen()  log10

CameraHardware.cpp  connectCamera()        log11                  V4L2Camera.cpp                Initialize()   log'3

                    startPreview()    log20
                    doStartPreview()    log21

V4L2CameraDevice.cpp  connectDevice()    log12                  V4L2Camera.h                    WorkerThread()  log'4  上述两种开启线程方法中的第一种,但并没有run(),
                                                                                                        所以还没有真正开启线程,初始化了一个指针V4L2Camera* camera_dev
                    openCameraDev()    log13
在这个最终打开设备文件的函数中,open()得到文件描述符后,
用iotrl()函数做了一些配置然后返回了

PreviewWindow.cpp        startPreview()    log22
                    onNextFrameAvailableHW()    log23
                    通过perform向mPreviewWindow窗体发送消息

                    打开camera并开启预览的流程跟到这里。

camera.cfg
                                                         HAL
---------------------------------------------------------------------------------------------------------------------------
    gc0308.c
    Sys_config1.fex
                                                      Kernel
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
cpp:
LOGD("dyyr - log %s, %s", __FILE__, __FUNCTION__);


Camera.java    

    1117        public void onCreate(Bundle icicle) {            //打开

                ......

                mCameraOpenThread.start();                                //  1097

                ......

            }


    1097        Thread mCameraOpenThread = new Thread(new Runnable() {
                public void run() {
                    try {
                        mCameraDevice = Util.openCamera(Camera.this, mCameraId);        //Util.java    267
                    }

                    .......

                }
             }
             
    1532        protected void doOnResume() {                //唤醒

                ......
                
                Util.openCamera(this, mCameraId);                        //Util.java    267

                ......

            }



    1836        private void startPreview() {

                ......

                
                if (mCameraPreviewThread != null) {
                        synchronized (mCameraPreviewThread) {
                            mCameraPreviewThread.notify();                      //开启预览线程
                        }
                    }

                    ......

                    
            }


Util.java                        package/apps/.../camera

    267        CameraHolder.instance().open(cameraId);                




CameraHolder.java                    package/apps/.../camera

    131        android.hardware.Camera.open(cameraId);            //无法自动定位,frameworks/base/core/java/android/hardware/Camera.java        264    open()
    




                            packages/apps/camera/src/com/android/camera/         -------->    Camera.apk






                                                                                                    Applications
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------



Camera.java     frameworks/base/core/java/android/hardware/Camera.java                  -------->   framework.jar

    264        public static Camera open(int cameraId) {
                return new Camera(cameraId);
            }                                        //open函数是一个静态方法,构造一个Camera对象

    285        Camera(int cameraId) {                    //构造函数
            mShutterCallback = null;
            mRawImageCallback = null;
            mJpegCallback = null;
            mPreviewCallback = null;
            mPostviewCallback = null;
            mZoomListener = null;

            Looper looper;
            if ((looper = Looper.myLooper()) != null) {
                mEventHandler = new EventHandler(this, looper);
            } else if ((looper = Looper.getMainLooper()) != null) {
                mEventHandler = new EventHandler(this, looper);
            } else {
                mEventHandler = null;
            }

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


    310        private native final void native_setup(Object camera_this, int cameraId);        其对应于android_hardware_Camera.cpp的android_hardware_Camera_native_setup方法,为什么????
                                                                                    貌似是有函数会去按照camMethods数组匹配



                                                                                                    Frameworks
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


android_hardware_camera.cpp            frameworks/base/core/jni

    458        // 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);            //无法自动定位.  Camera.cpp 128
                                                                    //Camera C/S架构的客户端调用connect函数向服务器发送连接请求,
                                                                    //这个Camera类的声明在Camera.h (android4.0\frameworks\base\include\camera)

                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.cpp        frameworks/base/libs/camera

    128        sp<Camera> Camera::connect(int cameraId)
            {
                LOGV("connect");
                sp<Camera> c = new Camera();
                const sp<ICameraService>& cs = getCameraService();            //获取一个Camera服务实例,本源文件40行
                if (cs != 0) {
                    c->mCamera = cs->connect(c, cameraId);                    //然后执行服务端的connect()函数,并返回一个ICamera对象赋值给Camera 的mCamera,
                                                                       //CameraService.cpp    185~254
                }
                if (c->mCamera != 0) {
                    c->mCamera->asBinder()->linkToDeath(c);
                    c->mStatus = NO_ERROR;
                } else {
                    c.clear();
                }
                return c;
            }

    
    40    // establish binder interface to camera service
        const sp<ICameraService>& Camera::getCameraService()
        {
            Mutex::Autolock _l(mLock);
            if (mCameraService.get() == 0) {
                sp<IServiceManager> sm = defaultServiceManager();                    //无法自动定位,调用的是IServiceManager.cpp(frameworks/base/libs/binder)    34
                sp<IBinder> binder;
                do {
                    binder = sm->getService(String16("media.camera"));            //无法自动定位,搜索符号getService,定位到ServiceManager.java   49
                    if (binder != 0)
                        break;
                    LOGW("CameraService not published, waiting...");
                    usleep(500000); // 0.5 s
                } while(true);
                if (mDeathNotifier == NULL) {
                    mDeathNotifier = new DeathNotifier();
                }
                binder->linkToDeath(mDeathNotifier);
                mCameraService = interface_cast<ICameraService>(binder);    //mCameraService是一个ICamerService类型,
                                                                        //更加具体具体一点来讲应该是BpCameraService,因为在这个类中实现了ICameraService的方法。
            }
            LOGE_IF(mCameraService==0, "no CameraService!?");
            return mCameraService;
        }


IServiceManager.cpp        frameworks/base/libs/binder

    34        sp<IServiceManager> defaultServiceManager()
            {
                if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
                
                {
                    AutoMutex _l(gDefaultServiceManagerLock);
                    if (gDefaultServiceManager == NULL) {
                        gDefaultServiceManager = interface_cast<IServiceManager>(   //得到上面要的sm,它的类型是"sp<IServiceManager>",
                                                                                 //sp<T>是android的智能指针,它持有一个T类实例,并负责在必要时释放此实例
                            ProcessState::self()->getContextObject(NULL));
                    }
                }
                
                return gDefaultServiceManager;
            }


我们有必要关注一下interface_cast,通过代码跟踪:看到它的实现
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
通过模板替换就是:
inline sp< IServiceManager > interface_cast(const sp<IBinder>& obj)
{
return IServiceManager::asInterface(obj);
}
看来asInterface是IServiceManager的一个成员函数,我们打开IServiceManager.cpp/
h文件,我们并没有发现该函数,那它到底在哪儿呢,仔细观察IServiceManager.cpp
,发现里面有个IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
在IServiceManager.h里面发现了DECLARE_META_INTERFACE(ServiceManager);
通过跟踪这两个宏发现DECLARE_META_INTERFACE声明了一个变量和两个函数...
interface_cast<IServiceManager>实际上返回了一个BpServiceManager,在创建一个BpServiceManager时,有些细节还是需要注意:...




ServiceManager.java        frameworks/base/core/java/android/os

    49    public static IBinder getService(String name) {
                Log.d(TAG, "dyyr - getService");
            try {
                IBinder service = sCache.get(name);          //sCache是个Hashmap<String,IBinder>,用参数name:"media.camera"get这个IBinder,
                                                            //那么,这个media.camera是源代码里配置好的还是开机后添加进去的?何时添加的?
                if (service != null) {
                    return service;
                } else {
                    return getIServiceManager().getService(name);
                }
            } catch (RemoteException e) {
                Log.e(TAG, "error in getService", e);
            }
            return null;
        }



CameraService.cpp            frameworks/base/services/camera/libcameraservice

    185        sp<ICamera> CameraService::connect(                                //服务端connect()
                    const sp<ICameraClient>& cameraClient, int cameraId) {
                LOGE("dyyr - CameraService.cpp connect");
                int callingPid = getCallingPid();
                sp<CameraHardwareInterface> hardware = NULL;                    //先实例化Camera Hal接口 hardware,
                    ......


    246            if (hardware->initialize(&mModule->common) != OK) {            //hardware调用initialize()进入HAL层打开Camear驱动, CameraHardwareDevice.cpp    52
                    hardware.clear();
                    return NULL;
                }

                client = new Client(this, cameraClient, hardware, cameraId, info.facing,
            callingPid);

                mClient[cameraId] = client;
                LOG1("CameraService::connect X");
                return client;                                            //返回的其实是它内部类client的一个实例。
            }
            


//Camera系统使用的是Server-Client机制,Service和Client位于不同的进程中,进程间使用Binder机制进行通信,
//Service端实际实现相机相关的操作,Client端通过Binder接口调用Service对应的操作。
//如下图所示


android_hardware_camera.cpp            fremework/base/core/jni                        -------->    libandroid_runtime.so                
                                                                                                    
                                                                                                    |
                                                                                                    |
                                                                                              ------    | --------------------------
                                                                                             |     ---------         ---------      |
                                                                                             |    |  Client |        | Service |-----------Binder IPC---------            
                                                                                             |     ---------         ---------      |                          |     
                                                                                             |            libui.so                  |                          |
                                                                                              -----------------------------------                          |
                                                                                                                                                ------
                                                                                                                                                |
    Camera服务                                                                                                                                    |
CameraService.cpp等                 frameworks/base/camera/libcameraservice/            -------->     libcameraservice.so  <------------------------------------


        (    UI 库               frameworks/base/libs/ui/camera                        -------->            libcamera_client.so        )






                                                                                            JNI
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


CameraHardwareDevice.cpp        device/softwinner/common/hardware/camera/

    52        status_t CameraHardwareDevice::Initialize()
            {
                F_LOG;

                // instance V4L2CameraDevice object
                mV4L2CameraDevice = new V4L2CameraDevice(this, mCameraID);
                if (mV4L2CameraDevice == NULL)
                {
                    LOGE("Failed to create V4L2Camera instance");
                    return NO_MEMORY;
                }
                
                status_t res = mV4L2CameraDevice->Initialize();            //V4L2CameraDevice.cpp     71

                ......

            }
                

V4L2CameraDevice.cpp        device/softwinner/common/hardware/camera/

    71        status_t V4L2CameraDevice::Initialize()
            {
                F_LOG;

                return V4L2Camera::Initialize();            //V4L2Camera.cpp        66
            }


V4L2Camera.cpp        device/softwinner/common/hardware/camera/

    66        status_t V4L2Camera::Initialize()
            {
                LOGE("dyyr - %s, %s", __FILE__, __FUNCTION__);
                F_LOG;
                if (isInitialized()) {
                    LOGW("%s: V4L2Camera device is already initialized: mState = %d",
                         __FUNCTION__, mState);
                    return NO_ERROR;
                }

                /* Instantiate worker thread object. */
                mWorkerThread = new WorkerThread(this);                                    //V4L2Camera.h    325
                if (getWorkerThread() == NULL) {
                    LOGE("%s: Unable to instantiate worker thread object", __FUNCTION__);
                    return ENOMEM;
                }

                mState = ECDS_INITIALIZED;

                return NO_ERROR;
            }


V4L2Camera.h        device/softwinner/common/hardware/camera/

    325        inline explicit WorkerThread(V4L2Camera* camera_dev)
                : Thread(true),   // Callbacks may involve Java calls.                //顶层打开/唤醒Camera的流程跟到这里---------------------------未完待续
                  mCameraDevice(camera_dev),
                  mThreadControl(-1),
                  mControlFD(-1)
            {
            }

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


下面是camera的HAL层open底层驱动的方法,没有使用传统的这一句:module->methods->open(module, mName.string(),(hw_device_t **)&mDevice),而走的是V4L2途径:


HALCameraFactory.cpp        device/softwinner/common/hardware/camera/

    201        struct hw_module_methods_t HALCameraFactory::mCameraModuleMethods = {
                open: HALCameraFactory::device_open                                            //    160
            };


    160        int HALCameraFactory::device_open(const hw_module_t* module,
                                                   const char* name,
                                                   hw_device_t** device)
            {
                F_LOG;
                /*
                 * Simply verify the parameters, and dispatch the call inside the            //只需确定参数,并调用HALCamera 实例.
                 * HALCameraFactory instance.
                 */


                ......
                

                return gEmulatedCameraFactory.cameraDeviceOpen(atoi(name), device);            //    118
            }


    118        int HALCameraFactory::cameraDeviceOpen(int camera_id, hw_device_t** device)
            {
                LOGV("%s: id = %d", __FUNCTION__, camera_id);

                ......
                

                return mHardwareCameras[camera_id]->connectCamera(device);            //CameraHardware.cpp        435
            }



CameraHardware.cpp        device/softwinner/common/hardware/camera/

    435        status_t CameraHardware::connectCamera(hw_device_t** device)
            {

            
                ......


                if (camera_dev != NULL) {
                    /* Connect to the camera device. */
                    res = getCameraDevice()->connectDevice();                    //V4L2CameraDevice        83
                    if (res == NO_ERROR) {
                        *device = &common;
                    }
                }

                return -res;
            }



V4L2CameraDevice.cpp        device/softwinner/common/hardware/camera/

    83        status_t V4L2CameraDevice::connectDevice()
            {


                ......


                // open v4l2 camera device
                int ret = openCameraDev();                                                    //448
                if (ret != OK)
                {
                    return ret;
                }

                ret = cedarx_hardware_init(2);// CEDARX_HARDWARE_MODE_VIDEO

                ......

                
            }


    448        int V4L2CameraDevice::openCameraDev()
            {
                // open V4L2 device
                Log.d(TAG, "dyyr - " + __FILE__ + ", " + __FUNCTION__);
                mCamFd = open(mDeviceName, O_RDWR | O_NONBLOCK, 0);                            //至此完成打开底层设备全过程
                if (mCamFd == -1)
                {
                    LOGE("ERROR opening V4L interface: %s", strerror(errno));
                    return -1;
                }

                struct v4l2_input inp;
                inp.index = mDeviceID;
                if (-1 == ioctl (mCamFd, VIDIOC_S_INPUT, &inp))
                {
                    LOGE("VIDIOC_S_INPUT error!\n");
                    return -1;
                }

                ......


            }

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



HAL层的配置文件camera.cfg            device/softwinner/Dimond_97HD/camera.cfg,          读取配置:  CCameraConfig.cpp,  xxx()

下面是读取配置信息的一个例子:

CameraHardware.cpp            device/softwinner/common/hardware/camera/

    105        status_t CameraHardware::Initialize()
            {
                F_LOG;

                if (mCameraConfig == NULL)
                {
                    return UNKNOWN_ERROR;
                }

                initDefaultParameters();                //145

                return NO_ERROR;
            }


    145        void CameraHardware::initDefaultParameters()
            {
            

                ......


                if (mCameraConfig->cameraFacing() == CAMERA_FACING_BACK)                            //根据配置信息设置XX
                {
                    p.set(CameraHardware::FACING_KEY, CameraHardware::FACING_BACK);
                    LOGV("%s: camera is facing %s", __FUNCTION__, CameraHardware::FACING_BACK
            );

                }
                else
                {
                    p.set(CameraHardware::FACING_KEY, CameraHardware::FACING_FRONT);
                    LOGV("%s: camera is facing %s", __FUNCTION__, CameraHardware::
            FACING_FRONT);

                }
                
                p.set(CameraHardware::ORIENTATION_KEY, 0);


                ......


            }






                                                                                                    HAL
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------



gc0308.c                        drivers/media/video/sun4i_csi/device/gc0308.c






配置文件Sys_config1.fex        Tools/pack/Chips/Sun4i/Configs/Crane/Dimod/Sys_config1.fex,  读取函数:        ????????




                                                                                                    Kernel
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


posted @ 2012-12-04 16:44  勒达与天鹅  阅读(7499)  评论(1编辑  收藏  举报