Complete Yocto mirror with license table for TQMa6UL (2038-compliance)

- 264 license table entries with exact download URLs (224/264 resolved)
- Complete sources/ directory with all BitBake recipes
- Build configuration: tqma6ul-multi-mba6ulx, spaetzle (musl)
- Full traceability for Softwarefreigabeantrag
- GCC 13.4.0, Linux 6.6.102, U-Boot 2023.04, musl 1.2.4
- License distribution: GPL-2.0 (24), MIT (23), GPL-2.0+ (18), BSD-3 (16)
This commit is contained in:
Siggi (OpenClaw Agent)
2026-03-01 20:58:18 +00:00
commit 16accb6b24
15086 changed files with 1292356 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
From dc5f1312aec01a20f14c822f8db351e98274941a 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/4] 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 acb4a60ba0..e93533ceca 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.25.1

View File

@@ -0,0 +1,77 @@
From 352d0c30aac32339a7139d321a3d95a8f342e17f Mon Sep 17 00:00:00 2001
From: Darren Etheridge <a0867391@uda0393673-1.dhcp.ti.com>
Date: Mon, 20 May 2024 15:48:36 -0500
Subject: [PATCH] chromium: gpu: sandbox: allow access to PowerVR GPU from
sandbox
Upstream-Status: Pending [not strictly necessary, but reduces
permissions warnings on console]
Chromium runs in a sandbox to limit access to the system, however
the PowerVR drivers for the Imagination GPU used on TI hardware need
some extra libraries along with the DRM device nodes to be opened up.
This patch opens up the necessary pieces.
Signed-off-by: Darren Etheridge <detheridge@ti.com>
---
content/common/gpu_pre_sandbox_hook_linux.cc | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/content/common/gpu_pre_sandbox_hook_linux.cc b/content/common/gpu_pre_sandbox_hook_linux.cc
index f5df3c667d..ad7b26aec7 100644
--- a/content/common/gpu_pre_sandbox_hook_linux.cc
+++ b/content/common/gpu_pre_sandbox_hook_linux.cc
@@ -67,6 +67,11 @@ inline bool UseChromecastSandboxAllowlist() {
#endif
}
+inline bool IsGPUIMGRogue() {
+ return true;
+}
+
+
inline bool IsArchitectureArm() {
#if defined(ARCH_CPU_ARM_FAMILY)
return true;
@@ -495,6 +500,11 @@ std::vector<BrokerFilePermission> FilePermissionsForGpu(
AddVulkanICDPermissions(&permissions);
+ if (IsGPUIMGRogue()) {
+ // Add standard DRM permissions for snapdragon/PowerVR:
+ AddDrmGpuPermissions(&permissions);
+ }
+
if (IsChromeOS()) {
// Permissions are additive, there can be multiple GPUs in the system.
AddStandardChromeOsPermissions(&permissions);
@@ -573,6 +583,8 @@ void LoadArmGpuLibraries() {
DRI_DRIVER_DIR "/mediatek_dri.so",
DRI_DRIVER_DIR "/rockchip_dri.so",
DRI_DRIVER_DIR "/asahi_dri.so",
+ DRI_DRIVER_DIR "/pvr_dri.so",
+ DRI_DRIVER_DIR "/tidss_dri.so",
#else
"/usr/lib64/dri/msm_dri.so",
"/usr/lib64/dri/panfrost_dri.so",
@@ -580,6 +592,8 @@ void LoadArmGpuLibraries() {
"/usr/lib64/dri/rockchip_dri.so",
"/usr/lib64/dri/asahi_dri.so",
"/usr/lib/dri/msm_dri.so",
+ "/usr/lib/dri/tidss_dri.so",
+ "/usr/lib/dri/pvr_dri.so",
"/usr/lib/dri/panfrost_dri.so",
"/usr/lib/dri/mediatek_dri.so",
"/usr/lib/dri/rockchip_dri.so",
@@ -677,7 +691,7 @@ sandbox::syscall_broker::BrokerCommandSet CommandSetForGPU(
command_set.set(sandbox::syscall_broker::COMMAND_ACCESS);
command_set.set(sandbox::syscall_broker::COMMAND_OPEN);
command_set.set(sandbox::syscall_broker::COMMAND_STAT);
- if (IsChromeOS() &&
+ if ((IsGPUIMGRogue() || IsChromeOS()) &&
(options.use_amd_specific_policies ||
options.use_intel_specific_policies ||
options.use_nvidia_specific_policies ||
--
2.45.2

View File

@@ -0,0 +1,34 @@
From a328a5a561ffd405c6f81d7cab377811b02fdb84 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 2/4] 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 5b68e7d051..8ba11ca00a 100644
--- a/ui/gl/BUILD.gn
+++ b/ui/gl/BUILD.gn
@@ -240,7 +240,7 @@ component("gl") {
}
if (use_ozone) {
- if (use_egl && !is_fuchsia) {
+ if (use_egl && !is_fuchsia && !ozone_platform_wayland) {
data_deps += [
"//third_party/angle:libEGL",
"//third_party/angle:libGLESv2",
--
2.25.1

View File

@@ -0,0 +1,54 @@
From 99b7f0b617e0169c90e7f98246ac92ab00afd262 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 3/4] 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 ++++++-
media/gpu/sandbox/BUILD.gn | 2 +-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/content/gpu/BUILD.gn b/content/gpu/BUILD.gn
index 098082510e..9befdb8c01 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" ]
}
}
diff --git a/media/gpu/sandbox/BUILD.gn b/media/gpu/sandbox/BUILD.gn
index cfcb7fa80e..de7e70c3bf 100644
--- a/media/gpu/sandbox/BUILD.gn
+++ b/media/gpu/sandbox/BUILD.gn
@@ -31,7 +31,7 @@ source_set("sandbox") {
deps += [ "//media/gpu/v4l2" ]
}
if (current_cpu != "s390x" && current_cpu != "ppc64" && is_linux &&
- !is_castos) {
+ !is_castos && !true) {
# For DRI_DRIVER_DIR.
configs += [ "//build/config/linux/dri" ]
}
--
2.25.1

View File

@@ -0,0 +1,46 @@
From a8f5c1646362c0fb3e60d711cd5edf07c9ef0fa7 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 4/4] 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 8ba11ca00a..0d511776ba 100644
--- a/ui/gl/BUILD.gn
+++ b/ui/gl/BUILD.gn
@@ -249,6 +249,15 @@ component("gl") {
data_deps += [ "//third_party/vulkan-deps/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.25.1

View File

@@ -0,0 +1,82 @@
From a2489f733bb842ee6aa222a97b108e18521e5ee1 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 6/6] 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 8fd34e8c7d..fa5e6a5854 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 8d60e2c720..499ad5d9ec 100644
--- a/ui/gfx/linux/gbm_wrapper.cc
+++ b/ui/gfx/linux/gbm_wrapper.cc
@@ -462,6 +462,8 @@ class Device final : public ui::GbmDevice {
}
#endif
+ gbm_device* get() override {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 4e725c5814..0258548fd8 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 b6e99324c0..410c2e9288 100644
--- a/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
+++ b/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
@@ -171,6 +171,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 gl::EGLDisplayPlatform(
reinterpret_cast<EGLNativeDisplayType>(connection_->display()));
--
2.25.1

View File

@@ -0,0 +1,35 @@
From 88167a0bb3665834cdcdacee2b5c8afdb8555db9 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Wed, 17 Aug 2022 16:57:11 +0800
Subject: [PATCH 101/120] V4L2VDA: Switch to use VDA instead of direct
VideoDecoder
commit b7f3a9e8058f593d7d88b6b6cafa71957aa3f1a1 aims to default
enable "direct VideoDecoder" support on Linux. So need to switch
to use VDA path iff:
1. kVaapiVideoDecodeLinux is enabled (disabled by default);
2. kUseChromeOSDirectVideoDecoder is disabled (enabled by default);
3. GL is used;
Upstream-Status: Inappropriate [NXP specific]
---
media/base/media_switches.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index 58025f50ce..77011a3e84 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -1252,7 +1252,7 @@ BASE_FEATURE(kChromeOSHWVBREncoding,
// TODO(b/159825227): remove when the direct video decoder is fully launched.
BASE_FEATURE(kUseChromeOSDirectVideoDecoder,
"UseChromeOSDirectVideoDecoder",
- base::FEATURE_ENABLED_BY_DEFAULT);
+ base::FEATURE_DISABLED_BY_DEFAULT);
#endif // !BUILDFLAG(USE_VAAPI)
// Limit the number of concurrent hardware decoder instances on ChromeOS.
--
2.25.1

View File

@@ -0,0 +1,31 @@
From e609e5db0a02dff77475beddc9e616818ed0f892 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Wed, 1 Nov 2023 18:55:31 +0900
Subject: [PATCH 102/120] GenericV4L2Device: Correct v4l2 decoder device path
Change decoder 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 e9fc02a472..326a39273a 100644
--- a/media/gpu/v4l2/v4l2_device.cc
+++ b/media/gpu/v4l2/v4l2_device.cc
@@ -849,8 +849,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.25.1

View File

@@ -0,0 +1,233 @@
From 41142ef256f7f58adf944ab4e910586bcce5dcaf Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Fri, 2 Sep 2022 13:18:34 +0800
Subject: [PATCH 103/120] V4L2VDA: 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 +++
.../gpu_video_decode_accelerator_factory.h | 2 ++
media/gpu/v4l2/BUILD.gn | 19 +++++++++----
media/gpu/v4l2/v4l2_utils.cc | 28 +++++++++++++++++++
media/gpu/v4l2/v4l2_video_decoder.cc | 8 ++++++
7 files changed, 58 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 8e8ad4a848..156b6bd256 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 0bb5edad02..a55fbd2325 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 37751112e3..49939b896e 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/gpu_video_decode_accelerator_factory.h b/media/gpu/gpu_video_decode_accelerator_factory.h
index 27ed3a8c90..27c06e2506 100644
--- a/media/gpu/gpu_video_decode_accelerator_factory.h
+++ b/media/gpu/gpu_video_decode_accelerator_factory.h
@@ -94,11 +94,13 @@ class MEDIA_GPU_EXPORT GpuVideoDecodeAcceleratorFactory {
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log) const;
+#if !BUILDFLAG(USE_LINUX_V4L2)
std::unique_ptr<VideoDecodeAccelerator> CreateV4L2SliceVDA(
const gpu::GpuDriverBugWorkarounds& workarounds,
const gpu::GpuPreferences& gpu_preferences,
MediaLog* media_log) const;
#endif
+#endif
#if BUILDFLAG(IS_APPLE)
std::unique_ptr<VideoDecodeAccelerator> CreateVTVDA(
const gpu::GpuDriverBugWorkarounds& workarounds,
diff --git a/media/gpu/v4l2/BUILD.gn b/media/gpu/v4l2/BUILD.gn
index cf469a68cd..a790c4910a 100644
--- a/media/gpu/v4l2/BUILD.gn
+++ b/media/gpu/v4l2/BUILD.gn
@@ -34,9 +34,6 @@ source_set("v4l2") {
"stateless/vp8_delegate.h",
"stateless/vp9_delegate.cc",
"stateless/vp9_delegate.h",
- "v4l2_decode_surface.cc",
- "v4l2_decode_surface.h",
- "v4l2_decode_surface_handler.h",
"v4l2_device.cc",
"v4l2_device.h",
"v4l2_device_poller.cc",
@@ -59,6 +56,17 @@ source_set("v4l2") {
"v4l2_video_decoder_backend.h",
"v4l2_video_decoder_backend_stateful.cc",
"v4l2_video_decoder_backend_stateful.h",
+ "v4l2_video_encode_accelerator.cc",
+ "v4l2_video_encode_accelerator.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",
@@ -67,9 +75,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 f0dfacdf62..afea7a870a 100644
--- a/media/gpu/v4l2/v4l2_utils.cc
+++ b/media/gpu/v4l2/v4l2_utils.cc
@@ -315,15 +315,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},
@@ -478,7 +486,27 @@ uint32_t VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile,
<< "Unsupported profile: " << GetProfileName(profile);
const auto& v4l2_pix_fmt = kVideoCodecProfileToV4L2CodecPixFmt.at(profile);
+#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 1ba50a5aa6..c6c5d4cb6c 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/v4l2_status.h"
#include "media/gpu/v4l2/v4l2_utils.h"
#include "media/gpu/v4l2/v4l2_video_decoder_backend_stateful.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,
@@ -76,13 +79,16 @@ const std::vector<uint32_t> kSupportedInputFourccs = {
V4L2_PIX_FMT_VP9_FRAME,
V4L2_PIX_FMT_AV1_FRAME,
// V4L2 stateful formats
+#endif
V4L2_PIX_FMT_H264,
#if BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
V4L2_PIX_FMT_HEVC,
#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.25.1

View File

@@ -0,0 +1,148 @@
From ea21db0b46091c76a2e389874617c64b69c768ce Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Wed, 1 Nov 2023 23:20:47 +0900
Subject: [PATCH 104/120] V4L2VDA: 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]
---
.../legacy/v4l2_video_decode_accelerator.cc | 28 +++++++++++++-----
media/gpu/v4l2/v4l2_device.cc | 29 ++++++++++++++-----
2 files changed, 42 insertions(+), 15 deletions(-)
diff --git a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
index 0269d7ca74..ad73ac674e 100644
--- a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
@@ -324,21 +324,35 @@ bool V4L2VideoDecodeAccelerator::CheckConfig(const Config& config) {
// Capabilities check.
struct v4l2_capability caps;
- const __u32 kCapsRequired = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
- IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_QUERYCAP, &caps);
- if ((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) {
+ VPLOGF(1) << "ioctl() failed: VIDIOC_QUERYCAP"
+ << ", caps check failed: 0x" << std::hex << caps.capabilities;
return false;
}
+ 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;
+
output_mode_ = config.output_mode;
- input_queue_ = device_->GetQueue(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
+ input_queue_ = device_->GetQueue(input_type);
if (!input_queue_)
return false;
- output_queue_ = device_->GetQueue(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+ output_queue_ = device_->GetQueue(output_type);
if (!output_queue_)
return false;
diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
index 326a39273a..daea76c9b6 100644
--- a/media/gpu/v4l2/v4l2_device.cc
+++ b/media/gpu/v4l2/v4l2_device.cc
@@ -93,6 +93,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;
@@ -539,9 +541,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)) {
@@ -856,27 +866,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;
}
@@ -896,6 +907,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;
}
@@ -909,6 +921,7 @@ void V4L2Device::EnumerateDevicesForType(Type type) {
CloseDevice();
}
+ }
DCHECK_EQ(devices_by_type_.count(type), 0u);
devices_by_type_[type] = devices;
--
2.25.1

View File

@@ -0,0 +1,97 @@
From d004057743fcb63fa6b0e28ad2c3dfd945c7c7d2 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Wed, 1 Nov 2023 23:27:25 +0900
Subject: [PATCH 105/120] 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 2e93c0bd8b..cae8d72a1d 100644
--- a/media/gpu/v4l2/v4l2_queue.cc
+++ b/media/gpu/v4l2/v4l2_queue.cc
@@ -236,24 +236,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);
}
}
}
@@ -267,6 +271,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;
@@ -290,9 +301,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.25.1

View File

@@ -0,0 +1,155 @@
From e284a3ab9ce5aef1c2fcc3e4feed4b4963b0340d Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Wed, 1 Nov 2023 23:41:23 +0900
Subject: [PATCH 106/120] V4L2VDA: 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 cae8d72a1d..df91ef0169 100644
--- a/media/gpu/v4l2/v4l2_queue.cc
+++ b/media/gpu/v4l2/v4l2_queue.cc
@@ -333,7 +333,7 @@ scoped_refptr<VideoFrame> V4L2Buffer::CreateVideoFrame() {
}
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";
@@ -360,7 +360,10 @@ scoped_refptr<VideoFrame> V4L2Buffer::CreateVideoFrame() {
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 VideoFrame::WrapExternalDmabufs(
*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 afea7a870a..7131cba379 100644
--- a/media/gpu/v4l2/v4l2_utils.cc
+++ b/media/gpu/v4l2/v4l2_utils.cc
@@ -217,13 +217,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: "
@@ -231,7 +227,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(): "
@@ -249,9 +245,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.
@@ -265,8 +269,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:
@@ -274,13 +282,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,
@@ -299,13 +312,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.25.1

View File

@@ -0,0 +1,184 @@
From f292a840f85cd97ef1f39dd5a929e65b252d9cdc Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Wed, 1 Nov 2023 23:47:31 +0900
Subject: [PATCH 107/120] V4L2VDA: 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]
---
.../legacy/v4l2_video_decode_accelerator.cc | 49 +++++++++++++++----
media/gpu/v4l2/v4l2_queue.cc | 36 +++++++++++---
media/gpu/v4l2/v4l2_queue.h | 1 +
3 files changed, 68 insertions(+), 18 deletions(-)
diff --git a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
index ad73ac674e..aa7253928a 100644
--- a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
@@ -2056,12 +2056,30 @@ bool V4L2VideoDecodeAccelerator::GetFormatInfo(struct v4l2_format* format,
}
// Make sure we are still getting the format we set on initialization.
- if (format->fmt.pix_mp.pixelformat != output_format_fourcc_->ToV4L2PixFmt()) {
+ unsigned int pixelformat = V4L2_TYPE_IS_MULTIPLANAR(format->type) ?
+ format->fmt.pix_mp.pixelformat : format->fmt.pix.pixelformat;
+ if (pixelformat != output_format_fourcc_->ToV4L2PixFmt()) {
VLOGF(1) << "Unexpected format from G_FMT on output";
return false;
}
- gfx::Size coded_size(format->fmt.pix_mp.width, format->fmt.pix_mp.height);
+ int width, height;
+ if (V4L2_TYPE_IS_MULTIPLANAR(format->type)) {
+ width = format->fmt.pix_mp.width;
+ height = format->fmt.pix_mp.height;
+ if ((format->fmt.pix_mp.width == 0) && (format->fmt.pix_mp.height == 0))
+ {
+ *again = true;
+ VLOG(1)<<"As got width=height=0 again";
+ } else {
+ VLOG(1)<<"format wxh" << format->fmt.pix_mp.width << "x" << format->fmt.pix_mp.height;
+ }
+ } else {
+ width = format->fmt.pix.width;
+ height = format->fmt.pix.height;
+ }
+
+ gfx::Size coded_size(width, height);
if (visible_size != nullptr)
*visible_size = GetVisibleSize(coded_size);
@@ -2168,7 +2186,7 @@ bool V4L2VideoDecodeAccelerator::SetupFormats() {
struct v4l2_fmtdesc fmtdesc;
memset(&fmtdesc, 0, sizeof(fmtdesc));
- fmtdesc.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ fmtdesc.type = input_queue_->IsMultiQueue() ? V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE : V4L2_BUF_TYPE_VIDEO_OUTPUT;
bool is_format_supported = false;
while (device_->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0) {
if (fmtdesc.pixelformat == input_format_fourcc_) {
@@ -2186,10 +2204,16 @@ bool V4L2VideoDecodeAccelerator::SetupFormats() {
struct v4l2_format format;
memset(&format, 0, sizeof(format));
- format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
- format.fmt.pix_mp.pixelformat = input_format_fourcc_;
- format.fmt.pix_mp.plane_fmt[0].sizeimage = input_size;
- format.fmt.pix_mp.num_planes = 1;
+ if (input_queue_->IsMultiQueue()) {
+ format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ format.fmt.pix_mp.pixelformat = input_format_fourcc_;
+ format.fmt.pix_mp.plane_fmt[0].sizeimage = input_size;
+ format.fmt.pix_mp.num_planes = 1;
+ } else {
+ format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ format.fmt.pix.pixelformat = input_format_fourcc_;
+ format.fmt.pix.sizeimage = input_size;
+ }
IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format);
DCHECK_EQ(format.fmt.pix_mp.pixelformat, input_format_fourcc_);
@@ -2197,7 +2221,7 @@ bool V4L2VideoDecodeAccelerator::SetupFormats() {
// changing it once we start streaming; whether it can support our chosen
// output format or not may depend on the input format.
memset(&fmtdesc, 0, sizeof(fmtdesc));
- fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmtdesc.type = output_queue_->IsMultiQueue() ? V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE : V4L2_BUF_TYPE_VIDEO_CAPTURE;
while (device_->Ioctl(VIDIOC_ENUM_FMT, &fmtdesc) == 0) {
auto fourcc = Fourcc::FromV4L2PixFmt(fmtdesc.pixelformat);
if (fourcc && device_->CanCreateEGLImageFrom(*fourcc)) {
@@ -2244,8 +2268,13 @@ bool V4L2VideoDecodeAccelerator::SetupFormats() {
// Just set the fourcc for output; resolution, etc., will come from the
// driver once it extracts it from the stream.
memset(&format, 0, sizeof(format));
- format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
- format.fmt.pix_mp.pixelformat = output_format_fourcc_->ToV4L2PixFmt();
+ if (output_queue_->IsMultiQueue()) {
+ format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ format.fmt.pix_mp.pixelformat = output_format_fourcc_->ToV4L2PixFmt();
+ } else {
+ format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ format.fmt.pix.pixelformat = output_format_fourcc_->ToV4L2PixFmt();
+ }
IOCTL_OR_ERROR_RETURN_FALSE(VIDIOC_S_FMT, &format);
DCHECK_EQ(format.fmt.pix_mp.pixelformat,
output_format_fourcc_->ToV4L2PixFmt());
diff --git a/media/gpu/v4l2/v4l2_queue.cc b/media/gpu/v4l2/v4l2_queue.cc
index df91ef0169..3d08149929 100644
--- a/media/gpu/v4l2/v4l2_queue.cc
+++ b/media/gpu/v4l2/v4l2_queue.cc
@@ -40,11 +40,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 b71ae14495..532b991f68 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.
--
2.25.1

View File

@@ -0,0 +1,43 @@
From 65e24611d443dbc8132c8be94cd8630041b90cd3 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Wed, 1 Nov 2023 23:48:55 +0900
Subject: [PATCH 108/120] V4L2VDA: Use correct size to allocate CAPTURE buffer
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
index aa7253928a..32b7e97338 100644
--- a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
@@ -2092,7 +2092,10 @@ bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat(
DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
size_t egl_image_planes_count;
- coded_size_.SetSize(format.fmt.pix_mp.width, format.fmt.pix_mp.height);
+ if (V4L2_TYPE_IS_MULTIPLANAR(format.type))
+ coded_size_.SetSize(format.fmt.pix_mp.width, format.fmt.pix_mp.height);
+ else
+ coded_size_.SetSize(format.fmt.pix.width, format.fmt.pix.height);
visible_size_ = visible_size;
egl_image_size_ = coded_size_;
if (image_processor_device_) {
@@ -2110,11 +2113,11 @@ bool V4L2VideoDecodeAccelerator::CreateBuffersForFormat(
// In practice, this applies to all Image Processors, i.e. Mediatek devices.
DCHECK_EQ(coded_size_, output_size);
} else {
- egl_image_planes_count = format.fmt.pix_mp.num_planes;
+ egl_image_planes_count = V4L2_TYPE_IS_MULTIPLANAR(format.type) ? format.fmt.pix_mp.num_planes : 1;
}
VLOGF(2) << "new resolution: " << coded_size_.ToString()
<< ", visible size: " << visible_size_.ToString()
- << ", decoder output planes count: " << format.fmt.pix_mp.num_planes
+ << ", decoder output planes count: " << egl_image_planes_count
<< ", EGLImage size: " << egl_image_size_.ToString()
<< ", EGLImage plane count: " << egl_image_planes_count;
--
2.25.1

View File

@@ -0,0 +1,65 @@
From 0112d7345d0aa44f83b3f23e0ed6d8c975c2d14c Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Wed, 1 Nov 2023 23:53:06 +0900
Subject: [PATCH 109/120] V4L2VDA: 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 3d08149929..41403f4e73 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.25.1

View File

@@ -0,0 +1,76 @@
From 57c6104b5cd7a2c35caa40cf19c176eb66ab2ee8 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Thu, 2 Nov 2023 00:03:11 +0900
Subject: [PATCH 110/120] V4L2VDA: Add hevc format support
Upstream-Status: Inappropriate [NXP specific]
---
media/base/supported_types.cc | 2 +-
media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc | 1 +
media/gpu/v4l2/v4l2_utils.cc | 4 +++-
media/media_options.gni | 2 +-
4 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/media/base/supported_types.cc b/media/base/supported_types.cc
index 7737099b6a..49cf1beb3f 100644
--- a/media/base/supported_types.cc
+++ b/media/base/supported_types.cc
@@ -373,7 +373,7 @@ bool IsDefaultSupportedVideoType(const VideoType& type) {
case VideoCodec::kVP9:
return IsVp9ProfileSupported(type);
case VideoCodec::kHEVC:
- return IsHevcProfileSupported(type);
+ return true;
case VideoCodec::kMPEG4:
return IsMPEG4Supported();
case VideoCodec::kDolbyVision:
diff --git a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
index 32b7e97338..05f10ee979 100644
--- a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
@@ -90,6 +90,7 @@ static const std::vector<uint32_t> kSupportedInputFourCCs = {
V4L2_PIX_FMT_H264,
V4L2_PIX_FMT_VP8,
V4L2_PIX_FMT_VP9,
+ V4L2_PIX_FMT_HEVC,
};
// static
diff --git a/media/gpu/v4l2/v4l2_utils.cc b/media/gpu/v4l2/v4l2_utils.cc
index 7131cba379..1c275257df 100644
--- a/media/gpu/v4l2/v4l2_utils.cc
+++ b/media/gpu/v4l2/v4l2_utils.cc
@@ -478,7 +478,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;
@@ -521,6 +521,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 156eaebf5d..67b184d3b3 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.25.1

View File

@@ -0,0 +1,31 @@
From 63e308a5c17c022a682ab7cd1376b7e167d0cc6a Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Thu, 18 Aug 2022 12:20:33 +0800
Subject: [PATCH 111/120] V4L2VDA: fix vp9 crash caused by
DequeueResolutionChangeEvent
Handle source change event only when decoder receives driver reported
source change event.
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
index 05f10ee979..d372bd8abc 100644
--- a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
@@ -1140,8 +1140,7 @@ void V4L2VideoDecodeAccelerator::ServiceDeviceTask(bool event_pending) {
gfx::Size visible_size;
bool again;
if (GetFormatInfo(&format, &visible_size, &again) && !again) {
- resolution_change_pending = true;
- DequeueResolutionChangeEvent();
+ resolution_change_pending = DequeueResolutionChangeEvent();
}
}
--
2.25.1

View File

@@ -0,0 +1,85 @@
From 341cb82e43f4bbe5702372f30b2fd13f87d42ce9 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Thu, 2 Nov 2023 11:26:12 +0900
Subject: [PATCH 112/120] V4L2VDA: 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 00178b9cd0..6974a30bf7 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
@@ -9,6 +9,7 @@
#include <string>
#include <utility>
#include <vector>
+#include <sys/time.h>
#include "base/debug/crash_logging.h"
#include "base/debug/dump_without_crashing.h"
@@ -133,6 +134,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 {
@@ -337,6 +347,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));
@@ -600,7 +611,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::EnsureMinNumberOfBuffers(int n) {
@@ -2103,6 +2120,7 @@ bool SkiaOutputSurfaceImplOnGpu::Initialize() {
context_state_->AddContextLostObserver(this);
}
+ 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 f3847a7826..f8b833d985 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
@@ -539,6 +539,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.25.1

View File

@@ -0,0 +1,113 @@
From 18e15e665dfd17787841898be4bcf2c4940dbc9e Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Thu, 2 Nov 2023 14:31:34 +0900
Subject: [PATCH 113/120] V4L2VDA: 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 41403f4e73..1c16e87084 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.25.1

View File

@@ -0,0 +1,76 @@
From 8c4da3a34c47cbf8fab2dfd6d928843e53a13ad8 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Thu, 2 Nov 2023 14:34:11 +0900
Subject: [PATCH 114/120] V4L2VDA: Set OUTPUT format with parsed resolution for
amphion
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]
---
.../v4l2/legacy/v4l2_video_decode_accelerator.cc | 13 +++++++++++--
.../gpu/v4l2/legacy/v4l2_video_decode_accelerator.h | 2 +-
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
index d372bd8abc..84a9b2f4d7 100644
--- a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
@@ -323,6 +323,9 @@ bool V4L2VideoDecodeAccelerator::CheckConfig(const Config& config) {
return false;
}
+ int width, height;
+ height = config.initial_expected_coded_size.height();
+ width = config.initial_expected_coded_size.width();
// Capabilities check.
struct v4l2_capability caps;
unsigned int device_caps;
@@ -357,7 +360,7 @@ bool V4L2VideoDecodeAccelerator::CheckConfig(const Config& config) {
if (!output_queue_)
return false;
- if (!SetupFormats())
+ if (!SetupFormats(width, height))
return false;
// We have confirmed that |config| is supported, tell the good news to the
@@ -2171,7 +2174,7 @@ bool V4L2VideoDecodeAccelerator::CreateInputBuffers() {
return true;
}
-bool V4L2VideoDecodeAccelerator::SetupFormats() {
+bool V4L2VideoDecodeAccelerator::SetupFormats(int width, int height) {
DCHECK(decoder_thread_.task_runner()->BelongsToCurrentThread());
DCHECK_EQ(decoder_state_, kInitialized);
DCHECK(!input_queue_->IsStreaming());
@@ -2212,6 +2215,12 @@ bool V4L2VideoDecodeAccelerator::SetupFormats() {
format.fmt.pix_mp.pixelformat = input_format_fourcc_;
format.fmt.pix_mp.plane_fmt[0].sizeimage = input_size;
format.fmt.pix_mp.num_planes = 1;
+ // For VP8, VC1l, rv, Amphion needs to set correct resolution for
+ // OUTPUT queue as it will be added to amphion customized header.
+ if(V4L2_PIX_FMT_VP8 == input_format_fourcc_){
+ format.fmt.pix_mp.width = width;
+ format.fmt.pix_mp.height = height;
+ }
} else {
format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
format.fmt.pix.pixelformat = input_format_fourcc_;
diff --git a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.h b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.h
index 60ee8ef7f8..8ae19f53de 100644
--- a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.h
+++ b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.h
@@ -386,7 +386,7 @@ class MEDIA_GPU_EXPORT V4L2VideoDecodeAccelerator
bool DestroyOutputBuffers();
// Set input and output formats before starting decode.
- bool SetupFormats();
+ bool SetupFormats(int, int);
// Reset image processor and drop all processing frames.
bool ResetImageProcessor();
--
2.25.1

View File

@@ -0,0 +1,109 @@
From f31fe999af5a2c7ce9270781236d23e19b8b6e6e Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Thu, 2 Nov 2023 15:19:32 +0900
Subject: [PATCH 115/120] V4L2VDA: 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/legacy/v4l2_video_decode_accelerator.cc | 9 +++++++--
media/gpu/v4l2/v4l2_device.cc | 1 +
media/gpu/v4l2/v4l2_device.h | 6 ++++++
5 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/media/gpu/chromeos/fourcc.cc b/media/gpu/chromeos/fourcc.cc
index 175cb3eb8e..bf10308c5c 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:
@@ -164,6 +165,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 6f08dba1de..12b71cbb8f 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/legacy/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
index 84a9b2f4d7..9791a69765 100644
--- a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
@@ -1249,8 +1249,9 @@ void V4L2VideoDecodeAccelerator::Enqueue() {
// yet. Also, V4L2VDA calls STREAMOFF and STREAMON after resolution
// change. They implicitly send a V4L2_DEC_CMD_STOP and V4L2_DEC_CMD_START
// to the decoder.
- if (input_queue_->QueuedBuffersCount() > 0)
- break;
+ if (input_queue_->QueuedBuffersCount() > 0) {
+ // break;
+ }
if (coded_size_.IsEmpty() || !input_queue_->IsStreaming()) {
// In these situations, we should call NotifyFlushDone() immediately:
@@ -1392,6 +1393,10 @@ bool V4L2VideoDecodeAccelerator::DequeueOutputBuffer() {
// Dequeue a completed output (VIDEO_CAPTURE) buffer, and queue to the
// completed queue.
auto ret = output_queue_->DequeueBuffer();
+ if (errno == EPIPE) {
+ VLOG(1) << "Got eos";
+ flush_awaiting_last_output_buffer_ = false;
+ }
if (ret.first == false) {
LOG(ERROR) << "Error in Dequeue output buffer";
NOTIFY_ERROR(PLATFORM_FAILURE);
diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
index daea76c9b6..6a77f5dd8f 100644
--- a/media/gpu/v4l2/v4l2_device.cc
+++ b/media/gpu/v4l2/v4l2_device.cc
@@ -43,6 +43,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 620dbd5237..45075e40ee 100644
--- a/media/gpu/v4l2/v4l2_device.h
+++ b/media/gpu/v4l2/v4l2_device.h
@@ -64,6 +64,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.25.1

View File

@@ -0,0 +1,311 @@
From d59e1fe890fc5815fa4466b8dc0044ce83d750ac Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Thu, 2 Nov 2023 15:29:30 +0900
Subject: [PATCH 116/120] V4L2VDA: Support tile to linear transform for amphion
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/v4l2/BUILD.gn | 1 +
media/gpu/v4l2/v4l2_queue.cc | 189 ++++++++++++++++++++++++++++++++++-
media/gpu/v4l2/v4l2_queue.h | 1 +
3 files changed, 186 insertions(+), 5 deletions(-)
diff --git a/media/gpu/v4l2/BUILD.gn b/media/gpu/v4l2/BUILD.gn
index a790c4910a..8c96e9a926 100644
--- a/media/gpu/v4l2/BUILD.gn
+++ b/media/gpu/v4l2/BUILD.gn
@@ -114,6 +114,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 1c16e87084..90a9db1367 100644
--- a/media/gpu/v4l2/v4l2_queue.cc
+++ b/media/gpu/v4l2/v4l2_queue.cc
@@ -19,6 +19,11 @@
#include "media/gpu/chromeos/video_frame_resource.h"
#include "media/gpu/macros.h"
+#include "g2d.h"
+#include "g2dExt.h"
+#include <linux/dma-buf.h>
+#include <time.h>
+
namespace media {
namespace {
@@ -188,6 +193,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,
@@ -202,6 +212,12 @@ 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;
// V4L2 data as queried by QUERYBUF.
struct v4l2_buffer v4l2_buffer_;
@@ -256,6 +272,9 @@ 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;
}
V4L2Buffer::~V4L2Buffer() {
@@ -268,6 +287,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() {
@@ -353,6 +398,66 @@ scoped_refptr<VideoFrame> V4L2Buffer::CreateVideoFrame() {
DLOG(ERROR) << "Fail to get DMABUFs of V4L2 buffer - invalid fd";
return nullptr;
}
+ if(dmafd0 == -1)
+ dmafd0 = dmabuf_fd.get();
+ else
+ dmafd1 = dmabuf_fd.get();
+ }
+
+ std::vector<base::ScopedFD> g2dbufs_fds;
+ if (V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type)) {
+ 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) {
+ DLOG(ERROR)<< "DMA_BUF_IOCTL_PHYS failed at dmafd" << dmafd0;
+ return nullptr;
+ }
+ else
+ phys_0 = query0.phys;
+
+ ret = ioctl(dmafd1, DMA_BUF_IOCTL_PHYS, &query1);
+ if(ret != 0) {
+ DLOG(ERROR)<< "DMA_BUF_IOCTL_PHYS failed at dmafd" << dmafd1;
+ return nullptr;
+ }
+ 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)){
+ DLOG(ERROR)<<"g2d buf alloc failed";
+ return nullptr;
+ }
+
+ 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)
+ {
+ DLOG(ERROR) << "Failed duplicating g2d fd";
+ return nullptr;
+ }
+
+ 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)
+ {
+ DLOG(ERROR) << "Failed duplicating g2d fd";
+ return nullptr;
+ }
}
// Duplicate the fd of the last v4l2 plane until the number of fds are the
@@ -367,13 +472,16 @@ scoped_refptr<VideoFrame> V4L2Buffer::CreateVideoFrame() {
dmabuf_fds.emplace_back(duped_fd);
}
- if (V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type))
+ if (V4L2_TYPE_IS_MULTIPLANAR(v4l2_buffer_.type)) {
gfx::Size size(format_.fmt.pix_mp.width, format_.fmt.pix_mp.height);
- else
+ return VideoFrame::WrapExternalDmabufs(
+ *layout, gfx::Rect(size), size, std::move(g2dbufs_fds), base::TimeDelta());
+ }
+ else {
gfx::Size size(format_.fmt.pix.width, format_.fmt.pix.height);
-
- return VideoFrame::WrapExternalDmabufs(
- *layout, gfx::Rect(size), size, std::move(dmabuf_fds), base::TimeDelta());
+ return VideoFrame::WrapExternalDmabufs(
+ *layout, gfx::Rect(size), size, std::move(dmabuf_fds), base::TimeDelta());
+ }
}
const scoped_refptr<FrameResource>& V4L2Buffer::GetFrameResource() {
@@ -1112,6 +1220,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 +1239,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 +1285,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 +1646,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 532b991f68..976ebc329c 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.25.1

View File

@@ -0,0 +1,29 @@
From 796cf27bef13a731f1f36f3c95894fe1db8a4b25 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Thu, 2 Nov 2023 16:21:06 +0900
Subject: [PATCH 117/120] V4L2VDA: Enlarge input buffer count to 16
Some stream can decode one frame only after queuing over 8 buffers.
So enlarge input buffer count to 16 to avoid such stream cannot play.
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.h b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.h
index 8ae19f53de..b7d43fce53 100644
--- a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.h
+++ b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.h
@@ -157,7 +157,7 @@ class MEDIA_GPU_EXPORT V4L2VideoDecodeAccelerator
private:
// These are rather subjectively tuned.
enum {
- kInputBufferCount = 8,
+ kInputBufferCount = 16,
// TODO(posciak): determine input buffer size based on level limits.
// See http://crbug.com/255116.
// Input bitstream buffer size for up to 1080p streams.
--
2.25.1

View File

@@ -0,0 +1,236 @@
From 2831164cc20184e5f470d3eecb99f32a4e330d24 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Thu, 2 Nov 2023 17:41:28 +0900
Subject: [PATCH 118/120] V4L2VDA: 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 8c96e9a926..a790c4910a 100644
--- a/media/gpu/v4l2/BUILD.gn
+++ b/media/gpu/v4l2/BUILD.gn
@@ -114,7 +114,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 90a9db1367..f717f945ee 100644
--- a/media/gpu/v4l2/v4l2_queue.cc
+++ b/media/gpu/v4l2/v4l2_queue.cc
@@ -19,10 +19,11 @@
#include "media/gpu/chromeos/video_frame_resource.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 {
@@ -159,6 +160,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;
@@ -1221,6 +1375,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.25.1

View File

@@ -0,0 +1,71 @@
From 4a730e50db3f7d845d667f7b07104d4d8a068baa Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Mon, 6 Nov 2023 17:31:56 +0900
Subject: [PATCH 119/120] V4L2VDA: Add back legacy VideoDecoderType kVda
Upstream-Status: Inappropriate [NXP specific]
---
.../services/gpu_mojo_media_client_linux.cc | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/media/mojo/services/gpu_mojo_media_client_linux.cc b/media/mojo/services/gpu_mojo_media_client_linux.cc
index 1cde275dac..9f11a10e0a 100644
--- a/media/mojo/services/gpu_mojo_media_client_linux.cc
+++ b/media/mojo/services/gpu_mojo_media_client_linux.cc
@@ -13,6 +13,7 @@
#include "media/gpu/chromeos/mailbox_video_frame_converter.h"
#include "media/gpu/chromeos/platform_video_frame_pool.h"
#include "media/gpu/chromeos/video_decoder_pipeline.h"
+#include "media/gpu/ipc/service/vda_video_decoder.h"
namespace media {
@@ -35,6 +36,10 @@ VideoDecoderType GetPreferredLinuxDecoderImplementation() {
break;
}
+ if (!base::FeatureList::IsEnabled(kUseChromeOSDirectVideoDecoder)) {
+ return VideoDecoderType::kVda;
+ }
+
#if BUILDFLAG(USE_VAAPI)
return VideoDecoderType::kVaapi;
#elif BUILDFLAG(USE_V4L2_CODEC)
@@ -67,6 +72,11 @@ VideoDecoderType GetActualPlatformDecoderImplementation(
return VideoDecoderType::kUnknown;
case VideoDecoderType::kOutOfProcess:
return VideoDecoderType::kOutOfProcess;
+ case VideoDecoderType::kVda: {
+ return gpu_preferences.gr_context_type == gpu::GrContextType::kGL
+ ? VideoDecoderType::kVda
+ : VideoDecoderType::kUnknown;
+ }
case VideoDecoderType::kV4L2:
return VideoDecoderType::kV4L2;
case VideoDecoderType::kVaapi: {
@@ -168,6 +178,13 @@ class GpuMojoMediaClientLinux final : public GpuMojoMediaClient {
traits.media_log->Clone(), /*oop_video_decoder=*/{},
/*in_video_decoder_process=*/false);
}
+ case VideoDecoderType::kVda: {
+ return VdaVideoDecoder::Create(
+ traits.task_runner, gpu_task_runner_, traits.media_log->Clone(),
+ *traits.target_color_space, gpu_preferences_,
+ gpu_workarounds_, traits.get_command_buffer_stub_cb,
+ VideoDecodeAccelerator::Config::OutputMode::kAllocate);
+ }
default:
return nullptr;
}
@@ -198,6 +215,8 @@ class GpuMojoMediaClientLinux final : public GpuMojoMediaClient {
base::UmaHistogramEnumeration("Media.VaapiLinux.SupportedVideoDecoder",
decoder_implementation);
switch (decoder_implementation) {
+ case VideoDecoderType::kVda:
+ return std::move(get_vda_configs).Run();
case VideoDecoderType::kOutOfProcess:
case VideoDecoderType::kVaapi:
case VideoDecoderType::kV4L2:
--
2.25.1

View File

@@ -0,0 +1,40 @@
From f8ef4fca6fc488019a00218a370131e8e011f393 Mon Sep 17 00:00:00 2001
From: Hou Qi <qi.hou@nxp.com>
Date: Wed, 29 Nov 2023 11:00:59 +0900
Subject: [PATCH 120/120] V4L2Buffer: Add support for imx95
Imx95 allocate capture buffers using NV12 format, while
amphion allocate capture buffers using NV12M format.
Upstream-Status: Inappropriate [NXP specific]
---
media/gpu/v4l2/v4l2_queue.cc | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/media/gpu/v4l2/v4l2_queue.cc b/media/gpu/v4l2/v4l2_queue.cc
index f717f945ee..7b37b874fa 100644
--- a/media/gpu/v4l2/v4l2_queue.cc
+++ b/media/gpu/v4l2/v4l2_queue.cc
@@ -559,7 +559,8 @@ scoped_refptr<VideoFrame> V4L2Buffer::CreateVideoFrame() {
}
std::vector<base::ScopedFD> g2dbufs_fds;
- 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) {
struct dma_buf_phys{
unsigned long phys;
};
@@ -626,7 +627,8 @@ scoped_refptr<VideoFrame> V4L2Buffer::CreateVideoFrame() {
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);
return VideoFrame::WrapExternalDmabufs(
*layout, gfx::Rect(size), size, std::move(g2dbufs_fds), base::TimeDelta());
--
2.25.1

View File

@@ -0,0 +1,88 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2024 TQ-Systems GmbH <oss@ew.tq-group.com>, D-82229 Seefeld, Germany.
# Author: Matthias Schiffer
#
# "0001-chromium-gpu-sandbox-allow-access-to-PowerVR-GPU-fro.patch" based
# on original patch and configuration by Texas Instruments, found in
# https://git.ti.com/cgit/arago-project/meta-arago/
#
# The patch was verified to work on Chromium versions
# 126.0.6478.126 to 129.0.6668.100.
#
# The bbappend does not limit it to a specific version, as
# meta-browser-chromium is updated too frequently, and the patch will
# usually apply just fine to newer versions as well (and working around a
# non-applicable patch using :remove is easier than working around a
# non-applicable bbappend).
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
CHROMIUM_EXTRA_ARGS:remove:dumpling-wayland-ti = " --use-gl=egl"
CHROMIUM_EXTRA_ARGS:append:dumpling-wayland-ti = " --use-gl=angle"
SRC_URI:append:dumpling-wayland-ti = " \
file://0001-chromium-gpu-sandbox-allow-access-to-PowerVR-GPU-fro.patch \
"
SRC_URI:append:imx-nxp-bsp = " \
file://0001-Fixed-chromium-flicker-with-g2d-renderer.patch \
file://0002-chromium-met-EGL-API-GetProcAddress-failures.patch \
file://0003-Disable-dri-for-imx-gpu.patch \
file://0004-Fix-chromium-build-failure.patch \
file://0006-Fixed-chromium-crash-after-upgrading.patch \
"
VDA_PATCH_SET = " \
file://0101-V4L2VDA-Switch-to-use-VDA-instead-of-direct-VideoDec.patch \
file://0102-GenericV4L2Device-Correct-v4l2-decoder-device-path.patch \
file://0103-V4L2VDA-Add-macro-use_linux_v4l2.patch \
file://0104-V4L2VDA-Create-single-multi-plane-queues.patch \
file://0105-V4L2Buffer-Allocate-correct-v4l2-buffers-for-queues.patch \
file://0106-V4L2VDA-Create-videoframe-according-to-v4l2buffer.patch \
file://0107-V4L2VDA-Add-function-IsMultiQueue-for-S_FMT-and-G_FM.patch \
file://0108-V4L2VDA-Use-correct-size-to-allocate-CAPTURE-buffer.patch \
file://0109-V4L2VDA-Use-correct-plane-size-and-bytesused.patch \
file://0110-V4L2VDA-Add-hevc-format-support.patch \
file://0111-V4L2VDA-fix-vp9-crash-caused-by-DequeueResolutionCha.patch \
file://0112-V4L2VDA-Add-fps-in-SkiaOutputSurfaceImplOnGpu-by-VLO.patch \
file://0113-V4L2VDA-Comment-some-unused-ioctl.patch \
file://0114-V4L2VDA-Set-OUTPUT-format-with-parsed-resolution-for.patch \
file://0115-V4L2VDA-Add-V4L2_PIX_FMT_NV12M_8L128-format-for-amph.patch \
file://0116-V4L2VDA-Support-tile-to-linear-transform-for-amphion.patch \
file://0117-V4L2VDA-Enlarge-input-buffer-count-to-16.patch \
file://0118-V4L2VDA-Use-dlopen-to-dynamically-use-g2d-api.patch \
file://0119-V4L2VDA-Add-back-legacy-VideoDecoderType-kVda.patch \
file://0120-V4L2Buffer-Add-support-for-imx95.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_FFMPEG_BRANDING = ""
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} \
"
CHROMIUM_EXTRA_ARGS:append:imx-nxp-bsp = " --disable-features=VizDisplayCompositor --in-process-gpu --disable-gpu-rasterization"
#Remove installed ANGLE libraries
do_install:append:imx-nxp-bsp() {
rm -rf ${D}${libdir}/chromium/libEGL.so
rm -rf ${D}${libdir}/chromium/libGLESv2.so
rm -rf ${D}${libdir}/chromium/libvulkan.so.1
}