| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/capture/video/linux/v4l2_capture_delegate.h" | 5 #include "media/capture/video/linux/v4l2_capture_delegate.h" |
| 6 | 6 |
| 7 #include <poll.h> | 7 #include <poll.h> |
| 8 #include <sys/fcntl.h> | 8 #include <sys/fcntl.h> |
| 9 #include <sys/ioctl.h> | 9 #include <sys/ioctl.h> |
| 10 #include <sys/mman.h> | 10 #include <sys/mman.h> |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 // https://crbug.com/470717 | 31 // https://crbug.com/470717 |
| 32 const int kCaptureTimeoutMs = 1000; | 32 const int kCaptureTimeoutMs = 1000; |
| 33 // The number of continuous timeouts tolerated before treated as error. | 33 // The number of continuous timeouts tolerated before treated as error. |
| 34 const int kContinuousTimeoutLimit = 10; | 34 const int kContinuousTimeoutLimit = 10; |
| 35 // MJPEG is preferred if the requested width or height is larger than this. | 35 // MJPEG is preferred if the requested width or height is larger than this. |
| 36 const int kMjpegWidth = 640; | 36 const int kMjpegWidth = 640; |
| 37 const int kMjpegHeight = 480; | 37 const int kMjpegHeight = 480; |
| 38 // Typical framerate, in fps | 38 // Typical framerate, in fps |
| 39 const int kTypicalFramerate = 30; | 39 const int kTypicalFramerate = 30; |
| 40 | 40 |
| 41 // Constant used to multiply zoom values to avoid using floating point. Used to |
| 42 // scale both the readings (min, max, current) and the value to set it to. |
| 43 const int kZoomMultiplier = 100; |
| 44 |
| 41 // V4L2 color formats supported by V4L2CaptureDelegate derived classes. | 45 // V4L2 color formats supported by V4L2CaptureDelegate derived classes. |
| 42 // This list is ordered by precedence of use -- but see caveats for MJPEG. | 46 // This list is ordered by precedence of use -- but see caveats for MJPEG. |
| 43 static struct { | 47 static struct { |
| 44 uint32_t fourcc; | 48 uint32_t fourcc; |
| 45 VideoPixelFormat pixel_format; | 49 VideoPixelFormat pixel_format; |
| 46 size_t num_planes; | 50 size_t num_planes; |
| 47 } const kSupportedFormatsAndPlanarity[] = { | 51 } const kSupportedFormatsAndPlanarity[] = { |
| 48 {V4L2_PIX_FMT_YUV420, PIXEL_FORMAT_I420, 1}, | 52 {V4L2_PIX_FMT_YUV420, PIXEL_FORMAT_I420, 1}, |
| 49 {V4L2_PIX_FMT_YUYV, PIXEL_FORMAT_YUY2, 1}, | 53 {V4L2_PIX_FMT_YUYV, PIXEL_FORMAT_YUY2, 1}, |
| 50 {V4L2_PIX_FMT_UYVY, PIXEL_FORMAT_UYVY, 1}, | 54 {V4L2_PIX_FMT_UYVY, PIXEL_FORMAT_UYVY, 1}, |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 is_capturing_ = false; | 325 is_capturing_ = false; |
| 322 client_.reset(); | 326 client_.reset(); |
| 323 } | 327 } |
| 324 | 328 |
| 325 void V4L2CaptureDelegate::TakePhoto( | 329 void V4L2CaptureDelegate::TakePhoto( |
| 326 VideoCaptureDevice::TakePhotoCallback callback) { | 330 VideoCaptureDevice::TakePhotoCallback callback) { |
| 327 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); | 331 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); |
| 328 take_photo_callbacks_.push(std::move(callback)); | 332 take_photo_callbacks_.push(std::move(callback)); |
| 329 } | 333 } |
| 330 | 334 |
| 335 void V4L2CaptureDelegate::GetPhotoCapabilities( |
| 336 VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) { |
| 337 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); |
| 338 if (!device_fd_.is_valid() || !is_capturing_) |
| 339 return; |
| 340 |
| 341 mojom::PhotoCapabilitiesPtr photo_capabilities = |
| 342 mojom::PhotoCapabilities::New(); |
| 343 |
| 344 photo_capabilities->zoom = mojom::Range::New(); |
| 345 v4l2_queryctrl zoom_range = {}; |
| 346 zoom_range.id = V4L2_CID_ZOOM_ABSOLUTE; |
| 347 zoom_range.type = V4L2_CTRL_TYPE_INTEGER; |
| 348 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_QUERYCTRL, &zoom_range)) >= |
| 349 0) { |
| 350 photo_capabilities->zoom->max = zoom_range.maximum * kZoomMultiplier; |
| 351 photo_capabilities->zoom->min = zoom_range.minimum * kZoomMultiplier; |
| 352 } |
| 353 v4l2_control zoom_current = {}; |
| 354 zoom_current.id = V4L2_CID_ZOOM_ABSOLUTE; |
| 355 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_G_CTRL, &zoom_current)) >= 0) |
| 356 photo_capabilities->zoom->current = zoom_current.value * kZoomMultiplier; |
| 357 |
| 358 photo_capabilities->focus_mode = mojom::MeteringMode::NONE; |
| 359 v4l2_control auto_focus_current = {}; |
| 360 auto_focus_current.id = V4L2_CID_FOCUS_AUTO; |
| 361 if (HANDLE_EINTR( |
| 362 ioctl(device_fd_.get(), VIDIOC_G_CTRL, &auto_focus_current)) >= 0) { |
| 363 photo_capabilities->focus_mode = auto_focus_current.value |
| 364 ? mojom::MeteringMode::CONTINUOUS |
| 365 : mojom::MeteringMode::MANUAL; |
| 366 } |
| 367 |
| 368 photo_capabilities->exposure_mode = mojom::MeteringMode::NONE; |
| 369 v4l2_control exposure_current = {}; |
| 370 exposure_current.id = V4L2_CID_EXPOSURE_AUTO; |
| 371 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_G_CTRL, &exposure_current)) >= |
| 372 0) { |
| 373 photo_capabilities->exposure_mode = |
| 374 exposure_current.value == V4L2_EXPOSURE_MANUAL |
| 375 ? mojom::MeteringMode::MANUAL |
| 376 : mojom::MeteringMode::CONTINUOUS; |
| 377 } |
| 378 |
| 379 photo_capabilities->white_balance_mode = mojom::MeteringMode::NONE; |
| 380 v4l2_control white_balance_current = {}; |
| 381 white_balance_current.id = V4L2_CID_AUTO_WHITE_BALANCE; |
| 382 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_G_CTRL, |
| 383 &white_balance_current)) >= 0) { |
| 384 photo_capabilities->white_balance_mode = |
| 385 white_balance_current.value ? mojom::MeteringMode::CONTINUOUS |
| 386 : mojom::MeteringMode::MANUAL; |
| 387 } |
| 388 |
| 389 photo_capabilities->iso = mojom::Range::New(); |
| 390 photo_capabilities->height = mojom::Range::New(); |
| 391 photo_capabilities->width = mojom::Range::New(); |
| 392 photo_capabilities->exposure_compensation = mojom::Range::New(); |
| 393 photo_capabilities->fill_light_mode = mojom::FillLightMode::NONE; |
| 394 photo_capabilities->red_eye_reduction = false; |
| 395 callback.Run(std::move(photo_capabilities)); |
| 396 } |
| 397 |
| 398 void V4L2CaptureDelegate::SetPhotoOptions( |
| 399 mojom::PhotoSettingsPtr settings, |
| 400 VideoCaptureDevice::SetPhotoOptionsCallback callback) { |
| 401 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); |
| 402 if (!device_fd_.is_valid() || !is_capturing_) |
| 403 return; |
| 404 |
| 405 if (settings->has_zoom) { |
| 406 v4l2_control zoom_current = {}; |
| 407 zoom_current.id = V4L2_CID_ZOOM_ABSOLUTE; |
| 408 zoom_current.value = settings->zoom / kZoomMultiplier; |
| 409 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_S_CTRL, &zoom_current)) < 0) |
| 410 DPLOG(ERROR) << "setting zoom to " << settings->zoom / kZoomMultiplier; |
| 411 } |
| 412 callback.Run(true); |
| 413 } |
| 414 |
| 331 void V4L2CaptureDelegate::SetRotation(int rotation) { | 415 void V4L2CaptureDelegate::SetRotation(int rotation) { |
| 332 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); | 416 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); |
| 333 DCHECK(rotation >= 0 && rotation < 360 && rotation % 90 == 0); | 417 DCHECK(rotation >= 0 && rotation < 360 && rotation % 90 == 0); |
| 334 rotation_ = rotation; | 418 rotation_ = rotation; |
| 335 } | 419 } |
| 336 | 420 |
| 337 V4L2CaptureDelegate::~V4L2CaptureDelegate() {} | 421 V4L2CaptureDelegate::~V4L2CaptureDelegate() {} |
| 338 | 422 |
| 339 bool V4L2CaptureDelegate::MapAndQueueBuffer(int index) { | 423 bool V4L2CaptureDelegate::MapAndQueueBuffer(int index) { |
| 340 v4l2_buffer buffer; | 424 v4l2_buffer buffer; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 DLOG(ERROR) << "Error mmap()ing a V4L2 buffer into userspace"; | 540 DLOG(ERROR) << "Error mmap()ing a V4L2 buffer into userspace"; |
| 457 return false; | 541 return false; |
| 458 } | 542 } |
| 459 start_ = static_cast<uint8_t*>(start); | 543 start_ = static_cast<uint8_t*>(start); |
| 460 length_ = buffer.length; | 544 length_ = buffer.length; |
| 461 payload_size_ = 0; | 545 payload_size_ = 0; |
| 462 return true; | 546 return true; |
| 463 } | 547 } |
| 464 | 548 |
| 465 } // namespace media | 549 } // namespace media |
| OLD | NEW |