Chromium Code Reviews| 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(); |
| } |
| } |