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

Unified 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, 9 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: content/common/gpu/media/generic_v4l2_device.cc
diff --git a/content/common/gpu/media/generic_v4l2_device.cc b/content/common/gpu/media/generic_v4l2_device.cc
index 5a6885d98478e21b6e2d3e9758bcdf4dd3ac5b39..4df2ea6366064de58ed78eca4ce3b877f42fe6df 100644
--- a/content/common/gpu/media/generic_v4l2_device.cc
+++ b/content/common/gpu/media/generic_v4l2_device.cc
@@ -176,6 +176,31 @@ bool GenericV4L2Device::Initialize() {
return true;
}
+std::vector<base::ScopedFD> GenericV4L2Device::GetDmabufsForV4L2Buffer(
+ int index,
+ size_t num_planes,
+ enum v4l2_buf_type type) {
+ DCHECK(V4L2_TYPE_IS_MULTIPLANAR(type));
+
+ std::vector<base::ScopedFD> dmabuf_fds;
+ for (size_t i = 0; i < num_planes; ++i) {
+ struct v4l2_exportbuffer expbuf;
+ memset(&expbuf, 0, sizeof(expbuf));
+ expbuf.type = type;
+ expbuf.index = index;
+ expbuf.plane = i;
+ expbuf.flags = O_CLOEXEC;
+ if (Ioctl(VIDIOC_EXPBUF, &expbuf) != 0) {
+ dmabuf_fds.clear();
+ break;
+ }
+
+ dmabuf_fds.push_back(base::ScopedFD(expbuf.fd));
+ }
+
+ return dmabuf_fds;
+}
+
bool GenericV4L2Device::CanCreateEGLImageFrom(uint32_t v4l2_pixfmt) {
static uint32_t kEGLImageDrmFmtsSupported[] = {
DRM_FORMAT_ARGB8888,
@@ -192,13 +217,14 @@ bool GenericV4L2Device::CanCreateEGLImageFrom(uint32_t v4l2_pixfmt) {
kEGLImageDrmFmtsSupported + arraysize(kEGLImageDrmFmtsSupported);
}
-EGLImageKHR GenericV4L2Device::CreateEGLImage(EGLDisplay egl_display,
- EGLContext /* egl_context */,
- GLuint texture_id,
- gfx::Size frame_buffer_size,
- unsigned int buffer_index,
- uint32_t v4l2_pixfmt,
- size_t num_v4l2_planes) {
+EGLImageKHR GenericV4L2Device::CreateEGLImage(
+ EGLDisplay egl_display,
+ EGLContext /* egl_context */,
+ GLuint texture_id,
+ const gfx::Size& size,
+ unsigned int buffer_index,
+ uint32_t v4l2_pixfmt,
+ const std::vector<base::ScopedFD>& dmabuf_fds) {
DVLOG(3) << "CreateEGLImage()";
if (!CanCreateEGLImageFrom(v4l2_pixfmt)) {
LOG(ERROR) << "Unsupported V4L2 pixel format";
@@ -210,33 +236,18 @@ EGLImageKHR GenericV4L2Device::CreateEGLImage(EGLDisplay egl_display,
// just a buffer count.
size_t num_planes = media::VideoFrame::NumPlanes(vf_format);
DCHECK_LE(num_planes, 3u);
- if (num_planes < num_v4l2_planes) {
+ if (num_planes < dmabuf_fds.size()) {
// It's possible for more than one DRM plane to reside in one V4L2 plane,
// but not the other way around. We must use all V4L2 planes.
LOG(ERROR) << "Invalid plane count";
return EGL_NO_IMAGE_KHR;
}
- scoped_ptr<base::ScopedFD[]> dmabuf_fds(new base::ScopedFD[num_v4l2_planes]);
- // Export dmabuf fds so we can create an EGLImage from them.
- for (size_t i = 0; i < num_v4l2_planes; ++i) {
- struct v4l2_exportbuffer expbuf;
- memset(&expbuf, 0, sizeof(expbuf));
- expbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- expbuf.index = buffer_index;
- expbuf.plane = i;
- expbuf.flags = O_CLOEXEC;
- if (Ioctl(VIDIOC_EXPBUF, &expbuf) != 0) {
- return EGL_NO_IMAGE_KHR;
- }
- dmabuf_fds[i].reset(expbuf.fd);
- }
-
std::vector<EGLint> attrs;
attrs.push_back(EGL_WIDTH);
- attrs.push_back(frame_buffer_size.width());
+ attrs.push_back(size.width());
attrs.push_back(EGL_HEIGHT);
- attrs.push_back(frame_buffer_size.height());
+ attrs.push_back(size.height());
attrs.push_back(EGL_LINUX_DRM_FOURCC_EXT);
attrs.push_back(V4L2PixFmtToDrmFormat(v4l2_pixfmt));
@@ -254,14 +265,14 @@ EGLImageKHR GenericV4L2Device::CreateEGLImage(EGLDisplay egl_display,
attrs.push_back(EGL_DMA_BUF_PLANE0_OFFSET_EXT + plane * 3);
attrs.push_back(plane_offset);
attrs.push_back(EGL_DMA_BUF_PLANE0_PITCH_EXT + plane * 3);
- attrs.push_back(media::VideoFrame::RowBytes(plane, vf_format,
- frame_buffer_size.width()));
+ attrs.push_back(
+ media::VideoFrame::RowBytes(plane, vf_format, size.width()));
- if (v4l2_plane + 1 < num_v4l2_planes) {
+ if (v4l2_plane + 1 < dmabuf_fds.size()) {
++v4l2_plane;
kcwu 2016/03/28 02:28:36 reset plane_offset to 0 here?
Pawel Osciak 2016/03/31 05:42:33 Good catch, thanks. Done.
} else {
- plane_offset += media::VideoFrame::PlaneSize(
- vf_format, plane, frame_buffer_size).GetArea();
+ plane_offset +=
+ media::VideoFrame::PlaneSize(vf_format, plane, size).GetArea();
}
}
« 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