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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/video/capture/linux/v4l2_capture_delegate_single_plane.h" 5 #include "media/video/capture/linux/v4l2_capture_delegate_single_plane.h"
6 6
7 #include <linux/version.h>
7 #include <sys/mman.h> 8 #include <sys/mman.h>
8 9
9 namespace media { 10 namespace media {
10 11
12 V4L2CaptureDelegateSinglePlane::V4L2CaptureDelegateSinglePlane(
13 const VideoCaptureDevice::Name& device_name,
14 const scoped_refptr<base::SingleThreadTaskRunner>& v4l2_task_runner,
15 int power_line_frequency,
16 bool allow_using_dma_bufs)
17 : V4L2CaptureDelegate(
18 device_name,
19 v4l2_task_runner,
20 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
21 allow_using_dma_bufs ? V4L2_MEMORY_DMABUF : V4L2_MEMORY_MMAP,
22 #else
23 V4L2_MEMORY_MMAP,
24 #endif
25 power_line_frequency) {
26 }
27
28 V4L2CaptureDelegateSinglePlane::~V4L2CaptureDelegateSinglePlane() {
29 }
30
11 scoped_refptr<V4L2CaptureDelegate::BufferTracker> 31 scoped_refptr<V4L2CaptureDelegate::BufferTracker>
12 V4L2CaptureDelegateSinglePlane::CreateBufferTracker() const { 32 V4L2CaptureDelegateSinglePlane::CreateBufferTracker() const {
13 return make_scoped_refptr(new BufferTrackerSPlane()); 33 return make_scoped_refptr(new BufferTrackerSPlane());
14 } 34 }
15 35
16 bool V4L2CaptureDelegateSinglePlane::FillV4L2Format( 36 bool V4L2CaptureDelegateSinglePlane::FillV4L2Format(
17 v4l2_format* format, 37 v4l2_format* format,
18 uint32_t width, 38 uint32_t width,
19 uint32_t height, 39 uint32_t height,
20 uint32_t pixelformat_fourcc) const { 40 uint32_t pixelformat_fourcc) const {
21 format->fmt.pix.width = width; 41 format->fmt.pix.width = width;
22 format->fmt.pix.height = height; 42 format->fmt.pix.height = height;
23 format->fmt.pix.pixelformat = pixelformat_fourcc; 43 format->fmt.pix.pixelformat = pixelformat_fourcc;
24 return true; 44 return true;
25 } 45 }
26 46
27 void V4L2CaptureDelegateSinglePlane::FinishFillingV4L2Buffer( 47 void V4L2CaptureDelegateSinglePlane::FinishFillingV4L2Buffer(
28 v4l2_buffer* buffer) const { 48 v4l2_buffer* buffer,
49 bool for_enqueue) const {
29 buffer->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 50 buffer->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
51
52 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
53 if (memory_type() == V4L2_MEMORY_MMAP)
54 return;
55
56 if (!for_enqueue) {
57 DCHECK_NE(buffer->m.fd, -1); // API should have filled |fd| in for dequeue.
58 return;
59 }
60 // For enqueueing, need to reserve an output buffer, keep it locally and pass
61 // its |fd| into the V4L2 API.
62 scoped_ptr<VideoCaptureDevice::Client::Buffer> capture_buffer =
63 client()->ReserveOutputBuffer(media::PIXEL_FORMAT_GPUMEMORYBUFFER,
64 capture_format().frame_size);
65 if (!capture_buffer)
66 return;
67
68 DCHECK_EQ(capture_buffer->GetType(), gfx::OZONE_NATIVE_BUFFER);
69 buffer->m.fd = capture_buffer->AsPlatformFile();
70
71 allocated_buffers_.push_back(capture_buffer.release());
72 DVLOG(1) << "Sizeof allocated_buffers_ " << allocated_buffers_.size();
73 #endif
30 } 74 }
31 75
32 void V4L2CaptureDelegateSinglePlane::SetPayloadSize( 76 void V4L2CaptureDelegateSinglePlane::SetPayloadSize(
33 const scoped_refptr<BufferTracker>& buffer_tracker, 77 const scoped_refptr<BufferTracker>& buffer_tracker,
34 const v4l2_buffer& buffer) const { 78 const v4l2_buffer& buffer) const {
35 buffer_tracker->SetPlanePayloadSize(0, buffer.bytesused); 79 buffer_tracker->SetPlanePayloadSize(0, buffer.bytesused);
36 } 80 }
37 81
38 void V4L2CaptureDelegateSinglePlane::SendBuffer( 82 void V4L2CaptureDelegateSinglePlane::SendBuffer(
39 const scoped_refptr<BufferTracker>& buffer_tracker, 83 const scoped_refptr<BufferTracker>& buffer_tracker,
40 const v4l2_format& format) const { 84 const v4l2_format& format) const {
41 client()->OnIncomingCapturedData( 85 DVLOG(1) << __FUNCTION__;
42 buffer_tracker->GetPlaneStart(0), 86
43 buffer_tracker->GetPlanePayloadSize(0), 87 if (memory_type() == V4L2_MEMORY_MMAP) {
44 capture_format(), 88 const size_t data_length = format.fmt.pix.sizeimage;
45 rotation(), 89 DCHECK_GE(data_length, capture_format().ImageAllocationSize());
46 base::TimeTicks::Now()); 90 client()->OnIncomingCapturedData(
91 buffer_tracker->GetPlaneStart(0),
92 buffer_tracker->GetPlanePayloadSize(0),
93 capture_format(),
94 rotation(),
95 base::TimeTicks::Now());
96 return;
97 }
98
99 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
100 // Search for the |fd| used for capture in |allocated_buffers_| and send it
101 // to client().
102 const int incoming_fd = buffer_tracker->GetPlaneFd(0);
103 ScopedVector<VideoCaptureDevice::Client::Buffer>::iterator used_buffer =
104 std::find_if(allocated_buffers_.begin(), allocated_buffers_.end(),
105 [incoming_fd](VideoCaptureDevice::Client::Buffer* b) {
106 return incoming_fd == b->AsPlatformFile();
107 });
108 CHECK(used_buffer != allocated_buffers_.end())
109 << "Uh oh, captured |fd| is not found in the list :?";
110 client()->OnIncomingCapturedBuffer(make_scoped_ptr(*used_buffer),
111 capture_format(), base::TimeTicks::Now());
112 allocated_buffers_.weak_erase(used_buffer);
113 #endif
47 } 114 }
48 115
49 bool V4L2CaptureDelegateSinglePlane::BufferTrackerSPlane::Init( 116 bool V4L2CaptureDelegateSinglePlane::BufferTrackerSPlane::Init(
50 int fd, 117 int fd,
51 const v4l2_buffer& buffer) { 118 const v4l2_buffer& buffer) {
119 DVLOG(1) << __FUNCTION__;
120 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
121 if (buffer.memory == V4L2_MEMORY_DMABUF) {
122 AddNonMmapedPlane(buffer.m.fd);
123 return true;
124 }
125 #endif
126
52 // Some devices require mmap() to be called with both READ and WRITE. 127 // Some devices require mmap() to be called with both READ and WRITE.
53 // See http://crbug.com/178582. 128 // See http://crbug.com/178582.
54 void* const start = mmap(NULL, buffer.length, PROT_READ | PROT_WRITE, 129 void* const start = mmap(NULL, buffer.length, PROT_READ | PROT_WRITE,
55 MAP_SHARED, fd, buffer.m.offset); 130 MAP_SHARED, fd, buffer.m.offset);
56 if (start == MAP_FAILED) { 131 if (start == MAP_FAILED) {
57 DLOG(ERROR) << "Error mmap()ing a V4L2 buffer into userspace"; 132 DLOG(ERROR) << "Error mmap()ing a V4L2 buffer into userspace";
58 return false; 133 return false;
59 } 134 }
60 AddMmapedPlane(static_cast<uint8_t*>(start), buffer.length); 135 AddMmapedPlane(static_cast<uint8_t*>(start), buffer.length);
61 return true; 136 return true;
62 } 137 }
63 138
64 } // namespace media 139 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698