Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: media/capture/video/linux/v4l2_capture_delegate.cc

Issue 2387303002: Image Capture Linux/CrOs, implement brightness, contrast, saturation and sharpness (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 request_buffer->memory = V4L2_MEMORY_MMAP; 91 request_buffer->memory = V4L2_MEMORY_MMAP;
92 request_buffer->count = count; 92 request_buffer->count = count;
93 } 93 }
94 94
95 // Returns the input |fourcc| as a std::string four char representation. 95 // Returns the input |fourcc| as a std::string four char representation.
96 static std::string FourccToString(uint32_t fourcc) { 96 static std::string FourccToString(uint32_t fourcc) {
97 return base::StringPrintf("%c%c%c%c", fourcc & 0xFF, (fourcc >> 8) & 0xFF, 97 return base::StringPrintf("%c%c%c%c", fourcc & 0xFF, (fourcc >> 8) & 0xFF,
98 (fourcc >> 16) & 0xFF, (fourcc >> 24) & 0xFF); 98 (fourcc >> 16) & 0xFF, (fourcc >> 24) & 0xFF);
99 } 99 }
100 100
101 // Creates a mojom::RangePtr with the range of values (min, max, current) of the
102 // user control associated with |control_id|. Returns an empty Range otherwise.
103 static mojom::RangePtr RetrieveUserControlRange(int device_fd, int control_id) {
104 mojom::RangePtr capability = mojom::Range::New();
105
106 v4l2_queryctrl range = {};
107 range.id = control_id;
108 range.type = V4L2_CTRL_TYPE_INTEGER;
109 if (HANDLE_EINTR(ioctl(device_fd, VIDIOC_QUERYCTRL, &range)) < 0)
110 return mojom::Range::New();
111 capability->max = range.maximum;
112 capability->min = range.minimum;
113
114 v4l2_control current = {};
115 current.id = control_id;
116 if (HANDLE_EINTR(ioctl(device_fd, VIDIOC_G_CTRL, &current)) < 0)
117 return mojom::Range::New();
118 capability->current = current.value;
119
120 return capability;
121 }
122
101 // Class keeping track of a SPLANE V4L2 buffer, mmap()ed on construction and 123 // Class keeping track of a SPLANE V4L2 buffer, mmap()ed on construction and
102 // munmap()ed on destruction. 124 // munmap()ed on destruction.
103 class V4L2CaptureDelegate::BufferTracker 125 class V4L2CaptureDelegate::BufferTracker
104 : public base::RefCounted<BufferTracker> { 126 : public base::RefCounted<BufferTracker> {
105 public: 127 public:
106 BufferTracker(); 128 BufferTracker();
107 // Abstract method to mmap() given |fd| according to |buffer|. 129 // Abstract method to mmap() given |fd| according to |buffer|.
108 bool Init(int fd, const v4l2_buffer& buffer); 130 bool Init(int fd, const v4l2_buffer& buffer);
109 131
110 const uint8_t* start() const { return start_; } 132 const uint8_t* start() const { return start_; }
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 356
335 void V4L2CaptureDelegate::GetPhotoCapabilities( 357 void V4L2CaptureDelegate::GetPhotoCapabilities(
336 VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) { 358 VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) {
337 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); 359 DCHECK(v4l2_task_runner_->BelongsToCurrentThread());
338 if (!device_fd_.is_valid() || !is_capturing_) 360 if (!device_fd_.is_valid() || !is_capturing_)
339 return; 361 return;
340 362
341 mojom::PhotoCapabilitiesPtr photo_capabilities = 363 mojom::PhotoCapabilitiesPtr photo_capabilities =
342 mojom::PhotoCapabilities::New(); 364 mojom::PhotoCapabilities::New();
343 365
344 photo_capabilities->zoom = mojom::Range::New(); 366 photo_capabilities->zoom =
345 v4l2_queryctrl zoom_range = {}; 367 RetrieveUserControlRange(device_fd_.get(), V4L2_CID_ZOOM_ABSOLUTE);
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 368
358 photo_capabilities->focus_mode = mojom::MeteringMode::NONE; 369 photo_capabilities->focus_mode = mojom::MeteringMode::NONE;
359 v4l2_control auto_focus_current = {}; 370 v4l2_control auto_focus_current = {};
360 auto_focus_current.id = V4L2_CID_FOCUS_AUTO; 371 auto_focus_current.id = V4L2_CID_FOCUS_AUTO;
361 if (HANDLE_EINTR( 372 if (HANDLE_EINTR(
362 ioctl(device_fd_.get(), VIDIOC_G_CTRL, &auto_focus_current)) >= 0) { 373 ioctl(device_fd_.get(), VIDIOC_G_CTRL, &auto_focus_current)) >= 0) {
363 photo_capabilities->focus_mode = auto_focus_current.value 374 photo_capabilities->focus_mode = auto_focus_current.value
364 ? mojom::MeteringMode::CONTINUOUS 375 ? mojom::MeteringMode::CONTINUOUS
365 : mojom::MeteringMode::MANUAL; 376 : mojom::MeteringMode::MANUAL;
366 } 377 }
(...skipping 12 matching lines...) Expand all
379 photo_capabilities->white_balance_mode = mojom::MeteringMode::NONE; 390 photo_capabilities->white_balance_mode = mojom::MeteringMode::NONE;
380 v4l2_control white_balance_current = {}; 391 v4l2_control white_balance_current = {};
381 white_balance_current.id = V4L2_CID_AUTO_WHITE_BALANCE; 392 white_balance_current.id = V4L2_CID_AUTO_WHITE_BALANCE;
382 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_G_CTRL, 393 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_G_CTRL,
383 &white_balance_current)) >= 0) { 394 &white_balance_current)) >= 0) {
384 photo_capabilities->white_balance_mode = 395 photo_capabilities->white_balance_mode =
385 white_balance_current.value ? mojom::MeteringMode::CONTINUOUS 396 white_balance_current.value ? mojom::MeteringMode::CONTINUOUS
386 : mojom::MeteringMode::MANUAL; 397 : mojom::MeteringMode::MANUAL;
387 } 398 }
388 399
389 photo_capabilities->color_temperature = mojom::Range::New(); 400 photo_capabilities->color_temperature = RetrieveUserControlRange(
390 v4l2_queryctrl color_temperature_range = {}; 401 device_fd_.get(), V4L2_CID_WHITE_BALANCE_TEMPERATURE);
391 color_temperature_range.id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
392 color_temperature_range.type = V4L2_CTRL_TYPE_INTEGER;
393 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_QUERYCTRL,
394 &color_temperature_range)) >= 0) {
395 photo_capabilities->color_temperature->max =
396 color_temperature_range.maximum;
397 photo_capabilities->color_temperature->min =
398 color_temperature_range.minimum;
399 }
400
401 v4l2_control color_temperature_current = {};
402 color_temperature_current.id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
403 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_G_CTRL,
404 &color_temperature_current)) >= 0) {
405 photo_capabilities->color_temperature->current =
406 color_temperature_current.value;
407 }
408 402
409 photo_capabilities->iso = mojom::Range::New(); 403 photo_capabilities->iso = mojom::Range::New();
410 photo_capabilities->height = mojom::Range::New(); 404 photo_capabilities->height = mojom::Range::New();
411 photo_capabilities->width = mojom::Range::New(); 405 photo_capabilities->width = mojom::Range::New();
412 photo_capabilities->exposure_compensation = mojom::Range::New(); 406 photo_capabilities->exposure_compensation = mojom::Range::New();
413 photo_capabilities->fill_light_mode = mojom::FillLightMode::NONE; 407 photo_capabilities->fill_light_mode = mojom::FillLightMode::NONE;
414 photo_capabilities->red_eye_reduction = false; 408 photo_capabilities->red_eye_reduction = false;
409
410 photo_capabilities->brightness =
411 RetrieveUserControlRange(device_fd_.get(), V4L2_CID_BRIGHTNESS);
412 photo_capabilities->contrast =
413 RetrieveUserControlRange(device_fd_.get(), V4L2_CID_CONTRAST);
414 photo_capabilities->saturation =
415 RetrieveUserControlRange(device_fd_.get(), V4L2_CID_SATURATION);
416 photo_capabilities->sharpness =
417 RetrieveUserControlRange(device_fd_.get(), V4L2_CID_SHARPNESS);
418
415 callback.Run(std::move(photo_capabilities)); 419 callback.Run(std::move(photo_capabilities));
416 } 420 }
417 421
418 void V4L2CaptureDelegate::SetPhotoOptions( 422 void V4L2CaptureDelegate::SetPhotoOptions(
419 mojom::PhotoSettingsPtr settings, 423 mojom::PhotoSettingsPtr settings,
420 VideoCaptureDevice::SetPhotoOptionsCallback callback) { 424 VideoCaptureDevice::SetPhotoOptionsCallback callback) {
421 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); 425 DCHECK(v4l2_task_runner_->BelongsToCurrentThread());
422 if (!device_fd_.is_valid() || !is_capturing_) 426 if (!device_fd_.is_valid() || !is_capturing_)
423 return; 427 return;
424 428
(...skipping 22 matching lines...) Expand all
447 const int result = HANDLE_EINTR( 451 const int result = HANDLE_EINTR(
448 ioctl(device_fd_.get(), VIDIOC_G_CTRL, &auto_white_balance_current)); 452 ioctl(device_fd_.get(), VIDIOC_G_CTRL, &auto_white_balance_current));
449 if (result >= 0 && !auto_white_balance_current.value) { 453 if (result >= 0 && !auto_white_balance_current.value) {
450 v4l2_control set_temperature = {}; 454 v4l2_control set_temperature = {};
451 set_temperature.id = V4L2_CID_WHITE_BALANCE_TEMPERATURE; 455 set_temperature.id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
452 set_temperature.value = settings->color_temperature; 456 set_temperature.value = settings->color_temperature;
453 HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_S_CTRL, &set_temperature)); 457 HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_S_CTRL, &set_temperature));
454 } 458 }
455 } 459 }
456 460
461 if (settings->has_brightness) {
462 v4l2_control current = {};
463 current.id = V4L2_CID_BRIGHTNESS;
464 current.value = settings->brightness;
465 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_S_CTRL, &current)) < 0)
466 DPLOG(ERROR) << "setting brightness to " << settings->brightness;
467 }
468 if (settings->has_brightness) {
chfremer 2016/10/04 17:36:06 Copy-paste error here and the blocks below?
mcasas 2016/10/04 17:44:11 Oh, hark, good catch. Done.
469 v4l2_control current = {};
470 current.id = V4L2_CID_CONTRAST;
471 current.value = settings->contrast;
472 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_S_CTRL, &current)) < 0)
473 DPLOG(ERROR) << "setting contrast to " << settings->contrast;
474 }
475 if (settings->has_brightness) {
476 v4l2_control current = {};
477 current.id = V4L2_CID_SATURATION;
478 current.value = settings->saturation;
479 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_S_CTRL, &current)) < 0)
480 DPLOG(ERROR) << "setting saturation to " << settings->saturation;
481 }
482 if (settings->has_brightness) {
483 v4l2_control current = {};
484 current.id = V4L2_CID_SHARPNESS;
485 current.value = settings->sharpness;
486 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_S_CTRL, &current)) < 0)
487 DPLOG(ERROR) << "setting sharpness to " << settings->sharpness;
488 }
489
457 callback.Run(true); 490 callback.Run(true);
458 } 491 }
459 492
460 void V4L2CaptureDelegate::SetRotation(int rotation) { 493 void V4L2CaptureDelegate::SetRotation(int rotation) {
461 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); 494 DCHECK(v4l2_task_runner_->BelongsToCurrentThread());
462 DCHECK(rotation >= 0 && rotation < 360 && rotation % 90 == 0); 495 DCHECK(rotation >= 0 && rotation < 360 && rotation % 90 == 0);
463 rotation_ = rotation; 496 rotation_ = rotation;
464 } 497 }
465 498
466 V4L2CaptureDelegate::~V4L2CaptureDelegate() {} 499 V4L2CaptureDelegate::~V4L2CaptureDelegate() {}
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 DLOG(ERROR) << "Error mmap()ing a V4L2 buffer into userspace"; 618 DLOG(ERROR) << "Error mmap()ing a V4L2 buffer into userspace";
586 return false; 619 return false;
587 } 620 }
588 start_ = static_cast<uint8_t*>(start); 621 start_ = static_cast<uint8_t*>(start);
589 length_ = buffer.length; 622 length_ = buffer.length;
590 payload_size_ = 0; 623 payload_size_ = 0;
591 return true; 624 return true;
592 } 625 }
593 626
594 } // namespace media 627 } // namespace media
OLDNEW
« no previous file with comments | « media/capture/video/fake_video_capture_device_unittest.cc ('k') | media/mojo/interfaces/image_capture.mojom » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698