1From 6b68dd8ef6cd64487be9a6503cd82a409a31656c Mon Sep 17 00:00:00 2001 2From: Maksim Sisov <msisov@igalia.com> 3Date: Wed, 31 Jul 2019 09:56:24 +0300 4Subject: [PATCH 01/14] Add support for V4L2VDA on Linux 5 6This patch enables hardware assisted video decoding via the 7Chromium V4L2VDA. Including changes when Linux is used. In 8order to use this, use_linux_v4l2_only flag should be set 9to true. 10 11Signed-off-by: Ryo Kodama <ryo.kodama.vz@renesas.com> 12 13fixup! avoid building not declared formats 14 15"FRAME", "_SLICE", "V4L2_PIX_FMT_VP9" are not defined in mainline 16 Linux headers. This patch avoids building these formats. 17 18Signed-off-by: Ryo Kodama <ryo.kodama.vz@renesas.com> 19 20fixup! add V4L2_PIX_FMT_VP9 support back again as it is now 21included in mainline Linux kernel. This allows VP9 codec 22to work with upstream kernel and v4l2 vda. Tested on db820c 23with Venus v4l2 driver. 24 25Signed-off-by: Peter Griffin <peter.griffin@linaro.org> 26Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org> 27Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 28--- 29 .../gpu_mjpeg_decode_accelerator_factory.cc | 3 +- 30 media/gpu/BUILD.gn | 1 + 31 media/gpu/args.gni | 4 ++ 32 .../gpu_video_decode_accelerator_factory.cc | 8 +++ 33 .../gpu_video_decode_accelerator_factory.h | 2 + 34 media/gpu/v4l2/BUILD.gn | 41 ++++++------ 35 media/gpu/v4l2/generic_v4l2_device.cc | 4 ++ 36 media/gpu/v4l2/v4l2_device.cc | 66 +++++++++++++++++++ 37 media/gpu/v4l2/v4l2_video_decoder.cc | 7 ++ 38 9 files changed, 116 insertions(+), 20 deletions(-) 39 40diff --git a/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc b/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc 41index 3772b8ef0..dece6b77f 100644 42--- a/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc 43+++ b/components/chromeos_camera/gpu_mjpeg_decode_accelerator_factory.cc 44@@ -13,7 +13,8 @@ 45 #include "media/base/media_switches.h" 46 #include "media/gpu/buildflags.h" 47 48-#if BUILDFLAG(USE_V4L2_CODEC) && defined(ARCH_CPU_ARM_FAMILY) 49+#if BUILDFLAG(USE_V4L2_CODEC) && defined(ARCH_CPU_ARM_FAMILY) && \ 50+ !BUILDFLAG(USE_LINUX_V4L2) 51 #define USE_V4L2_MJPEG_DECODE_ACCELERATOR 52 #endif 53 54diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn 55index 52c22c3fd..8ca11e1c8 100644 56--- a/media/gpu/BUILD.gn 57+++ b/media/gpu/BUILD.gn 58@@ -20,6 +20,7 @@ buildflag_header("buildflags") { 59 "USE_VAAPI_IMAGE_CODECS=$use_vaapi_image_codecs", 60 "USE_V4L2_CODEC=$use_v4l2_codec", 61 "USE_LIBV4L2=$use_v4lplugin", 62+ "USE_LINUX_V4L2=$use_linux_v4l2_only", 63 "USE_VAAPI_X11=$use_vaapi_x11", 64 ] 65 } 66diff --git a/media/gpu/args.gni b/media/gpu/args.gni 67index bb2ff0797..da20cff79 100644 68--- a/media/gpu/args.gni 69+++ b/media/gpu/args.gni 70@@ -21,6 +21,10 @@ declare_args() { 71 # platforms which have v4l2 hardware encoder / decoder. 72 use_v4l2_codec = false 73 74+ # Indicates that only definitions available in the mainline linux kernel 75+ # will be used. 76+ use_linux_v4l2_only = false 77+ 78 # Indicates if Video4Linux2 AML encoder is used. This is used for AML 79 # platforms which have v4l2 hardware encoder 80 use_v4l2_codec_aml = false 81diff --git a/media/gpu/gpu_video_decode_accelerator_factory.cc b/media/gpu/gpu_video_decode_accelerator_factory.cc 82index 98f1e2ee7..b7cfffabb 100644 83--- a/media/gpu/gpu_video_decode_accelerator_factory.cc 84+++ b/media/gpu/gpu_video_decode_accelerator_factory.cc 85@@ -29,7 +29,9 @@ 86 #include "ui/gl/gl_implementation.h" 87 #elif BUILDFLAG(USE_V4L2_CODEC) 88 #include "media/gpu/v4l2/v4l2_device.h" 89+#if !BUILDFLAG(USE_LINUX_V4L2) 90 #include "media/gpu/v4l2/v4l2_slice_video_decode_accelerator.h" 91+#endif 92 #include "media/gpu/v4l2/v4l2_video_decode_accelerator.h" 93 #include "ui/gl/gl_surface_egl.h" 94 #endif 95@@ -64,10 +66,12 @@ gpu::VideoDecodeAcceleratorCapabilities GetDecoderCapabilitiesInternal( 96 GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles( 97 V4L2VideoDecodeAccelerator::GetSupportedProfiles(), 98 &capabilities.supported_profiles); 99+#if !BUILDFLAG(USE_LINUX_V4L2) 100 GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles( 101 V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles(), 102 &capabilities.supported_profiles); 103 #endif 104+#endif 105 #elif BUILDFLAG(IS_MAC) 106 capabilities.supported_profiles = 107 VTVideoDecodeAccelerator::GetSupportedProfiles(workarounds); 108@@ -146,8 +150,10 @@ GpuVideoDecodeAcceleratorFactory::CreateVDA( 109 &GpuVideoDecodeAcceleratorFactory::CreateVaapiVDA, 110 #elif BUILDFLAG(USE_V4L2_CODEC) 111 &GpuVideoDecodeAcceleratorFactory::CreateV4L2VDA, 112+#if !BUILDFLAG(USE_LINUX_V4L2) 113 &GpuVideoDecodeAcceleratorFactory::CreateV4L2SliceVDA, 114 #endif 115+#endif 116 117 #if BUILDFLAG(IS_MAC) 118 &GpuVideoDecodeAcceleratorFactory::CreateVTVDA, 119@@ -207,6 +213,7 @@ GpuVideoDecodeAcceleratorFactory::CreateV4L2VDA( 120 return decoder; 121 } 122 123+#if !BUILDFLAG(USE_LINUX_V4L2) 124 std::unique_ptr<VideoDecodeAccelerator> 125 GpuVideoDecodeAcceleratorFactory::CreateV4L2SliceVDA( 126 const gpu::GpuDriverBugWorkarounds& /*workarounds*/, 127@@ -222,6 +229,7 @@ GpuVideoDecodeAcceleratorFactory::CreateV4L2SliceVDA( 128 return decoder; 129 } 130 #endif 131+#endif 132 133 #if BUILDFLAG(IS_MAC) 134 std::unique_ptr<VideoDecodeAccelerator> 135diff --git a/media/gpu/gpu_video_decode_accelerator_factory.h b/media/gpu/gpu_video_decode_accelerator_factory.h 136index b2e1390c5..5a714eb80 100644 137--- a/media/gpu/gpu_video_decode_accelerator_factory.h 138+++ b/media/gpu/gpu_video_decode_accelerator_factory.h 139@@ -104,11 +104,13 @@ class MEDIA_GPU_EXPORT GpuVideoDecodeAcceleratorFactory { 140 const gpu::GpuDriverBugWorkarounds& workarounds, 141 const gpu::GpuPreferences& gpu_preferences, 142 MediaLog* media_log) const; 143+#if !BUILDFLAG(USE_LINUX_V4L2) 144 std::unique_ptr<VideoDecodeAccelerator> CreateV4L2SliceVDA( 145 const gpu::GpuDriverBugWorkarounds& workarounds, 146 const gpu::GpuPreferences& gpu_preferences, 147 MediaLog* media_log) const; 148 #endif 149+#endif 150 #if BUILDFLAG(IS_MAC) 151 std::unique_ptr<VideoDecodeAccelerator> CreateVTVDA( 152 const gpu::GpuDriverBugWorkarounds& workarounds, 153diff --git a/media/gpu/v4l2/BUILD.gn b/media/gpu/v4l2/BUILD.gn 154index 50d81e483..3a47d1166 100644 155--- a/media/gpu/v4l2/BUILD.gn 156+++ b/media/gpu/v4l2/BUILD.gn 157@@ -28,9 +28,6 @@ source_set("v4l2") { 158 "buffer_affinity_tracker.h", 159 "generic_v4l2_device.cc", 160 "generic_v4l2_device.h", 161- "v4l2_decode_surface.cc", 162- "v4l2_decode_surface.h", 163- "v4l2_decode_surface_handler.h", 164 "v4l2_device.cc", 165 "v4l2_device.h", 166 "v4l2_device_poller.cc", 167@@ -39,8 +36,6 @@ source_set("v4l2") { 168 "v4l2_framerate_control.h", 169 "v4l2_image_processor_backend.cc", 170 "v4l2_image_processor_backend.h", 171- "v4l2_slice_video_decode_accelerator.cc", 172- "v4l2_slice_video_decode_accelerator.h", 173 "v4l2_stateful_workaround.cc", 174 "v4l2_stateful_workaround.h", 175 "v4l2_utils.cc", 176@@ -55,24 +50,32 @@ source_set("v4l2") { 177 "v4l2_video_decoder_backend.h", 178 "v4l2_video_decoder_backend_stateful.cc", 179 "v4l2_video_decoder_backend_stateful.h", 180- "v4l2_video_decoder_backend_stateless.cc", 181- "v4l2_video_decoder_backend_stateless.h", 182- "v4l2_video_decoder_delegate_h264.cc", 183- "v4l2_video_decoder_delegate_h264.h", 184- "v4l2_video_decoder_delegate_h264_legacy.cc", 185- "v4l2_video_decoder_delegate_h264_legacy.h", 186- "v4l2_video_decoder_delegate_vp8.cc", 187- "v4l2_video_decoder_delegate_vp8.h", 188- "v4l2_video_decoder_delegate_vp8_legacy.cc", 189- "v4l2_video_decoder_delegate_vp8_legacy.h", 190- "v4l2_video_decoder_delegate_vp9.cc", 191- "v4l2_video_decoder_delegate_vp9.h", 192- "v4l2_video_decoder_delegate_vp9_legacy.cc", 193- "v4l2_video_decoder_delegate_vp9_legacy.h", 194 "v4l2_video_encode_accelerator.cc", 195 "v4l2_video_encode_accelerator.h", 196 ] 197 198+ if (!use_linux_v4l2_only) { 199+ sources += [ 200+ "v4l2_slice_video_decode_accelerator.cc", 201+ "v4l2_slice_video_decode_accelerator.h", 202+ "v4l2_video_decoder_backend_stateless.cc", 203+ "v4l2_video_decoder_backend_stateless.h", 204+ "v4l2_video_decoder_delegate_h264.cc", 205+ "v4l2_video_decoder_delegate_h264.h", 206+ "v4l2_video_decoder_delegate_h264_legacy.cc", 207+ "v4l2_video_decoder_delegate_h264_legacy.h", 208+ "v4l2_video_decoder_delegate_vp8.cc", 209+ "v4l2_video_decoder_delegate_vp8.h", 210+ "v4l2_video_decoder_delegate_vp8_legacy.cc", 211+ "v4l2_video_decoder_delegate_vp8_legacy.h", 212+ "v4l2_video_decoder_delegate_vp9.cc", 213+ "v4l2_video_decoder_delegate_vp9.h", 214+ "v4l2_video_decoder_delegate_vp9_legacy.cc", 215+ "v4l2_video_decoder_delegate_vp9_legacy.h", 216+ ] 217+ } 218+ 219+ 220 libs = [ 221 "EGL", 222 "GLESv2", 223diff --git a/media/gpu/v4l2/generic_v4l2_device.cc b/media/gpu/v4l2/generic_v4l2_device.cc 224index a6fe9d914..becf30c9c 100644 225--- a/media/gpu/v4l2/generic_v4l2_device.cc 226+++ b/media/gpu/v4l2/generic_v4l2_device.cc 227@@ -440,7 +440,11 @@ bool GenericV4L2Device::OpenDevicePath(const std::string& path, Type type) { 228 return false; 229 230 #if BUILDFLAG(USE_LIBV4L2) 231+#if BUILDFLAG(USE_LINUX_V4L2) 232+ if ( 233+#else 234 if (type == Type::kEncoder && 235+#endif 236 HANDLE_EINTR(v4l2_fd_open(device_fd_.get(), V4L2_DISABLE_CONVERSION)) != 237 -1) { 238 DVLOGF(3) << "Using libv4l2 for " << path; 239diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc 240index de2800fda..866c79e4d 100644 241--- a/media/gpu/v4l2/v4l2_device.cc 242+++ b/media/gpu/v4l2/v4l2_device.cc 243@@ -853,7 +853,9 @@ void V4L2WritableBufferRef::SetConfigStore(uint32_t config_store) { 244 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 245 DCHECK(buffer_data_); 246 247+#if !BUILDFLAG(USE_LINUX_V4L2) 248 buffer_data_->v4l2_buffer_.config_store = config_store; 249+#endif 250 } 251 252 V4L2ReadableBuffer::V4L2ReadableBuffer(const struct v4l2_buffer& v4l2_buffer, 253@@ -996,10 +998,12 @@ V4L2Queue::V4L2Queue(scoped_refptr<V4L2Device> dev, 254 return; 255 } 256 257+#if !BUILDFLAG(USE_LINUX_V4L2) 258 if (reqbufs.capabilities & V4L2_BUF_CAP_SUPPORTS_REQUESTS) { 259 supports_requests_ = true; 260 DVLOGF(4) << "Queue supports request API."; 261 } 262+#endif 263 } 264 265 V4L2Queue::~V4L2Queue() { 266@@ -1539,6 +1543,23 @@ std::string V4L2Device::GetDriverName() { 267 // static 268 uint32_t V4L2Device::VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile, 269 bool slice_based) { 270+#if BUILDFLAG(USE_LINUX_V4L2) 271+ if (slice_based) { 272+ LOG(ERROR) << "Slice not supported"; 273+ return 0; 274+ } 275+ 276+ if (profile >= H264PROFILE_MIN && profile <= H264PROFILE_MAX) { 277+ return V4L2_PIX_FMT_H264; 278+ } else if (profile >= VP8PROFILE_MIN && profile <= VP8PROFILE_MAX) { 279+ return V4L2_PIX_FMT_VP8; 280+ } else if (profile >= VP9PROFILE_MIN && profile <= VP9PROFILE_MAX) { 281+ return V4L2_PIX_FMT_VP9; 282+ } else { 283+ DVLOGF(1) << "Unsupported profile: " << GetProfileName(profile); 284+ return 0; 285+ } 286+#else 287 if (profile >= H264PROFILE_MIN && profile <= H264PROFILE_MAX) { 288 if (slice_based) 289 return V4L2_PIX_FMT_H264_SLICE; 290@@ -1558,8 +1579,10 @@ uint32_t V4L2Device::VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile, 291 DVLOGF(1) << "Unsupported profile: " << GetProfileName(profile); 292 return 0; 293 } 294+#endif 295 } 296 297+#if !BUILDFLAG(USE_LINUX_V4L2) 298 namespace { 299 300 VideoCodecProfile V4L2ProfileToVideoCodecProfile(VideoCodec codec, 301@@ -1606,9 +1629,11 @@ VideoCodecProfile V4L2ProfileToVideoCodecProfile(VideoCodec codec, 302 } 303 304 } // namespace 305+#endif 306 307 std::vector<VideoCodecProfile> V4L2Device::V4L2PixFmtToVideoCodecProfiles( 308 uint32_t pix_fmt) { 309+#if !BUILDFLAG(USE_LINUX_V4L2) 310 auto get_supported_profiles = [this]( 311 VideoCodec codec, 312 std::vector<VideoCodecProfile>* profiles) { 313@@ -1679,6 +1704,27 @@ std::vector<VideoCodecProfile> V4L2Device::V4L2PixFmtToVideoCodecProfiles( 314 VLOGF(1) << "Unhandled pixelformat " << FourccToString(pix_fmt); 315 return {}; 316 } 317+#else 318+ std::vector<VideoCodecProfile> profiles; 319+ switch (pix_fmt) { 320+ case V4L2_PIX_FMT_H264: 321+ profiles = { 322+ H264PROFILE_BASELINE, 323+ H264PROFILE_MAIN, 324+ H264PROFILE_HIGH, 325+ }; 326+ break; 327+ case V4L2_PIX_FMT_VP8: 328+ profiles = {VP8PROFILE_ANY}; 329+ break; 330+ case V4L2_PIX_FMT_VP9: 331+ profiles = {VP9PROFILE_PROFILE0}; 332+ break; 333+ default: 334+ VLOGF(1) << "Unhandled pixelformat " << FourccToString(pix_fmt); 335+ return {}; 336+ } 337+#endif 338 339 // Erase duplicated profiles. 340 std::sort(profiles.begin(), profiles.end()); 341@@ -2346,10 +2392,14 @@ bool V4L2Request::ApplyCtrls(struct v4l2_ext_controls* ctrls) { 342 return false; 343 } 344 345+#if !BUILDFLAG(USE_LINUX_V4L2) 346 ctrls->which = V4L2_CTRL_WHICH_REQUEST_VAL; 347 ctrls->request_fd = request_fd_.get(); 348 349 return true; 350+#else 351+ return false; 352+#endif 353 } 354 355 bool V4L2Request::ApplyQueueBuffer(struct v4l2_buffer* buffer) { 356@@ -2361,10 +2411,14 @@ bool V4L2Request::ApplyQueueBuffer(struct v4l2_buffer* buffer) { 357 return false; 358 } 359 360+#if !BUILDFLAG(USE_LINUX_V4L2) 361 buffer->flags |= V4L2_BUF_FLAG_REQUEST_FD; 362 buffer->request_fd = request_fd_.get(); 363 364 return true; 365+#else 366+ return false; 367+#endif 368 } 369 370 bool V4L2Request::Submit() { 371@@ -2375,7 +2429,11 @@ bool V4L2Request::Submit() { 372 return false; 373 } 374 375+#if !BUILDFLAG(USE_LINUX_V4L2) 376 return HANDLE_EINTR(ioctl(request_fd_.get(), MEDIA_REQUEST_IOC_QUEUE)) == 0; 377+#else 378+ return false; 379+#endif 380 } 381 382 bool V4L2Request::IsCompleted() { 383@@ -2418,6 +2476,7 @@ bool V4L2Request::Reset() { 384 return false; 385 } 386 387+#if !BUILDFLAG(USE_LINUX_V4L2) 388 // Reinit the request to make sure we can use it for a new submission. 389 if (HANDLE_EINTR(ioctl(request_fd_.get(), MEDIA_REQUEST_IOC_REINIT)) < 0) { 390 VPLOGF(1) << "Failed to reinit request."; 391@@ -2425,6 +2484,9 @@ bool V4L2Request::Reset() { 392 } 393 394 return true; 395+#else 396+ return false; 397+#endif 398 } 399 400 V4L2RequestRefBase::V4L2RequestRefBase(V4L2RequestRefBase&& req_base) { 401@@ -2499,6 +2561,7 @@ V4L2RequestsQueue::~V4L2RequestsQueue() { 402 absl::optional<base::ScopedFD> V4L2RequestsQueue::CreateRequestFD() { 403 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 404 405+#if !BUILDFLAG(USE_LINUX_V4L2) 406 int request_fd; 407 int ret = HANDLE_EINTR( 408 ioctl(media_fd_.get(), MEDIA_IOC_REQUEST_ALLOC, &request_fd)); 409@@ -2508,6 +2571,9 @@ absl::optional<base::ScopedFD> V4L2RequestsQueue::CreateRequestFD() { 410 } 411 412 return base::ScopedFD(request_fd); 413+#else 414+ return absl::nullopt; 415+#endif 416 } 417 418 absl::optional<V4L2RequestRef> V4L2RequestsQueue::GetFreeRequest() { 419diff --git a/media/gpu/v4l2/v4l2_video_decoder.cc b/media/gpu/v4l2/v4l2_video_decoder.cc 420index 7f4c9f244..e887fb896 100644 421--- a/media/gpu/v4l2/v4l2_video_decoder.cc 422+++ b/media/gpu/v4l2/v4l2_video_decoder.cc 423@@ -27,7 +27,10 @@ 424 #include "media/gpu/macros.h" 425 #include "media/gpu/v4l2/v4l2_status.h" 426 #include "media/gpu/v4l2/v4l2_video_decoder_backend_stateful.h" 427+ 428+#if !BUILDFLAG(USE_LINUX_V4L2) 429 #include "media/gpu/v4l2/v4l2_video_decoder_backend_stateless.h" 430+#endif 431 432 namespace media { 433 434@@ -45,7 +48,9 @@ constexpr size_t kNumInputBuffers = 8; 435 436 // Input format V4L2 fourccs this class supports. 437 constexpr uint32_t kSupportedInputFourccs[] = { 438+#if !BUILDFLAG(USE_LINUX_V4L2) 439 V4L2_PIX_FMT_H264_SLICE, V4L2_PIX_FMT_VP8_FRAME, V4L2_PIX_FMT_VP9_FRAME, 440+#endif 441 V4L2_PIX_FMT_H264, V4L2_PIX_FMT_VP8, V4L2_PIX_FMT_VP9, 442 }; 443 444@@ -319,6 +324,7 @@ V4L2Status V4L2VideoDecoder::InitializeBackend() { 445 << " and fourcc: " << FourccToString(input_format_fourcc); 446 backend_ = std::make_unique<V4L2StatefulVideoDecoderBackend>( 447 this, device_, profile_, color_space_, decoder_task_runner_); 448+#if !BUILDFLAG(USE_LINUX_V4L2) 449 } else { 450 DCHECK_EQ(preferred_api_and_format.first, kStateless); 451 VLOGF(1) << "Using a stateless API for profile: " 452@@ -326,6 +332,7 @@ V4L2Status V4L2VideoDecoder::InitializeBackend() { 453 << " and fourcc: " << FourccToString(input_format_fourcc); 454 backend_ = std::make_unique<V4L2StatelessVideoDecoderBackend>( 455 this, device_, profile_, color_space_, decoder_task_runner_); 456+#endif 457 } 458 459 if (!backend_->Initialize()) { 460-- 4612.20.1 462 463