meta-digi-dey: add chromium support

This comes from NXP's 'walnascar-6.12.34.2.1.0' release.

It depends on "meta-chromium" layer (which is part of meta-browser
repository.

https://onedigi.atlassian.net/browse/DEL-9838

Signed-off-by: Javier Viguera <javier.viguera@digi.com>
This commit is contained in:
Javier Viguera 2025-11-20 16:08:12 +01:00
parent 2aaa76c963
commit 2441ddb589
35 changed files with 2684 additions and 0 deletions

View File

@ -6,6 +6,8 @@ BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
${LAYERDIR}/recipes-*/*/*.bbappend"
BBFILES_DYNAMIC += " \
chromium-browser-layer:${LAYERDIR}/dynamic-layers/chromium-browser-layer/*/*/*.bb \
chromium-browser-layer:${LAYERDIR}/dynamic-layers/chromium-browser-layer/*/*/*.bbappend \
webkit:${LAYERDIR}/dynamic-layers/webkit/*/*/*.bb \
webkit:${LAYERDIR}/dynamic-layers/webkit/*/*/*.bbappend \
selinux:${LAYERDIR}/dynamic-layers/selinux/*/*/*.bb \

View File

@ -0,0 +1,34 @@
From 48becd0d71aa2fb1ca5b31c77b66997fe1f77737 Mon Sep 17 00:00:00 2001
From: Wujian Sun <wujian.sun_1@nxp.com>
Date: Wed, 1 Nov 2023 18:19:23 +0800
Subject: [PATCH 1/7] Fixed chromium flicker with g2d-renderer
chromium V89 reland linux_explicit_synchronization_protocol for
in-fence feature caused the flicker.
The rootcasue is that weston can not acquire fence fd.
A workaround no checking supports_acquire_fence supported.
Upstream-Status: Inappropriate [i.MX specific]
Signed-off-by: Wujian Sun <wujian.sun_1@nxp.com>
---
ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc b/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc
index acb4a60ba01ea..e93533cecaeb7 100644
--- a/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc
+++ b/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc
@@ -208,8 +208,7 @@ void GbmSurfacelessWayland::Present(SwapCompletionCallback completion_callback,
unsubmitted_frames_.back()->configs.reserve(frame->configs.size());
// If Wayland server supports linux_explicit_synchronization_protocol, fences
// should be shipped with buffers. Otherwise, we will wait for fences.
- if (buffer_manager_->supports_acquire_fence() || !use_egl_fence_sync_ ||
- !frame->schedule_planes_succeeded) {
+ if (!use_egl_fence_sync_ || !frame->schedule_planes_succeeded) {
frame->ready = true;
MaybeSubmitFrames();
return;
--
2.34.1

View File

@ -0,0 +1,40 @@
From 18bda704c4e54bd947746729a0ddde672376c081 Mon Sep 17 00:00:00 2001
From: Wujian Sun <wujian.sun_1@nxp.com>
Date: Mon, 23 Oct 2023 15:21:53 +0800
Subject: [PATCH 2/7] Disable dri for imx gpu
Upstream-Status: Inappropriate [i.MX-specific]
Signed-off-by: Wujian Sun <wujian.sun_1@nxp.com>
---
content/gpu/BUILD.gn | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/content/gpu/BUILD.gn b/content/gpu/BUILD.gn
index 098082510efab..9befdb8c01499 100644
--- a/content/gpu/BUILD.gn
+++ b/content/gpu/BUILD.gn
@@ -8,6 +8,11 @@ import("//build/config/ui.gni")
import("//gpu/vulkan/features.gni")
import("//media/media_options.gni")
+declare_args() {
+ # Checks if i.MX GPU is being used
+ use_imxgpu = false
+}
+
# See //content/BUILD.gn for how this works.
group("gpu") {
visibility = [ "//content/*" ] # This is an internal content API.
@@ -128,7 +133,7 @@ target(link_target_type, "gpu_sources") {
# Use DRI on desktop Linux builds.
if (current_cpu != "s390x" && current_cpu != "ppc64" && is_linux &&
- !is_castos) {
+ !is_castos && !use_imxgpu) {
configs += [ "//build/config/linux/dri" ]
}
}
--
2.34.1

View File

@ -0,0 +1,34 @@
From fc83501ff2105f99183b3f6ea240d6baacf3ea05 Mon Sep 17 00:00:00 2001
From: Wujian Sun <wujian.sun_1@nxp.com>
Date: Wed, 10 Nov 2021 17:28:22 +0800
Subject: [PATCH] chromium met EGL API GetProcAddress failures
Wayland not use SwANGLE as below commit, so no need
build SwANGLE on wayland platform.
commit 97f919dd8b544b583b772664f0d7b8e6b6d8da2e
Reland "Use SwANGLE on all Ozone platforms, except Wayland"
Upstream-Status: Inappropriate [i.MX-specific]
Signed-off-by: Wujian Sun <wujian.sun_1@nxp.com>
---
ui/gl/BUILD.gn | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/gl/BUILD.gn b/ui/gl/BUILD.gn
index bb7d843c1f363..4b4b360758e1d 100644
--- a/ui/gl/BUILD.gn
+++ b/ui/gl/BUILD.gn
@@ -252,7 +252,7 @@ component("gl") {
if (use_ozone) {
deps += [ "//ui/ozone:buildflags" ]
- if (use_egl && !is_fuchsia) {
+ if (use_egl && !is_fuchsia && !ozone_platform_wayland) {
data_deps += [
"//third_party/angle:libEGL",
"//third_party/angle:libGLESv2",
--
2.17.1

View File

@ -0,0 +1,46 @@
From 2f284f6819dbd7c37d90ebb2e4076f55745be8b7 Mon Sep 17 00:00:00 2001
From: Wujian Sun <wujian.sun_1@nxp.com>
Date: Wed, 18 Oct 2023 15:56:59 +0800
Subject: [PATCH 3/7] Fix chromium build failure
| aarch64-poky-linux-ld.lld: error: undefined symbol:
gl::NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(gl::GLDisplayEGL*,
void*, std::__1::unique_ptr<gfx::VSyncProvider,
std::__1::default_deletegfx::VSyncProvider >)
| >>> referenced by gl_surface_wayland.cc:35
(./../../ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc:35)
| >>>
thinlto-cache/Thin-7f2605.tmp.o:(ui::GLSurfaceWayland::GLSurfaceWayland(gl::GLDisplayEGL*,
std::__1::unique_ptr<wl_egl_window, ui::EGLWindowDeleter>,
ui::WaylandWindow*))
Upstream-Status: Inappropriate [i.MX-specific]
Signed-off-by: Wujian Sun <wujian.sun_1@nxp.com>
---
ui/gl/BUILD.gn | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/ui/gl/BUILD.gn b/ui/gl/BUILD.gn
index 89d11ec9754bb..af207a4dbaea3 100644
--- a/ui/gl/BUILD.gn
+++ b/ui/gl/BUILD.gn
@@ -196,6 +196,15 @@ component("gl") {
data_deps += [ "//third_party/vulkan-loader/src:libvulkan" ]
}
}
+ if(ozone_platform_wayland) {
+ defines += [ "WAYLAND_GBM" ]
+
+ deps += [
+ "//third_party/minigbm",
+ "//ui/gfx:memory_buffer",
+ "//ui/gfx/linux:gbm",
+ ]
+ }
}
if (ozone_platform_x11) {
--
2.34.1

View File

@ -0,0 +1,82 @@
From 7104f3eb76e3efa58764a53fe125583dc228a806 Mon Sep 17 00:00:00 2001
From: Wujian Sun <wujian.sun_1@nxp.com>
Date: Wed, 22 Nov 2023 16:52:59 +0800
Subject: [PATCH 4/7] Fixed chromium crash after upgrading
Native display fail to get GBM platform,
add EGL_PLATFORM_GBM_KHR for WAYLAND_GBM.
Upstream-Status: Inappropriate [i.MX-specific]
Signed-off-by: Xianzhong Li <xianzhong.li@nxp.com
Signed-off-by: Wujian Sun <wujian.sun_1@nxp.com>
---
ui/gfx/linux/gbm_device.h | 2 ++
ui/gfx/linux/gbm_wrapper.cc | 2 ++
.../platform/wayland/gpu/wayland_buffer_manager_gpu.cc | 2 --
.../platform/wayland/gpu/wayland_surface_factory.cc | 10 ++++++++++
4 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/ui/gfx/linux/gbm_device.h b/ui/gfx/linux/gbm_device.h
index 8fd34e8c7d434..fa5e6a58544bc 100644
--- a/ui/gfx/linux/gbm_device.h
+++ b/ui/gfx/linux/gbm_device.h
@@ -34,6 +34,8 @@ class GbmDevice {
gfx::NativePixmapHandle handle) = 0;
virtual bool CanCreateBufferForFormat(uint32_t format) = 0;
+
+ virtual gbm_device* get() = 0;
};
} // namespace ui
diff --git a/ui/gfx/linux/gbm_wrapper.cc b/ui/gfx/linux/gbm_wrapper.cc
index 7a1ae26444f36..415640e5825e3 100644
--- a/ui/gfx/linux/gbm_wrapper.cc
+++ b/ui/gfx/linux/gbm_wrapper.cc
@@ -467,6 +467,8 @@ class Device final : public ui::GbmDevice {
}
#endif
+ gbm_device* get() {return device_.get();}
+
private:
std::vector<uint64_t> GetFilteredModifiers(
uint32_t format,
diff --git a/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc b/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc
index 4e725c5814969..0258548fd80b2 100644
--- a/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc
+++ b/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc
@@ -363,8 +363,6 @@ GbmDevice* WaylandBufferManagerGpu::GetGbmDevice() {
if (!supports_dmabuf_ || (!gl::GLSurfaceEGL::GetGLDisplayEGL()
->ext->b_EGL_EXT_image_dma_buf_import &&
!use_fake_gbm_device_for_test_)) {
- supports_dmabuf_ = false;
- return nullptr;
}
if (gbm_device_ || use_fake_gbm_device_for_test_)
diff --git a/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc b/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
index bab048c4afac1..d9fe372879061 100644
--- a/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
+++ b/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
@@ -172,6 +172,16 @@ scoped_refptr<gl::GLSurface> GLOzoneEGLWayland::CreateOffscreenGLSurface(
}
gl::EGLDisplayPlatform GLOzoneEGLWayland::GetNativeDisplay() {
+#if defined(WAYLAND_GBM)
+ GbmDevice* const device = buffer_manager_->GetGbmDevice();
+ if (device != nullptr) {
+ gbm_device* gbm = device->get();
+ if (gbm) {
+ return gl::EGLDisplayPlatform(
+ reinterpret_cast<EGLNativeDisplayType>(gbm), EGL_PLATFORM_GBM_KHR);
+ }
+ }
+#endif
if (connection_) {
return connection_->GetNativeDisplay();
}
--
2.34.1

View File

@ -0,0 +1,43 @@
From 2822bbb8da30ab6f8415db4c98014418519f6b42 Mon Sep 17 00:00:00 2001
From: Wujian Sun <wujian.sun_1@nxp.com>
Date: Wed, 26 Jun 2024 15:33:23 +0800
Subject: [PATCH 5/7] MGS-7765: Blacklist MSAA for GPU Raster on Vivante GPUs
Vivante had poor performance when enbale MSAA, disable MSAA
for Vivante GPU.
The same workaround as other GPU vendor having the same issue.
https://codereview.chromium.org/1374043005
Upstream-Status: Pending
Signed-off-by: Wujian Sun <wujian.sun_1@nxp.com>
---
gpu/config/gpu_driver_bug_list.json | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json
index 27fc6e04be012..86ce0297db4f4 100644
--- a/gpu/config/gpu_driver_bug_list.json
+++ b/gpu/config/gpu_driver_bug_list.json
@@ -3399,6 +3399,17 @@
"features": [
"disable_accelerated_h264_encode"
]
+ },
+ {
+ "id": 436,
+ "description": "On Vivante GPUs MSAA performance is not acceptable for GPU rasterization",
+ "os": {
+ "type": "linux"
+ },
+ "gl_vendor": "Vivante Corporation",
+ "features": [
+ "msaa_is_slow"
+ ]
}
]
}
--
2.34.1

View File

@ -0,0 +1,45 @@
From dd7196aac0a632cf11bfe37be6832b6f11026aac Mon Sep 17 00:00:00 2001
From: Wujian Sun <wujian.sun_1@nxp.com>
Date: Thu, 27 Jun 2024 14:43:08 +0800
Subject: [PATCH 6/7] LF-12406: Fixed webgl test fail for GL_MAX_SAMPLES
checking
Differences Between WebGL and OpenGL ES 3.0 about GL_MAX_SAMPLES.
https://registry.khronos.org/OpenGL-Refpages/es3.0/html/glGetInternalformativ.xhtml
So disable the GL_MAX_SAMPLES checking for webgl context.
Upstream-Status: Inappropriate [i.MX specific]
Signed-off-by: Wujian Sun <wujian.sun_1@nxp.com>
---
gpu/command_buffer/service/gles2_cmd_decoder.cc | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 895524c824bdb..0132e2c712183 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -8209,11 +8209,13 @@ bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
}
}
- if (samples > renderbuffer_manager()->max_samples()) {
- LOCAL_SET_GL_ERROR(
- GL_INVALID_VALUE,
- "glRenderbufferStorageMultisample", "samples too large");
- return false;
+ if (!feature_info_->IsWebGLContext()) {
+ if (samples > renderbuffer_manager()->max_samples()) {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE,
+ "glRenderbufferStorageMultisample", "samples too large");
+ return false;
+ }
}
if (width > renderbuffer_manager()->max_renderbuffer_size() ||
--
2.34.1

View File

@ -0,0 +1,33 @@
From 5dfac9d33977e7db161c04d8e701fb255f9a5710 Mon Sep 17 00:00:00 2001
From: Wujian Sun <wujian.sun_1@nxp.com>
Date: Fri, 6 Sep 2024 14:04:35 +0800
Subject: [PATCH 7/7] Enable native GLES2 for Ozone wayland
Our GPU not support ANGLE extension
Revert "Remove native GLES2 implementation from Ozone."
This reverts commit e10fc690c15674d0434e94a959e99ef510e4ceb0.
Upstream-Status: Inappropriate [i.MX specific]
Signed-off-by: Wujian Sun <wujian.sun_1@nxp.com>
---
ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc | 1 +
1 file changed, 1 insertion(+)
diff --git a/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc b/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
index d9fe372879061..20ca068659d6b 100644
--- a/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
+++ b/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
@@ -225,6 +225,7 @@ WaylandSurfaceFactory::GetAllowedGLImplementations() {
impls.emplace_back(gl::ANGLEImplementation::kOpenGLES);
impls.emplace_back(gl::ANGLEImplementation::kSwiftShader);
impls.emplace_back(gl::ANGLEImplementation::kVulkan);
+ impls.emplace_back(gl::kGLImplementationEGLGLES2);
}
return impls;
}
--
2.34.1

View File

@ -0,0 +1,38 @@
From 7299ca8b360cd3596c7fbc5f31fae48ce1060e24 Mon Sep 17 00:00:00 2001
From: Wujian Sun <wujian.sun_1@nxp.com>
Date: Thu, 7 Nov 2024 10:34:46 +0800
Subject: [PATCH] Fix build fail after clang/llvm upgrade
Disable thinlto cache for need large memory.
| terminate called after throwing an instance of 'std::bad_alloc'
| what(): std::bad_alloc
| terminate called recursively
| aarch64-poky-linux-clang++: error: unable to execute command: Aborted
(core dumped)
| aarch64-poky-linux-clang++: error: linker command failed due to signal
(use -v to see invocation)
Upstream-Status: Inappropriate [i.MX specific]
Signed-off-by: Wujian Sun <wujian.sun_1@nxp.com>
---
build/config/compiler/BUILD.gn | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 45086d6838cac..8a148e4f53e0b 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -131,7 +131,7 @@ declare_args() {
# Whether to enable thin lto incremental builds.
# See: https://clang.llvm.org/docs/ThinLTO.html#incremental
# The cache can lead to non-determinism: https://crbug.com/1486045
- thin_lto_enable_cache = true
+ thin_lto_enable_cache = false
# Initialize all local variables with a pattern. This flag will fill
# uninitialized floating-point types (and 32-bit pointers) with 0xFF and the
--
2.34.1

View File

@ -0,0 +1,36 @@
From 4850cb4d7eb2d81beb7e4d2311b225b7b1c0bc25 Mon Sep 17 00:00:00 2001
From: Wujian Sun <wujian.sun_1@nxp.com>
Date: Tue, 19 Nov 2024 14:11:21 +0800
Subject: [PATCH] Fix chromium crash when run webgl 2.0.0 cts
Most display not support YUV format SCANOUT usage,
don't create YUV format GBM bo for SCANOUT.
webgl 2.0.0 fail cases:
all/conformance2/textures/video
Upstream-Status: Inappropriate [i.MX specific]
Signed-off-by: Wujian Sun <wujian.sun_1@nxp.com>
---
ui/gfx/linux/gbm_wrapper.cc | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/ui/gfx/linux/gbm_wrapper.cc b/ui/gfx/linux/gbm_wrapper.cc
index 415640e5825e3..ae99206f28f6a 100644
--- a/ui/gfx/linux/gbm_wrapper.cc
+++ b/ui/gfx/linux/gbm_wrapper.cc
@@ -313,6 +313,10 @@ class Device final : public ui::GbmDevice {
return CreateBuffer(format, requested_size, flags);
}
+ //Most display not support YUV format SCANOUT usage
+ if (format == GBM_FORMAT_NV12 && (flags & GBM_BO_USE_SCANOUT))
+ return nullptr;
+
// Buggy drivers prevent us from getting plane FDs from a BO which had its
// previously imported BO destroyed. E.g: Nvidia. Thus, on Linux Desktop, we
// do the create/import modifiers validation loop below using a separate set
--
2.34.1

View File

@ -0,0 +1,34 @@
From d4edb5af2a09a891e02a22514703860c911664a0 Mon Sep 17 00:00:00 2001
From: Wujian Sun <wujian.sun_1@nxp.com>
Date: Tue, 10 Dec 2024 14:40:49 +0800
Subject: [PATCH] Fix canvas test fail for webgl
canvas fallback from GPU to CPU meet issue with WillReadFrequently.
Set it false as default to avoid the failures.
conformance/canvas/draw-webgl-to-canvas-test.html
conformance/canvas/draw-static-webgl-to-multiple-canvas-test.html
Upstream-Status: Inappropriate [i.MX specific]
Signed-off-by: Wujian Sun <wujian.sun_1@nxp.com>
---
.../htmlcanvas/canvas_context_creation_attributes_helpers.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc b/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc
index 8938e79c1cbd0..b699d89763ad9 100644
--- a/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc
+++ b/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_helpers.cc
@@ -53,7 +53,7 @@ bool ToCanvasContextCreationAttributes(
break;
default:
result.will_read_frequently =
- CanvasContextCreationAttributesCore::WillReadFrequently::kUndefined;
+ CanvasContextCreationAttributesCore::WillReadFrequently::kFalse;
}
result.xr_compatible = attrs->xrCompatible();
return true;
--
2.34.1

View File

@ -0,0 +1,48 @@
From c0b01bd497e34bc9d8f0fcb72cd3d5ec36a72f75 Mon Sep 17 00:00:00 2001
From: Wujian Sun <wujian.sun_1@nxp.com>
Date: Fri, 3 Jan 2025 14:23:43 +0800
Subject: [PATCH] LF-12406-1: Blacklist disable
program_caching_for_transform_feedback on Mali GPUs
Mali GPU can't pass webgl cts case transform_feedback.
conformance2/transform_feedback/transform_feedback.html
Seems a bug where program binaries don't cache transform feedback
varyings.
The same workaround as other GPU vendor having the same issue.
https://codereview.chromium.org/2615573002
Upstream-Status: Pending
Signed-off-by: Wujian Sun <wujian.sun_1@nxp.com>
---
gpu/config/gpu_driver_bug_list.json | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json
index 86ce0297db4f4..332a5c15768be 100644
--- a/gpu/config/gpu_driver_bug_list.json
+++ b/gpu/config/gpu_driver_bug_list.json
@@ -3410,6 +3410,18 @@
"features": [
"msaa_is_slow"
]
+ },
+ {
+ "id": 437,
+ "description": "Program binaries don't contain transform feedback varyings on Mali GPUs",
+ "os": {
+ "type": "linux"
+ },
+ "gl_vendor": "ARM.*",
+ "gl_renderer": "Mali.*",
+ "features": [
+ "disable_program_caching_for_transform_feedback"
+ ]
}
]
}
--
2.34.1

View File

@ -0,0 +1,31 @@
From fb1763465e8720cd090a9787ef52376611064337 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Fri, 13 Sep 2024 22:18:54 +0900
Subject: [PATCH 01/19] V4L2Device: Correct v4l2 codec device path
Change codec device pattern to /dev/video, and select one
correct device path /dev/videox where x is an integer.
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/v4l2/v4l2_device.cc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
index 39c16611c76f3..ebbf240a3c5e7 100644
--- a/media/gpu/v4l2/v4l2_device.cc
+++ b/media/gpu/v4l2/v4l2_device.cc
@@ -852,8 +852,8 @@ void V4L2Device::CloseDevice() {
}
void V4L2Device::EnumerateDevicesForType(Type type) {
- static const std::string kDecoderDevicePattern = "/dev/video-dec";
- static const std::string kEncoderDevicePattern = "/dev/video-enc";
+ static const std::string kDecoderDevicePattern = "/dev/video";
+ static const std::string kEncoderDevicePattern = "/dev/video";
static const std::string kImageProcessorDevicePattern = "/dev/image-proc";
static const std::string kJpegDecoderDevicePattern = "/dev/jpeg-dec";
static const std::string kJpegEncoderDevicePattern = "/dev/jpeg-enc";
--
2.34.1

View File

@ -0,0 +1,213 @@
From 6d4413788f248814f498981d97d78d92e0dc85f3 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Fri, 13 Sep 2024 22:31:51 +0900
Subject: [PATCH 02/19] V4L2VideoDecoder: Add macro use_linux_v4l2
Upstream-Status: Inappropriate [NXP specific]
---
.../gpu_mjpeg_decode_accelerator_factory.cc | 3 +-
media/gpu/BUILD.gn | 1 +
media/gpu/args.gni | 4 +++
media/gpu/v4l2/BUILD.gn | 15 ++++++----
media/gpu/v4l2/v4l2_utils.cc | 30 ++++++++++++++++++-
media/gpu/v4l2/v4l2_video_decoder.cc | 8 +++++
6 files changed, 54 insertions(+), 7 deletions(-)
diff --git a/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc b/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc
index 8e8ad4a84875c..156b6bd25674e 100644
--- a/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc
+++ b/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc
@@ -14,7 +14,8 @@
#include "media/base/media_switches.h"
#include "media/gpu/buildflags.h"
-#if BUILDFLAG(USE_V4L2_CODEC) && defined(ARCH_CPU_ARM_FAMILY)
+#if BUILDFLAG(USE_V4L2_CODEC) && defined(ARCH_CPU_ARM_FAMILY) && \
+ !BUILDFLAG(USE_LINUX_V4L2)
#define USE_V4L2_MJPEG_DECODE_ACCELERATOR
#endif
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn
index 727cbedee37a3..4843c717966b9 100644
--- a/media/gpu/BUILD.gn
+++ b/media/gpu/BUILD.gn
@@ -22,6 +22,7 @@ buildflag_header("buildflags") {
"USE_VAAPI_IMAGE_CODECS=$use_vaapi_image_codecs",
"USE_V4L2_CODEC=$use_v4l2_codec",
"USE_LIBV4L2=$use_v4lplugin",
+ "USE_LINUX_V4L2=$use_linux_v4l2_only",
]
}
diff --git a/media/gpu/args.gni b/media/gpu/args.gni
index 37751112e34a7..49939b896e699 100644
--- a/media/gpu/args.gni
+++ b/media/gpu/args.gni
@@ -14,6 +14,10 @@ declare_args() {
use_v4l2_codec =
is_chromeos_lacros && (target_cpu == "arm" || target_cpu == "arm64")
+ # Indicates that only definitions available in the mainline linux kernel
+ # will be used.
+ use_linux_v4l2_only = false
+
# Indicates if VA-API-based hardware acceleration is to be used. This
# is typically the case on x86-based ChromeOS devices.
# VA-API should also be compiled by default on x11/wayland linux devices
diff --git a/media/gpu/v4l2/BUILD.gn b/media/gpu/v4l2/BUILD.gn
index bd5d25000cfcb..0aa466ba9cec5 100644
--- a/media/gpu/v4l2/BUILD.gn
+++ b/media/gpu/v4l2/BUILD.gn
@@ -20,9 +20,6 @@ source_set("v4l2") {
"legacy/v4l2_video_decode_accelerator.h",
"legacy/v4l2_video_decoder_backend_stateful.cc",
"legacy/v4l2_video_decoder_backend_stateful.h",
- "v4l2_decode_surface.cc",
- "v4l2_decode_surface.h",
- "v4l2_decode_surface_handler.h",
"v4l2_device.cc",
"v4l2_device.h",
"v4l2_device_poller.cc",
@@ -43,6 +40,15 @@ source_set("v4l2") {
"v4l2_video_decoder.h",
"v4l2_video_decoder_backend.cc",
"v4l2_video_decoder_backend.h",
+ "v4l2_vp9_helpers.cc",
+ "v4l2_vp9_helpers.h",
+ ]
+
+ if (!use_linux_v4l2_only) {
+ sources += [
+ "v4l2_decode_surface.cc",
+ "v4l2_decode_surface.h",
+ "v4l2_decode_surface_handler.h",
"v4l2_video_decoder_backend_stateless.cc",
"v4l2_video_decoder_backend_stateless.h",
"v4l2_video_decoder_delegate_h264.cc",
@@ -51,9 +57,8 @@ source_set("v4l2") {
"v4l2_video_decoder_delegate_vp8.h",
"v4l2_video_decoder_delegate_vp9.cc",
"v4l2_video_decoder_delegate_vp9.h",
- "v4l2_vp9_helpers.cc",
- "v4l2_vp9_helpers.h",
]
+ }
if (enable_hevc_parser_and_hw_decoder) {
sources += [
diff --git a/media/gpu/v4l2/v4l2_utils.cc b/media/gpu/v4l2/v4l2_utils.cc
index 1455996823334..bb3ffb4f4642b 100644
--- a/media/gpu/v4l2/v4l2_utils.cc
+++ b/media/gpu/v4l2/v4l2_utils.cc
@@ -317,15 +317,23 @@ using v4l2_enum_type = decltype(V4L2_PIX_FMT_H264);
static const std::map<v4l2_enum_type, v4l2_enum_type>
kV4L2CodecPixFmtToProfileCID = {
{V4L2_PIX_FMT_H264, V4L2_CID_MPEG_VIDEO_H264_PROFILE},
+#if !BUILDFLAG(USE_LINUX_V4L2)
{V4L2_PIX_FMT_H264_SLICE, V4L2_CID_MPEG_VIDEO_H264_PROFILE},
+#endif
#if BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
{V4L2_PIX_FMT_HEVC, V4L2_CID_MPEG_VIDEO_HEVC_PROFILE},
+#if !BUILDFLAG(USE_LINUX_V4L2)
{V4L2_PIX_FMT_HEVC_SLICE, V4L2_CID_MPEG_VIDEO_HEVC_PROFILE},
+#endif
#endif // BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
{V4L2_PIX_FMT_VP8, V4L2_CID_MPEG_VIDEO_VP8_PROFILE},
+#if !BUILDFLAG(USE_LINUX_V4L2)
{V4L2_PIX_FMT_VP8_FRAME, V4L2_CID_MPEG_VIDEO_VP8_PROFILE},
+#endif
{V4L2_PIX_FMT_VP9, V4L2_CID_MPEG_VIDEO_VP9_PROFILE},
+#if !BUILDFLAG(USE_LINUX_V4L2)
{V4L2_PIX_FMT_VP9_FRAME, V4L2_CID_MPEG_VIDEO_VP9_PROFILE},
+#endif
#if BUILDFLAG(IS_CHROMEOS)
{V4L2_PIX_FMT_AV1, V4L2_CID_MPEG_VIDEO_AV1_PROFILE},
{V4L2_PIX_FMT_AV1_FRAME, V4L2_CID_MPEG_VIDEO_AV1_PROFILE},
@@ -537,7 +545,27 @@ uint32_t VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile,
<< "Unsupported profile: " << GetProfileName(profile);
const auto& v4l2_pix_fmt = kVideoCodecProfileToV4L2CodecPixFmt.at(profile);
- return slice_based ? v4l2_pix_fmt.first : v4l2_pix_fmt.second;
+#if BUILDFLAG(USE_LINUX_V4L2)
+ if (slice_based) {
+ LOG(ERROR) << "Unsupported slice";
+ return 0;
+ }
+
+ if (profile >= H264PROFILE_MIN && profile <= H264PROFILE_MAX) {
+ return V4L2_PIX_FMT_H264;
+ } else if (profile >= VP8PROFILE_MIN && profile <= VP8PROFILE_MAX) {
+ return V4L2_PIX_FMT_VP8;
+ } else if (profile >= VP9PROFILE_MIN && profile <= VP9PROFILE_MAX) {
+ return V4L2_PIX_FMT_VP9;
+ } else if (profile == HEVCPROFILE_MAIN) {
+ return V4L2_PIX_FMT_HEVC;
+ } else {
+ DVLOGF(1) << "Unsupported profile: " << GetProfileName(profile);
+ return 0;
+ }
+#else
+ return slice_based ? v4l2_pix_fmt.first : v4l2_pix_fmt.second;
+#endif
}
base::TimeDelta TimeValToTimeDelta(const struct timeval& timeval) {
diff --git a/media/gpu/v4l2/v4l2_video_decoder.cc b/media/gpu/v4l2/v4l2_video_decoder.cc
index 601f57fe0e6d0..5765761592344 100644
--- a/media/gpu/v4l2/v4l2_video_decoder.cc
+++ b/media/gpu/v4l2/v4l2_video_decoder.cc
@@ -32,7 +32,9 @@
#include "media/gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.h"
#include "media/gpu/v4l2/v4l2_status.h"
#include "media/gpu/v4l2/v4l2_utils.h"
+#if !BUILDFLAG(USE_LINUX_V4L2)
#include "media/gpu/v4l2/v4l2_video_decoder_backend_stateless.h"
+#endif
#include "mojo/public/cpp/bindings/callback_helpers.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -68,6 +70,7 @@ constexpr size_t kInputBufferMaxSizeFor4k = 2 * kInputBufferMaxSizeFor1080p;
// Input format V4L2 fourccs this class supports.
const std::vector<uint32_t> kSupportedInputFourccs = {
// V4L2 stateless formats
+#if !BUILDFLAG(USE_LINUX_V4L2)
V4L2_PIX_FMT_H264_SLICE,
#if BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
V4L2_PIX_FMT_HEVC_SLICE,
@@ -75,6 +78,7 @@ const std::vector<uint32_t> kSupportedInputFourccs = {
V4L2_PIX_FMT_VP8_FRAME,
V4L2_PIX_FMT_VP9_FRAME,
V4L2_PIX_FMT_AV1_FRAME,
+#endif
// V4L2 stateful formats
V4L2_PIX_FMT_H264,
#if BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
@@ -82,7 +86,9 @@ const std::vector<uint32_t> kSupportedInputFourccs = {
#endif // BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
V4L2_PIX_FMT_VP8,
V4L2_PIX_FMT_VP9,
+#if !BUILDFLAG(USE_LINUX_V4L2)
V4L2_PIX_FMT_AV1,
+#endif
};
// These values are logged to UMA. Entries should not be renumbered and numeric
@@ -471,6 +477,7 @@ V4L2Status V4L2VideoDecoder::InitializeBackend() {
<< " and fourcc: " << FourccToString(input_format_fourcc_);
backend_ = std::make_unique<V4L2StatefulVideoDecoderBackend>(
this, device_, profile_, color_space_, decoder_task_runner_);
+#if !BUILDFLAG(USE_LINUX_V4L2)
} else {
DCHECK_EQ(preferred_api_and_format.first, kStateless);
VLOGF(1) << "Using a stateless API for profile: "
@@ -479,6 +486,7 @@ V4L2Status V4L2VideoDecoder::InitializeBackend() {
backend_ = std::make_unique<V4L2StatelessVideoDecoderBackend>(
this, device_, profile_, color_space_, decoder_task_runner_,
cdm_context_ref_ ? cdm_context_ref_->GetCdmContext() : nullptr);
+#endif
}
if (!backend_->Initialize()) {
--
2.34.1

View File

@ -0,0 +1,142 @@
From c175fe907f93f5db9327ca1030820cdba8df137c Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Fri, 13 Sep 2024 22:36:04 +0900
Subject: [PATCH 03/19] V4L2VideoDecoder: Create single/multi plane queues
Decide to create single-plane queue or multi-plane queue according to
the capabilities returned by VIDIOC_QUERYCAP.
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/v4l2/v4l2_device.cc | 29 ++++++++++++++++++++--------
media/gpu/v4l2/v4l2_video_decoder.cc | 27 ++++++++++++++++++--------
2 files changed, 40 insertions(+), 16 deletions(-)
diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
index ebbf240a3c5e7..c04873fe2ae84 100644
--- a/media/gpu/v4l2/v4l2_device.cc
+++ b/media/gpu/v4l2/v4l2_device.cc
@@ -92,6 +92,8 @@ scoped_refptr<V4L2Queue> V4L2Device::GetQueue(enum v4l2_buf_type type) {
// Supported queue types.
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
break;
default:
VLOGF(1) << "Unsupported V4L2 queue type: " << type;
@@ -538,9 +540,17 @@ V4L2Device::EnumerateSupportedDecodeProfiles(
const std::vector<uint32_t>& pixelformats) {
VideoDecodeAccelerator::SupportedProfiles profiles;
- const auto v4l2_codecs_as_pix_fmts =
+ std::vector<uint32_t> enumerated_pixelformats;
+ enumerated_pixelformats =
EnumerateSupportedPixFmts(base::BindRepeating(&V4L2Device::Ioctl, this),
- V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ if (enumerated_pixelformats.empty()) {
+ VLOG(1) << "empty.... Try Multi-plane";
+ enumerated_pixelformats =
+ EnumerateSupportedPixFmts(base::BindRepeating(&V4L2Device::Ioctl, this),
+ V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ }
+ const auto v4l2_codecs_as_pix_fmts = enumerated_pixelformats;
for (uint32_t pixelformat : v4l2_codecs_as_pix_fmts) {
if (!base::Contains(pixelformats, pixelformat)) {
@@ -859,27 +869,28 @@ void V4L2Device::EnumerateDevicesForType(Type type) {
static const std::string kJpegEncoderDevicePattern = "/dev/jpeg-enc";
std::string device_pattern;
- v4l2_buf_type buf_type;
+ std::vector<v4l2_buf_type> candidate_buf_types;
switch (type) {
case Type::kDecoder:
device_pattern = kDecoderDevicePattern;
- buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ candidate_buf_types.push_back(V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ candidate_buf_types.push_back(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
break;
case Type::kEncoder:
device_pattern = kEncoderDevicePattern;
- buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ candidate_buf_types.push_back(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
break;
case Type::kImageProcessor:
device_pattern = kImageProcessorDevicePattern;
- buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ candidate_buf_types.push_back(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
break;
case Type::kJpegDecoder:
device_pattern = kJpegDecoderDevicePattern;
- buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ candidate_buf_types.push_back(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
break;
case Type::kJpegEncoder:
device_pattern = kJpegEncoderDevicePattern;
- buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ candidate_buf_types.push_back(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
break;
}
@@ -899,6 +910,7 @@ void V4L2Device::EnumerateDevicesForType(Type type) {
Devices devices;
for (const auto& path : candidate_paths) {
+ for (const auto& buf_type : candidate_buf_types){
if (!OpenDevicePath(path)) {
continue;
}
@@ -912,6 +924,7 @@ void V4L2Device::EnumerateDevicesForType(Type type) {
CloseDevice();
}
+ }
DCHECK_EQ(devices_by_type_.count(type), 0u);
devices_by_type_[type] = devices;
diff --git a/media/gpu/v4l2/v4l2_video_decoder.cc b/media/gpu/v4l2/v4l2_video_decoder.cc
index 5765761592344..857576ae56d6a 100644
--- a/media/gpu/v4l2/v4l2_video_decoder.cc
+++ b/media/gpu/v4l2/v4l2_video_decoder.cc
@@ -454,17 +454,28 @@ V4L2Status V4L2VideoDecoder::InitializeBackend() {
#endif // BUILDFLAG(USE_CHROMEOS_PROTECTED_MEDIA)
struct v4l2_capability caps;
- const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
- if (device_->Ioctl(VIDIOC_QUERYCAP, &caps) ||
- (caps.capabilities & kCapsRequired) != kCapsRequired) {
- VLOGF(1) << "ioctl() failed: VIDIOC_QUERYCAP, "
- << "caps check failed: 0x" << std::hex << caps.capabilities;
+ unsigned int device_caps;
+ enum v4l2_buf_type input_type, output_type;
+ if (device_->Ioctl(VIDIOC_QUERYCAP, &caps) != 0)
return V4L2Status::Codes::kFailedFileCapabilitiesCheck;
- }
+
+ if (caps.capabilities & V4L2_CAP_DEVICE_CAPS)
+ device_caps = caps.device_caps;
+ else
+ device_caps = caps.capabilities;
+
+ if (device_caps & (V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE))
+ input_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ else
+ input_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ if (device_caps & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE))
+ output_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ else
+ output_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
// Create Input/Output V4L2Queue
- input_queue_ = device_->GetQueue(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
- output_queue_ = device_->GetQueue(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ input_queue_ = device_->GetQueue(input_type);
+ output_queue_ = device_->GetQueue(output_type);
if (!input_queue_ || !output_queue_) {
VLOGF(1) << "Failed to create V4L2 queue.";
return V4L2Status::Codes::kFailedResourceAllocation;
--
2.34.1

View File

@ -0,0 +1,97 @@
From 1dec452c446aaa8ab37c75bf0bcae9f8ea8b3fea Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Fri, 13 Sep 2024 22:39:10 +0900
Subject: [PATCH 04/19] V4L2Buffer: Allocate correct v4l2 buffers for queues
For single plane queue, need to fill v4l2_planes_[0] with
correct size quried from v4l2 driver.
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/v4l2/v4l2_queue.cc | 39 +++++++++++++++++++++++++-----------
1 file changed, 27 insertions(+), 12 deletions(-)
diff --git a/media/gpu/v4l2/v4l2_queue.cc b/media/gpu/v4l2/v4l2_queue.cc
index 4851e5b5255c0..8bcf8101f3a20 100644
--- a/media/gpu/v4l2/v4l2_queue.cc
+++ b/media/gpu/v4l2/v4l2_queue.cc
@@ -237,24 +237,28 @@ V4L2Buffer::V4L2Buffer(const IoctlAsCallback& ioctl_cb,
DCHECK(V4L2_TYPE_IS_MULTIPLANAR(type));
DCHECK_LE(format.fmt.pix_mp.num_planes, std::size(v4l2_planes_));
- memset(&v4l2_buffer_, 0, sizeof(v4l2_buffer_));
- memset(v4l2_planes_, 0, sizeof(v4l2_planes_));
- v4l2_buffer_.m.planes = v4l2_planes_;
- // Just in case we got more planes than we want.
- v4l2_buffer_.length =
- std::min(static_cast<size_t>(format.fmt.pix_mp.num_planes),
- std::size(v4l2_planes_));
+ if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
+ memset(&v4l2_buffer_, 0, sizeof(v4l2_buffer_));
+ memset(v4l2_planes_, 0, sizeof(v4l2_planes_));
+ v4l2_buffer_.m.planes = v4l2_planes_;
+ // Just in case we got more planes than we want.
+ v4l2_buffer_.length =
+ std::min(static_cast<size_t>(format.fmt.pix_mp.num_planes),
+ std::size(v4l2_planes_));
+ }
v4l2_buffer_.index = buffer_id;
v4l2_buffer_.type = type;
v4l2_buffer_.memory = memory;
- plane_mappings_.resize(v4l2_buffer_.length);
+ plane_mappings_.resize(V4L2_TYPE_IS_MULTIPLANAR(type) ? v4l2_buffer_.length : 1);
}
V4L2Buffer::~V4L2Buffer() {
if (v4l2_buffer_.memory == V4L2_MEMORY_MMAP) {
for (size_t i = 0; i < plane_mappings_.size(); i++) {
if (plane_mappings_[i] != nullptr) {
- munmap(plane_mappings_[i], v4l2_buffer_.m.planes[i].length);
+ unsigned int length = V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type) ?
+ v4l2_buffer_.m.planes[i].length : v4l2_buffer_.length;
+ munmap(plane_mappings_[i], length);
}
}
}
@@ -268,6 +272,13 @@ bool V4L2Buffer::Query() {
return false;
}
+ if (!V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type)) {
+ v4l2_planes_[0].bytesused = v4l2_buffer_.bytesused;
+ v4l2_planes_[0].length = v4l2_buffer_.length;
+ v4l2_planes_[0].data_offset = 0;
+ memcpy (&v4l2_planes_[0].m, &v4l2_buffer_.m, sizeof (v4l2_buffer_.m));
+ }
+
DCHECK(plane_mappings_.size() == v4l2_buffer_.length);
return true;
@@ -291,9 +302,13 @@ void* V4L2Buffer::GetPlaneMapping(const size_t plane) {
return nullptr;
}
- p = mmap_cb_.Run(nullptr, v4l2_buffer_.m.planes[plane].length,
+ unsigned int length = V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type) ?
+ v4l2_buffer_.m.planes[plane].length : v4l2_planes_[plane].length;
+ unsigned int mem_offset = V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type) ?
+ v4l2_buffer_.m.planes[plane].m.mem_offset : v4l2_planes_[plane].m.mem_offset;
+ p = mmap_cb_.Run(nullptr, length,
PROT_READ | PROT_WRITE, MAP_SHARED,
- v4l2_buffer_.m.planes[plane].m.mem_offset);
+ mem_offset);
if (p == MAP_FAILED) {
VPLOGF(1) << "mmap() failed: ";
return nullptr;
@@ -1177,7 +1192,7 @@ size_t V4L2Queue::AllocateBuffers(size_t count,
VQLOGF(1) << "Cannot get format.";
return 0;
}
- planes_count_ = format->fmt.pix_mp.num_planes;
+ planes_count_ = V4L2_TYPE_IS_MULTIPLANAR(format->type) ? format->fmt.pix_mp.num_planes : 1;
DCHECK_LE(planes_count_, static_cast<size_t>(VIDEO_MAX_PLANES));
__u8 flags = incoherent ? V4L2_MEMORY_FLAG_NON_COHERENT : 0;
--
2.34.1

View File

@ -0,0 +1,156 @@
From 41cb3357eeace1686fa453ec3c18c01c879f58c9 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Fri, 13 Sep 2024 22:43:15 +0900
Subject: [PATCH 05/19] V4L2VideoDecoder: Create videoframe according to
v4l2buffer
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/v4l2/v4l2_queue.cc | 7 ++--
media/gpu/v4l2/v4l2_utils.cc | 63 ++++++++++++++++++++++++------------
2 files changed, 48 insertions(+), 22 deletions(-)
diff --git a/media/gpu/v4l2/v4l2_queue.cc b/media/gpu/v4l2/v4l2_queue.cc
index 8bcf8101f3a20..ffa94c3d2c9f8 100644
--- a/media/gpu/v4l2/v4l2_queue.cc
+++ b/media/gpu/v4l2/v4l2_queue.cc
@@ -334,7 +334,7 @@ scoped_refptr<FrameResource> V4L2Buffer::CreateFrame() {
}
std::vector<base::ScopedFD> dmabuf_fds = GetDmabufsForV4L2Buffer(
- ioctl_cb_, v4l2_buffer_.index, v4l2_buffer_.length,
+ ioctl_cb_, v4l2_buffer_.index, V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type) ? v4l2_buffer_.length : 1,
static_cast<enum v4l2_buf_type>(v4l2_buffer_.type));
if (dmabuf_fds.empty()) {
VLOGF(1) << "Failed to get DMABUFs of V4L2 buffer";
@@ -361,7 +361,10 @@ scoped_refptr<FrameResource> V4L2Buffer::CreateFrame() {
dmabuf_fds.emplace_back(duped_fd);
}
- gfx::Size size(format_.fmt.pix_mp.width, format_.fmt.pix_mp.height);
+ if (V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type))
+ gfx::Size size(format_.fmt.pix_mp.width, format_.fmt.pix_mp.height);
+ else
+ gfx::Size size(format_.fmt.pix.width, format_.fmt.pix.height);
return NativePixmapFrameResource::Create(
*layout, gfx::Rect(size), size, std::move(dmabuf_fds), base::TimeDelta());
diff --git a/media/gpu/v4l2/v4l2_utils.cc b/media/gpu/v4l2/v4l2_utils.cc
index bb3ffb4f4642b..06b4329764b3f 100644
--- a/media/gpu/v4l2/v4l2_utils.cc
+++ b/media/gpu/v4l2/v4l2_utils.cc
@@ -219,13 +219,9 @@ size_t GetNumPlanesOfV4L2PixFmt(uint32_t pix_fmt) {
std::optional<VideoFrameLayout> V4L2FormatToVideoFrameLayout(
const struct v4l2_format& format) {
- if (!V4L2_TYPE_IS_MULTIPLANAR(format.type)) {
- VLOGF(1) << "v4l2_buf_type is not multiplanar: " << std::hex << "0x"
- << format.type;
- return std::nullopt;
- }
const v4l2_pix_format_mplane& pix_mp = format.fmt.pix_mp;
- const uint32_t& pix_fmt = pix_mp.pixelformat;
+ const v4l2_pix_format& pix = format.fmt.pix;
+ const uint32_t& pix_fmt = V4L2_TYPE_IS_MULTIPLANAR(format.type) ? pix_mp.pixelformat : pix.pixelformat;
const auto video_fourcc = Fourcc::FromV4L2PixFmt(pix_fmt);
if (!video_fourcc) {
VLOGF(1) << "Failed to convert pixel format to VideoPixelFormat: "
@@ -233,7 +229,7 @@ std::optional<VideoFrameLayout> V4L2FormatToVideoFrameLayout(
return std::nullopt;
}
const VideoPixelFormat video_format = video_fourcc->ToVideoPixelFormat();
- const size_t num_buffers = pix_mp.num_planes;
+ const size_t num_buffers = V4L2_TYPE_IS_MULTIPLANAR(format.type) ? format.fmt.pix_mp.num_planes : 1;
const size_t num_color_planes = VideoFrame::NumPlanes(video_format);
if (num_color_planes == 0) {
VLOGF(1) << "Unsupported video format for NumPlanes(): "
@@ -251,9 +247,17 @@ std::optional<VideoFrameLayout> V4L2FormatToVideoFrameLayout(
std::vector<ColorPlaneLayout> planes;
planes.reserve(num_color_planes);
for (size_t i = 0; i < num_buffers; ++i) {
- const v4l2_plane_pix_format& plane_format = pix_mp.plane_fmt[i];
- planes.emplace_back(static_cast<int32_t>(plane_format.bytesperline), 0u,
- plane_format.sizeimage);
+ if (V4L2_TYPE_IS_MULTIPLANAR(format.type)) {
+ if(i==0)
+ planes.emplace_back(static_cast<int32_t>(pix_mp.width), 0u,
+ pix_mp.width*pix_mp.height);
+ else
+ planes.emplace_back(static_cast<int32_t>(pix_mp.width), 0u,
+ pix_mp.width*pix_mp.height/2);
+ } else {
+ planes.emplace_back(static_cast<int32_t>(pix.bytesperline), 0u,
+ pix.sizeimage);
+ }
}
// For the case that #color planes > #buffers, it fills stride of color
// plane which does not map to buffer.
@@ -267,8 +271,12 @@ std::optional<VideoFrameLayout> V4L2FormatToVideoFrameLayout(
case V4L2_PIX_FMT_NV12:
// The stride of UV is the same as Y in NV12.
// The height is half of Y plane.
- planes.emplace_back(y_stride, y_stride_abs * pix_mp.height,
- y_stride_abs * pix_mp.height / 2);
+ if (V4L2_TYPE_IS_MULTIPLANAR(format.type))
+ planes.emplace_back(y_stride, y_stride_abs * pix_mp.height,
+ y_stride_abs * pix_mp.height / 2);
+ else
+ planes.emplace_back(y_stride, y_stride_abs * pix.height,
+ y_stride_abs * pix.height / 2);
DCHECK_EQ(2u, planes.size());
break;
case V4L2_PIX_FMT_YUV420:
@@ -276,13 +284,18 @@ std::optional<VideoFrameLayout> V4L2FormatToVideoFrameLayout(
// The spec claims that two Cx rows (including padding) is exactly as
// long as one Y row (including padding). So stride of Y must be even
// number.
- if (y_stride % 2 != 0 || pix_mp.height % 2 != 0) {
+ if (V4L2_TYPE_IS_MULTIPLANAR(format.type) && (y_stride % 2 != 0 || pix_mp.height % 2 != 0)) {
VLOGF(1) << "Plane-Y stride and height should be even; stride: "
<< y_stride << ", height: " << pix_mp.height;
return std::nullopt;
}
+ else if (!V4L2_TYPE_IS_MULTIPLANAR(format.type) && (y_stride % 2 != 0 || pix.height % 2 != 0)){
+ VLOGF(1) << "Plane-Y stride and height should be even; stride: "
+ << y_stride << ", height: " << pix.height;
+ return std::nullopt;
+ }
const int32_t half_stride = y_stride / 2;
- const size_t plane_0_area = y_stride_abs * pix_mp.height;
+ const size_t plane_0_area = y_stride_abs * (V4L2_TYPE_IS_MULTIPLANAR(format.type) ? pix_mp.height : pix.height);
const size_t plane_1_area = plane_0_area / 4;
planes.emplace_back(half_stride, plane_0_area, plane_1_area);
planes.emplace_back(half_stride, plane_0_area + plane_1_area,
@@ -301,13 +314,23 @@ std::optional<VideoFrameLayout> V4L2FormatToVideoFrameLayout(
// such devices individually, so set this as a video frame layout property.
constexpr size_t buffer_alignment = 0x1000;
if (num_buffers == 1) {
- return VideoFrameLayout::CreateWithPlanes(
- video_format, gfx::Size(pix_mp.width, pix_mp.height), std::move(planes),
- buffer_alignment);
+ if (V4L2_TYPE_IS_MULTIPLANAR(format.type))
+ return VideoFrameLayout::CreateWithPlanes(
+ video_format, gfx::Size(pix_mp.width, pix_mp.height), std::move(planes),
+ buffer_alignment);
+ else
+ return VideoFrameLayout::CreateWithPlanes(
+ video_format, gfx::Size(pix.width, pix.height), std::move(planes),
+ buffer_alignment);
} else {
- return VideoFrameLayout::CreateMultiPlanar(
- video_format, gfx::Size(pix_mp.width, pix_mp.height), std::move(planes),
- buffer_alignment);
+ if (V4L2_TYPE_IS_MULTIPLANAR(format.type))
+ return VideoFrameLayout::CreateMultiPlanar(
+ video_format, gfx::Size(pix_mp.width, pix_mp.height), std::move(planes),
+ buffer_alignment);
+ else
+ return VideoFrameLayout::CreateMultiPlanar(
+ video_format, gfx::Size(pix.width, pix.height), std::move(planes),
+ buffer_alignment);
}
}
--
2.34.1

View File

@ -0,0 +1,114 @@
From 7efe2eff075518ed1c7342ab35ea084fb8754b54 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Fri, 13 Sep 2024 22:46:22 +0900
Subject: [PATCH 06/19] V4L2VideoDecoder: Add function IsMultiQueue for S_FMT
and G_FMT
Function IsMultiQueue() is used to set correct fotmat type for
8M and 8Q.
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/v4l2/v4l2_queue.cc | 36 +++++++++++++++++++++-------
media/gpu/v4l2/v4l2_queue.h | 1 +
media/gpu/v4l2/v4l2_video_decoder.cc | 4 ++--
3 files changed, 31 insertions(+), 10 deletions(-)
diff --git a/media/gpu/v4l2/v4l2_queue.cc b/media/gpu/v4l2/v4l2_queue.cc
index ffa94c3d2c9f8..5eae387499eec 100644
--- a/media/gpu/v4l2/v4l2_queue.cc
+++ b/media/gpu/v4l2/v4l2_queue.cc
@@ -41,11 +41,18 @@ struct v4l2_format BuildV4L2Format(const enum v4l2_buf_type type,
struct v4l2_format format;
memset(&format, 0, sizeof(format));
format.type = type;
- format.fmt.pix_mp.pixelformat = fourcc;
- format.fmt.pix_mp.width = size.width();
- format.fmt.pix_mp.height = size.height();
- format.fmt.pix_mp.num_planes = GetNumPlanesOfV4L2PixFmt(fourcc);
- format.fmt.pix_mp.plane_fmt[0].sizeimage = buffer_size;
+ if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
+ format.fmt.pix_mp.pixelformat = fourcc;
+ format.fmt.pix_mp.width = size.width();
+ format.fmt.pix_mp.height = size.height();
+ format.fmt.pix_mp.num_planes = GetNumPlanesOfV4L2PixFmt(fourcc);
+ format.fmt.pix_mp.plane_fmt[0].sizeimage = buffer_size;
+ } else {
+ format.fmt.pix.pixelformat = fourcc;
+ format.fmt.pix.width = size.width();
+ format.fmt.pix.height = size.height();
+ format.fmt.pix.sizeimage = buffer_size;
+ }
return format;
}
@@ -506,9 +513,13 @@ V4L2BufferRefBase::V4L2BufferRefBase(const struct v4l2_buffer& v4l2_buffer,
DCHECK(return_to_);
memcpy(&v4l2_buffer_, &v4l2_buffer, sizeof(v4l2_buffer_));
- memcpy(v4l2_planes_, v4l2_buffer.m.planes,
- sizeof(struct v4l2_plane) * v4l2_buffer.length);
- v4l2_buffer_.m.planes = v4l2_planes_;
+ if (V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer.type)) {
+ memcpy(v4l2_planes_, v4l2_buffer.m.planes,
+ sizeof(struct v4l2_plane) * v4l2_buffer.length);
+ v4l2_buffer_.m.planes = v4l2_planes_;
+ } else {
+ memcpy(&v4l2_planes_[0].m, &v4l2_buffer.m, sizeof(v4l2_buffer.m));
+ }
}
V4L2BufferRefBase::~V4L2BufferRefBase() {
@@ -1566,6 +1577,15 @@ bool V4L2Queue::Streamoff() {
return true;
}
+bool V4L2Queue::IsMultiQueue() {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ if (type_ == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE || type_ == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ return true;
+ else
+ return false;
+}
+
size_t V4L2Queue::AllocatedBuffersCount() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/media/gpu/v4l2/v4l2_queue.h b/media/gpu/v4l2/v4l2_queue.h
index 4713ea3eebcfd..85c7920417935 100644
--- a/media/gpu/v4l2/v4l2_queue.h
+++ b/media/gpu/v4l2/v4l2_queue.h
@@ -534,6 +534,7 @@ class MEDIA_GPU_EXPORT V4L2Queue
// still be using them.
[[nodiscard]] bool Streamoff();
+ [[nodiscard]] bool IsMultiQueue();
// Returns the number of buffers currently allocated for this queue.
[[nodiscard]] size_t AllocatedBuffersCount() const;
// Returns the number of currently free buffers on this queue.
diff --git a/media/gpu/v4l2/v4l2_video_decoder.cc b/media/gpu/v4l2/v4l2_video_decoder.cc
index 857576ae56d6a..4a2591f092f42 100644
--- a/media/gpu/v4l2/v4l2_video_decoder.cc
+++ b/media/gpu/v4l2/v4l2_video_decoder.cc
@@ -608,7 +608,7 @@ bool V4L2VideoDecoder::SetupInputFormat() {
// Check if the format is supported.
const auto v4l2_codecs_as_pix_fmts = EnumerateSupportedPixFmts(
base::BindRepeating(&V4L2Device::Ioctl, device_),
- V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ input_queue_->IsMultiQueue() ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE : V4L2_BUF_TYPE_VIDEO_OUTPUT);
if (!base::Contains(v4l2_codecs_as_pix_fmts, input_format_fourcc_)) {
DVLOGF(1) << FourccToString(input_format_fourcc_)
<< " not recognised, skipping...";
@@ -677,7 +677,7 @@ CroStatus V4L2VideoDecoder::SetupOutputFormat(const gfx::Size& size,
const auto v4l2_pix_fmts = EnumerateSupportedPixFmts(
base::BindRepeating(&V4L2Device::Ioctl, device_),
- V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ output_queue_->IsMultiQueue() ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : V4L2_BUF_TYPE_VIDEO_CAPTURE);
std::vector<PixelLayoutCandidate> candidates;
for (const uint32_t& pixfmt : v4l2_pix_fmts) {
--
2.34.1

View File

@ -0,0 +1,65 @@
From 90edd752075e29ac990da5ac52ccd5721c15853a Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Fri, 13 Sep 2024 22:48:10 +0900
Subject: [PATCH 07/19] V4L2VideoDecoder: Use correct plane size and bytesused
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/v4l2/v4l2_queue.cc | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/media/gpu/v4l2/v4l2_queue.cc b/media/gpu/v4l2/v4l2_queue.cc
index 5eae387499eec..afa5d91ddb4b4 100644
--- a/media/gpu/v4l2/v4l2_queue.cc
+++ b/media/gpu/v4l2/v4l2_queue.cc
@@ -851,7 +851,10 @@ size_t V4L2WritableBufferRef::GetPlaneSize(const size_t plane) const {
return 0;
}
- return buffer_data_->v4l2_buffer_.m.planes[plane].length;
+ if (V4L2_TYPE_IS_MULTIPLANAR(buffer_data_->v4l2_buffer_.type))
+ return buffer_data_->v4l2_buffer_.m.planes[plane].length;
+ else
+ return buffer_data_->v4l2_buffer_.length;
}
void V4L2WritableBufferRef::SetPlaneSize(const size_t plane,
@@ -911,7 +914,10 @@ void V4L2WritableBufferRef::SetPlaneBytesUsed(const size_t plane,
return;
}
- buffer_data_->v4l2_buffer_.m.planes[plane].bytesused = bytes_used;
+ if (V4L2_TYPE_IS_MULTIPLANAR(buffer_data_->v4l2_buffer_.type))
+ buffer_data_->v4l2_buffer_.m.planes[plane].bytesused = bytes_used;
+ else
+ buffer_data_->v4l2_buffer_.bytesused = bytes_used;
}
size_t V4L2WritableBufferRef::GetPlaneBytesUsed(const size_t plane) const {
@@ -923,7 +929,10 @@ size_t V4L2WritableBufferRef::GetPlaneBytesUsed(const size_t plane) const {
return 0;
}
- return buffer_data_->v4l2_buffer_.m.planes[plane].bytesused;
+ if (V4L2_TYPE_IS_MULTIPLANAR(buffer_data_->v4l2_buffer_.type))
+ return buffer_data_->v4l2_buffer_.m.planes[plane].bytesused;
+ else
+ return buffer_data_->v4l2_buffer_.bytesused;
}
void V4L2WritableBufferRef::SetPlaneDataOffset(const size_t plane,
@@ -1029,7 +1038,10 @@ size_t V4L2ReadableBuffer::GetPlaneBytesUsed(const size_t plane) const {
return 0;
}
- return buffer_data_->v4l2_planes_[plane].bytesused;
+ if (V4L2_TYPE_IS_MULTIPLANAR(buffer_data_->v4l2_buffer_.type))
+ return buffer_data_->v4l2_planes_[plane].bytesused;
+ else
+ return buffer_data_->v4l2_buffer_.bytesused;
}
size_t V4L2ReadableBuffer::GetPlaneDataOffset(const size_t plane) const {
--
2.34.1

View File

@ -0,0 +1,63 @@
From d297967d980eb8fa6f67ee723a625f35cec403ee Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Fri, 13 Sep 2024 22:50:43 +0900
Subject: [PATCH 08/19] V4L2VideoDecoder: Add hevc format support
Upstream-Status: Inappropriate [NXP specific]
---
media/base/supported_types.cc | 2 +-
media/gpu/v4l2/v4l2_utils.cc | 4 +++-
media/media_options.gni | 2 +-
3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/media/base/supported_types.cc b/media/base/supported_types.cc
index de9d4be3b92e8..11ef3357e2376 100644
--- a/media/base/supported_types.cc
+++ b/media/base/supported_types.cc
@@ -387,7 +387,7 @@ bool IsDefaultSupportedVideoType(const VideoType& type) {
case VideoCodec::kVP9:
return IsVp9ProfileSupported(type);
case VideoCodec::kHEVC:
- return IsHevcProfileSupported(type);
+ return true;
case VideoCodec::kDolbyVision:
return IsDolbyVisionProfileSupported(type);
case VideoCodec::kUnknown:
diff --git a/media/gpu/v4l2/v4l2_utils.cc b/media/gpu/v4l2/v4l2_utils.cc
index 06b4329764b3f..8fbd4cfa10561 100644
--- a/media/gpu/v4l2/v4l2_utils.cc
+++ b/media/gpu/v4l2/v4l2_utils.cc
@@ -537,7 +537,7 @@ void GetSupportedResolution(const IoctlAsCallback& ioctl_cb,
uint32_t pixelformat,
gfx::Size* min_resolution,
gfx::Size* max_resolution) {
- constexpr gfx::Size kDefaultMaxCodedSize(1920, 1088);
+ constexpr gfx::Size kDefaultMaxCodedSize(4096, 4096);
*max_resolution = kDefaultMaxCodedSize;
constexpr gfx::Size kDefaultMinCodedSize(16, 16);
*min_resolution = kDefaultMinCodedSize;
@@ -580,6 +580,8 @@ uint32_t VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile,
return V4L2_PIX_FMT_VP8;
} else if (profile >= VP9PROFILE_MIN && profile <= VP9PROFILE_MAX) {
return V4L2_PIX_FMT_VP9;
+ } else if (profile >= HEVCPROFILE_MIN && profile <= HEVCPROFILE_MAX) {
+ return V4L2_PIX_FMT_HEVC;
} else if (profile == HEVCPROFILE_MAIN) {
return V4L2_PIX_FMT_HEVC;
} else {
diff --git a/media/media_options.gni b/media/media_options.gni
index 1924017f9e7dd..0f1be96bf308e 100644
--- a/media/media_options.gni
+++ b/media/media_options.gni
@@ -138,7 +138,7 @@ declare_args() {
# applies to video-capable devices.
enable_platform_hevc =
proprietary_codecs && (enable_hevc_parser_and_hw_decoder ||
- is_cast_media_device || is_chromeos_lacros)
+ is_cast_media_device || is_chromeos_lacros || use_v4l2_codec)
enable_mse_mpeg2ts_stream_parser =
proprietary_codecs &&
--
2.34.1

View File

@ -0,0 +1,85 @@
From ac51e4353acbe44ec8beef3f36715faa9568231c Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Fri, 11 Oct 2024 18:16:14 +0900
Subject: [PATCH 09/19] display: Add fps in SkiaOutputSurfaceImplOnGpu by
VLOG(1)
Upstream-Status: Inappropriate [NXP specific]
---
.../skia_output_surface_impl_on_gpu.cc | 18 ++++++++++++++++++
.../skia_output_surface_impl_on_gpu.h | 1 +
2 files changed, 19 insertions(+)
diff --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
index 1ad55916b42a5..227173cd9bc76 100644
--- 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
@@ -15,6 +15,7 @@
#include <string_view>
#include <utility>
#include <vector>
+#include <sys/time.h>
#include "base/debug/crash_logging.h"
#include "base/debug/dump_without_crashing.h"
@@ -138,6 +139,15 @@
#include "components/viz/service/display_embedder/output_presenter_fuchsia.h"
#endif
+static uint64_t start_time = 0;
+static uint64_t stop_time = 0;
+
+uint64_t NowMicros() {
+ struct timeval tv;
+ gettimeofday(&tv, nullptr);
+ return static_cast<uint64_t>(tv.tv_sec) * 1e6 + tv.tv_usec;
+}
+
namespace viz {
namespace {
@@ -341,6 +351,7 @@ SkiaOutputSurfaceImplOnGpu::SkiaOutputSurfaceImplOnGpu(
async_read_result_lock_(base::MakeRefCounted<AsyncReadResultLock>()) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ swap_buffers_number_ = 0;
weak_ptr_ = weak_ptr_factory_.GetWeakPtr();
buffer_presented_callback_ = CreateSafeRepeatingCallback(
weak_ptr_, std::move(buffer_presented_callback));
@@ -595,7 +606,13 @@ void SkiaOutputSurfaceImplOnGpu::SwapBuffers(OutputSurfaceFrame frame) {
TRACE_EVENT0("viz", "SkiaOutputSurfaceImplOnGpu::SwapBuffers");
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ if ( swap_buffers_number_ == 0)
+ start_time = NowMicros();
+
+ swap_buffers_number_++;
+ stop_time = NowMicros();
SwapBuffersInternal(std::move(frame));
+ 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;
}
void SkiaOutputSurfaceImplOnGpu::SetDependenciesResolvedTimings(
@@ -1938,6 +1955,7 @@ bool SkiaOutputSurfaceImplOnGpu::Initialize() {
// allow neither to be set in the offscreen case.
DCHECK(!(gl_surface_ != nullptr && presenter_ != nullptr));
+ start_time = NowMicros();
return true;
}
diff --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
index b82de4041e78a..532866bc30297 100644
--- 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
@@ -498,6 +498,7 @@ class SkiaOutputSurfaceImplOnGpu
ScheduleGpuTaskCallback schedule_gpu_task_;
AddChildWindowToBrowserCallback add_child_window_to_browser_callback_;
SkiaOutputDevice::ReleaseOverlaysCallback release_overlays_callback_;
+ size_t swap_buffers_number_;
// ImplOnGpu::CopyOutput can create SharedImages via ImplOnGpu's
// SharedImageFactory. Clients can use these images via CopyOutputResult and
--
2.34.1

View File

@ -0,0 +1,113 @@
From 8eb371e7afe04e86469ac605afbc5b8069bd8811 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Fri, 13 Sep 2024 22:57:00 +0900
Subject: [PATCH 10/19] V4L2VideoDecoder: Comment some unused ioctl
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/v4l2/v4l2_queue.cc | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/media/gpu/v4l2/v4l2_queue.cc b/media/gpu/v4l2/v4l2_queue.cc
index afa5d91ddb4b4..de74d0da308c3 100644
--- a/media/gpu/v4l2/v4l2_queue.cc
+++ b/media/gpu/v4l2/v4l2_queue.cc
@@ -1101,10 +1101,12 @@ V4L2Queue::V4L2Queue(const IoctlAsCallback& ioctl_cb,
weak_this_factory_(this) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+#if !BUILDFLAG(USE_LINUX_V4L2)
struct v4l2_requestbuffers reqbufs = {
.count = 0, .type = type_, .memory = V4L2_MEMORY_MMAP};
supports_requests_ = (ioctl_cb_.Run(VIDIOC_REQBUFS, &reqbufs) == kIoctlOk) &&
(reqbufs.capabilities & V4L2_BUF_CAP_SUPPORTS_REQUESTS);
+#endif
// Stateful backends for example do not support requests.
VPLOG_IF(4, supports_requests_)
@@ -1754,10 +1756,14 @@ bool V4L2Request::ApplyCtrls(struct v4l2_ext_controls* ctrls) {
return false;
}
+#if !BUILDFLAG(USE_LINUX_V4L2)
ctrls->which = V4L2_CTRL_WHICH_REQUEST_VAL;
ctrls->request_fd = request_fd_.get();
return true;
+#else
+ return false;
+#endif
}
bool V4L2Request::ApplyQueueBuffer(struct v4l2_buffer* buffer) {
@@ -1769,10 +1775,14 @@ bool V4L2Request::ApplyQueueBuffer(struct v4l2_buffer* buffer) {
return false;
}
+#if !BUILDFLAG(USE_LINUX_V4L2)
buffer->flags |= V4L2_BUF_FLAG_REQUEST_FD;
buffer->request_fd = request_fd_.get();
return true;
+#else
+ return false;
+#endif
}
bool V4L2Request::Submit() {
@@ -1783,12 +1793,16 @@ bool V4L2Request::Submit() {
return false;
}
+#if !BUILDFLAG(USE_LINUX_V4L2)
if (HANDLE_EINTR(ioctl(request_fd_.get(), MEDIA_REQUEST_IOC_QUEUE)) != 0) {
RecordMediaIoctlUMA(MediaIoctlRequests::kMediaRequestIocQueue);
return false;
}
return true;
+#else
+ return false;
+#endif
}
bool V4L2Request::IsCompleted() {
@@ -1830,6 +1844,7 @@ bool V4L2Request::Reset() {
return false;
}
+#if !BUILDFLAG(USE_LINUX_V4L2)
// Reinit the request to make sure we can use it for a new submission.
if (HANDLE_EINTR(ioctl(request_fd_.get(), MEDIA_REQUEST_IOC_REINIT)) < 0) {
RecordMediaIoctlUMA(MediaIoctlRequests::kMediaRequestIocReinit);
@@ -1838,6 +1853,9 @@ bool V4L2Request::Reset() {
}
return true;
+#else
+ return false;
+#endif
}
V4L2RequestRefBase::V4L2RequestRefBase(V4L2RequestRefBase&& req_base) {
@@ -1914,6 +1932,7 @@ V4L2RequestsQueue::~V4L2RequestsQueue() {
std::optional<base::ScopedFD> V4L2RequestsQueue::CreateRequestFD() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+#if !BUILDFLAG(USE_LINUX_V4L2)
int request_fd;
int ret = HANDLE_EINTR(
ioctl(media_fd_.get(), MEDIA_IOC_REQUEST_ALLOC, &request_fd));
@@ -1924,6 +1943,9 @@ std::optional<base::ScopedFD> V4L2RequestsQueue::CreateRequestFD() {
}
return base::ScopedFD(request_fd);
+#else
+ return std::nullopt;
+#endif
}
std::optional<V4L2RequestRef> V4L2RequestsQueue::GetFreeRequest() {
--
2.34.1

View File

@ -0,0 +1,81 @@
From fe9d852a4f33d4efdcbf52e761a9c32c76970517 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Fri, 13 Sep 2024 22:59:46 +0900
Subject: [PATCH 11/19] V4L2VideoDecoder: Add V4L2_PIX_FMT_NV12M_8L128 format
for amphion
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/chromeos/fourcc.cc | 2 ++
media/gpu/chromeos/fourcc.h | 4 ++++
media/gpu/v4l2/v4l2_device.cc | 1 +
media/gpu/v4l2/v4l2_device.h | 6 ++++++
4 files changed, 13 insertions(+)
diff --git a/media/gpu/chromeos/fourcc.cc b/media/gpu/chromeos/fourcc.cc
index 5b7444a7b6319..6236034447322 100644
--- a/media/gpu/chromeos/fourcc.cc
+++ b/media/gpu/chromeos/fourcc.cc
@@ -24,6 +24,7 @@ std::optional<Fourcc> Fourcc::FromUint32(uint32_t fourcc) {
case YM12:
case YM21:
case YUYV:
+ case NA12:
case NV12:
case NV21:
case NM12:
@@ -172,6 +173,7 @@ VideoPixelFormat Fourcc::ToVideoPixelFormat() const {
return PIXEL_FORMAT_YUY2;
case NV12:
case NM12:
+ case NA12:
return PIXEL_FORMAT_NV12;
case NV21:
case NM21:
diff --git a/media/gpu/chromeos/fourcc.h b/media/gpu/chromeos/fourcc.h
index 6f08dba1de919..12b71cbb8f394 100644
--- a/media/gpu/chromeos/fourcc.h
+++ b/media/gpu/chromeos/fourcc.h
@@ -69,6 +69,10 @@ class MEDIA_GPU_EXPORT Fourcc {
// Maps to PIXEL_FORMAT_NV21, V4L2_PIX_FMT_NV21M.
NM21 = ComposeFourcc('N', 'M', '2', '1'),
+ // Tiled YUV formats, non contiguous planes.
+ // Maps to V4L2_PIX_FMT_NV12M_8L128.
+ NA12 = ComposeFourcc('N', 'A', '1', '2'),
+
// YUV422 single-planar format.
// https://linuxtv.org/downloads/v4l-dvb-apis-new/userspace-api/v4l/pixfmt-yuv422p.html
// Maps to PIXEL_FORMAT_I422, V4L2_PIX_FMT_YUV422P.
diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
index c04873fe2ae84..08a3fe203cb81 100644
--- a/media/gpu/v4l2/v4l2_device.cc
+++ b/media/gpu/v4l2/v4l2_device.cc
@@ -42,6 +42,7 @@ uint32_t V4L2PixFmtToDrmFormat(uint32_t format) {
switch (format) {
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV12M:
+ case V4L2_PIX_FMT_NV12M_8L128:
return DRM_FORMAT_NV12;
case V4L2_PIX_FMT_YUV420:
diff --git a/media/gpu/v4l2/v4l2_device.h b/media/gpu/v4l2/v4l2_device.h
index 2d2800f3925f5..34e1b4d9380b2 100644
--- a/media/gpu/v4l2/v4l2_device.h
+++ b/media/gpu/v4l2/v4l2_device.h
@@ -63,6 +63,12 @@
v4l2_fourcc('Q', '1', '0', 'C') /* Qualcomm 10-bit compressed */
#endif
+/* Tiled YUV formats, non contiguous planes */
+#ifndef V4L2_PIX_FMT_NV12M_8L128
+#define V4L2_PIX_FMT_NV12M_8L128 \
+ v4l2_fourcc('N', 'A', '1', '2') /* Y/CbCr 4:2:0 8x128 tiles */
+#endif
+
#define V4L2_PIX_FMT_INVALID v4l2_fourcc('0', '0', '0', '0')
namespace media {
--
2.34.1

View File

@ -0,0 +1,328 @@
From 591913ea8a59426be9902599cec129445804c8d7 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Fri, 13 Sep 2024 23:09:35 +0900
Subject: [PATCH 12/19] V4L2VideoDecoder: Support tile to linear transform for
amphion
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/v4l2/BUILD.gn | 1 +
media/gpu/v4l2/v4l2_queue.cc | 211 ++++++++++++++++++++++++++++++++++-
media/gpu/v4l2/v4l2_queue.h | 1 +
3 files changed, 209 insertions(+), 4 deletions(-)
diff --git a/media/gpu/v4l2/BUILD.gn b/media/gpu/v4l2/BUILD.gn
index 0aa466ba9cec5..836ee0bc7504c 100644
--- a/media/gpu/v4l2/BUILD.gn
+++ b/media/gpu/v4l2/BUILD.gn
@@ -92,6 +92,7 @@ source_set("v4l2") {
"EGL",
"GLESv2",
]
+ libs += [ "g2d" ]
configs += [ "//third_party/libyuv:libyuv_config" ]
diff --git a/media/gpu/v4l2/v4l2_queue.cc b/media/gpu/v4l2/v4l2_queue.cc
index de74d0da308c3..945e7a7df9b93 100644
--- a/media/gpu/v4l2/v4l2_queue.cc
+++ b/media/gpu/v4l2/v4l2_queue.cc
@@ -20,6 +20,11 @@
#include "media/gpu/chromeos/platform_video_frame_utils.h"
#include "media/gpu/macros.h"
+#include "g2d.h"
+#include "g2dExt.h"
+#include <linux/dma-buf.h>
+#include <time.h>
+
namespace media {
namespace {
@@ -189,6 +194,11 @@ class V4L2Buffer {
size_t GetMemoryUsage() const;
const struct v4l2_buffer& v4l2_buffer() const { return v4l2_buffer_; }
const scoped_refptr<FrameResource>& GetFrameResource();
+ std::pair<int, int> GetSavedmafd();
+ std::pair<unsigned int, unsigned int> GetSavedphys();
+ std::pair<int, int> Getg2dbufphys();
+ std::pair<void *, void *> Getg2dbufvirs();
+ const struct v4l2_format& GetFmt() const {return format_;}
private:
V4L2Buffer(const IoctlAsCallback& ioctl_cb,
@@ -203,6 +213,13 @@ class V4L2Buffer {
const IoctlAsCallback ioctl_cb_;
const MmapAsCallback mmap_cb_;
std::vector<void*> plane_mappings_;
+ int dmafd0;
+ int dmafd1;
+ unsigned long phys_0;
+ unsigned long phys_1;
+ struct g2d_buf *g2dbuf_p0;
+ struct g2d_buf *g2dbuf_p1;
+ std::vector<base::ScopedFD> g2dbufs_fds;
// V4L2 data as queried by QUERYBUF.
struct v4l2_buffer v4l2_buffer_;
@@ -257,6 +274,90 @@ V4L2Buffer::V4L2Buffer(const IoctlAsCallback& ioctl_cb,
v4l2_buffer_.type = type;
v4l2_buffer_.memory = memory;
plane_mappings_.resize(V4L2_TYPE_IS_MULTIPLANAR(type) ? v4l2_buffer_.length : 1);
+ dmafd0 = dmafd1 = -1;
+ phys_0 = phys_1 = 0;
+ g2dbuf_p0 = g2dbuf_p1 = NULL;
+
+ if (V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type) &&
+ format_.fmt.pix_mp.pixelformat == V4L2_PIX_FMT_NV12M_8L128) {
+ VLOGF(3) << "Map physical address";
+
+ std::vector<base::ScopedFD> dmabuf_fds = GetDmabufsForV4L2Buffer(
+ ioctl_cb_, v4l2_buffer_.index, V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type) ? v4l2_buffer_.length : 1,
+ static_cast<enum v4l2_buf_type>(v4l2_buffer_.type));
+ if (dmabuf_fds.empty()) {
+ LOG(ERROR) << "Failed to get DMABUFs of V4L2 buffer";
+ return;
+ }
+
+ // DMA buffer fds should not be invalid
+ for (const auto& dmabuf_fd : dmabuf_fds) {
+ if (!dmabuf_fd.is_valid()) {
+ LOG(ERROR) << "Fail to get DMABUFs of V4L2 buffer - invalid fd";
+ return;
+ }
+ if(dmafd0 == -1)
+ dmafd0 = dmabuf_fd.get();
+ else
+ dmafd1 = dmabuf_fd.get();
+ }
+
+ struct dma_buf_phys{
+ unsigned long phys;
+ };
+ #define DMA_BUF_IOCTL_PHYS _IOW(DMA_BUF_BASE, 10, struct dma_buf_phys)
+ struct dma_buf_phys query0, query1;
+ int ret = ioctl(dmafd0, DMA_BUF_IOCTL_PHYS, &query0);
+ if(ret != 0) {
+ LOG(ERROR)<< "DMA_BUF_IOCTL_PHYS failed at dmafd" << dmafd0;
+ return;
+ }
+ else {
+ phys_0 = query0.phys;
+ }
+
+ ret = ioctl(dmafd1, DMA_BUF_IOCTL_PHYS, &query1);
+ if(ret != 0) {
+ LOG(ERROR)<< "DMA_BUF_IOCTL_PHYS failed at dmafd" << dmafd1;
+ return;
+ }
+ else {
+ phys_1 = query1.phys;
+ }
+
+ if (g2d_alloc) {
+ g2dbuf_p0 = g2d_alloc(format_.fmt.pix_mp.width * format_.fmt.pix_mp.height, 0);
+ g2dbuf_p1 = g2d_alloc(format_.fmt.pix_mp.width * format_.fmt.pix_mp.height / 2, 0);
+ }
+ if((!g2dbuf_p0) || (!g2dbuf_p1)){
+ LOG(ERROR)<<"g2d buf alloc failed";
+ return;
+ }
+
+ int tmpfd = -1;
+ if (g2d_buf_export_fd)
+ tmpfd = g2d_buf_export_fd(g2dbuf_p0);
+ tmpfd = dup(tmpfd);
+ if(tmpfd > 0)
+ g2dbufs_fds.push_back(base::ScopedFD(tmpfd));
+ else if(tmpfd == -1)
+ {
+ LOG(ERROR) << "Failed duplicating g2d fd";
+ return;
+ }
+
+ if (g2d_buf_export_fd)
+ tmpfd = g2d_buf_export_fd(g2dbuf_p1);
+ tmpfd = dup(tmpfd);
+ if(tmpfd>0)
+ g2dbufs_fds.push_back(base::ScopedFD(tmpfd));
+ else if(tmpfd == -1)
+ {
+ LOG(ERROR) << "Failed duplicating g2d fd";
+ return;
+ }
+
+ }
}
V4L2Buffer::~V4L2Buffer() {
@@ -269,6 +370,32 @@ V4L2Buffer::~V4L2Buffer() {
}
}
}
+ if(g2d_free && g2dbuf_p0 && g2dbuf_p1) {
+ g2d_free(g2dbuf_p0);
+ g2d_free(g2dbuf_p1);
+ }
+}
+
+std::pair<int, int> V4L2Buffer::GetSavedmafd() {
+ return std::make_pair(dmafd0, dmafd1);
+}
+
+std::pair<unsigned int, unsigned int> V4L2Buffer::GetSavedphys() {
+ return std::make_pair(phys_0, phys_1);
+}
+
+std::pair<int, int> V4L2Buffer::Getg2dbufphys() {
+ if(g2dbuf_p0 && g2dbuf_p1)
+ return std::make_pair(g2dbuf_p0->buf_paddr, g2dbuf_p1->buf_paddr);
+ else
+ return std::make_pair(-1, -1);
+}
+
+std::pair<void*, void*> V4L2Buffer::Getg2dbufvirs() {
+ if(g2dbuf_p0 && g2dbuf_p1)
+ return std::make_pair(g2dbuf_p0->buf_vaddr, g2dbuf_p1->buf_vaddr);
+ else
+ return std::make_pair(nullptr, nullptr);
}
bool V4L2Buffer::Query() {
@@ -368,13 +495,18 @@ scoped_refptr<FrameResource> V4L2Buffer::CreateFrame() {
dmabuf_fds.emplace_back(duped_fd);
}
- if (V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type))
+ if (V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type) &&
+ format_.fmt.pix_mp.pixelformat == V4L2_PIX_FMT_NV12M_8L128) {
gfx::Size size(format_.fmt.pix_mp.width, format_.fmt.pix_mp.height);
- else
+ return NativePixmapFrameResource::Create(
+ *layout, gfx::Rect(size), size, std::move(g2dbufs_fds), base::TimeDelta());
+ }
+ else {
gfx::Size size(format_.fmt.pix.width, format_.fmt.pix.height);
- return NativePixmapFrameResource::Create(
- *layout, gfx::Rect(size), size, std::move(dmabuf_fds), base::TimeDelta());
+ return NativePixmapFrameResource::Create(
+ *layout, gfx::Rect(size), size, std::move(dmabuf_fds), base::TimeDelta());
+ }
}
const scoped_refptr<FrameResource>& V4L2Buffer::GetFrameResource() {
@@ -1112,6 +1244,10 @@ V4L2Queue::V4L2Queue(const IoctlAsCallback& ioctl_cb,
VPLOG_IF(4, supports_requests_)
<< "This queue does " << (supports_requests_ ? "" : "not")
<< " support requests.";
+
+ g2d_handle = NULL;
+ if(g2d_open && g2d_open(&g2d_handle))
+ VLOGF(1) << "g2d_open fail";
}
V4L2Queue::~V4L2Queue() {
@@ -1127,6 +1263,9 @@ V4L2Queue::~V4L2Queue() {
VQLOGF(1) << "Failed to deallocate queue buffers";
}
+ if(g2d_close && g2d_handle)
+ g2d_close(g2d_handle);
+
std::move(destroy_cb_).Run();
}
@@ -1170,6 +1309,8 @@ std::pair<std::optional<struct v4l2_format>, int> V4L2Queue::GetFormat() {
VPQLOGF(2) << "Failed to get format";
return std::make_pair(std::nullopt, errno);
}
+ if (type_ == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+ format.fmt.pix_mp.width = format.fmt.pix_mp.plane_fmt[0].bytesperline;
return std::make_pair(format, 0);
}
@@ -1529,6 +1670,68 @@ std::pair<bool, V4L2ReadableBufferRef> V4L2Queue::DequeueBuffer() {
}
DCHECK(free_buffers_);
+
+ if(type_ == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
+ buffers_[v4l2_buffer.index]->GetFmt().fmt.pix_mp.pixelformat == V4L2_PIX_FMT_NV12M_8L128)
+ {
+ std::pair<unsigned int, unsigned int> v4l_phys = buffers_[v4l2_buffer.index]->GetSavedphys();
+ int width = buffers_[v4l2_buffer.index]->GetFmt().fmt.pix_mp.width;
+ int height = buffers_[v4l2_buffer.index]->GetFmt().fmt.pix_mp.height;
+ int stride = buffers_[v4l2_buffer.index]->GetFmt().fmt.pix_mp.plane_fmt[0].bytesperline;
+ bool interlaced = false;
+ switch (buffers_[v4l2_buffer.index]->GetFmt().fmt.pix_mp.field) {
+ case V4L2_FIELD_INTERLACED:
+ case V4L2_FIELD_INTERLACED_TB:
+ case V4L2_FIELD_INTERLACED_BT:
+ case V4L2_FIELD_SEQ_TB:
+ interlaced = true;
+ break;
+ default:
+ break;
+ };
+ struct g2d_surfaceEx srcEx, dstEx;
+ struct g2d_surface *src = &srcEx.base;
+ struct g2d_surface *dst = &dstEx.base;
+
+ dst->format = G2D_NV12;
+ dst->planes[0] = buffers_[v4l2_buffer.index]->Getg2dbufphys().first;
+ dst->planes[1] = buffers_[v4l2_buffer.index]->Getg2dbufphys().second;
+ dstEx.tiling = G2D_LINEAR;
+ dst->left = 0;
+ dst->top = 0;
+ dst->right = dst->left + width;
+ dst->bottom = dst->top + height;
+ dst->stride= width;
+ dst->width = width;
+ dst->height = height;
+ dst->rot = G2D_ROTATION_0;
+ dst->global_alpha = 0xff;
+ dst->blendfunc = G2D_ONE_MINUS_SRC_ALPHA;
+ dst->clrcolor = 0;
+
+ src->format = G2D_NV12;
+ src->planes[0] = v4l_phys.first;
+ src->planes[1] = v4l_phys.second;
+ srcEx.tiling = G2D_AMPHION_TILED;
+ if (interlaced) {
+ srcEx.tiling = static_cast<g2d_tiling>(0x18); //G2D_AMPHION_TILED | G2D_AMPHION_INTERLACED;
+ DVLOGF(4)<<"interlaced video convert";
+ }
+ src->left = 0;
+ src->top = 0;
+ src->right = src->left + width;
+ src->bottom = src->top + height;
+ src->stride= stride;
+ src->width = width;
+ src->height = height;
+ src->rot = G2D_ROTATION_0;
+ src->global_alpha = 0xff;
+ src->blendfunc = G2D_ONE;
+
+ if (g2d_blitEx)
+ g2d_blitEx(g2d_handle, &srcEx, &dstEx);
+ }
+
return std::make_pair(true, V4L2BufferRefFactory::CreateReadableRef(
v4l2_buffer, weak_this_factory_.GetWeakPtr(),
std::move(queued_frame)));
diff --git a/media/gpu/v4l2/v4l2_queue.h b/media/gpu/v4l2/v4l2_queue.h
index 85c7920417935..1cc22fff58277 100644
--- a/media/gpu/v4l2/v4l2_queue.h
+++ b/media/gpu/v4l2/v4l2_queue.h
@@ -584,6 +584,7 @@ class MEDIA_GPU_EXPORT V4L2Queue
std::optional<struct v4l2_format> current_format_;
std::vector<std::unique_ptr<V4L2Buffer>> buffers_;
+ void* g2d_handle;
// Buffers that are available for client to get and submit.
// Buffers in this list are not referenced by anyone else than ourselves.
--
2.34.1

View File

@ -0,0 +1,236 @@
From 44d6b2c7ec8fc21cb3151688008384bf5fad39dc Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Fri, 13 Sep 2024 23:13:36 +0900
Subject: [PATCH 13/19] V4L2VideoDecoder: Use dlopen to dynamically use g2d api
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/v4l2/BUILD.gn | 1 -
media/gpu/v4l2/v4l2_queue.cc | 183 ++++++++++++++++++++++++++++++++++-
2 files changed, 181 insertions(+), 3 deletions(-)
diff --git a/media/gpu/v4l2/BUILD.gn b/media/gpu/v4l2/BUILD.gn
index 836ee0bc7504c..0aa466ba9cec5 100644
--- a/media/gpu/v4l2/BUILD.gn
+++ b/media/gpu/v4l2/BUILD.gn
@@ -92,7 +92,6 @@ source_set("v4l2") {
"EGL",
"GLESv2",
]
- libs += [ "g2d" ]
configs += [ "//third_party/libyuv:libyuv_config" ]
diff --git a/media/gpu/v4l2/v4l2_queue.cc b/media/gpu/v4l2/v4l2_queue.cc
index 945e7a7df9b93..9fc55cfd59459 100644
--- a/media/gpu/v4l2/v4l2_queue.cc
+++ b/media/gpu/v4l2/v4l2_queue.cc
@@ -20,10 +20,11 @@
#include "media/gpu/chromeos/platform_video_frame_utils.h"
#include "media/gpu/macros.h"
-#include "g2d.h"
-#include "g2dExt.h"
+// #include "g2d.h"
+// #include "g2dExt.h"
#include <linux/dma-buf.h>
#include <time.h>
+#include <dlfcn.h>
namespace media {
@@ -160,6 +161,159 @@ std::vector<base::ScopedFD> GetDmabufsForV4L2Buffer(
} // namespace
+/* g2d.h g2dExt.h */
+enum g2d_format
+{
+//rgb formats
+ G2D_RGB565 = 0, /* [0:4] Blue; [5:10] Green; [11:15] Red */
+ G2D_RGBA8888 = 1, /* [0:7] Red; [8:15] Green; [16:23] Blue; [23:31] Alpha */
+ G2D_RGBX8888 = 2, /* [0:7] Red; [8:15] Green; [16:23] Blue; [23:31] don't care */
+ G2D_BGRA8888 = 3, /* [0:7] Blue; [8:15] Green; [16:23] Red; [23:31] Alpha */
+ G2D_BGRX8888 = 4, /* [0:7] Blue; [8:15] Green; [16:23] Red; [23:31] don't care */
+ G2D_BGR565 = 5, /* [0:4] Red; [5:10] Green; [11:15] Blue */
+
+ G2D_ARGB8888 = 6, /* [0:7] Alpha; [8:15] Red; [16:23] Green; [23:31] Blue */
+ G2D_ABGR8888 = 7, /* [0:7] Alpha; [8:15] Blue; [16:23] Green; [23:31] Red */
+ G2D_XRGB8888 = 8, /* [0:7] don't care; [8:15] Red; [16:23] Green; [23:31] Blue */
+ G2D_XBGR8888 = 9, /* [0:7] don't care; [8:15] Blue; [16:23] Green; [23:31] Red */
+ G2D_RGB888 = 10, /* [0:7] Red; [8:15] Green; [16:23] Blue */
+ G2D_BGR888 = 11, /* [0:7] Blue; [8:15] Green; [16:23] Red */
+
+ G2D_RGBA5551 = 12, /* [0:4] Red; [5:9] Green; [10:14] Blue; [15] Alpha */
+ G2D_RGBX5551 = 13, /* [0:4] Red; [5:9] Green; [10:14] Blue; [15] don't care */
+ G2D_BGRA5551 = 14, /* [0:4] Blue; [5:9] Green; [10:14] Red; [15] Alpha */
+ G2D_BGRX5551 = 15, /* [0:4] Blue; [5:9] Green; [10:14] Red; [15] don't care */
+
+//yuv formats
+ G2D_NV12 = 20, /* 2 plane 420 format; plane 1: [0:7] Y ; plane 2: [0:7] U; [8:15] V */
+ G2D_I420 = 21, /* 3 plane 420 format; plane 1: [0:7] Y ; plane 2: [0:7] U; plane 3: [0:7] V */
+ G2D_YV12 = 22, /* 3 plane 420 format; plane 1: [0:7] Y ; plane 2: [0:7] V; plane 3: [0:7] U */
+ G2D_NV21 = 23, /* 2 plane 420 format; plane 1: [0:7] Y ; plane 2: [0:7] V; [8:15] U */
+ G2D_YUYV = 24, /* 1 plane 422 format; [0:7] Y; [8:15; U; [16:23] Y; [24:31] V */
+ G2D_YVYU = 25, /* 1 plane 422 format; [0:7] Y; [8:15; V; [16:23] Y; [24:31] U */
+ G2D_UYVY = 26, /* 1 plane 422 format; [0:7] U; [8:15; Y; [16:23] V; [24:31] Y */
+ G2D_VYUY = 27, /* 1 plane 422 format; [0:7] V; [8:15; Y; [16:23] U; [24:31] Y */
+ G2D_NV16 = 28, /* 2 plane 422 format; plane 1: [0:7] Y ; plane 2: [0:7] U; [8:15] V */
+ G2D_NV61 = 29, /* 2 plane 422 format; plane 1: [0:7] Y ; plane 2: [0:7] V; [8:15] U */
+};
+
+enum g2d_tiling
+{
+ G2D_LINEAR = 0x1,
+ G2D_TILED = 0x2,
+ G2D_SUPERTILED = 0x4,
+ G2D_AMPHION_TILED = 0x8,
+ G2D_AMPHION_INTERLACED = 0x10,
+ G2D_TILED_STATUS = 0x20,
+ G2D_AMPHION_TILED_10BIT = 0x40,
+};
+
+struct g2d_tile_status
+{
+ unsigned int ts_addr;
+
+ unsigned int fc_enabled;
+ unsigned int fc_value;
+ unsigned int fc_value_upper;
+};
+
+struct g2d_buf
+{
+ void *buf_handle;
+ void *buf_vaddr;
+ int buf_paddr;
+ int buf_size;
+};
+
+enum g2d_blend_func
+{
+//basic blend
+ G2D_ZERO = 0,
+ G2D_ONE = 1,
+ G2D_SRC_ALPHA = 2,
+ G2D_ONE_MINUS_SRC_ALPHA = 3,
+ G2D_DST_ALPHA = 4,
+ G2D_ONE_MINUS_DST_ALPHA = 5,
+
+// extensive blend is set with basic blend together,
+// such as, G2D_ONE | G2D_PRE_MULTIPLIED_ALPHA
+ G2D_PRE_MULTIPLIED_ALPHA = 0x10,
+ G2D_DEMULTIPLY_OUT_ALPHA = 0x20,
+};
+
+enum g2d_rotation
+{
+ G2D_ROTATION_0 = 0,
+ G2D_ROTATION_90 = 1,
+ G2D_ROTATION_180 = 2,
+ G2D_ROTATION_270 = 3,
+ G2D_FLIP_H = 4,
+ G2D_FLIP_V = 5,
+};
+
+struct g2d_surface
+{
+ enum g2d_format format;
+
+ int planes[3];//surface buffer addresses are set in physical planes separately
+ //RGB: planes[0] - RGB565/RGBA8888/RGBX8888/BGRA8888/BRGX8888
+ //NV12: planes[0] - Y, planes[1] - packed UV
+ //I420: planes[0] - Y, planes[1] - U, planes[2] - V
+ //YV12: planes[0] - Y, planes[1] - V, planes[2] - U
+ //NV21: planes[0] - Y, planes[1] - packed VU
+ //YUYV: planes[0] - packed YUYV
+ //YVYU: planes[0] - packed YVYU
+ //UYVY: planes[0] - packed UYVY
+ //VYUY: planes[0] - packed VYUY
+ //NV16: planes[0] - Y, planes[1] - packed UV
+ //NV61: planes[0] - Y, planes[1] - packed VU
+
+ //blit rectangle in surface
+ int left;
+ int top;
+ int right;
+ int bottom;
+ int stride; ///< buffer stride, in Pixels
+ int width; ///< surface width, in Pixels
+ int height; ///< surface height, in Pixels
+ enum g2d_blend_func blendfunc; ///< alpha blending parameters
+ int global_alpha; ///< value is 0 ~ 255
+ //clrcolor format is RGBA8888, used as dst for clear, as src for blend dim
+ int clrcolor;
+
+ //rotation degree
+ enum g2d_rotation rot;
+};
+
+struct g2d_surfaceEx
+{
+ struct g2d_surface base;
+ enum g2d_tiling tiling;
+
+ struct g2d_tile_status ts;
+ int reserved[8];
+};
+
+void *dl_handle = NULL;
+
+typedef int (*g2d_api_open)(void **handle);
+typedef int (*g2d_api_close)(void *handle);
+typedef int (*g2d_api_free)(struct g2d_buf *buf);
+typedef struct g2d_buf* (*g2d_api_alloc)(int size, int cacheable);
+typedef int (*g2d_api_buf_export_fd)(struct g2d_buf *);
+typedef int (*g2d_api_blitEx)(void *handle, struct g2d_surfaceEx *srcEx, struct g2d_surfaceEx *dstEx);
+
+#define G2D_LIB_NAME "/usr/lib/libg2d.so.2"
+#define G2D_API_SYM(name) g2d_api_##name g2d_##name = nullptr
+G2D_API_SYM(open);
+G2D_API_SYM(close);
+G2D_API_SYM(free);
+G2D_API_SYM(alloc);
+G2D_API_SYM(buf_export_fd);
+G2D_API_SYM(blitEx);
+#undef G2D_API_SYM
+/* g2d.h g2dExt.h */
+
V4L2ExtCtrl::V4L2ExtCtrl(uint32_t id) {
memset(&ctrl, 0, sizeof(ctrl));
ctrl.id = id;
@@ -1245,6 +1399,31 @@ V4L2Queue::V4L2Queue(const IoctlAsCallback& ioctl_cb,
<< "This queue does " << (supports_requests_ ? "" : "not")
<< " support requests.";
+ if (dl_handle == NULL) {
+ dl_handle = dlopen(G2D_LIB_NAME,
+ RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE | RTLD_LAZY);
+ if (!dl_handle) {
+ VLOGF(1) << "Failed to dlopen " << G2D_LIB_NAME;
+ return;
+ }
+
+#define G2D_API_DLSYM(lib, name) \
+ do { \
+ g2d_##name = reinterpret_cast<g2d_api_##name>(dlsym(lib, "g2d_" #name)); \
+ if (!(g2d_##name)) \
+ VLOGF(1) << "Failed to dlsym g2d_" #name; \
+ } while (0)
+
+ G2D_API_DLSYM(dl_handle, open);
+ G2D_API_DLSYM(dl_handle, close);
+ G2D_API_DLSYM(dl_handle, free);
+ G2D_API_DLSYM(dl_handle, alloc);
+ G2D_API_DLSYM(dl_handle, buf_export_fd);
+ G2D_API_DLSYM(dl_handle, blitEx);
+
+ dlclose(dl_handle);
+ }
+
g2d_handle = NULL;
if(g2d_open && g2d_open(&g2d_handle))
VLOGF(1) << "g2d_open fail";
--
2.34.1

View File

@ -0,0 +1,51 @@
From c8b82b832fc6c34ff27f73739c60472c15ca7380 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Fri, 13 Sep 2024 23:15:59 +0900
Subject: [PATCH 14/19] V4L2VideoDecoderBackend: Create queue according to
queried caps capabilities
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/v4l2/v4l2_video_decoder_backend.cc | 26 ++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/media/gpu/v4l2/v4l2_video_decoder_backend.cc b/media/gpu/v4l2/v4l2_video_decoder_backend.cc
index ff08c18100e0c..0e5747a5a83e7 100644
--- a/media/gpu/v4l2/v4l2_video_decoder_backend.cc
+++ b/media/gpu/v4l2/v4l2_video_decoder_backend.cc
@@ -14,8 +14,30 @@ V4L2VideoDecoderBackend::V4L2VideoDecoderBackend(
Client* const client,
scoped_refptr<V4L2Device> device)
: client_(client), device_(std::move(device)) {
- input_queue_ = device_->GetQueue(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
- output_queue_ = device_->GetQueue(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ struct v4l2_capability caps;
+ unsigned int device_caps;
+ enum v4l2_buf_type input_type, output_type;
+ if (device_->Ioctl(VIDIOC_QUERYCAP, &caps) != 0) {
+ LOG(ERROR) << "QUERYCAP failed";
+ }
+
+ if (caps.capabilities & V4L2_CAP_DEVICE_CAPS)
+ device_caps = caps.device_caps;
+ else
+ device_caps = caps.capabilities;
+
+ if (device_caps & (V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE))
+ input_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ else
+ input_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ if (device_caps & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE))
+ output_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ else
+ output_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ input_queue_ = device_->GetQueue(input_type);
+ output_queue_ = device_->GetQueue(output_type);
+
if (!input_queue_ || !output_queue_) {
VLOGF(1) << "Failed to get V4L2 queue. This should not happen since the "
<< "queues are supposed to be initialized when we are called.";
--
2.34.1

View File

@ -0,0 +1,52 @@
From f68295ed3d0a313948d8693e169933e3450156fb Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Fri, 13 Sep 2024 23:19:48 +0900
Subject: [PATCH 15/19] V4L2VideoDecoder: support gpu import NV12 format
Upstream-Status: Inappropriate [NXP specific]
---
media/mojo/services/gpu_mojo_media_client_linux.cc | 6 ++++++
ui/gfx/linux/gbm_wrapper.cc | 3 ++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/media/mojo/services/gpu_mojo_media_client_linux.cc b/media/mojo/services/gpu_mojo_media_client_linux.cc
index 6c8dcffca0505..f0be46c786975 100644
--- a/media/mojo/services/gpu_mojo_media_client_linux.cc
+++ b/media/mojo/services/gpu_mojo_media_client_linux.cc
@@ -58,6 +58,12 @@ std::vector<Fourcc> GetPreferredRenderableFourccs(
}
#endif // BUILDFLAG(ENABLE_VULKAN)
+ // HACK: Support for zero-copy NV12 textures preferentially.
+ if (gpu_preferences.gr_context_type == gpu::GrContextType::kGL) {
+ renderable_fourccs.emplace_back(Fourcc::NV12);
+ renderable_fourccs.emplace_back(Fourcc::NA12);
+ }
+
// Support 1-copy argb textures.
renderable_fourccs.emplace_back(Fourcc::AR24);
diff --git a/ui/gfx/linux/gbm_wrapper.cc b/ui/gfx/linux/gbm_wrapper.cc
index 7a1ae26444f36..b5a1f5776b90a 100644
--- a/ui/gfx/linux/gbm_wrapper.cc
+++ b/ui/gfx/linux/gbm_wrapper.cc
@@ -32,6 +32,7 @@
#include <dlfcn.h>
#include <fcntl.h>
#include <xf86drm.h>
+#include <libdrm/drm_fourcc.h>
#include "base/strings/stringize_macros.h"
#endif
@@ -414,7 +415,7 @@ class Device final : public ui::GbmDevice {
fd_data.height = size.height();
fd_data.format = format;
fd_data.num_fds = handle.planes.size();
- fd_data.modifier = handle.modifier;
+ fd_data.modifier = DRM_FORMAT_MOD_LINEAR;
// One specific situation where we expect 4 planes is for Intel media
// compressed buffers: the number of planes for such buffers and format
--
2.34.1

View File

@ -0,0 +1,55 @@
From ce372a56ed44ddd6cda68080e9594e6d02d2279a Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Fri, 13 Sep 2024 23:21:51 +0900
Subject: [PATCH 16/19] VideoDecoderPipeline: Add resolution change support
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/chromeos/video_decoder_pipeline.cc | 31 ++++++++++----------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/media/gpu/chromeos/video_decoder_pipeline.cc b/media/gpu/chromeos/video_decoder_pipeline.cc
index a92b0a297e22d..7cf16cc9faa77 100644
--- a/media/gpu/chromeos/video_decoder_pipeline.cc
+++ b/media/gpu/chromeos/video_decoder_pipeline.cc
@@ -647,21 +647,22 @@ void VideoDecoderPipeline::InitializeTask(const VideoDecoderConfig& config,
&OOPVideoDecoder::GetOriginalFrame,
base::Unretained(static_cast<OOPVideoDecoder*>(decoder_.get())));
} else {
- CHECK(main_frame_pool_);
- PlatformVideoFramePool* platform_video_frame_pool =
- main_frame_pool_->AsPlatformVideoFramePool();
- // The only |frame_converter_| that needs the GetOriginalFrameCB callback
- // is the MailboxVideoFrameConverter. When it is used, the
- // |main_frame_pool_| should always be a PlatformVideoFramePool.
- CHECK(platform_video_frame_pool);
-
- // Note: base::Unretained() is safe because either a) the
- // |main_frame_pool_| outlives |frame_converter_| or b) we call
- // |frame_converter_|->set_get_original_frame_cb() with a null
- // GetOriginalFrameCB before destroying |main_frame_pool_|.
- get_original_frame_cb =
- base::BindRepeating(&PlatformVideoFramePool::GetOriginalFrame,
- base::Unretained(platform_video_frame_pool));
+ if (main_frame_pool_) {
+ PlatformVideoFramePool* platform_video_frame_pool =
+ main_frame_pool_->AsPlatformVideoFramePool();
+ // The only |frame_converter_| that needs the GetOriginalFrameCB callback
+ // is the MailboxVideoFrameConverter. When it is used, the
+ // |main_frame_pool_| should always be a PlatformVideoFramePool.
+ CHECK(platform_video_frame_pool);
+
+ // Note: base::Unretained() is safe because either a) the
+ // |main_frame_pool_| outlives |frame_converter_| or b) we call
+ // |frame_converter_|->set_get_original_frame_cb() with a null
+ // GetOriginalFrameCB before destroying |main_frame_pool_|.
+ get_original_frame_cb =
+ base::BindRepeating(&PlatformVideoFramePool::GetOriginalFrame,
+ base::Unretained(platform_video_frame_pool));
+ }
}
frame_converter_->set_get_original_frame_cb(
--
2.34.1

View File

@ -0,0 +1,27 @@
From 074a419931f1691e312cde9da3beeb454d31ee36 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Fri, 13 Sep 2024 23:22:56 +0900
Subject: [PATCH 17/19] V4L2StatefulVideoDecoderBackend: Enlarge input buffer
number to 16
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/media/gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.cc b/media/gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.cc
index 8929feb42d89c..7d35c58d4cae8 100644
--- a/media/gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.cc
+++ b/media/gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.cc
@@ -778,7 +778,7 @@ bool V4L2StatefulVideoDecoderBackend::StopInputQueueOnResChange() const {
size_t V4L2StatefulVideoDecoderBackend::GetNumOUTPUTQueueBuffers(
bool secure_mode) const {
CHECK(!secure_mode);
- constexpr size_t kNumInputBuffers = 8;
+ constexpr size_t kNumInputBuffers = 16;
return kNumInputBuffers;
}
--
2.34.1

View File

@ -0,0 +1,27 @@
From 4ca9aa503552e9b052b85512e3d1fe24998de195 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Fri, 13 Sep 2024 23:23:56 +0900
Subject: [PATCH 18/19] V4L2VideoDecoder: Fix amphion report size mismatch
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/v4l2/v4l2_video_decoder.cc | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/media/gpu/v4l2/v4l2_video_decoder.cc b/media/gpu/v4l2/v4l2_video_decoder.cc
index 4a2591f092f42..4c33ed4fea41f 100644
--- a/media/gpu/v4l2/v4l2_video_decoder.cc
+++ b/media/gpu/v4l2/v4l2_video_decoder.cc
@@ -736,7 +736,8 @@ CroStatus V4L2VideoDecoder::SetupOutputFormat(const gfx::Size& size,
output_queue_->SetFormat(fourcc.ToV4L2PixFmt(), picked_size, 0);
DCHECK(format);
gfx::Size adjusted_size(format->fmt.pix_mp.width, format->fmt.pix_mp.height);
- if (!gfx::Rect(adjusted_size).Contains(gfx::Rect(picked_size))) {
+ if (fourcc != std::optional<Fourcc>(Fourcc(Fourcc::NA12)) &&
+ !gfx::Rect(adjusted_size).Contains(gfx::Rect(picked_size))) {
VLOGF(1) << "The adjusted coded size (" << adjusted_size.ToString()
<< ") should contains the original coded size("
<< picked_size.ToString() << ").";
--
2.34.1

View File

@ -0,0 +1,27 @@
From 5bfdec4c48af188f30534914fbd9c3aa9d140503 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Thu, 19 Sep 2024 15:12:47 +0900
Subject: [PATCH 19/19] VideoDecoderPipeline: Get V4L2VideoDecoder supported
configs
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/chromeos/video_decoder_pipeline.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/media/gpu/chromeos/video_decoder_pipeline.cc b/media/gpu/chromeos/video_decoder_pipeline.cc
index 7cf16cc9faa77..7bffad93cfd5e 100644
--- a/media/gpu/chromeos/video_decoder_pipeline.cc
+++ b/media/gpu/chromeos/video_decoder_pipeline.cc
@@ -356,7 +356,7 @@ VideoDecoderPipeline::GetSupportedConfigs(
break;
#elif BUILDFLAG(USE_V4L2_CODEC)
case VideoDecoderType::kV4L2:
- configs = GetSupportedV4L2DecoderConfigs();
+ configs = V4L2VideoDecoder::GetSupportedConfigs();
break;
#endif
default:
--
2.34.1

View File

@ -0,0 +1,61 @@
From 2cf45a6abd796448126d1c1cc6f13e5e347d8c05 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Wed, 23 Oct 2024 19:08:46 +0900
Subject: [PATCH] V4L2VideoDecoder: Fix amphion cannot streamoff after eos
Amphion vpu driver directly return EPIPE without dequeuing extra
empty buffer when eos. Need to streamoff correctly for this case.
Upstream-Status: Inappropriate [NXP specific]
---
.../gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.cc | 6 ++++--
media/gpu/v4l2/v4l2_video_decoder.cc | 2 +-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/media/gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.cc b/media/gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.cc
index 7d35c58d4cae8..4bd6ac7fe1fcf 100644
--- a/media/gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.cc
+++ b/media/gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.cc
@@ -4,6 +4,7 @@
#include "media/gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.h"
+#include <errno.h>
#include <cstddef>
#include <memory>
#include <optional>
@@ -438,7 +439,7 @@ void V4L2StatefulVideoDecoderBackend::OnOutputBufferDequeued(
DVLOGF(3);
// Zero-bytes buffers are returned as part of a flush and can be dismissed.
- if (buffer->GetPlaneBytesUsed(0) > 0) {
+ if (buffer && buffer->GetPlaneBytesUsed(0) > 0) {
// TODO(mcasas): Consider using TimeValToTimeDelta().
const struct timeval timeval = buffer->GetTimeStamp();
const struct timespec timespec = {
@@ -489,7 +490,8 @@ void V4L2StatefulVideoDecoderBackend::OnOutputBufferDequeued(
// The order here is important! A flush event may come after a resolution
// change event (but not the opposite), so we must make sure both events
// are processed in the correct order.
- if (buffer->IsLast()){
+ if (errno == EPIPE || buffer->IsLast()){
+ VLOGF(3) << "Got buffer with last flag or got EPIPE";
// Check that we don't have a resolution change event pending. If we do
// then this LAST buffer was related to it.
ProcessEventQueue();
diff --git a/media/gpu/v4l2/v4l2_video_decoder.cc b/media/gpu/v4l2/v4l2_video_decoder.cc
index 4c33ed4fea41f..d0f35414c69c9 100644
--- a/media/gpu/v4l2/v4l2_video_decoder.cc
+++ b/media/gpu/v4l2/v4l2_video_decoder.cc
@@ -1282,7 +1282,7 @@ void V4L2VideoDecoder::ServiceDeviceTask(bool event) {
SetState(State::kError);
return;
}
- if (!dequeued_buffer)
+ if (!dequeued_buffer && errno != EPIPE)
break;
if (backend_)
--
2.34.1

View File

@ -0,0 +1,37 @@
From 13e0146475ec26b59c706249c7a61c7d9ee2d360 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Mon, 18 Nov 2024 14:59:51 +0900
Subject: [PATCH] V4L2VideoDecoder: Set OUTPUT format with parsed resolution
For VP8, VC1l, rv, amphion needs to set correct resolution for OUTPUT
queue as it will be added to amphion customized header.
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/v4l2/v4l2_video_decoder.cc | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/media/gpu/v4l2/v4l2_video_decoder.cc b/media/gpu/v4l2/v4l2_video_decoder.cc
index d0f35414c69c9..05c8d61f5f9fb 100644
--- a/media/gpu/v4l2/v4l2_video_decoder.cc
+++ b/media/gpu/v4l2/v4l2_video_decoder.cc
@@ -328,6 +328,7 @@ void V4L2VideoDecoder::Initialize(const VideoDecoderConfig& config,
aspect_ratio_ = config.aspect_ratio();
color_space_ = config.color_space_info();
current_resolution_ = config.visible_rect().size();
+ VLOGF(3) << "resolution is " << current_resolution_.width() << "x" << current_resolution_.height();
if (profile_ == VIDEO_CODEC_PROFILE_UNKNOWN) {
VLOGF(1) << "Unknown profile.";
@@ -632,7 +633,7 @@ bool V4L2VideoDecoder::SetupInputFormat() {
// Setup the input format.
auto format =
- input_queue_->SetFormat(input_format_fourcc_, gfx::Size(), input_size);
+ input_queue_->SetFormat(input_format_fourcc_, current_resolution_, input_size);
if (!format) {
VPLOGF(1) << "Failed to call IOCTL to set input format.";
return false;
--
2.34.1

View File

@ -0,0 +1,108 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
SRC_URI:append:imx-nxp-bsp = " \
file://0001-Fixed-chromium-flicker-with-g2d-renderer.patch \
file://0002-Disable-dri-for-imx-gpu.patch \
file://0003-Fix-chromium-build-failure.patch \
file://0004-Fixed-chromium-crash-after-upgrading.patch \
file://0005-MGS-7765-Blacklist-MSAA-for-GPU-Raster-on-Vivante-GP.patch \
file://0006-LF-12406-Fixed-webgl-test-fail-for-GL_MAX_SAMPLES-ch.patch \
file://0007-Enable-native-GLES2-for-Ozone-wayland.patch \
file://0008-Fix-build-fail-after-clang-llvm-upgrade.patch \
file://0009-Fix-chromium-crash-when-run-webgl-2.0.0-cts.patch \
file://0010-Fix-canvas-test-fail-for-webgl.patch \
file://0011-LF-12406-1-Blacklist-disable-program_caching_for_tra.patch \
"
VDA_PATCH_SET = " \
file://0101-V4L2Device-Correct-v4l2-codec-device-path.patch \
file://0102-V4L2VideoDecoder-Add-macro-use_linux_v4l2.patch \
file://0103-V4L2VideoDecoder-Create-single-multi-plane-queues.patch \
file://0104-V4L2Buffer-Allocate-correct-v4l2-buffers-for-queues.patch \
file://0105-V4L2VideoDecoder-Create-videoframe-according-to-v4l2.patch \
file://0106-V4L2VideoDecoder-Add-function-IsMultiQueue-for-S_FMT.patch \
file://0107-V4L2VideoDecoder-Use-correct-plane-size-and-bytesuse.patch \
file://0108-V4L2VideoDecoder-Add-hevc-format-support.patch \
file://0109-display-Add-fps-in-SkiaOutputSurfaceImplOnGpu-by-VLO.patch \
file://0110-V4L2VideoDecoder-Comment-some-unused-ioctl.patch \
file://0111-V4L2VideoDecoder-Add-V4L2_PIX_FMT_NV12M_8L128-format.patch \
file://0112-V4L2VideoDecoder-Support-tile-to-linear-transform-fo.patch \
file://0113-V4L2VideoDecoder-Use-dlopen-to-dynamically-use-g2d-a.patch \
file://0114-V4L2VideoDecoderBackend-Create-queue-according-to-qu.patch \
file://0115-V4L2VideoDecoder-support-gpu-import-NV12-format.patch \
file://0116-VideoDecoderPipeline-Add-resolution-change-support.patch \
file://0117-V4L2StatefulVideoDecoderBackend-Enlarge-input-buffer.patch \
file://0118-V4L2VideoDecoder-Fix-amphion-report-size-mismatch.patch \
file://0119-VideoDecoderPipeline-Get-V4L2VideoDecoder-supported-.patch \
file://0120-V4L2VideoDecoder-Fix-amphion-cannot-streamoff-after-.patch \
file://0121-V4L2VideoDecoder-Set-OUTPUT-format-with-parsed-resol.patch \
"
SRC_URI:append:mx8-nxp-bsp = " ${VDA_PATCH_SET}"
SRC_URI:append:mx95-nxp-bsp = " ${VDA_PATCH_SET}"
GN_ARGS_DISABLE_GBM = ""
GN_ARGS_DISABLE_GBM:mx6-nxp-bsp = "use_system_minigbm=false use_wayland_gbm=false"
GN_ARGS_DISABLE_GBM:mx7-nxp-bsp = "${GN_ARGS_DISABLE_GBM:mx6-nxp-bsp}"
GN_ARGS_USE_IMXGPU = "use_imxgpu=false"
GN_ARGS_USE_IMXGPU:imxgpu = "use_imxgpu=true"
GN_ARGS_ENABLE_PROPRIETARY_CODECS = ""
GN_ARGS_ENABLE_PROPRIETARY_CODECS:mx8-nxp-bsp = "proprietary_codecs=true"
GN_ARGS_ENABLE_PROPRIETARY_CODECS:mx95-nxp-bsp = "proprietary_codecs=true"
GN_ARGS_FFMPEG_BRANDING = ""
GN_ARGS_FFMPEG_BRANDING:mx8-nxp-bsp = "ffmpeg_branding="Chrome""
GN_ARGS_FFMPEG_BRANDING:mx95-nxp-bsp = "ffmpeg_branding="Chrome""
GN_ARGS_USE_V4L2_CODEC = ""
GN_ARGS_USE_V4L2_CODEC:mx8-nxp-bsp = "use_v4l2_codec=true"
GN_ARGS_USE_V4L2_CODEC:mx95-nxp-bsp = "use_v4l2_codec=true"
GN_ARGS_USE_LINUX_V4L2_ONLY = ""
GN_ARGS_USE_LINUX_V4L2_ONLY:mx8-nxp-bsp = "use_linux_v4l2_only=true"
GN_ARGS_USE_LINUX_V4L2_ONLY:mx95-nxp-bsp = "use_linux_v4l2_only=true"
GN_ARGS:append:imx-nxp-bsp = " \
${GN_ARGS_DISABLE_GBM} \
${GN_ARGS_USE_IMXGPU} \
${GN_ARGS_ENABLE_PROPRIETARY_CODECS} \
${GN_ARGS_FFMPEG_BRANDING} \
${GN_ARGS_USE_V4L2_CODEC} \
${GN_ARGS_USE_LINUX_V4L2_ONLY} \
use_pulseaudio=true \
"
DEPENDS:append = " pulseaudio"
CHROMIUM_EXTRA_ARGS_ENABLE_ANGLE = ""
CHROMIUM_EXTRA_ARGS_ENABLE_ANGLE:mx93-nxp-bsp = "--use-gl=angle --use-angle=gles-egl"
CHROMIUM_EXTRA_ARGS_ENABLE_ANGLE:mx943-nxp-bsp = "--use-gl=angle --use-angle=gles-egl"
CHROMIUM_EXTRA_ARGS:remove:mx93-nxp-bsp = "--use-gl=egl"
CHROMIUM_EXTRA_ARGS:remove:mx943-nxp-bsp = "--use-gl=egl"
CHROMIUM_EXTRA_ARGS:append = " \
--disable-features=VizDisplayCompositor \
--in-process-gpu \
--disable-gpu-rasterization \
${CHROMIUM_EXTRA_ARGS_ENABLE_ANGLE} \
"
#Remove installed ANGLE libraries
do_install:append:mx6-nxp-bsp() {
rm -rf ${D}${libdir}/chromium/libEGL.so
rm -rf ${D}${libdir}/chromium/libGLESv2.so
rm -rf ${D}${libdir}/chromium/libvulkan.so.1
}
do_install:append:mx7-nxp-bsp() {
rm -rf ${D}${libdir}/chromium/libEGL.so
rm -rf ${D}${libdir}/chromium/libGLESv2.so
rm -rf ${D}${libdir}/chromium/libvulkan.so.1
}
do_install:append:mx8-nxp-bsp() {
rm -rf ${D}${libdir}/chromium/libEGL.so
rm -rf ${D}${libdir}/chromium/libGLESv2.so
rm -rf ${D}${libdir}/chromium/libvulkan.so.1
}
do_install:append:mx95-nxp-bsp() {
rm -rf ${D}${libdir}/chromium/libEGL.so
rm -rf ${D}${libdir}/chromium/libGLESv2.so
rm -rf ${D}${libdir}/chromium/libvulkan.so.1
}