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 _xioctl(int fd,int request,void * arg)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 */ _qemu_pixel_format_free(QemuPixelFormat * fmt)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 _get_format_index(uint32_t fmt,QemuPixelFormat * formats,int size)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 _free_framebuffers(CameraFrameBuffer * fb,int num,CameraIoType io_type)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* _camera_device_alloc(void)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 _camera_device_free(LinuxCameraDevice * lcd)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 _camera_device_reset(LinuxCameraDevice * cd)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 _camera_device_mmap_framebuffer(LinuxCameraDevice * cd)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 _camera_device_user_framebuffer(LinuxCameraDevice * cd)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 _camera_device_direct_framebuffer(LinuxCameraDevice * cd)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 _camera_device_open(LinuxCameraDevice * cd)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 _camera_device_enum_format_sizes(LinuxCameraDevice * cd,uint32_t fmt,CameraFrameDim ** sizes)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 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 _camera_device_enum_pixel_formats(LinuxCameraDevice * cd,QemuPixelFormat ** fmts)671 _camera_device_enum_pixel_formats(LinuxCameraDevice* cd, QemuPixelFormat** fmts) 672 { 673 int n; 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 (n = 0; ; n++) { 681 fmt_enum.index = n; 682 fmt_enum.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 683 if(_xioctl(cd->handle, VIDIOC_ENUM_FMT, &fmt_enum)) { 684 break; 685 } 686 /* Skip the compressed ones. */ 687 if ((fmt_enum.flags & V4L2_FMT_FLAG_COMPRESSED) == 0) { 688 fmt_num++; 689 } 690 } 691 if (fmt_num == 0) { 692 return 0; 693 } 694 695 /* Allocate, and initialize array for enumerated formats. */ 696 *fmts = (QemuPixelFormat*)malloc(fmt_num * sizeof(QemuPixelFormat)); 697 if (*fmts == NULL) { 698 E("%s: Memory allocation failure", __FUNCTION__); 699 return -1; 700 } 701 arr = *fmts; 702 memset(arr, 0, fmt_num * sizeof(QemuPixelFormat)); 703 for (n = 0; out_num < fmt_num; n++) { 704 fmt_enum.index = n; 705 fmt_enum.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 706 if(_xioctl(cd->handle, VIDIOC_ENUM_FMT, &fmt_enum)) { 707 int nn; 708 /* Errors are not welcome here anymore. */ 709 E("%s: Unexpected failure while getting pixel format: %s", 710 strerror(errno)); 711 for (nn = 0; nn < out_num; nn++) { 712 _qemu_pixel_format_free(arr + nn); 713 } 714 free(arr); 715 return -1; 716 } 717 /* Skip the compressed ones. */ 718 if ((fmt_enum.flags & V4L2_FMT_FLAG_COMPRESSED) == 0) { 719 arr[out_num].format = fmt_enum.pixelformat; 720 /* Enumerate frame dimensions supported for this format. */ 721 arr[out_num].dim_num = 722 _camera_device_enum_format_sizes(cd, fmt_enum.pixelformat, 723 &arr[out_num].dims); 724 if (arr[out_num].dim_num > 0) { 725 out_num++; 726 } else if (arr[out_num].dim_num < 0) { 727 int nn; 728 E("Unable to enumerate supported dimensions for pixel format %d", 729 fmt_enum.pixelformat); 730 for (nn = 0; nn < out_num; nn++) { 731 _qemu_pixel_format_free(arr + nn); 732 } 733 free(arr); 734 return -1; 735 } 736 } 737 } 738 739 return out_num; 740 } 741 742 /* Collects information about an opened camera device. 743 * The information collected in this routine contains list of pixel formats, 744 * supported by the device, and list of frame dimensions supported by the camera 745 * for each pixel format. 746 * Param: 747 * cd - Opened camera device descriptor. 748 * cis - Upon success contains information collected from the camera device. 749 * Return: 750 * 0 on success, != 0 on failure. 751 */ 752 static int _camera_device_get_info(LinuxCameraDevice * cd,CameraInfo * cis)753 _camera_device_get_info(LinuxCameraDevice* cd, CameraInfo* cis) 754 { 755 int f; 756 int chosen = -1; 757 QemuPixelFormat* formats = NULL; 758 int num_pix_fmts = _camera_device_enum_pixel_formats(cd, &formats); 759 if (num_pix_fmts <= 0) { 760 return num_pix_fmts; 761 } 762 763 /* Lets see if camera supports preferred formats */ 764 for (f = 0; f < _preferred_format_num; f++) { 765 chosen = _get_format_index(_preferred_formats[f], formats, num_pix_fmts); 766 if (chosen >= 0) { 767 break; 768 } 769 } 770 if (chosen < 0) { 771 /* Camera doesn't support any of the chosen formats. Then it doesn't 772 * matter which one we choose. Lets choose the first one. */ 773 chosen = 0; 774 } 775 776 cis->device_name = ASTRDUP(cd->device_name); 777 cis->inp_channel = cd->input_channel; 778 cis->pixel_format = formats[chosen].format; 779 cis->frame_sizes_num = formats[chosen].dim_num; 780 /* Swap instead of copy. */ 781 cis->frame_sizes = formats[chosen].dims; 782 formats[chosen].dims = NULL; 783 cis->in_use = 0; 784 785 for (f = 0; f < num_pix_fmts; f++) { 786 _qemu_pixel_format_free(formats + f); 787 } 788 free(formats); 789 790 return 0; 791 } 792 793 /******************************************************************************* 794 * CameraDevice API 795 ******************************************************************************/ 796 797 CameraDevice* camera_device_open(const char * name,int inp_channel)798 camera_device_open(const char* name, int inp_channel) 799 { 800 struct v4l2_cropcap cropcap; 801 struct v4l2_crop crop; 802 LinuxCameraDevice* cd; 803 804 /* Allocate and initialize the descriptor. */ 805 cd = _camera_device_alloc(); 806 cd->device_name = name != NULL ? ASTRDUP(name) : ASTRDUP("/dev/video0"); 807 cd->input_channel = inp_channel; 808 809 /* Open the device. */ 810 if (_camera_device_open(cd)) { 811 _camera_device_free(cd); 812 return NULL; 813 } 814 815 /* Select video input, video standard and tune here. */ 816 cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 817 _xioctl(cd->handle, VIDIOC_CROPCAP, &cropcap); 818 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 819 crop.c = cropcap.defrect; /* reset to default */ 820 _xioctl (cd->handle, VIDIOC_S_CROP, &crop); 821 822 return &cd->header; 823 } 824 825 int camera_device_start_capturing(CameraDevice * ccd,uint32_t pixel_format,int frame_width,int frame_height)826 camera_device_start_capturing(CameraDevice* ccd, 827 uint32_t pixel_format, 828 int frame_width, 829 int frame_height) 830 { 831 struct v4l2_format fmt; 832 LinuxCameraDevice* cd; 833 char fmt_str[5]; 834 int r; 835 836 /* Sanity checks. */ 837 if (ccd == NULL || ccd->opaque == NULL) { 838 E("%s: Invalid camera device descriptor", __FUNCTION__); 839 return -1; 840 } 841 cd = (LinuxCameraDevice*)ccd->opaque; 842 if (cd->handle < 0) { 843 E("%s: Camera device is not opened", __FUNCTION__); 844 return -1; 845 } 846 847 /* Try to set pixel format with the given dimensions. */ 848 CLEAR(fmt); 849 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 850 fmt.fmt.pix.width = frame_width; 851 fmt.fmt.pix.height = frame_height; 852 fmt.fmt.pix.pixelformat = pixel_format; 853 if (_xioctl(cd->handle, VIDIOC_S_FMT, &fmt) < 0) { 854 memcpy(fmt_str, &pixel_format, 4); 855 fmt_str[4] = '\0'; 856 E("%s: Camera '%s' does not support pixel format '%s' with dimensions %dx%d", 857 __FUNCTION__, cd->device_name, fmt_str, frame_width, frame_height); 858 _camera_device_reset(cd); 859 return -1; 860 } 861 /* VIDIOC_S_FMT may has changed some properties of the structure. Make sure 862 * that dimensions didn't change. */ 863 if (fmt.fmt.pix.width != frame_width || fmt.fmt.pix.height != frame_height) { 864 memcpy(fmt_str, &pixel_format, 4); 865 fmt_str[4] = '\0'; 866 E("%s: Dimensions %dx%d are wrong for pixel format '%s'", 867 __FUNCTION__, frame_width, frame_height, fmt_str); 868 _camera_device_reset(cd); 869 return -1; 870 } 871 memcpy(&cd->actual_pixel_format, &fmt.fmt.pix, sizeof(struct v4l2_pix_format)); 872 873 /* 874 * Lets initialize frame buffers, and see what kind of I/O we're going to 875 * use to retrieve frames. 876 */ 877 878 /* First, lets see if we can do mapped I/O (as most performant one). */ 879 r = _camera_device_mmap_framebuffer(cd); 880 if (r < 0) { 881 /* Some critical error has ocurred. Bail out. */ 882 _camera_device_reset(cd); 883 return -1; 884 } else if (r > 0) { 885 /* Device doesn't support memory mapping. Retrieve to the next performant 886 * one: preallocated user buffers. */ 887 r = _camera_device_user_framebuffer(cd); 888 if (r < 0) { 889 /* Some critical error has ocurred. Bail out. */ 890 _camera_device_reset(cd); 891 return -1; 892 } else if (r > 0) { 893 /* The only thing left for us is direct reading from the device. */ 894 if (!(cd->caps.capabilities & V4L2_CAP_READWRITE)) { 895 E("%s: Don't know how to access frames on device '%s'", 896 __FUNCTION__, cd->device_name); 897 _camera_device_reset(cd); 898 return -1; 899 } 900 r = _camera_device_direct_framebuffer(cd); 901 if (r != 0) { 902 /* Any error at this point is a critical one. */ 903 _camera_device_reset(cd); 904 return -1; 905 } 906 } 907 } 908 909 /* Start capturing from the device. */ 910 if (cd->io_type != CAMERA_IO_DIRECT) { 911 enum v4l2_buf_type type; 912 type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 913 if (_xioctl (cd->handle, VIDIOC_STREAMON, &type) < 0) { 914 E("%s: VIDIOC_STREAMON on camera '%s' has failed: %s", 915 __FUNCTION__, cd->device_name, strerror(errno)); 916 _camera_device_reset(cd); 917 return -1; 918 } 919 } 920 return 0; 921 } 922 923 int camera_device_stop_capturing(CameraDevice * ccd)924 camera_device_stop_capturing(CameraDevice* ccd) 925 { 926 enum v4l2_buf_type type; 927 LinuxCameraDevice* cd; 928 929 /* Sanity checks. */ 930 if (ccd == NULL || ccd->opaque == NULL) { 931 E("%s: Invalid camera device descriptor", __FUNCTION__); 932 return -1; 933 } 934 cd = (LinuxCameraDevice*)ccd->opaque; 935 if (cd->handle < 0) { 936 E("%s: Camera device is not opened", __FUNCTION__); 937 return -1; 938 } 939 940 switch (cd->io_type) { 941 case CAMERA_IO_DIRECT: 942 /* Nothing to do. */ 943 break; 944 945 case CAMERA_IO_MEMMAP: 946 case CAMERA_IO_USERPTR: 947 type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 948 if (_xioctl(cd->handle, VIDIOC_STREAMOFF, &type) < 0) { 949 E("%s: VIDIOC_STREAMOFF on camera '%s' has failed: %s", 950 __FUNCTION__, cd->device_name, strerror(errno)); 951 return -1; 952 } 953 break; 954 default: 955 E("%s: Unknown I/O method: %d", __FUNCTION__, cd->io_type); 956 return -1; 957 } 958 959 /* Reopen the device to reset its internal state. It seems that if we don't 960 * do that, an attempt to reinit the device with different frame dimensions 961 * would fail. */ 962 _camera_device_reset(cd); 963 964 return 0; 965 } 966 967 int camera_device_read_frame(CameraDevice * ccd,ClientFrameBuffer * framebuffers,int fbs_num)968 camera_device_read_frame(CameraDevice* ccd, 969 ClientFrameBuffer* framebuffers, 970 int fbs_num) 971 { 972 LinuxCameraDevice* cd; 973 974 /* Sanity checks. */ 975 if (ccd == NULL || ccd->opaque == NULL) { 976 E("%s: Invalid camera device descriptor", __FUNCTION__); 977 return -1; 978 } 979 cd = (LinuxCameraDevice*)ccd->opaque; 980 if (cd->handle < 0) { 981 E("%s: Camera device is not opened", __FUNCTION__); 982 return -1; 983 } 984 985 if (cd->io_type == CAMERA_IO_DIRECT) { 986 /* Read directly from the device. */ 987 size_t total_read_bytes = 0; 988 /* There is one framebuffer allocated for direct read. */ 989 void* buff = cd->framebuffers[0].data; 990 do { 991 int read_bytes = 992 read(cd->handle, buff + total_read_bytes, 993 cd->actual_pixel_format.sizeimage - total_read_bytes); 994 if (read_bytes < 0) { 995 switch (errno) { 996 case EIO: 997 case EAGAIN: 998 continue; 999 default: 1000 E("%s: Unable to read from the camera device '%s': %s", 1001 __FUNCTION__, cd->device_name, strerror(errno)); 1002 return -1; 1003 } 1004 } 1005 total_read_bytes += read_bytes; 1006 } while (total_read_bytes < cd->actual_pixel_format.sizeimage); 1007 /* Convert the read frame into the caller's framebuffers. */ 1008 return convert_frame(buff, cd->actual_pixel_format.pixelformat, 1009 cd->actual_pixel_format.sizeimage, 1010 cd->actual_pixel_format.width, 1011 cd->actual_pixel_format.height, 1012 framebuffers, fbs_num); 1013 } else { 1014 /* Dequeue next buffer from the device. */ 1015 struct v4l2_buffer buf; 1016 int res; 1017 CLEAR(buf); 1018 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1019 buf.memory = cd->io_type == CAMERA_IO_MEMMAP ? V4L2_MEMORY_MMAP : 1020 V4L2_MEMORY_USERPTR; 1021 for (;;) { 1022 const int res = _xioctl(cd->handle, VIDIOC_DQBUF, &buf); 1023 if (res >= 0) { 1024 break; 1025 } else if (errno == EAGAIN) { 1026 return 1; // Tells the caller to repeat. 1027 } else if (errno != EINTR && errno != EIO) { 1028 E("%s: VIDIOC_DQBUF on camera '%s' has failed: %s", 1029 __FUNCTION__, cd->device_name, strerror(errno)); 1030 return -1; 1031 } 1032 } 1033 1034 /* Convert frame to the receiving buffers. */ 1035 res = convert_frame(cd->framebuffers[buf.index].data, 1036 cd->actual_pixel_format.pixelformat, 1037 cd->actual_pixel_format.sizeimage, 1038 cd->actual_pixel_format.width, 1039 cd->actual_pixel_format.height, 1040 framebuffers, fbs_num); 1041 1042 /* Requeue the buffer back to the device. */ 1043 if (_xioctl(cd->handle, VIDIOC_QBUF, &buf) < 0) { 1044 W("%s: VIDIOC_QBUF on camera '%s' has failed: %s", 1045 __FUNCTION__, cd->device_name, strerror(errno)); 1046 } 1047 1048 return res; 1049 } 1050 } 1051 1052 void camera_device_close(CameraDevice * ccd)1053 camera_device_close(CameraDevice* ccd) 1054 { 1055 LinuxCameraDevice* cd; 1056 1057 /* Sanity checks. */ 1058 if (ccd != NULL && ccd->opaque != NULL) { 1059 cd = (LinuxCameraDevice*)ccd->opaque; 1060 _camera_device_free(cd); 1061 } else { 1062 E("%s: Invalid camera device descriptor", __FUNCTION__); 1063 } 1064 } 1065 1066 int enumerate_camera_devices(CameraInfo * cis,int max)1067 enumerate_camera_devices(CameraInfo* cis, int max) 1068 { 1069 char dev_name[24]; 1070 int found = 0; 1071 int n; 1072 1073 for (n = 0; n < max; n++) { 1074 CameraDevice* cd; 1075 1076 sprintf(dev_name, "/dev/video%d", n); 1077 cd = camera_device_open(dev_name, 0); 1078 if (cd != NULL) { 1079 LinuxCameraDevice* lcd = (LinuxCameraDevice*)cd->opaque; 1080 if (!_camera_device_get_info(lcd, cis + found)) { 1081 char user_name[24]; 1082 sprintf(user_name, "webcam%d", found); 1083 cis[found].display_name = ASTRDUP(user_name); 1084 cis[found].in_use = 0; 1085 found++; 1086 } 1087 camera_device_close(cd); 1088 } else { 1089 break; 1090 } 1091 } 1092 1093 return found; 1094 } 1095