*/
#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"
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);
}
/****************************************************************************
*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)",
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]);
}
/****************************************************************************
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)
#include "CameraHardware.h"
#include "Converter.h"
-#define VIDEO_DEVICE "/dev/video0"
#define MIN_WIDTH 320
#define MIN_HEIGHT 240
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
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),
mCurrentRecordingFrame(0),
mCameraPowerFile(0)
{
+ //Store the video device location
+ mVideoDevice = devLocation;
+
/*
* Initialize camera_device descriptor for this object.
*/
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;
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;
SortedVector<SurfaceSize> avSizes;
SortedVector<int> avFps;
- if (camera.Open(VIDEO_DEVICE) != NO_ERROR) {
+ if (camera.Open(mVideoDevice) != NO_ERROR) {
LOGE("cannot open device.");
} else {
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 */