new/yocto/meta-rockchip/dynamic-layers/recipes-browser/chromium/chromium_111.0.5563/0001-media-gpu-v4l2-Support-V4L2-VDA-with-libv4l2-on-Linu.patch

462 lines
16 KiB
Diff
Raw Permalink Normal View History

2025-05-10 21:58:58 +08:00
From b4df6bb5295e9b1d6d192abbaefa0ae2f802b2b1 Mon Sep 17 00:00:00 2001
From: Maksim Sisov <msisov@igalia.com>
Date: Wed, 31 Jul 2019 09:56:24 +0300
Subject: [PATCH 01/18] media: gpu: v4l2: Support V4L2 VDA with libv4l2 on
Linux
Based on:
https://github.com/OSSystems/meta-browser/pull/263/commits/60ceb28750ee1f73c9cc2bf7e9e20e1c37a03497
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
.../gpu_mjpeg_decode_accelerator_factory.cc | 3 +-
media/gpu/BUILD.gn | 1 +
media/gpu/args.gni | 3 +
.../gpu_video_decode_accelerator_factory.cc | 8 +++
.../gpu_video_decode_accelerator_factory.h | 2 +
media/gpu/v4l2/BUILD.gn | 43 +++++++-----
media/gpu/v4l2/generic_v4l2_device.cc | 2 +-
media/gpu/v4l2/v4l2_device.cc | 70 +++++++++++++++++++
media/gpu/v4l2/v4l2_video_decoder.cc | 7 ++
9 files changed, 120 insertions(+), 19 deletions(-)
diff --git a/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc b/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc
index 888a5ce26..f083c93c7 100644
--- a/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc
+++ b/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc
@@ -12,7 +12,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 9ecae932b..f4b656e40 100644
--- a/media/gpu/BUILD.gn
+++ b/media/gpu/BUILD.gn
@@ -20,6 +20,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",
"USE_VAAPI_X11=$use_vaapi_x11",
]
}
diff --git a/media/gpu/args.gni b/media/gpu/args.gni
index 813657af1..65fb45c1d 100644
--- a/media/gpu/args.gni
+++ b/media/gpu/args.gni
@@ -25,6 +25,9 @@ declare_args() {
# platforms which have v4l2 hardware encoder
use_v4l2_codec_aml = false
+ # Indicates if Video4Linux2 codec is used for linux platform.
+ 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-using linux devices
diff --git a/media/gpu/gpu_video_decode_accelerator_factory.cc b/media/gpu/gpu_video_decode_accelerator_factory.cc
index 2db7d44e7..94287277a 100644
--- a/media/gpu/gpu_video_decode_accelerator_factory.cc
+++ b/media/gpu/gpu_video_decode_accelerator_factory.cc
@@ -29,7 +29,9 @@
#elif BUILDFLAG(USE_V4L2_CODEC) && \
(BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_ASH))
#include "media/gpu/v4l2/v4l2_device.h"
+#if !BUILDFLAG(USE_LINUX_V4L2)
#include "media/gpu/v4l2/v4l2_slice_video_decode_accelerator.h"
+#endif
#include "media/gpu/v4l2/v4l2_video_decode_accelerator.h"
#include "ui/gl/gl_surface_egl.h"
#endif
@@ -65,10 +67,12 @@ gpu::VideoDecodeAcceleratorCapabilities GetDecoderCapabilitiesInternal(
GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(
V4L2VideoDecodeAccelerator::GetSupportedProfiles(),
&capabilities.supported_profiles);
+#if !BUILDFLAG(USE_LINUX_V4L2)
GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(
V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles(),
&capabilities.supported_profiles);
#endif
+#endif
#elif BUILDFLAG(IS_MAC)
capabilities.supported_profiles =
VTVideoDecodeAccelerator::GetSupportedProfiles(workarounds);
@@ -149,8 +153,10 @@ GpuVideoDecodeAcceleratorFactory::CreateVDA(
#elif BUILDFLAG(USE_V4L2_CODEC) && \
(BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_ASH))
&GpuVideoDecodeAcceleratorFactory::CreateV4L2VDA,
+#if !BUILDFLAG(USE_LINUX_V4L2)
&GpuVideoDecodeAcceleratorFactory::CreateV4L2SliceVDA,
#endif
+#endif
#if BUILDFLAG(IS_MAC)
&GpuVideoDecodeAcceleratorFactory::CreateVTVDA,
@@ -211,6 +217,7 @@ GpuVideoDecodeAcceleratorFactory::CreateV4L2VDA(
return decoder;
}
+#if !BUILDFLAG(USE_LINUX_V4L2)
std::unique_ptr<VideoDecodeAccelerator>
GpuVideoDecodeAcceleratorFactory::CreateV4L2SliceVDA(
const gpu::GpuDriverBugWorkarounds& /*workarounds*/,
@@ -226,6 +233,7 @@ GpuVideoDecodeAcceleratorFactory::CreateV4L2SliceVDA(
return decoder;
}
#endif
+#endif
#if BUILDFLAG(IS_MAC)
std::unique_ptr<VideoDecodeAccelerator>
diff --git a/media/gpu/gpu_video_decode_accelerator_factory.h b/media/gpu/gpu_video_decode_accelerator_factory.h
index fadf95184..5d1ae3581 100644
--- a/media/gpu/gpu_video_decode_accelerator_factory.h
+++ b/media/gpu/gpu_video_decode_accelerator_factory.h
@@ -104,11 +104,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_MAC)
std::unique_ptr<VideoDecodeAccelerator> CreateVTVDA(
const gpu::GpuDriverBugWorkarounds& workarounds,
diff --git a/media/gpu/v4l2/BUILD.gn b/media/gpu/v4l2/BUILD.gn
index 12e6b66cf..23c1961c2 100644
--- a/media/gpu/v4l2/BUILD.gn
+++ b/media/gpu/v4l2/BUILD.gn
@@ -27,9 +27,6 @@ source_set("v4l2") {
"buffer_affinity_tracker.h",
"generic_v4l2_device.cc",
"generic_v4l2_device.h",
- "v4l2_decode_surface.cc",
- "v4l2_decode_surface.h",
- "v4l2_decode_surface_handler.h",
"v4l2_device.cc",
"v4l2_device.h",
"v4l2_device_poller.cc",
@@ -38,8 +35,6 @@ source_set("v4l2") {
"v4l2_framerate_control.h",
"v4l2_image_processor_backend.cc",
"v4l2_image_processor_backend.h",
- "v4l2_slice_video_decode_accelerator.cc",
- "v4l2_slice_video_decode_accelerator.h",
"v4l2_stateful_workaround.cc",
"v4l2_stateful_workaround.h",
"v4l2_utils.cc",
@@ -54,22 +49,36 @@ source_set("v4l2") {
"v4l2_video_decoder_backend.h",
"v4l2_video_decoder_backend_stateful.cc",
"v4l2_video_decoder_backend_stateful.h",
- "v4l2_video_decoder_backend_stateless.cc",
- "v4l2_video_decoder_backend_stateless.h",
- "v4l2_video_decoder_delegate_h264.cc",
- "v4l2_video_decoder_delegate_h264.h",
- "v4l2_video_decoder_delegate_vp8.cc",
- "v4l2_video_decoder_delegate_vp8.h",
- "v4l2_video_decoder_delegate_vp9.cc",
- "v4l2_video_decoder_delegate_vp9.h",
]
- if (is_chromeos) {
+ if (!use_linux_v4l2_only) {
sources += [
- # AV1 delegate depends on header files only in ChromeOS SDK
- "v4l2_video_decoder_delegate_av1.cc",
- "v4l2_video_decoder_delegate_av1.h",
+ "v4l2_decode_surface.cc",
+ "v4l2_decode_surface.h",
+ "v4l2_decode_surface_handler.h",
+ "v4l2_slice_video_decode_accelerator.cc",
+ "v4l2_slice_video_decode_accelerator.h",
+ "v4l2_video_decoder_backend_stateless.cc",
+ "v4l2_video_decoder_backend_stateless.h",
+ "v4l2_video_decoder_delegate_h264.cc",
+ "v4l2_video_decoder_delegate_h264.h",
+ "v4l2_video_decoder_delegate_vp8.cc",
+ "v4l2_video_decoder_delegate_vp8.h",
+ "v4l2_video_decoder_delegate_vp9.cc",
+ "v4l2_video_decoder_delegate_vp9.h",
+ ]
+
+ if (is_chromeos) {
+ sources += [
+ # AV1 delegate depends on header files only in ChromeOS SDK
+ "v4l2_video_decoder_delegate_av1.cc",
+ "v4l2_video_decoder_delegate_av1.h",
+ ]
+ }
+ }
+ if (is_chromeos) {
+ sources += [
# TODO(crbug.com/901264): Encoders use hack for passing offset
# within a DMA-buf, which is not supported upstream.
"v4l2_video_encode_accelerator.cc",
diff --git a/media/gpu/v4l2/generic_v4l2_device.cc b/media/gpu/v4l2/generic_v4l2_device.cc
index c3c57a0f4..9238385fb 100644
--- a/media/gpu/v4l2/generic_v4l2_device.cc
+++ b/media/gpu/v4l2/generic_v4l2_device.cc
@@ -433,7 +433,7 @@ bool GenericV4L2Device::OpenDevicePath(const std::string& path, Type type) {
return false;
if (V4L2Device::UseLibV4L2()) {
- if (type == Type::kEncoder &&
+ if (/* type == Type::kEncoder && */
HANDLE_EINTR(v4l2_fd_open(device_fd_.get(), V4L2_DISABLE_CONVERSION)) !=
-1) {
DVLOGF(3) << "Using libv4l2 for " << path;
diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
index cdbdb4b84..090863ce6 100644
--- a/media/gpu/v4l2/v4l2_device.cc
+++ b/media/gpu/v4l2/v4l2_device.cc
@@ -1009,10 +1009,12 @@ V4L2Queue::V4L2Queue(scoped_refptr<V4L2Device> dev,
return;
}
+#if BUILDFLAG(IS_CHROMEOS)
if (reqbufs.capabilities & V4L2_BUF_CAP_SUPPORTS_REQUESTS) {
supports_requests_ = true;
DVLOGF(4) << "Queue supports request API.";
}
+#endif
}
V4L2Queue::~V4L2Queue() {
@@ -1156,9 +1158,13 @@ size_t V4L2Queue::AllocateBuffers(size_t count,
reqbufs.count = count;
reqbufs.type = type_;
reqbufs.memory = memory;
+#if BUILDFLAG(IS_CHROMEOS)
reqbufs.flags = incoherent ? V4L2_MEMORY_FLAG_NON_COHERENT : 0;
DVQLOGF(3) << "Requesting " << count << " buffers.";
DVQLOGF(3) << "Incoherent flag is " << incoherent << ".";
+#else
+ DVQLOGF(3) << "Requesting " << count << " buffers.";
+#endif
int ret = device_->Ioctl(VIDIOC_REQBUFS, &reqbufs);
if (ret) {
@@ -1217,7 +1223,9 @@ bool V4L2Queue::DeallocateBuffers() {
reqbufs.count = 0;
reqbufs.type = type_;
reqbufs.memory = memory_;
+#if BUILDFLAG(IS_CHROMEOS)
reqbufs.flags = incoherent_ ? V4L2_MEMORY_FLAG_NON_COHERENT : 0;
+#endif
int ret = device_->Ioctl(VIDIOC_REQBUFS, &reqbufs);
if (ret) {
@@ -1562,6 +1570,23 @@ std::string V4L2Device::GetDriverName() {
// static
uint32_t V4L2Device::VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile,
bool slice_based) {
+#if BUILDFLAG(USE_LINUX_V4L2)
+ if (slice_based) {
+ LOG(ERROR) << "Slice not supported";
+ 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 {
+ DVLOGF(1) << "Unsupported profile: " << GetProfileName(profile);
+ return 0;
+ }
+#else
if (profile >= H264PROFILE_MIN && profile <= H264PROFILE_MAX) {
if (slice_based)
return V4L2_PIX_FMT_H264_SLICE;
@@ -1596,8 +1621,10 @@ uint32_t V4L2Device::VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile,
DVLOGF(1) << "Unsupported profile: " << GetProfileName(profile);
return 0;
}
+#endif
}
+#if !BUILDFLAG(USE_LINUX_V4L2)
namespace {
VideoCodecProfile V4L2ProfileToVideoCodecProfile(VideoCodec codec,
@@ -1656,9 +1683,11 @@ VideoCodecProfile V4L2ProfileToVideoCodecProfile(VideoCodec codec,
}
} // namespace
+#endif
std::vector<VideoCodecProfile> V4L2Device::V4L2PixFmtToVideoCodecProfiles(
uint32_t pix_fmt) {
+#if !BUILDFLAG(USE_LINUX_V4L2)
auto get_supported_profiles = [this](
VideoCodec codec,
std::vector<VideoCodecProfile>* profiles) {
@@ -1758,6 +1787,27 @@ std::vector<VideoCodecProfile> V4L2Device::V4L2PixFmtToVideoCodecProfiles(
VLOGF(1) << "Unhandled pixelformat " << FourccToString(pix_fmt);
return {};
}
+#else
+ std::vector<VideoCodecProfile> profiles;
+ switch (pix_fmt) {
+ case V4L2_PIX_FMT_H264:
+ profiles = {
+ H264PROFILE_BASELINE,
+ H264PROFILE_MAIN,
+ H264PROFILE_HIGH,
+ };
+ break;
+ case V4L2_PIX_FMT_VP8:
+ profiles = {VP8PROFILE_ANY};
+ break;
+ case V4L2_PIX_FMT_VP9:
+ profiles = {VP9PROFILE_PROFILE0};
+ break;
+ default:
+ VLOGF(1) << "Unhandled pixelformat " << FourccToString(pix_fmt);
+ return {};
+ }
+#endif
// Erase duplicated profiles.
std::sort(profiles.begin(), profiles.end());
@@ -2493,10 +2543,14 @@ bool V4L2Request::ApplyCtrls(struct v4l2_ext_controls* ctrls) {
return false;
}
+#if BUILDFLAG(IS_CHROMEOS)
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) {
@@ -2508,10 +2562,14 @@ bool V4L2Request::ApplyQueueBuffer(struct v4l2_buffer* buffer) {
return false;
}
+#if BUILDFLAG(IS_CHROMEOS)
buffer->flags |= V4L2_BUF_FLAG_REQUEST_FD;
buffer->request_fd = request_fd_.get();
return true;
+#else
+ return false;
+#endif
}
bool V4L2Request::Submit() {
@@ -2522,7 +2580,11 @@ bool V4L2Request::Submit() {
return false;
}
+#if BUILDFLAG(IS_CHROMEOS)
return HANDLE_EINTR(ioctl(request_fd_.get(), MEDIA_REQUEST_IOC_QUEUE)) == 0;
+#else
+ return false;
+#endif
}
bool V4L2Request::IsCompleted() {
@@ -2565,6 +2627,7 @@ bool V4L2Request::Reset() {
return false;
}
+#if BUILDFLAG(IS_CHROMEOS)
// 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) {
VPLOGF(1) << "Failed to reinit request.";
@@ -2572,6 +2635,9 @@ bool V4L2Request::Reset() {
}
return true;
+#else
+ return false;
+#endif
}
V4L2RequestRefBase::V4L2RequestRefBase(V4L2RequestRefBase&& req_base) {
@@ -2646,6 +2712,7 @@ V4L2RequestsQueue::~V4L2RequestsQueue() {
absl::optional<base::ScopedFD> V4L2RequestsQueue::CreateRequestFD() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+#if BUILDFLAG(IS_CHROMEOS)
int request_fd;
int ret = HANDLE_EINTR(
ioctl(media_fd_.get(), MEDIA_IOC_REQUEST_ALLOC, &request_fd));
@@ -2655,6 +2722,9 @@ absl::optional<base::ScopedFD> V4L2RequestsQueue::CreateRequestFD() {
}
return base::ScopedFD(request_fd);
+#else
+ return absl::nullopt;
+#endif
}
absl::optional<V4L2RequestRef> V4L2RequestsQueue::GetFreeRequest() {
diff --git a/media/gpu/v4l2/v4l2_video_decoder.cc b/media/gpu/v4l2/v4l2_video_decoder.cc
index e57c0043b..300711821 100644
--- a/media/gpu/v4l2/v4l2_video_decoder.cc
+++ b/media/gpu/v4l2/v4l2_video_decoder.cc
@@ -28,7 +28,10 @@
#include "media/gpu/macros.h"
#include "media/gpu/v4l2/v4l2_status.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
namespace media {
@@ -45,11 +48,13 @@ constexpr size_t kInputBufferMaxSizeFor4k = 4 * kInputBufferMaxSizeFor1080p;
// Input format V4L2 fourccs this class supports.
constexpr uint32_t kSupportedInputFourccs[] = {
+#if !BUILDFLAG(USE_LINUX_V4L2)
// V4L2 stateless formats
V4L2_PIX_FMT_H264_SLICE,
V4L2_PIX_FMT_VP8_FRAME,
V4L2_PIX_FMT_VP9_FRAME,
V4L2_PIX_FMT_AV1_FRAME,
+#endif
// V4L2 stateful formats
V4L2_PIX_FMT_H264,
#if BUILDFLAG(ENABLE_HEVC_PARSER_AND_HW_DECODER)
@@ -343,6 +348,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: "
@@ -350,6 +356,7 @@ V4L2Status V4L2VideoDecoder::InitializeBackend() {
<< " and fourcc: " << FourccToString(input_format_fourcc);
backend_ = std::make_unique<V4L2StatelessVideoDecoderBackend>(
this, device_, profile_, color_space_, decoder_task_runner_);
+#endif
}
if (!backend_->Initialize()) {
--
2.20.1