Chromium Code Reviews| 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 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 321 is_capturing_ = false; | 321 is_capturing_ = false; |
| 322 client_.reset(); | 322 client_.reset(); |
| 323 } | 323 } |
| 324 | 324 |
| 325 void V4L2CaptureDelegate::TakePhoto( | 325 void V4L2CaptureDelegate::TakePhoto( |
| 326 VideoCaptureDevice::TakePhotoCallback callback) { | 326 VideoCaptureDevice::TakePhotoCallback callback) { |
| 327 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); | 327 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); |
| 328 take_photo_callbacks_.push(std::move(callback)); | 328 take_photo_callbacks_.push(std::move(callback)); |
| 329 } | 329 } |
| 330 | 330 |
| 331 void V4L2CaptureDelegate::GetPhotoCapabilities( | |
| 332 VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) { | |
| 333 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); | |
| 334 if (!device_fd_.is_valid() || !is_capturing_) | |
| 335 return; | |
|
chfremer
2016/09/23 21:18:29
This error case silently swallows the call and doe
mcasas
2016/09/23 22:10:57
The callback is not a simple thing, but a
ScopedR
chfremer
2016/09/23 22:48:56
Thanks. Now I remember you mentioned that to me be
| |
| 336 | |
| 337 mojom::PhotoCapabilitiesPtr photo_capabilities = | |
| 338 mojom::PhotoCapabilities::New(); | |
| 339 | |
| 340 photo_capabilities->zoom = mojom::Range::New(); | |
| 341 v4l2_queryctrl zoom_range = {}; | |
| 342 zoom_range.id = V4L2_CID_ZOOM_ABSOLUTE; | |
| 343 zoom_range.type = V4L2_CTRL_TYPE_INTEGER; | |
| 344 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_QUERYCTRL, &zoom_range)) >= | |
| 345 0) { | |
| 346 photo_capabilities->zoom->max = zoom_range.maximum * 100; | |
| 347 photo_capabilities->zoom->min = zoom_range.minimum * 100; | |
| 348 } | |
| 349 v4l2_control zoom_current = {}; | |
| 350 zoom_current.id = V4L2_CID_ZOOM_ABSOLUTE; | |
| 351 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_G_CTRL, &zoom_current)) >= 0) | |
| 352 photo_capabilities->zoom->current = zoom_current.value * 100; | |
| 353 | |
| 354 photo_capabilities->focus_mode = mojom::MeteringMode::NONE; | |
| 355 v4l2_control auto_focus_current = {}; | |
| 356 auto_focus_current.id = V4L2_CID_FOCUS_AUTO; | |
| 357 if (HANDLE_EINTR( | |
| 358 ioctl(device_fd_.get(), VIDIOC_G_CTRL, &auto_focus_current)) >= 0) { | |
| 359 photo_capabilities->focus_mode = auto_focus_current.value | |
| 360 ? mojom::MeteringMode::CONTINUOUS | |
| 361 : mojom::MeteringMode::MANUAL; | |
| 362 } | |
| 363 | |
| 364 photo_capabilities->exposure_mode = mojom::MeteringMode::NONE; | |
| 365 v4l2_control exposure_current = {}; | |
| 366 exposure_current.id = V4L2_CID_EXPOSURE_AUTO; | |
| 367 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_G_CTRL, &exposure_current)) >= | |
| 368 0) { | |
| 369 photo_capabilities->exposure_mode = | |
| 370 exposure_current.value == V4L2_EXPOSURE_MANUAL | |
| 371 ? mojom::MeteringMode::MANUAL | |
| 372 : mojom::MeteringMode::CONTINUOUS; | |
| 373 } | |
| 374 | |
| 375 photo_capabilities->white_balance_mode = mojom::MeteringMode::NONE; | |
| 376 v4l2_control white_balance_current = {}; | |
| 377 white_balance_current.id = V4L2_CID_AUTO_WHITE_BALANCE; | |
| 378 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_G_CTRL, | |
| 379 &white_balance_current)) >= 0) { | |
| 380 photo_capabilities->white_balance_mode = | |
| 381 white_balance_current.value ? mojom::MeteringMode::CONTINUOUS | |
| 382 : mojom::MeteringMode::MANUAL; | |
| 383 } | |
| 384 | |
| 385 photo_capabilities->iso = mojom::Range::New(); | |
| 386 photo_capabilities->height = mojom::Range::New(); | |
| 387 photo_capabilities->width = mojom::Range::New(); | |
| 388 photo_capabilities->exposure_compensation = mojom::Range::New(); | |
| 389 photo_capabilities->fill_light_mode = mojom::FillLightMode::NONE; | |
| 390 photo_capabilities->red_eye_reduction = false; | |
|
chfremer
2016/09/23 21:18:29
Does the spec allow these "empty ranges" as way of
mcasas
2016/09/23 22:10:57
Yes, mojom::Range::New() essentially makes
all the
| |
| 391 callback.Run(std::move(photo_capabilities)); | |
| 392 } | |
| 393 | |
| 394 void V4L2CaptureDelegate::SetPhotoOptions( | |
| 395 mojom::PhotoSettingsPtr settings, | |
| 396 VideoCaptureDevice::SetPhotoOptionsCallback callback) { | |
| 397 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); | |
| 398 if (!device_fd_.is_valid() || !is_capturing_) | |
| 399 return; | |
|
chfremer
2016/09/23 21:18:29
Same as above.
mcasas
2016/09/23 22:10:57
Acknowledged.
| |
| 400 | |
| 401 if (settings->has_zoom) { | |
| 402 v4l2_control zoom_current = {}; | |
| 403 zoom_current.id = V4L2_CID_ZOOM_ABSOLUTE; | |
| 404 zoom_current.value = settings->zoom / 100; | |
|
chfremer
2016/09/23 21:18:29
If the result of the division is a float, please w
mcasas
2016/09/23 22:10:57
Ridiculously enough, the setting (and the
underlyi
chfremer
2016/09/23 22:48:56
Seems I misinterpreted the value 100 by assuming t
mcasas
2016/09/23 23:16:26
|kZoomMultiplier| it is.
| |
| 405 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_S_CTRL, &zoom_current)) < 0) | |
| 406 DPLOG(ERROR) << "Error setting zoom value to " << (settings->zoom / 100); | |
| 407 } | |
| 408 callback.Run(true); | |
| 409 } | |
| 410 | |
| 331 void V4L2CaptureDelegate::SetRotation(int rotation) { | 411 void V4L2CaptureDelegate::SetRotation(int rotation) { |
| 332 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); | 412 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); |
| 333 DCHECK(rotation >= 0 && rotation < 360 && rotation % 90 == 0); | 413 DCHECK(rotation >= 0 && rotation < 360 && rotation % 90 == 0); |
| 334 rotation_ = rotation; | 414 rotation_ = rotation; |
| 335 } | 415 } |
| 336 | 416 |
| 337 V4L2CaptureDelegate::~V4L2CaptureDelegate() {} | 417 V4L2CaptureDelegate::~V4L2CaptureDelegate() {} |
| 338 | 418 |
| 339 bool V4L2CaptureDelegate::MapAndQueueBuffer(int index) { | 419 bool V4L2CaptureDelegate::MapAndQueueBuffer(int index) { |
| 340 v4l2_buffer buffer; | 420 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"; | 536 DLOG(ERROR) << "Error mmap()ing a V4L2 buffer into userspace"; |
| 457 return false; | 537 return false; |
| 458 } | 538 } |
| 459 start_ = static_cast<uint8_t*>(start); | 539 start_ = static_cast<uint8_t*>(start); |
| 460 length_ = buffer.length; | 540 length_ = buffer.length; |
| 461 payload_size_ = 0; | 541 payload_size_ = 0; |
| 462 return true; | 542 return true; |
| 463 } | 543 } |
| 464 | 544 |
| 465 } // namespace media | 545 } // namespace media |
| OLD | NEW |