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

Side by Side Diff: content/common/gpu/media/exynos_v4l2_video_device.cc

Issue 137023008: Add support for Tegra V4L2 VDA (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 8 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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
5 #include <fcntl.h> 6 #include <fcntl.h>
6 #include <linux/videodev2.h> 7 #include <linux/videodev2.h>
8 #include <libdrm/drm_fourcc.h>
sheu 2014/03/27 02:00:23 Header ordering -- this one above.
7 #include <poll.h> 9 #include <poll.h>
8 #include <sys/eventfd.h> 10 #include <sys/eventfd.h>
9 #include <sys/ioctl.h> 11 #include <sys/ioctl.h>
10 #include <sys/mman.h> 12 #include <sys/mman.h>
11 13
12 #include "base/debug/trace_event.h" 14 #include "base/debug/trace_event.h"
13 #include "base/posix/eintr_wrapper.h" 15 #include "base/posix/eintr_wrapper.h"
14 #include "content/common/gpu/media/exynos_v4l2_video_device.h" 16 #include "content/common/gpu/media/exynos_v4l2_video_device.h"
17 #include "ui/gl/gl_bindings.h"
15 18
16 namespace content { 19 namespace content {
17 20
18 namespace { 21 namespace {
19 const char kDevice[] = "/dev/mfc-dec"; 22 const char kDevice[] = "/dev/mfc-dec";
20 } 23 }
21 24
22 ExynosV4L2Device::ExynosV4L2Device() 25 ExynosV4L2Device::ExynosV4L2Device()
23 : device_fd_(-1), device_poll_interrupt_fd_(-1) {} 26 : device_fd_(-1), device_poll_interrupt_fd_(-1) {}
24 27
25 ExynosV4L2Device::~ExynosV4L2Device() { 28 ExynosV4L2Device::~ExynosV4L2Device() {
26 if (device_poll_interrupt_fd_ != -1) { 29 if (device_poll_interrupt_fd_ != -1) {
27 close(device_poll_interrupt_fd_); 30 close(device_poll_interrupt_fd_);
28 device_poll_interrupt_fd_ = -1; 31 device_poll_interrupt_fd_ = -1;
29 } 32 }
30 if (device_fd_ != -1) { 33 if (device_fd_ != -1) {
31 close(device_fd_); 34 close(device_fd_);
32 device_fd_ = -1; 35 device_fd_ = -1;
33 } 36 }
34 } 37 }
35 38
39 ExynosV4L2Device::DeviceOutputRecord::DeviceOutputRecord()
40 : egl_image(EGL_NO_IMAGE_KHR) {
41 for (size_t i = 0; i < arraysize(fds); ++i)
42 fds[i] = -1;
43 }
44
45 ExynosV4L2Device::DeviceOutputRecord::~DeviceOutputRecord() {}
46
36 int ExynosV4L2Device::Ioctl(int request, void* arg) { 47 int ExynosV4L2Device::Ioctl(int request, void* arg) {
37 return ioctl(device_fd_, request, arg); 48 return ioctl(device_fd_, request, arg);
38 } 49 }
39 50
40 bool ExynosV4L2Device::Poll(bool poll_device, bool* event_pending) { 51 bool ExynosV4L2Device::Poll(bool poll_device, bool* event_pending) {
41 struct pollfd pollfds[2]; 52 struct pollfd pollfds[2];
42 nfds_t nfds; 53 nfds_t nfds;
43 int pollfd = -1; 54 int pollfd = -1;
44 55
45 pollfds[0].fd = device_poll_interrupt_fd_; 56 pollfds[0].fd = device_poll_interrupt_fd_;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 if (device_fd_ == -1) { 118 if (device_fd_ == -1) {
108 return false; 119 return false;
109 } 120 }
110 121
111 device_poll_interrupt_fd_ = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); 122 device_poll_interrupt_fd_ = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
112 if (device_poll_interrupt_fd_ == -1) { 123 if (device_poll_interrupt_fd_ == -1) {
113 return false; 124 return false;
114 } 125 }
115 return true; 126 return true;
116 } 127 }
128
129 EGLImageKHR ExynosV4L2Device::CreateEGLImage(EGLDisplay egl_display,
130 GLuint texture_id,
131 gfx::Size frame_buffer_size,
132 unsigned int buffer_index,
133 unsigned int total_buffers) {
134 DVLOG(3) << "CreateEGLImage() ";
135 // Initialize the map if it is empty.
136 if (device_output_buffer_map_.empty())
137 device_output_buffer_map_.resize(total_buffers);
138
139 // First get the export buffer
140 DeviceOutputRecord& output_record = device_output_buffer_map_[buffer_index];
141
142 for (size_t i = 0; i < arraysize(output_record.fds); ++i) {
143 // Export the DMABUF fd so we can export it as a texture.
144 struct v4l2_exportbuffer expbuf;
145 memset(&expbuf, 0, sizeof(expbuf));
146 expbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
147 expbuf.index = buffer_index;
148 expbuf.plane = i;
149 expbuf.flags = O_CLOEXEC;
150 if (HANDLE_EINTR(Ioctl(VIDIOC_EXPBUF, &expbuf) != 0)) {
151 return EGL_NO_IMAGE_KHR;
152 }
153 output_record.fds[i] = expbuf.fd;
154 }
155
156 EGLint attrs[] = {
157 EGL_WIDTH, 0, EGL_HEIGHT, 0,
158 EGL_LINUX_DRM_FOURCC_EXT, 0, EGL_DMA_BUF_PLANE0_FD_EXT, 0,
159 EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, EGL_DMA_BUF_PLANE0_PITCH_EXT, 0,
160 EGL_DMA_BUF_PLANE1_FD_EXT, 0, EGL_DMA_BUF_PLANE1_OFFSET_EXT, 0,
161 EGL_DMA_BUF_PLANE1_PITCH_EXT, 0, EGL_NONE, };
162
163 attrs[1] = frame_buffer_size.width();
164 attrs[3] = frame_buffer_size.height();
165 attrs[5] = DRM_FORMAT_NV12;
166 attrs[7] = output_record.fds[0];
167 attrs[9] = 0;
168 attrs[11] = frame_buffer_size.width();
169 attrs[13] = output_record.fds[1];
170 attrs[15] = 0;
171 attrs[17] = frame_buffer_size.width();
172
173 EGLImageKHR egl_image = eglCreateImageKHR(
174 egl_display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attrs);
175 if (egl_image == EGL_NO_IMAGE_KHR) {
176 return egl_image;
177 }
178 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id);
179 glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, egl_image);
180 return egl_image;
181 }
182
183 void ExynosV4L2Device::DestroyEGLImage(unsigned int buffer_index) {
184 DeviceOutputRecord& output_record = device_output_buffer_map_[buffer_index];
185 for (size_t j = 0; j < arraysize(output_record.fds); ++j) {
186 if (output_record.fds[j] != -1) {
187 if (close(output_record.fds[j])) {
188 DVPLOG(1) << __func__ << " close() on a dmabuf fd failed.";
189 }
190 }
191 }
192 // Clear the map if this is the last buffer.
193 if (buffer_index == device_output_buffer_map_.size() - 1)
194 device_output_buffer_map_.clear();
sheu 2014/03/27 02:00:23 This is really brittle.
shivdasp 2014/03/27 02:41:04 Seems this is not needed now after reading your pr
195 }
196
197 GLenum ExynosV4L2Device::GetTextureTarget() { return GL_TEXTURE_EXTERNAL_OES; }
198
199 uint32 ExynosV4L2Device::GetCapturePixelFormat() { return V4L2_PIX_FMT_NV12M; }
200
201 uint8 ExynosV4L2Device::GetNumberOfPlanes() { return 2; }
202
117 } // namespace content 203 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698