summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Dimich <chris.dimich@boundarydevices.com>2023-01-09 10:52:50 -0800
committergithub-actions[bot] <github-actions[bot]@users.noreply.github.com>2023-01-10 11:48:52 +0000
commit481b7f0468b3f5928f8f0fc6aa21e4836fb3f3c5 (patch)
tree110b6e167690d55ae88cad23a9e6c418d982edb6
parent1cfd9c034ea323f198f1bfadd74f589ffa3cc061 (diff)
downloadmeta-freescale-backport-1375-to-kirkstone.tar.gz
chromium-ozone-wayland: add bbappend and patches as per NXP 5.15.71_2.2.0 relbackport-1375-to-kirkstone
Changes include: - support on i.MX 8 series platform. - 8MM/8MP/8MQ support h264/hevc/vp8/vp9 hardware decoding. - 8QM/8QXP support h264/hevc/vp8 hardware decoding. - support seek, playrate change and resolution change. - support video acceleration for online media platform such as Youtube, bilibili. Signed-off-by: Chris Dimich <chris.dimich@boundarydevices.com> (cherry picked from commit 23bdb51b7858db363e56f7748f5523d44f78ac98)
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0001-Fixed-chromium-flicker-with-g2d-renderer.patch33
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0002-chromium-met-EGL-API-GetProcAddress-failures.patch34
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0003-Disable-dri-for-imx-gpu.patch25
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0101-V4L2VDA-Switch-to-use-VDA-instead-of-direct-VideoDec.patch44
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0102-GenericV4L2Device-Correct-v4l2-decoder-device-path.patch31
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0103-V4L2VDA-Add-macro-use_linux_v4l2.patch320
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0104-V4L2VDA-Create-single-multi-plane-queues.patch152
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0105-V4L2Buffer-Allocate-correct-v4l2-buffers-for-queues.patch101
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0106-V4L2VDA-Create-videoframe-according-to-v4l2buffer.patch150
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0107-V4L2VDA-Add-function-IsMultiQueue-for-S_FMT-and-G_FM.patch183
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0108-V4L2VDA-Use-correct-size-to-allocate-CAPTURE-buffer.patch43
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0109-V4L2VDA-Use-correct-plane-size-and-bytesused.patch65
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0110-V4L2VDA-Add-hevc-format-support.patch313
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0111-V4L2VDA-fix-vp9-crash-caused-by-DequeueResolutionCha.patch31
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0112-V4L2VDA-Add-fps-in-SkiaOutputSurfaceImplOnGpu-by-VLO.patch88
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0113-V4L2VDA-Comment-some-unused-ioctl.patch108
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0114-V4L2VDA-Set-OUTPUT-format-with-parsed-resolution-for.patch76
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0115-V4L2VDA-Add-V4L2_PIX_FMT_NV12M_8L128-format-for-amph.patch101
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0116-V4L2VDA-Support-tile-to-linear-transform-for-amphion.patch304
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0117-V4L2VDA-Enlarge-input-buffer-count-to-16.patch29
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0118-V4L2VDA-Use-dlopen-to-dynamically-use-g2d-api.patch306
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0119-V4L2VDA-dlopen-libg2d.so.2-to-avoid-segfault.patch40
-rw-r--r--dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland_%.bbappend51
23 files changed, 2628 insertions, 0 deletions
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0001-Fixed-chromium-flicker-with-g2d-renderer.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0001-Fixed-chromium-flicker-with-g2d-renderer.patch
new file mode 100644
index 00000000..3aa41ecf
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0001-Fixed-chromium-flicker-with-g2d-renderer.patch
@@ -0,0 +1,33 @@
1From 1c7fd64b69feb0ea14047ce1ed68138ccf33687e Mon Sep 17 00:00:00 2001
2From: Wujian sun <wujian.sun_1@nxp.com>
3Date: Mon, 5 Jul 2021 10:28:44 +0800
4Subject: [PATCH] Fixed chromium flicker with g2d-renderer
5
6chromium V89 reland linux_explicit_synchronization_protocol for
7in-fence feature caused the flicker.
8The rootcasue is that weston can not acquire fence fd.
9A workaround no checking supports_acquire_fence supported.
10
11Upstream-Status: Inappropriate [i.MX specific]
12Signed-off-by: Wujian sun <wujian.sun_1@nxp.com>
13---
14 ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc | 3 +--
15 1 file changed, 1 insertion(+), 2 deletions(-)
16
17diff --git a/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc b/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc
18index e7d3e7268a08..83c57fd65d72 100644
19--- a/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc
20+++ b/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc
21@@ -112,8 +112,7 @@ void GbmSurfacelessWayland::SwapBuffersAsync(
22
23 // If Wayland server supports linux_explicit_synchronization_protocol, fences
24 // should be shipped with buffers. Otherwise, we will wait for fences.
25- if (buffer_manager_->supports_acquire_fence() || !use_egl_fence_sync_ ||
26- !frame->schedule_planes_succeeded) {
27+ if (!use_egl_fence_sync_ || !frame->schedule_planes_succeeded) {
28 frame->ready = true;
29 MaybeSubmitFrames();
30 return;
31--
322.17.1
33
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0002-chromium-met-EGL-API-GetProcAddress-failures.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0002-chromium-met-EGL-API-GetProcAddress-failures.patch
new file mode 100644
index 00000000..b85e3cfd
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0002-chromium-met-EGL-API-GetProcAddress-failures.patch
@@ -0,0 +1,34 @@
1From fc83501ff2105f99183b3f6ea240d6baacf3ea05 Mon Sep 17 00:00:00 2001
2From: Wujian Sun <wujian.sun_1@nxp.com>
3Date: Wed, 10 Nov 2021 17:28:22 +0800
4Subject: [PATCH] chromium met EGL API GetProcAddress failures
5
6Wayland not use SwANGLE as below commit, so no need
7build SwANGLE on wayland platform.
8
9commit 97f919dd8b544b583b772664f0d7b8e6b6d8da2e
10Reland "Use SwANGLE on all Ozone platforms, except Wayland"
11
12Upstream-Status: Inappropriate [i.MX-specific]
13
14Signed-off-by: Wujian Sun <wujian.sun_1@nxp.com>
15---
16 ui/gl/BUILD.gn | 2 +-
17 1 file changed, 1 insertion(+), 1 deletion(-)
18
19diff --git a/ui/gl/BUILD.gn b/ui/gl/BUILD.gn
20index bb7d843c1f363..4b4b360758e1d 100644
21--- a/ui/gl/BUILD.gn
22+++ b/ui/gl/BUILD.gn
23@@ -252,7 +252,7 @@ component("gl") {
24
25 if (use_ozone) {
26 deps += [ "//ui/ozone:buildflags" ]
27- if (use_egl && !is_fuchsia) {
28+ if (use_egl && !is_fuchsia && !ozone_platform_wayland) {
29 data_deps += [
30 "//third_party/angle:libEGL",
31 "//third_party/angle:libGLESv2",
32--
332.17.1
34
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0003-Disable-dri-for-imx-gpu.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0003-Disable-dri-for-imx-gpu.patch
new file mode 100644
index 00000000..73b917fb
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0003-Disable-dri-for-imx-gpu.patch
@@ -0,0 +1,25 @@
1Index: chromium-96.0.4664.45/content/gpu/BUILD.gn
2===================================================================
3--- chromium-96.0.4664.45.orig/content/gpu/BUILD.gn
4+++ chromium-96.0.4664.45/content/gpu/BUILD.gn
5@@ -7,6 +7,11 @@ import("//build/config/ui.gni")
6 import("//gpu/vulkan/features.gni")
7 import("//media/media_options.gni")
8
9+declare_args() {
10+ # Checks if i.MX GPU is being used
11+ use_imxgpu = false
12+}
13+
14 # See //content/BUILD.gn for how this works.
15 group("gpu") {
16 visibility = [ "//content/*" ] # This is an internal content API.
17@@ -136,7 +141,7 @@ target(link_target_type, "gpu_sources")
18
19 # Use DRI on desktop Linux builds.
20 if (current_cpu != "s390x" && current_cpu != "ppc64" && is_linux &&
21- (!is_chromecast || is_cast_desktop_build)) {
22+ (!is_chromecast || is_cast_desktop_build) && !use_imxgpu) {
23 configs += [ "//build/config/linux/dri" ]
24 }
25 }
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0101-V4L2VDA-Switch-to-use-VDA-instead-of-direct-VideoDec.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0101-V4L2VDA-Switch-to-use-VDA-instead-of-direct-VideoDec.patch
new file mode 100644
index 00000000..24ae4dd3
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0101-V4L2VDA-Switch-to-use-VDA-instead-of-direct-VideoDec.patch
@@ -0,0 +1,44 @@
1From a86b5ee086e281f34ab90498aedde523c47f9df0 Mon Sep 17 00:00:00 2001
2From: Hou Qi <qi.hou@nxp.com>
3Date: Wed, 17 Aug 2022 16:57:11 +0800
4Subject: [PATCH 01/17] V4L2VDA: Switch to use VDA instead of direct
5 VideoDecoder
6
7commit b7f3a9e8058f593d7d88b6b6cafa71957aa3f1a1 aims to default
8enable "direct VideoDecoder" support on Linux. So need to switch
9to use VDA path iff:
10
111. kVaapiVideoDecodeLinux is enabled (disabled by default);
122. kUseChromeOSDirectVideoDecoder is disabled (enabled by default);
133. GL is used;
14
15Upstream-Status: Inappropriate [NXP specific]
16---
17 media/base/media_switches.cc | 4 ++--
18 1 file changed, 2 insertions(+), 2 deletions(-)
19
20diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
21index 36d638adb816e..938bcede9c878 100644
22--- a/media/base/media_switches.cc
23+++ b/media/base/media_switches.cc
24@@ -487,7 +487,7 @@ const base::Feature kUnifiedAutoplay{"UnifiedAutoplay",
25 // Enable vaapi video decoding on linux. This is already enabled by default on
26 // chromeos, but needs an experiment on linux.
27 const base::Feature kVaapiVideoDecodeLinux{"VaapiVideoDecoder",
28- base::FEATURE_DISABLED_BY_DEFAULT};
29+ base::FEATURE_ENABLED_BY_DEFAULT};
30
31 const base::Feature kVaapiVideoEncodeLinux{"VaapiVideoEncoder",
32 base::FEATURE_DISABLED_BY_DEFAULT};
33@@ -735,7 +735,7 @@ const base::Feature kUseRealColorSpaceForAndroidVideo{
34 // experiment with direct VideoDecoder path on Linux Desktop.
35 // TODO(b/159825227): remove when the direct video decoder is fully launched.
36 const base::Feature kUseChromeOSDirectVideoDecoder{
37- "UseChromeOSDirectVideoDecoder", base::FEATURE_ENABLED_BY_DEFAULT};
38+ "UseChromeOSDirectVideoDecoder", base::FEATURE_DISABLED_BY_DEFAULT};
39
40 #if BUILDFLAG(IS_CHROMEOS)
41 // ChromeOS has one of two VideoDecoder implementations active based on
42--
432.17.1
44
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0102-GenericV4L2Device-Correct-v4l2-decoder-device-path.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0102-GenericV4L2Device-Correct-v4l2-decoder-device-path.patch
new file mode 100644
index 00000000..f7af6acf
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0102-GenericV4L2Device-Correct-v4l2-decoder-device-path.patch
@@ -0,0 +1,31 @@
1From b81ae910fcc8d44ba26ee33923860978b092329a Mon Sep 17 00:00:00 2001
2From: Hou Qi <qi.hou@nxp.com>
3Date: Fri, 2 Sep 2022 16:42:58 +0800
4Subject: [PATCH 02/17] GenericV4L2Device: Correct v4l2 decoder device path
5
6Change decoder device pattern to /dev/video, and select one
7correct device path /dev/videox where x is an integer.
8
9Upstream-Status: Inappropriate [NXP specific]
10---
11 media/gpu/v4l2/generic_v4l2_device.cc | 4 ++--
12 1 file changed, 2 insertions(+), 2 deletions(-)
13
14diff --git a/media/gpu/v4l2/generic_v4l2_device.cc b/media/gpu/v4l2/generic_v4l2_device.cc
15index a6fe9d914e8d9..c1fccf3e2e813 100644
16--- a/media/gpu/v4l2/generic_v4l2_device.cc
17+++ b/media/gpu/v4l2/generic_v4l2_device.cc
18@@ -478,8 +478,8 @@ bool GenericV4L2Device::PostSandboxInitialization() {
19 }
20
21 void GenericV4L2Device::EnumerateDevicesForType(Type type) {
22- static const std::string kDecoderDevicePattern = "/dev/video-dec";
23- static const std::string kEncoderDevicePattern = "/dev/video-enc";
24+ static const std::string kDecoderDevicePattern = "/dev/video";
25+ static const std::string kEncoderDevicePattern = "/dev/video";
26 static const std::string kImageProcessorDevicePattern = "/dev/image-proc";
27 static const std::string kJpegDecoderDevicePattern = "/dev/jpeg-dec";
28 static const std::string kJpegEncoderDevicePattern = "/dev/jpeg-enc";
29--
302.17.1
31
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0103-V4L2VDA-Add-macro-use_linux_v4l2.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0103-V4L2VDA-Add-macro-use_linux_v4l2.patch
new file mode 100644
index 00000000..a0219b8c
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0103-V4L2VDA-Add-macro-use_linux_v4l2.patch
@@ -0,0 +1,320 @@
1From fdc95ddfab945de74fe6b0b196df9a6394013243 Mon Sep 17 00:00:00 2001
2From: Hou Qi <qi.hou@nxp.com>
3Date: Fri, 2 Sep 2022 13:18:34 +0800
4Subject: [PATCH 03/17] V4L2VDA: Add macro use_linux_v4l2
5
6Upstream-Status: Inappropriate [NXP specific]
7---
8 .../gpu_mjpeg_decode_accelerator_factory.cc | 3 +-
9 media/gpu/BUILD.gn | 1 +
10 media/gpu/args.gni | 4 +++
11 .../gpu_video_decode_accelerator_factory.cc | 8 ++++++
12 .../gpu_video_decode_accelerator_factory.h | 2 ++
13 media/gpu/v4l2/BUILD.gn | 22 +++++++++------
14 media/gpu/v4l2/generic_v4l2_device.cc | 4 +++
15 media/gpu/v4l2/v4l2_device.cc | 28 +++++++++++++++++++
16 media/gpu/v4l2/v4l2_video_decoder.cc | 6 ++++
17 9 files changed, 69 insertions(+), 9 deletions(-)
18
19diff --git a/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc b/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc
20index 3772b8ef048a2..dece6b77f6a23 100644
21--- a/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc
22+++ b/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc
23@@ -13,7 +13,8 @@
24 #include "media/base/media_switches.h"
25 #include "media/gpu/buildflags.h"
26
27-#if BUILDFLAG(USE_V4L2_CODEC) && defined(ARCH_CPU_ARM_FAMILY)
28+#if BUILDFLAG(USE_V4L2_CODEC) && defined(ARCH_CPU_ARM_FAMILY) && \
29+ !BUILDFLAG(USE_LINUX_V4L2)
30 #define USE_V4L2_MJPEG_DECODE_ACCELERATOR
31 #endif
32
33diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn
34index 78d151fa630d2..101e2e4f9411e 100644
35--- a/media/gpu/BUILD.gn
36+++ b/media/gpu/BUILD.gn
37@@ -20,6 +20,7 @@ buildflag_header("buildflags") {
38 "USE_VAAPI_IMAGE_CODECS=$use_vaapi_image_codecs",
39 "USE_V4L2_CODEC=$use_v4l2_codec",
40 "USE_LIBV4L2=$use_v4lplugin",
41+ "USE_LINUX_V4L2=$use_linux_v4l2_only",
42 "USE_VAAPI_X11=$use_vaapi_x11",
43 ]
44 }
45diff --git a/media/gpu/args.gni b/media/gpu/args.gni
46index bb2ff0797e031..da20cff798728 100644
47--- a/media/gpu/args.gni
48+++ b/media/gpu/args.gni
49@@ -21,6 +21,10 @@ declare_args() {
50 # platforms which have v4l2 hardware encoder / decoder.
51 use_v4l2_codec = false
52
53+ # Indicates that only definitions available in the mainline linux kernel
54+ # will be used.
55+ use_linux_v4l2_only = false
56+
57 # Indicates if Video4Linux2 AML encoder is used. This is used for AML
58 # platforms which have v4l2 hardware encoder
59 use_v4l2_codec_aml = false
60diff --git a/media/gpu/gpu_video_decode_accelerator_factory.cc b/media/gpu/gpu_video_decode_accelerator_factory.cc
61index 6687b11865f07..9514786384aa7 100644
62--- a/media/gpu/gpu_video_decode_accelerator_factory.cc
63+++ b/media/gpu/gpu_video_decode_accelerator_factory.cc
64@@ -29,7 +29,9 @@
65 #include "ui/gl/gl_implementation.h"
66 #elif BUILDFLAG(USE_V4L2_CODEC)
67 #include "media/gpu/v4l2/v4l2_device.h"
68+#if !BUILDFLAG(USE_LINUX_V4L2)
69 #include "media/gpu/v4l2/v4l2_slice_video_decode_accelerator.h"
70+#endif
71 #include "media/gpu/v4l2/v4l2_video_decode_accelerator.h"
72 #include "ui/gl/gl_surface_egl.h"
73 #endif
74@@ -64,10 +66,12 @@ gpu::VideoDecodeAcceleratorCapabilities GetDecoderCapabilitiesInternal(
75 GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(
76 V4L2VideoDecodeAccelerator::GetSupportedProfiles(),
77 &capabilities.supported_profiles);
78+#if !BUILDFLAG(USE_LINUX_V4L2)
79 GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(
80 V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles(),
81 &capabilities.supported_profiles);
82 #endif
83+#endif
84 #elif BUILDFLAG(IS_MAC)
85 capabilities.supported_profiles =
86 VTVideoDecodeAccelerator::GetSupportedProfiles(workarounds);
87@@ -146,8 +150,10 @@ GpuVideoDecodeAcceleratorFactory::CreateVDA(
88 &GpuVideoDecodeAcceleratorFactory::CreateVaapiVDA,
89 #elif BUILDFLAG(USE_V4L2_CODEC)
90 &GpuVideoDecodeAcceleratorFactory::CreateV4L2VDA,
91+#if !BUILDFLAG(USE_LINUX_V4L2)
92 &GpuVideoDecodeAcceleratorFactory::CreateV4L2SliceVDA,
93 #endif
94+#endif
95
96 #if BUILDFLAG(IS_MAC)
97 &GpuVideoDecodeAcceleratorFactory::CreateVTVDA,
98@@ -207,6 +213,7 @@ GpuVideoDecodeAcceleratorFactory::CreateV4L2VDA(
99 return decoder;
100 }
101
102+#if !BUILDFLAG(USE_LINUX_V4L2)
103 std::unique_ptr<VideoDecodeAccelerator>
104 GpuVideoDecodeAcceleratorFactory::CreateV4L2SliceVDA(
105 const gpu::GpuDriverBugWorkarounds& /*workarounds*/,
106@@ -222,6 +229,7 @@ GpuVideoDecodeAcceleratorFactory::CreateV4L2SliceVDA(
107 return decoder;
108 }
109 #endif
110+#endif
111
112 #if BUILDFLAG(IS_MAC)
113 std::unique_ptr<VideoDecodeAccelerator>
114diff --git a/media/gpu/gpu_video_decode_accelerator_factory.h b/media/gpu/gpu_video_decode_accelerator_factory.h
115index b2e1390c5f02d..5a714eb801d04 100644
116--- a/media/gpu/gpu_video_decode_accelerator_factory.h
117+++ b/media/gpu/gpu_video_decode_accelerator_factory.h
118@@ -104,11 +104,13 @@ class MEDIA_GPU_EXPORT GpuVideoDecodeAcceleratorFactory {
119 const gpu::GpuDriverBugWorkarounds& workarounds,
120 const gpu::GpuPreferences& gpu_preferences,
121 MediaLog* media_log) const;
122+#if !BUILDFLAG(USE_LINUX_V4L2)
123 std::unique_ptr<VideoDecodeAccelerator> CreateV4L2SliceVDA(
124 const gpu::GpuDriverBugWorkarounds& workarounds,
125 const gpu::GpuPreferences& gpu_preferences,
126 MediaLog* media_log) const;
127 #endif
128+#endif
129 #if BUILDFLAG(IS_MAC)
130 std::unique_ptr<VideoDecodeAccelerator> CreateVTVDA(
131 const gpu::GpuDriverBugWorkarounds& workarounds,
132diff --git a/media/gpu/v4l2/BUILD.gn b/media/gpu/v4l2/BUILD.gn
133index 65e5f58d1efef..ebd0a4ad64646 100644
134--- a/media/gpu/v4l2/BUILD.gn
135+++ b/media/gpu/v4l2/BUILD.gn
136@@ -28,9 +28,6 @@ source_set("v4l2") {
137 "buffer_affinity_tracker.h",
138 "generic_v4l2_device.cc",
139 "generic_v4l2_device.h",
140- "v4l2_decode_surface.cc",
141- "v4l2_decode_surface.h",
142- "v4l2_decode_surface_handler.h",
143 "v4l2_device.cc",
144 "v4l2_device.h",
145 "v4l2_device_poller.cc",
146@@ -39,8 +36,6 @@ source_set("v4l2") {
147 "v4l2_framerate_control.h",
148 "v4l2_image_processor_backend.cc",
149 "v4l2_image_processor_backend.h",
150- "v4l2_slice_video_decode_accelerator.cc",
151- "v4l2_slice_video_decode_accelerator.h",
152 "v4l2_stateful_workaround.cc",
153 "v4l2_stateful_workaround.h",
154 "v4l2_status.h",
155@@ -56,8 +51,19 @@ source_set("v4l2") {
156 "v4l2_video_decoder_backend.h",
157 "v4l2_video_decoder_backend_stateful.cc",
158 "v4l2_video_decoder_backend_stateful.h",
159+ "v4l2_video_encode_accelerator.cc",
160+ "v4l2_video_encode_accelerator.h",
161+ ]
162+
163+ if (!use_linux_v4l2_only) {
164+ sources += [
165+ "v4l2_decode_surface.cc",
166+ "v4l2_decode_surface.h",
167+ "v4l2_decode_surface_handler.h",
168 "v4l2_video_decoder_backend_stateless.cc",
169 "v4l2_video_decoder_backend_stateless.h",
170+ "v4l2_slice_video_decode_accelerator.cc",
171+ "v4l2_slice_video_decode_accelerator.h",
172 "v4l2_video_decoder_delegate_h264.cc",
173 "v4l2_video_decoder_delegate_h264.h",
174 "v4l2_video_decoder_delegate_h264_legacy.cc",
175@@ -72,9 +78,9 @@ source_set("v4l2") {
176 "v4l2_video_decoder_delegate_vp9_chromium.h",
177 "v4l2_video_decoder_delegate_vp9_legacy.cc",
178 "v4l2_video_decoder_delegate_vp9_legacy.h",
179- "v4l2_video_encode_accelerator.cc",
180- "v4l2_video_encode_accelerator.h",
181- ]
182+ ]
183+ }
184+
185
186 libs = [
187 "EGL",
188diff --git a/media/gpu/v4l2/generic_v4l2_device.cc b/media/gpu/v4l2/generic_v4l2_device.cc
189index c1fccf3e2e813..319357922c901 100644
190--- a/media/gpu/v4l2/generic_v4l2_device.cc
191+++ b/media/gpu/v4l2/generic_v4l2_device.cc
192@@ -440,7 +440,11 @@ bool GenericV4L2Device::OpenDevicePath(const std::string& path, Type type) {
193 return false;
194
195 #if BUILDFLAG(USE_LIBV4L2)
196+#if BUILDFLAG(USE_LINUX_V4L2)
197+ if (
198+#else
199 if (type == Type::kEncoder &&
200+#endif
201 HANDLE_EINTR(v4l2_fd_open(device_fd_.get(), V4L2_DISABLE_CONVERSION)) !=
202 -1) {
203 DVLOGF(3) << "Using libv4l2 for " << path;
204diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
205index de2800fdab395..722ddbd68cb2b 100644
206--- a/media/gpu/v4l2/v4l2_device.cc
207+++ b/media/gpu/v4l2/v4l2_device.cc
208@@ -853,7 +853,9 @@ void V4L2WritableBufferRef::SetConfigStore(uint32_t config_store) {
209 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
210 DCHECK(buffer_data_);
211
212+#if !BUILDFLAG(USE_LINUX_V4L2)
213 buffer_data_->v4l2_buffer_.config_store = config_store;
214+#endif
215 }
216
217 V4L2ReadableBuffer::V4L2ReadableBuffer(const struct v4l2_buffer& v4l2_buffer,
218@@ -1539,6 +1541,25 @@ std::string V4L2Device::GetDriverName() {
219 // static
220 uint32_t V4L2Device::VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile,
221 bool slice_based) {
222+#if BUILDFLAG(USE_LINUX_V4L2)
223+ if (slice_based) {
224+ LOG(ERROR) << "Unsupported slice";
225+ return 0;
226+ }
227+
228+ if (profile >= H264PROFILE_MIN && profile <= H264PROFILE_MAX) {
229+ return V4L2_PIX_FMT_H264;
230+ } else if (profile >= VP8PROFILE_MIN && profile <= VP8PROFILE_MAX) {
231+ return V4L2_PIX_FMT_VP8;
232+ } else if (profile >= VP9PROFILE_MIN && profile <= VP9PROFILE_MAX) {
233+ return V4L2_PIX_FMT_VP9;
234+ } else if (profile == HEVCPROFILE_MAIN) {
235+ return V4L2_PIX_FMT_HEVC;
236+ } else {
237+ DVLOGF(1) << "Unsupported profile: " << GetProfileName(profile);
238+ return 0;
239+ }
240+#else
241 if (profile >= H264PROFILE_MIN && profile <= H264PROFILE_MAX) {
242 if (slice_based)
243 return V4L2_PIX_FMT_H264_SLICE;
244@@ -1558,6 +1579,7 @@ uint32_t V4L2Device::VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile,
245 DVLOGF(1) << "Unsupported profile: " << GetProfileName(profile);
246 return 0;
247 }
248+#endif
249 }
250
251 namespace {
252@@ -1652,7 +1674,9 @@ std::vector<VideoCodecProfile> V4L2Device::V4L2PixFmtToVideoCodecProfiles(
253 std::vector<VideoCodecProfile> profiles;
254 switch (pix_fmt) {
255 case V4L2_PIX_FMT_H264:
256+#if !BUILDFLAG(USE_LINUX_V4L2)
257 case V4L2_PIX_FMT_H264_SLICE:
258+#endif
259 if (!get_supported_profiles(VideoCodec::kH264, &profiles)) {
260 DLOG(WARNING) << "Driver doesn't support QUERY H264 profiles, "
261 << "use default values, Base, Main, High";
262@@ -1664,11 +1688,15 @@ std::vector<VideoCodecProfile> V4L2Device::V4L2PixFmtToVideoCodecProfiles(
263 }
264 break;
265 case V4L2_PIX_FMT_VP8:
266+#if !BUILDFLAG(USE_LINUX_V4L2)
267 case V4L2_PIX_FMT_VP8_FRAME:
268+#endif
269 profiles = {VP8PROFILE_ANY};
270 break;
271 case V4L2_PIX_FMT_VP9:
272+#if !BUILDFLAG(USE_LINUX_V4L2)
273 case V4L2_PIX_FMT_VP9_FRAME:
274+#endif
275 if (!get_supported_profiles(VideoCodec::kVP9, &profiles)) {
276 DLOG(WARNING) << "Driver doesn't support QUERY VP9 profiles, "
277 << "use default values, Profile0";
278diff --git a/media/gpu/v4l2/v4l2_video_decoder.cc b/media/gpu/v4l2/v4l2_video_decoder.cc
279index 057b28663b15b..691908a3ba8ed 100644
280--- a/media/gpu/v4l2/v4l2_video_decoder.cc
281+++ b/media/gpu/v4l2/v4l2_video_decoder.cc
282@@ -28,7 +28,9 @@
283 #include "media/gpu/macros.h"
284 #include "media/gpu/v4l2/v4l2_status.h"
285 #include "media/gpu/v4l2/v4l2_video_decoder_backend_stateful.h"
286+#if !BUILDFLAG(USE_LINUX_V4L2)
287 #include "media/gpu/v4l2/v4l2_video_decoder_backend_stateless.h"
288+#endif
289
290 namespace media {
291
292@@ -46,7 +48,9 @@ constexpr size_t kNumInputBuffers = 8;
293
294 // Input format V4L2 fourccs this class supports.
295 constexpr uint32_t kSupportedInputFourccs[] = {
296+#if !BUILDFLAG(USE_LINUX_V4L2)
297 V4L2_PIX_FMT_H264_SLICE, V4L2_PIX_FMT_VP8_FRAME, V4L2_PIX_FMT_VP9_FRAME,
298+#endif
299 V4L2_PIX_FMT_H264, V4L2_PIX_FMT_VP8, V4L2_PIX_FMT_VP9,
300 };
301
302@@ -320,6 +324,7 @@ V4L2Status V4L2VideoDecoder::InitializeBackend() {
303 << " and fourcc: " << FourccToString(input_format_fourcc);
304 backend_ = std::make_unique<V4L2StatefulVideoDecoderBackend>(
305 this, device_, profile_, color_space_, decoder_task_runner_);
306+#if !BUILDFLAG(USE_LINUX_V4L2)
307 } else {
308 DCHECK_EQ(preferred_api_and_format.first, kStateless);
309 VLOGF(1) << "Using a stateless API for profile: "
310@@ -327,6 +332,7 @@ V4L2Status V4L2VideoDecoder::InitializeBackend() {
311 << " and fourcc: " << FourccToString(input_format_fourcc);
312 backend_ = std::make_unique<V4L2StatelessVideoDecoderBackend>(
313 this, device_, profile_, color_space_, decoder_task_runner_);
314+#endif
315 }
316
317 if (!backend_->Initialize()) {
318--
3192.17.1
320
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0104-V4L2VDA-Create-single-multi-plane-queues.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0104-V4L2VDA-Create-single-multi-plane-queues.patch
new file mode 100644
index 00000000..817868ac
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0104-V4L2VDA-Create-single-multi-plane-queues.patch
@@ -0,0 +1,152 @@
1From 9caf73fb012217db1581a5079dfbc9872196571f Mon Sep 17 00:00:00 2001
2From: Hou Qi <qi.hou@nxp.com>
3Date: Fri, 2 Sep 2022 15:35:52 +0800
4Subject: [PATCH 04/17] V4L2VDA: Create single/multi plane queues
5
6Decide to create single-plane queue or multi-plane queue according to
7the capabilities returned by VIDIOC_QUERYCAP.
8
9Upstream-Status: Inappropriate [NXP specific]
10---
11 media/gpu/v4l2/generic_v4l2_device.cc | 15 ++++++----
12 media/gpu/v4l2/v4l2_device.cc | 11 ++++++--
13 .../gpu/v4l2/v4l2_video_decode_accelerator.cc | 28 ++++++++++++++-----
14 3 files changed, 39 insertions(+), 15 deletions(-)
15
16diff --git a/media/gpu/v4l2/generic_v4l2_device.cc b/media/gpu/v4l2/generic_v4l2_device.cc
17index 319357922c901..a578768f8d3b1 100644
18--- a/media/gpu/v4l2/generic_v4l2_device.cc
19+++ b/media/gpu/v4l2/generic_v4l2_device.cc
20@@ -489,27 +489,28 @@ void GenericV4L2Device::EnumerateDevicesForType(Type type) {
21 static const std::string kJpegEncoderDevicePattern = "/dev/jpeg-enc";
22
23 std::string device_pattern;
24- v4l2_buf_type buf_type;
25+ std::vector<v4l2_buf_type> candidate_buf_types;
26 switch (type) {
27 case Type::kDecoder:
28 device_pattern = kDecoderDevicePattern;
29- buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
30+ candidate_buf_types.push_back(V4L2_BUF_TYPE_VIDEO_OUTPUT);
31+ candidate_buf_types.push_back(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
32 break;
33 case Type::kEncoder:
34 device_pattern = kEncoderDevicePattern;
35- buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
36+ candidate_buf_types.push_back(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
37 break;
38 case Type::kImageProcessor:
39 device_pattern = kImageProcessorDevicePattern;
40- buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
41+ candidate_buf_types.push_back(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
42 break;
43 case Type::kJpegDecoder:
44 device_pattern = kJpegDecoderDevicePattern;
45- buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
46+ candidate_buf_types.push_back(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
47 break;
48 case Type::kJpegEncoder:
49 device_pattern = kJpegEncoderDevicePattern;
50- buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
51+ candidate_buf_types.push_back(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
52 break;
53 }
54
55@@ -529,6 +530,7 @@ void GenericV4L2Device::EnumerateDevicesForType(Type type) {
56
57 Devices devices;
58 for (const auto& path : candidate_paths) {
59+ for (const auto& buf_type : candidate_buf_types){
60 if (!OpenDevicePath(path, type))
61 continue;
62
63@@ -541,6 +543,7 @@ void GenericV4L2Device::EnumerateDevicesForType(Type type) {
64
65 CloseDevice();
66 }
67+ }
68
69 DCHECK_EQ(devices_by_type_.count(type), 0u);
70 devices_by_type_[type] = devices;
71diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
72index 722ddbd68cb2b..8194d8646637c 100644
73--- a/media/gpu/v4l2/v4l2_device.cc
74+++ b/media/gpu/v4l2/v4l2_device.cc
75@@ -1479,6 +1479,8 @@ scoped_refptr<V4L2Queue> V4L2Device::GetQueue(enum v4l2_buf_type type) {
76 // Supported queue types.
77 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
78 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
79+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
80+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
81 break;
82 default:
83 VLOGF(1) << "Unsupported V4L2 queue type: " << type;
84@@ -2049,8 +2051,13 @@ V4L2Device::EnumerateSupportedDecodeProfiles(const size_t num_formats,
85 const uint32_t pixelformats[]) {
86 VideoDecodeAccelerator::SupportedProfiles profiles;
87
88- const auto& supported_pixelformats =
89- EnumerateSupportedPixelformats(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
90+ std::vector<uint32_t> enumerated_pixelformats;
91+ enumerated_pixelformats = EnumerateSupportedPixelformats(V4L2_BUF_TYPE_VIDEO_OUTPUT);
92+ if (enumerated_pixelformats.empty()) {
93+ VLOG(1) << "empty.... Try Multi-plane";
94+ enumerated_pixelformats = EnumerateSupportedPixelformats(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
95+ }
96+ const auto& supported_pixelformats = enumerated_pixelformats;
97
98 for (uint32_t pixelformat : supported_pixelformats) {
99 if (std::find(pixelformats, pixelformats + num_formats, pixelformat) ==
100diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
101index c920940572fb2..631e68e0f9314 100644
102--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
103+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
104@@ -322,24 +322,38 @@ bool V4L2VideoDecodeAccelerator::CheckConfig(const Config& config) {
105
106 // Capabilities check.
107 struct v4l2_capability caps;
108- const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
109- IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
110- if ((caps.capabilities & kCapsRequired) != kCapsRequired) {
111- VLOGF(1) << "ioctl() failed: VIDIOC_QUERYCAP"
112- << ", caps check failed: 0x" << std::hex << caps.capabilities;
113+ unsigned int device_caps;
114+ enum v4l2_buf_type input_type, output_type;
115+ if (device_->Ioctl(VIDIOC_QUERYCAP, &caps) != 0) {
116+ VPLOGF(1) << "ioctl() failed: VIDIOC_QUERYCAP"
117+ << ", caps check failed: 0x" << std::hex << caps.capabilities;
118 return false;
119 }
120
121+ if (caps.capabilities & V4L2_CAP_DEVICE_CAPS)
122+ device_caps = caps.device_caps;
123+ else
124+ device_caps = caps.capabilities;
125+
126+ if (device_caps & (V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE))
127+ input_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
128+ else
129+ input_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
130+ if (device_caps & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE))
131+ output_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
132+ else
133+ output_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
134+
135 workarounds_ =
136 CreateV4L2StatefulWorkarounds(V4L2Device::Type::kDecoder, config.profile);
137
138 output_mode_ = config.output_mode;
139
140- input_queue_ = device_->GetQueue(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
141+ input_queue_ = device_->GetQueue(input_type);
142 if (!input_queue_)
143 return false;
144
145- output_queue_ = device_->GetQueue(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
146+ output_queue_ = device_->GetQueue(output_type);
147 if (!output_queue_)
148 return false;
149
150--
1512.17.1
152
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0105-V4L2Buffer-Allocate-correct-v4l2-buffers-for-queues.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0105-V4L2Buffer-Allocate-correct-v4l2-buffers-for-queues.patch
new file mode 100644
index 00000000..b790b9ff
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0105-V4L2Buffer-Allocate-correct-v4l2-buffers-for-queues.patch
@@ -0,0 +1,101 @@
1From 8c5e88c38c6ef5c9864016b90dfc3ae49cc11ddb Mon Sep 17 00:00:00 2001
2From: Hou Qi <qi.hou@nxp.com>
3Date: Fri, 2 Sep 2022 17:10:12 +0800
4Subject: [PATCH 05/17] V4L2Buffer: Allocate correct v4l2 buffers for queues
5
6For single plane queue, need to fill v4l2_planes_[0] with
7correct size quried from v4l2 driver.
8
9Upstream-Status: Inappropriate [NXP specific]
10---
11 media/gpu/v4l2/v4l2_device.cc | 45 ++++++++++++++++++++++++-----------
12 1 file changed, 31 insertions(+), 14 deletions(-)
13
14diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
15index 8194d8646637c..9614eb8e71668 100644
16--- a/media/gpu/v4l2/v4l2_device.cc
17+++ b/media/gpu/v4l2/v4l2_device.cc
18@@ -210,24 +210,30 @@ V4L2Buffer::V4L2Buffer(scoped_refptr<V4L2Device> device,
19 DCHECK(V4L2_TYPE_IS_MULTIPLANAR(type));
20 DCHECK_LE(format.fmt.pix_mp.num_planes, std::size(v4l2_planes_));
21
22- memset(&v4l2_buffer_, 0, sizeof(v4l2_buffer_));
23- memset(v4l2_planes_, 0, sizeof(v4l2_planes_));
24- v4l2_buffer_.m.planes = v4l2_planes_;
25- // Just in case we got more planes than we want.
26- v4l2_buffer_.length =
27- std::min(static_cast<size_t>(format.fmt.pix_mp.num_planes),
28- std::size(v4l2_planes_));
29+ if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
30+ memset(&v4l2_buffer_, 0, sizeof(v4l2_buffer_));
31+ memset(v4l2_planes_, 0, sizeof(v4l2_planes_));
32+ v4l2_buffer_.m.planes = v4l2_planes_;
33+ // Just in case we got more planes than we want.
34+ v4l2_buffer_.length =
35+ std::min(static_cast<size_t>(format.fmt.pix_mp.num_planes),
36+ std::size(v4l2_planes_));
37+ }
38 v4l2_buffer_.index = buffer_id;
39 v4l2_buffer_.type = type;
40 v4l2_buffer_.memory = memory;
41- plane_mappings_.resize(v4l2_buffer_.length);
42+ plane_mappings_.resize(V4L2_TYPE_IS_MULTIPLANAR(type) ? v4l2_buffer_.length : 1);
43 }
44
45 V4L2Buffer::~V4L2Buffer() {
46 if (v4l2_buffer_.memory == V4L2_MEMORY_MMAP) {
47- for (size_t i = 0; i < plane_mappings_.size(); i++)
48- if (plane_mappings_[i] != nullptr)
49- device_->Munmap(plane_mappings_[i], v4l2_buffer_.m.planes[i].length);
50+ for (size_t i = 0; i < plane_mappings_.size(); i++) {
51+ if (plane_mappings_[i] != nullptr) {
52+ unsigned int length = V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type) ?
53+ v4l2_buffer_.m.planes[i].length : v4l2_buffer_.length;
54+ device_->Munmap(plane_mappings_[i], length);
55+ }
56+ }
57 }
58 }
59
60@@ -238,6 +244,13 @@ bool V4L2Buffer::Query() {
61 return false;
62 }
63
64+ if (!V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type)) {
65+ v4l2_planes_[0].bytesused = v4l2_buffer_.bytesused;
66+ v4l2_planes_[0].length = v4l2_buffer_.length;
67+ v4l2_planes_[0].data_offset = 0;
68+ memcpy (&v4l2_planes_[0].m, &v4l2_buffer_.m, sizeof (v4l2_buffer_.m));
69+ }
70+
71 DCHECK(plane_mappings_.size() == v4l2_buffer_.length);
72
73 return true;
74@@ -260,9 +273,13 @@ void* V4L2Buffer::GetPlaneMapping(const size_t plane) {
75 return nullptr;
76 }
77
78- p = device_->Mmap(nullptr, v4l2_buffer_.m.planes[plane].length,
79+ unsigned int length = V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type) ?
80+ v4l2_buffer_.m.planes[plane].length : v4l2_planes_[plane].length;
81+ unsigned int mem_offset = V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type) ?
82+ v4l2_buffer_.m.planes[plane].m.mem_offset : v4l2_planes_[plane].m.mem_offset;
83+ p = device_->Mmap(nullptr, length,
84 PROT_READ | PROT_WRITE, MAP_SHARED,
85- v4l2_buffer_.m.planes[plane].m.mem_offset);
86+ mem_offset);
87 if (p == MAP_FAILED) {
88 VPLOGF(1) << "mmap() failed: ";
89 return nullptr;
90@@ -1131,7 +1148,7 @@ size_t V4L2Queue::AllocateBuffers(size_t count, enum v4l2_memory memory) {
91 VQLOGF(1) << "Cannot get format.";
92 return 0;
93 }
94- planes_count_ = format->fmt.pix_mp.num_planes;
95+ planes_count_ = V4L2_TYPE_IS_MULTIPLANAR(format->type) ? format->fmt.pix_mp.num_planes : 1;
96 DCHECK_LE(planes_count_, static_cast<size_t>(VIDEO_MAX_PLANES));
97
98 struct v4l2_requestbuffers reqbufs;
99--
1002.17.1
101
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0106-V4L2VDA-Create-videoframe-according-to-v4l2buffer.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0106-V4L2VDA-Create-videoframe-according-to-v4l2buffer.patch
new file mode 100644
index 00000000..f210fe57
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0106-V4L2VDA-Create-videoframe-according-to-v4l2buffer.patch
@@ -0,0 +1,150 @@
1From 0e5dd1497ff0764dc28ef9bbd3f9249617f8af59 Mon Sep 17 00:00:00 2001
2From: Hou Qi <qi.hou@nxp.com>
3Date: Fri, 2 Sep 2022 17:30:16 +0800
4Subject: [PATCH 06/17] V4L2VDA: Create videoframe according to v4l2buffer
5
6Upstream-Status: Inappropriate [NXP specific]
7---
8 media/gpu/v4l2/v4l2_device.cc | 70 ++++++++++++++++++++++++-----------
9 1 file changed, 48 insertions(+), 22 deletions(-)
10
11diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
12index 9614eb8e71668..a9462c9a2fb2d 100644
13--- a/media/gpu/v4l2/v4l2_device.cc
14+++ b/media/gpu/v4l2/v4l2_device.cc
15@@ -305,7 +305,7 @@ scoped_refptr<VideoFrame> V4L2Buffer::CreateVideoFrame() {
16 }
17
18 std::vector<base::ScopedFD> dmabuf_fds = device_->GetDmabufsForV4L2Buffer(
19- v4l2_buffer_.index, v4l2_buffer_.length,
20+ v4l2_buffer_.index, V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type) ? v4l2_buffer_.length : 1,
21 static_cast<enum v4l2_buf_type>(v4l2_buffer_.type));
22 if (dmabuf_fds.empty()) {
23 VLOGF(1) << "Failed to get DMABUFs of V4L2 buffer";
24@@ -332,7 +332,10 @@ scoped_refptr<VideoFrame> V4L2Buffer::CreateVideoFrame() {
25 dmabuf_fds.emplace_back(duped_fd);
26 }
27
28- gfx::Size size(format_.fmt.pix_mp.width, format_.fmt.pix_mp.height);
29+ if (V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type))
30+ gfx::Size size(format_.fmt.pix_mp.width, format_.fmt.pix_mp.height);
31+ else
32+ gfx::Size size(format_.fmt.pix.width, format_.fmt.pix.height);
33
34 return VideoFrame::WrapExternalDmabufs(
35 *layout, gfx::Rect(size), size, std::move(dmabuf_fds), base::TimeDelta());
36@@ -1897,13 +1900,9 @@ gfx::Size V4L2Device::AllocatedSizeFromV4L2Format(
37 // static
38 absl::optional<VideoFrameLayout> V4L2Device::V4L2FormatToVideoFrameLayout(
39 const struct v4l2_format& format) {
40- if (!V4L2_TYPE_IS_MULTIPLANAR(format.type)) {
41- VLOGF(1) << "v4l2_buf_type is not multiplanar: " << std::hex << "0x"
42- << format.type;
43- return absl::nullopt;
44- }
45 const v4l2_pix_format_mplane& pix_mp = format.fmt.pix_mp;
46- const uint32_t& pix_fmt = pix_mp.pixelformat;
47+ const v4l2_pix_format& pix = format.fmt.pix;
48+ const uint32_t& pix_fmt = V4L2_TYPE_IS_MULTIPLANAR(format.type) ? pix_mp.pixelformat : pix.pixelformat;
49 const auto video_fourcc = Fourcc::FromV4L2PixFmt(pix_fmt);
50 if (!video_fourcc) {
51 VLOGF(1) << "Failed to convert pixel format to VideoPixelFormat: "
52@@ -1911,7 +1910,7 @@ absl::optional<VideoFrameLayout> V4L2Device::V4L2FormatToVideoFrameLayout(
53 return absl::nullopt;
54 }
55 const VideoPixelFormat video_format = video_fourcc->ToVideoPixelFormat();
56- const size_t num_buffers = pix_mp.num_planes;
57+ const size_t num_buffers = V4L2_TYPE_IS_MULTIPLANAR(format.type) ? format.fmt.pix_mp.num_planes : 1;
58 const size_t num_color_planes = VideoFrame::NumPlanes(video_format);
59 if (num_color_planes == 0) {
60 VLOGF(1) << "Unsupported video format for NumPlanes(): "
61@@ -1929,9 +1928,17 @@ absl::optional<VideoFrameLayout> V4L2Device::V4L2FormatToVideoFrameLayout(
62 std::vector<ColorPlaneLayout> planes;
63 planes.reserve(num_color_planes);
64 for (size_t i = 0; i < num_buffers; ++i) {
65- const v4l2_plane_pix_format& plane_format = pix_mp.plane_fmt[i];
66- planes.emplace_back(static_cast<int32_t>(plane_format.bytesperline), 0u,
67- plane_format.sizeimage);
68+ if (V4L2_TYPE_IS_MULTIPLANAR(format.type)) {
69+ if(i==0)
70+ planes.emplace_back(static_cast<int32_t>(pix_mp.width), 0u,
71+ pix_mp.width*pix_mp.height);
72+ else
73+ planes.emplace_back(static_cast<int32_t>(pix_mp.width), 0u,
74+ pix_mp.width*pix_mp.height/2);
75+ } else {
76+ planes.emplace_back(static_cast<int32_t>(pix.bytesperline), 0u,
77+ pix.sizeimage);
78+ }
79 }
80 // For the case that #color planes > #buffers, it fills stride of color
81 // plane which does not map to buffer.
82@@ -1945,8 +1952,12 @@ absl::optional<VideoFrameLayout> V4L2Device::V4L2FormatToVideoFrameLayout(
83 case V4L2_PIX_FMT_NV12:
84 // The stride of UV is the same as Y in NV12.
85 // The height is half of Y plane.
86- planes.emplace_back(y_stride, y_stride_abs * pix_mp.height,
87- y_stride_abs * pix_mp.height / 2);
88+ if (V4L2_TYPE_IS_MULTIPLANAR(format.type))
89+ planes.emplace_back(y_stride, y_stride_abs * pix_mp.height,
90+ y_stride_abs * pix_mp.height / 2);
91+ else
92+ planes.emplace_back(y_stride, y_stride_abs * pix.height,
93+ y_stride_abs * pix.height / 2);
94 DCHECK_EQ(2u, planes.size());
95 break;
96 case V4L2_PIX_FMT_YUV420:
97@@ -1954,13 +1965,18 @@ absl::optional<VideoFrameLayout> V4L2Device::V4L2FormatToVideoFrameLayout(
98 // The spec claims that two Cx rows (including padding) is exactly as
99 // long as one Y row (including padding). So stride of Y must be even
100 // number.
101- if (y_stride % 2 != 0 || pix_mp.height % 2 != 0) {
102+ if (V4L2_TYPE_IS_MULTIPLANAR(format.type) && (y_stride % 2 != 0 || pix_mp.height % 2 != 0)) {
103 VLOGF(1) << "Plane-Y stride and height should be even; stride: "
104 << y_stride << ", height: " << pix_mp.height;
105 return absl::nullopt;
106 }
107+ else if (!V4L2_TYPE_IS_MULTIPLANAR(format.type) && (y_stride % 2 != 0 || pix.height % 2 != 0)){
108+ VLOGF(1) << "Plane-Y stride and height should be even; stride: "
109+ << y_stride << ", height: " << pix.height;
110+ return absl::nullopt;
111+ }
112 const int32_t half_stride = y_stride / 2;
113- const size_t plane_0_area = y_stride_abs * pix_mp.height;
114+ const size_t plane_0_area = y_stride_abs * (V4L2_TYPE_IS_MULTIPLANAR(format.type) ? pix_mp.height : pix.height);
115 const size_t plane_1_area = plane_0_area / 4;
116 planes.emplace_back(half_stride, plane_0_area, plane_1_area);
117 planes.emplace_back(half_stride, plane_0_area + plane_1_area,
118@@ -1979,13 +1995,23 @@ absl::optional<VideoFrameLayout> V4L2Device::V4L2FormatToVideoFrameLayout(
119 // such devices individually, so set this as a video frame layout property.
120 constexpr size_t buffer_alignment = 0x1000;
121 if (num_buffers == 1) {
122- return VideoFrameLayout::CreateWithPlanes(
123- video_format, gfx::Size(pix_mp.width, pix_mp.height), std::move(planes),
124- buffer_alignment);
125+ if (V4L2_TYPE_IS_MULTIPLANAR(format.type))
126+ return VideoFrameLayout::CreateWithPlanes(
127+ video_format, gfx::Size(pix_mp.width, pix_mp.height), std::move(planes),
128+ buffer_alignment);
129+ else
130+ return VideoFrameLayout::CreateWithPlanes(
131+ video_format, gfx::Size(pix.width, pix.height), std::move(planes),
132+ buffer_alignment);
133 } else {
134- return VideoFrameLayout::CreateMultiPlanar(
135- video_format, gfx::Size(pix_mp.width, pix_mp.height), std::move(planes),
136- buffer_alignment);
137+ if (V4L2_TYPE_IS_MULTIPLANAR(format.type))
138+ return VideoFrameLayout::CreateMultiPlanar(
139+ video_format, gfx::Size(pix_mp.width, pix_mp.height), std::move(planes),
140+ buffer_alignment);
141+ else
142+ return VideoFrameLayout::CreateMultiPlanar(
143+ video_format, gfx::Size(pix.width, pix.height), std::move(planes),
144+ buffer_alignment);
145 }
146 }
147
148--
1492.17.1
150
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0107-V4L2VDA-Add-function-IsMultiQueue-for-S_FMT-and-G_FM.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0107-V4L2VDA-Add-function-IsMultiQueue-for-S_FMT-and-G_FM.patch
new file mode 100644
index 00000000..2e9b4431
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0107-V4L2VDA-Add-function-IsMultiQueue-for-S_FMT-and-G_FM.patch
@@ -0,0 +1,183 @@
1From 3c9a3ef7f2c45386486a86bdbfa6c355f4c8da05 Mon Sep 17 00:00:00 2001
2From: Hou Qi <qi.hou@nxp.com>
3Date: Sun, 4 Sep 2022 15:48:00 +0800
4Subject: [PATCH 07/17] V4L2VDA: Add function IsMultiQueue for S_FMT and G_FMT
5
6Function IsMultiQueue() is used to set correct fotmat type for
78M and 8Q.
8
9Upstream-Status: Inappropriate [NXP specific]
10---
11 media/gpu/v4l2/v4l2_device.cc | 36 +++++++++++---
12 media/gpu/v4l2/v4l2_device.h | 1 +
13 .../gpu/v4l2/v4l2_video_decode_accelerator.cc | 49 +++++++++++++++----
14 3 files changed, 68 insertions(+), 18 deletions(-)
15
16diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
17index a9462c9a2fb2d..200b0fccb1232 100644
18--- a/media/gpu/v4l2/v4l2_device.cc
19+++ b/media/gpu/v4l2/v4l2_device.cc
20@@ -58,11 +58,18 @@ struct v4l2_format BuildV4L2Format(const enum v4l2_buf_type type,
21 struct v4l2_format format;
22 memset(&format, 0, sizeof(format));
23 format.type = type;
24- format.fmt.pix_mp.pixelformat = fourcc;
25- format.fmt.pix_mp.width = size.width();
26- format.fmt.pix_mp.height = size.height();
27- format.fmt.pix_mp.num_planes = V4L2Device::GetNumPlanesOfV4L2PixFmt(fourcc);
28- format.fmt.pix_mp.plane_fmt[0].sizeimage = buffer_size;
29+ if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
30+ format.fmt.pix_mp.pixelformat = fourcc;
31+ format.fmt.pix_mp.width = size.width();
32+ format.fmt.pix_mp.height = size.height();
33+ format.fmt.pix_mp.num_planes = V4L2Device::GetNumPlanesOfV4L2PixFmt(fourcc);
34+ format.fmt.pix_mp.plane_fmt[0].sizeimage = buffer_size;
35+ } else {
36+ format.fmt.pix.pixelformat = fourcc;
37+ format.fmt.pix.width = size.width();
38+ format.fmt.pix.height = size.height();
39+ format.fmt.pix.sizeimage = buffer_size;
40+ }
41
42 return format;
43 }
44@@ -476,9 +483,13 @@ V4L2BufferRefBase::V4L2BufferRefBase(const struct v4l2_buffer& v4l2_buffer,
45 DCHECK(return_to_);
46
47 memcpy(&v4l2_buffer_, &v4l2_buffer, sizeof(v4l2_buffer_));
48- memcpy(v4l2_planes_, v4l2_buffer.m.planes,
49- sizeof(struct v4l2_plane) * v4l2_buffer.length);
50- v4l2_buffer_.m.planes = v4l2_planes_;
51+ if (V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer.type)) {
52+ memcpy(v4l2_planes_, v4l2_buffer.m.planes,
53+ sizeof(struct v4l2_plane) * v4l2_buffer.length);
54+ v4l2_buffer_.m.planes = v4l2_planes_;
55+ } else {
56+ memcpy(&v4l2_planes_[0].m, &v4l2_buffer.m, sizeof(v4l2_buffer.m));
57+ }
58 }
59
60 V4L2BufferRefBase::~V4L2BufferRefBase() {
61@@ -1434,6 +1445,15 @@ bool V4L2Queue::Streamoff() {
62 return true;
63 }
64
65+bool V4L2Queue::IsMultiQueue() {
66+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
67+
68+ if (type_ == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || type_ == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
69+ return true;
70+ else
71+ return false;
72+}
73+
74 size_t V4L2Queue::AllocatedBuffersCount() const {
75 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
76
77diff --git a/media/gpu/v4l2/v4l2_device.h b/media/gpu/v4l2/v4l2_device.h
78index 70f47ae91b648..86ef80fd09579 100644
79--- a/media/gpu/v4l2/v4l2_device.h
80+++ b/media/gpu/v4l2/v4l2_device.h
81@@ -424,6 +424,7 @@ class MEDIA_GPU_EXPORT V4L2Queue
82 // still be using them.
83 bool Streamoff();
84
85+ bool IsMultiQueue();
86 // Returns the number of buffers currently allocated for this queue.
87 size_t AllocatedBuffersCount() const;
88 // Returns the number of currently free buffers on this queue.
89diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
90index 631e68e0f9314..54c72c6148d94 100644
91--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
92+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
93@@ -2153,12 +2153,30 @@ bool V4L2VideoDecodeAccelerator::GetFormatInfo(struct v4l2_format* format,
94 }
95
96 // Make sure we are still getting the format we set on initialization.
97- if (format->fmt.pix_mp.pixelformat != output_format_fourcc_->ToV4L2PixFmt()) {
98+ unsigned int pixelformat = V4L2_TYPE_IS_MULTIPLANAR(format->type) ?
99+ format->fmt.pix_mp.pixelformat : format->fmt.pix.pixelformat;
100+ if (pixelformat != output_format_fourcc_->ToV4L2PixFmt()) {
101 VLOGF(1) << "Unexpected format from G_FMT on output";
102 return false;
103 }
104
105- gfx::Size coded_size(format->fmt.pix_mp.width, format->fmt.pix_mp.height);
106+ int width, height;
107+ if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) {
108+ width = format->fmt.pix_mp.width;
109+ height = format->fmt.pix_mp.height;
110+ if ((format->fmt.pix_mp.width == 0) && (format->fmt.pix_mp.height == 0))
111+ {
112+ *again = true;
113+ VLOG(1)<<"As got width=height=0 again";
114+ } else {
115+ VLOG(1)<<"format wxh" << format->fmt.pix_mp.width << "x" << format->fmt.pix_mp.height;
116+ }
117+ } else {
118+ width = format->fmt.pix.width;
119+ height = format->fmt.pix.height;
120+ }
121+
122+ gfx::Size coded_size(width, height);
123 if (visible_size != nullptr)
124 *visible_size = GetVisibleSize(coded_size);
125
126@@ -2263,7 +2281,7 @@ bool V4L2VideoDecodeAccelerator::SetupFormats() {
127
128 struct v4l2_fmtdesc fmtdesc;
129 memset(&fmtdesc, 0, sizeof(fmtdesc));
130- fmtdesc.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
131+ fmtdesc.type = input_queue_->IsMultiQueue() ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE : V4L2_BUF_TYPE_VIDEO_OUTPUT;
132 bool is_format_supported = false;
133 while (device_->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0) {
134 if (fmtdesc.pixelformat == input_format_fourcc_) {
135@@ -2281,10 +2299,16 @@ bool V4L2VideoDecodeAccelerator::SetupFormats() {
136
137 struct v4l2_format format;
138 memset(&format, 0, sizeof(format));
139- format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
140- format.fmt.pix_mp.pixelformat = input_format_fourcc_;
141- format.fmt.pix_mp.plane_fmt[0].sizeimage = input_size;
142- format.fmt.pix_mp.num_planes = 1;
143+ if (input_queue_->IsMultiQueue()) {
144+ format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
145+ format.fmt.pix_mp.pixelformat = input_format_fourcc_;
146+ format.fmt.pix_mp.plane_fmt[0].sizeimage = input_size;
147+ format.fmt.pix_mp.num_planes = 1;
148+ } else {
149+ format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
150+ format.fmt.pix.pixelformat = input_format_fourcc_;
151+ format.fmt.pix.sizeimage = input_size;
152+ }
153 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format);
154 DCHECK_EQ(format.fmt.pix_mp.pixelformat, input_format_fourcc_);
155
156@@ -2292,7 +2316,7 @@ bool V4L2VideoDecodeAccelerator::SetupFormats() {
157 // changing it once we start streaming; whether it can support our chosen
158 // output format or not may depend on the input format.
159 memset(&fmtdesc, 0, sizeof(fmtdesc));
160- fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
161+ fmtdesc.type = output_queue_->IsMultiQueue() ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : V4L2_BUF_TYPE_VIDEO_CAPTURE;
162 while (device_->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0) {
163 auto fourcc = Fourcc::FromV4L2PixFmt(fmtdesc.pixelformat);
164 if (fourcc && device_->CanCreateEGLImageFrom(*fourcc)) {
165@@ -2334,8 +2358,13 @@ bool V4L2VideoDecodeAccelerator::SetupFormats() {
166 // Just set the fourcc for output; resolution, etc., will come from the
167 // driver once it extracts it from the stream.
168 memset(&format, 0, sizeof(format));
169- format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
170- format.fmt.pix_mp.pixelformat = output_format_fourcc_->ToV4L2PixFmt();
171+ if (output_queue_->IsMultiQueue()) {
172+ format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
173+ format.fmt.pix_mp.pixelformat = output_format_fourcc_->ToV4L2PixFmt();
174+ } else {
175+ format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
176+ format.fmt.pix.pixelformat = output_format_fourcc_->ToV4L2PixFmt();
177+ }
178 IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format);
179 DCHECK_EQ(format.fmt.pix_mp.pixelformat,
180 output_format_fourcc_->ToV4L2PixFmt());
181--
1822.17.1
183
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0108-V4L2VDA-Use-correct-size-to-allocate-CAPTURE-buffer.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0108-V4L2VDA-Use-correct-size-to-allocate-CAPTURE-buffer.patch
new file mode 100644
index 00000000..d10e7046
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0108-V4L2VDA-Use-correct-size-to-allocate-CAPTURE-buffer.patch
@@ -0,0 +1,43 @@
1From cd2caf4313d91197092dce6262a6f4b325501c04 Mon Sep 17 00:00:00 2001
2From: Hou Qi <qi.hou@nxp.com>
3Date: Sun, 4 Sep 2022 20:19:05 +0800
4Subject: [PATCH 08/17] V4L2VDA: Use correct size to allocate CAPTURE buffer
5
6Upstream-Status: Inappropriate [NXP specific]
7---
8 media/gpu/v4l2/v4l2_video_decode_accelerator.cc | 9 ++++++---
9 1 file changed, 6 insertions(+), 3 deletions(-)
10
11diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
12index 54c72c6148d94..018fe8c25f506 100644
13--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
14+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
15@@ -2189,7 +2189,10 @@ bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat(
16 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
17 size_t egl_image_planes_count;
18
19- coded_size_.SetSize(format.fmt.pix_mp.width, format.fmt.pix_mp.height);
20+ if (V4L2_TYPE_IS_MULTIPLANAR(format.type))
21+ coded_size_.SetSize(format.fmt.pix_mp.width, format.fmt.pix_mp.height);
22+ else
23+ coded_size_.SetSize(format.fmt.pix.width, format.fmt.pix.height);
24 visible_size_ = visible_size;
25 egl_image_size_ = coded_size_;
26 if (image_processor_device_) {
27@@ -2207,11 +2210,11 @@ bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat(
28 // In practice, this applies to all Image Processors, i.e. Mediatek devices.
29 DCHECK_EQ(coded_size_, output_size);
30 } else {
31- egl_image_planes_count = format.fmt.pix_mp.num_planes;
32+ egl_image_planes_count = V4L2_TYPE_IS_MULTIPLANAR(format.type) ? format.fmt.pix_mp.num_planes : 1;
33 }
34 VLOGF(2) << "new resolution: " << coded_size_.ToString()
35 << ", visible size: " << visible_size_.ToString()
36- << ", decoder output planes count: " << format.fmt.pix_mp.num_planes
37+ << ", decoder output planes count: " << egl_image_planes_count
38 << ", EGLImage size: " << egl_image_size_.ToString()
39 << ", EGLImage plane count: " << egl_image_planes_count;
40
41--
422.17.1
43
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0109-V4L2VDA-Use-correct-plane-size-and-bytesused.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0109-V4L2VDA-Use-correct-plane-size-and-bytesused.patch
new file mode 100644
index 00000000..53a1a973
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0109-V4L2VDA-Use-correct-plane-size-and-bytesused.patch
@@ -0,0 +1,65 @@
1From 0fa8f2fb83398d48f54c3462b0d1626037e0ee73 Mon Sep 17 00:00:00 2001
2From: Hou Qi <qi.hou@nxp.com>
3Date: Sun, 4 Sep 2022 20:30:31 +0800
4Subject: [PATCH 09/17] V4L2VDA: Use correct plane size and bytesused
5
6Upstream-Status: Inappropriate [NXP specific]
7---
8 media/gpu/v4l2/v4l2_device.cc | 20 ++++++++++++++++----
9 1 file changed, 16 insertions(+), 4 deletions(-)
10
11diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
12index 200b0fccb1232..726ad1ab0f144 100644
13--- a/media/gpu/v4l2/v4l2_device.cc
14+++ b/media/gpu/v4l2/v4l2_device.cc
15@@ -785,7 +785,10 @@ size_t V4L2WritableBufferRef::GetPlaneSize(const size_t plane) const {
16 return 0;
17 }
18
19- return buffer_data_->v4l2_buffer_.m.planes[plane].length;
20+ if (V4L2_TYPE_IS_MULTIPLANAR(buffer_data_->v4l2_buffer_.type))
21+ return buffer_data_->v4l2_buffer_.m.planes[plane].length;
22+ else
23+ return buffer_data_->v4l2_buffer_.length;
24 }
25
26 void V4L2WritableBufferRef::SetPlaneSize(const size_t plane,
27@@ -845,7 +848,10 @@ void V4L2WritableBufferRef::SetPlaneBytesUsed(const size_t plane,
28 return;
29 }
30
31- buffer_data_->v4l2_buffer_.m.planes[plane].bytesused = bytes_used;
32+ if (V4L2_TYPE_IS_MULTIPLANAR(buffer_data_->v4l2_buffer_.type))
33+ buffer_data_->v4l2_buffer_.m.planes[plane].bytesused = bytes_used;
34+ else
35+ buffer_data_->v4l2_buffer_.bytesused = bytes_used;
36 }
37
38 size_t V4L2WritableBufferRef::GetPlaneBytesUsed(const size_t plane) const {
39@@ -857,7 +863,10 @@ size_t V4L2WritableBufferRef::GetPlaneBytesUsed(const size_t plane) const {
40 return 0;
41 }
42
43- return buffer_data_->v4l2_buffer_.m.planes[plane].bytesused;
44+ if (V4L2_TYPE_IS_MULTIPLANAR(buffer_data_->v4l2_buffer_.type))
45+ return buffer_data_->v4l2_buffer_.m.planes[plane].bytesused;
46+ else
47+ return buffer_data_->v4l2_buffer_.bytesused;
48 }
49
50 void V4L2WritableBufferRef::SetPlaneDataOffset(const size_t plane,
51@@ -959,7 +968,10 @@ size_t V4L2ReadableBuffer::GetPlaneBytesUsed(const size_t plane) const {
52 return 0;
53 }
54
55- return buffer_data_->v4l2_planes_[plane].bytesused;
56+ if (V4L2_TYPE_IS_MULTIPLANAR(buffer_data_->v4l2_buffer_.type))
57+ return buffer_data_->v4l2_planes_[plane].bytesused;
58+ else
59+ return buffer_data_->v4l2_buffer_.bytesused;
60 }
61
62 size_t V4L2ReadableBuffer::GetPlaneDataOffset(const size_t plane) const {
63--
642.17.1
65
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0110-V4L2VDA-Add-hevc-format-support.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0110-V4L2VDA-Add-hevc-format-support.patch
new file mode 100644
index 00000000..aa4f1648
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0110-V4L2VDA-Add-hevc-format-support.patch
@@ -0,0 +1,313 @@
1From e86109fa5e05268acc3557d308e5ae12136b391a Mon Sep 17 00:00:00 2001
2From: Hou Qi <qi.hou@nxp.com>
3Date: Mon, 5 Sep 2022 10:38:53 +0800
4Subject: [PATCH 10/17] V4L2VDA: Add hevc format support
5
6Upstream-Status: Inappropriate [NXP specific]
7---
8 media/base/supported_types.cc | 2 +-
9 media/gpu/v4l2/v4l2_device.cc | 28 ++++-
10 media/gpu/v4l2/v4l2_vda_helpers.cc | 119 ++++++++++++++++++
11 media/gpu/v4l2/v4l2_vda_helpers.h | 20 +++
12 .../gpu/v4l2/v4l2_video_decode_accelerator.cc | 2 +-
13 media/media_options.gni | 4 +-
14 6 files changed, 170 insertions(+), 5 deletions(-)
15
16diff --git a/media/base/supported_types.cc b/media/base/supported_types.cc
17index 3e174b9320d08..727dc1867e6ff 100644
18--- a/media/base/supported_types.cc
19+++ b/media/base/supported_types.cc
20@@ -318,7 +318,7 @@ bool IsDefaultSupportedVideoType(const VideoType& type) {
21 case VideoCodec::kVP9:
22 return IsVp9ProfileSupported(type);
23 case VideoCodec::kHEVC:
24- return IsHevcProfileSupported(type);
25+ return true;
26 case VideoCodec::kMPEG4:
27 return IsMPEG4Supported();
28 case VideoCodec::kUnknown:
29diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
30index 726ad1ab0f144..e090cad6626f7 100644
31--- a/media/gpu/v4l2/v4l2_device.cc
32+++ b/media/gpu/v4l2/v4l2_device.cc
33@@ -1607,6 +1607,8 @@ uint32_t V4L2Device::VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile,
34 return V4L2_PIX_FMT_VP8;
35 } else if (profile >= VP9PROFILE_MIN && profile <= VP9PROFILE_MAX) {
36 return V4L2_PIX_FMT_VP9;
37+ } else if (profile >= HEVCPROFILE_MIN && profile <= HEVCPROFILE_MAX) {
38+ return V4L2_PIX_FMT_HEVC;
39 } else if (profile == HEVCPROFILE_MAIN) {
40 return V4L2_PIX_FMT_HEVC;
41 } else {
42@@ -1674,6 +1676,16 @@ VideoCodecProfile V4L2ProfileToVideoCodecProfile(VideoCodec codec,
43 return VP9PROFILE_PROFILE2;
44 }
45 break;
46+ case VideoCodec::kHEVC:
47+ switch (v4l2_profile) {
48+ case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN:
49+ return HEVCPROFILE_MAIN;
50+ case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10:
51+ return HEVCPROFILE_MAIN10;
52+ case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE:
53+ return HEVCPROFILE_MAIN_STILL_PICTURE;
54+ }
55+ break;
56 default:
57 VLOGF(2) << "Unsupported codec: " << GetCodecName(codec);
58 }
59@@ -1699,6 +1711,9 @@ std::vector<VideoCodecProfile> V4L2Device::V4L2PixFmtToVideoCodecProfiles(
60 case VideoCodec::kVP9:
61 query_id = V4L2_CID_MPEG_VIDEO_VP9_PROFILE;
62 break;
63+ case VideoCodec::kHEVC:
64+ query_id = V4L2_CID_MPEG_VIDEO_HEVC_PROFILE;
65+ break;
66 default:
67 return false;
68 }
69@@ -1757,6 +1772,17 @@ std::vector<VideoCodecProfile> V4L2Device::V4L2PixFmtToVideoCodecProfiles(
70 profiles = {VP9PROFILE_PROFILE0};
71 }
72 break;
73+ case V4L2_PIX_FMT_HEVC:
74+ if (!get_supported_profiles(VideoCodec::kHEVC, &profiles)) {
75+ DLOG(WARNING) << "Driver doesn't support QUERY HEVC profiles, "
76+ << "use default values, main, mian-10, main-still-picture";
77+ profiles = {
78+ HEVCPROFILE_MAIN,
79+ HEVCPROFILE_MAIN10,
80+ HEVCPROFILE_MAIN_STILL_PICTURE,
81+ };
82+ }
83+ break;
84 default:
85 VLOGF(1) << "Unhandled pixelformat " << FourccToString(pix_fmt);
86 return {};
87@@ -2091,7 +2117,7 @@ void V4L2Device::GetSupportedResolution(uint32_t pixelformat,
88 }
89 }
90 if (max_resolution->IsEmpty()) {
91- max_resolution->SetSize(1920, 1088);
92+ max_resolution->SetSize(4096, 4096);
93 VLOGF(1) << "GetSupportedResolution failed to get maximum resolution for "
94 << "fourcc " << FourccToString(pixelformat) << ", fall back to "
95 << max_resolution->ToString();
96diff --git a/media/gpu/v4l2/v4l2_vda_helpers.cc b/media/gpu/v4l2/v4l2_vda_helpers.cc
97index f25619077035c..5fa8593a5cf1e 100644
98--- a/media/gpu/v4l2/v4l2_vda_helpers.cc
99+++ b/media/gpu/v4l2/v4l2_vda_helpers.cc
100@@ -12,6 +12,7 @@
101 #include "media/gpu/v4l2/v4l2_device.h"
102 #include "media/gpu/v4l2/v4l2_image_processor_backend.h"
103 #include "media/video/h264_parser.h"
104+#include "media/video/h265_parser.h"
105
106 namespace media {
107 namespace v4l2_vda_helpers {
108@@ -155,6 +156,9 @@ InputBufferFragmentSplitter::CreateFromProfile(
109 case VideoCodec::kVP9:
110 // VP8/VP9 don't need any frame splitting, use the default implementation.
111 return std::make_unique<v4l2_vda_helpers::InputBufferFragmentSplitter>();
112+ case VideoCodec::kHEVC:
113+ return std::make_unique<
114+ v4l2_vda_helpers::H265InputBufferFragmentSplitter>();
115 default:
116 LOG(ERROR) << "Unhandled profile: " << profile;
117 return nullptr;
118@@ -274,5 +278,120 @@ bool H264InputBufferFragmentSplitter::IsPartialFramePending() const {
119 return partial_frame_pending_;
120 }
121
122+H265InputBufferFragmentSplitter::H265InputBufferFragmentSplitter()
123+ : h265_parser_(new H265Parser()) {}
124+
125+H265InputBufferFragmentSplitter::~H265InputBufferFragmentSplitter() = default;
126+
127+bool H265InputBufferFragmentSplitter::AdvanceFrameFragment(const uint8_t* data,
128+ size_t size,
129+ size_t* endpos) {
130+ DCHECK(h265_parser_);
131+
132+ // For H265, we need to feed HW one frame at a time. This is going to take
133+ // some parsing of our input stream.
134+ h265_parser_->SetStream(data, size);
135+ H265NALU nalu;
136+ H265Parser::Result result;
137+ bool has_frame_data = false;
138+ *endpos = 0;
139+ DVLOGF(4) << "H265InputBufferFragmentSplitter::AdvanceFrameFragment size" << size;
140+ // Keep on peeking the next NALs while they don't indicate a frame
141+ // boundary.
142+ while (true) {
143+ bool end_of_frame = false;
144+ result = h265_parser_->AdvanceToNextNALU(&nalu);
145+ if (result == H265Parser::kInvalidStream ||
146+ result == H265Parser::kUnsupportedStream) {
147+ return false;
148+ }
149+
150+ DVLOGF(4) << "NALU type " << nalu.nal_unit_type << "NALU size" << nalu.size;
151+ if (result == H265Parser::kEOStream) {
152+ // We've reached the end of the buffer before finding a frame boundary.
153+ if (has_frame_data){
154+ // partial_frame_pending_ = true;
155+ // DVLOGF(4)<<"partial_frame_pending_ true as H265Parser::kEOStream has_frame_data";
156+ }
157+ *endpos = size;
158+ DVLOGF(4)<< " MET kEOStream endpos " << *endpos <<" nalu.size " << nalu.size;
159+ return true;
160+ }
161+ switch (nalu.nal_unit_type) {
162+ case H265NALU::TRAIL_N:
163+ case H265NALU::TRAIL_R:
164+ case H265NALU::TSA_N:
165+ case H265NALU::TSA_R:
166+ case H265NALU::STSA_N:
167+ case H265NALU::STSA_R:
168+ case H265NALU::RADL_R:
169+ case H265NALU::RADL_N:
170+ case H265NALU::RASL_N:
171+ case H265NALU::RASL_R:
172+ case H265NALU::BLA_W_LP:
173+ case H265NALU::BLA_W_RADL:
174+ case H265NALU::BLA_N_LP:
175+ case H265NALU::IDR_W_RADL:
176+ case H265NALU::IDR_N_LP:
177+ case H265NALU::CRA_NUT:
178+ if (nalu.size < 1)
179+ return false;
180+
181+ has_frame_data = true;
182+
183+ // For these two, if the "first_mb_in_slice" field is zero, start a
184+ // new frame and return. This field is Exp-Golomb coded starting on
185+ // the eighth data bit of the NAL; a zero value is encoded with a
186+ // leading '1' bit in the byte, which we can detect as the byte being
187+ // (unsigned) greater than or equal to 0x80.
188+ if (nalu.data[1] >= 0x80) {
189+ end_of_frame = true;
190+ break;
191+ }
192+ break;
193+ case H265NALU::VPS_NUT:
194+ case H265NALU::SPS_NUT:
195+ case H265NALU::PPS_NUT:
196+ case H265NALU::AUD_NUT:
197+ case H265NALU::EOS_NUT:
198+ case H265NALU::EOB_NUT:
199+ case H265NALU::FD_NUT:
200+ case H265NALU::PREFIX_SEI_NUT:
201+ case H265NALU::SUFFIX_SEI_NUT:
202+ // These unconditionally signal a frame boundary.
203+ end_of_frame = true;
204+ break;
205+ default:
206+ // For all others, keep going.
207+ break;
208+ }
209+ if (end_of_frame) {
210+ if (!partial_frame_pending_ && *endpos == 0) {
211+ // The frame was previously restarted, and we haven't filled the
212+ // current frame with any contents yet. Start the new frame here and
213+ // continue parsing NALs.
214+ } else {
215+ // The frame wasn't previously restarted and/or we have contents for
216+ // the current frame; signal the start of a new frame here: we don't
217+ // have a partial frame anymore.
218+ partial_frame_pending_ = false;
219+ // return true;
220+ }
221+ }
222+ *endpos = (nalu.data + nalu.size) - data;
223+ }
224+ NOTREACHED();
225+ return false;
226+}
227+
228+void H265InputBufferFragmentSplitter::Reset() {
229+ partial_frame_pending_ = false;
230+ h265_parser_.reset(new H265Parser());
231+}
232+
233+bool H265InputBufferFragmentSplitter::IsPartialFramePending() const {
234+ return partial_frame_pending_;
235+}
236+
237 } // namespace v4l2_vda_helpers
238 } // namespace media
239diff --git a/media/gpu/v4l2/v4l2_vda_helpers.h b/media/gpu/v4l2/v4l2_vda_helpers.h
240index ebd07cf7e5b37..4b7fbd2985473 100644
241--- a/media/gpu/v4l2/v4l2_vda_helpers.h
242+++ b/media/gpu/v4l2/v4l2_vda_helpers.h
243@@ -18,6 +18,7 @@ namespace media {
244
245 class V4L2Device;
246 class H264Parser;
247+class H265Parser;
248
249 // Helper static methods to be shared between V4L2VideoDecodeAccelerator and
250 // V4L2SliceVideoDecodeAccelerator. This avoids some code duplication between
251@@ -115,6 +116,25 @@ class H264InputBufferFragmentSplitter : public InputBufferFragmentSplitter {
252 bool partial_frame_pending_ = false;
253 };
254
255+class H265InputBufferFragmentSplitter : public InputBufferFragmentSplitter {
256+ public:
257+ explicit H265InputBufferFragmentSplitter();
258+ ~H265InputBufferFragmentSplitter() override;
259+
260+ bool AdvanceFrameFragment(const uint8_t* data,
261+ size_t size,
262+ size_t* endpos) override;
263+ void Reset() override;
264+ bool IsPartialFramePending() const override;
265+
266+ private:
267+ // For H264 decode, hardware requires that we send it frame-sized chunks.
268+ // We'll need to parse the stream.
269+ std::unique_ptr<H265Parser> h265_parser_;
270+ // Set if we have a pending incomplete frame in the input buffer.
271+ bool partial_frame_pending_ = false;
272+};
273+
274 } // namespace v4l2_vda_helpers
275 } // namespace media
276
277diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
278index 018fe8c25f506..c00cd2b5f6ad7 100644
279--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
280+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
281@@ -84,7 +84,7 @@ bool IsVp9KSVCStream(uint32_t input_format_fourcc,
282
283 // static
284 const uint32_t V4L2VideoDecodeAccelerator::supported_input_fourccs_[] = {
285- V4L2_PIX_FMT_H264, V4L2_PIX_FMT_VP8, V4L2_PIX_FMT_VP9,
286+ V4L2_PIX_FMT_H264, V4L2_PIX_FMT_VP8, V4L2_PIX_FMT_VP9, V4L2_PIX_FMT_HEVC,
287 };
288
289 // static
290diff --git a/media/media_options.gni b/media/media_options.gni
291index 1b2af27c5079d..0da73f1f81407 100644
292--- a/media/media_options.gni
293+++ b/media/media_options.gni
294@@ -92,14 +92,14 @@ declare_args() {
295 # video on ChromeOS and Windows.
296 enable_platform_hevc =
297 proprietary_codecs &&
298- (is_chromecast || use_fuzzing_engine || enable_platform_encrypted_hevc)
299+ (is_chromecast || use_fuzzing_engine || enable_platform_encrypted_hevc || use_v4l2_codec)
300
301 # Enable HEVC/H265 decoding with hardware acceleration assist. Enabled by
302 # default for fuzzer builds and protected video on ChromeOS. It is also
303 # enabled for Chromecast by default so the unit tests get run in Chrome CQ.
304 enable_platform_hevc_decoding =
305 proprietary_codecs &&
306- (is_chromecast || use_fuzzing_engine || use_chromeos_protected_media)
307+ (is_chromecast || use_fuzzing_engine || use_chromeos_protected_media || use_v4l2_codec)
308 }
309
310 assert(
311--
3122.17.1
313
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0111-V4L2VDA-fix-vp9-crash-caused-by-DequeueResolutionCha.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0111-V4L2VDA-fix-vp9-crash-caused-by-DequeueResolutionCha.patch
new file mode 100644
index 00000000..bf78e1fe
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0111-V4L2VDA-fix-vp9-crash-caused-by-DequeueResolutionCha.patch
@@ -0,0 +1,31 @@
1From 46217b35c7ec0a84175882acb4e8c363975d5701 Mon Sep 17 00:00:00 2001
2From: Hou Qi <qi.hou@nxp.com>
3Date: Thu, 18 Aug 2022 12:20:33 +0800
4Subject: [PATCH 11/17] V4L2VDA: fix vp9 crash caused by
5 DequeueResolutionChangeEvent
6
7Handle source change event only when decoder receives driver reported
8source change event.
9
10Upstream-Status: Inappropriate [NXP specific]
11---
12 media/gpu/v4l2/v4l2_video_decode_accelerator.cc | 3 +--
13 1 file changed, 1 insertion(+), 2 deletions(-)
14
15diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
16index c00cd2b5f6ad7..ff543f6865802 100644
17--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
18+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
19@@ -1247,8 +1247,7 @@ void V4L2VideoDecodeAccelerator::ServiceDeviceTask(bool event_pending) {
20 gfx::Size visible_size;
21 bool again;
22 if (GetFormatInfo(&format, &visible_size, &again) && !again) {
23- resolution_change_pending = true;
24- DequeueResolutionChangeEvent();
25+ resolution_change_pending = DequeueResolutionChangeEvent();
26 }
27 }
28
29--
302.17.1
31
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0112-V4L2VDA-Add-fps-in-SkiaOutputSurfaceImplOnGpu-by-VLO.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0112-V4L2VDA-Add-fps-in-SkiaOutputSurfaceImplOnGpu-by-VLO.patch
new file mode 100644
index 00000000..78be7a25
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0112-V4L2VDA-Add-fps-in-SkiaOutputSurfaceImplOnGpu-by-VLO.patch
@@ -0,0 +1,88 @@
1From a49818e6727dc3ec25e438b032b761e668542886 Mon Sep 17 00:00:00 2001
2From: Hou Qi <qi.hou@nxp.com>
3Date: Thu, 18 Aug 2022 12:22:20 +0800
4Subject: [PATCH 12/17] V4L2VDA: Add fps in SkiaOutputSurfaceImplOnGpu by
5 VLOG(1)
6
7Upstream-Status: Inappropriate [NXP specific]
8---
9 .../skia_output_surface_impl_on_gpu.cc | 18 ++++++++++++++++++
10 .../skia_output_surface_impl_on_gpu.h | 1 +
11 2 files changed, 19 insertions(+)
12
13diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
14index 946f4f40aaa08..8a05a8c41bd05 100644
15--- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
16+++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
17@@ -6,6 +6,7 @@
18
19 #include <memory>
20 #include <vector>
21+#include <sys/time.h>
22
23 #include "base/atomic_sequence_num.h"
24 #include "base/bind.h"
25@@ -104,6 +105,15 @@
26 #include "components/viz/service/display_embedder/output_presenter_fuchsia.h"
27 #endif
28
29+static uint64_t start_time = 0;
30+static uint64_t stop_time = 0;
31+
32+uint64_t NowMicros() {
33+ struct timeval tv;
34+ gettimeofday(&tv, nullptr);
35+ return static_cast<uint64_t>(tv.tv_sec) * 1e6 + tv.tv_usec;
36+}
37+
38 namespace viz {
39
40 namespace {
41@@ -320,6 +330,7 @@ SkiaOutputSurfaceImplOnGpu::SkiaOutputSurfaceImplOnGpu(
42 async_read_result_lock_(base::MakeRefCounted<AsyncReadResultLock>()) {
43 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
44
45+ swap_buffers_number_ = 0;
46 weak_ptr_ = weak_ptr_factory_.GetWeakPtr();
47 buffer_presented_callback_ = CreateSafeRepeatingCallback(
48 weak_ptr_, std::move(buffer_presented_callback));
49@@ -500,10 +511,16 @@ void SkiaOutputSurfaceImplOnGpu::SwapBuffers(OutputSurfaceFrame frame,
50 TRACE_EVENT0("viz", "SkiaOutputSurfaceImplOnGpu::SwapBuffers");
51 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
52
53+ if ( swap_buffers_number_ == 0)
54+ start_time = NowMicros();
55 if (release_frame_buffer)
56 output_device_->ReleaseOneFrameBuffer();
57
58+ swap_buffers_number_++;
59+ stop_time = NowMicros();
60+
61 SwapBuffersInternal(std::move(frame));
62+ VLOG(1) << "total showed " << swap_buffers_number_ << " frames, total time " << (stop_time - start_time) << " ms, fps is " << swap_buffers_number_*1e6/(stop_time - start_time) << std::endl;
63 }
64
65 void SkiaOutputSurfaceImplOnGpu::AllocateFrameBuffers(size_t n) {
66@@ -1525,6 +1542,7 @@ bool SkiaOutputSurfaceImplOnGpu::Initialize() {
67 if (context_state_)
68 context_state_->AddContextLostObserver(this);
69
70+ start_time = NowMicros();
71 return true;
72 }
73
74diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
75index febdaebbb740c..be1cedf2babc9 100644
76--- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
77+++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
78@@ -423,6 +423,7 @@ class SkiaOutputSurfaceImplOnGpu
79 BufferPresentedCallback buffer_presented_callback_;
80 ContextLostCallback context_lost_callback_;
81 GpuVSyncCallback gpu_vsync_callback_;
82+ size_t swap_buffers_number_;
83
84 // ImplOnGpu::CopyOutput can create SharedImages via ImplOnGpu's
85 // SharedImageFactory. Clients can use these images via CopyOutputResult and
86--
872.17.1
88
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0113-V4L2VDA-Comment-some-unused-ioctl.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0113-V4L2VDA-Comment-some-unused-ioctl.patch
new file mode 100644
index 00000000..d587b835
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0113-V4L2VDA-Comment-some-unused-ioctl.patch
@@ -0,0 +1,108 @@
1From 1cae59ad534e9f10f27de3d92e828be5968f1632 Mon Sep 17 00:00:00 2001
2From: Hou Qi <qi.hou@nxp.com>
3Date: Mon, 5 Sep 2022 12:11:36 +0800
4Subject: [PATCH 13/17] V4L2VDA: Comment some unused ioctl
5
6Upstream-Status: Inappropriate [NXP specific]
7---
8 media/gpu/v4l2/v4l2_device.cc | 22 ++++++++++++++++++++++
9 1 file changed, 22 insertions(+)
10
11diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
12index e090cad6626f7..5a1057c845e85 100644
13--- a/media/gpu/v4l2/v4l2_device.cc
14+++ b/media/gpu/v4l2/v4l2_device.cc
15@@ -1041,10 +1041,12 @@ V4L2Queue::V4L2Queue(scoped_refptr<V4L2Device> dev,
16 return;
17 }
18
19+#if !BUILDFLAG(USE_LINUX_V4L2)
20 if (reqbufs.capabilities & V4L2_BUF_CAP_SUPPORTS_REQUESTS) {
21 supports_requests_ = true;
22 DVLOGF(4) << "Queue supports request API.";
23 }
24+#endif
25 }
26
27 V4L2Queue::~V4L2Queue() {
28@@ -2482,10 +2484,14 @@ bool V4L2Request::ApplyCtrls(struct v4l2_ext_controls* ctrls) {
29 return false;
30 }
31
32+#if !BUILDFLAG(USE_LINUX_V4L2)
33 ctrls->which = V4L2_CTRL_WHICH_REQUEST_VAL;
34 ctrls->request_fd = request_fd_.get();
35
36 return true;
37+#else
38+ return false;
39+#endif
40 }
41
42 bool V4L2Request::ApplyQueueBuffer(struct v4l2_buffer* buffer) {
43@@ -2497,10 +2503,14 @@ bool V4L2Request::ApplyQueueBuffer(struct v4l2_buffer* buffer) {
44 return false;
45 }
46
47+#if !BUILDFLAG(USE_LINUX_V4L2)
48 buffer->flags |= V4L2_BUF_FLAG_REQUEST_FD;
49 buffer->request_fd = request_fd_.get();
50
51 return true;
52+#else
53+ return false;
54+#endif
55 }
56
57 bool V4L2Request::Submit() {
58@@ -2511,7 +2521,11 @@ bool V4L2Request::Submit() {
59 return false;
60 }
61
62+#if !BUILDFLAG(USE_LINUX_V4L2)
63 return HANDLE_EINTR(ioctl(request_fd_.get(), MEDIA_REQUEST_IOC_QUEUE)) == 0;
64+#else
65+ return false;
66+#endif
67 }
68
69 bool V4L2Request::IsCompleted() {
70@@ -2554,6 +2568,7 @@ bool V4L2Request::Reset() {
71 return false;
72 }
73
74+#if !BUILDFLAG(USE_LINUX_V4L2)
75 // Reinit the request to make sure we can use it for a new submission.
76 if (HANDLE_EINTR(ioctl(request_fd_.get(), MEDIA_REQUEST_IOC_REINIT)) < 0) {
77 VPLOGF(1) << "Failed to reinit request.";
78@@ -2561,6 +2576,9 @@ bool V4L2Request::Reset() {
79 }
80
81 return true;
82+#else
83+ return false;
84+#endif
85 }
86
87 V4L2RequestRefBase::V4L2RequestRefBase(V4L2RequestRefBase&& req_base) {
88@@ -2635,6 +2653,7 @@ V4L2RequestsQueue::~V4L2RequestsQueue() {
89 absl::optional<base::ScopedFD> V4L2RequestsQueue::CreateRequestFD() {
90 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
91
92+#if !BUILDFLAG(USE_LINUX_V4L2)
93 int request_fd;
94 int ret = HANDLE_EINTR(
95 ioctl(media_fd_.get(), MEDIA_IOC_REQUEST_ALLOC, &request_fd));
96@@ -2644,6 +2663,9 @@ absl::optional<base::ScopedFD> V4L2RequestsQueue::CreateRequestFD() {
97 }
98
99 return base::ScopedFD(request_fd);
100+#else
101+ return absl::nullopt;
102+#endif
103 }
104
105 absl::optional<V4L2RequestRef> V4L2RequestsQueue::GetFreeRequest() {
106--
1072.17.1
108
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0114-V4L2VDA-Set-OUTPUT-format-with-parsed-resolution-for.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0114-V4L2VDA-Set-OUTPUT-format-with-parsed-resolution-for.patch
new file mode 100644
index 00000000..6bde73d6
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0114-V4L2VDA-Set-OUTPUT-format-with-parsed-resolution-for.patch
@@ -0,0 +1,76 @@
1From b37891b75a53061ce6bdaaab926c2b630f6c1a61 Mon Sep 17 00:00:00 2001
2From: Hou Qi <qi.hou@nxp.com>
3Date: Mon, 5 Sep 2022 12:23:04 +0800
4Subject: [PATCH 14/17] V4L2VDA: Set OUTPUT format with parsed resolution for
5 amphion
6
7For VP8, VC1l, rv, Amphion needs to set correct resolution for OUTPUT
8queue as it will be added to amphion customized header.
9
10Upstream-Status: Inappropriate [NXP specific]
11---
12 media/gpu/v4l2/v4l2_video_decode_accelerator.cc | 13 +++++++++++--
13 media/gpu/v4l2/v4l2_video_decode_accelerator.h | 2 +-
14 2 files changed, 12 insertions(+), 3 deletions(-)
15
16diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
17index ff543f6865802..fba38c4021855 100644
18--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
19+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
20@@ -320,6 +320,9 @@ bool V4L2VideoDecodeAccelerator::CheckConfig(const Config& config) {
21 return false;
22 }
23
24+ int width, height;
25+ height = config.initial_expected_coded_size.height();
26+ width = config.initial_expected_coded_size.width();
27 // Capabilities check.
28 struct v4l2_capability caps;
29 unsigned int device_caps;
30@@ -357,7 +360,7 @@ bool V4L2VideoDecodeAccelerator::CheckConfig(const Config& config) {
31 if (!output_queue_)
32 return false;
33
34- if (!SetupFormats())
35+ if (!SetupFormats(width, height))
36 return false;
37
38 // We have confirmed that |config| is supported, tell the good news to the
39@@ -2266,7 +2269,7 @@ bool V4L2VideoDecodeAccelerator::CreateInputBuffers() {
40 return true;
41 }
42
43-bool V4L2VideoDecodeAccelerator::SetupFormats() {
44+bool V4L2VideoDecodeAccelerator::SetupFormats(int width, int height) {
45 DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
46 DCHECK_EQ(decoder_state_, kInitialized);
47 DCHECK(!input_queue_->IsStreaming());
48@@ -2306,6 +2309,12 @@ bool V4L2VideoDecodeAccelerator::SetupFormats() {
49 format.fmt.pix_mp.pixelformat = input_format_fourcc_;
50 format.fmt.pix_mp.plane_fmt[0].sizeimage = input_size;
51 format.fmt.pix_mp.num_planes = 1;
52+ // For VP8, VC1l, rv, Amphion needs to set correct resolution for
53+ // OUTPUT queue as it will be added to amphion customized header.
54+ if(V4L2_PIX_FMT_VP8 == input_format_fourcc_){
55+ format.fmt.pix_mp.width = width;
56+ format.fmt.pix_mp.height = height;
57+ }
58 } else {
59 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
60 format.fmt.pix.pixelformat = input_format_fourcc_;
61diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.h b/media/gpu/v4l2/v4l2_video_decode_accelerator.h
62index 163907129a095..d16ee5857785b 100644
63--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.h
64+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.h
65@@ -395,7 +395,7 @@ class MEDIA_GPU_EXPORT V4L2VideoDecodeAccelerator
66 bool DestroyOutputBuffers();
67
68 // Set input and output formats before starting decode.
69- bool SetupFormats();
70+ bool SetupFormats(int, int);
71 // Reset image processor and drop all processing frames.
72 bool ResetImageProcessor();
73
74--
752.17.1
76
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0115-V4L2VDA-Add-V4L2_PIX_FMT_NV12M_8L128-format-for-amph.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0115-V4L2VDA-Add-V4L2_PIX_FMT_NV12M_8L128-format-for-amph.patch
new file mode 100644
index 00000000..e9afc8e6
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0115-V4L2VDA-Add-V4L2_PIX_FMT_NV12M_8L128-format-for-amph.patch
@@ -0,0 +1,101 @@
1From 4a3c50348edb021d0529d350aabcd78cc0c75164 Mon Sep 17 00:00:00 2001
2From: Hou Qi <qi.hou@nxp.com>
3Date: Fri, 9 Sep 2022 10:06:51 +0800
4Subject: [PATCH 15/17] V4L2VDA: Add V4L2_PIX_FMT_NV12M_8L128 format for
5 amphion
6
7Upstream-Status: Inappropriate [NXP specific]
8---
9 media/gpu/chromeos/fourcc.cc | 2 ++
10 media/gpu/chromeos/fourcc.h | 4 ++++
11 media/gpu/v4l2/generic_v4l2_device.cc | 4 ++++
12 media/gpu/v4l2/v4l2_video_decode_accelerator.cc | 9 +++++++--
13 4 files changed, 17 insertions(+), 2 deletions(-)
14
15diff --git a/media/gpu/chromeos/fourcc.cc b/media/gpu/chromeos/fourcc.cc
16index 80f392ebf5e41..e8239121d8e96 100644
17--- a/media/gpu/chromeos/fourcc.cc
18+++ b/media/gpu/chromeos/fourcc.cc
19@@ -26,6 +26,7 @@ absl::optional<Fourcc> Fourcc::FromUint32(uint32_t fourcc) {
20 case YM12:
21 case YM21:
22 case YUYV:
23+ case NA12:
24 case NV12:
25 case NV21:
26 case NM12:
27@@ -149,6 +150,7 @@ VideoPixelFormat Fourcc::ToVideoPixelFormat() const {
28 return PIXEL_FORMAT_YUY2;
29 case NV12:
30 case NM12:
31+ case NA12:
32 return PIXEL_FORMAT_NV12;
33 case NV21:
34 case NM21:
35diff --git a/media/gpu/chromeos/fourcc.h b/media/gpu/chromeos/fourcc.h
36index c4b233ac64562..27f1b679435b1 100644
37--- a/media/gpu/chromeos/fourcc.h
38+++ b/media/gpu/chromeos/fourcc.h
39@@ -68,6 +68,10 @@ class MEDIA_GPU_EXPORT Fourcc {
40 // Maps to PIXEL_FORMAT_NV21, V4L2_PIX_FMT_NV21M.
41 NM21 = ComposeFourcc('N', 'M', '2', '1'),
42
43+ // Tiled YUV formats, non contiguous planes.
44+ // Maps to V4L2_PIX_FMT_NV12M_8L128.
45+ NA12 = ComposeFourcc('N', 'A', '1', '2'),
46+
47 // YUV422 single-planar format.
48 // https://linuxtv.org/downloads/v4l-dvb-apis-new/userspace-api/v4l/pixfmt-yuv422p.html
49 // Maps to PIXEL_FORMAT_I422, V4L2_PIX_FMT_YUV422P.
50diff --git a/media/gpu/v4l2/generic_v4l2_device.cc b/media/gpu/v4l2/generic_v4l2_device.cc
51index a578768f8d3b1..d7b57d180f7f7 100644
52--- a/media/gpu/v4l2/generic_v4l2_device.cc
53+++ b/media/gpu/v4l2/generic_v4l2_device.cc
54@@ -46,6 +46,9 @@ using media_gpu_v4l2::InitializeStubs;
55 using media_gpu_v4l2::StubPathMap;
56 #endif
57
58+/* Tiled YUV formats, non contiguous planes */
59+#define V4L2_PIX_FMT_NV12M_8L128 v4l2_fourcc('N', 'A', '1', '2') /* Y/CbCr 4:2:0 8x128 tiles */
60+
61 namespace media {
62
63 namespace {
64@@ -54,6 +57,7 @@ uint32_t V4L2PixFmtToDrmFormat(uint32_t format) {
65 switch (format) {
66 case V4L2_PIX_FMT_NV12:
67 case V4L2_PIX_FMT_NV12M:
68+ case V4L2_PIX_FMT_NV12M_8L128:
69 return DRM_FORMAT_NV12;
70
71 case V4L2_PIX_FMT_YUV420:
72diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
73index fba38c4021855..a37efa9a708e8 100644
74--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
75+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.cc
76@@ -1356,8 +1356,9 @@ void V4L2VideoDecodeAccelerator::Enqueue() {
77 // yet. Also, V4L2VDA calls STREAMOFF and STREAMON after resolution
78 // change. They implicitly send a V4L2_DEC_CMD_STOP and V4L2_DEC_CMD_START
79 // to the decoder.
80- if (input_queue_->QueuedBuffersCount() > 0)
81- break;
82+ if (input_queue_->QueuedBuffersCount() > 0) {
83+ // break;
84+ }
85
86 if (coded_size_.IsEmpty() || !input_queue_->IsStreaming()) {
87 // In these situations, we should call NotifyFlushDone() immediately:
88@@ -1499,6 +1500,10 @@ bool V4L2VideoDecodeAccelerator::DequeueOutputBuffer() {
89 // Dequeue a completed output (VIDEO_CAPTURE) buffer, and queue to the
90 // completed queue.
91 auto ret = output_queue_->DequeueBuffer();
92+ if (errno == EPIPE) {
93+ VLOG(1) << "Got eos";
94+ flush_awaiting_last_output_buffer_ = false;
95+ }
96 if (ret.first == false) {
97 LOG(ERROR) << "Error in Dequeue output buffer";
98 NOTIFY_ERROR(PLATFORM_FAILURE);
99--
1002.17.1
101
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
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0117-V4L2VDA-Enlarge-input-buffer-count-to-16.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0117-V4L2VDA-Enlarge-input-buffer-count-to-16.patch
new file mode 100644
index 00000000..7d962d69
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0117-V4L2VDA-Enlarge-input-buffer-count-to-16.patch
@@ -0,0 +1,29 @@
1From cce8813b76367550ca0a934481ff9263afc09698 Mon Sep 17 00:00:00 2001
2From: Hou Qi <qi.hou@nxp.com>
3Date: Thu, 15 Sep 2022 18:12:55 +0800
4Subject: [PATCH 17/17] V4L2VDA: Enlarge input buffer count to 16
5
6Some stream can decode one frame only after queuing over 8 buffers.
7So enlarge input buffer count to 16 to avoid such stream cannot play.
8
9Upstream-Status: Inappropriate [NXP specific]
10---
11 media/gpu/v4l2/v4l2_video_decode_accelerator.h | 2 +-
12 1 file changed, 1 insertion(+), 1 deletion(-)
13
14diff --git a/media/gpu/v4l2/v4l2_video_decode_accelerator.h b/media/gpu/v4l2/v4l2_video_decode_accelerator.h
15index d16ee5857785b..5724a972ce4f3 100644
16--- a/media/gpu/v4l2/v4l2_video_decode_accelerator.h
17+++ b/media/gpu/v4l2/v4l2_video_decode_accelerator.h
18@@ -145,7 +145,7 @@ class MEDIA_GPU_EXPORT V4L2VideoDecodeAccelerator
19 private:
20 // These are rather subjectively tuned.
21 enum {
22- kInputBufferCount = 8,
23+ kInputBufferCount = 16,
24 // TODO(posciak): determine input buffer size based on level limits.
25 // See http://crbug.com/255116.
26 // Input bitstream buffer size for up to 1080p streams.
27--
282.17.1
29
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0118-V4L2VDA-Use-dlopen-to-dynamically-use-g2d-api.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0118-V4L2VDA-Use-dlopen-to-dynamically-use-g2d-api.patch
new file mode 100644
index 00000000..7cd0b852
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0118-V4L2VDA-Use-dlopen-to-dynamically-use-g2d-api.patch
@@ -0,0 +1,306 @@
1From 59bf28174104b591088a08e2ed61644cc93101fd Mon Sep 17 00:00:00 2001
2From: Hou Qi <qi.hou@nxp.com>
3Date: Thu, 22 Sep 2022 11:10:46 +0800
4Subject: [PATCH] V4L2VDA: Use dlopen to dynamically use g2d api
5
6Upstream-Status: Inappropriate [NXP specific]
7---
8 media/gpu/v4l2/BUILD.gn | 1 -
9 media/gpu/v4l2/v4l2_device.cc | 205 ++++++++++++++++++++++++++++++++--
10 2 files changed, 194 insertions(+), 12 deletions(-)
11
12diff --git a/media/gpu/v4l2/BUILD.gn b/media/gpu/v4l2/BUILD.gn
13index 273f6066de175..ebd0a4ad64646 100644
14--- a/media/gpu/v4l2/BUILD.gn
15+++ b/media/gpu/v4l2/BUILD.gn
16@@ -86,7 +86,6 @@ source_set("v4l2") {
17 "EGL",
18 "GLESv2",
19 ]
20- libs += [ "g2d" ]
21
22 if (use_v4l2_codec_aml) {
23 sources += [
24diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
25index 42cd8386f41cb..af71f54d141aa 100644
26--- a/media/gpu/v4l2/v4l2_device.cc
27+++ b/media/gpu/v4l2/v4l2_device.cc
28@@ -40,10 +40,12 @@
29 #include "media/gpu/v4l2/aml_v4l2_device.h"
30 #endif
31
32-#include "g2d.h"
33-#include "g2dExt.h"
34+// #include "g2d.h"
35+// #include "g2dExt.h"
36+
37 #include <linux/dma-buf.h>
38 #include <time.h>
39+#include <dlfcn.h>
40
41 namespace media {
42
43@@ -142,6 +144,158 @@ void V4L2ProcessingTrace(const struct v4l2_buffer* v4l2_buffer, bool start) {
44
45 } // namespace
46
47+/* g2d.h g2dExt.h */
48+enum g2d_format
49+{
50+//rgb formats
51+ G2D_RGB565 = 0, /* [0:4] Blue; [5:10] Green; [11:15] Red */
52+ G2D_RGBA8888 = 1, /* [0:7] Red; [8:15] Green; [16:23] Blue; [23:31] Alpha */
53+ G2D_RGBX8888 = 2, /* [0:7] Red; [8:15] Green; [16:23] Blue; [23:31] don't care */
54+ G2D_BGRA8888 = 3, /* [0:7] Blue; [8:15] Green; [16:23] Red; [23:31] Alpha */
55+ G2D_BGRX8888 = 4, /* [0:7] Blue; [8:15] Green; [16:23] Red; [23:31] don't care */
56+ G2D_BGR565 = 5, /* [0:4] Red; [5:10] Green; [11:15] Blue */
57+
58+ G2D_ARGB8888 = 6, /* [0:7] Alpha; [8:15] Red; [16:23] Green; [23:31] Blue */
59+ G2D_ABGR8888 = 7, /* [0:7] Alpha; [8:15] Blue; [16:23] Green; [23:31] Red */
60+ G2D_XRGB8888 = 8, /* [0:7] don't care; [8:15] Red; [16:23] Green; [23:31] Blue */
61+ G2D_XBGR8888 = 9, /* [0:7] don't care; [8:15] Blue; [16:23] Green; [23:31] Red */
62+ G2D_RGB888 = 10, /* [0:7] Red; [8:15] Green; [16:23] Blue */
63+ G2D_BGR888 = 11, /* [0:7] Blue; [8:15] Green; [16:23] Red */
64+
65+ G2D_RGBA5551 = 12, /* [0:4] Red; [5:9] Green; [10:14] Blue; [15] Alpha */
66+ G2D_RGBX5551 = 13, /* [0:4] Red; [5:9] Green; [10:14] Blue; [15] don't care */
67+ G2D_BGRA5551 = 14, /* [0:4] Blue; [5:9] Green; [10:14] Red; [15] Alpha */
68+ G2D_BGRX5551 = 15, /* [0:4] Blue; [5:9] Green; [10:14] Red; [15] don't care */
69+
70+//yuv formats
71+ G2D_NV12 = 20, /* 2 plane 420 format; plane 1: [0:7] Y ; plane 2: [0:7] U; [8:15] V */
72+ G2D_I420 = 21, /* 3 plane 420 format; plane 1: [0:7] Y ; plane 2: [0:7] U; plane 3: [0:7] V */
73+ G2D_YV12 = 22, /* 3 plane 420 format; plane 1: [0:7] Y ; plane 2: [0:7] V; plane 3: [0:7] U */
74+ G2D_NV21 = 23, /* 2 plane 420 format; plane 1: [0:7] Y ; plane 2: [0:7] V; [8:15] U */
75+ G2D_YUYV = 24, /* 1 plane 422 format; [0:7] Y; [8:15; U; [16:23] Y; [24:31] V */
76+ G2D_YVYU = 25, /* 1 plane 422 format; [0:7] Y; [8:15; V; [16:23] Y; [24:31] U */
77+ G2D_UYVY = 26, /* 1 plane 422 format; [0:7] U; [8:15; Y; [16:23] V; [24:31] Y */
78+ G2D_VYUY = 27, /* 1 plane 422 format; [0:7] V; [8:15; Y; [16:23] U; [24:31] Y */
79+ G2D_NV16 = 28, /* 2 plane 422 format; plane 1: [0:7] Y ; plane 2: [0:7] U; [8:15] V */
80+ G2D_NV61 = 29, /* 2 plane 422 format; plane 1: [0:7] Y ; plane 2: [0:7] V; [8:15] U */
81+};
82+
83+enum g2d_tiling
84+{
85+ G2D_LINEAR = 0x1,
86+ G2D_TILED = 0x2,
87+ G2D_SUPERTILED = 0x4,
88+ G2D_AMPHION_TILED = 0x8,
89+ G2D_AMPHION_INTERLACED = 0x10,
90+ G2D_TILED_STATUS = 0x20,
91+ G2D_AMPHION_TILED_10BIT = 0x40,
92+};
93+
94+struct g2d_tile_status
95+{
96+ unsigned int ts_addr;
97+
98+ unsigned int fc_enabled;
99+ unsigned int fc_value;
100+ unsigned int fc_value_upper;
101+};
102+
103+struct g2d_buf
104+{
105+ void *buf_handle;
106+ void *buf_vaddr;
107+ int buf_paddr;
108+ int buf_size;
109+};
110+
111+enum g2d_blend_func
112+{
113+//basic blend
114+ G2D_ZERO = 0,
115+ G2D_ONE = 1,
116+ G2D_SRC_ALPHA = 2,
117+ G2D_ONE_MINUS_SRC_ALPHA = 3,
118+ G2D_DST_ALPHA = 4,
119+ G2D_ONE_MINUS_DST_ALPHA = 5,
120+
121+// extensive blend is set with basic blend together,
122+// such as, G2D_ONE | G2D_PRE_MULTIPLIED_ALPHA
123+ G2D_PRE_MULTIPLIED_ALPHA = 0x10,
124+ G2D_DEMULTIPLY_OUT_ALPHA = 0x20,
125+};
126+
127+enum g2d_rotation
128+{
129+ G2D_ROTATION_0 = 0,
130+ G2D_ROTATION_90 = 1,
131+ G2D_ROTATION_180 = 2,
132+ G2D_ROTATION_270 = 3,
133+ G2D_FLIP_H = 4,
134+ G2D_FLIP_V = 5,
135+};
136+
137+struct g2d_surface
138+{
139+ enum g2d_format format;
140+
141+ int planes[3];//surface buffer addresses are set in physical planes separately
142+ //RGB: planes[0] - RGB565/RGBA8888/RGBX8888/BGRA8888/BRGX8888
143+ //NV12: planes[0] - Y, planes[1] - packed UV
144+ //I420: planes[0] - Y, planes[1] - U, planes[2] - V
145+ //YV12: planes[0] - Y, planes[1] - V, planes[2] - U
146+ //NV21: planes[0] - Y, planes[1] - packed VU
147+ //YUYV: planes[0] - packed YUYV
148+ //YVYU: planes[0] - packed YVYU
149+ //UYVY: planes[0] - packed UYVY
150+ //VYUY: planes[0] - packed VYUY
151+ //NV16: planes[0] - Y, planes[1] - packed UV
152+ //NV61: planes[0] - Y, planes[1] - packed VU
153+
154+ //blit rectangle in surface
155+ int left;
156+ int top;
157+ int right;
158+ int bottom;
159+ int stride; ///< buffer stride, in Pixels
160+ int width; ///< surface width, in Pixels
161+ int height; ///< surface height, in Pixels
162+ enum g2d_blend_func blendfunc; ///< alpha blending parameters
163+ int global_alpha; ///< value is 0 ~ 255
164+ //clrcolor format is RGBA8888, used as dst for clear, as src for blend dim
165+ int clrcolor;
166+
167+ //rotation degree
168+ enum g2d_rotation rot;
169+};
170+
171+struct g2d_surfaceEx
172+{
173+ struct g2d_surface base;
174+ enum g2d_tiling tiling;
175+
176+ struct g2d_tile_status ts;
177+ int reserved[8];
178+};
179+
180+void *dl_handle = NULL;
181+
182+typedef int (*g2d_api_open)(void **handle);
183+typedef int (*g2d_api_close)(void *handle);
184+typedef int (*g2d_api_free)(struct g2d_buf *buf);
185+typedef struct g2d_buf* (*g2d_api_alloc)(int size, int cacheable);
186+typedef int (*g2d_api_buf_export_fd)(struct g2d_buf *);
187+typedef int (*g2d_api_blitEx)(void *handle, struct g2d_surfaceEx *srcEx, struct g2d_surfaceEx *dstEx);
188+
189+#define G2D_API_SYM(name) g2d_api_##name g2d_##name = nullptr
190+G2D_API_SYM(open);
191+G2D_API_SYM(close);
192+G2D_API_SYM(free);
193+G2D_API_SYM(alloc);
194+G2D_API_SYM(buf_export_fd);
195+G2D_API_SYM(blitEx);
196+#undef G2D_API_SYM
197+/* g2d.h g2dExt.h */
198+
199 V4L2ExtCtrl::V4L2ExtCtrl(uint32_t id) {
200 memset(&ctrl, 0, sizeof(ctrl));
201 ctrl.id = id;
202@@ -261,7 +415,7 @@ V4L2Buffer::~V4L2Buffer() {
203 }
204 }
205 }
206- if(g2dbuf_p0 && g2dbuf_p1) {
207+ if(g2d_free && g2dbuf_p0 && g2dbuf_p1) {
208 g2d_free(g2dbuf_p0);
209 g2d_free(g2dbuf_p1);
210 }
211@@ -399,14 +553,18 @@ scoped_refptr<VideoFrame> V4L2Buffer::CreateVideoFrame() {
212 else
213 phys_1 = query1.phys;
214
215- g2dbuf_p0 = g2d_alloc(format_.fmt.pix_mp.width * format_.fmt.pix_mp.height, 0);
216- g2dbuf_p1 = g2d_alloc(format_.fmt.pix_mp.width * format_.fmt.pix_mp.height / 2, 0);
217+ if (g2d_alloc) {
218+ g2dbuf_p0 = g2d_alloc(format_.fmt.pix_mp.width * format_.fmt.pix_mp.height, 0);
219+ g2dbuf_p1 = g2d_alloc(format_.fmt.pix_mp.width * format_.fmt.pix_mp.height / 2, 0);
220+ }
221 if((!g2dbuf_p0) || (!g2dbuf_p1)){
222 DLOG(ERROR)<<"g2d buf alloc failed";
223 return nullptr;
224 }
225
226- int tmpfd = g2d_buf_export_fd(g2dbuf_p0);
227+ int tmpfd = -1;
228+ if (g2d_buf_export_fd)
229+ tmpfd = g2d_buf_export_fd(g2dbuf_p0);
230 tmpfd = dup(tmpfd);
231 if(tmpfd > 0)
232 g2dbufs_fds.push_back(base::ScopedFD(tmpfd));
233@@ -416,7 +574,8 @@ scoped_refptr<VideoFrame> V4L2Buffer::CreateVideoFrame() {
234 return nullptr;
235 }
236
237- tmpfd = g2d_buf_export_fd(g2dbuf_p1);
238+ if (g2d_buf_export_fd)
239+ tmpfd = g2d_buf_export_fd(g2dbuf_p1);
240 tmpfd = dup(tmpfd);
241 if(tmpfd>0)
242 g2dbufs_fds.push_back(base::ScopedFD(tmpfd));
243@@ -1152,7 +1311,7 @@ V4L2Queue::V4L2Queue(scoped_refptr<V4L2Device> dev,
244 #endif
245
246 g2d_handle = NULL;
247- if(g2d_open(&g2d_handle))
248+ if(g2d_open && g2d_open(&g2d_handle))
249 VLOGF(1) << "g2d_open fail";
250 }
251
252@@ -1172,7 +1331,7 @@ V4L2Queue::~V4L2Queue() {
253 DeallocateBuffers();
254 }
255
256- if(g2d_handle)
257+ if(g2d_close && g2d_handle)
258 g2d_close(g2d_handle);
259
260 std::move(destroy_cb_).Run();
261@@ -1573,7 +1732,8 @@ std::pair<bool, V4L2ReadableBufferRef> V4L2Queue::DequeueBuffer() {
262 src->global_alpha = 0xff;
263 src->blendfunc = G2D_ONE;
264
265- g2d_blitEx(g2d_handle, &srcEx, &dstEx);
266+ if (g2d_blitEx)
267+ g2d_blitEx(g2d_handle, &srcEx, &dstEx);
268 }
269
270 return std::make_pair(true, V4L2BufferRefFactory::CreateReadableRef(
271@@ -1747,8 +1907,31 @@ scoped_refptr<V4L2Device> V4L2Device::Create() {
272 #endif
273
274 device = new GenericV4L2Device();
275- if (device->Initialize())
276+ if (device->Initialize()) {
277+ dl_handle = dlopen("/usr/lib/libg2d.so",
278+ RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE | RTLD_LAZY);
279+ if (!dl_handle) {
280+ VLOGF(1) << "Has no libg2d.so";
281+ return device;
282+ }
283+
284+#define G2D_API_DLSYM(lib, name) \
285+ do { \
286+ g2d_##name = reinterpret_cast<g2d_api_##name>(dlsym(lib, "g2d_" #name)); \
287+ if (!(g2d_##name)) \
288+ VLOGF(1) << "Failed to dlsym g2d_" #name; \
289+ } while (0)
290+
291+ G2D_API_DLSYM(dl_handle, open);
292+ G2D_API_DLSYM(dl_handle, close);
293+ G2D_API_DLSYM(dl_handle, free);
294+ G2D_API_DLSYM(dl_handle, alloc);
295+ G2D_API_DLSYM(dl_handle, buf_export_fd);
296+ G2D_API_DLSYM(dl_handle, blitEx);
297+
298 return device;
299+ }
300+
301
302 VLOGF(1) << "Failed to create a V4L2Device";
303 return nullptr;
304--
3052.17.1
306
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0119-V4L2VDA-dlopen-libg2d.so.2-to-avoid-segfault.patch b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0119-V4L2VDA-dlopen-libg2d.so.2-to-avoid-segfault.patch
new file mode 100644
index 00000000..df6c6fe4
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland/0119-V4L2VDA-dlopen-libg2d.so.2-to-avoid-segfault.patch
@@ -0,0 +1,40 @@
1From 4e33abf0778eba9b6bf5bf4fc01e021775b7d2c7 Mon Sep 17 00:00:00 2001
2From: Hou Qi <qi.hou@nxp.com>
3Date: Thu, 29 Sep 2022 11:12:12 +0800
4Subject: [PATCH] V4L2VDA: dlopen libg2d.so.2 to avoid segfault
5
6For rootfs that have no libg2d.so, dlopen libg2d.so.2 instead.
7
8Upstream-Status: Inappropriate [NXP specific]
9---
10 media/gpu/v4l2/v4l2_device.cc | 5 +++--
11 1 file changed, 3 insertions(+), 2 deletions(-)
12
13diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
14index af71f54d141aa..139d32d3a788f 100644
15--- a/media/gpu/v4l2/v4l2_device.cc
16+++ b/media/gpu/v4l2/v4l2_device.cc
17@@ -286,6 +286,7 @@ typedef struct g2d_buf* (*g2d_api_alloc)(int size, int cacheable);
18 typedef int (*g2d_api_buf_export_fd)(struct g2d_buf *);
19 typedef int (*g2d_api_blitEx)(void *handle, struct g2d_surfaceEx *srcEx, struct g2d_surfaceEx *dstEx);
20
21+#define G2D_LIB_NAME "/usr/lib/libg2d.so.2"
22 #define G2D_API_SYM(name) g2d_api_##name g2d_##name = nullptr
23 G2D_API_SYM(open);
24 G2D_API_SYM(close);
25@@ -1908,10 +1909,10 @@ scoped_refptr<V4L2Device> V4L2Device::Create() {
26
27 device = new GenericV4L2Device();
28 if (device->Initialize()) {
29- dl_handle = dlopen("/usr/lib/libg2d.so",
30+ dl_handle = dlopen(G2D_LIB_NAME,
31 RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE | RTLD_LAZY);
32 if (!dl_handle) {
33- VLOGF(1) << "Has no libg2d.so";
34+ VLOGF(1) << "Failed to dlopen " << G2D_LIB_NAME;
35 return device;
36 }
37
38--
392.17.1
40
diff --git a/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland_%.bbappend b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland_%.bbappend
new file mode 100644
index 00000000..6b14bbc8
--- /dev/null
+++ b/dynamic-layers/chromium-browser-layer/recipes-browser/chromium/chromium-ozone-wayland_%.bbappend
@@ -0,0 +1,51 @@
1FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
2
3SRC_URI:append:imx-nxp-bsp = " \
4 file://0001-Fixed-chromium-flicker-with-g2d-renderer.patch \
5 file://0002-chromium-met-EGL-API-GetProcAddress-failures.patch \
6 file://0003-Disable-dri-for-imx-gpu.patch \
7"
8SRC_URI:append:mx8-nxp-bsp = " \
9 file://0101-V4L2VDA-Switch-to-use-VDA-instead-of-direct-VideoDec.patch \
10 file://0102-GenericV4L2Device-Correct-v4l2-decoder-device-path.patch \
11 file://0103-V4L2VDA-Add-macro-use_linux_v4l2.patch \
12 file://0104-V4L2VDA-Create-single-multi-plane-queues.patch \
13 file://0105-V4L2Buffer-Allocate-correct-v4l2-buffers-for-queues.patch \
14 file://0106-V4L2VDA-Create-videoframe-according-to-v4l2buffer.patch \
15 file://0107-V4L2VDA-Add-function-IsMultiQueue-for-S_FMT-and-G_FM.patch \
16 file://0108-V4L2VDA-Use-correct-size-to-allocate-CAPTURE-buffer.patch \
17 file://0109-V4L2VDA-Use-correct-plane-size-and-bytesused.patch \
18 file://0110-V4L2VDA-Add-hevc-format-support.patch \
19 file://0111-V4L2VDA-fix-vp9-crash-caused-by-DequeueResolutionCha.patch \
20 file://0112-V4L2VDA-Add-fps-in-SkiaOutputSurfaceImplOnGpu-by-VLO.patch \
21 file://0113-V4L2VDA-Comment-some-unused-ioctl.patch \
22 file://0114-V4L2VDA-Set-OUTPUT-format-with-parsed-resolution-for.patch \
23 file://0115-V4L2VDA-Add-V4L2_PIX_FMT_NV12M_8L128-format-for-amph.patch \
24 file://0116-V4L2VDA-Support-tile-to-linear-transform-for-amphion.patch \
25 file://0117-V4L2VDA-Enlarge-input-buffer-count-to-16.patch \
26 file://0118-V4L2VDA-Use-dlopen-to-dynamically-use-g2d-api.patch \
27 file://0119-V4L2VDA-dlopen-libg2d.so.2-to-avoid-segfault.patch \
28"
29
30GN_ARGS_DISABLE_GBM = ""
31GN_ARGS_DISABLE_GBM:mx6-nxp-bsp = "use_system_minigbm=false use_wayland_gbm=false"
32GN_ARGS_DISABLE_GBM:mx7-nxp-bsp = "${GN_ARGS_DISABLE_GBM:mx6-nxp-bsp}"
33GN_ARGS_USE_IMXGPU = "use_imxgpu=false"
34GN_ARGS_USE_IMXGPU:imxgpu = "use_imxgpu=true"
35GN_ARGS_ENABLE_PROPRIETARY_CODECS = ""
36GN_ARGS_ENABLE_PROPRIETARY_CODECS:mx8-nxp-bsp = "proprietary_codecs=true"
37GN_ARGS_FFMPEG_BRANDING = ""
38GN_ARGS_FFMPEG_BRANDING:mx8-nxp-bsp = "ffmpeg_branding="Chrome""
39GN_ARGS_USE_V4L2_CODEC = ""
40GN_ARGS_USE_V4L2_CODEC:mx8-nxp-bsp = "use_v4l2_codec=true"
41GN_ARGS_USE_LINUX_V4L2_ONLY = ""
42GN_ARGS_USE_LINUX_V4L2_ONLY:mx8-nxp-bsp = "use_linux_v4l2_only=true"
43GN_ARGS:append:imx-nxp-bsp = " \
44 ${GN_ARGS_DISABLE_GBM} \
45 ${GN_ARGS_USE_IMXGPU} \
46 ${GN_ARGS_ENABLE_PROPRIETARY_CODECS} \
47 ${GN_ARGS_FFMPEG_BRANDING} \
48 ${GN_ARGS_USE_V4L2_CODEC} \
49 ${GN_ARGS_USE_LINUX_V4L2_ONLY} \
50"
51CHROMIUM_EXTRA_ARGS:append = " --disable-features=VizDisplayCompositor --in-process-gpu --disable-gpu-rasterization"