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

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

Issue 1124723006: VideoCaptureDeviceLinux: Add support for SPLANE+DMABUF V4L2 type capture (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: posciak@ review and rebase (AsPlatformFile(), ...BufferPoolUtilization...)). Created 5 years, 6 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/video/capture/linux/v4l2_capture_delegate_single_plane.cc
diff --git a/media/video/capture/linux/v4l2_capture_delegate_single_plane.cc b/media/video/capture/linux/v4l2_capture_delegate_single_plane.cc
index e2e7e5b0da16a9c4b934b83bdfa567a1f1ab39d6..7176f094cc8f7416ffee1a321a62f7df7e9539da 100644
--- a/media/video/capture/linux/v4l2_capture_delegate_single_plane.cc
+++ b/media/video/capture/linux/v4l2_capture_delegate_single_plane.cc
@@ -4,10 +4,30 @@
#include "media/video/capture/linux/v4l2_capture_delegate_single_plane.h"
+#include <linux/version.h>
#include <sys/mman.h>
namespace media {
+V4L2CaptureDelegateSinglePlane::V4L2CaptureDelegateSinglePlane(
+ const VideoCaptureDevice::Name& device_name,
+ const scoped_refptr<base::SingleThreadTaskRunner>& v4l2_task_runner,
+ int power_line_frequency,
+ bool allow_using_dma_bufs)
+ : V4L2CaptureDelegate(
+ device_name,
+ v4l2_task_runner,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+ allow_using_dma_bufs ? V4L2_MEMORY_DMABUF : V4L2_MEMORY_MMAP,
+#else
+ V4L2_MEMORY_MMAP,
+#endif
+ power_line_frequency) {
+}
+
+V4L2CaptureDelegateSinglePlane::~V4L2CaptureDelegateSinglePlane() {
+}
+
scoped_refptr<V4L2CaptureDelegate::BufferTracker>
V4L2CaptureDelegateSinglePlane::CreateBufferTracker() const {
return make_scoped_refptr(new BufferTrackerSPlane());
@@ -25,8 +45,32 @@ bool V4L2CaptureDelegateSinglePlane::FillV4L2Format(
}
void V4L2CaptureDelegateSinglePlane::FinishFillingV4L2Buffer(
- v4l2_buffer* buffer) const {
+ v4l2_buffer* buffer,
+ bool for_enqueue) const {
buffer->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+ if (memory_type() == V4L2_MEMORY_MMAP)
+ return;
+
+ if (!for_enqueue) {
+ DCHECK_NE(buffer->m.fd, -1); // API should have filled |fd| in for dequeue.
+ return;
+ }
+ // For enqueueing, need to reserve an output buffer, keep it locally and pass
+ // its |fd| into the V4L2 API.
+ scoped_ptr<VideoCaptureDevice::Client::Buffer> capture_buffer =
+ client()->ReserveOutputBuffer(media::PIXEL_FORMAT_GPUMEMORYBUFFER,
+ capture_format().frame_size);
+ if (!capture_buffer)
+ return;
+
+ DCHECK_EQ(capture_buffer->GetType(), gfx::OZONE_NATIVE_BUFFER);
+ buffer->m.fd = capture_buffer->AsPlatformFile();
+
+ allocated_buffers_.push_back(capture_buffer.release());
+ DVLOG(1) << "Sizeof allocated_buffers_ " << allocated_buffers_.size();
+#endif
}
void V4L2CaptureDelegateSinglePlane::SetPayloadSize(
@@ -38,17 +82,48 @@ void V4L2CaptureDelegateSinglePlane::SetPayloadSize(
void V4L2CaptureDelegateSinglePlane::SendBuffer(
const scoped_refptr<BufferTracker>& buffer_tracker,
const v4l2_format& format) const {
- client()->OnIncomingCapturedData(
- buffer_tracker->GetPlaneStart(0),
- buffer_tracker->GetPlanePayloadSize(0),
- capture_format(),
- rotation(),
- base::TimeTicks::Now());
+ DVLOG(1) << __FUNCTION__;
+
+ if (memory_type() == V4L2_MEMORY_MMAP) {
+ const size_t data_length = format.fmt.pix.sizeimage;
+ DCHECK_GE(data_length, capture_format().ImageAllocationSize());
+ client()->OnIncomingCapturedData(
+ buffer_tracker->GetPlaneStart(0),
+ buffer_tracker->GetPlanePayloadSize(0),
+ capture_format(),
+ rotation(),
+ base::TimeTicks::Now());
+ return;
+ }
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+ // Search for the |fd| used for capture in |allocated_buffers_| and send it
+ // to client().
+ const int incoming_fd = buffer_tracker->GetPlaneFd(0);
+ ScopedVector<VideoCaptureDevice::Client::Buffer>::iterator used_buffer =
+ std::find_if(allocated_buffers_.begin(), allocated_buffers_.end(),
+ [incoming_fd](VideoCaptureDevice::Client::Buffer* b) {
+ return incoming_fd == b->AsPlatformFile();
+ });
+ CHECK(used_buffer != allocated_buffers_.end())
+ << "Uh oh, captured |fd| is not found in the list :?";
+ client()->OnIncomingCapturedBuffer(make_scoped_ptr(*used_buffer),
+ capture_format(), base::TimeTicks::Now());
+ allocated_buffers_.weak_erase(used_buffer);
+#endif
}
bool V4L2CaptureDelegateSinglePlane::BufferTrackerSPlane::Init(
int fd,
const v4l2_buffer& buffer) {
+ DVLOG(1) << __FUNCTION__;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+ if (buffer.memory == V4L2_MEMORY_DMABUF) {
+ AddNonMmapedPlane(buffer.m.fd);
+ return true;
+ }
+#endif
+
// Some devices require mmap() to be called with both READ and WRITE.
// See http://crbug.com/178582.
void* const start = mmap(NULL, buffer.length, PROT_READ | PROT_WRITE,

Powered by Google App Engine
This is Rietveld 408576698