diff options
author | Vladimir Chtchetkine <vchtchetkine@google.com> | 2011-09-03 15:17:13 -0700 |
---|---|---|
committer | Vladimir Chtchetkine <vchtchetkine@google.com> | 2011-09-07 10:34:21 -0700 |
commit | c646f5e40ddda3d49b581ac0c78cf748b5dee74c (patch) | |
tree | 6787ec15abd61a9d5e337d1db8a1a8a27faaf15c /android/camera | |
parent | 1875d374acc7412b8b0aacaff073c8080d532924 (diff) | |
download | external_qemu-c646f5e40ddda3d49b581ac0c78cf748b5dee74c.zip external_qemu-c646f5e40ddda3d49b581ac0c78cf748b5dee74c.tar.gz external_qemu-c646f5e40ddda3d49b581ac0c78cf748b5dee74c.tar.bz2 |
Camera service skeleton
Skeleton that implements camera emulation service over QEMU pipe. More meat
will be added as the guest camera emulation develops.
This is a patch taken from approved AOSP commit that didn't go through
because of a merge conflict.
Change-Id: I6f0a2e42be4f5f0bd86d3dbf0c2a609e74b200c2
Diffstat (limited to 'android/camera')
-rw-r--r-- | android/camera/camera-service.c | 322 | ||||
-rw-r--r-- | android/camera/camera-service.h | 27 |
2 files changed, 349 insertions, 0 deletions
diff --git a/android/camera/camera-service.c b/android/camera/camera-service.c new file mode 100644 index 0000000..077809d --- /dev/null +++ b/android/camera/camera-service.c @@ -0,0 +1,322 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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. + */ + +/* + * Contains emulated camera service implementation. + */ + +#include "qemu-common.h" +#include "android/hw-qemud.h" +#include "android/utils/misc.h" +#include "android/utils/system.h" +#include "android/utils/debug.h" +#include "android/camera/camera-capture.h" +#include "android/camera/camera-format-converters.h" +#include "android/camera/camera-service.h" + +#define D(...) VERBOSE_PRINT(camera,__VA_ARGS__) +#define W(...) VERBOSE_PRINT(camera,__VA_ARGS__) +#define E(...) VERBOSE_PRINT(camera,__VA_ARGS__) +#define D_ACTIVE VERBOSE_CHECK(camera) + +#define SERVICE_NAME "camera" + +/* Camera sevice descriptor. */ +typedef struct CameraServiceDesc CameraServiceDesc; +struct CameraServiceDesc { + /* Number of camera devices connected to the host. */ + int camera_count; +}; + +/* One and only one camera service. */ +static CameraServiceDesc _camera_service_desc; + +/******************************************************************************** + * CameraServiceDesc API + *******************************************************************************/ + +/* Initializes camera service descriptor. + */ +static void +_csDesc_init(CameraServiceDesc* csd) +{ + csd->camera_count = 0; +} + +/******************************************************************************** + * Camera Factory API + *******************************************************************************/ + +/* Handles a message received from the emulated camera factory client. + */ +static void +_factory_client_recv(void* opaque, + uint8_t* msg, + int msglen, + QemudClient* client) +{ + // TODO: implement. +} + +/* Emulated camera factory client has been disconnected from the service. + */ +static void +_factory_client_close(void* opaque) +{ +} + +/******************************************************************************** + * Camera client API + *******************************************************************************/ + +/* Describes an emulated camera client. + */ +typedef struct CameraClient CameraClient; +struct CameraClient +{ + /* Client name. + * On Linux this is the name of the camera device. + * On Windows this is the name of capturing window. + */ + char* name; + + /* Input channel to use to connect to the camera. */ + int inp_channel; + + /* Extra parameters passed to the client. */ + char* remaining_param; +}; + +/* Frees emulated camera client descriptor. + */ +static void +_camera_client_free(CameraClient* cc) +{ + if (cc->remaining_param != NULL) { + free(cc->remaining_param); + } + if (cc->name != NULL) { + free(cc->name); + } + + AFREE(cc); +} + +/* Parses emulated camera client parameters. + * Param: + * param - Parameters to parse. This string contains multiple parameters, + * separated by a ':' character. The format of the parameters string is as + * follows: + * <device name>[:<input channel #>][:<extra param>], + * where 'device name' is a required parameter defining name of the camera + * device, 'input channel' is an optional parameter (positive integer), + * defining input channel to use on the camera device. Format of the + * extra parameters is not defined at this point. + * device_name - Upon success contains camera device name. The caller is + * responsible for freeing string buffer returned here. + * inp_channel - Upon success contains the input channel to use when connecting + * to the device. If this parameter is missing, a 0 will be returned here. + * remainder - Contains copy of the string containing remander of the parameters + * following device name and input channel. If there are no remainding + * parameters, a NULL will be returned here. The caller is responsible for + * freeing string buffer returned here. + * Return: + * 0 on success, or !0 on failure. + */ +static int +_parse_camera_client_param(const char* param, + char** device_name, + int* inp_channel, + char** remainder) +{ + const char* wrk = param; + const char* sep; + + *device_name = *remainder = NULL; + *inp_channel = 0; + + /* Sanity check. */ + if (param == NULL || *param == '\0') { + E("%s: Parameters must contain device name", __FUNCTION__); + return -1; + } + + /* Must contain device name. */ + sep = strchr(wrk, ':'); + if (sep == NULL) { + /* Contains only device name. */ + *device_name = ASTRDUP(param); + return 0; + } + + /* Save device name. */ + *device_name = (char*)malloc((sep - wrk) + 1); + if (*device_name == NULL) { + derror("%s: Not enough memory", __FUNCTION__); + return -1; + } + memcpy(*device_name, wrk, sep - wrk); + (*device_name)[sep - wrk] = '\0'; + + /* Move on to the the input channel. */ + wrk = sep + 1; + if (*wrk == '\0') { + return 0; + } + sep = strchr(wrk, ':'); + if (sep == NULL) { + sep = wrk + strlen(wrk); + } + errno = 0; // strtol doesn't set it on success. + *inp_channel = strtol(wrk, (char**)&sep, 10); + if (errno != 0) { + E("%s: Parameters %s contain invalid input channel", + __FUNCTION__, param); + free(*device_name); + *device_name = NULL; + return -1; + } + if (*sep == '\0') { + return 0; + } + + /* Move on to the the remaining string. */ + wrk = sep + 1; + if (*wrk == '\0') { + return 0; + } + *remainder = ASTRDUP(wrk); + + return 0; +} + +/* Creates descriptor for a connecting emulated camera client. + * Param: + * csd - Camera service descriptor. + * param - Client parameters. Must be formatted as follows: + * - Multiple parameters are separated by ':' + * - Must begin with camera device name + * - Can follow with an optional input channel number, wich must be an + * integer value + * Return: + * Emulated camera client descriptor on success, or NULL on failure. + */ +static CameraClient* +_camera_client_create(CameraServiceDesc* csd, const char* param) +{ + CameraClient* cc; + int res; + + ANEW0(cc); + + /* Parse parameters, and save them to the client. */ + res = _parse_camera_client_param(param, &cc->name, &cc->inp_channel, + &cc->remaining_param); + if (res) { + _camera_client_free(cc); + return NULL; + } + + D("Camera client created: name=%s, inp_channel=%d", + cc->name, cc->inp_channel); + return cc; +} + +/* Handles a message received from the emulated camera client. + */ +static void +_camera_client_recv(void* opaque, + uint8_t* msg, + int msglen, + QemudClient* client) +{ + CameraClient* cc = (CameraClient*)opaque; + + // TODO: implement! +} + +/* Emulated camera client has been disconnected from the service. + */ +static void +_camera_client_close(void* opaque) +{ + CameraClient* cc = (CameraClient*)opaque; + + D("Camera client closed: name=%s, inp_channel=%d", + cc->name, cc->inp_channel); + + _camera_client_free(cc); +} + +/******************************************************************************** + * Camera service API + *******************************************************************************/ + +/* Connects a client to the camera service. + * There are two classes of the client that can connect to the service: + * - Camera factory that is insterested only in listing camera devices attached + * to the host. + * - Camera device emulators that attach to the actual camera devices. + * The distinction between these two classes is made by looking at extra + * parameters passed in client_param variable. If it's NULL, or empty, the client + * connects to a camera factory. Otherwise, parameters describe the camera device + * the client wants to connect to. + */ +static QemudClient* +_camera_service_connect(void* opaque, + QemudService* serv, + int channel, + const char* client_param) +{ + QemudClient* client = NULL; + CameraServiceDesc* csd = (CameraServiceDesc*)opaque; + + if (client_param == NULL || *client_param == '\0') { + /* This is an emulated camera factory client. */ + client = qemud_client_new(serv, channel, client_param, csd, + _factory_client_recv, _factory_client_close, + NULL, NULL); + } else { + /* This is an emulated camera client. */ + CameraClient* cc = _camera_client_create(csd, client_param); + if (cc != NULL) { + client = qemud_client_new(serv, channel, client_param, cc, + _camera_client_recv, _camera_client_close, + NULL, NULL); + } + } + + return client; +} + +void +android_camera_service_init(void) +{ + static int _inited = 0; + + if (!_inited) { + _csDesc_init(&_camera_service_desc); + QemudService* serv = qemud_service_register( SERVICE_NAME, 0, + &_camera_service_desc, + _camera_service_connect, + NULL, NULL); + if (serv == NULL) { + derror("could not register '%s' service", SERVICE_NAME); + return; + } + D("registered '%s' qemud service", SERVICE_NAME); + } +} diff --git a/android/camera/camera-service.h b/android/camera/camera-service.h new file mode 100644 index 0000000..6794187 --- /dev/null +++ b/android/camera/camera-service.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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. + */ + +#ifndef ANDROID_CAMERA_CAMERA_SERVICE_H_ +#define ANDROID_CAMERA_CAMERA_SERVICE_H_ + +/* + * Contains public camera service API. + */ + +/* Initializes camera emulation service over qemu pipe. */ +extern void android_camera_service_init(void); + +#endif /* ANDROID_CAMERA_CAMERA_SERVICE_H_ */ |