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

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: Rebase 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..b650ba34c8006578902486a82fc196f70a7c1eb3 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,27 @@
#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 try_to_use_dma_buf)
+ : V4L2CaptureDelegate(device_name, v4l2_task_runner, power_line_frequency) {
+ memory_type_ = V4L2_MEMORY_MMAP;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
+ if (try_to_use_dma_buf)
+ memory_type_ = V4L2_MEMORY_DMABUF;
+#endif
+}
+
+V4L2CaptureDelegateSinglePlane::~V4L2CaptureDelegateSinglePlane() {
+}
+
scoped_refptr<V4L2CaptureDelegate::BufferTracker>
V4L2CaptureDelegateSinglePlane::CreateBufferTracker() const {
return make_scoped_refptr(new BufferTrackerSPlane());
@@ -25,8 +42,34 @@ bool V4L2CaptureDelegateSinglePlane::FillV4L2Format(
}
void V4L2CaptureDelegateSinglePlane::FinishFillingV4L2Buffer(
- v4l2_buffer* buffer) const {
+ v4l2_buffer* buffer,
+ bool for_enqueue) const {
+ buffer->memory = memory_type_;
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(buffer->m.fd); // For Dequeue, API should have filled |fd| in.
Pawel Osciak 2015/06/15 10:34:55 We call this before calling DQBUF, so it couldn't
mcasas 2015/06/17 01:30:53 First time this method is called, it's with |for_
+ 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 =
Pawel Osciak 2015/06/15 10:34:55 Do we need to allocate buffers on each QBUF? Could
mcasas 2015/06/17 01:30:53 We don't allocate a Buffers on each QBUF, we Rese
+ client()->ReserveOutputBuffer(media::PIXEL_FORMAT_GPUMEMORYBUFFER,
+ capture_format().frame_size);
+ if (capture_buffer && 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();
+ } else {
+ DLOG(WARNING) << "Uh oh, platform does not support Dma-Buf allocation, "
Pawel Osciak 2015/06/15 10:34:55 We should propagate errors and SetErrorState() in
mcasas 2015/06/17 01:30:53 This is a Warning, and it was meant to be to help
+ << "or has run out of buffers :-?";
+ }
+#endif
}
void V4L2CaptureDelegateSinglePlane::SetPayloadSize(
@@ -35,20 +78,58 @@ void V4L2CaptureDelegateSinglePlane::SetPayloadSize(
buffer_tracker->SetPlanePayloadSize(0, buffer.bytesused);
}
+void V4L2CaptureDelegateSinglePlane::FinishFillingV4L2RequestBuffers(
+ v4l2_requestbuffers* request) const {
+ request->memory = memory_type_;
+}
+
void V4L2CaptureDelegateSinglePlane::SendBuffer(
const scoped_refptr<BufferTracker>& buffer_tracker,
const v4l2_format& format) const {
- client()->OnIncomingCapturedData(
- buffer_tracker->GetPlaneStart(0),
+ 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());
+ 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() if found. Otherwise is an error.
+ const int incoming_fd = buffer_tracker->GetFd(0);
+ ScopedVector<VideoCaptureDevice::Client::Buffer>::iterator used_buffer =
+ std::find_if(allocated_buffers_.begin(), allocated_buffers_.end(),
+ [incoming_fd](const VideoCaptureDevice::Client::Buffer* b) {
Pawel Osciak 2015/06/15 10:34:55 const Buffer& possible?
mcasas 2015/06/17 01:30:53 ScopedVector keeps pointers, from which you can ma
+ return incoming_fd == b->AsPlatformFile();
+ });
+ if (used_buffer == allocated_buffers_.end()) {
+ DLOG(ERROR) << "Uh oh, captured |fd| is not found in the list :?";
+ return;
Pawel Osciak 2015/06/15 10:34:55 Need to propagate the error.
mcasas 2015/06/17 01:30:53 Same as before, this was meant to be for helping
+ }
+ client()->OnIncomingCapturedBuffer(make_scoped_ptr(*used_buffer),
+ capture_format(), base::TimeTicks::Now());
+ allocated_buffers_.weak_erase(used_buffer);
Pawel Osciak 2015/06/15 10:34:55 Perhaps we could use std::vector<scoped_refptr<>>
mcasas 2015/06/17 01:30:53 I wish! ReserveOutputBuffer() returns a scoped_ptr
+#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);
Pawel Osciak 2015/06/15 10:34:55 Would it be possible to have one AddPlane() method
mcasas 2015/06/17 01:30:53 Wouldn't it move this ifdef somewhere else, and fo
+ 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