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

Unified Diff: media/capture/video/linux/v4l2_capture_delegate.cc

Issue 2344123002: ImageCapture: Implement TakePhoto() for Linux/CrOs (Closed)
Patch Set: v4l2_capture_delegate.cc l.152: Added back '&0xf0' 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 side-by-side diff with in-line comments
Download patch
Index: media/capture/video/linux/v4l2_capture_delegate.cc
diff --git a/media/capture/video/linux/v4l2_capture_delegate.cc b/media/capture/video/linux/v4l2_capture_delegate.cc
index a6f47b551ed410f3fa28c5f45b888eee6f97c0b7..ddc69dc7ba1c91fc4ec5cd8d47851cbd1e382284 100644
--- a/media/capture/video/linux/v4l2_capture_delegate.cc
+++ b/media/capture/video/linux/v4l2_capture_delegate.cc
@@ -17,6 +17,9 @@
#include "build/build_config.h"
#include "media/base/bind_to_current_loop.h"
#include "media/capture/video/linux/video_capture_device_linux.h"
+#include "third_party/libyuv/include/libyuv.h"
+#include "third_party/skia/include/core/SkImage.h"
+#include "ui/gfx/codec/png_codec.h"
namespace media {
@@ -321,6 +324,12 @@ void V4L2CaptureDelegate::StopAndDeAllocate() {
client_.reset();
}
+void V4L2CaptureDelegate::TakePhoto(
+ VideoCaptureDevice::TakePhotoCallback callback) {
+ DCHECK(v4l2_task_runner_->BelongsToCurrentThread());
+ take_photo_callbacks_.push(std::move(callback));
+}
+
void V4L2CaptureDelegate::SetRotation(int rotation) {
DCHECK(v4l2_task_runner_->BelongsToCurrentThread());
DCHECK(rotation >= 0 && rotation < 360 && rotation % 90 == 0);
@@ -401,6 +410,16 @@ void V4L2CaptureDelegate::DoCapture() {
buffer_tracker->start(), buffer_tracker->payload_size(),
capture_format_, rotation_, base::TimeTicks::Now(), timestamp);
+ while (!take_photo_callbacks_.empty()) {
+ VideoCaptureDevice::TakePhotoCallback cb =
+ std::move(take_photo_callbacks_.front());
+ take_photo_callbacks_.pop();
+
+ mojom::BlobPtr blob = GetPhotoBlob(buffer_tracker, buffer.bytesused);
+ if (blob)
+ cb.Run(std::move(blob));
+ }
+
if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_QBUF, &buffer)) < 0) {
SetErrorState(FROM_HERE, "Failed to enqueue capture buffer");
return;
@@ -411,6 +430,59 @@ void V4L2CaptureDelegate::DoCapture() {
FROM_HERE, base::Bind(&V4L2CaptureDelegate::DoCapture, this));
}
+mojom::BlobPtr V4L2CaptureDelegate::GetPhotoBlob(
+ const scoped_refptr<BufferTracker>& buffer_tracker,
+ const uint32_t bytesused) {
+ uint32 src_format;
+
+ if (capture_format_.pixel_format == VideoPixelFormat::PIXEL_FORMAT_MJPEG) {
+ mojom::BlobPtr blob = mojom::Blob::New();
+ blob->data.resize(bytesused);
+ memcpy(blob->data.data(), buffer_tracker->start(), bytesused);
+ blob->mime_type = "image/jpeg";
+ return blob;
+ } else if (capture_format_.pixel_format ==
+ VideoPixelFormat::PIXEL_FORMAT_UYVY) {
+ src_format = libyuv::FOURCC_UYVY;
+ } else if (capture_format_.pixel_format ==
+ VideoPixelFormat::PIXEL_FORMAT_YUY2) {
+ src_format = libyuv::FOURCC_YUY2;
+ } else if (capture_format_.pixel_format ==
+ VideoPixelFormat::PIXEL_FORMAT_I420) {
+ src_format = libyuv::FOURCC_I420;
+ } else if (capture_format_.pixel_format ==
+ VideoPixelFormat::PIXEL_FORMAT_RGB24) {
+ src_format = libyuv::FOURCC_24BG;
+ } else {
+ return nullptr;
+ }
+
+ std::unique_ptr<uint8_t[]> dst_argb(new uint8_t[VideoFrame::AllocationSize(
+ PIXEL_FORMAT_ARGB, capture_format_.frame_size)]);
+ if (ConvertToARGB(buffer_tracker->start(), bytesused, dst_argb.get(),
+ capture_format_.frame_size.width() * 4, 0 /* crop_x_pos */,
+ 0 /* crop_y_pos */, capture_format_.frame_size.width(),
+ capture_format_.frame_size.height(),
+ capture_format_.frame_size.width(),
+ capture_format_.frame_size.height(),
+ libyuv::RotationMode::kRotate0, src_format) != 0) {
+ return nullptr;
+ }
+
+ mojom::BlobPtr blob = mojom::Blob::New();
+ const gfx::PNGCodec::ColorFormat codec_color_format =
+ (kN32_SkColorType == kRGBA_8888_SkColorType) ? gfx::PNGCodec::FORMAT_RGBA
+ : gfx::PNGCodec::FORMAT_BGRA;
+ const bool result = gfx::PNGCodec::Encode(
+ dst_argb.get(), codec_color_format, capture_format_.frame_size,
+ capture_format_.frame_size.width() * 4, true /* discard_transparency */,
+ std::vector<gfx::PNGCodec::Comment>(), &blob->data);
+ DCHECK(result);
+
+ blob->mime_type = "image/png";
+ return blob;
+}
+
void V4L2CaptureDelegate::SetErrorState(
const tracked_objects::Location& from_here,
const std::string& reason) {
« no previous file with comments | « media/capture/video/linux/v4l2_capture_delegate.h ('k') | media/capture/video/linux/video_capture_device_linux.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698