1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * Contains emulated camera service implementation. 19 */ 20 21 #include "qemu-common.h" 22 #include "android/globals.h" /* for android_hw */ 23 #include "android/hw-qemud.h" 24 #include "android/utils/misc.h" 25 #include "android/utils/system.h" 26 #include "android/utils/debug.h" 27 #include "android/camera/camera-capture.h" 28 #include "android/camera/camera-format-converters.h" 29 #include "android/camera/camera-service.h" 30 31 #define E(...) derror(__VA_ARGS__) 32 #define W(...) dwarning(__VA_ARGS__) 33 #define D(...) VERBOSE_PRINT(camera,__VA_ARGS__) 34 #define D_ACTIVE VERBOSE_CHECK(camera) 35 36 /* the T(...) macro is used to dump traffic */ 37 #define T_ACTIVE 0 38 39 #if T_ACTIVE 40 #define T(...) VERBOSE_PRINT(camera,__VA_ARGS__) 41 #else 42 #define T(...) ((void)0) 43 #endif 44 45 /* Defines name of the camera service. */ 46 #define SERVICE_NAME "camera" 47 48 /* Maximum number of supported emulated cameras. */ 49 #define MAX_CAMERA 8 50 51 /* Camera sevice descriptor. */ 52 typedef struct CameraServiceDesc CameraServiceDesc; 53 struct CameraServiceDesc { 54 /* Information about camera devices connected to the host. 55 * Note that once initialized, entries in this array are considered to be 56 * constant. */ 57 CameraInfo camera_info[MAX_CAMERA]; 58 /* Number of camera devices connected to the host. */ 59 int camera_count; 60 }; 61 62 /* One and only one camera service. */ 63 static CameraServiceDesc _camera_service_desc; 64 65 /******************************************************************************** 66 * Helper routines 67 *******************************************************************************/ 68 69 /* A strict 'int' version of the 'strtol'. 70 * This routine is implemented on top of the standard 'strtol' for 32/64 bit 71 * portability. 72 */ 73 static int 74 strtoi(const char *nptr, char **endptr, int base) 75 { 76 long val; 77 78 errno = 0; 79 val = strtol(nptr, endptr, base); 80 if (errno) { 81 return (val == LONG_MAX) ? INT_MAX : INT_MIN; 82 } else { 83 if (val == (int)val) { 84 return (int)val; 85 } else { 86 errno = ERANGE; 87 return val > 0 ? INT_MAX : INT_MIN; 88 } 89 } 90 } 91 92 /* Gets a parameter value out of the parameter string. 93 * All parameters that are passed to the camera service are formatted as such: 94 * "<name1>=<value1> <name2>=<value2> ... <nameN>=<valueN>" 95 * I.e.: 96 * - Every parameter must have a name, and a value. 97 * - Name and value must be separated with '='. 98 * - No spaces are allowed around '=' separating name and value. 99 * - Parameters must be separated with a single ' ' character. 100 * - No '=' character is allowed in name and in value. 101 * Param: 102 * params - String, containing the parameters. 103 * name - Parameter name. 104 * value - Upon success contains value for the given parameter. 105 * val_size - Size of the 'value' string buffer. 106 * Return: 107 * 0 on success, -1 if requested parameter is not found, or (a positive) number 108 * of bytes, required to make a copy of the parameter's value if 'value' string 109 * was too small to contain it. 110 */ 111 static int 112 _get_param_value(const char* params, const char* name, char* value, int val_size) 113 { 114 const char* val_end; 115 int len = strlen(name); 116 const char* par_end = params + strlen(params); 117 const char* par_start = strstr(params, name); 118 119 /* Search for 'name=' */ 120 while (par_start != NULL) { 121 /* Make sure that we're within the parameters buffer. */ 122 if ((par_end - par_start) < len) { 123 par_start = NULL; 124 break; 125 } 126 /* Make sure that par_start starts at the beginning of <name>, and only 127 * then check for '=' value separator. */ 128 if ((par_start == params || (*(par_start - 1) == ' ')) && 129 par_start[len] == '=') { 130 break; 131 } 132 /* False positive. Move on... */ 133 par_start = strstr(par_start + 1, name); 134 } 135 if (par_start == NULL) { 136 return -1; 137 } 138 139 /* Advance past 'name=', and calculate value's string length. */ 140 par_start += len + 1; 141 val_end = strchr(par_start, ' '); 142 if (val_end == NULL) { 143 val_end = par_start + strlen(par_start); 144 } 145 len = val_end - par_start; 146 147 /* Check if fits... */ 148 if ((len + 1) <= val_size) { 149 memcpy(value, par_start, len); 150 value[len] = '\0'; 151 return 0; 152 } else { 153 return len + 1; 154 } 155 } 156 157 /* Gets a parameter value out of the parameter string. 158 * This routine is similar to _get_param_value, except it will always allocate 159 * a string buffer for the value. 160 * Param: 161 * params - String, containing the parameters. 162 * name - Parameter name. 163 * value - Upon success contains an allocated string containint the value for 164 * the given parameter. The caller is responsible for freeing the buffer 165 * returned in this parameter on success. 166 * Return: 167 * 0 on success, -1 if requested parameter is not found, or -2 on 168 * memory failure. 169 */ 170 static int 171 _get_param_value_alloc(const char* params, const char* name, char** value) 172 { 173 char tmp; 174 int res; 175 176 /* Calculate size of string buffer required for the value. */ 177 const int val_size = _get_param_value(params, name, &tmp, 0); 178 if (val_size < 0) { 179 *value = NULL; 180 return val_size; 181 } 182 183 /* Allocate string buffer, and retrieve the value. */ 184 *value = (char*)malloc(val_size); 185 if (*value == NULL) { 186 E("%s: Unable to allocated %d bytes for string buffer.", 187 __FUNCTION__, val_size); 188 return -2; 189 } 190 res = _get_param_value(params, name, *value, val_size); 191 if (res) { 192 E("%s: Unable to retrieve value into allocated buffer.", __FUNCTION__); 193 free(*value); 194 *value = NULL; 195 } 196 197 return res; 198 } 199 200 /* Gets an integer parameter value out of the parameter string. 201 * Param: 202 * params - String, containing the parameters. See comments to _get_param_value 203 * routine on the parameters format. 204 * name - Parameter name. Parameter value must be a decimal number. 205 * value - Upon success contains integer value for the given parameter. 206 * Return: 207 * 0 on success, or -1 if requested parameter is not found, or -2 if parameter's 208 * format was bad (i.e. value was not a decimal number). 209 */ 210 static int 211 _get_param_value_int(const char* params, const char* name, int* value) 212 { 213 char val_str[64]; // Should be enough for all numeric values. 214 if (!_get_param_value(params, name, val_str, sizeof(val_str))) { 215 errno = 0; 216 *value = strtoi(val_str, (char**)NULL, 10); 217 if (errno) { 218 E("%s: Value '%s' of the parameter '%s' in '%s' is not a decimal number.", 219 __FUNCTION__, val_str, name, params); 220 return -2; 221 } else { 222 return 0; 223 } 224 } else { 225 return -1; 226 } 227 } 228 229 /* Extracts query name, and (optionally) query parameters from the query string. 230 * Param: 231 * query - Query string. Query string in the camera service are formatted as such: 232 * "<query name>[ <parameters>]", 233 * where parameters are optional, and if present, must be separated from the 234 * query name with a single ' '. See comments to _get_param_value routine 235 * for the format of the parameters string. 236 * query_name - Upon success contains query name extracted from the query 237 * string. 238 * query_name_size - Buffer size for 'query_name' string. 239 * query_param - Upon success contains a pointer to the beginning of the query 240 * parameters. If query has no parameters, NULL will be passed back with 241 * this parameter. This parameter is optional and can be NULL. 242 * Return: 243 * 0 on success, or number of bytes required for query name if 'query_name' 244 * string buffer was too small to contain it. 245 */ 246 static int 247 _parse_query(const char* query, 248 char* query_name, 249 int query_name_size, 250 const char** query_param) 251 { 252 /* Extract query name. */ 253 const char* qend = strchr(query, ' '); 254 if (qend == NULL) { 255 qend = query + strlen(query); 256 } 257 if ((qend - query) >= query_name_size) { 258 return qend - query + 1; 259 } 260 memcpy(query_name, query, qend - query); 261 query_name[qend - query] = '\0'; 262 263 /* Calculate query parameters pointer (if needed) */ 264 if (query_param != NULL) { 265 if (*qend == ' ') { 266 qend++; 267 } 268 *query_param = (*qend == '\0') ? NULL : qend; 269 } 270 271 return 0; 272 } 273 274 /* Appends one string to another, growing the destination string buffer if 275 * needed. 276 * Param: 277 * str_buffer - Contains pointer to the destination string buffer. Content of 278 * this parameter can be NULL. Note that content of this parameter will 279 * change if string buffer has been reallocated. 280 * str_buf_size - Contains current buffer size of the string, addressed by 281 * 'str_buffer' parameter. Note that content of this parameter will change 282 * if string buffer has been reallocated. 283 * str - String to append. 284 * Return: 285 * 0 on success, or -1 on failure (memory allocation). 286 */ 287 static int 288 _append_string(char** str_buf, size_t* str_buf_size, const char* str) 289 { 290 const size_t offset = (*str_buf != NULL) ? strlen(*str_buf) : 0; 291 const size_t append_bytes = strlen(str) + 1; 292 293 /* Make sure these two match. */ 294 if (*str_buf == NULL) { 295 *str_buf_size = 0; 296 } 297 298 if ((offset + append_bytes) > *str_buf_size) { 299 /* Reallocate string, so it can fit what's being append to it. Note that 300 * we reallocate a bit bigger buffer than is needed in order to minimize 301 * number of memory allocation calls in case there are more "appends" 302 * coming. */ 303 const size_t required_mem = offset + append_bytes + 256; 304 char* new_buf = (char*)realloc(*str_buf, required_mem); 305 if (new_buf == NULL) { 306 E("%s: Unable to allocate %d bytes for a string", 307 __FUNCTION__, required_mem); 308 return -1; 309 } 310 *str_buf = new_buf; 311 *str_buf_size = required_mem; 312 } 313 memcpy(*str_buf + offset, str, append_bytes); 314 315 return 0; 316 } 317 318 /* Represents camera information as a string formatted as follows: 319 * 'name=<devname> channel=<num> pix=<format> facing=<direction> framedims=<widh1xheight1,...>\n' 320 * Param: 321 * ci - Camera information descriptor to convert into a string. 322 * str - Pointer to the string buffer where to save the converted camera 323 * information descriptor. On entry, content of this parameter can be NULL. 324 * Note that string buffer addressed with this parameter may be reallocated 325 * in this routine, so (if not NULL) it must contain a buffer allocated with 326 * malloc. The caller is responsible for freeing string buffer returned in 327 * this parameter. 328 * str_size - Contains byte size of the buffer addressed by 'str' parameter. 329 * Return: 330 * 0 on success, or != 0 on failure. 331 */ 332 static int 333 _camera_info_to_string(const CameraInfo* ci, char** str, size_t* str_size) { 334 int res; 335 int n; 336 char tmp[128]; 337 338 /* Append device name. */ 339 snprintf(tmp, sizeof(tmp), "name=%s ", ci->device_name); 340 res = _append_string(str, str_size, tmp); 341 if (res) { 342 return res; 343 } 344 /* Append input channel. */ 345 snprintf(tmp, sizeof(tmp), "channel=%d ", ci->inp_channel); 346 res = _append_string(str, str_size, tmp); 347 if (res) { 348 return res; 349 } 350 /* Append pixel format. */ 351 snprintf(tmp, sizeof(tmp), "pix=%d ", ci->pixel_format); 352 res = _append_string(str, str_size, tmp); 353 if (res) { 354 return res; 355 } 356 /* Append direction. */ 357 snprintf(tmp, sizeof(tmp), "dir=%s ", ci->direction); 358 res = _append_string(str, str_size, tmp); 359 if (res) { 360 return res; 361 } 362 /* Append supported frame sizes. */ 363 snprintf(tmp, sizeof(tmp), "framedims=%dx%d", 364 ci->frame_sizes[0].width, ci->frame_sizes[0].height); 365 res = _append_string(str, str_size, tmp); 366 if (res) { 367 return res; 368 } 369 for (n = 1; n < ci->frame_sizes_num; n++) { 370 snprintf(tmp, sizeof(tmp), ",%dx%d", 371 ci->frame_sizes[n].width, ci->frame_sizes[n].height); 372 res = _append_string(str, str_size, tmp); 373 if (res) { 374 return res; 375 } 376 } 377 378 /* Stringified camera properties should end with EOL. */ 379 return _append_string(str, str_size, "\n"); 380 } 381 382 /* Gets camera information matching a display name. 383 * Param: 384 * disp_name - Display name to match. 385 * arr - Array of camera informations. 386 * num - Number of elements in the array. 387 * Return: 388 * Matching camera information, or NULL if matching camera information for the 389 * given display name has not been found in the array. 390 */ 391 static CameraInfo* 392 _camera_info_get_by_display_name(const char* disp_name, CameraInfo* arr, int num) 393 { 394 int n; 395 for (n = 0; n < num; n++) { 396 if (arr[n].display_name != NULL && !strcmp(arr[n].display_name, disp_name)) { 397 return &arr[n]; 398 } 399 } 400 return NULL; 401 } 402 403 /* Gets camera information matching a device name. 404 * Param: 405 * device_name - Device name to match. 406 * arr - Array of camera informations. 407 * num - Number of elements in the array. 408 * Return: 409 * Matching camera information, or NULL if matching camera information for the 410 * given device name has not been found in the array. 411 */ 412 static CameraInfo* 413 _camera_info_get_by_device_name(const char* device_name, CameraInfo* arr, int num) 414 { 415 int n; 416 for (n = 0; n < num; n++) { 417 if (arr[n].device_name != NULL && !strcmp(arr[n].device_name, device_name)) { 418 return &arr[n]; 419 } 420 } 421 return NULL; 422 } 423 424 /******************************************************************************** 425 * CameraServiceDesc API 426 *******************************************************************************/ 427 428 /* Initializes camera service descriptor. 429 */ 430 static void 431 _camera_service_init(CameraServiceDesc* csd) 432 { 433 CameraInfo ci[MAX_CAMERA]; 434 int connected_cnt; 435 int i; 436 437 /* Enumerate camera devices connected to the host. */ 438 memset(ci, 0, sizeof(CameraInfo) * MAX_CAMERA); 439 memset(csd->camera_info, 0, sizeof(CameraInfo) * MAX_CAMERA); 440 csd->camera_count = 0; 441 connected_cnt = enumerate_camera_devices(ci, MAX_CAMERA); 442 if (connected_cnt <= 0) { 443 /* Nothing is connected - nothing to emulate. */ 444 return; 445 } 446 447 /* For each webcam declared in hw.ini find an actual camera information 448 * descriptor, and save it into the service descriptor for the emulation. 449 * Stop the loop when all the connected cameras have been added to the 450 * service. */ 451 for (i = 0; i < android_hw->hw_webcam_count && 452 csd->camera_count < connected_cnt; i++) { 453 const char* disp_name; 454 const char* dir; 455 CameraInfo* found; 456 457 switch (i) { 458 case 0: 459 disp_name = android_hw->hw_webcam_0_name; 460 dir = android_hw->hw_webcam_0_direction; 461 break; 462 case 1: 463 disp_name = android_hw->hw_webcam_1_name; 464 dir = android_hw->hw_webcam_1_direction; 465 break; 466 case 2: 467 disp_name = android_hw->hw_webcam_2_name; 468 dir = android_hw->hw_webcam_2_direction; 469 break; 470 case 3: 471 disp_name = android_hw->hw_webcam_3_name; 472 dir = android_hw->hw_webcam_3_direction; 473 break; 474 case 4: 475 disp_name = android_hw->hw_webcam_4_name; 476 dir = android_hw->hw_webcam_4_direction; 477 break; 478 case 5: 479 default: 480 disp_name = android_hw->hw_webcam_5_name; 481 dir = android_hw->hw_webcam_5_direction; 482 break; 483 } 484 found = _camera_info_get_by_display_name(disp_name, ci, connected_cnt); 485 if (found != NULL) { 486 /* Save to the camera info array that will be used by the service. 487 * Note that we just copy everything over, and NULL the source 488 * record. */ 489 memcpy(csd->camera_info + csd->camera_count, found, sizeof(CameraInfo)); 490 /* Update direction parameter. */ 491 if (csd->camera_info[csd->camera_count].direction != NULL) { 492 free(csd->camera_info[csd->camera_count].direction); 493 } 494 csd->camera_info[csd->camera_count].direction = ASTRDUP(dir); 495 D("Camera %d '%s' connected to '%s' facing %s using %.4s pixel format", 496 csd->camera_count, csd->camera_info[csd->camera_count].display_name, 497 csd->camera_info[csd->camera_count].device_name, 498 csd->camera_info[csd->camera_count].direction, 499 (const char*)(&csd->camera_info[csd->camera_count].pixel_format)); 500 csd->camera_count++; 501 memset(found, 0, sizeof(CameraInfo)); 502 } else { 503 W("Camera name '%s' is not found in the list of connected cameras.\n" 504 "Use '-webcam list' emulator option to obtain the list of connected camera names.\n", 505 disp_name); 506 } 507 } 508 509 /* Make sure that camera 0 and camera 1 are facing in opposite directions. 510 * If they don't the camera application will crash on an attempt to switch 511 * cameras. */ 512 if (csd->camera_count > 0) { 513 const char* cam2_dir = NULL; 514 const char* cam2_name = NULL; 515 if (csd->camera_count >= 2) { 516 cam2_dir = csd->camera_info[1].direction; 517 cam2_name = csd->camera_info[1].display_name; 518 } else if (strcmp(android_hw->hw_fakeCamera, "off")) { 519 cam2_dir = android_hw->hw_fakeCamera; 520 cam2_name = "fake camera"; 521 } 522 if (cam2_dir != NULL && !strcmp(csd->camera_info[0].direction, cam2_dir)) { 523 W("Cameras '%s' and '%s' are both facing %s.\n" 524 "It is required by the camera application that first two emulated cameras\n" 525 "are facing in opposite directions. If they both are facing in the same direction,\n" 526 "the camera application will crash on an attempt to switch the camera.\n", 527 csd->camera_info[0].display_name, cam2_name, cam2_dir); 528 529 } 530 } 531 } 532 533 /* Gets camera information for the given camera device name. 534 * Param: 535 * cs - Initialized camera service descriptor. 536 * device_name - Camera's device name to look up the information for. 537 * Return: 538 * Camera information pointer on success, or NULL if no camera information has 539 * been found for the given device name. 540 */ 541 static CameraInfo* 542 _camera_service_get_camera_info_by_device_name(CameraServiceDesc* cs, 543 const char* device_name) 544 { 545 return _camera_info_get_by_device_name(device_name, cs->camera_info, 546 cs->camera_count); 547 } 548 549 /******************************************************************************** 550 * Helpers for handling camera client queries 551 *******************************************************************************/ 552 553 /* Formats paload size according to the protocol, and sends it to the client. 554 * To simplify endianess handling we convert payload size to an eight characters 555 * string, representing payload size value in hexadecimal format. 556 * Param: 557 * qc - Qemu client to send the payload size to. 558 * payload_size - Payload size to report to the client. 559 */ 560 static void 561 _qemu_client_reply_payload(QemudClient* qc, size_t payload_size) 562 { 563 char payload_size_str[9]; 564 snprintf(payload_size_str, sizeof(payload_size_str), "%08x", payload_size); 565 qemud_client_send(qc, (const uint8_t*)payload_size_str, 8); 566 } 567 568 /* 569 * Prefixes for replies to camera client queries. 570 */ 571 572 /* Success, no data to send in reply. */ 573 #define OK_REPLY "ok" 574 /* Failure, no data to send in reply. */ 575 #define KO_REPLY "ko" 576 /* Success, there are data to send in reply. */ 577 #define OK_REPLY_DATA OK_REPLY ":" 578 /* Failure, there are data to send in reply. */ 579 #define KO_REPLY_DATA KO_REPLY ":" 580 581 /* Builds and sends a reply to a query. 582 * All replies to a query in camera service have a prefix indicating whether the 583 * query has succeeded ("ok"), or failed ("ko"). The prefix can be followed by 584 * extra data, containing response to the query. In case there are extra data, 585 * they are separated from the prefix with a ':' character. 586 * Param: 587 * qc - Qemu client to send the reply to. 588 * ok_ko - An "ok", or "ko" selector, where 0 is for "ko", and !0 is for "ok". 589 * extra - Optional extra query data. Can be NULL. 590 * extra_size - Extra data size. 591 */ 592 static void 593 _qemu_client_query_reply(QemudClient* qc, 594 int ok_ko, 595 const void* extra, 596 size_t extra_size) 597 { 598 const char* ok_ko_str; 599 size_t payload_size; 600 601 /* Make sure extra_size is 0 if extra is NULL. */ 602 if (extra == NULL && extra_size != 0) { 603 W("%s: 'extra' = NULL, while 'extra_size' = %d", 604 __FUNCTION__, extra, extra_size); 605 extra_size = 0; 606 } 607 608 /* Calculate total payload size, and select appropriate 'ok'/'ko' prefix */ 609 if (extra_size) { 610 /* 'extra' size + 2 'ok'/'ko' bytes + 1 ':' separator byte. */ 611 payload_size = extra_size + 3; 612 ok_ko_str = ok_ko ? OK_REPLY_DATA : KO_REPLY_DATA; 613 } else { 614 /* No extra data: just zero-terminated 'ok'/'ko'. */ 615 payload_size = 3; 616 ok_ko_str = ok_ko ? OK_REPLY : KO_REPLY; 617 } 618 619 /* Send payload size first. */ 620 _qemu_client_reply_payload(qc, payload_size); 621 /* Send 'ok[:]'/'ko[:]' next. Note that if there is no extra data, we still 622 * need to send a zero-terminator for 'ok'/'ko' string instead of the ':' 623 * separator. So, one way or another, the prefix is always 3 bytes. */ 624 qemud_client_send(qc, (const uint8_t*)ok_ko_str, 3); 625 /* Send extra data (if present). */ 626 if (extra != NULL) { 627 qemud_client_send(qc, (const uint8_t*)extra, extra_size); 628 } 629 } 630 631 /* Replies query success ("OK") back to the client. 632 * Param: 633 * qc - Qemu client to send the reply to. 634 * ok_str - An optional string containing query results. Can be NULL. 635 */ 636 static void 637 _qemu_client_reply_ok(QemudClient* qc, const char* ok_str) 638 { 639 _qemu_client_query_reply(qc, 1, ok_str, 640 (ok_str != NULL) ? (strlen(ok_str) + 1) : 0); 641 } 642 643 /* Replies query failure ("KO") back to the client. 644 * Param: 645 * qc - Qemu client to send the reply to. 646 * ko_str - An optional string containing reason for failure. Can be NULL. 647 */ 648 static void 649 _qemu_client_reply_ko(QemudClient* qc, const char* ko_str) 650 { 651 _qemu_client_query_reply(qc, 0, ko_str, 652 (ko_str != NULL) ? (strlen(ko_str) + 1) : 0); 653 } 654 655 /******************************************************************************** 656 * Camera Factory API 657 *******************************************************************************/ 658 659 /* Handles 'list' query received from the Factory client. 660 * Response to this query is a string that represents each connected camera in 661 * this format: 'name=devname framedims=widh1xheight1,widh2xheight2,widhNxheightN\n' 662 * Strings, representing each camera are separated with EOL symbol. 663 * Param: 664 * csd, client - Factory serivice, and client. 665 * Return: 666 * 0 on success, or != 0 on failure. 667 */ 668 static int 669 _factory_client_list_cameras(CameraServiceDesc* csd, QemudClient* client) 670 { 671 int n; 672 size_t reply_size = 0; 673 char* reply = NULL; 674 675 /* Lets see if there was anything found... */ 676 if (csd->camera_count == 0) { 677 /* No cameras connected to the host. Reply with "\n" */ 678 _qemu_client_reply_ok(client, "\n"); 679 return 0; 680 } 681 682 /* "Stringify" each camera information into the reply string. */ 683 for (n = 0; n < csd->camera_count; n++) { 684 const int res = 685 _camera_info_to_string(csd->camera_info + n, &reply, &reply_size); 686 if (res) { 687 if (reply != NULL) { 688 free(reply); 689 } 690 _qemu_client_reply_ko(client, "Memory allocation error"); 691 return res; 692 } 693 } 694 695 D("%s Replied: %s", __FUNCTION__, reply); 696 _qemu_client_reply_ok(client, reply); 697 free(reply); 698 699 return 0; 700 } 701 702 /* Handles a message received from the emulated camera factory client. 703 * Queries received here are represented as strings: 704 * 'list' - Queries list of cameras connected to the host. 705 * Param: 706 * opaque - Camera service descriptor. 707 * msg, msglen - Message received from the camera factory client. 708 * client - Camera factory client pipe. 709 */ 710 static void 711 _factory_client_recv(void* opaque, 712 uint8_t* msg, 713 int msglen, 714 QemudClient* client) 715 { 716 /* 717 * Emulated camera factory client queries. 718 */ 719 720 /* List cameras connected to the host. */ 721 static const char _query_list[] = "list"; 722 723 CameraServiceDesc* csd = (CameraServiceDesc*)opaque; 724 char query_name[64]; 725 const char* query_param = NULL; 726 727 /* Parse the query, extracting query name and parameters. */ 728 if (_parse_query((const char*)msg, query_name, sizeof(query_name), 729 &query_param)) { 730 E("%s: Invalid format in query '%s'", __FUNCTION__, (const char*)msg); 731 _qemu_client_reply_ko(client, "Invalid query format"); 732 return; 733 } 734 735 D("%s Camera factory query '%s'", __FUNCTION__, query_name); 736 737 /* Dispatch the query to an appropriate handler. */ 738 if (!strcmp(query_name, _query_list)) { 739 /* This is a "list" query. */ 740 _factory_client_list_cameras(csd, client); 741 } else { 742 E("%s: Unknown camera factory query name in '%s'", 743 __FUNCTION__, (const char*)msg); 744 _qemu_client_reply_ko(client, "Unknown query name"); 745 } 746 } 747 748 /* Emulated camera factory client has been disconnected from the service. */ 749 static void 750 _factory_client_close(void* opaque) 751 { 752 /* There is nothing to clean up here: factory service is just an alias for 753 * the "root" camera service, that doesn't require anything more, than camera 754 * dervice descriptor already provides. */ 755 } 756 757 /******************************************************************************** 758 * Camera client API 759 *******************************************************************************/ 760 761 /* Describes an emulated camera client. 762 */ 763 typedef struct CameraClient CameraClient; 764 struct CameraClient 765 { 766 /* Client name. 767 * On Linux this is the name of the camera device. 768 * On Windows this is the name of capturing window. 769 */ 770 char* device_name; 771 /* Input channel to use to connect to the camera. */ 772 int inp_channel; 773 /* Camera information. */ 774 const CameraInfo* camera_info; 775 /* Emulated camera device descriptor. */ 776 CameraDevice* camera; 777 /* Buffer allocated for video frames. 778 * Note that memory allocated for this buffer 779 * also contains preview framebuffer. */ 780 uint8_t* video_frame; 781 /* Preview frame buffer. 782 * This address points inside the 'video_frame' buffer. */ 783 uint16_t* preview_frame; 784 /* Byte size of the videoframe buffer. */ 785 size_t video_frame_size; 786 /* Byte size of the preview frame buffer. */ 787 size_t preview_frame_size; 788 /* Pixel format required by the guest. */ 789 uint32_t pixel_format; 790 /* Frame width. */ 791 int width; 792 /* Frame height. */ 793 int height; 794 /* Number of pixels in a frame buffer. */ 795 int pixel_num; 796 /* Status of video and preview frame cache. */ 797 int frames_cached; 798 }; 799 800 /* Frees emulated camera client descriptor. */ 801 static void 802 _camera_client_free(CameraClient* cc) 803 { 804 /* The only exception to the "read only" rule: we have to mark the camera 805 * as being not used when we destroy a service for it. */ 806 if (cc->camera_info != NULL) { 807 ((CameraInfo*)cc->camera_info)->in_use = 0; 808 } 809 if (cc->camera != NULL) { 810 camera_device_close(cc->camera); 811 } 812 if (cc->video_frame != NULL) { 813 free(cc->video_frame); 814 } 815 if (cc->device_name != NULL) { 816 free(cc->device_name); 817 } 818 819 AFREE(cc); 820 } 821 822 /* Creates descriptor for a connecting emulated camera client. 823 * Param: 824 * csd - Camera service descriptor. 825 * param - Client parameters. Must be formatted as described in comments to 826 * _get_param_value routine, and must contain at least 'name' parameter, 827 * identifiying the camera device to create the service for. Also parameters 828 * may contain a decimal 'inp_channel' parameter, selecting the input 829 * channel to use when communicating with the camera device. 830 * Return: 831 * Emulated camera client descriptor on success, or NULL on failure. 832 */ 833 static CameraClient* 834 _camera_client_create(CameraServiceDesc* csd, const char* param) 835 { 836 CameraClient* cc; 837 CameraInfo* ci; 838 int res; 839 ANEW0(cc); 840 841 /* 842 * Parse parameter string, containing camera client properties. 843 */ 844 845 /* Pull required device name. */ 846 if (_get_param_value_alloc(param, "name", &cc->device_name)) { 847 E("%s: Allocation failure, or required 'name' parameter is missing, or misformed in '%s'", 848 __FUNCTION__, param); 849 return NULL; 850 } 851 852 /* Pull optional input channel. */ 853 res = _get_param_value_int(param, "inp_channel", &cc->inp_channel); 854 if (res != 0) { 855 if (res == -1) { 856 /* 'inp_channel' parameter has been ommited. Use default input 857 * channel, which is zero. */ 858 cc->inp_channel = 0; 859 } else { 860 E("%s: 'inp_channel' parameter is misformed in '%s'", 861 __FUNCTION__, param); 862 return NULL; 863 } 864 } 865 866 /* Get camera info for the emulated camera represented with this service. 867 * Array of camera information records has been created when the camera 868 * service was enumerating camera devices during the service initialization. 869 * By the camera service protocol, camera service clients must first obtain 870 * list of enumerated cameras via the 'list' query to the camera service, and 871 * then use device name reported in the list to connect to an emulated camera 872 * service. So, if camera information for the given device name is not found 873 * in the array, we fail this connection due to protocol violation. */ 874 ci = _camera_service_get_camera_info_by_device_name(csd, cc->device_name); 875 if (ci == NULL) { 876 E("%s: Cannot find camera info for device '%s'", 877 __FUNCTION__, cc->device_name); 878 _camera_client_free(cc); 879 return NULL; 880 } 881 882 /* We can't allow multiple camera services for a single camera device, Lets 883 * make sure that there is no client created for this camera. */ 884 if (ci->in_use) { 885 E("%s: Camera device '%s' is in use", __FUNCTION__, cc->device_name); 886 _camera_client_free(cc); 887 return NULL; 888 } 889 890 /* We're done. Set camera in use, and succeed the connection. */ 891 ci->in_use = 1; 892 cc->camera_info = ci; 893 894 D("%s: Camera service is created for device '%s' using input channel %d", 895 __FUNCTION__, cc->device_name, cc->inp_channel); 896 897 return cc; 898 } 899 900 /******************************************************************************** 901 * Camera client queries 902 *******************************************************************************/ 903 904 /* Client has queried conection to the camera. 905 * Param: 906 * cc - Queried camera client descriptor. 907 * qc - Qemu client for the emulated camera. 908 * param - Query parameters. There are no parameters expected for this query. 909 */ 910 static void 911 _camera_client_query_connect(CameraClient* cc, QemudClient* qc, const char* param) 912 { 913 if (cc->camera != NULL) { 914 /* Already connected. */ 915 W("%s: Camera '%s' is already connected", __FUNCTION__, cc->device_name); 916 _qemu_client_reply_ok(qc, "Camera is already connected"); 917 return; 918 } 919 920 /* Open camera device. */ 921 cc->camera = camera_device_open(cc->device_name, cc->inp_channel); 922 if (cc->camera == NULL) { 923 E("%s: Unable to open camera device '%s'", __FUNCTION__, cc->device_name); 924 _qemu_client_reply_ko(qc, "Unable to open camera device."); 925 return; 926 } 927 928 D("%s: Camera device '%s' is now connected", __FUNCTION__, cc->device_name); 929 930 _qemu_client_reply_ok(qc, NULL); 931 } 932 933 /* Client has queried disconection from the camera. 934 * Param: 935 * cc - Queried camera client descriptor. 936 * qc - Qemu client for the emulated camera. 937 * param - Query parameters. There are no parameters expected for this query. 938 */ 939 static void 940 _camera_client_query_disconnect(CameraClient* cc, 941 QemudClient* qc, 942 const char* param) 943 { 944 if (cc->camera == NULL) { 945 /* Already disconnected. */ 946 W("%s: Camera '%s' is already disconnected", __FUNCTION__, cc->device_name); 947 _qemu_client_reply_ok(qc, "Camera is not connected"); 948 return; 949 } 950 951 /* Before we can go ahead and disconnect, we must make sure that camera is 952 * not capturing frames. */ 953 if (cc->video_frame != NULL) { 954 E("%s: Cannot disconnect camera '%s' while it is not stopped", 955 __FUNCTION__, cc->device_name); 956 _qemu_client_reply_ko(qc, "Camera is not stopped"); 957 return; 958 } 959 960 /* Close camera device. */ 961 camera_device_close(cc->camera); 962 cc->camera = NULL; 963 964 D("Camera device '%s' is now disconnected", cc->device_name); 965 966 _qemu_client_reply_ok(qc, NULL); 967 } 968 969 /* Client has queried the client to start capturing video. 970 * Param: 971 * cc - Queried camera client descriptor. 972 * qc - Qemu client for the emulated camera. 973 * param - Query parameters. Parameters for this query must contain a 'dim', and 974 * a 'pix' parameters, where 'dim' must be "dim=<width>x<height>", and 'pix' 975 * must be "pix=<format>", where 'width' and 'height' must be numerical 976 * values for the capturing video frame width, and height, and 'format' must 977 * be a numerical value for the pixel format of the video frames expected by 978 * the client. 'format' must be one of the V4L2_PIX_FMT_XXX values. 979 */ 980 static void 981 _camera_client_query_start(CameraClient* cc, QemudClient* qc, const char* param) 982 { 983 char* w; 984 char dim[64]; 985 int width, height, pix_format; 986 987 /* Sanity check. */ 988 if (cc->camera == NULL) { 989 /* Not connected. */ 990 E("%s: Camera '%s' is not connected", __FUNCTION__, cc->device_name); 991 _qemu_client_reply_ko(qc, "Camera is not connected"); 992 return; 993 } 994 995 /* 996 * Parse parameters. 997 */ 998 999 if (param == NULL) { 1000 E("%s: Missing parameters for the query", __FUNCTION__); 1001 _qemu_client_reply_ko(qc, "Missing parameters for the query"); 1002 return; 1003 } 1004 1005 /* Pull required 'dim' parameter. */ 1006 if (_get_param_value(param, "dim", dim, sizeof(dim))) { 1007 E("%s: Invalid or missing 'dim' parameter in '%s'", __FUNCTION__, param); 1008 _qemu_client_reply_ko(qc, "Invalid or missing 'dim' parameter"); 1009 return; 1010 } 1011 1012 /* Pull required 'pix' parameter. */ 1013 if (_get_param_value_int(param, "pix", &pix_format)) { 1014 E("%s: Invalid or missing 'pix' parameter in '%s'", __FUNCTION__, param); 1015 _qemu_client_reply_ko(qc, "Invalid or missing 'pix' parameter"); 1016 return; 1017 } 1018 1019 /* Parse 'dim' parameter, and get requested frame width and height. */ 1020 w = strchr(dim, 'x'); 1021 if (w == NULL || w[1] == '\0') { 1022 E("%s: Invalid 'dim' parameter in '%s'", __FUNCTION__, param); 1023 _qemu_client_reply_ko(qc, "Invalid 'dim' parameter"); 1024 return; 1025 } 1026 *w = '\0'; w++; 1027 errno = 0; 1028 width = strtoi(dim, NULL, 10); 1029 height = strtoi(w, NULL, 10); 1030 if (errno) { 1031 E("%s: Invalid 'dim' parameter in '%s'", __FUNCTION__, param); 1032 _qemu_client_reply_ko(qc, "Invalid 'dim' parameter"); 1033 return; 1034 } 1035 1036 /* After collecting capture parameters lets see if camera has already 1037 * started, and if so, lets see if parameters match. */ 1038 if (cc->video_frame != NULL) { 1039 /* Already started. Match capture parameters. */ 1040 if (cc->pixel_format != pix_format ||cc->width != width || 1041 cc->height != height) { 1042 /* Parameters match. Succeed the query. */ 1043 W("%s: Camera '%s' is already started", __FUNCTION__, cc->device_name); 1044 _qemu_client_reply_ok(qc, "Camera is already started"); 1045 } else { 1046 /* Parameters don't match. Fail the query. */ 1047 E("%s: Camera '%s' is already started, and parameters don't match:\n" 1048 "Current %.4s[%dx%d] != requested %.4s[%dx%d]", 1049 __FUNCTION__, cc->device_name, (const char*)&cc->pixel_format, 1050 cc->width, cc->height, (const char*)&pix_format, width, height); 1051 _qemu_client_reply_ko(qc, 1052 "Camera is already started with different capturing parameters"); 1053 } 1054 return; 1055 } 1056 1057 /* 1058 * Start the camera. 1059 */ 1060 1061 /* Save capturing parameters. */ 1062 cc->pixel_format = pix_format; 1063 cc->width = width; 1064 cc->height = height; 1065 cc->pixel_num = cc->width * cc->height; 1066 cc->frames_cached = 0; 1067 1068 /* Make sure that pixel format is known, and calculate video framebuffer size 1069 * along the lines. */ 1070 switch (cc->pixel_format) { 1071 case V4L2_PIX_FMT_YUV420: 1072 case V4L2_PIX_FMT_YVU420: 1073 case V4L2_PIX_FMT_NV12: 1074 case V4L2_PIX_FMT_NV21: 1075 cc->video_frame_size = (cc->pixel_num * 12) / 8; 1076 break; 1077 1078 default: 1079 E("%s: Unknown pixel format %.4s", 1080 __FUNCTION__, (char*)&cc->pixel_format); 1081 _qemu_client_reply_ko(qc, "Pixel format is unknown"); 1082 return; 1083 } 1084 1085 /* Make sure that we have a converters between the original camera pixel 1086 * format and the one that the client expects. Also a converter must exist 1087 * for the preview window pixel format (RGB32) */ 1088 if (!has_converter(cc->camera_info->pixel_format, cc->pixel_format) || 1089 !has_converter(cc->camera_info->pixel_format, V4L2_PIX_FMT_RGB32)) { 1090 E("%s: No conversion exist between %.4s and %.4s (or RGB32) pixel formats", 1091 __FUNCTION__, (char*)&cc->camera_info->pixel_format, (char*)&cc->pixel_format); 1092 _qemu_client_reply_ko(qc, "No conversion exist for the requested pixel format"); 1093 return; 1094 } 1095 1096 /* TODO: At the moment camera framework in the emulator requires RGB32 pixel 1097 * format for preview window. So, we need to keep two framebuffers here: one 1098 * for the video, and another for the preview window. Watch out when this 1099 * changes (if changes). */ 1100 cc->preview_frame_size = cc->pixel_num * 4; 1101 1102 /* Allocate buffer large enough to contain both, video and preview 1103 * framebuffers. */ 1104 cc->video_frame = 1105 (uint8_t*)malloc(cc->video_frame_size + cc->preview_frame_size); 1106 if (cc->video_frame == NULL) { 1107 E("%s: Not enough memory for framebuffers %d + %d", 1108 __FUNCTION__, cc->video_frame_size, cc->preview_frame_size); 1109 _qemu_client_reply_ko(qc, "Out of memory"); 1110 return; 1111 } 1112 1113 /* Set framebuffer pointers. */ 1114 cc->preview_frame = (uint16_t*)(cc->video_frame + cc->video_frame_size); 1115 1116 /* Start the camera. */ 1117 if (camera_device_start_capturing(cc->camera, cc->camera_info->pixel_format, 1118 cc->width, cc->height)) { 1119 E("%s: Cannot start camera '%s' for %.4s[%dx%d]: %s", 1120 __FUNCTION__, cc->device_name, (const char*)&cc->pixel_format, 1121 cc->width, cc->height, strerror(errno)); 1122 free(cc->video_frame); 1123 cc->video_frame = NULL; 1124 _qemu_client_reply_ko(qc, "Cannot start the camera"); 1125 return; 1126 } 1127 1128 D("%s: Camera '%s' is now started for %.4s[%dx%d]", 1129 __FUNCTION__, cc->device_name, (char*)&cc->pixel_format, cc->width, 1130 cc->height); 1131 1132 _qemu_client_reply_ok(qc, NULL); 1133 } 1134 1135 /* Client has queried the client to stop capturing video. 1136 * Param: 1137 * cc - Queried camera client descriptor. 1138 * qc - Qemu client for the emulated camera. 1139 * param - Query parameters. There are no parameters expected for this query. 1140 */ 1141 static void 1142 _camera_client_query_stop(CameraClient* cc, QemudClient* qc, const char* param) 1143 { 1144 if (cc->video_frame == NULL) { 1145 /* Not started. */ 1146 W("%s: Camera '%s' is not started", __FUNCTION__, cc->device_name); 1147 _qemu_client_reply_ok(qc, "Camera is not started"); 1148 return; 1149 } 1150 1151 /* Stop the camera. */ 1152 if (camera_device_stop_capturing(cc->camera)) { 1153 E("%s: Cannot stop camera device '%s': %s", 1154 __FUNCTION__, cc->device_name, strerror(errno)); 1155 _qemu_client_reply_ko(qc, "Cannot stop camera device"); 1156 return; 1157 } 1158 1159 free(cc->video_frame); 1160 cc->video_frame = NULL; 1161 1162 D("%s: Camera device '%s' is now stopped.", __FUNCTION__, cc->device_name); 1163 _qemu_client_reply_ok(qc, NULL); 1164 } 1165 1166 /* Client has queried next frame. 1167 * Param: 1168 * cc - Queried camera client descriptor. 1169 * qc - Qemu client for the emulated camera. 1170 * param - Query parameters. Parameters for this query must contain a 'video', 1171 * and a 'preview' parameters, both must be decimal values, defining size of 1172 * requested video, and preview frames respectively. Zero value for any of 1173 * the parameters means that this particular frame is not requested. 1174 */ 1175 static void 1176 _camera_client_query_frame(CameraClient* cc, QemudClient* qc, const char* param) 1177 { 1178 int video_size = 0; 1179 int preview_size = 0; 1180 int repeat; 1181 ClientFrameBuffer fbs[2]; 1182 int fbs_num = 0; 1183 size_t payload_size; 1184 uint64_t tick; 1185 1186 /* Sanity check. */ 1187 if (cc->video_frame == NULL) { 1188 /* Not started. */ 1189 E("%s: Camera '%s' is not started", __FUNCTION__, cc->device_name); 1190 _qemu_client_reply_ko(qc, "Camera is not started"); 1191 return; 1192 } 1193 1194 /* Pull required parameters. */ 1195 if (_get_param_value_int(param, "video", &video_size) || 1196 _get_param_value_int(param, "preview", &preview_size)) { 1197 E("%s: Invalid or missing 'video', or 'preview' parameter in '%s'", 1198 __FUNCTION__, param); 1199 _qemu_client_reply_ko(qc, 1200 "Invalid or missing 'video', or 'preview' parameter"); 1201 return; 1202 } 1203 1204 /* Verify that framebuffer sizes match the ones that the started camera 1205 * operates with. */ 1206 if ((video_size != 0 && cc->video_frame_size != video_size) || 1207 (preview_size != 0 && cc->preview_frame_size != preview_size)) { 1208 E("%s: Frame sizes don't match for camera '%s':\n" 1209 "Expected %d for video, and %d for preview. Requested %d, and %d", 1210 __FUNCTION__, cc->device_name, cc->video_frame_size, 1211 cc->preview_frame_size, video_size, preview_size); 1212 _qemu_client_reply_ko(qc, "Frame size mismatch"); 1213 return; 1214 } 1215 1216 /* 1217 * Initialize framebuffer array for frame read. 1218 */ 1219 1220 if (video_size) { 1221 fbs[fbs_num].pixel_format = cc->pixel_format; 1222 fbs[fbs_num].framebuffer = cc->video_frame; 1223 fbs_num++; 1224 } 1225 if (preview_size) { 1226 /* TODO: Watch out for preview format changes! */ 1227 fbs[fbs_num].pixel_format = V4L2_PIX_FMT_RGB32; 1228 fbs[fbs_num].framebuffer = cc->preview_frame; 1229 fbs_num++; 1230 } 1231 1232 /* Capture new frame. */ 1233 tick = _get_timestamp(); 1234 repeat = camera_device_read_frame(cc->camera, fbs, fbs_num); 1235 1236 /* Note that there is no (known) way how to wait on next frame being 1237 * available, so we could dequeue frame buffer from the device only when we 1238 * know it's available. Instead we're shooting in the dark, and quite often 1239 * device will response with EAGAIN, indicating that it doesn't have frame 1240 * ready. In turn, it means that the last frame we have obtained from the 1241 * device is still good, and we can reply with the cached frames. The only 1242 * case when we need to keep trying to obtain a new frame is when frame cache 1243 * is empty. To prevent ourselves from an indefinite loop in case device got 1244 * stuck on something (observed with some Microsoft devices) we will limit 1245 * the loop by 2 second time period (which is more than enough to obtain 1246 * something from the device) */ 1247 while (repeat == 1 && !cc->frames_cached && 1248 (_get_timestamp() - tick) < 2000000LL) { 1249 /* Sleep for 10 millisec before repeating the attempt. */ 1250 _camera_sleep(10); 1251 repeat = camera_device_read_frame(cc->camera, fbs, fbs_num); 1252 } 1253 if (repeat == 1 && !cc->frames_cached) { 1254 /* Waited too long for the first frame. */ 1255 E("%s: Unable to obtain first video frame from the camera '%s' in %d milliseconds: %s.", 1256 __FUNCTION__, cc->device_name, 1257 (uint32_t)(_get_timestamp() - tick) / 1000, strerror(errno)); 1258 _qemu_client_reply_ko(qc, "Unable to obtain video frame from the camera"); 1259 return; 1260 } else if (repeat < 0) { 1261 /* An I/O error. */ 1262 E("%s: Unable to obtain video frame from the camera '%s': %s.", 1263 __FUNCTION__, cc->device_name, strerror(errno)); 1264 _qemu_client_reply_ko(qc, strerror(errno)); 1265 return; 1266 } 1267 1268 /* We have cached something... */ 1269 cc->frames_cached = 1; 1270 1271 /* 1272 * Build the reply. 1273 */ 1274 1275 /* Payload includes "ok:" + requested video and preview frames. */ 1276 payload_size = 3 + video_size + preview_size; 1277 1278 /* Send payload size first. */ 1279 _qemu_client_reply_payload(qc, payload_size); 1280 1281 /* After that send the 'ok:'. Note that if there is no frames sent, we should 1282 * use prefix "ok" instead of "ok:" */ 1283 if (video_size || preview_size) { 1284 qemud_client_send(qc, (const uint8_t*)"ok:", 3); 1285 } else { 1286 /* Still 3 bytes: zero terminator is required in this case. */ 1287 qemud_client_send(qc, (const uint8_t*)"ok", 3); 1288 } 1289 1290 /* After that send video frame (if requested). */ 1291 if (video_size) { 1292 qemud_client_send(qc, cc->video_frame, video_size); 1293 } 1294 1295 /* After that send preview frame (if requested). */ 1296 if (preview_size) { 1297 qemud_client_send(qc, (const uint8_t*)cc->preview_frame, preview_size); 1298 } 1299 } 1300 1301 /* Handles a message received from the emulated camera client. 1302 * Queries received here are represented as strings: 1303 * - 'connect' - Connects to the camera device (opens it). 1304 * - 'disconnect' - Disconnexts from the camera device (closes it). 1305 * - 'start' - Starts capturing video from the connected camera device. 1306 * - 'stop' - Stop capturing video from the connected camera device. 1307 * - 'frame' - Queries video and preview frames captured from the camera. 1308 * Param: 1309 * opaque - Camera service descriptor. 1310 * msg, msglen - Message received from the camera factory client. 1311 * client - Camera factory client pipe. 1312 */ 1313 static void 1314 _camera_client_recv(void* opaque, 1315 uint8_t* msg, 1316 int msglen, 1317 QemudClient* client) 1318 { 1319 /* 1320 * Emulated camera client queries. 1321 */ 1322 1323 /* Connect to the camera. */ 1324 static const char _query_connect[] = "connect"; 1325 /* Disconnect from the camera. */ 1326 static const char _query_disconnect[] = "disconnect"; 1327 /* Start video capturing. */ 1328 static const char _query_start[] = "start"; 1329 /* Stop video capturing. */ 1330 static const char _query_stop[] = "stop"; 1331 /* Query frame(s). */ 1332 static const char _query_frame[] = "frame"; 1333 1334 char query_name[64]; 1335 const char* query_param; 1336 CameraClient* cc = (CameraClient*)opaque; 1337 1338 /* 1339 * Emulated camera queries are formatted as such: 1340 * "<query name> [<parameters>]" 1341 */ 1342 1343 T("%s: Camera client query: '%s'", __FUNCTION__, (char*)msg); 1344 if (_parse_query((const char*)msg, query_name, sizeof(query_name), 1345 &query_param)) { 1346 E("%s: Invalid query '%s'", __FUNCTION__, (char*)msg); 1347 _qemu_client_reply_ko(client, "Invalid query"); 1348 return; 1349 } 1350 1351 /* Dispatch the query to an appropriate handler. */ 1352 if (!strcmp(query_name, _query_frame)) { 1353 /* A frame is queried. */ 1354 _camera_client_query_frame(cc, client, query_param); 1355 } else if (!strcmp(query_name, _query_connect)) { 1356 /* Camera connection is queried. */ 1357 _camera_client_query_connect(cc, client, query_param); 1358 } else if (!strcmp(query_name, _query_disconnect)) { 1359 /* Camera disnection is queried. */ 1360 _camera_client_query_disconnect(cc, client, query_param); 1361 } else if (!strcmp(query_name, _query_start)) { 1362 /* Start capturing is queried. */ 1363 _camera_client_query_start(cc, client, query_param); 1364 } else if (!strcmp(query_name, _query_stop)) { 1365 /* Stop capturing is queried. */ 1366 _camera_client_query_stop(cc, client, query_param); 1367 } else { 1368 E("%s: Unknown query '%s'", __FUNCTION__, (char*)msg); 1369 _qemu_client_reply_ko(client, "Unknown query"); 1370 } 1371 } 1372 1373 /* Emulated camera client has been disconnected from the service. */ 1374 static void 1375 _camera_client_close(void* opaque) 1376 { 1377 CameraClient* cc = (CameraClient*)opaque; 1378 1379 D("%s: Camera client for device '%s' on input channel %d is now closed", 1380 __FUNCTION__, cc->device_name, cc->inp_channel); 1381 1382 _camera_client_free(cc); 1383 } 1384 1385 /******************************************************************************** 1386 * Camera service API 1387 *******************************************************************************/ 1388 1389 /* Connects a client to the camera service. 1390 * There are two classes of the client that can connect to the service: 1391 * - Camera factory that is insterested only in listing camera devices attached 1392 * to the host. 1393 * - Camera device emulators that attach to the actual camera devices. 1394 * The distinction between these two classes is made by looking at extra 1395 * parameters passed in client_param variable. If it's NULL, or empty, the client 1396 * connects to a camera factory. Otherwise, parameters describe the camera device 1397 * the client wants to connect to. 1398 */ 1399 static QemudClient* 1400 _camera_service_connect(void* opaque, 1401 QemudService* serv, 1402 int channel, 1403 const char* client_param) 1404 { 1405 QemudClient* client = NULL; 1406 CameraServiceDesc* csd = (CameraServiceDesc*)opaque; 1407 1408 D("%s: Connecting camera client '%s'", 1409 __FUNCTION__, client_param ? client_param : "Factory"); 1410 if (client_param == NULL || *client_param == '\0') { 1411 /* This is an emulated camera factory client. */ 1412 client = qemud_client_new(serv, channel, client_param, csd, 1413 _factory_client_recv, _factory_client_close, 1414 NULL, NULL); 1415 } else { 1416 /* This is an emulated camera client. */ 1417 CameraClient* cc = _camera_client_create(csd, client_param); 1418 if (cc != NULL) { 1419 client = qemud_client_new(serv, channel, client_param, cc, 1420 _camera_client_recv, _camera_client_close, 1421 NULL, NULL); 1422 } 1423 } 1424 1425 return client; 1426 } 1427 1428 void 1429 android_camera_service_init(void) 1430 { 1431 static int _inited = 0; 1432 1433 if (!_inited) { 1434 _camera_service_init(&_camera_service_desc); 1435 QemudService* serv = qemud_service_register( SERVICE_NAME, 0, 1436 &_camera_service_desc, 1437 _camera_service_connect, 1438 NULL, NULL); 1439 if (serv == NULL) { 1440 derror("%s: Could not register '%s' service", 1441 __FUNCTION__, SERVICE_NAME); 1442 return; 1443 } 1444 D("%s: Registered '%s' qemud service", __FUNCTION__, SERVICE_NAME); 1445 } 1446 } 1447 1448 void 1449 android_list_web_cameras(void) 1450 { 1451 CameraInfo ci[MAX_CAMERA]; 1452 int connected_cnt; 1453 int i; 1454 1455 /* Enumerate camera devices connected to the host. */ 1456 connected_cnt = enumerate_camera_devices(ci, MAX_CAMERA); 1457 if (connected_cnt <= 0) { 1458 return; 1459 } 1460 1461 printf("List of web cameras connected to the computer:\n"); 1462 for (i = 0; i < connected_cnt; i++) { 1463 printf(" Camera '%s' is connected to device '%s' on channel %d using pixel format '%.4s'\n", 1464 ci[i].display_name, ci[i].device_name, ci[i].inp_channel, 1465 (const char*)&ci[i].pixel_format); 1466 } 1467 printf("\n"); 1468 } 1469