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

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

Issue 2354783002: ImageCapture: Implement takePhoto() for Windows (Closed)
Patch Set: xianglu@ comments Created 4 years, 3 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>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/files/file_enumerator.h" 14 #include "base/files/file_enumerator.h"
15 #include "base/posix/eintr_wrapper.h" 15 #include "base/posix/eintr_wrapper.h"
16 #include "base/strings/stringprintf.h" 16 #include "base/strings/stringprintf.h"
17 #include "build/build_config.h" 17 #include "build/build_config.h"
18 #include "media/base/bind_to_current_loop.h" 18 #include "media/base/bind_to_current_loop.h"
19 #include "media/capture/video/blob_utils.h"
19 #include "media/capture/video/linux/video_capture_device_linux.h" 20 #include "media/capture/video/linux/video_capture_device_linux.h"
20 #include "third_party/libyuv/include/libyuv.h"
21 #include "third_party/skia/include/core/SkImage.h"
22 #include "ui/gfx/codec/png_codec.h"
23 21
24 namespace media { 22 namespace media {
25 23
26 // Desired number of video buffers to allocate. The actual number of allocated 24 // Desired number of video buffers to allocate. The actual number of allocated
27 // buffers by v4l2 driver can be higher or lower than this number. 25 // buffers by v4l2 driver can be higher or lower than this number.
28 // kNumVideoBuffers should not be too small, or Chrome may not return enough 26 // kNumVideoBuffers should not be too small, or Chrome may not return enough
29 // buffers back to driver in time. 27 // buffers back to driver in time.
30 const uint32_t kNumVideoBuffers = 4; 28 const uint32_t kNumVideoBuffers = 4;
31 // Timeout in milliseconds v4l2_thread_ blocks waiting for a frame from the hw. 29 // Timeout in milliseconds v4l2_thread_ blocks waiting for a frame from the hw.
32 // This value has been fine tuned. Before changing or modifying it see 30 // This value has been fine tuned. Before changing or modifying it see
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 base::TimeDelta::FromMicroseconds(buffer.timestamp.tv_usec); 406 base::TimeDelta::FromMicroseconds(buffer.timestamp.tv_usec);
409 client_->OnIncomingCapturedData( 407 client_->OnIncomingCapturedData(
410 buffer_tracker->start(), buffer_tracker->payload_size(), 408 buffer_tracker->start(), buffer_tracker->payload_size(),
411 capture_format_, rotation_, base::TimeTicks::Now(), timestamp); 409 capture_format_, rotation_, base::TimeTicks::Now(), timestamp);
412 410
413 while (!take_photo_callbacks_.empty()) { 411 while (!take_photo_callbacks_.empty()) {
414 VideoCaptureDevice::TakePhotoCallback cb = 412 VideoCaptureDevice::TakePhotoCallback cb =
415 std::move(take_photo_callbacks_.front()); 413 std::move(take_photo_callbacks_.front());
416 take_photo_callbacks_.pop(); 414 take_photo_callbacks_.pop();
417 415
418 mojom::BlobPtr blob = GetPhotoBlob(buffer_tracker, buffer.bytesused); 416 mojom::BlobPtr blob =
417 Blobify(buffer_tracker->start(), buffer.bytesused, capture_format_);
419 if (blob) 418 if (blob)
420 cb.Run(std::move(blob)); 419 cb.Run(std::move(blob));
421 } 420 }
422 421
423 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_QBUF, &buffer)) < 0) { 422 if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_QBUF, &buffer)) < 0) {
424 SetErrorState(FROM_HERE, "Failed to enqueue capture buffer"); 423 SetErrorState(FROM_HERE, "Failed to enqueue capture buffer");
425 return; 424 return;
426 } 425 }
427 } 426 }
428 427
429 v4l2_task_runner_->PostTask( 428 v4l2_task_runner_->PostTask(
430 FROM_HERE, base::Bind(&V4L2CaptureDelegate::DoCapture, this)); 429 FROM_HERE, base::Bind(&V4L2CaptureDelegate::DoCapture, this));
431 } 430 }
432 431
433 mojom::BlobPtr V4L2CaptureDelegate::GetPhotoBlob(
434 const scoped_refptr<BufferTracker>& buffer_tracker,
435 const uint32_t bytesused) {
436 uint32 src_format;
437
438 if (capture_format_.pixel_format == VideoPixelFormat::PIXEL_FORMAT_MJPEG) {
439 mojom::BlobPtr blob = mojom::Blob::New();
440 blob->data.resize(bytesused);
441 memcpy(blob->data.data(), buffer_tracker->start(), bytesused);
442 blob->mime_type = "image/jpeg";
443 return blob;
444 } else if (capture_format_.pixel_format ==
445 VideoPixelFormat::PIXEL_FORMAT_UYVY) {
446 src_format = libyuv::FOURCC_UYVY;
447 } else if (capture_format_.pixel_format ==
448 VideoPixelFormat::PIXEL_FORMAT_YUY2) {
449 src_format = libyuv::FOURCC_YUY2;
450 } else if (capture_format_.pixel_format ==
451 VideoPixelFormat::PIXEL_FORMAT_I420) {
452 src_format = libyuv::FOURCC_I420;
453 } else if (capture_format_.pixel_format ==
454 VideoPixelFormat::PIXEL_FORMAT_RGB24) {
455 src_format = libyuv::FOURCC_24BG;
456 } else {
457 return nullptr;
458 }
459
460 std::unique_ptr<uint8_t[]> dst_argb(new uint8_t[VideoFrame::AllocationSize(
461 PIXEL_FORMAT_ARGB, capture_format_.frame_size)]);
462 if (ConvertToARGB(buffer_tracker->start(), bytesused, dst_argb.get(),
463 capture_format_.frame_size.width() * 4, 0 /* crop_x_pos */,
464 0 /* crop_y_pos */, capture_format_.frame_size.width(),
465 capture_format_.frame_size.height(),
466 capture_format_.frame_size.width(),
467 capture_format_.frame_size.height(),
468 libyuv::RotationMode::kRotate0, src_format) != 0) {
469 return nullptr;
470 }
471
472 mojom::BlobPtr blob = mojom::Blob::New();
473 const gfx::PNGCodec::ColorFormat codec_color_format =
474 (kN32_SkColorType == kRGBA_8888_SkColorType) ? gfx::PNGCodec::FORMAT_RGBA
475 : gfx::PNGCodec::FORMAT_BGRA;
476 const bool result = gfx::PNGCodec::Encode(
477 dst_argb.get(), codec_color_format, capture_format_.frame_size,
478 capture_format_.frame_size.width() * 4, true /* discard_transparency */,
479 std::vector<gfx::PNGCodec::Comment>(), &blob->data);
480 DCHECK(result);
481
482 blob->mime_type = "image/png";
483 return blob;
484 }
485
486 void V4L2CaptureDelegate::SetErrorState( 432 void V4L2CaptureDelegate::SetErrorState(
487 const tracked_objects::Location& from_here, 433 const tracked_objects::Location& from_here,
488 const std::string& reason) { 434 const std::string& reason) {
489 DCHECK(v4l2_task_runner_->BelongsToCurrentThread()); 435 DCHECK(v4l2_task_runner_->BelongsToCurrentThread());
490 is_capturing_ = false; 436 is_capturing_ = false;
491 client_->OnError(from_here, reason); 437 client_->OnError(from_here, reason);
492 } 438 }
493 439
494 V4L2CaptureDelegate::BufferTracker::BufferTracker() {} 440 V4L2CaptureDelegate::BufferTracker::BufferTracker() {}
495 441
(...skipping 14 matching lines...) Expand all
510 DLOG(ERROR) << "Error mmap()ing a V4L2 buffer into userspace"; 456 DLOG(ERROR) << "Error mmap()ing a V4L2 buffer into userspace";
511 return false; 457 return false;
512 } 458 }
513 start_ = static_cast<uint8_t*>(start); 459 start_ = static_cast<uint8_t*>(start);
514 length_ = buffer.length; 460 length_ = buffer.length;
515 payload_size_ = 0; 461 payload_size_ = 0;
516 return true; 462 return true;
517 } 463 }
518 464
519 } // namespace media 465 } // namespace media
OLDNEW
« no previous file with comments | « media/capture/video/linux/v4l2_capture_delegate.h ('k') | media/capture/video/video_capture_device_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698