diff options
Diffstat (limited to 'dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0116-V4L2VDA-Support-tile-to-linear-transform-for-amphion.patch')
-rw-r--r-- | dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0116-V4L2VDA-Support-tile-to-linear-transform-for-amphion.patch | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0116-V4L2VDA-Support-tile-to-linear-transform-for-amphion.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0116-V4L2VDA-Support-tile-to-linear-transform-for-amphion.patch new file mode 100644 index 00000000..f0e4c46b --- /dev/null +++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0116-V4L2VDA-Support-tile-to-linear-transform-for-amphion.patch | |||
@@ -0,0 +1,304 @@ | |||
1 | From 346a96e47990cae31b4afe774d9fabf53219c3a9 Mon Sep 17 00:00:00 2001 | ||
2 | From: Hou Qi <qi.hou@nxp.com> | ||
3 | Date: Mon, 5 Sep 2022 14:14:10 +0800 | ||
4 | Subject: [PATCH 16/17] V4L2VDA: Support tile to linear transform for amphion | ||
5 | |||
6 | Upstream-Status: Inappropriate [NXP specific] | ||
7 | --- | ||
8 | media/gpu/v4l2/BUILD.gn | 1 + | ||
9 | media/gpu/v4l2/v4l2_device.cc | 182 +++++++++++++++++++++++++++++++++- | ||
10 | media/gpu/v4l2/v4l2_device.h | 1 + | ||
11 | 3 files changed, 179 insertions(+), 5 deletions(-) | ||
12 | |||
13 | diff --git a/media/gpu/v4l2/BUILD.gn b/media/gpu/v4l2/BUILD.gn | ||
14 | index ebd0a4ad64646..273f6066de175 100644 | ||
15 | --- a/media/gpu/v4l2/BUILD.gn | ||
16 | +++ b/media/gpu/v4l2/BUILD.gn | ||
17 | @@ -86,6 +86,7 @@ source_set("v4l2") { | ||
18 | "EGL", | ||
19 | "GLESv2", | ||
20 | ] | ||
21 | + libs += [ "g2d" ] | ||
22 | |||
23 | if (use_v4l2_codec_aml) { | ||
24 | sources += [ | ||
25 | diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc | ||
26 | index 5a1057c845e85..42cd8386f41cb 100644 | ||
27 | --- a/media/gpu/v4l2/v4l2_device.cc | ||
28 | +++ b/media/gpu/v4l2/v4l2_device.cc | ||
29 | @@ -40,6 +40,11 @@ | ||
30 | #include "media/gpu/v4l2/aml_v4l2_device.h" | ||
31 | #endif | ||
32 | |||
33 | +#include "g2d.h" | ||
34 | +#include "g2dExt.h" | ||
35 | +#include <linux/dma-buf.h> | ||
36 | +#include <time.h> | ||
37 | + | ||
38 | namespace media { | ||
39 | |||
40 | namespace { | ||
41 | @@ -169,6 +174,11 @@ class V4L2Buffer { | ||
42 | size_t GetMemoryUsage() const; | ||
43 | const struct v4l2_buffer& v4l2_buffer() const { return v4l2_buffer_; } | ||
44 | scoped_refptr<VideoFrame> GetVideoFrame(); | ||
45 | + std::pair<int, int> GetSavedmafd(); | ||
46 | + std::pair<unsigned int, unsigned int> GetSavedphys(); | ||
47 | + std::pair<int, int> Getg2dbufphys(); | ||
48 | + std::pair<void *, void *> Getg2dbufvirs(); | ||
49 | + const struct v4l2_format& GetFmt() const {return format_;} | ||
50 | |||
51 | private: | ||
52 | V4L2Buffer(scoped_refptr<V4L2Device> device, | ||
53 | @@ -181,6 +191,12 @@ class V4L2Buffer { | ||
54 | |||
55 | scoped_refptr<V4L2Device> device_; | ||
56 | std::vector<void*> plane_mappings_; | ||
57 | + int dmafd0; | ||
58 | + int dmafd1; | ||
59 | + unsigned long phys_0; | ||
60 | + unsigned long phys_1; | ||
61 | + struct g2d_buf *g2dbuf_p0; | ||
62 | + struct g2d_buf *g2dbuf_p1; | ||
63 | |||
64 | // V4L2 data as queried by QUERYBUF. | ||
65 | struct v4l2_buffer v4l2_buffer_; | ||
66 | @@ -230,6 +246,9 @@ V4L2Buffer::V4L2Buffer(scoped_refptr<V4L2Device> device, | ||
67 | v4l2_buffer_.type = type; | ||
68 | v4l2_buffer_.memory = memory; | ||
69 | plane_mappings_.resize(V4L2_TYPE_IS_MULTIPLANAR(type) ? v4l2_buffer_.length : 1); | ||
70 | + dmafd0 = dmafd1 = -1; | ||
71 | + phys_0 = phys_1 = 0; | ||
72 | + g2dbuf_p0 = g2dbuf_p1 = NULL; | ||
73 | } | ||
74 | |||
75 | V4L2Buffer::~V4L2Buffer() { | ||
76 | @@ -242,6 +261,32 @@ V4L2Buffer::~V4L2Buffer() { | ||
77 | } | ||
78 | } | ||
79 | } | ||
80 | + if(g2dbuf_p0 && g2dbuf_p1) { | ||
81 | + g2d_free(g2dbuf_p0); | ||
82 | + g2d_free(g2dbuf_p1); | ||
83 | + } | ||
84 | +} | ||
85 | + | ||
86 | +std::pair<int, int> V4L2Buffer::GetSavedmafd() { | ||
87 | + return std::make_pair(dmafd0, dmafd1); | ||
88 | +} | ||
89 | + | ||
90 | +std::pair<unsigned int, unsigned int> V4L2Buffer::GetSavedphys() { | ||
91 | + return std::make_pair(phys_0, phys_1); | ||
92 | +} | ||
93 | + | ||
94 | +std::pair<int, int> V4L2Buffer::Getg2dbufphys() { | ||
95 | + if(g2dbuf_p0 && g2dbuf_p1) | ||
96 | + return std::make_pair(g2dbuf_p0->buf_paddr, g2dbuf_p1->buf_paddr); | ||
97 | + else | ||
98 | + return std::make_pair(-1, -1); | ||
99 | +} | ||
100 | + | ||
101 | +std::pair<void*, void*> V4L2Buffer::Getg2dbufvirs() { | ||
102 | + if(g2dbuf_p0 && g2dbuf_p1) | ||
103 | + return std::make_pair(g2dbuf_p0->buf_vaddr, g2dbuf_p1->buf_vaddr); | ||
104 | + else | ||
105 | + return std::make_pair(nullptr, nullptr); | ||
106 | } | ||
107 | |||
108 | bool V4L2Buffer::Query() { | ||
109 | @@ -325,6 +370,61 @@ scoped_refptr<VideoFrame> V4L2Buffer::CreateVideoFrame() { | ||
110 | DLOG(ERROR) << "Fail to get DMABUFs of V4L2 buffer - invalid fd"; | ||
111 | return nullptr; | ||
112 | } | ||
113 | + if(dmafd0 == -1) | ||
114 | + dmafd0 = dmabuf_fd.get(); | ||
115 | + else | ||
116 | + dmafd1 = dmabuf_fd.get(); | ||
117 | + } | ||
118 | + | ||
119 | + std::vector<base::ScopedFD> g2dbufs_fds; | ||
120 | + if (V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type)) { | ||
121 | + struct dma_buf_phys{ | ||
122 | + unsigned long phys; | ||
123 | + }; | ||
124 | + #define DMA_BUF_IOCTL_PHYS _IOW(DMA_BUF_BASE, 10, struct dma_buf_phys) | ||
125 | + struct dma_buf_phys query0, query1; | ||
126 | + int ret = ioctl(dmafd0, DMA_BUF_IOCTL_PHYS, &query0); | ||
127 | + if(ret != 0) { | ||
128 | + DLOG(ERROR)<< "DMA_BUF_IOCTL_PHYS failed at dmafd" << dmafd0; | ||
129 | + return nullptr; | ||
130 | + } | ||
131 | + else | ||
132 | + phys_0 = query0.phys; | ||
133 | + | ||
134 | + ret = ioctl(dmafd1, DMA_BUF_IOCTL_PHYS, &query1); | ||
135 | + if(ret != 0) { | ||
136 | + DLOG(ERROR)<< "DMA_BUF_IOCTL_PHYS failed at dmafd" << dmafd1; | ||
137 | + return nullptr; | ||
138 | + } | ||
139 | + else | ||
140 | + phys_1 = query1.phys; | ||
141 | + | ||
142 | + g2dbuf_p0 = g2d_alloc(format_.fmt.pix_mp.width * format_.fmt.pix_mp.height, 0); | ||
143 | + g2dbuf_p1 = g2d_alloc(format_.fmt.pix_mp.width * format_.fmt.pix_mp.height / 2, 0); | ||
144 | + if((!g2dbuf_p0) || (!g2dbuf_p1)){ | ||
145 | + DLOG(ERROR)<<"g2d buf alloc failed"; | ||
146 | + return nullptr; | ||
147 | + } | ||
148 | + | ||
149 | + int tmpfd = g2d_buf_export_fd(g2dbuf_p0); | ||
150 | + tmpfd = dup(tmpfd); | ||
151 | + if(tmpfd > 0) | ||
152 | + g2dbufs_fds.push_back(base::ScopedFD(tmpfd)); | ||
153 | + else if(tmpfd == -1) | ||
154 | + { | ||
155 | + DLOG(ERROR) << "Failed duplicating g2d fd"; | ||
156 | + return nullptr; | ||
157 | + } | ||
158 | + | ||
159 | + tmpfd = g2d_buf_export_fd(g2dbuf_p1); | ||
160 | + tmpfd = dup(tmpfd); | ||
161 | + if(tmpfd>0) | ||
162 | + g2dbufs_fds.push_back(base::ScopedFD(tmpfd)); | ||
163 | + else if(tmpfd == -1) | ||
164 | + { | ||
165 | + DLOG(ERROR) << "Failed duplicating g2d fd"; | ||
166 | + return nullptr; | ||
167 | + } | ||
168 | } | ||
169 | |||
170 | // Duplicate the fd of the last v4l2 plane until the number of fds are the | ||
171 | @@ -339,13 +439,16 @@ scoped_refptr<VideoFrame> V4L2Buffer::CreateVideoFrame() { | ||
172 | dmabuf_fds.emplace_back(duped_fd); | ||
173 | } | ||
174 | |||
175 | - if (V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type)) | ||
176 | + if (V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type)) { | ||
177 | gfx::Size size(format_.fmt.pix_mp.width, format_.fmt.pix_mp.height); | ||
178 | - else | ||
179 | + return VideoFrame::WrapExternalDmabufs( | ||
180 | + *layout, gfx::Rect(size), size, std::move(g2dbufs_fds), base::TimeDelta()); | ||
181 | + } | ||
182 | + else { | ||
183 | gfx::Size size(format_.fmt.pix.width, format_.fmt.pix.height); | ||
184 | - | ||
185 | - return VideoFrame::WrapExternalDmabufs( | ||
186 | - *layout, gfx::Rect(size), size, std::move(dmabuf_fds), base::TimeDelta()); | ||
187 | + return VideoFrame::WrapExternalDmabufs( | ||
188 | + *layout, gfx::Rect(size), size, std::move(dmabuf_fds), base::TimeDelta()); | ||
189 | + } | ||
190 | } | ||
191 | |||
192 | scoped_refptr<VideoFrame> V4L2Buffer::GetVideoFrame() { | ||
193 | @@ -1047,6 +1150,10 @@ V4L2Queue::V4L2Queue(scoped_refptr<V4L2Device> dev, | ||
194 | DVLOGF(4) << "Queue supports request API."; | ||
195 | } | ||
196 | #endif | ||
197 | + | ||
198 | + g2d_handle = NULL; | ||
199 | + if(g2d_open(&g2d_handle)) | ||
200 | + VLOGF(1) << "g2d_open fail"; | ||
201 | } | ||
202 | |||
203 | V4L2Queue::~V4L2Queue() { | ||
204 | @@ -1065,6 +1172,9 @@ V4L2Queue::~V4L2Queue() { | ||
205 | DeallocateBuffers(); | ||
206 | } | ||
207 | |||
208 | + if(g2d_handle) | ||
209 | + g2d_close(g2d_handle); | ||
210 | + | ||
211 | std::move(destroy_cb_).Run(); | ||
212 | } | ||
213 | |||
214 | @@ -1103,6 +1213,8 @@ std::pair<absl::optional<struct v4l2_format>, int> V4L2Queue::GetFormat() { | ||
215 | VPQLOGF(2) << "Failed to get format"; | ||
216 | return std::make_pair(absl::nullopt, errno); | ||
217 | } | ||
218 | + if (type_ == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) | ||
219 | + format.fmt.pix_mp.width = format.fmt.pix_mp.plane_fmt[0].bytesperline; | ||
220 | |||
221 | return std::make_pair(format, 0); | ||
222 | } | ||
223 | @@ -1404,6 +1516,66 @@ std::pair<bool, V4L2ReadableBufferRef> V4L2Queue::DequeueBuffer() { | ||
224 | device_->SchedulePoll(); | ||
225 | |||
226 | DCHECK(free_buffers_); | ||
227 | + | ||
228 | + if(type_ == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) | ||
229 | + { | ||
230 | + std::pair<unsigned int, unsigned int> v4l_phys = buffers_[v4l2_buffer.index]->GetSavedphys(); | ||
231 | + int width = buffers_[v4l2_buffer.index]->GetFmt().fmt.pix_mp.width; | ||
232 | + int height = buffers_[v4l2_buffer.index]->GetFmt().fmt.pix_mp.height; | ||
233 | + int stride = buffers_[v4l2_buffer.index]->GetFmt().fmt.pix_mp.plane_fmt[0].bytesperline; | ||
234 | + bool interlaced = false; | ||
235 | + switch (buffers_[v4l2_buffer.index]->GetFmt().fmt.pix_mp.field) { | ||
236 | + case V4L2_FIELD_INTERLACED: | ||
237 | + case V4L2_FIELD_INTERLACED_TB: | ||
238 | + case V4L2_FIELD_INTERLACED_BT: | ||
239 | + case V4L2_FIELD_SEQ_TB: | ||
240 | + interlaced = true; | ||
241 | + break; | ||
242 | + default: | ||
243 | + break; | ||
244 | + }; | ||
245 | + struct g2d_surfaceEx srcEx, dstEx; | ||
246 | + struct g2d_surface *src = &srcEx.base; | ||
247 | + struct g2d_surface *dst = &dstEx.base; | ||
248 | + | ||
249 | + dst->format = G2D_NV12; | ||
250 | + dst->planes[0] = buffers_[v4l2_buffer.index]->Getg2dbufphys().first; | ||
251 | + dst->planes[1] = buffers_[v4l2_buffer.index]->Getg2dbufphys().second; | ||
252 | + dstEx.tiling = G2D_LINEAR; | ||
253 | + dst->left = 0; | ||
254 | + dst->top = 0; | ||
255 | + dst->right = dst->left + width; | ||
256 | + dst->bottom = dst->top + height; | ||
257 | + dst->stride= width; | ||
258 | + dst->width = width; | ||
259 | + dst->height = height; | ||
260 | + dst->rot = G2D_ROTATION_0; | ||
261 | + dst->global_alpha = 0xff; | ||
262 | + dst->blendfunc = G2D_ONE_MINUS_SRC_ALPHA; | ||
263 | + dst->clrcolor = 0; | ||
264 | + | ||
265 | + src->format = G2D_NV12; | ||
266 | + src->planes[0] = v4l_phys.first; | ||
267 | + src->planes[1] = v4l_phys.second; | ||
268 | + srcEx.tiling = G2D_AMPHION_TILED; | ||
269 | + if (interlaced) { | ||
270 | + srcEx.tiling = static_cast<g2d_tiling>(0x18); //G2D_AMPHION_TILED | G2D_AMPHION_INTERLACED; | ||
271 | + DVLOGF(4)<<"interlaced video convert"; | ||
272 | + } | ||
273 | + src->left = 0; | ||
274 | + src->top = 0; | ||
275 | + src->right = src->left + width; | ||
276 | + src->bottom = src->top + height; | ||
277 | + src->stride= stride; | ||
278 | + src->width = width; | ||
279 | + src->height = height; | ||
280 | + src->rot = G2D_ROTATION_0; | ||
281 | + src->global_alpha = 0xff; | ||
282 | + src->blendfunc = G2D_ONE; | ||
283 | + | ||
284 | + g2d_blitEx(g2d_handle, &srcEx, &dstEx); | ||
285 | + } | ||
286 | + | ||
287 | return std::make_pair(true, V4L2BufferRefFactory::CreateReadableRef( | ||
288 | v4l2_buffer, weak_this_factory_.GetWeakPtr(), | ||
289 | std::move(queued_frame))); | ||
290 | diff --git a/media/gpu/v4l2/v4l2_device.h b/media/gpu/v4l2/v4l2_device.h | ||
291 | index 86ef80fd09579..516d0a63b5689 100644 | ||
292 | --- a/media/gpu/v4l2/v4l2_device.h | ||
293 | +++ b/media/gpu/v4l2/v4l2_device.h | ||
294 | @@ -457,6 +457,7 @@ class MEDIA_GPU_EXPORT V4L2Queue | ||
295 | absl::optional<struct v4l2_format> current_format_; | ||
296 | |||
297 | std::vector<std::unique_ptr<V4L2Buffer>> buffers_; | ||
298 | + void* g2d_handle; | ||
299 | |||
300 | // Buffers that are available for client to get and submit. | ||
301 | // Buffers in this list are not referenced by anyone else than ourselves. | ||
302 | -- | ||
303 | 2.17.1 | ||
304 | |||