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 code that is used to capture video frames from a camera device 19 * on Linux. This code uses V4L2 API to work with camera devices, and requires 20 * Linux kernel version at least 2.5 21 */ 22 23 #include <sys/mman.h> 24 #include <sys/stat.h> 25 #include <sys/ioctl.h> 26 #include "android/camera/camera-capture.h" 27 #include "android/camera/camera-format-converters.h" 28 29 #define E(...) derror(__VA_ARGS__) 30 #define W(...) dwarning(__VA_ARGS__) 31 #define D(...) VERBOSE_PRINT(camera,__VA_ARGS__) 32 #define D_ACTIVE VERBOSE_CHECK(camera) 33 34 /* the T(...) macro is used to dump traffic */ 35 #define T_ACTIVE 0 36 37 #if T_ACTIVE 38 #define T(...) VERBOSE_PRINT(camera,__VA_ARGS__) 39 #else 40 #define T(...) ((void)0) 41 #endif 42 43 #define CLEAR(x) memset (&(x), 0, sizeof(x)) 44 45 /* Pixel format descriptor. 46 * Instances of this descriptor are created during camera device enumeration, and 47 * an instance of this structure describing pixel format chosen for the camera 48 * emulation is saved by the camera factory service to represent an emulating 49 * camera properties. 50 */ 51 typedef struct QemuPixelFormat { 52 /* Pixel format in V4L2_PIX_FMT_XXX form. */ 53 uint32_t format; 54 /* Frame dimensions supported by this format. */ 55 CameraFrameDim* dims; 56 /* Number of frame dimensions supported by this format. */ 57 int dim_num; 58 } QemuPixelFormat; 59 60 /* Describes a framebuffer. */ 61 typedef struct CameraFrameBuffer { 62 /* Framebuffer data. */ 63 uint8_t* data; 64 /* Framebuffer data size. */ 65 size_t size; 66 } CameraFrameBuffer; 67 68 /* Defines type of the I/O used to obtain frames from the device. */ 69 typedef enum CameraIoType { 70 /* Framebuffers are shared via memory mapping. */ 71 CAMERA_IO_MEMMAP, 72 /* Framebuffers are available via user pointers. */ 73 CAMERA_IO_USERPTR, 74 /* Framebuffers are to be read from the device. */ 75 CAMERA_IO_DIRECT 76 } CameraIoType; 77 78 typedef struct LinuxCameraDevice LinuxCameraDevice; 79 /* 80 * Describes a connection to an actual camera device. 81 */ 82 struct LinuxCameraDevice { 83 /* Common header. */ 84 CameraDevice header; 85 86 /* Camera device name. (default is /dev/video0) */ 87 char* device_name; 88 /* Input channel. (default is 0) */ 89 int input_channel; 90 91 /* 92 * Set by the framework after initializing camera connection. 93 */ 94 95 /* Handle to the opened camera device. */ 96 int handle; 97 /* Device capabilities. */ 98 struct v4l2_capability caps; 99 /* Actual pixel format reported by the device when capturing is started. */ 100 struct v4l2_pix_format actual_pixel_format; 101 /* Defines type of the I/O to use to retrieve frames from the device. */ 102 CameraIoType io_type; 103 /* Allocated framebuffers. */ 104 struct CameraFrameBuffer* framebuffers; 105 /* Actual number of allocated framebuffers. */ 106 int framebuffer_num; 107 }; 108 109 /* Preferred pixel formats arranged from the most to the least desired. 110 * 111 * More than anything else this array is defined by an existance of format 112 * conversion between the camera supported formats, and formats that are 113 * supported by camera framework in the guest system. Currently, guest supports 114 * only YV12 pixel format for data, and RGB32 for preview. So, this array should 115 * contain only those formats, for which converters are implemented. Generally 116 * speaking, the order in which entries should be arranged in this array matters 117 * only as far as conversion speed is concerned. So, formats with the fastest 118 * converters should be put closer to the top of the array, while slower ones 119 * should be put closer to the bottom. But as far as functionality is concerned, 120 * the orser doesn't matter, and any format can be placed anywhere in this array, 121 * as long as conversion for it exists. 122 */ 123 static const uint32_t _preferred_formats[] = 124 { 125 /* Native format for the emulated camera: no conversion at all. */ 126 V4L2_PIX_FMT_YUV420, 127 V4L2_PIX_FMT_YVU420, 128 /* Continue with YCbCr: less math than with RGB */ 129 V4L2_PIX_FMT_NV12, 130 V4L2_PIX_FMT_NV21, 131 V4L2_PIX_FMT_YUYV, 132 /* End with RGB. */ 133 V4L2_PIX_FMT_RGB32, 134 V4L2_PIX_FMT_RGB24, 135 V4L2_PIX_FMT_RGB565, 136 }; 137 /* Number of entries in _preferred_formats array. */ 138 static const int _preferred_format_num = 139 sizeof(_preferred_formats)/sizeof(*_preferred_formats); 140 141 /******************************************************************************* 142 * Helper routines 143 ******************************************************************************/ 144 145 /* IOCTL wrapper. */ 146 static int 147 _xioctl(int fd, int request, void *arg) { 148 int r; 149 do { 150 r = ioctl(fd, request, arg); 151 } while (-1 == r && EINTR == errno); 152 return r; 153 } 154 155 /* Frees resource allocated for QemuPixelFormat instance, excluding the instance 156 * itself. 157 */ 158 static void _qemu_pixel_format_free(QemuPixelFormat* fmt) 159 { 160 if (fmt != NULL) { 161 if (fmt->dims != NULL) 162 free(fmt->dims); 163 } 164 } 165 166 /* Returns an index of the given pixel format in an array containing pixel 167 * format descriptors. 168 * This routine is used to choose a pixel format for a camera device. The idea 169 * is that when the camera service enumerates all pixel formats for all cameras 170 * connected to the host, we need to choose just one, which would be most 171 * appropriate for camera emulation. To do that, the camera service will run 172 * formats, contained in _preferred_formats array against enumerated pixel 173 * formats to pick the first format that match. 174 * Param: 175 * fmt - Pixel format, for which to obtain the index. 176 * formats - Array containing list of pixel formats, supported by the camera 177 * device. 178 * size - Number of elements in the 'formats' array. 179 * Return: 180 * Index of the matched entry in the array, or -1 if no entry has been found. 181 */ 182 static int 183 _get_format_index(uint32_t fmt, QemuPixelFormat* formats, int size) 184 { 185 int f; 186 for (f = 0; f < size && formats[f].format != fmt; f++); 187 return f < size ? f : -1; 188 } 189 190 /******************************************************************************* 191 * CameraFrameBuffer routines 192 ******************************************************************************/ 193 194 /* Frees array of framebuffers, depending on the I/O method the array has been 195 * initialized for. 196 * Note that this routine doesn't frees the array itself. 197 * Param: 198 * fb, num - Array data, and its size. 199 * io_type - Type of the I/O the array has been initialized for. 200 */ 201 static void 202 _free_framebuffers(CameraFrameBuffer* fb, int num, CameraIoType io_type) 203 { 204 if (fb != NULL) { 205 int n; 206 207 switch (io_type) { 208 case CAMERA_IO_MEMMAP: 209 /* Unmap framebuffers. */ 210 for (n = 0; n < num; n++) { 211 if (fb[n].data != NULL) { 212 munmap(fb[n].data, fb[n].size); 213 fb[n].data = NULL; 214 fb[n].size = 0; 215 } 216 } 217 break; 218 219 case CAMERA_IO_USERPTR: 220 case CAMERA_IO_DIRECT: 221 /* Free framebuffers. */ 222 for (n = 0; n < num; n++) { 223 if (fb[n].data != NULL) { 224 free(fb[n].data); 225 fb[n].data = NULL; 226 fb[n].size = 0; 227 } 228 } 229 break; 230 231 default: 232 E("%s: Invalid I/O type %d", __FUNCTION__, io_type); 233 break; 234 } 235 } 236 } 237 238 /******************************************************************************* 239 * CameraDevice routines 240 ******************************************************************************/ 241 242 /* Allocates an instance of LinuxCameraDevice structure. 243 * Return: 244 * Allocated instance of LinuxCameraDevice structure. Note that this routine 245 * also sets 'opaque' field in the 'header' structure to point back to the 246 * containing LinuxCameraDevice instance. 247 */ 248 static LinuxCameraDevice* 249 _camera_device_alloc(void) 250 { 251 LinuxCameraDevice* cd; 252 253 ANEW0(cd); 254 memset(cd, 0, sizeof(*cd)); 255 cd->header.opaque = cd; 256 cd->handle = -1; 257 258 return cd; 259 } 260 261 /* Uninitializes and frees CameraDevice structure. 262 */ 263 static void 264 _camera_device_free(LinuxCameraDevice* lcd) 265 { 266 if (lcd != NULL) { 267 /* Closing handle will also disconnect from the driver. */ 268 if (lcd->handle >= 0) { 269 close(lcd->handle); 270 } 271 if (lcd->device_name != NULL) { 272 free(lcd->device_name); 273 } 274 if (lcd->framebuffers != NULL) { 275 _free_framebuffers(lcd->framebuffers, lcd->framebuffer_num, 276 lcd->io_type); 277 free(lcd->framebuffers); 278 } 279 AFREE(lcd); 280 } else { 281 E("%s: No descriptor", __FUNCTION__); 282 } 283 } 284 285 /* Resets camera device after capturing. 286 * Since new capture request may require different frame dimensions we must 287 * reset camera device by reopening its handle. Otherwise attempts to set up new 288 * frame properties (different from the previous one) may fail. */ 289 static void 290 _camera_device_reset(LinuxCameraDevice* cd) 291 { 292 struct v4l2_cropcap cropcap; 293 struct v4l2_crop crop; 294 295 /* Free capturing framebuffers first. */ 296 if (cd->framebuffers != NULL) { 297 _free_framebuffers(cd->framebuffers, cd->framebuffer_num, cd->io_type); 298 free(cd->framebuffers); 299 cd->framebuffers = NULL; 300 cd->framebuffer_num = 0; 301 } 302 303 /* Reset device handle. */ 304 close(cd->handle); 305 cd->handle = open(cd->device_name, O_RDWR | O_NONBLOCK, 0); 306 307 if (cd->handle >= 0) { 308 /* Select video input, video standard and tune here. */ 309 cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 310 _xioctl(cd->handle, VIDIOC_CROPCAP, &cropcap); 311 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 312 crop.c = cropcap.defrect; /* reset to default */ 313 _xioctl (cd->handle, VIDIOC_S_CROP, &crop); 314 } 315 } 316 317 /* Memory maps buffers and shares mapped memory with the device. 318 * Return: 319 * 0 Framebuffers have been mapped. 320 * -1 A critical error has ocurred. 321 * 1 Memory mapping is not available. 322 */ 323 static int 324 _camera_device_mmap_framebuffer(LinuxCameraDevice* cd) 325 { 326 struct v4l2_requestbuffers req; 327 CLEAR(req); 328 req.count = 4; 329 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 330 req.memory = V4L2_MEMORY_MMAP; 331 332 /* Request memory mapped buffers. Note that device can return less buffers 333 * than requested. */ 334 if(_xioctl(cd->handle, VIDIOC_REQBUFS, &req)) { 335 if (EINVAL == errno) { 336 D("%s: Device '%s' does not support memory mapping", 337 __FUNCTION__, cd->device_name); 338 return 1; 339 } else { 340 E("%s: VIDIOC_REQBUFS has failed: %s", 341 __FUNCTION__, strerror(errno)); 342 return -1; 343 } 344 } 345 346 /* Allocate framebuffer array. */ 347 cd->framebuffers = calloc(req.count, sizeof(CameraFrameBuffer)); 348 if (cd->framebuffers == NULL) { 349 E("%s: Not enough memory to allocate framebuffer array", __FUNCTION__); 350 return -1; 351 } 352 353 /* Map every framebuffer to the shared memory, and queue it 354 * with the device. */ 355 for(cd->framebuffer_num = 0; cd->framebuffer_num < req.count; 356 cd->framebuffer_num++) { 357 /* Map framebuffer. */ 358 struct v4l2_buffer buf; 359 CLEAR(buf); 360 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 361 buf.memory = V4L2_MEMORY_MMAP; 362 buf.index = cd->framebuffer_num; 363 if(_xioctl(cd->handle, VIDIOC_QUERYBUF, &buf) < 0) { 364 E("%s: VIDIOC_QUERYBUF has failed: %s", 365 __FUNCTION__, strerror(errno)); 366 return -1; 367 } 368 cd->framebuffers[cd->framebuffer_num].size = buf.length; 369 cd->framebuffers[cd->framebuffer_num].data = 370 mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, 371 cd->handle, buf.m.offset); 372 if (MAP_FAILED == cd->framebuffers[cd->framebuffer_num].data) { 373 E("%s: Memory mapping has failed: %s", 374 __FUNCTION__, strerror(errno)); 375 return -1; 376 } 377 378 /* Queue the mapped buffer. */ 379 CLEAR(buf); 380 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 381 buf.memory = V4L2_MEMORY_MMAP; 382 buf.index = cd->framebuffer_num; 383 if (_xioctl(cd->handle, VIDIOC_QBUF, &buf) < 0) { 384 E("%s: VIDIOC_QBUF has failed: %s", __FUNCTION__, strerror(errno)); 385 return -1; 386 } 387 } 388 389 cd->io_type = CAMERA_IO_MEMMAP; 390 391 return 0; 392 } 393 394 /* Allocates frame buffers and registers them with the device. 395 * Return: 396 * 0 Framebuffers have been mapped. 397 * -1 A critical error has ocurred. 398 * 1 Device doesn't support user pointers. 399 */ 400 static int 401 _camera_device_user_framebuffer(LinuxCameraDevice* cd) 402 { 403 struct v4l2_requestbuffers req; 404 CLEAR (req); 405 req.count = 4; 406 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 407 req.memory = V4L2_MEMORY_USERPTR; 408 409 /* Request user buffers. Note that device can return less buffers 410 * than requested. */ 411 if(_xioctl(cd->handle, VIDIOC_REQBUFS, &req)) { 412 if (EINVAL == errno) { 413 D("%s: Device '%s' does not support user pointers", 414 __FUNCTION__, cd->device_name); 415 return 1; 416 } else { 417 E("%s: VIDIOC_REQBUFS has failed: %s", 418 __FUNCTION__, strerror(errno)); 419 return -1; 420 } 421 } 422 423 /* Allocate framebuffer array. */ 424 cd->framebuffers = calloc(req.count, sizeof(CameraFrameBuffer)); 425 if (cd->framebuffers == NULL) { 426 E("%s: Not enough memory to allocate framebuffer array", __FUNCTION__); 427 return -1; 428 } 429 430 /* Allocate buffers, queueing them wit the device at the same time */ 431 for(cd->framebuffer_num = 0; cd->framebuffer_num < req.count; 432 cd->framebuffer_num++) { 433 cd->framebuffers[cd->framebuffer_num].size = 434 cd->actual_pixel_format.sizeimage; 435 cd->framebuffers[cd->framebuffer_num].data = 436 malloc(cd->framebuffers[cd->framebuffer_num].size); 437 if (cd->framebuffers[cd->framebuffer_num].data == NULL) { 438 E("%s: Not enough memory to allocate framebuffer", __FUNCTION__); 439 return -1; 440 } 441 442 /* Queue the user buffer. */ 443 struct v4l2_buffer buf; 444 CLEAR(buf); 445 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 446 buf.memory = V4L2_MEMORY_USERPTR; 447 buf.m.userptr = (unsigned long)cd->framebuffers[cd->framebuffer_num].data; 448 buf.length = cd->framebuffers[cd->framebuffer_num].size; 449 if (_xioctl(cd->handle, VIDIOC_QBUF, &buf) < 0) { 450 E("%s: VIDIOC_QBUF has failed: %s", __FUNCTION__, strerror(errno)); 451 return -1; 452 } 453 } 454 455 cd->io_type = CAMERA_IO_USERPTR; 456 457 return 0; 458 } 459 460 /* Allocate frame buffer for direct read from the device. 461 * Return: 462 * 0 Framebuffers have been mapped. 463 * -1 A critical error has ocurred. 464 * 1 Memory mapping is not available. 465 */ 466 static int 467 _camera_device_direct_framebuffer(LinuxCameraDevice* cd) 468 { 469 /* Allocate framebuffer array. */ 470 cd->framebuffer_num = 1; 471 cd->framebuffers = malloc(sizeof(CameraFrameBuffer)); 472 if (cd->framebuffers == NULL) { 473 E("%s: Not enough memory to allocate framebuffer array", __FUNCTION__); 474 return -1; 475 } 476 477 cd->framebuffers[0].size = cd->actual_pixel_format.sizeimage; 478 cd->framebuffers[0].data = malloc(cd->framebuffers[0].size); 479 if (cd->framebuffers[0].data == NULL) { 480 E("%s: Not enough memory to allocate framebuffer", __FUNCTION__); 481 return -1; 482 } 483 484 cd->io_type = CAMERA_IO_DIRECT; 485 486 return 0; 487 } 488 489 /* Opens camera device. 490 * Param: 491 * cd - Camera device descriptor to open the camera for. 492 * Return: 493 * 0 on success, != 0 on failure. 494 */ 495 static int 496 _camera_device_open(LinuxCameraDevice* cd) 497 { 498 struct stat st; 499 500 if (stat(cd->device_name, &st)) { 501 return -1; 502 } 503 504 if (!S_ISCHR(st.st_mode)) { 505 E("%s: '%s' is not a device", __FUNCTION__, cd->device_name); 506 return -1; 507 } 508 509 /* Open handle to the device, and query device capabilities. */ 510 cd->handle = open(cd->device_name, O_RDWR | O_NONBLOCK, 0); 511 if (cd->handle < 0) { 512 E("%s: Cannot open camera device '%s': %s", 513 __FUNCTION__, cd->device_name, strerror(errno)); 514 return -1; 515 } 516 if (_xioctl(cd->handle, VIDIOC_QUERYCAP, &cd->caps) < 0) { 517 if (EINVAL == errno) { 518 E("%s: Camera '%s' is not a V4L2 device", 519 __FUNCTION__, cd->device_name); 520 close(cd->handle); 521 cd->handle = -1; 522 return -1; 523 } else { 524 E("%s: Unable to query capabilities for camera device '%s'", 525 __FUNCTION__, cd->device_name); 526 close(cd->handle); 527 cd->handle = -1; 528 return -1; 529 } 530 } 531 532 /* Make sure that camera supports minimal requirements. */ 533 if (!(cd->caps.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { 534 E("%s: Camera '%s' is not a video capture device", 535 __FUNCTION__, cd->device_name); 536 close(cd->handle); 537 cd->handle = -1; 538 return -1; 539 } 540 541 return 0; 542 } 543 544 /* Enumerates frame sizes for the given pixel format. 545 * Param: 546 * cd - Opened camera device descriptor. 547 * fmt - Pixel format to enum frame sizes for. 548 * sizes - Upon success contains an array of supported frame sizes. The size of 549 * the array is defined by the value, returned from this routine. The caller 550 * is responsible for freeing memory allocated for this array. 551 * Return: 552 * On success returns number of entries in the 'sizes' array. On failure returns 553 * a negative value. 554 */ 555 static int 556 _camera_device_enum_format_sizes(LinuxCameraDevice* cd, 557 uint32_t fmt, 558 CameraFrameDim** sizes) 559 { 560 int n; 561 int sizes_num = 0; 562 int out_num = 0; 563 struct v4l2_frmsizeenum size_enum; 564 CameraFrameDim* arr; 565 566 /* Calculate number of supported sizes for the given format. */ 567 for (n = 0; ; n++) { 568 size_enum.index = n; 569 size_enum.pixel_format = fmt; 570 if(_xioctl(cd->handle, VIDIOC_ENUM_FRAMESIZES, &size_enum)) { 571 break; 572 } 573 if (size_enum.type == V4L2_FRMSIZE_TYPE_DISCRETE) { 574 /* Size is in the simpe width, height form. */ 575 sizes_num++; 576 } else if (size_enum.type == V4L2_FRMSIZE_TYPE_STEPWISE) { 577 /* Sizes are represented as min/max width and height with a step for 578 * each dimension. Since at the end we want to list each supported 579 * size in the array (that's the only format supported by the guest 580 * camera framework), we need to calculate how many array entries 581 * this will generate. */ 582 const uint32_t dif_widths = 583 (size_enum.stepwise.max_width - size_enum.stepwise.min_width) / 584 size_enum.stepwise.step_width + 1; 585 const uint32_t dif_heights = 586 (size_enum.stepwise.max_height - size_enum.stepwise.min_height) / 587 size_enum.stepwise.step_height + 1; 588 sizes_num += dif_widths * dif_heights; 589 } else if (size_enum.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) { 590 /* Special stepwise case, when steps are set to 1. We still need to 591 * flatten this for the guest, but the array may be too big. 592 * Fortunately, we don't need to be fancy, so three sizes would be 593 * sufficient here: min, max, and one in the middle. */ 594 sizes_num += 3; 595 } 596 597 } 598 if (sizes_num == 0) { 599 return 0; 600 } 601 602 /* Allocate, and initialize the array of supported entries. */ 603 *sizes = (CameraFrameDim*)malloc(sizes_num * sizeof(CameraFrameDim)); 604 if (*sizes == NULL) { 605 E("%s: Memory allocation failure", __FUNCTION__); 606 return -1; 607 } 608 arr = *sizes; 609 for (n = 0; out_num < sizes_num; n++) { 610 size_enum.index = n; 611 size_enum.pixel_format = fmt; 612 if(_xioctl(cd->handle, VIDIOC_ENUM_FRAMESIZES, &size_enum)) { 613 /* Errors are not welcome here anymore. */ 614 E("%s: Unexpected failure while getting pixel dimensions: %s", 615 __FUNCTION__, strerror(errno)); 616 free(arr); 617 return -1; 618 } 619 620 if (size_enum.type == V4L2_FRMSIZE_TYPE_DISCRETE) { 621 arr[out_num].width = size_enum.discrete.width; 622 arr[out_num].height = size_enum.discrete.height; 623 out_num++; 624 } else if (size_enum.type == V4L2_FRMSIZE_TYPE_STEPWISE) { 625 uint32_t w; 626 for (w = size_enum.stepwise.min_width; 627 w <= size_enum.stepwise.max_width; 628 w += size_enum.stepwise.step_width) { 629 uint32_t h; 630 for (h = size_enum.stepwise.min_height; 631 h <= size_enum.stepwise.max_height; 632 h += size_enum.stepwise.step_height) { 633 arr[out_num].width = w; 634 arr[out_num].height = h; 635 out_num++; 636 } 637 } 638 } else if (size_enum.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) { 639 /* min */ 640 arr[out_num].width = size_enum.stepwise.min_width; 641 arr[out_num].height = size_enum.stepwise.min_height; 642 out_num++; 643 /* one in the middle */ 644 arr[out_num].width = 645 (size_enum.stepwise.min_width + size_enum.stepwise.max_width) / 2; 646 arr[out_num].height = 647 (size_enum.stepwise.min_height + size_enum.stepwise.max_height) / 2; 648 out_num++; 649 /* max */ 650 arr[out_num].width = size_enum.stepwise.max_width; 651 arr[out_num].height = size_enum.stepwise.max_height; 652 out_num++; 653 } 654 } 655 656 return out_num; 657 } 658 659 /* Enumerates pixel formats, supported by the device. 660 * Note that this routine will enumerate only raw (uncompressed) formats. 661 * Param: 662 * cd - Opened camera device descriptor. 663 * fmts - Upon success contains an array of supported pixel formats. The size of 664 * the array is defined by the value, returned from this routine. The caller 665 * is responsible for freeing memory allocated for this array. 666 * Return: 667 * On success returns number of entries in the 'fmts' array. On failure returns 668 * a negative value. 669 */ 670 static int 671 _camera_device_enum_pixel_formats(LinuxCameraDevice* cd, QemuPixelFormat** fmts) 672 { 673 int n, max_fmt; 674 int fmt_num = 0; 675 int out_num = 0; 676 struct v4l2_fmtdesc fmt_enum; 677 QemuPixelFormat* arr; 678 679 /* Calculate number of supported formats. */ 680 for (max_fmt = 0; ; max_fmt++) { 681 memset(&fmt_enum, 0, sizeof(fmt_enum)); 682 fmt_enum.index = max_fmt; 683 fmt_enum.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 684 if(_xioctl(cd->handle, VIDIOC_ENUM_FMT, &fmt_enum)) { 685 break; 686 } 687 /* Skip the compressed ones. */ 688 if ((fmt_enum.flags & V4L2_FMT_FLAG_COMPRESSED) == 0) { 689 fmt_num++; 690 } 691 } 692 if (fmt_num == 0) { 693 return 0; 694 } 695 696 /* Allocate, and initialize array for enumerated formats. */ 697 *fmts = (QemuPixelFormat*)malloc(fmt_num * sizeof(QemuPixelFormat)); 698 if (*fmts == NULL) { 699 E("%s: Memory allocation failure", __FUNCTION__); 700 return -1; 701 } 702 arr = *fmts; 703 memset(arr, 0, fmt_num * sizeof(QemuPixelFormat)); 704 for (n = 0; n < max_fmt && out_num < fmt_num; n++) { 705 memset(&fmt_enum, 0, sizeof(fmt_enum)); 706 fmt_enum.index = n; 707 fmt_enum.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 708 if(_xioctl(cd->handle, VIDIOC_ENUM_FMT, &fmt_enum)) { 709 int nn; 710 /* Errors are not welcome here anymore. */ 711 E("%s: Unexpected failure while getting pixel format: %s", 712 __FUNCTION__, strerror(errno)); 713 for (nn = 0; nn < out_num; nn++) { 714 _qemu_pixel_format_free(arr + nn); 715 } 716 free(arr); 717 return -1; 718 } 719 /* Skip the compressed ones. */ 720 if ((fmt_enum.flags & V4L2_FMT_FLAG_COMPRESSED) == 0) { 721 arr[out_num].format = fmt_enum.pixelformat; 722 /* Enumerate frame dimensions supported for this format. */ 723 arr[out_num].dim_num = 724 _camera_device_enum_format_sizes(cd, fmt_enum.pixelformat, 725 &arr[out_num].dims); 726 if (arr[out_num].dim_num > 0) { 727 out_num++; 728 } else if (arr[out_num].dim_num < 0) { 729 int nn; 730 E("Unable to enumerate supported dimensions for pixel format %d", 731 fmt_enum.pixelformat); 732 for (nn = 0; nn < out_num; nn++) { 733 _qemu_pixel_format_free(arr + nn); 734 } 735 free(arr); 736 return -1; 737 } 738 } 739 } 740 741 return out_num; 742 } 743 744 /* Collects information about an opened camera device. 745 * The information collected in this routine contains list of pixel formats, 746 * supported by the device, and list of frame dimensions supported by the camera 747 * for each pixel format. 748 * Param: 749 * cd - Opened camera device descriptor. 750 * cis - Upon success contains information collected from the camera device. 751 * Return: 752 * 0 on success, != 0 on failure. 753 */ 754 static int 755 _camera_device_get_info(LinuxCameraDevice* cd, CameraInfo* cis) 756 { 757 int f; 758 int chosen = -1; 759 QemuPixelFormat* formats = NULL; 760 int num_pix_fmts = _camera_device_enum_pixel_formats(cd, &formats); 761 if (num_pix_fmts <= 0) { 762 return -1; 763 } 764 765 /* Lets see if camera supports preferred formats */ 766 for (f = 0; f < _preferred_format_num; f++) { 767 chosen = _get_format_index(_preferred_formats[f], formats, num_pix_fmts); 768 if (chosen >= 0) { 769 break; 770 } 771 } 772 if (chosen < 0) { 773 /* Camera doesn't support any of the chosen formats. Then it doesn't 774 * matter which one we choose. Lets choose the first one. */ 775 chosen = 0; 776 } 777 778 cis->device_name = ASTRDUP(cd->device_name); 779 cis->inp_channel = cd->input_channel; 780 cis->pixel_format = formats[chosen].format; 781 cis->frame_sizes_num = formats[chosen].dim_num; 782 /* Swap instead of copy. */ 783 cis->frame_sizes = formats[chosen].dims; 784 formats[chosen].dims = NULL; 785 cis->in_use = 0; 786 787 for (f = 0; f < num_pix_fmts; f++) { 788 _qemu_pixel_format_free(formats + f); 789 } 790 free(formats); 791 792 return 0; 793 } 794 795 /******************************************************************************* 796 * CameraDevice API 797 ******************************************************************************/ 798 799 CameraDevice* 800 camera_device_open(const char* name, int inp_channel) 801 { 802 struct v4l2_cropcap cropcap; 803 struct v4l2_crop crop; 804 LinuxCameraDevice* cd; 805 806 /* Allocate and initialize the descriptor. */ 807 cd = _camera_device_alloc(); 808 cd->device_name = name != NULL ? ASTRDUP(name) : ASTRDUP("/dev/video0"); 809 cd->input_channel = inp_channel; 810 811 /* Open the device. */ 812 if (_camera_device_open(cd)) { 813 _camera_device_free(cd); 814 return NULL; 815 } 816 817 /* Select video input, video standard and tune here. */ 818 cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 819 _xioctl(cd->handle, VIDIOC_CROPCAP, &cropcap); 820 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 821 crop.c = cropcap.defrect; /* reset to default */ 822 _xioctl (cd->handle, VIDIOC_S_CROP, &crop); 823 824 return &cd->header; 825 } 826 827 int 828 camera_device_start_capturing(CameraDevice* ccd, 829 uint32_t pixel_format, 830 int frame_width, 831 int frame_height) 832 { 833 struct v4l2_format fmt; 834 LinuxCameraDevice* cd; 835 char fmt_str[5]; 836 int r; 837 838 /* Sanity checks. */ 839 if (ccd == NULL || ccd->opaque == NULL) { 840 E("%s: Invalid camera device descriptor", __FUNCTION__); 841 return -1; 842 } 843 cd = (LinuxCameraDevice*)ccd->opaque; 844 if (cd->handle < 0) { 845 E("%s: Camera device is not opened", __FUNCTION__); 846 return -1; 847 } 848 849 /* Try to set pixel format with the given dimensions. */ 850 CLEAR(fmt); 851 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 852 fmt.fmt.pix.width = frame_width; 853 fmt.fmt.pix.height = frame_height; 854 fmt.fmt.pix.pixelformat = pixel_format; 855 if (_xioctl(cd->handle, VIDIOC_S_FMT, &fmt) < 0) { 856 memcpy(fmt_str, &pixel_format, 4); 857 fmt_str[4] = '\0'; 858 E("%s: Camera '%s' does not support pixel format '%s' with dimensions %dx%d", 859 __FUNCTION__, cd->device_name, fmt_str, frame_width, frame_height); 860 _camera_device_reset(cd); 861 return -1; 862 } 863 /* VIDIOC_S_FMT may has changed some properties of the structure. Make sure 864 * that dimensions didn't change. */ 865 if (fmt.fmt.pix.width != frame_width || fmt.fmt.pix.height != frame_height) { 866 memcpy(fmt_str, &pixel_format, 4); 867 fmt_str[4] = '\0'; 868 E("%s: Dimensions %dx%d are wrong for pixel format '%s'", 869 __FUNCTION__, frame_width, frame_height, fmt_str); 870 _camera_device_reset(cd); 871 return -1; 872 } 873 memcpy(&cd->actual_pixel_format, &fmt.fmt.pix, sizeof(struct v4l2_pix_format)); 874 875 /* 876 * Lets initialize frame buffers, and see what kind of I/O we're going to 877 * use to retrieve frames. 878 */ 879 880 /* First, lets see if we can do mapped I/O (as most performant one). */ 881 r = _camera_device_mmap_framebuffer(cd); 882 if (r < 0) { 883 /* Some critical error has ocurred. Bail out. */ 884 _camera_device_reset(cd); 885 return -1; 886 } else if (r > 0) { 887 /* Device doesn't support memory mapping. Retrieve to the next performant 888 * one: preallocated user buffers. */ 889 r = _camera_device_user_framebuffer(cd); 890 if (r < 0) { 891 /* Some critical error has ocurred. Bail out. */ 892 _camera_device_reset(cd); 893 return -1; 894 } else if (r > 0) { 895 /* The only thing left for us is direct reading from the device. */ 896 if (!(cd->caps.capabilities & V4L2_CAP_READWRITE)) { 897 E("%s: Don't know how to access frames on device '%s'", 898 __FUNCTION__, cd->device_name); 899 _camera_device_reset(cd); 900 return -1; 901 } 902 r = _camera_device_direct_framebuffer(cd); 903 if (r != 0) { 904 /* Any error at this point is a critical one. */ 905 _camera_device_reset(cd); 906 return -1; 907 } 908 } 909 } 910 911 /* Start capturing from the device. */ 912 if (cd->io_type != CAMERA_IO_DIRECT) { 913 enum v4l2_buf_type type; 914 type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 915 if (_xioctl (cd->handle, VIDIOC_STREAMON, &type) < 0) { 916 E("%s: VIDIOC_STREAMON on camera '%s' has failed: %s", 917 __FUNCTION__, cd->device_name, strerror(errno)); 918 _camera_device_reset(cd); 919 return -1; 920 } 921 } 922 return 0; 923 } 924 925 int 926 camera_device_stop_capturing(CameraDevice* ccd) 927 { 928 enum v4l2_buf_type type; 929 LinuxCameraDevice* cd; 930 931 /* Sanity checks. */ 932 if (ccd == NULL || ccd->opaque == NULL) { 933 E("%s: Invalid camera device descriptor", __FUNCTION__); 934 return -1; 935 } 936 cd = (LinuxCameraDevice*)ccd->opaque; 937 if (cd->handle < 0) { 938 E("%s: Camera device is not opened", __FUNCTION__); 939 return -1; 940 } 941 942 switch (cd->io_type) { 943 case CAMERA_IO_DIRECT: 944 /* Nothing to do. */ 945 break; 946 947 case CAMERA_IO_MEMMAP: 948 case CAMERA_IO_USERPTR: 949 type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 950 if (_xioctl(cd->handle, VIDIOC_STREAMOFF, &type) < 0) { 951 E("%s: VIDIOC_STREAMOFF on camera '%s' has failed: %s", 952 __FUNCTION__, cd->device_name, strerror(errno)); 953 return -1; 954 } 955 break; 956 default: 957 E("%s: Unknown I/O method: %d", __FUNCTION__, cd->io_type); 958 return -1; 959 } 960 961 /* Reopen the device to reset its internal state. It seems that if we don't 962 * do that, an attempt to reinit the device with different frame dimensions 963 * would fail. */ 964 _camera_device_reset(cd); 965 966 return 0; 967 } 968 969 int 970 camera_device_read_frame(CameraDevice* ccd, 971 ClientFrameBuffer* framebuffers, 972 int fbs_num, 973 float r_scale, 974 float g_scale, 975 float b_scale, 976 float exp_comp) 977 { 978 LinuxCameraDevice* cd; 979 980 /* Sanity checks. */ 981 if (ccd == NULL || ccd->opaque == NULL) { 982 E("%s: Invalid camera device descriptor", __FUNCTION__); 983 return -1; 984 } 985 cd = (LinuxCameraDevice*)ccd->opaque; 986 if (cd->handle < 0) { 987 E("%s: Camera device is not opened", __FUNCTION__); 988 return -1; 989 } 990 991 if (cd->io_type == CAMERA_IO_DIRECT) { 992 /* Read directly from the device. */ 993 size_t total_read_bytes = 0; 994 /* There is one framebuffer allocated for direct read. */ 995 void* buff = cd->framebuffers[0].data; 996 do { 997 int read_bytes = 998 read(cd->handle, buff + total_read_bytes, 999 cd->actual_pixel_format.sizeimage - total_read_bytes); 1000 if (read_bytes < 0) { 1001 switch (errno) { 1002 case EIO: 1003 case EAGAIN: 1004 continue; 1005 default: 1006 E("%s: Unable to read from the camera device '%s': %s", 1007 __FUNCTION__, cd->device_name, strerror(errno)); 1008 return -1; 1009 } 1010 } 1011 total_read_bytes += read_bytes; 1012 } while (total_read_bytes < cd->actual_pixel_format.sizeimage); 1013 /* Convert the read frame into the caller's framebuffers. */ 1014 return convert_frame(buff, cd->actual_pixel_format.pixelformat, 1015 cd->actual_pixel_format.sizeimage, 1016 cd->actual_pixel_format.width, 1017 cd->actual_pixel_format.height, 1018 framebuffers, fbs_num, 1019 r_scale, g_scale, b_scale, exp_comp); 1020 } else { 1021 /* Dequeue next buffer from the device. */ 1022 struct v4l2_buffer buf; 1023 int res; 1024 CLEAR(buf); 1025 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1026 buf.memory = cd->io_type == CAMERA_IO_MEMMAP ? V4L2_MEMORY_MMAP : 1027 V4L2_MEMORY_USERPTR; 1028 for (;;) { 1029 const int res = _xioctl(cd->handle, VIDIOC_DQBUF, &buf); 1030 if (res >= 0) { 1031 break; 1032 } else if (errno == EAGAIN) { 1033 return 1; // Tells the caller to repeat. 1034 } else if (errno != EINTR && errno != EIO) { 1035 E("%s: VIDIOC_DQBUF on camera '%s' has failed: %s", 1036 __FUNCTION__, cd->device_name, strerror(errno)); 1037 return -1; 1038 } 1039 } 1040 1041 /* Convert frame to the receiving buffers. */ 1042 res = convert_frame(cd->framebuffers[buf.index].data, 1043 cd->actual_pixel_format.pixelformat, 1044 cd->actual_pixel_format.sizeimage, 1045 cd->actual_pixel_format.width, 1046 cd->actual_pixel_format.height, 1047 framebuffers, fbs_num, 1048 r_scale, g_scale, b_scale, exp_comp); 1049 1050 /* Requeue the buffer back to the device. */ 1051 if (_xioctl(cd->handle, VIDIOC_QBUF, &buf) < 0) { 1052 W("%s: VIDIOC_QBUF on camera '%s' has failed: %s", 1053 __FUNCTION__, cd->device_name, strerror(errno)); 1054 } 1055 1056 return res; 1057 } 1058 } 1059 1060 void 1061 camera_device_close(CameraDevice* ccd) 1062 { 1063 LinuxCameraDevice* cd; 1064 1065 /* Sanity checks. */ 1066 if (ccd != NULL && ccd->opaque != NULL) { 1067 cd = (LinuxCameraDevice*)ccd->opaque; 1068 _camera_device_free(cd); 1069 } else { 1070 E("%s: Invalid camera device descriptor", __FUNCTION__); 1071 } 1072 } 1073 1074 int 1075 enumerate_camera_devices(CameraInfo* cis, int max) 1076 { 1077 char dev_name[24]; 1078 int found = 0; 1079 int n; 1080 1081 for (n = 0; n < max; n++) { 1082 CameraDevice* cd; 1083 1084 sprintf(dev_name, "/dev/video%d", n); 1085 cd = camera_device_open(dev_name, 0); 1086 if (cd != NULL) { 1087 LinuxCameraDevice* lcd = (LinuxCameraDevice*)cd->opaque; 1088 if (!_camera_device_get_info(lcd, cis + found)) { 1089 char user_name[24]; 1090 sprintf(user_name, "webcam%d", found); 1091 cis[found].display_name = ASTRDUP(user_name); 1092 cis[found].in_use = 0; 1093 found++; 1094 } 1095 camera_device_close(cd); 1096 } else { 1097 break; 1098 } 1099 } 1100 1101 return found; 1102 } 1103