summaryrefslogtreecommitdiffstats
path: root/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0116-V4L2VDA-Support-tile-to-linear-transform-for-amphion.patch
diff options
context:
space:
mode:
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.patch304
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 @@
1From 346a96e47990cae31b4afe774d9fabf53219c3a9 Mon Sep 17 00:00:00 2001
2From: Hou Qi <qi.hou@nxp.com>
3Date: Mon, 5 Sep 2022 14:14:10 +0800
4Subject: [PATCH 16/17] V4L2VDA: Support tile to linear transform for amphion
5
6Upstream-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
13diff --git a/media/gpu/v4l2/BUILD.gn b/media/gpu/v4l2/BUILD.gn
14index 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 += [
25diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
26index 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)));
290diff --git a/media/gpu/v4l2/v4l2_device.h b/media/gpu/v4l2/v4l2_device.h
291index 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--
3032.17.1
304