From 8c13cc78f1deb0d3b22eb50021e57f73ed43173b 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/15] Add support for V4L2VDA on Linux
|
|
This patch enables hardware assisted video decoding via the
|
Chromium V4L2VDA. Including changes when Linux is used. In
|
order to use this, use_linux_v4l2_only flag should be set
|
to true.
|
|
Signed-off-by: Ryo Kodama <ryo.kodama.vz@renesas.com>
|
|
fixup! avoid building not declared formats
|
|
"FRAME", "_SLICE", "V4L2_PIX_FMT_VP9" are not defined in mainline
|
Linux headers. This patch avoids building these formats.
|
|
Signed-off-by: Ryo Kodama <ryo.kodama.vz@renesas.com>
|
|
fixup! add V4L2_PIX_FMT_VP9 support back again as it is now
|
included in mainline Linux kernel. This allows VP9 codec
|
to work with upstream kernel and v4l2 vda. Tested on db820c
|
with Venus v4l2 driver.
|
|
Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
|
Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
|
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 | 4 ++
|
.../gpu_video_decode_accelerator_factory.cc | 8 +++
|
.../gpu_video_decode_accelerator_factory.h | 2 +
|
media/gpu/v4l2/BUILD.gn | 42 ++++++------
|
media/gpu/v4l2/generic_v4l2_device.cc | 4 ++
|
media/gpu/v4l2/v4l2_device.cc | 66 +++++++++++++++++++
|
media/gpu/v4l2/v4l2_video_decoder.cc | 7 ++
|
9 files changed, 115 insertions(+), 22 deletions(-)
|
|
diff --git a/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc b/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc
|
index 3772b8ef0..dece6b77f 100644
|
--- a/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc
|
+++ b/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc
|
@@ -13,7 +13,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 78d151fa6..101e2e4f9 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 bb2ff0797..da20cff79 100644
|
--- a/media/gpu/args.gni
|
+++ b/media/gpu/args.gni
|
@@ -21,6 +21,10 @@ declare_args() {
|
# platforms which have v4l2 hardware encoder / decoder.
|
use_v4l2_codec = false
|
|
+ # Indicates that only definitions available in the mainline linux kernel
|
+ # will be used.
|
+ use_linux_v4l2_only = false
|
+
|
# Indicates if Video4Linux2 AML encoder is used. This is used for AML
|
# platforms which have v4l2 hardware encoder
|
use_v4l2_codec_aml = false
|
diff --git a/media/gpu/gpu_video_decode_accelerator_factory.cc b/media/gpu/gpu_video_decode_accelerator_factory.cc
|
index 6687b1186..951478638 100644
|
--- a/media/gpu/gpu_video_decode_accelerator_factory.cc
|
+++ b/media/gpu/gpu_video_decode_accelerator_factory.cc
|
@@ -29,7 +29,9 @@
|
#include "ui/gl/gl_implementation.h"
|
#elif BUILDFLAG(USE_V4L2_CODEC)
|
#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
|
@@ -64,10 +66,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);
|
@@ -146,8 +150,10 @@ GpuVideoDecodeAcceleratorFactory::CreateVDA(
|
&GpuVideoDecodeAcceleratorFactory::CreateVaapiVDA,
|
#elif BUILDFLAG(USE_V4L2_CODEC)
|
&GpuVideoDecodeAcceleratorFactory::CreateV4L2VDA,
|
+#if !BUILDFLAG(USE_LINUX_V4L2)
|
&GpuVideoDecodeAcceleratorFactory::CreateV4L2SliceVDA,
|
#endif
|
+#endif
|
|
#if BUILDFLAG(IS_MAC)
|
&GpuVideoDecodeAcceleratorFactory::CreateVTVDA,
|
@@ -207,6 +213,7 @@ GpuVideoDecodeAcceleratorFactory::CreateV4L2VDA(
|
return decoder;
|
}
|
|
+#if !BUILDFLAG(USE_LINUX_V4L2)
|
std::unique_ptr<VideoDecodeAccelerator>
|
GpuVideoDecodeAcceleratorFactory::CreateV4L2SliceVDA(
|
const gpu::GpuDriverBugWorkarounds& /*workarounds*/,
|
@@ -222,6 +229,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 b2e1390c5..5a714eb80 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 65e5f58d1..bde4c169d 100644
|
--- a/media/gpu/v4l2/BUILD.gn
|
+++ b/media/gpu/v4l2/BUILD.gn
|
@@ -28,9 +28,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",
|
@@ -39,8 +36,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_status.h",
|
@@ -56,26 +51,31 @@ 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_h264_legacy.cc",
|
- "v4l2_video_decoder_delegate_h264_legacy.h",
|
- "v4l2_video_decoder_delegate_vp8.cc",
|
- "v4l2_video_decoder_delegate_vp8.h",
|
- "v4l2_video_decoder_delegate_vp8_legacy.cc",
|
- "v4l2_video_decoder_delegate_vp8_legacy.h",
|
- "v4l2_video_decoder_delegate_vp9.cc",
|
- "v4l2_video_decoder_delegate_vp9.h",
|
- "v4l2_video_decoder_delegate_vp9_chromium.cc",
|
- "v4l2_video_decoder_delegate_vp9_chromium.h",
|
- "v4l2_video_decoder_delegate_vp9_legacy.cc",
|
- "v4l2_video_decoder_delegate_vp9_legacy.h",
|
"v4l2_video_encode_accelerator.cc",
|
"v4l2_video_encode_accelerator.h",
|
]
|
|
+ if (!use_linux_v4l2_only) {
|
+ sources += [
|
+ "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_h264_legacy.cc",
|
+ "v4l2_video_decoder_delegate_h264_legacy.h",
|
+ "v4l2_video_decoder_delegate_vp8.cc",
|
+ "v4l2_video_decoder_delegate_vp8.h",
|
+ "v4l2_video_decoder_delegate_vp8_legacy.cc",
|
+ "v4l2_video_decoder_delegate_vp8_legacy.h",
|
+ "v4l2_video_decoder_delegate_vp9.cc",
|
+ "v4l2_video_decoder_delegate_vp9.h",
|
+ "v4l2_video_decoder_delegate_vp9_chromium.cc",
|
+ "v4l2_video_decoder_delegate_vp9_chromium.h",
|
+ "v4l2_video_decoder_delegate_vp9_legacy.cc",
|
+ "v4l2_video_decoder_delegate_vp9_legacy.h",
|
+ ]
|
+ }
|
+
|
libs = [
|
"EGL",
|
"GLESv2",
|
diff --git a/media/gpu/v4l2/generic_v4l2_device.cc b/media/gpu/v4l2/generic_v4l2_device.cc
|
index a6fe9d914..becf30c9c 100644
|
--- a/media/gpu/v4l2/generic_v4l2_device.cc
|
+++ b/media/gpu/v4l2/generic_v4l2_device.cc
|
@@ -440,7 +440,11 @@ bool GenericV4L2Device::OpenDevicePath(const std::string& path, Type type) {
|
return false;
|
|
#if BUILDFLAG(USE_LIBV4L2)
|
+#if BUILDFLAG(USE_LINUX_V4L2)
|
+ if (
|
+#else
|
if (type == Type::kEncoder &&
|
+#endif
|
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 de2800fda..866c79e4d 100644
|
--- a/media/gpu/v4l2/v4l2_device.cc
|
+++ b/media/gpu/v4l2/v4l2_device.cc
|
@@ -853,7 +853,9 @@ void V4L2WritableBufferRef::SetConfigStore(uint32_t config_store) {
|
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
DCHECK(buffer_data_);
|
|
+#if !BUILDFLAG(USE_LINUX_V4L2)
|
buffer_data_->v4l2_buffer_.config_store = config_store;
|
+#endif
|
}
|
|
V4L2ReadableBuffer::V4L2ReadableBuffer(const struct v4l2_buffer& v4l2_buffer,
|
@@ -996,10 +998,12 @@ V4L2Queue::V4L2Queue(scoped_refptr<V4L2Device> dev,
|
return;
|
}
|
|
+#if !BUILDFLAG(USE_LINUX_V4L2)
|
if (reqbufs.capabilities & V4L2_BUF_CAP_SUPPORTS_REQUESTS) {
|
supports_requests_ = true;
|
DVLOGF(4) << "Queue supports request API.";
|
}
|
+#endif
|
}
|
|
V4L2Queue::~V4L2Queue() {
|
@@ -1539,6 +1543,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;
|
@@ -1558,8 +1579,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,
|
@@ -1606,9 +1629,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) {
|
@@ -1679,6 +1704,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());
|
@@ -2346,10 +2392,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) {
|
@@ -2361,10 +2411,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() {
|
@@ -2375,7 +2429,11 @@ bool V4L2Request::Submit() {
|
return false;
|
}
|
|
+#if !BUILDFLAG(USE_LINUX_V4L2)
|
return HANDLE_EINTR(ioctl(request_fd_.get(), MEDIA_REQUEST_IOC_QUEUE)) == 0;
|
+#else
|
+ return false;
|
+#endif
|
}
|
|
bool V4L2Request::IsCompleted() {
|
@@ -2418,6 +2476,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) {
|
VPLOGF(1) << "Failed to reinit request.";
|
@@ -2425,6 +2484,9 @@ bool V4L2Request::Reset() {
|
}
|
|
return true;
|
+#else
|
+ return false;
|
+#endif
|
}
|
|
V4L2RequestRefBase::V4L2RequestRefBase(V4L2RequestRefBase&& req_base) {
|
@@ -2499,6 +2561,7 @@ V4L2RequestsQueue::~V4L2RequestsQueue() {
|
absl::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));
|
@@ -2508,6 +2571,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 057b28663..1df3f1a5c 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 {
|
|
@@ -46,7 +49,9 @@ constexpr size_t kNumInputBuffers = 8;
|
|
// Input format V4L2 fourccs this class supports.
|
constexpr uint32_t kSupportedInputFourccs[] = {
|
+#if !BUILDFLAG(USE_LINUX_V4L2)
|
V4L2_PIX_FMT_H264_SLICE, V4L2_PIX_FMT_VP8_FRAME, V4L2_PIX_FMT_VP9_FRAME,
|
+#endif
|
V4L2_PIX_FMT_H264, V4L2_PIX_FMT_VP8, V4L2_PIX_FMT_VP9,
|
};
|
|
@@ -320,6 +325,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: "
|
@@ -327,6 +333,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
|