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