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()) { |
kcwu
2016/03/22 07:47:01
I don't understand the code what if 1 < dmabuf_fds
Pawel Osciak
2016/03/28 01:31:28
num_planes is logical planes, while dmabuf_fds.siz
|
// 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; |
} else { |
- plane_offset += media::VideoFrame::PlaneSize( |
- vf_format, plane, frame_buffer_size).GetArea(); |
+ plane_offset += |
+ media::VideoFrame::PlaneSize(vf_format, plane, size).GetArea(); |
} |
} |