Index: media/video/capture/linux/v4l2_capture_delegate_multi_plane.cc |
diff --git a/media/video/capture/linux/v4l2_capture_delegate_multi_plane.cc b/media/video/capture/linux/v4l2_capture_delegate_multi_plane.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..876a0959761f65d9041a9ba83fd937dc3820e82c |
--- /dev/null |
+++ b/media/video/capture/linux/v4l2_capture_delegate_multi_plane.cc |
@@ -0,0 +1,97 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "media/video/capture/linux/v4l2_capture_delegate_multi_plane.h" |
+ |
+#include <sys/mman.h> |
+ |
+namespace media { |
+ |
+V4L2CaptureDelegateMultiPlane::V4L2CaptureDelegateMultiPlane( |
+ const VideoCaptureDevice::Name& device_name, |
+ const scoped_refptr<base::SingleThreadTaskRunner>& v4l2_task_runner, |
+ int power_line_frequency) |
+ : V4L2VideoCaptureDelegate(device_name, |
+ v4l2_task_runner, |
+ power_line_frequency) { |
+} |
+ |
+V4L2CaptureDelegateMultiPlane::~V4L2CaptureDelegateMultiPlane() { |
+} |
+ |
+scoped_refptr<V4L2VideoCaptureDelegate::BufferTracker> |
+V4L2CaptureDelegateMultiPlane::CreateBufferTracker() const { |
+ return make_scoped_refptr(new BufferTrackerMPlane()); |
+} |
+ |
+bool V4L2CaptureDelegateMultiPlane::FillV4L2Format( |
+ v4l2_format* format, |
+ uint32_t width, |
+ uint32_t height, |
+ uint32_t pixelformat_fourcc) const { |
+ format->fmt.pix_mp.width = width; |
+ format->fmt.pix_mp.height = height; |
+ format->fmt.pix_mp.pixelformat = pixelformat_fourcc; |
+ |
+ const size_t num_v4l2_planes = |
+ V4L2VideoCaptureDelegate::GetNumPlanesForFourCc(pixelformat_fourcc); |
+ if (num_v4l2_planes == 0u) |
+ return false; |
+ DCHECK_LE(num_v4l2_planes, static_cast<size_t>(VIDEO_MAX_PLANES)); |
+ format->fmt.pix_mp.num_planes = num_v4l2_planes; |
+ |
+ v4l2_planes_.resize(num_v4l2_planes); |
+ return true; |
+} |
+ |
+void V4L2CaptureDelegateMultiPlane::FinishFillingV4L2Buffer( |
+ v4l2_buffer* buffer) const { |
+ buffer->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; |
+ buffer->length = v4l2_planes_.size(); |
+ |
+ static const struct v4l2_plane empty_plane = {}; |
+ std::fill(v4l2_planes_.begin(), v4l2_planes_.end(), empty_plane); |
+ buffer->m.planes = v4l2_planes_.data(); |
+} |
+ |
+void V4L2CaptureDelegateMultiPlane::SendBuffer( |
+ const scoped_refptr<BufferTracker>& buffer_tracker) const { |
+ DCHECK_EQ(capture_format().pixel_format, PIXEL_FORMAT_I420); |
+ const size_t y_stride = |
+ buffer_tracker->GetPlaneLength(0) / capture_format().frame_size.height(); |
Pawel Osciak
2015/03/20 00:56:06
If you need stride, then you should use bytesperli
mcasas
2015/03/20 03:01:20
Done.
|
+ const size_t u_stride = buffer_tracker->GetPlaneLength(1) / |
+ ((capture_format().frame_size.height() + 1) / 2); |
+ const size_t v_stride = buffer_tracker->GetPlaneLength(2) / |
+ ((capture_format().frame_size.height() + 1) / 2); |
+ client()->OnIncomingCapturedYuvData(buffer_tracker->GetPlaneStart(0), |
+ buffer_tracker->GetPlaneStart(1), |
+ buffer_tracker->GetPlaneStart(2), |
+ y_stride, |
Pawel Osciak
2015/03/20 00:56:06
The prototype of VideoCaptureDevice::Client::OnInc
mcasas
2015/03/20 03:01:20
Done.
|
+ u_stride, |
+ v_stride, |
+ capture_format(), |
+ rotation(), |
+ base::TimeTicks::Now()); |
+} |
+ |
+bool V4L2CaptureDelegateMultiPlane::BufferTrackerMPlane::Init( |
+ int fd, |
+ const v4l2_buffer& buffer) { |
+ for (size_t p = 0; p < buffer.length; ++p) { |
+ // Some devices require mmap() to be called with both READ and WRITE. |
+ // See http://crbug.com/178582. |
+ void* const start = |
+ mmap(NULL, buffer.m.planes[p].length, PROT_READ | PROT_WRITE, |
+ MAP_SHARED, fd, buffer.m.planes[p].m.mem_offset); |
+ if (start == MAP_FAILED) { |
+ DLOG(ERROR) << "Error mmap()ing a V4L2 buffer into userspace"; |
+ return false; |
+ } |
+ AddMmapedPlane(static_cast<uint8_t*>(start), buffer.m.planes[p].length); |
+ DVLOG(3) << "Mmap()ed plane #" << p << " of " << GetPlaneLength(p) << "B"; |
+ } |
+ return true; |
+} |
+ |
+} // namespace media |