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

Unified Diff: content/common/gpu/media/tegra_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, 10 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/tegra_v4l2_video_device.cc
diff --git a/content/common/gpu/media/tegra_v4l2_video_device.cc b/content/common/gpu/media/tegra_v4l2_video_device.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b7b7cddd14b0749d0719eeab03b1655814c0eeac
--- /dev/null
+++ b/content/common/gpu/media/tegra_v4l2_video_device.cc
@@ -0,0 +1,172 @@
+#include <dlfcn.h>
Ami GONE FROM CHROMIUM 2014/02/07 09:09:30 missing copyright header
+#include <errno.h>
+#include <fcntl.h>
+#include <libdrm/drm_fourcc.h>
Pawel Osciak 2014/02/10 06:36:17 Not needed?
+#include <linux/videodev2.h>
+#include <poll.h>
Pawel Osciak 2014/02/10 06:36:17 Not needed.
+#include <sys/eventfd.h>
Pawel Osciak 2014/02/10 06:36:17 Not needed.
+#include <sys/ioctl.h>
+#include <sys/mman.h>
Pawel Osciak 2014/02/10 06:36:17 Not needed? Please clean up the headers in this f
+
+#include "base/bind.h"
+#include "base/debug/trace_event.h"
+#include "base/memory/shared_memory.h"
+#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/posix/eintr_wrapper.h"
+#include "content/common/gpu/media/tegra_v4l2_video_device.h"
+#include "ui/gl/gl_bindings.h"
+
+namespace content {
+
+namespace {
+const char kDevice[] = "/dev/video0";
Pawel Osciak 2014/02/10 06:36:17 Is this is the codec device exposed by Tegra kerne
shivdasp 2014/02/10 13:31:17 This is a v4l2 decoder device name which we use to
Pawel Osciak 2014/02/12 09:15:13 Which device is actually being used? Does the libr
shivdasp 2014/02/12 10:11:55 This library internally talks to MM layer which ta
Pawel Osciak 2014/02/13 10:42:54 This means you will have to add it to sandbox rule
shivdasp 2014/02/14 03:06:45 Yes /dev/tegra_avpchannel will be added in the san
Pawel Osciak 2014/02/14 07:36:10 Why it may not be required? How else would it be a
shivdasp 2014/02/14 09:18:58 Whitelisted will not be required because of pre-ac
+}
+
+TegraV4L2Device::TegraV4L2Device(EGLContext egl_context)
+ : device_fd_(-1), egl_context_(egl_context) {}
+
+TegraV4L2Device::~TegraV4L2Device() {
+ if (device_fd_ != -1) {
+ TegraV4L2Close(device_fd_);
+ device_fd_ = -1;
+ }
+}
+
+int TegraV4L2Device::Ioctl(int flags, void* arg) {
+ return TegraV4L2Ioctl(device_fd_, flags, arg);
+}
+
+bool TegraV4L2Device::Poll(bool poll_device, bool* event_pending) {
+ if (TegraV4L2Poll(device_fd_, poll_device, event_pending) == -1) {
+ DLOG(ERROR) << "TegraV4L2Poll returned -1 ";
+ return false;
+ }
+ return true;
+}
+
+void* TegraV4L2Device::Mmap(void* addr,
+ unsigned int len,
+ int prot,
+ int flags,
+ unsigned int offset) {
+ // No real mmap for tegrav4l2 device, the offset is itself the address.
+ return (void*)offset;
Pawel Osciak 2014/02/10 06:36:17 QUERYBUFS from V4L2VDA is used to acquire offsets
shivdasp 2014/02/10 13:31:17 When REQBUFS is called for OUTPUT_PLANE, the libra
Pawel Osciak 2014/02/12 09:15:13 The library must be using some kind of an mmap cal
shivdasp 2014/02/12 10:11:55 Okay I will add Mmap and Munmap calls to the libra
Pawel Osciak 2014/02/13 10:42:54 Great. Thank you!
+}
+
+void TegraV4L2Device::Munmap(void* addr, unsigned int len) {
+ // No real munmap for tegrav4l2 device.
Pawel Osciak 2014/02/10 06:36:17 If so, how is unmapping handled then? What if we w
shivdasp 2014/02/10 13:31:17 Buffers are unmapped in REQBUFS(0) call and destro
Pawel Osciak 2014/02/12 09:15:13 We should not rely on V4L2VDA to be the only place
shivdasp 2014/02/12 10:11:55 If not in REQBUFS(0) then what will be the appropr
Pawel Osciak 2014/02/13 10:42:54 Sorry, perhaps I wasn't clear, the term "buffers"
shivdasp 2014/02/14 03:06:45 Understood. I believe the dmabuf export mechanism
Pawel Osciak 2014/02/14 07:36:10 Yes, although it's not "synchronized", but the own
shivdasp 2014/02/14 09:18:58 I checked with the graphics team here. This is han
+ return;
+}
+
+bool TegraV4L2Device::SetDevicePollInterrupt(void) {
Ami GONE FROM CHROMIUM 2014/02/07 09:09:30 drop "void"
+ if (HANDLE_EINTR(TegraV4L2SetDevicePollInterrupt(device_fd_) == -1)) {
Ami GONE FROM CHROMIUM 2014/02/07 09:09:30 bug: HANDLE_EINTR should not be accepting the ==-1
+ DLOG(ERROR) << "Error in calling TegraV4L2SetDevicePollInterrupt";
+ return false;
+ }
+ return true;
+}
+
+bool TegraV4L2Device::ClearDevicePollInterrupt(void) {
+ if (HANDLE_EINTR(TegraV4L2ClearDevicePollInterrupt(device_fd_) == -1)) {
+ DLOG(ERROR) << "Error in calling TegraV4L2ClearDevicePollInterrupt";
+ return false;
+ }
+ return true;
+}
+
+bool TegraV4L2Device::Initialize(void) {
Ami GONE FROM CHROMIUM 2014/02/07 09:09:30 drop "void"
+ TegraV4L2Open = reinterpret_cast<TegraV4L2OpenFunc>(
Ami GONE FROM CHROMIUM 2014/02/07 09:09:30 Please avoid the sort of code duplication below (s
shivdasp 2014/02/10 13:31:17 Yes I will do this. That looks very clean. On 2014
+ dlsym(RTLD_DEFAULT, "tegra_v4l2_open"));
+ if (TegraV4L2Open == NULL) {
+ DLOG(ERROR) << "Unable to get Tegra_v4l2_open handle ";
+ return false;
+ }
+
+ TegraV4L2Ioctl = reinterpret_cast<TegraV4L2IoctlFunc>(
+ dlsym(RTLD_DEFAULT, "tegra_v4l2_ioctl"));
+ if (TegraV4L2Ioctl == NULL) {
+ DLOG(ERROR) << "Unable to get tegra_v4l2_ioctl handle ";
+ return false;
+ }
+
+ TegraV4L2Close = reinterpret_cast<TegraV4L2CloseFunc>(
+ dlsym(RTLD_DEFAULT, "tegra_v4l2_close"));
+ if (TegraV4L2Close == NULL) {
+ DLOG(ERROR) << "Unable to get tegra_v4l2_close handle ";
+ return false;
+ }
+
+ TegraV4L2Poll = reinterpret_cast<TegraV4L2PollFunc>(
+ dlsym(RTLD_DEFAULT, "tegra_v4l2_poll"));
+ if (TegraV4L2Poll == NULL) {
+ DLOG(ERROR) << "Unable to get tegra_v4l2_poll handle ";
+ return false;
+ }
+
+ TegraV4L2SetDevicePollInterrupt =
+ reinterpret_cast<TegraV4L2SetDevicePollInterruptFunc>(
+ dlsym(RTLD_DEFAULT, "tegra_v4l2_set_device_poll_interrupt"));
+ if (TegraV4L2SetDevicePollInterrupt == NULL) {
+ DLOG(ERROR) << "Unable to get tegra_v4l2_set_device_poll_interrupt handle";
+ return false;
+ }
+
+ TegraV4L2ClearDevicePollInterrupt =
+ reinterpret_cast<TegraV4L2ClearDevicePollInterruptFunc>(
+ dlsym(RTLD_DEFAULT, "tegra_v4l2_clear_device_poll_interrupt"));
+ if (TegraV4L2ClearDevicePollInterrupt == NULL) {
+ DLOG(ERROR)
+ << "Unable to get tegra_v4l2_clear_device_poll_interrupt handle ";
+ return false;
+ }
+
+ device_fd_ =
+ HANDLE_EINTR(TegraV4L2Open(kDevice, O_RDWR | O_NONBLOCK | O_CLOEXEC));
+ if (device_fd_ == -1) {
+ DLOG(ERROR) << "Unable to open tegra_v4l2_open ";
+ return false;
+ }
+ return true;
+}
+
+EGLImageKHR TegraV4L2Device::CreateEGLImage(EGLDisplay egl_display,
+ EGLint attrib[],
Ami GONE FROM CHROMIUM 2014/02/07 09:09:30 EGLint[] /* attrib */
+ unsigned int texture_id,
+ unsigned int buffer_index) {
Pawel Osciak 2014/02/10 06:36:17 This method should take a v4l2_buffer instead. De
shivdasp 2014/02/10 13:31:17 Since ExynosV4L2Device does not need the v4l2_buff
+ // Ignore the attributes sent to us since Tegra does not need those.
+ EGLint attr = EGL_NONE;
+ EGLImageKHR egl_image = eglCreateImageKHR(egl_display,
+ egl_context_,
+ EGL_GL_TEXTURE_2D_KHR,
+ (EGLClientBuffer)(texture_id),
Ami GONE FROM CHROMIUM 2014/02/07 09:09:30 static_cast
+ &attr);
+ if (egl_image == EGL_NO_IMAGE_KHR) {
+ DLOG(ERROR) << "CreateEGLImage(): could not create EGLImageKHR";
+ return egl_image;
+ }
+
+ struct v4l2_plane planes[2];
+ struct v4l2_buffer capture_buffer;
+
+ memset(&capture_buffer, 0, sizeof(capture_buffer));
+ memset(planes, 0, sizeof(planes));
Ami GONE FROM CHROMIUM 2014/02/07 09:09:30 swap w/ previous line to match declaration order
+ capture_buffer.index = buffer_index;
+ capture_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ capture_buffer.memory = V4L2_MEMORY_MMAP;
+ capture_buffer.m.planes = planes;
+ capture_buffer.length = 2;
Pawel Osciak 2014/02/10 06:36:17 arraysize(planes)
+ // We send the EGLImage handle in mem_offset for the library to perform
+ // conversion internally
+
+ planes[0].m.mem_offset = reinterpret_cast<unsigned int>(egl_image);
Ami GONE FROM CHROMIUM 2014/02/07 09:09:30 how wide is mem_offset? I'm worried about this ca
Pawel Osciak 2014/02/10 06:36:17 mem_offset is u32 always, an unsigned int shouldn'
shivdasp 2014/02/10 13:31:17 We are really passing in the EglImage handle here
Pawel Osciak 2014/02/12 09:15:13 EGLImageKHR is typedef void*, which can be 64 bit.
shivdasp 2014/02/12 10:11:55 The output is YUV420 planar. I think rather than u
Pawel Osciak 2014/02/13 10:42:54 Are all planes non-interleaved and contiguous in m
shivdasp 2014/02/14 03:06:45 Okay I will change the pixel format. However there
Pawel Osciak 2014/02/14 07:36:10 As I said, those checks and should be fixed to use
shivdasp 2014/02/14 09:18:58 Okay will use the V4L2 API.
+ if (HANDLE_EINTR(Ioctl(VIDIOC_QUERYBUF, &capture_buffer)) != 0) {
+ DLOG(ERROR) << "Some error in querybuf";
+ return EGL_NO_IMAGE_KHR;
Ami GONE FROM CHROMIUM 2014/02/07 09:09:30 leak? (no eglDestroyImageKHR needed?)
shivdasp 2014/02/10 13:31:17 Yes will fix this. On 2014/02/07 09:09:30, Ami Fis
+ }
+ return egl_image;
+}
Pawel Osciak 2014/02/10 06:36:17 After reading through it, this method feels unnece
shivdasp 2014/02/10 13:31:17 Since we started with implementing this as a V4L2-
Pawel Osciak 2014/02/12 09:15:13 Please understand that: 1. We are asking for a V4L
shivdasp 2014/02/12 10:11:55 There is no extension to create EglImages from dma
Pawel Osciak 2014/02/13 10:42:54 Could you explain why is it not affected? VEA call
shivdasp 2014/02/14 03:06:45 The fd returned by TegraV4L2Open() knows whether i
+
+unsigned int TegraV4L2Device::GetTextureTarget() { return GL_TEXTURE_2D; }
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698