OLD | NEW |
---|---|
(Empty) | |
1 #include <dlfcn.h> | |
Ami GONE FROM CHROMIUM
2014/02/07 09:09:30
missing copyright header
| |
2 #include <errno.h> | |
3 #include <fcntl.h> | |
4 #include <libdrm/drm_fourcc.h> | |
Pawel Osciak
2014/02/10 06:36:17
Not needed?
| |
5 #include <linux/videodev2.h> | |
6 #include <poll.h> | |
Pawel Osciak
2014/02/10 06:36:17
Not needed.
| |
7 #include <sys/eventfd.h> | |
Pawel Osciak
2014/02/10 06:36:17
Not needed.
| |
8 #include <sys/ioctl.h> | |
9 #include <sys/mman.h> | |
Pawel Osciak
2014/02/10 06:36:17
Not needed?
Please clean up the headers in this f
| |
10 | |
11 #include "base/bind.h" | |
12 #include "base/debug/trace_event.h" | |
13 #include "base/memory/shared_memory.h" | |
14 #include "base/message_loop/message_loop.h" | |
15 #include "base/message_loop/message_loop_proxy.h" | |
16 #include "base/posix/eintr_wrapper.h" | |
17 #include "content/common/gpu/media/tegra_v4l2_video_device.h" | |
18 #include "ui/gl/gl_bindings.h" | |
19 | |
20 namespace content { | |
21 | |
22 namespace { | |
23 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
| |
24 } | |
25 | |
26 TegraV4L2Device::TegraV4L2Device(EGLContext egl_context) | |
27 : device_fd_(-1), egl_context_(egl_context) {} | |
28 | |
29 TegraV4L2Device::~TegraV4L2Device() { | |
30 if (device_fd_ != -1) { | |
31 TegraV4L2Close(device_fd_); | |
32 device_fd_ = -1; | |
33 } | |
34 } | |
35 | |
36 int TegraV4L2Device::Ioctl(int flags, void* arg) { | |
37 return TegraV4L2Ioctl(device_fd_, flags, arg); | |
38 } | |
39 | |
40 bool TegraV4L2Device::Poll(bool poll_device, bool* event_pending) { | |
41 if (TegraV4L2Poll(device_fd_, poll_device, event_pending) == -1) { | |
42 DLOG(ERROR) << "TegraV4L2Poll returned -1 "; | |
43 return false; | |
44 } | |
45 return true; | |
46 } | |
47 | |
48 void* TegraV4L2Device::Mmap(void* addr, | |
49 unsigned int len, | |
50 int prot, | |
51 int flags, | |
52 unsigned int offset) { | |
53 // No real mmap for tegrav4l2 device, the offset is itself the address. | |
54 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!
| |
55 } | |
56 | |
57 void TegraV4L2Device::Munmap(void* addr, unsigned int len) { | |
58 // 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
| |
59 return; | |
60 } | |
61 | |
62 bool TegraV4L2Device::SetDevicePollInterrupt(void) { | |
Ami GONE FROM CHROMIUM
2014/02/07 09:09:30
drop "void"
| |
63 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
| |
64 DLOG(ERROR) << "Error in calling TegraV4L2SetDevicePollInterrupt"; | |
65 return false; | |
66 } | |
67 return true; | |
68 } | |
69 | |
70 bool TegraV4L2Device::ClearDevicePollInterrupt(void) { | |
71 if (HANDLE_EINTR(TegraV4L2ClearDevicePollInterrupt(device_fd_) == -1)) { | |
72 DLOG(ERROR) << "Error in calling TegraV4L2ClearDevicePollInterrupt"; | |
73 return false; | |
74 } | |
75 return true; | |
76 } | |
77 | |
78 bool TegraV4L2Device::Initialize(void) { | |
Ami GONE FROM CHROMIUM
2014/02/07 09:09:30
drop "void"
| |
79 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
| |
80 dlsym(RTLD_DEFAULT, "tegra_v4l2_open")); | |
81 if (TegraV4L2Open == NULL) { | |
82 DLOG(ERROR) << "Unable to get Tegra_v4l2_open handle "; | |
83 return false; | |
84 } | |
85 | |
86 TegraV4L2Ioctl = reinterpret_cast<TegraV4L2IoctlFunc>( | |
87 dlsym(RTLD_DEFAULT, "tegra_v4l2_ioctl")); | |
88 if (TegraV4L2Ioctl == NULL) { | |
89 DLOG(ERROR) << "Unable to get tegra_v4l2_ioctl handle "; | |
90 return false; | |
91 } | |
92 | |
93 TegraV4L2Close = reinterpret_cast<TegraV4L2CloseFunc>( | |
94 dlsym(RTLD_DEFAULT, "tegra_v4l2_close")); | |
95 if (TegraV4L2Close == NULL) { | |
96 DLOG(ERROR) << "Unable to get tegra_v4l2_close handle "; | |
97 return false; | |
98 } | |
99 | |
100 TegraV4L2Poll = reinterpret_cast<TegraV4L2PollFunc>( | |
101 dlsym(RTLD_DEFAULT, "tegra_v4l2_poll")); | |
102 if (TegraV4L2Poll == NULL) { | |
103 DLOG(ERROR) << "Unable to get tegra_v4l2_poll handle "; | |
104 return false; | |
105 } | |
106 | |
107 TegraV4L2SetDevicePollInterrupt = | |
108 reinterpret_cast<TegraV4L2SetDevicePollInterruptFunc>( | |
109 dlsym(RTLD_DEFAULT, "tegra_v4l2_set_device_poll_interrupt")); | |
110 if (TegraV4L2SetDevicePollInterrupt == NULL) { | |
111 DLOG(ERROR) << "Unable to get tegra_v4l2_set_device_poll_interrupt handle"; | |
112 return false; | |
113 } | |
114 | |
115 TegraV4L2ClearDevicePollInterrupt = | |
116 reinterpret_cast<TegraV4L2ClearDevicePollInterruptFunc>( | |
117 dlsym(RTLD_DEFAULT, "tegra_v4l2_clear_device_poll_interrupt")); | |
118 if (TegraV4L2ClearDevicePollInterrupt == NULL) { | |
119 DLOG(ERROR) | |
120 << "Unable to get tegra_v4l2_clear_device_poll_interrupt handle "; | |
121 return false; | |
122 } | |
123 | |
124 device_fd_ = | |
125 HANDLE_EINTR(TegraV4L2Open(kDevice, O_RDWR | O_NONBLOCK | O_CLOEXEC)); | |
126 if (device_fd_ == -1) { | |
127 DLOG(ERROR) << "Unable to open tegra_v4l2_open "; | |
128 return false; | |
129 } | |
130 return true; | |
131 } | |
132 | |
133 EGLImageKHR TegraV4L2Device::CreateEGLImage(EGLDisplay egl_display, | |
134 EGLint attrib[], | |
Ami GONE FROM CHROMIUM
2014/02/07 09:09:30
EGLint[] /* attrib */
| |
135 unsigned int texture_id, | |
136 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
| |
137 // Ignore the attributes sent to us since Tegra does not need those. | |
138 EGLint attr = EGL_NONE; | |
139 EGLImageKHR egl_image = eglCreateImageKHR(egl_display, | |
140 egl_context_, | |
141 EGL_GL_TEXTURE_2D_KHR, | |
142 (EGLClientBuffer)(texture_id), | |
Ami GONE FROM CHROMIUM
2014/02/07 09:09:30
static_cast
| |
143 &attr); | |
144 if (egl_image == EGL_NO_IMAGE_KHR) { | |
145 DLOG(ERROR) << "CreateEGLImage(): could not create EGLImageKHR"; | |
146 return egl_image; | |
147 } | |
148 | |
149 struct v4l2_plane planes[2]; | |
150 struct v4l2_buffer capture_buffer; | |
151 | |
152 memset(&capture_buffer, 0, sizeof(capture_buffer)); | |
153 memset(planes, 0, sizeof(planes)); | |
Ami GONE FROM CHROMIUM
2014/02/07 09:09:30
swap w/ previous line to match declaration order
| |
154 capture_buffer.index = buffer_index; | |
155 capture_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | |
156 capture_buffer.memory = V4L2_MEMORY_MMAP; | |
157 capture_buffer.m.planes = planes; | |
158 capture_buffer.length = 2; | |
Pawel Osciak
2014/02/10 06:36:17
arraysize(planes)
| |
159 // We send the EGLImage handle in mem_offset for the library to perform | |
160 // conversion internally | |
161 | |
162 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.
| |
163 if (HANDLE_EINTR(Ioctl(VIDIOC_QUERYBUF, &capture_buffer)) != 0) { | |
164 DLOG(ERROR) << "Some error in querybuf"; | |
165 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
| |
166 } | |
167 return egl_image; | |
168 } | |
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
| |
169 | |
170 unsigned int TegraV4L2Device::GetTextureTarget() { return GL_TEXTURE_2D; } | |
171 | |
172 } // namespace content | |
OLD | NEW |