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

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

Issue 1822983002: Support external buffer import in VDA interface and add a V4L2SVDA impl. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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
6 #include <errno.h> 6 #include <errno.h>
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <libdrm/drm_fourcc.h> 8 #include <libdrm/drm_fourcc.h>
9 #include <linux/videodev2.h> 9 #include <linux/videodev2.h>
10 #include <poll.h> 10 #include <poll.h>
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 #endif 210 #endif
211 }; 211 };
212 212
213 return std::find( 213 return std::find(
214 kEGLImageDrmFmtsSupported, 214 kEGLImageDrmFmtsSupported,
215 kEGLImageDrmFmtsSupported + arraysize(kEGLImageDrmFmtsSupported), 215 kEGLImageDrmFmtsSupported + arraysize(kEGLImageDrmFmtsSupported),
216 V4L2PixFmtToDrmFormat(v4l2_pixfmt)) != 216 V4L2PixFmtToDrmFormat(v4l2_pixfmt)) !=
217 kEGLImageDrmFmtsSupported + arraysize(kEGLImageDrmFmtsSupported); 217 kEGLImageDrmFmtsSupported + arraysize(kEGLImageDrmFmtsSupported);
218 } 218 }
219 219
220 EGLImageKHR GenericV4L2Device::CreateEGLImage(EGLDisplay egl_display, 220 EGLImageKHR GenericV4L2Device::CreateEGLImage(
221 EGLContext /* egl_context */, 221 EGLDisplay egl_display,
222 GLuint texture_id, 222 EGLContext /* egl_context */,
223 gfx::Size frame_buffer_size, 223 GLuint texture_id,
224 unsigned int buffer_index, 224 const gfx::Size& size,
225 uint32_t v4l2_pixfmt, 225 unsigned int buffer_index,
226 size_t num_v4l2_planes) { 226 uint32_t v4l2_pixfmt,
227 const std::vector<base::ScopedFD>& dmabuf_fds) {
227 DVLOG(3) << "CreateEGLImage()"; 228 DVLOG(3) << "CreateEGLImage()";
228 if (!CanCreateEGLImageFrom(v4l2_pixfmt)) { 229 if (!CanCreateEGLImageFrom(v4l2_pixfmt)) {
229 LOG(ERROR) << "Unsupported V4L2 pixel format"; 230 LOG(ERROR) << "Unsupported V4L2 pixel format";
230 return EGL_NO_IMAGE_KHR; 231 return EGL_NO_IMAGE_KHR;
231 } 232 }
232 233
233 media::VideoPixelFormat vf_format = V4L2PixFmtToVideoPixelFormat(v4l2_pixfmt); 234 media::VideoPixelFormat vf_format = V4L2PixFmtToVideoPixelFormat(v4l2_pixfmt);
234 // Number of components, as opposed to the number of V4L2 planes, which is 235 // Number of components, as opposed to the number of V4L2 planes, which is
235 // just a buffer count. 236 // just a buffer count.
236 size_t num_planes = media::VideoFrame::NumPlanes(vf_format); 237 size_t num_planes = media::VideoFrame::NumPlanes(vf_format);
237 DCHECK_LE(num_planes, 3u); 238 DCHECK_LE(num_planes, 3u);
238 if (num_planes < num_v4l2_planes) { 239 if (num_planes < dmabuf_fds.size()) {
239 // It's possible for more than one DRM plane to reside in one V4L2 plane, 240 // It's possible for more than one DRM plane to reside in one V4L2 plane,
240 // but not the other way around. We must use all V4L2 planes. 241 // but not the other way around. We must use all V4L2 planes.
241 LOG(ERROR) << "Invalid plane count"; 242 LOG(ERROR) << "Invalid plane count";
242 return EGL_NO_IMAGE_KHR; 243 return EGL_NO_IMAGE_KHR;
243 } 244 }
244 245
245 std::unique_ptr<base::ScopedFD[]> dmabuf_fds(
246 new base::ScopedFD[num_v4l2_planes]);
247 // Export dmabuf fds so we can create an EGLImage from them.
248 for (size_t i = 0; i < num_v4l2_planes; ++i) {
249 struct v4l2_exportbuffer expbuf;
250 memset(&expbuf, 0, sizeof(expbuf));
251 expbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
252 expbuf.index = buffer_index;
253 expbuf.plane = i;
254 expbuf.flags = O_CLOEXEC;
255 if (Ioctl(VIDIOC_EXPBUF, &expbuf) != 0) {
256 return EGL_NO_IMAGE_KHR;
257 }
258 dmabuf_fds[i].reset(expbuf.fd);
259 }
260
261 std::vector<EGLint> attrs; 246 std::vector<EGLint> attrs;
262 attrs.push_back(EGL_WIDTH); 247 attrs.push_back(EGL_WIDTH);
263 attrs.push_back(frame_buffer_size.width()); 248 attrs.push_back(size.width());
264 attrs.push_back(EGL_HEIGHT); 249 attrs.push_back(EGL_HEIGHT);
265 attrs.push_back(frame_buffer_size.height()); 250 attrs.push_back(size.height());
266 attrs.push_back(EGL_LINUX_DRM_FOURCC_EXT); 251 attrs.push_back(EGL_LINUX_DRM_FOURCC_EXT);
267 attrs.push_back(V4L2PixFmtToDrmFormat(v4l2_pixfmt)); 252 attrs.push_back(V4L2PixFmtToDrmFormat(v4l2_pixfmt));
268 253
269 // For existing formats, if we have less buffers (V4L2 planes) than 254 // For existing formats, if we have less buffers (V4L2 planes) than
270 // components (planes), the remaining planes are stored in the last 255 // components (planes), the remaining planes are stored in the last
271 // V4L2 plane. Use one V4L2 plane per each component until we run out of V4L2 256 // V4L2 plane. Use one V4L2 plane per each component until we run out of V4L2
272 // planes, and use the last V4L2 plane for all remaining components, each 257 // planes, and use the last V4L2 plane for all remaining components, each
273 // with an offset equal to the size of the preceding planes in the same 258 // with an offset equal to the size of the preceding planes in the same
274 // V4L2 plane. 259 // V4L2 plane.
275 size_t v4l2_plane = 0; 260 size_t v4l2_plane = 0;
276 size_t plane_offset = 0; 261 size_t plane_offset = 0;
277 for (size_t plane = 0; plane < num_planes; ++plane) { 262 for (size_t plane = 0; plane < num_planes; ++plane) {
278 attrs.push_back(EGL_DMA_BUF_PLANE0_FD_EXT + plane * 3); 263 attrs.push_back(EGL_DMA_BUF_PLANE0_FD_EXT + plane * 3);
279 attrs.push_back(dmabuf_fds[v4l2_plane].get()); 264 attrs.push_back(dmabuf_fds[v4l2_plane].get());
280 attrs.push_back(EGL_DMA_BUF_PLANE0_OFFSET_EXT + plane * 3); 265 attrs.push_back(EGL_DMA_BUF_PLANE0_OFFSET_EXT + plane * 3);
281 attrs.push_back(plane_offset); 266 attrs.push_back(plane_offset);
282 attrs.push_back(EGL_DMA_BUF_PLANE0_PITCH_EXT + plane * 3); 267 attrs.push_back(EGL_DMA_BUF_PLANE0_PITCH_EXT + plane * 3);
283 attrs.push_back(media::VideoFrame::RowBytes(plane, vf_format, 268 attrs.push_back(
284 frame_buffer_size.width())); 269 media::VideoFrame::RowBytes(plane, vf_format, size.width()));
285 270
286 if (v4l2_plane + 1 < num_v4l2_planes) { 271 if (v4l2_plane + 1 < dmabuf_fds.size()) {
287 ++v4l2_plane; 272 ++v4l2_plane;
273 plane_offset = 0;
288 } else { 274 } else {
289 plane_offset += media::VideoFrame::PlaneSize( 275 plane_offset +=
290 vf_format, plane, frame_buffer_size).GetArea(); 276 media::VideoFrame::PlaneSize(vf_format, plane, size).GetArea();
291 } 277 }
292 } 278 }
293 279
294 attrs.push_back(EGL_NONE); 280 attrs.push_back(EGL_NONE);
295 281
296 EGLImageKHR egl_image = eglCreateImageKHR( 282 EGLImageKHR egl_image = eglCreateImageKHR(
297 egl_display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, &attrs[0]); 283 egl_display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, &attrs[0]);
298 if (egl_image == EGL_NO_IMAGE_KHR) { 284 if (egl_image == EGL_NO_IMAGE_KHR) {
299 LOG(ERROR) << "Failed creating EGL image: " << ui::GetLastEGLErrorString(); 285 LOG(ERROR) << "Failed creating EGL image: " << ui::GetLastEGLErrorString();
300 return egl_image; 286 return egl_image;
(...skipping 24 matching lines...) Expand all
325 StubPathMap paths; 311 StubPathMap paths;
326 paths[kModuleV4l2].push_back(kV4l2Lib); 312 paths[kModuleV4l2].push_back(kV4l2Lib);
327 313
328 return InitializeStubs(paths); 314 return InitializeStubs(paths);
329 #else 315 #else
330 return true; 316 return true;
331 #endif 317 #endif
332 } 318 }
333 319
334 } // namespace content 320 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/generic_v4l2_device.h ('k') | content/common/gpu/media/gpu_video_decode_accelerator_factory_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698