summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camera/Android.mk3
-rw-r--r--camera/V4LCameraAdapter/V4LCameraAdapter.cpp110
-rw-r--r--camera/V4LCameraAdapter/V4LCapabilities.cpp261
-rw-r--r--camera/inc/V4LCameraAdapter/V4LCameraAdapter.h65
4 files changed, 395 insertions, 44 deletions
diff --git a/camera/Android.mk b/camera/Android.mk
index f97b2a9..ea9e2ec 100644
--- a/camera/Android.mk
+++ b/camera/Android.mk
@@ -65,7 +65,8 @@ OMAP4_CAMERA_OMX_SRC:= \
OMXCameraAdapter/OMXDccDataSave.cpp \
OMAP4_CAMERA_USB_SRC:= \
- V4LCameraAdapter/V4LCameraAdapter.cpp
+ V4LCameraAdapter/V4LCameraAdapter.cpp \
+ V4LCameraAdapter/V4LCapabilities.cpp \
#
# OMX Camera HAL
diff --git a/camera/V4LCameraAdapter/V4LCameraAdapter.cpp b/camera/V4LCameraAdapter/V4LCameraAdapter.cpp
index 18ccf21..af92405 100644
--- a/camera/V4LCameraAdapter/V4LCameraAdapter.cpp
+++ b/camera/V4LCameraAdapter/V4LCameraAdapter.cpp
@@ -58,7 +58,7 @@ namespace android {
//#define SAVE_RAW_FRAMES 1
Mutex gV4LAdapterLock;
-const char *device = DEVICE;
+char device[15];
/*--------------------Camera Adapter Class STARTS here-----------------------------*/
@@ -636,6 +636,36 @@ int V4LCameraAdapter::previewThread()
return ret;
}
+//scan for video devices
+void detectVideoDevice(char** video_device_list, int& num_device) {
+ char dir_path[20];
+ char* filename;
+ char** dev_list = video_device_list;
+ DIR *d;
+ struct dirent *dir;
+ int index = 0;
+
+ strcpy(dir_path, DEVICE_PATH);
+ d = opendir(dir_path);
+ if(d) {
+ //read each entry in the /dev/ and find if there is videox entry.
+ while ((dir = readdir(d)) != NULL) {
+ filename = dir->d_name;
+ if (strncmp(filename, DEVICE_NAME, 5) == 0) {
+ strcpy(dev_list[index],DEVICE_PATH);
+ strncat(dev_list[index],filename,sizeof(DEVICE_NAME));
+ index++;
+ }
+ } //end of while()
+ closedir(d);
+ num_device = index;
+
+ for(int i=0; i<index; i++){
+ CAMHAL_LOGDB("Video device list::dev_list[%d]= %s",i,dev_list[i]);
+ }
+ }
+}
+
extern "C" CameraAdapter* V4LCameraAdapter_Factory(size_t sensor_index)
{
CameraAdapter *adapter = NULL;
@@ -663,6 +693,10 @@ extern "C" status_t V4LCameraAdapter_Capabilities(
struct v4l2_capability cap;
int tempHandle = NULL;
int num_cameras_supported = 0;
+ char device_list[5][15];
+ char* video_device_list[5];
+ int num_v4l_devices = 0;
+ int sensorId = 0;
CameraProperties::Properties* properties = NULL;
LOG_FUNCTION_NAME;
@@ -676,50 +710,52 @@ extern "C" status_t V4LCameraAdapter_Capabilities(
return BAD_VALUE;
}
+ for (int i = 0; i < 5; i++) {
+ video_device_list[i] = device_list[i];
+ }
//look for the connected video devices
- if (ret == NO_ERROR && (starting_camera + num_cameras_supported) < max_camera) {
+ detectVideoDevice(video_device_list, num_v4l_devices);
- if ((tempHandle = open(device, O_RDWR)) == -1) {
- CAMHAL_LOGEB("Error while opening handle to V4L2 Camera: %s", strerror(errno));
- return NO_ERROR;
- }
+ for (int i = 0; i < num_v4l_devices; i++) {
+ if ( (starting_camera + num_cameras_supported) < max_camera) {
+ sensorId = starting_camera + num_cameras_supported;
- ret = ioctl (tempHandle, VIDIOC_QUERYCAP, &cap);
- if (ret < 0)
- {
- CAMHAL_LOGEA("Error when querying the capabilities of the V4L Camera");
- goto EXIT;
- }
+ CAMHAL_LOGDB("Opening device[%d] = %s..",i, video_device_list[i]);
+ if ((tempHandle = open(video_device_list[i], O_RDWR)) == -1) {
+ CAMHAL_LOGEB("Error while opening handle to V4L2 Camera(%s): %s",video_device_list[i], strerror(errno));
+ continue;
+ }
- //check for video capture devices
- if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0)
- {
- CAMHAL_LOGEA("Error while adapter initialization: video capture not supported.");
- goto EXIT;
- }
+ ret = ioctl (tempHandle, VIDIOC_QUERYCAP, &cap);
+ if (ret < 0) {
+ CAMHAL_LOGEA("Error when querying the capabilities of the V4L Camera");
+ close(tempHandle);
+ continue;
+ }
+
+ //check for video capture devices
+ if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) {
+ CAMHAL_LOGEA("Error while adapter initialization: video capture not supported.");
+ close(tempHandle);
+ continue;
+ }
- num_cameras_supported++;
- properties = properties_array + starting_camera;
-
- // TODO: Need to tell camera properties what other cameras we can support
- properties->set(CameraProperties::CAMERA_NAME, "USBCAMERA");
- properties->set(CameraProperties::PREVIEW_SIZE, "640x480");
- properties->set(CameraProperties::PREVIEW_FORMAT, "yuv420sp");
- properties->set(CameraProperties::SUPPORTED_PREVIEW_FORMATS, "yuv420sp");
- properties->set(CameraProperties::PICTURE_SIZE, "640x480");
- properties->set(CameraProperties::JPEG_THUMBNAIL_SIZE, "320x240");
- properties->set(CameraProperties::SUPPORTED_PREVIEW_SIZES, "640x480");
- properties->set(CameraProperties::SUPPORTED_PICTURE_SIZES, "640x480");
- properties->set(CameraProperties::REQUIRED_PREVIEW_BUFS, "6");
- properties->set(CameraProperties::FRAMERATE_RANGE_SUPPORTED, "30000,30000");
- properties->set(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES, "30000,30000");
- properties->set(CameraProperties::FRAMERATE_RANGE, "30000,30000");
- properties->set(CameraProperties::PREVIEW_FRAME_RATE, "30000");
+ strcpy(device, video_device_list[i]);
+ properties = properties_array + starting_camera + num_cameras_supported;
- }
+ //fetch capabilities for this camera
+ V4LCameraAdapter::getCaps( sensorId, properties, tempHandle );
+
+ num_cameras_supported++;
+
+ }
+ //For now exit this loop once a valid video capture device is found.
+ //TODO: find all V4L capture devices and it capabilities
+ break;
+ }//end of for() loop
supportedCameras = num_cameras_supported;
- CAMHAL_LOGDB("V4L cameras detected =%d", num_cameras_supported);
+ CAMHAL_LOGDB("Number of V4L cameras detected =%d", num_cameras_supported);
EXIT:
LOG_FUNCTION_NAME_EXIT;
diff --git a/camera/V4LCameraAdapter/V4LCapabilities.cpp b/camera/V4LCameraAdapter/V4LCapabilities.cpp
new file mode 100644
index 0000000..fdc16d6
--- /dev/null
+++ b/camera/V4LCameraAdapter/V4LCapabilities.cpp
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) Texas Instruments - http://www.ti.com/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @file V4LCapabilities.cpp
+*
+* This file implements the V4L Capabilities feature.
+*
+*/
+
+#include "CameraHal.h"
+#include "V4LCameraAdapter.h"
+#include "ErrorUtils.h"
+#include "TICameraParameters.h"
+
+namespace android {
+
+/************************************
+ * global constants and variables
+ *************************************/
+
+#define ARRAY_SIZE(array) (sizeof((array)) / sizeof((array)[0]))
+#define MAX_RES_STRING_LENGTH 10
+#define DEFAULT_WIDTH 640
+#define DEFAULT_HEIGHT 480
+
+static const char PARAM_SEP[] = ",";
+
+//Camera defaults
+const char V4LCameraAdapter::DEFAULT_PICTURE_FORMAT[] = "jpeg";
+const char V4LCameraAdapter::DEFAULT_PICTURE_SIZE[] = "640x480";
+const char V4LCameraAdapter::DEFAULT_PREVIEW_FORMAT[] = "yuv422i";
+const char V4LCameraAdapter::DEFAULT_PREVIEW_SIZE[] = "640x480";
+const char V4LCameraAdapter::DEFAULT_NUM_PREV_BUFS[] = "6";
+const char V4LCameraAdapter::DEFAULT_FRAMERATE[] = "30";
+
+
+const CapPixelformat V4LCameraAdapter::mPixelformats [] = {
+ { V4L2_PIX_FMT_YUYV, CameraParameters::PIXEL_FORMAT_YUV422I },
+ { V4L2_PIX_FMT_JPEG, CameraParameters::PIXEL_FORMAT_JPEG },
+};
+
+/*****************************************
+ * internal static function declarations
+ *****************************************/
+
+/**** Utility functions to help translate V4L Caps to Parameter ****/
+
+status_t V4LCameraAdapter::insertDefaults(CameraProperties::Properties* params, V4L_TI_CAPTYPE &caps)
+{
+ status_t ret = NO_ERROR;
+ LOG_FUNCTION_NAME;
+
+ params->set(CameraProperties::PREVIEW_FORMAT, DEFAULT_PREVIEW_FORMAT);
+
+ params->set(CameraProperties::PICTURE_FORMAT, DEFAULT_PICTURE_FORMAT);
+ params->set(CameraProperties::PICTURE_SIZE, DEFAULT_PICTURE_SIZE);
+ params->set(CameraProperties::PREVIEW_SIZE, DEFAULT_PREVIEW_SIZE);
+ params->set(CameraProperties::PREVIEW_FRAME_RATE, DEFAULT_FRAMERATE);
+ params->set(CameraProperties::REQUIRED_PREVIEW_BUFS, DEFAULT_NUM_PREV_BUFS);
+
+ params->set(CameraProperties::CAMERA_NAME, "USBCAMERA");
+ params->set(CameraProperties::JPEG_THUMBNAIL_SIZE, "320x240");
+ params->set(CameraProperties::FRAMERATE_RANGE_SUPPORTED, "30000,30000");
+ params->set(CameraProperties::FRAMERATE_RANGE, "30000,30000");
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+status_t V4LCameraAdapter::insertPreviewFormats(CameraProperties::Properties* params, V4L_TI_CAPTYPE &caps) {
+
+ char supported[MAX_PROP_VALUE_LENGTH];
+
+ memset(supported, '\0', MAX_PROP_VALUE_LENGTH);
+ for (int i = 0; i < caps.ulPreviewFormatCount; i++) {
+ for (unsigned int j = 0; j < ARRAY_SIZE(mPixelformats); j++) {
+ if(caps.ePreviewFormats[i] == mPixelformats[j].pixelformat ) {
+ strncat (supported, mPixelformats[j].param, MAX_PROP_VALUE_LENGTH-1 );
+ strncat (supported, PARAM_SEP, 1 );
+ }
+ }
+ }
+ strncat(supported, CameraParameters::PIXEL_FORMAT_YUV420P, MAX_PROP_VALUE_LENGTH - 1);
+ params->set(CameraProperties::SUPPORTED_PREVIEW_FORMATS, supported);
+ return NO_ERROR;
+}
+
+status_t V4LCameraAdapter::insertPreviewSizes(CameraProperties::Properties* params, V4L_TI_CAPTYPE &caps) {
+
+ char supported[MAX_PROP_VALUE_LENGTH];
+
+ memset(supported, '\0', MAX_PROP_VALUE_LENGTH);
+ for (int i = 0; i < caps.ulPreviewResCount; i++) {
+ strncat (supported, caps.tPreviewRes[i].param, MAX_PROP_VALUE_LENGTH-1 );
+ strncat (supported, PARAM_SEP, 1 );
+ }
+ params->set(CameraProperties::SUPPORTED_PREVIEW_SIZES, supported);
+ return NO_ERROR;
+}
+
+status_t V4LCameraAdapter::insertImageSizes(CameraProperties::Properties* params, V4L_TI_CAPTYPE &caps) {
+
+ char supported[MAX_PROP_VALUE_LENGTH];
+
+ memset(supported, '\0', MAX_PROP_VALUE_LENGTH);
+ for (int i = 0; i < caps.ulCaptureResCount; i++) {
+ strncat (supported, caps.tCaptureRes[i].param, MAX_PROP_VALUE_LENGTH-1 );
+ strncat (supported, PARAM_SEP, 1 );
+ }
+ params->set(CameraProperties::SUPPORTED_PICTURE_SIZES, supported);
+ return NO_ERROR;
+}
+
+status_t V4LCameraAdapter::insertFrameRates(CameraProperties::Properties* params, V4L_TI_CAPTYPE &caps) {
+
+ char supported[MAX_PROP_VALUE_LENGTH];
+
+ memset(supported, '\0', MAX_PROP_VALUE_LENGTH);
+ for (int i = 0; i < caps.ulFrameRateCount; i++) {
+ snprintf (supported, 10, "%d", caps.ulFrameRates[i]*1000 );
+ strncat (supported, PARAM_SEP, 1 );
+ }
+ params->set(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES, supported);
+ return NO_ERROR;
+}
+
+status_t V4LCameraAdapter::insertCapabilities(CameraProperties::Properties* params, V4L_TI_CAPTYPE &caps)
+{
+ status_t ret = NO_ERROR;
+
+ LOG_FUNCTION_NAME;
+
+ if ( NO_ERROR == ret ) {
+ ret = insertPreviewFormats(params, caps);
+ }
+
+ if ( NO_ERROR == ret ) {
+ ret = insertImageSizes(params, caps);
+ }
+
+ if ( NO_ERROR == ret ) {
+ ret = insertPreviewSizes(params, caps);
+ }
+
+ if ( NO_ERROR == ret ) {
+ ret = insertFrameRates(params, caps);
+ }
+
+ if ( NO_ERROR == ret ) {
+ ret = insertDefaults(params, caps);
+ }
+
+ LOG_FUNCTION_NAME_EXIT;
+
+ return ret;
+}
+
+/*****************************************
+ * public exposed function declarations
+ *****************************************/
+
+status_t V4LCameraAdapter::getCaps(const int sensorId, CameraProperties::Properties* params,
+ V4L_HANDLETYPE handle) {
+ status_t status = NO_ERROR;
+ V4L_TI_CAPTYPE caps;
+ int i = 0;
+ struct v4l2_fmtdesc fmtDesc;
+ struct v4l2_frmsizeenum frmSizeEnum;
+ struct v4l2_frmivalenum frmIvalEnum;
+
+ //get supported pixel formats
+ for ( i = 0; status == NO_ERROR; i++) {
+ fmtDesc.index = i;
+ fmtDesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ status = ioctl (handle, VIDIOC_ENUM_FMT, &fmtDesc);
+ if (status == NO_ERROR) {
+ CAMHAL_LOGDB("fmtDesc[%d].description::pixelformat::flags== (%s::%d::%d)",i, fmtDesc.description,fmtDesc.pixelformat,fmtDesc.flags);
+ caps.ePreviewFormats[i] = fmtDesc.pixelformat;
+ }
+ }
+ caps.ulPreviewFormatCount = i;
+
+ //get preview sizes & capture image sizes
+ status = NO_ERROR;
+ for ( i = 0; status == NO_ERROR; i++) {
+ frmSizeEnum.index = i;
+ //Check for frame sizes for default pixel format
+ //TODO: Check for frame sizes for all supported pixel formats
+ frmSizeEnum.pixel_format = V4L2_PIX_FMT_YUYV;
+ status = ioctl (handle, VIDIOC_ENUM_FRAMESIZES, &frmSizeEnum);
+ if(frmSizeEnum.type != V4L2_FRMSIZE_TYPE_DISCRETE) {
+ break;
+ }
+ if (status == NO_ERROR) {
+ CAMHAL_LOGDB("frmSizeEnum.index[%d].width x height == (%d x %d)", i, frmSizeEnum.discrete.width, frmSizeEnum.discrete.height);
+ caps.tPreviewRes[i].width = frmSizeEnum.discrete.width;
+ caps.tPreviewRes[i].height = frmSizeEnum.discrete.height;
+ snprintf(caps.tPreviewRes[i].param, MAX_RES_STRING_LENGTH,"%dx%d",frmSizeEnum.discrete.width,frmSizeEnum.discrete.height);
+
+ caps.tCaptureRes[i].width = frmSizeEnum.discrete.width;
+ caps.tCaptureRes[i].height = frmSizeEnum.discrete.height;
+ snprintf(caps.tCaptureRes[i].param, MAX_RES_STRING_LENGTH,"%dx%d",frmSizeEnum.discrete.width,frmSizeEnum.discrete.height);
+ }
+ else {
+ caps.ulCaptureResCount = i;
+ caps.ulPreviewResCount = i;
+ }
+ }
+ if(frmSizeEnum.type != V4L2_FRMSIZE_TYPE_DISCRETE) {
+ CAMHAL_LOGDB("\nmin_width x height = %d x %d ",frmSizeEnum.stepwise.min_width, frmSizeEnum.stepwise.min_height);
+ CAMHAL_LOGDB("\nmax_width x height = %d x %d ",frmSizeEnum.stepwise.max_width, frmSizeEnum.stepwise.max_height);
+ CAMHAL_LOGDB("\nstep width x height = %d x %d ",frmSizeEnum.stepwise.step_width,frmSizeEnum.stepwise.step_height);
+ //TODO: populate the sizes when type = V4L2_FRMSIZE_TYPE_STEPWISE
+ }
+
+ //get supported frame rates
+ status = NO_ERROR;
+ for ( i = 0; status == NO_ERROR; i++) {
+ frmIvalEnum.index = i;
+ //Check for supported frame rates for the default pixel format and default image frame size.
+ //TODO: Check supported frame rates for all supported pixel format + resolution
+ frmIvalEnum.pixel_format = V4L2_PIX_FMT_YUYV;
+ frmIvalEnum.width = DEFAULT_WIDTH;
+ frmIvalEnum.height = DEFAULT_HEIGHT;
+ status = ioctl (handle, VIDIOC_ENUM_FRAMEINTERVALS, &frmIvalEnum);
+ if(frmIvalEnum.type != V4L2_FRMIVAL_TYPE_DISCRETE) {
+ break;
+ }
+ if (status == NO_ERROR) {
+ LOGD("frmIvalEnum[%d].frame rate= %d)",i, (frmIvalEnum.discrete.denominator/frmIvalEnum.discrete.numerator));
+ caps.ulFrameRates[i] = (frmIvalEnum.discrete.denominator/frmIvalEnum.discrete.numerator);
+ }
+ else {
+ caps.ulFrameRateCount = i;
+ }
+ }
+ if(frmIvalEnum.type != V4L2_FRMIVAL_TYPE_DISCRETE) {
+ //TODO: populate the frame rates when type = V4L2_FRMIVAL_TYPE_STEPWISE;
+ }
+
+ insertCapabilities (params, caps);
+ return NO_ERROR;
+}
+
+
+
+};
diff --git a/camera/inc/V4LCameraAdapter/V4LCameraAdapter.h b/camera/inc/V4LCameraAdapter/V4LCameraAdapter.h
index 1279bd0..9a16275 100644
--- a/camera/inc/V4LCameraAdapter/V4LCameraAdapter.h
+++ b/camera/inc/V4LCameraAdapter/V4LCameraAdapter.h
@@ -28,8 +28,28 @@ namespace android {
#define DEFAULT_PIXEL_FORMAT V4L2_PIX_FMT_YUYV
#define NB_BUFFER 10
-#define DEVICE "/dev/video0"
+#define DEVICE "/dev/videoxx"
+#define DEVICE_PATH "/dev/"
+#define DEVICE_NAME "videoxx"
+typedef int V4L_HANDLETYPE;
+
+struct CapPixelformat {
+ uint32_t pixelformat;
+ const char *param;
+};
+
+struct CapResolution {
+ size_t width, height;
+ char param[10];
+};
+
+struct CapU32 {
+ uint32_t num;
+ const char *param;
+};
+
+typedef CapU32 CapFramerate;
struct VideoInfo {
struct v4l2_capability cap;
@@ -44,6 +64,16 @@ struct VideoInfo {
int framesizeIn;
};
+typedef struct V4L_TI_CAPTYPE {
+ uint16_t ulPreviewFormatCount; // supported preview pixelformat count
+ uint32_t ePreviewFormats[32];
+ uint16_t ulPreviewResCount; // supported preview resolution sizes
+ CapResolution tPreviewRes[32];
+ uint16_t ulCaptureResCount; // supported capture resolution sizes
+ CapResolution tCaptureRes[32];
+ uint16_t ulFrameRateCount; // supported frame rate
+ uint16_t ulFrameRates[32];
+}V4L_TI_CAPTYPE;
/**
* Class which completely abstracts the camera hardware interaction from camera hal
@@ -79,6 +109,8 @@ public:
// API
virtual status_t UseBuffersPreview(void* bufArr, int num);
+ static status_t getCaps(const int sensorId, CameraProperties::Properties* params, V4L_HANDLETYPE handle);
+
protected:
//----------Parent class method implementation------------------------------------
@@ -120,6 +152,28 @@ private:
public:
private:
+ //capabilities data
+ static const CapPixelformat mPixelformats [];
+ static const CapResolution mPreviewRes [];
+ static const CapFramerate mFramerates [];
+ static const CapResolution mImageCapRes [];
+
+ //camera defaults
+ static const char DEFAULT_PREVIEW_FORMAT[];
+ static const char DEFAULT_PREVIEW_SIZE[];
+ static const char DEFAULT_FRAMERATE[];
+ static const char DEFAULT_NUM_PREV_BUFS[];
+
+ static const char DEFAULT_PICTURE_FORMAT[];
+ static const char DEFAULT_PICTURE_SIZE[];
+
+ static status_t insertDefaults(CameraProperties::Properties*, V4L_TI_CAPTYPE&);
+ static status_t insertCapabilities(CameraProperties::Properties*, V4L_TI_CAPTYPE&);
+ static status_t insertPreviewFormats(CameraProperties::Properties* , V4L_TI_CAPTYPE&);
+ static status_t insertPreviewSizes(CameraProperties::Properties* , V4L_TI_CAPTYPE&);
+ static status_t insertImageSizes(CameraProperties::Properties* , V4L_TI_CAPTYPE&);
+ static status_t insertFrameRates(CameraProperties::Properties* , V4L_TI_CAPTYPE&);
+
int mPreviewBufferCount;
KeyedVector<int, int> mPreviewBufs;
mutable Mutex mPreviewBufsLock;
@@ -140,12 +194,11 @@ private:
int mSensorIndex;
- // protected by mLock
- sp<PreviewThread> mPreviewThread;
-
- struct VideoInfo *mVideoInfo;
- int mCameraHandle;
+ // protected by mLock
+ sp<PreviewThread> mPreviewThread;
+ struct VideoInfo *mVideoInfo;
+ int mCameraHandle;
int nQueued;
int nDequeued;