Android4.2.2 CameraService Service Startup and application-side camera initialization records

Source: Internet
Author: User

The first 10 blog posts mainly record the related content of SurfaceFlinger of Android4.2.2. The reason why we invested so much time is that when we looked at the camera architecture, encountered ANativeWindow and Surface content. These are the most common application-end supplies in SurfaceFlinger. So after learning SurfaceFlinger, let's take a look at the architecture of Camera. Here we will first share with you the startup process and architecture of CameraService of android4.2.2.

1. Where does cameraService start?

Mediaserver starts our cameraservice, the so-called multimedia-related service manager.

Int main (int argc, char ** argv) {signal (SIGPIPE, SIG_IGN); sp
 
  
Proc (ProcessState: self (); sp
  
   
Sm = defaservicservicemanager (); ALOGI ("ServiceManager: % p", sm. get (); AudioFlinger: instantiate (); // Multimedia Service Startup includes audio, camera, and other MediaPlayerService: instantiate (); CameraService: instantiate (); AudioPolicyService :: instantiate (); ProcessState: self ()-> startThreadPool (); IPCThreadState: self ()-> joinThreadPool ();}
  
 

Previous articles mentioned the General Service Startup method. Here is a typical BinderService startup method.

Class BinderService {public: static status_t publish (bool allowIsolated = false) {sp
 
  
Sm (defaservicservicemanager (); return sm-> addService (String16 (SERVICE: getServiceName (), new SERVICE (), allowIsolated );} static void publishAndJoinThreadPool (bool allowIsolated = false) {sp
  
   
Sm (defaservicservicemanager (); sm-> addService (String16 (SERVICE: getServiceName (), new SERVICE (), allowIsolated); ProcessState: self () -> startThreadPool (); IPCThreadState: self ()-> joinThreadPool ();} static void instantiate () {publish ();} // two methods for initializing the binder service: static status_t shutdown () {return NO_ERROR ;}};
  
 

CameraService: CameraService (): mSoundRef (0), mModule (0) {ALOGI ("CameraService started (pid = % d)", getpid (); gCameraService = this ;} void CameraService: onFirstRef () // camerservice is called after sp is generated {BnCameraService: onFirstRef (); if (hw_get_module (partition, (const hw_module_t **) & mModule) <0) {// obtain and load the mModule variable. The actual hardware library of the hal layer is camera. fiber. so, loaded the module ALOGE ("cocould not load camera HAL module"); mNumberOfCameras = 0;} else {mNumberOfCameras = mModule-> get_number_of_cameras (); // obtain the Number of camera via hal if (mNumberOfCameras> MAX_CAMERAS) {ALOGE ("Number of cameras (% d)> MAX_CAMERAS (% d ). ", mNumberOfCameras, MAX_CAMERAS); mNumberOfCameras = MAX_CAMERAS;} for (int I = 0; I <mNumberOfCameras; I ++) {setCameraFree (I );}}}

After the constructor of CameraService is called, onFirstRef () is automatically executed. The Hal layer of Camera is implemented in this function.

Use hw_get_module () to obtain the module handle for loading the HAL layer to the mModule member variable, and obtain the number of hardware Camera to mNumberOfCameras. We can see that CameraService is much simpler than SurfaceFinger's powerful service.

Step 3: Create a camera Client

The new Camera () of the java layer comes to the JNI layer, which goes through camera. java and then to android_hardware_Camera.cpp of the local JNI.

Execution of the camera. open () function in Camera. java

   public static Camera open(int cameraId) {        return new Camera(cameraId);    }    /**     * Creates a new Camera object to access the first back-facing camera on the     * device. If the device does not have a back-facing camera, this returns     * null.     * @see #open(int)     */    public static Camera open() {        int numberOfCameras = getNumberOfCameras();        CameraInfo cameraInfo = new CameraInfo();        for (int i = 0; i < numberOfCameras; i++) {            getCameraInfo(i, cameraInfo);            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {                return new Camera(i);            }        }        return null;    }

Classes in Camera

    Camera(int cameraId) {        mShutterCallback = null;        mRawImageCallback = null;        mJpegCallback = null;        mPreviewCallback = null;        mPostviewCallback = null;        mZoomListener = null;        Looper looper;        if ((looper = Looper.myLooper()) != null) {.....        native_setup(new WeakReference
 
  (this), cameraId);    }
 

In android_hardware_camera.cpp of the jni layer:

// Connect to camera servicestatic void android_hardware_Camera_native_setup (JNIEnv * env, jobject thiz, jobject weak_this, jint cameraId) {sp
 
  
Camera = Camera: connect (cameraId); // call the connect function of 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 ;}......}
 

The connect function of the Camera application layer is called to request CameraService to create a new Camera client.

Step 4: connect function of the camera Client

Sp
 
  
Camera: connect (int cameraId) {ALOGV ("connect"); sp
  
   
C = new Camera (); // BnCameraClient const sp
   
    
& Cs = getCameraService (); // obtain a Bpcamerservice if (cs! = 0) {c-> mCamera = cs-> connect (c, cameraId); // Based on the binder driver, connect on the camerservice side will be called, mCamera points to a Bpcamera} if (c-> mCamera! = 0) {c-> mCamera-> asBinder ()-> linkToDeath (c); c-> mStatus = NO_ERROR;} else {c. clear () ;}return c ;}
   
  
 

Create an application-side Camera. The class Camera: public BnCameraClient, public IBinder: DeathRecipient inheritance relationships are as follows.

Cs = getCameraService () obtains a local proxy of CameraService through SM. Call the connect function and call the connect () function on the CameraService side.

Virtual sp
 
  
Connect (const sp
  
   
& CameraClient, int cameraId) {Parcel data, reply; data. writeInterfaceToken (ICameraService: getInterfaceDescriptor (); data. writeStrongBinder (cameraClient-> asBinder (); data. writeInt32 (cameraId); // The data packet sent to the server remote ()-> transact (BnCameraService: CONNECT, data, & reply); // The transaction return interface_cast of Bpbinder is actually called
   
    
(Reply. readStrongBinder (); // The handle value of the incoming Bpbinder returns a new BpCamera, which is actually the server's Bncamera }};
   
  
 

Here we can see that a local Camera Class Object (new Camera () is passed in. This anonymous binder object will be passed to CameraService through the Binder driver. It is mainly used for subsequent callback of CameraService to the Camera at the application layer for processing.

Step 5: connect function on CameraSevice

Sp
 
  
CameraService: connect (const sp
  
   
& CameraClient, int cameraId) {int callingPid = getCallingPid (); LOG1 ("CameraService: connect E (pid % d, id % d)", callingPid, cameraId ); if (! MModule) {ALOGE ("Camera HAL module not loaded"); return NULL;} sp
   
    
Client; if (cameraId <0 | cameraId> = mNumberOfCameras) {ALOGE ("CameraService: connect X (pid % d) rejected (invalid cameraId % d ). ", callingPid, cameraId); return NULL;} char value [PROPERTY_VALUE_MAX]; property_get (" sys. secpolicy. camera. disabled ", value," 0 "); if (strcmp (value," 1 ") = 0) {// Camera is disabled by DevicePolicyManager. ALOGI ("Camera is disabled. connect X (pid % d) rejected ", cal LingPid); 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 {ALOGW (" CameraService: connect X (pid % d) rejected (existing client ). ", callingPid); return NULL ;}} mClient [cameraId]. clear ();} if (mBusy [cameraId]) {ALOGW ("CameraService: connect X (pid % d) rejected" "(camera % d is stil L busy). ", callingPid, cameraId); return NULL;} struct camera_info info; if (mModule-> get_camera_info (cameraId, & info )! = OK) {// obtain information about camera ALOGE ("Invalid camera id % d", cameraId); return NULL;} int deviceVersion; if (mModule-> common. module_api_version = CAMERA_MODULE_API_VERSION_2_0) {deviceVersion = info. device_version;} else {deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;} switch (deviceVersion) {case when: client = new CameraClient (this, cameraClient, cameraId, info. facing, call IngPid, getpid (); // client is the base class of CameraClient, and a camerservice-side cameraclient break is created; case when: client = new Camera2Client (this, cameraClient, cameraId, info. facing, callingPid, getpid (); break; default: ALOGE ("Unknown camera device HAL version: % d", deviceVersion); return NULL ;} if (client-> initialize (mModule )! = OK) {// cameraclient init initialization. The actual call is CameraClient return NULL;} cameraClient-> asBinder ()-> linkToDeath (this); mClient [cameraId] = client; // new LOG1 ("CameraService: connect X (id % d, this pid is % d)", cameraId, getpid (); return client; // return CameraClient}
   
  
 

This function is analyzed in the following processes:

A. sp Client; a client class inside CameraService

First, check the number of camera clients maintained by the current server. mClient [cameraId]! = 0. The initial start time is 0.

B. obtain the information of the underlying camera module get_camera_info. Check whether the current api version is CAMERA_MODULE_API_VERSION_2_0 or CAMERA_MODULE_API_VERSION_1_0. If my platform is 1.0, run the following command:

Switch (deviceVersion) {case CAMERA_DEVICE_API_VERSION_1_0: client = new CameraClient (this, cameraClient, cameraId, info. facing, callingPid, getpid (); // The client is the base class of CameraClient and creates a camerservice-side cameraclient break;

C. Establish CameraClient. This class inherits the internal class of public CameraService: Client, which inherits BnCamera.

D. client-> initialize (mModule) processing, and hardware-related

Status_t CameraClient: initialize (initialize * module) {// A cameraClient creates a unique hard interface int callingPid = getCallingPid (); LOG1 ("CameraClient: initialize E (pid % d, id % d) ", callingPid, mCameraId); char camera_device_name [10]; status_t res; snprintf (camera_device_name, sizeof (camera_device_name)," % d ", mCameraId ); mHardware = new CameraHardwareInterface (camera_device_name); // create a c Amera hardware interface, camera_device_name is the device name res = mHardware-> initialize (& module-> common); // The initial if (res! = OK) {ALOGE ("% s: Camera % d: unable to initialize device: % s (% d)", _ FUNCTION __, mCameraId, strerror (-res ), res); mHardware. clear (); return NO_INIT;} mHardware-> setCallbacks (yycallback, dataCallback, dataCallbackTimestamp, (void *) mCameraId ); // register the callback function at the camerservice to the HAL. // Enable zoom, error, focus, and metadata messages by default enableMsgType (CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS | percent | CAMERA_MSG_FOCUS_MOVE | percent | CAMERA_MSG_SNAP | percent | CAMERA_MSG_SNAP_FD ); // enable the continuoussnap and singlesnap message by fuqiang LOG1 ("CameraClient: initialize X (pid % d, id % d)", callingPid, mCameraId); return OK ;}

Here we see a hardware interface class CameraHardwareInterface that encapsulates the underlying operations of Camera. It can shield the hardware features of different platforms and mainly implement HAL-related operations.

Step6.CameraHardwareInterface interface class implementation initialize () function.

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); // enable the camera hardware device if (rc! = OK) {ALOGE ("cocould not open camera % s: % d", mName. string (), rc); return rc;} initHalPreviewWindow (); // The opspreview_stream_ops stream of the initial preview, And the return rc window for initializing hal ;}

The module here is the underlying camera module, which eventually completes the open operation. HAL operations are not described here. We will share the HAL Implementation of camera in the future.

Step 7: setCallbacks () sets the callback function, that is, registers the callback function to HAL.

Void setCallbacks (notify_callback notify_cb, data_callback data_cb, data_callback_timestamp data_cb_timestamp, void * user) {mNotifyCb = yy_cb; mDataCb = data_cb; callback = callback; mCbUser = user; ALOGV ("% s (% s)", _ FUNCTION __, mName. string (); if (mDevice-> ops-> set_callbacks) {mDevice-> ops-> set_callbacks (mDevice, _ policy_cb, _ data_cb, _ data_cb_timestamp, _ get_memory, this); // input the _ policy_cb function} // callback for hardware device settings}

Message callbacks, data callbacks, timestamp callbacks, and memory-related operations respectively.

Step 8:

MClient [cameraId] = client maintains the new cameraclient object to CameraService and returns to exit connect. Finally, the agent BpCameraClient of CameraClient is returned to the client through the Binder driver, is an anonymous Binder service.

C-> mCamera = cs-> connect (c, cameraId); Maintain the cameraclient of this server to the mCamera member of the local application. Subsequent operations on Camera are performed through the mCamera member and CameraService.

A call architecture diagram of camera:







Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.