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

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

Issue 2344123002: ImageCapture: Implement TakePhoto() for Linux/CrOs (Closed)
Patch Set: 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..491f4f869281c3a343bb47c53995af9c0b7a6ca4 100644
--- a/media/capture/video/linux/v4l2_capture_delegate.cc
+++ b/media/capture/video/linux/v4l2_capture_delegate.cc
@@ -321,6 +321,12 @@ void V4L2CaptureDelegate::StopAndDeAllocate() {
client_.reset();
}
+void V4L2CaptureDelegate::TakePhoto(
+ VideoCaptureDevice::TakePhotoCallback callback) {
+ take_photo_callbacks_.push(std::move(callback));
mcasas 2016/09/16 03:50:36 nit: add DCHECK(v4l2_task_runner_->BelongsToCurren
xianglu 2016/09/16 18:22:33 Done.
+ DVLOG(1) << "in V4L2CaptureDelegate: callback moved";
mcasas 2016/09/16 03:50:36 nit: remove DVLOG()s when you submit for review,
xianglu 2016/09/16 18:22:33 Done.
+}
+
void V4L2CaptureDelegate::SetRotation(int rotation) {
DCHECK(v4l2_task_runner_->BelongsToCurrentThread());
DCHECK(rotation >= 0 && rotation < 360 && rotation % 90 == 0);
@@ -401,6 +407,18 @@ void V4L2CaptureDelegate::DoCapture() {
buffer_tracker->start(), buffer_tracker->payload_size(),
capture_format_, rotation_, base::TimeTicks::Now(), timestamp);
+ // Process all the callbacks from TakePhoto()
mcasas 2016/09/16 03:50:36 nit: No need for this comment.
xianglu 2016/09/16 18:22:33 Done.
+ while (!take_photo_callbacks_.empty()) {
+ VideoCaptureDevice::TakePhotoCallback cb =
+ std::move(take_photo_callbacks_.front());
+ take_photo_callbacks_.pop();
+
+ if (mojom::BlobPtr blob = GetPhotoBlob(buffer_tracker, buffer))
mcasas 2016/09/16 03:50:36 nit: Don't mix assignments and conditionals.
xianglu 2016/09/16 18:22:33 Done.
+ cb.Run(std::move(blob));
+ else
+ DVLOG(3) << "blob pointer is null.";
+ }
+
if (HANDLE_EINTR(ioctl(device_fd_.get(), VIDIOC_QBUF, &buffer)) < 0) {
SetErrorState(FROM_HERE, "Failed to enqueue capture buffer");
return;
@@ -411,6 +429,60 @@ void V4L2CaptureDelegate::DoCapture() {
FROM_HERE, base::Bind(&V4L2CaptureDelegate::DoCapture, this));
}
+mojom::BlobPtr V4L2CaptureDelegate::GetPhotoBlob(
+ const scoped_refptr<BufferTracker>& buffer_tracker,
+ const v4l2_buffer& buffer) {
+ std::unique_ptr<uint8_t[]> dst_argb(new uint8_t[VideoFrame::AllocationSize(
+ PIXEL_FORMAT_ARGB, capture_format_.frame_size)]);
+ mojom::BlobPtr blob = mojom::Blob::New();
+
+ DVLOG(1) << "Format captured: "
+ << VideoPixelFormatToString(capture_format_.pixel_format);
+
+ uint32 src_format;
+ switch (capture_format_.pixel_format) {
+ case VideoPixelFormat::PIXEL_FORMAT_MJPEG:
+ blob->data.resize(buffer.bytesused);
mcasas 2016/09/16 03:50:36 If we take this path, |dst_argb| would be unused a
xianglu 2016/09/16 18:22:33 Indeed. Should work this way.
+ memcpy(blob->data.data(), buffer_tracker->start(), buffer.bytesused);
+ blob->mime_type = "image/jpeg";
+ return blob;
+ case VideoPixelFormat::PIXEL_FORMAT_UYVY:
+ src_format = libyuv::FOURCC_UYVY;
+ break;
+ case VideoPixelFormat::PIXEL_FORMAT_YUY2:
+ src_format = libyuv::FOURCC_YUY2;
+ break;
+ default:
+ DVLOG(3) << "FORMAT not supported.";
mcasas 2016/09/16 03:50:36 Instead of DVLOG(3), consider using DLOG(ERROR) <
xianglu 2016/09/16 18:22:33 Why would you remove ConvertFailure log?
mcasas 2016/09/16 18:59:15 All those error logs are only really useful for d
+ return nullptr;
+ }
+
+ if (ConvertToARGB(buffer_tracker->start(), buffer.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) {
+ DVLOG(3) << "Failed to convert buffer's pixel format from "
+ << VideoPixelFormatToString(capture_format_.pixel_format)
+ << " to ARGB";
+ return nullptr;
+ }
+
+ 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) {

Powered by Google App Engine
This is Rietveld 408576698