OSDN Git Service

Add support for multiple cameras. ics-x86
authorAndres Rodriguez <andresx7@gmail.com>
Thu, 19 Apr 2012 15:38:00 +0000 (23:38 +0800)
committerChih-Wei Huang <cwhuang@linux.org.tw>
Sun, 29 Apr 2012 18:35:19 +0000 (02:35 +0800)
The camera layout can be specified in camera.cfg using the following format
$orientation $camerapath

Where orientation can be "front" or "back" and $camerapath is the path to the
V4L device to use as input.

CameraFactory.cpp
CameraFactory.h
CameraHardware.cpp
CameraHardware.h

index e31f491..00db892 100644 (file)
  */
 
 #define LOG_NDEBUG 0
+#define DEFAULT_DEVICE_FRONT "/dev/video1"
+#define DEFAULT_DEVICE_BACK  "/dev/video0"
+#define CONFIG_FILE "/etc/camera.cfg"
 #define LOG_TAG "Camera_Factory"
+
 #include <cutils/log.h>
 #include <cutils/properties.h>
 #include "CameraFactory.h"
@@ -34,18 +38,22 @@ android::CameraFactory  gCameraFactory;
 
 namespace android {
 
-CameraFactory::CameraFactory() : mCamera(NULL)
+CameraFactory::CameraFactory()
 {
     LOGD("CameraFactory::CameraFactory");
+    mCamera = NULL;
+    mCameraDevices = NULL;
+    mCameraOrientation = NULL;
+    parseConfig(CONFIG_FILE);
 }
 
 CameraFactory::~CameraFactory()
 {
     LOGD("CameraFactory::~CameraFactory");
-    if (mCamera != NULL) {
-        delete mCamera;
-        mCamera = NULL;
+    for (int i=0; i < getCameraNum(); i++) {
+        delete mCamera[i];
     }
+    free(mCamera);
 }
 
 /****************************************************************************
@@ -62,29 +70,28 @@ int CameraFactory::cameraDeviceOpen(const hw_module_t* module,int camera_id, hw_
 
     *device = NULL;
 
-    if (camera_id < 0 || camera_id >= getCameraNum()) {
+    if (!mCamera || camera_id < 0 || camera_id >= getCameraNum()) {
         LOGE("%s: Camera id %d is out of bounds (%d)",
              __FUNCTION__, camera_id, getCameraNum());
         return -EINVAL;
     }
 
-    if (!mCamera)
-        mCamera = new CameraHardware(module);
-
-    return mCamera->connectCamera(device);
+    if (!mCamera[camera_id]) {
+        mCamera[camera_id] = new CameraHardware(module, mCameraDevices[camera_id]);
+    }
+    return mCamera[camera_id]->connectCamera(device);
 }
 
 /* Returns the number of available cameras */
 int CameraFactory::getCameraNum()
 {
-    LOGD("CameraFactory::getCameraNum");
-    return 1;
+    LOGD("CameraFactory::getCameraNum: %d", mCameraNum);
+    return mCameraNum;
 }
 
-
 int CameraFactory::getCameraInfo(int camera_id, struct camera_info* info)
 {
-    LOGD("CameraFactory::getCameraInfo: id = %d,info = %p", camera_id,info);
+    LOGD("CameraFactory::getCameraInfo: id = %d, info = %p", camera_id, info);
 
     if (camera_id < 0 || camera_id >= getCameraNum()) {
         LOGE("%s: Camera id %d is out of bounds (%d)",
@@ -92,9 +99,65 @@ int CameraFactory::getCameraInfo(int camera_id, struct camera_info* info)
         return -EINVAL;
     }
 
+    return CameraHardware::getCameraInfo(info, mCameraOrientation[camera_id]);
+}
 
-    LOGD("CameraFactory::getCameraInfo: about to fetch info");
-    return CameraHardware::getCameraInfo(info);
+// Parse a simple configuration file
+void CameraFactory::parseConfig(const char* configFile)
+{
+    LOGD("CameraFactory::parseConfig: configFile = %s", configFile);
+
+    FILE* config = fopen(configFile, "r");
+    if (config != NULL) {
+        char line[128];
+        char arg1[128];
+        char arg2[128];
+
+        while (fgets(line, sizeof line, config) != NULL) {
+            int lineStart = strspn(line, " \t\n\v" );
+
+            if (line[lineStart] == '#')
+                continue;
+
+            sscanf(line, "%s %s", arg1, arg2);
+
+            if (strcmp(arg1, "front")) {
+                newCameraConfig(CAMERA_FACING_FRONT, arg2);
+            } else if (strcmp(arg1, "back")) {
+                newCameraConfig(CAMERA_FACING_BACK, arg2);
+            } else {
+                LOGD("CameraFactory::parseConfig: Unrecognized config line '%s'", line);
+            }
+        }
+    } else {
+        LOGD("%s not found, using camera configuration defaults", CONFIG_FILE);
+        if (access(DEFAULT_DEVICE_BACK, F_OK) != -1){
+            LOGD("Found device %s", DEFAULT_DEVICE_BACK);
+            newCameraConfig(CAMERA_FACING_BACK, DEFAULT_DEVICE_BACK);
+        }
+        if (access(DEFAULT_DEVICE_FRONT, F_OK) != -1){
+            LOGD("Found device %s", DEFAULT_DEVICE_FRONT);
+            newCameraConfig(CAMERA_FACING_FRONT, DEFAULT_DEVICE_FRONT);
+        }
+    }
+}
+
+// Although realloc could be a costly operation, we only execute this function usually 2 times
+void CameraFactory::newCameraConfig(int facing, const char* location)
+{
+    // Keep track of cameras
+    mCameraNum++;
+
+    // Grow the information arrays
+    mCamera = (CameraHardware**) realloc(mCamera, mCameraNum * sizeof(CameraHardware*));
+    mCameraDevices = (char**) realloc(mCameraDevices, mCameraNum * sizeof(char*));
+    mCameraOrientation = (int*) realloc(mCameraOrientation, mCameraNum * sizeof(int));
+
+    // Store the values for each camera_id
+    mCamera[mCameraNum - 1] = NULL;
+    mCameraDevices[mCameraNum - 1] = strdup(location);
+    mCameraOrientation[mCameraNum - 1] = facing;
+    LOGD("CameraFactory::newCameraConfig: %d -> %s", mCameraOrientation[mCameraNum - 1], mCameraDevices[mCameraNum - 1]);
 }
 
 /****************************************************************************
@@ -122,7 +185,8 @@ int CameraFactory::device_open(const hw_module_t* module,
         return -EINVAL;
     }
 
-    return gCameraFactory.cameraDeviceOpen(module,atoi(name), device);
+    int camera_id = atoi(name);
+    return gCameraFactory.cameraDeviceOpen(module, camera_id, device);
 }
 
 int CameraFactory::get_number_of_cameras(void)
index 11abe64..f04d89f 100644 (file)
@@ -72,11 +72,10 @@ public:
     /* Gets emulated camera information.
      * This method is called in response to camera_module_t::get_camera_info callback.
      */
-    static int getCameraInfo(int camera_id, struct camera_info *info);
-
+    int getCameraInfo(int camera_id, struct camera_info *info);
 
     /* Returns the number of available cameras */
-    static int getCameraNum();
+    int getCameraNum();
 
     /****************************************************************************
      * Camera HAL API callbacks.
@@ -95,10 +94,16 @@ private:
                            const char* name,
                            hw_device_t** device);
 
+    void parseConfig(const char* configFile);
+    void newCameraConfig(int facing, const char* location);
+
 private:
 
     /* Camera hardware */
-    CameraHardware* mCamera;
+    CameraHardware**    mCamera;
+    char**              mCameraDevices;
+    int*                mCameraOrientation;
+    int                 mCameraNum;
 
 public:
     /* Contains device open entry point, as required by HAL API. */
index 32ed43e..1c4da16 100644 (file)
@@ -28,7 +28,6 @@
 #include "CameraHardware.h"
 #include "Converter.h"
 
-#define VIDEO_DEVICE    "/dev/video0"
 #define MIN_WIDTH       320
 #define MIN_HEIGHT      240
 
@@ -132,7 +131,7 @@ bool CameraHardware::PowerOn()
     int timeOut = 500;
     do {
         // Try to open the video capture device
-        handle = ::open(VIDEO_DEVICE,O_RDWR);
+        handle = ::open(mVideoDevice,O_RDWR);
         if (handle >= 0)
             break;
         // Wait a bit
@@ -170,7 +169,7 @@ bool CameraHardware::PowerOff()
     return true;
 }
 
-CameraHardware::CameraHardware(const hw_module_t* module) :
+CameraHardware::CameraHardware(const hw_module_t* module, char* devLocation) :
         mWin(0),
         mPreviewWinFmt(PIXEL_FORMAT_UNKNOWN),
         mPreviewWinWidth(0),
@@ -211,6 +210,9 @@ CameraHardware::CameraHardware(const hw_module_t* module) :
         mCurrentRecordingFrame(0),
         mCameraPowerFile(0)
 {
+    //Store the video device location
+    mVideoDevice = devLocation;
+
     /*
      * Initialize camera_device descriptor for this object.
      */
@@ -319,11 +321,11 @@ status_t CameraHardware::closeCamera()
     return NO_ERROR;
 }
 
-status_t CameraHardware::getCameraInfo(struct camera_info* info)
+status_t CameraHardware::getCameraInfo(struct camera_info* info, int facing)
 {
     LOGD("CameraHardware::getCameraInfo");
 
-    info->facing = CAMERA_FACING_FRONT;
+    info->facing = facing;
     info->orientation = 0;
 
     return NO_ERROR;
@@ -476,7 +478,7 @@ status_t CameraHardware::startPreviewLocked()
 
     LOGD("CameraHardware::startPreviewLocked: Open, %dx%d", width, height);
 
-    status_t ret = camera.Open(VIDEO_DEVICE);
+    status_t ret = camera.Open(mVideoDevice);
     if (ret != NO_ERROR) {
         LOGE("Failed to initialize Camera");
         return ret;
@@ -810,7 +812,7 @@ void CameraHardware::initDefaultParameters()
     SortedVector<SurfaceSize> avSizes;
     SortedVector<int> avFps;
 
-    if (camera.Open(VIDEO_DEVICE) != NO_ERROR) {
+    if (camera.Open(mVideoDevice) != NO_ERROR) {
         LOGE("cannot open device.");
     } else {
 
@@ -1644,7 +1646,7 @@ int CameraHardware::pictureThread()
 
         LOGD("CameraHardware::pictureThread: taking picture (%d x %d)", w, h);
 
-        if (camera.Open(VIDEO_DEVICE) == NO_ERROR) {
+        if (camera.Open(mVideoDevice) == NO_ERROR) {
             camera.Init(w, h, 1);
 
             /* Retrieve the real size being used */
index 94d478e..a57261c 100644 (file)
@@ -182,7 +182,7 @@ public:
      *      instance in camera factory's array.
      *  module - Emulated camera HAL module descriptor.
      */
-    CameraHardware(const hw_module_t* module);
+    CameraHardware(const hw_module_t* module, char* devLocation);
 
     /* Destructs EmulatedCamera instance. */
     virtual ~CameraHardware();
@@ -212,7 +212,7 @@ public:
      * NOTE: When this method is called the object is locked.
      * Note that failures in this method are reported as negave EXXX statuses.
      */
-    static status_t getCameraInfo(struct camera_info* info);
+    static status_t getCameraInfo(struct camera_info* info, int facing);
 
 private:
 
@@ -251,7 +251,7 @@ private:
     int                 mPreviewWinHeight;
 
     CameraParameters    mParameters;
-
+    char*               mVideoDevice;
 
     camera_memory_t*    mRawPreviewHeap;
     int                 mRawPreviewFrameSize;