aboutsummaryrefslogtreecommitdiffstats
path: root/android/camera
diff options
context:
space:
mode:
authorVladimir Chtchetkine <vchtchetkine@google.com>2011-09-17 11:15:47 -0700
committerVladimir Chtchetkine <vchtchetkine@google.com>2011-09-20 09:43:13 -0700
commitb8dcaffaf7dcb0c795d2776abf3bb75196f8527c (patch)
tree62b03c33eac338e02a9ff1630672072c676a70e4 /android/camera
parentd6362e54b7b116a42d45a1ef499ff180548c7674 (diff)
downloadexternal_qemu-b8dcaffaf7dcb0c795d2776abf3bb75196f8527c.zip
external_qemu-b8dcaffaf7dcb0c795d2776abf3bb75196f8527c.tar.gz
external_qemu-b8dcaffaf7dcb0c795d2776abf3bb75196f8527c.tar.bz2
Add -webcam commandline option to control webcam emulation
-webcam name=<name>[,dir=<direction>] options controls web cameras to use for emulation. Change-Id: I961fd399c7e041541adda040dd24f194cc383cb9
Diffstat (limited to 'android/camera')
-rw-r--r--android/camera/camera-capture-linux.c3
-rwxr-xr-xandroid/camera/camera-capture-windows.c4
-rwxr-xr-xandroid/camera/camera-common.h8
-rw-r--r--android/camera/camera-service.c212
-rw-r--r--android/camera/camera-service.h3
5 files changed, 186 insertions, 44 deletions
diff --git a/android/camera/camera-capture-linux.c b/android/camera/camera-capture-linux.c
index 072d06e..50324f0 100644
--- a/android/camera/camera-capture-linux.c
+++ b/android/camera/camera-capture-linux.c
@@ -1048,6 +1048,9 @@ enumerate_camera_devices(CameraInfo* cis, int max)
if (cd != NULL) {
LinuxCameraDevice* lcd = (LinuxCameraDevice*)cd->opaque;
if (!_camera_device_get_info(lcd, cis + found)) {
+ char user_name[24];
+ sprintf(user_name, "webcam%d", found);
+ cis[found].display_name = ASTRDUP(user_name);
cis[found].in_use = 0;
found++;
}
diff --git a/android/camera/camera-capture-windows.c b/android/camera/camera-capture-windows.c
index e5120ab..0fb172e 100755
--- a/android/camera/camera-capture-windows.c
+++ b/android/camera/camera-capture-windows.c
@@ -504,7 +504,11 @@ enumerate_camera_devices(CameraInfo* cis, int max)
* but the actual numbers may vary). */
cis[found].frame_sizes = (CameraFrameDim*)malloc(sizeof(CameraFrameDim));
if (cis[found].frame_sizes != NULL) {
+ char disp_name[24];
+ sprintf(disp_name, "webcam%d", found);
+ cis[found].display_name = ASTRDUP(disp_name);
cis[found].device_name = ASTRDUP(name);
+ cis[found].direction = ASTRDUP("front");
cis[found].inp_channel = inp_channel;
cis[found].frame_sizes->width = wcd->frame_bitmap->bmiHeader.biWidth;
cis[found].frame_sizes->height = wcd->frame_bitmap->bmiHeader.biHeight;
diff --git a/android/camera/camera-common.h b/android/camera/camera-common.h
index 0cf8cea..a3fdd5f 100755
--- a/android/camera/camera-common.h
+++ b/android/camera/camera-common.h
@@ -88,12 +88,16 @@ typedef struct CameraFrameDim {
* representing that camera.
*/
typedef struct CameraInfo {
+ /* User-friendly camera display name. */
+ char* display_name;
/* Device name for the camera. */
char* device_name;
/* Input channel for the camera. */
int inp_channel;
/* Pixel format chosen for the camera. */
uint32_t pixel_format;
+ /* Direction the camera is facing: 'front', or 'back' */
+ char* direction;
/* Array of frame sizes supported for the pixel format chosen for the camera.
* The size of the array is defined by the frame_sizes_num field of this
* structure. */
@@ -120,8 +124,12 @@ static __inline__ CameraInfo* _camera_info_alloc(void)
static __inline__ void _camera_info_free(CameraInfo* ci)
{
if (ci != NULL) {
+ if (ci->display_name != NULL)
+ free(ci->display_name);
if (ci->device_name != NULL)
free(ci->device_name);
+ if (ci->direction != NULL)
+ free(ci->direction);
if (ci->frame_sizes != NULL)
free(ci->frame_sizes);
AFREE(ci);
diff --git a/android/camera/camera-service.c b/android/camera/camera-service.c
index a35f595..96d3c44 100644
--- a/android/camera/camera-service.c
+++ b/android/camera/camera-service.c
@@ -19,6 +19,7 @@
*/
#include "qemu-common.h"
+#include "android/globals.h" /* for android_hw */
#include "android/hw-qemud.h"
#include "android/utils/misc.h"
#include "android/utils/system.h"
@@ -62,48 +63,6 @@ struct CameraServiceDesc {
static CameraServiceDesc _camera_service_desc;
/********************************************************************************
- * CameraServiceDesc API
- *******************************************************************************/
-
-/* Initializes camera service descriptor.
- */
-static void
-_camera_service_init(CameraServiceDesc* csd)
-{
- /* Enumerate camera devices connected to the host. */
- csd->camera_count = enumerate_camera_devices(csd->camera_info, MAX_CAMERA);
- if (csd->camera_count >= 0) {
- D("%s: Enumerated %d cameras connected to the host",
- __FUNCTION__, csd->camera_count);
- } else {
- E("%s: Unable to enumerate camera devices", __FUNCTION__);
- csd->camera_count = 0;
- return;
- }
-}
-
-/* Gets camera information for the given camera device name.
- * Param:
- * cs - Initialized camera service descriptor.
- * name - Camera device name to look up the information for.
- * Return:
- * Camera information pointer on success, or NULL if no camera information has
- * been found for the given device name. Note that camera information returned
- * from this routine is constant.
- */
-static CameraInfo*
-_camera_service_get_camera_info(CameraServiceDesc* cs, const char* name)
-{
- int n;
- for (n = 0; n < cs->camera_count; n++) {
- if (!strcmp(cs->camera_info[n].device_name, name)) {
- return &cs->camera_info[n];
- }
- }
- return NULL;
-}
-
-/********************************************************************************
* Helper routines
*******************************************************************************/
@@ -357,7 +316,7 @@ _append_string(char** str_buf, size_t* str_buf_size, const char* str)
}
/* Represents camera information as a string formatted as follows:
- * 'name=<devname> channel=<num> pix=<format> framedims=<widh1xheight1,widh2xheight2,widhNxheightN>\n'
+ * 'name=<devname> channel=<num> pix=<format> facing=<direction> framedims=<widh1xheight1,...>\n'
* Param:
* ci - Camera information descriptor to convert into a string.
* str - Pointer to the string buffer where to save the converted camera
@@ -394,6 +353,12 @@ _camera_info_to_string(const CameraInfo* ci, char** str, size_t* str_size) {
if (res) {
return res;
}
+ /* Append direction. */
+ snprintf(tmp, sizeof(tmp), "dir=%s ", ci->direction);
+ res = _append_string(str, str_size, tmp);
+ if (res) {
+ return res;
+ }
/* Append supported frame sizes. */
snprintf(tmp, sizeof(tmp), "framedims=%dx%d",
ci->frame_sizes[0].width, ci->frame_sizes[0].height);
@@ -414,6 +379,143 @@ _camera_info_to_string(const CameraInfo* ci, char** str, size_t* str_size) {
return _append_string(str, str_size, "\n");
}
+/* Gets camera information matching a display name.
+ * Param:
+ * disp_name - Display name to match.
+ * arr - Array of camera informations.
+ * num - Number of elements in the array.
+ * Return:
+ * Matching camera information, or NULL if matching camera information for the
+ * given display name has not been found in the array.
+ */
+static CameraInfo*
+_camera_info_get_by_display_name(const char* disp_name, CameraInfo* arr, int num)
+{
+ int n;
+ for (n = 0; n < num; n++) {
+ if (arr[n].display_name != NULL && !strcmp(arr[n].display_name, disp_name)) {
+ return &arr[n];
+ }
+ }
+ return NULL;
+}
+
+/* Gets camera information matching a device name.
+ * Param:
+ * device_name - Device name to match.
+ * arr - Array of camera informations.
+ * num - Number of elements in the array.
+ * Return:
+ * Matching camera information, or NULL if matching camera information for the
+ * given device name has not been found in the array.
+ */
+static CameraInfo*
+_camera_info_get_by_device_name(const char* device_name, CameraInfo* arr, int num)
+{
+ int n;
+ for (n = 0; n < num; n++) {
+ if (arr[n].device_name != NULL && !strcmp(arr[n].device_name, device_name)) {
+ return &arr[n];
+ }
+ }
+ return NULL;
+}
+
+/********************************************************************************
+ * CameraServiceDesc API
+ *******************************************************************************/
+
+/* Initializes camera service descriptor.
+ */
+static void
+_camera_service_init(CameraServiceDesc* csd)
+{
+ CameraInfo ci[MAX_CAMERA];
+ int connected_cnt;
+ int i;
+
+ /* Enumerate camera devices connected to the host. */
+ memset(ci, 0, sizeof(CameraInfo) * MAX_CAMERA);
+ memset(csd->camera_info, 0, sizeof(CameraInfo) * MAX_CAMERA);
+ csd->camera_count = 0;
+ connected_cnt = enumerate_camera_devices(ci, MAX_CAMERA);
+ if (connected_cnt <= 0) {
+ /* Nothing is connected - nothing to emulate. */
+ return;
+ }
+
+ /* For each webcam declared in hw.ini find an actual camera information
+ * descriptor, and save it into the service descriptor for the emulation. */
+ for (i = 0; i < android_hw->hw_webcam_count; i++) {
+ const char* disp_name;
+ const char* dir;
+ CameraInfo* found;
+
+ switch (i) {
+ case 0:
+ disp_name = android_hw->hw_webcam_0_name;
+ dir = android_hw->hw_webcam_0_direction;
+ break;
+ case 1:
+ disp_name = android_hw->hw_webcam_1_name;
+ dir = android_hw->hw_webcam_1_direction;
+ break;
+ case 2:
+ disp_name = android_hw->hw_webcam_2_name;
+ dir = android_hw->hw_webcam_2_direction;
+ break;
+ case 3:
+ disp_name = android_hw->hw_webcam_3_name;
+ dir = android_hw->hw_webcam_3_direction;
+ break;
+ case 4:
+ disp_name = android_hw->hw_webcam_4_name;
+ dir = android_hw->hw_webcam_4_direction;
+ break;
+ case 5:
+ default:
+ disp_name = android_hw->hw_webcam_5_name;
+ dir = android_hw->hw_webcam_5_direction;
+ break;
+ }
+ found = _camera_info_get_by_display_name(disp_name, ci, connected_cnt);
+ if (found != NULL) {
+ /* Save to the camera info array that will be used by the service.
+ * Note that we just copy everything over, and NULL the source
+ * record. */
+ memcpy(csd->camera_info + csd->camera_count, found, sizeof(CameraInfo));
+ /* Update direction parameter. */
+ if (csd->camera_info[csd->camera_count].direction != NULL) {
+ free(csd->camera_info[csd->camera_count].direction);
+ }
+ csd->camera_info[csd->camera_count].direction = ASTRDUP(dir);
+ D("Camera %d '%s' connected to '%s' facing %s using %.4s pixel format",
+ csd->camera_count, csd->camera_info[csd->camera_count].display_name,
+ csd->camera_info[csd->camera_count].device_name,
+ csd->camera_info[csd->camera_count].direction,
+ (const char*)(&csd->camera_info[csd->camera_count].pixel_format));
+ csd->camera_count++;
+ memset(found, 0, sizeof(CameraInfo));
+ }
+ }
+}
+
+/* Gets camera information for the given camera device name.
+ * Param:
+ * cs - Initialized camera service descriptor.
+ * device_name - Camera's device name to look up the information for.
+ * Return:
+ * Camera information pointer on success, or NULL if no camera information has
+ * been found for the given device name.
+ */
+static CameraInfo*
+_camera_service_get_camera_info_by_device_name(CameraServiceDesc* cs,
+ const char* device_name)
+{
+ return _camera_info_get_by_device_name(device_name, cs->camera_info,
+ cs->camera_count);
+}
+
/********************************************************************************
* Helpers for handling camera client queries
*******************************************************************************/
@@ -743,7 +845,7 @@ _camera_client_create(CameraServiceDesc* csd, const char* param)
* then use device name reported in the list to connect to an emulated camera
* service. So, if camera information for the given device name is not found
* in the array, we fail this connection due to protocol violation. */
- ci = _camera_service_get_camera_info(csd, cc->device_name);
+ ci = _camera_service_get_camera_info_by_device_name(csd, cc->device_name);
if (ci == NULL) {
E("%s: Cannot find camera info for device '%s'",
__FUNCTION__, cc->device_name);
@@ -1303,3 +1405,25 @@ android_camera_service_init(void)
D("%s: Registered '%s' qemud service", __FUNCTION__, SERVICE_NAME);
}
}
+
+void
+android_list_web_cameras(void)
+{
+ CameraInfo ci[MAX_CAMERA];
+ int connected_cnt;
+ int i;
+
+ /* Enumerate camera devices connected to the host. */
+ connected_cnt = enumerate_camera_devices(ci, MAX_CAMERA);
+ if (connected_cnt <= 0) {
+ return;
+ }
+
+ printf("List of web cameras connected to the computer:\n");
+ for (i = 0; i < connected_cnt; i++) {
+ printf(" Camera '%s' is connected to device '%s' on channel %d using pixel format '%.4s'\n",
+ ci[i].display_name, ci[i].device_name, ci[i].inp_channel,
+ (const char*)&ci[i].pixel_format);
+ }
+ printf("\n");
+}
diff --git a/android/camera/camera-service.h b/android/camera/camera-service.h
index 6794187..e8df288 100644
--- a/android/camera/camera-service.h
+++ b/android/camera/camera-service.h
@@ -24,4 +24,7 @@
/* Initializes camera emulation service over qemu pipe. */
extern void android_camera_service_init(void);
+/* Lists available web cameras. */
+extern void android_list_web_cameras(void);
+
#endif /* ANDROID_CAMERA_CAMERA_SERVICE_H_ */