1From 8c13cc78f1deb0d3b22eb50021e57f73ed43173b 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/15] 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 | 42 ++++++------ 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, 115 insertions(+), 22 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 78d151fa6..101e2e4f9 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 6687b1186..951478638 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 65e5f58d1..bde4c169d 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_status.h", 176@@ -56,26 +51,31 @@ 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_chromium.cc", 193- "v4l2_video_decoder_delegate_vp9_chromium.h", 194- "v4l2_video_decoder_delegate_vp9_legacy.cc", 195- "v4l2_video_decoder_delegate_vp9_legacy.h", 196 "v4l2_video_encode_accelerator.cc", 197 "v4l2_video_encode_accelerator.h", 198 ] 199 200+ if (!use_linux_v4l2_only) { 201+ sources += [ 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_chromium.cc", 215+ "v4l2_video_decoder_delegate_vp9_chromium.h", 216+ "v4l2_video_decoder_delegate_vp9_legacy.cc", 217+ "v4l2_video_decoder_delegate_vp9_legacy.h", 218+ ] 219+ } 220+ 221 libs = [ 222 "EGL", 223 "GLESv2", 224diff --git a/media/gpu/v4l2/generic_v4l2_device.cc b/media/gpu/v4l2/generic_v4l2_device.cc 225index a6fe9d914..becf30c9c 100644 226--- a/media/gpu/v4l2/generic_v4l2_device.cc 227+++ b/media/gpu/v4l2/generic_v4l2_device.cc 228@@ -440,7 +440,11 @@ bool GenericV4L2Device::OpenDevicePath(const std::string& path, Type type) { 229 return false; 230 231 #if BUILDFLAG(USE_LIBV4L2) 232+#if BUILDFLAG(USE_LINUX_V4L2) 233+ if ( 234+#else 235 if (type == Type::kEncoder && 236+#endif 237 HANDLE_EINTR(v4l2_fd_open(device_fd_.get(), V4L2_DISABLE_CONVERSION)) != 238 -1) { 239 DVLOGF(3) << "Using libv4l2 for " << path; 240diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc 241index de2800fda..866c79e4d 100644 242--- a/media/gpu/v4l2/v4l2_device.cc 243+++ b/media/gpu/v4l2/v4l2_device.cc 244@@ -853,7 +853,9 @@ void V4L2WritableBufferRef::SetConfigStore(uint32_t config_store) { 245 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 246 DCHECK(buffer_data_); 247 248+#if !BUILDFLAG(USE_LINUX_V4L2) 249 buffer_data_->v4l2_buffer_.config_store = config_store; 250+#endif 251 } 252 253 V4L2ReadableBuffer::V4L2ReadableBuffer(const struct v4l2_buffer& v4l2_buffer, 254@@ -996,10 +998,12 @@ V4L2Queue::V4L2Queue(scoped_refptr<V4L2Device> dev, 255 return; 256 } 257 258+#if !BUILDFLAG(USE_LINUX_V4L2) 259 if (reqbufs.capabilities & V4L2_BUF_CAP_SUPPORTS_REQUESTS) { 260 supports_requests_ = true; 261 DVLOGF(4) << "Queue supports request API."; 262 } 263+#endif 264 } 265 266 V4L2Queue::~V4L2Queue() { 267@@ -1539,6 +1543,23 @@ std::string V4L2Device::GetDriverName() { 268 // static 269 uint32_t V4L2Device::VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile, 270 bool slice_based) { 271+#if BUILDFLAG(USE_LINUX_V4L2) 272+ if (slice_based) { 273+ LOG(ERROR) << "Slice not supported"; 274+ return 0; 275+ } 276+ 277+ if (profile >= H264PROFILE_MIN && profile <= H264PROFILE_MAX) { 278+ return V4L2_PIX_FMT_H264; 279+ } else if (profile >= VP8PROFILE_MIN && profile <= VP8PROFILE_MAX) { 280+ return V4L2_PIX_FMT_VP8; 281+ } else if (profile >= VP9PROFILE_MIN && profile <= VP9PROFILE_MAX) { 282+ return V4L2_PIX_FMT_VP9; 283+ } else { 284+ DVLOGF(1) << "Unsupported profile: " << GetProfileName(profile); 285+ return 0; 286+ } 287+#else 288 if (profile >= H264PROFILE_MIN && profile <= H264PROFILE_MAX) { 289 if (slice_based) 290 return V4L2_PIX_FMT_H264_SLICE; 291@@ -1558,8 +1579,10 @@ uint32_t V4L2Device::VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile, 292 DVLOGF(1) << "Unsupported profile: " << GetProfileName(profile); 293 return 0; 294 } 295+#endif 296 } 297 298+#if !BUILDFLAG(USE_LINUX_V4L2) 299 namespace { 300 301 VideoCodecProfile V4L2ProfileToVideoCodecProfile(VideoCodec codec, 302@@ -1606,9 +1629,11 @@ VideoCodecProfile V4L2ProfileToVideoCodecProfile(VideoCodec codec, 303 } 304 305 } // namespace 306+#endif 307 308 std::vector<VideoCodecProfile> V4L2Device::V4L2PixFmtToVideoCodecProfiles( 309 uint32_t pix_fmt) { 310+#if !BUILDFLAG(USE_LINUX_V4L2) 311 auto get_supported_profiles = [this]( 312 VideoCodec codec, 313 std::vector<VideoCodecProfile>* profiles) { 314@@ -1679,6 +1704,27 @@ std::vector<VideoCodecProfile> V4L2Device::V4L2PixFmtToVideoCodecProfiles( 315 VLOGF(1) << "Unhandled pixelformat " << FourccToString(pix_fmt); 316 return {}; 317 } 318+#else 319+ std::vector<VideoCodecProfile> profiles; 320+ switch (pix_fmt) { 321+ case V4L2_PIX_FMT_H264: 322+ profiles = { 323+ H264PROFILE_BASELINE, 324+ H264PROFILE_MAIN, 325+ H264PROFILE_HIGH, 326+ }; 327+ break; 328+ case V4L2_PIX_FMT_VP8: 329+ profiles = {VP8PROFILE_ANY}; 330+ break; 331+ case V4L2_PIX_FMT_VP9: 332+ profiles = {VP9PROFILE_PROFILE0}; 333+ break; 334+ default: 335+ VLOGF(1) << "Unhandled pixelformat " << FourccToString(pix_fmt); 336+ return {}; 337+ } 338+#endif 339 340 // Erase duplicated profiles. 341 std::sort(profiles.begin(), profiles.end()); 342@@ -2346,10 +2392,14 @@ bool V4L2Request::ApplyCtrls(struct v4l2_ext_controls* ctrls) { 343 return false; 344 } 345 346+#if !BUILDFLAG(USE_LINUX_V4L2) 347 ctrls->which = V4L2_CTRL_WHICH_REQUEST_VAL; 348 ctrls->request_fd = request_fd_.get(); 349 350 return true; 351+#else 352+ return false; 353+#endif 354 } 355 356 bool V4L2Request::ApplyQueueBuffer(struct v4l2_buffer* buffer) { 357@@ -2361,10 +2411,14 @@ bool V4L2Request::ApplyQueueBuffer(struct v4l2_buffer* buffer) { 358 return false; 359 } 360 361+#if !BUILDFLAG(USE_LINUX_V4L2) 362 buffer->flags |= V4L2_BUF_FLAG_REQUEST_FD; 363 buffer->request_fd = request_fd_.get(); 364 365 return true; 366+#else 367+ return false; 368+#endif 369 } 370 371 bool V4L2Request::Submit() { 372@@ -2375,7 +2429,11 @@ bool V4L2Request::Submit() { 373 return false; 374 } 375 376+#if !BUILDFLAG(USE_LINUX_V4L2) 377 return HANDLE_EINTR(ioctl(request_fd_.get(), MEDIA_REQUEST_IOC_QUEUE)) == 0; 378+#else 379+ return false; 380+#endif 381 } 382 383 bool V4L2Request::IsCompleted() { 384@@ -2418,6 +2476,7 @@ bool V4L2Request::Reset() { 385 return false; 386 } 387 388+#if !BUILDFLAG(USE_LINUX_V4L2) 389 // Reinit the request to make sure we can use it for a new submission. 390 if (HANDLE_EINTR(ioctl(request_fd_.get(), MEDIA_REQUEST_IOC_REINIT)) < 0) { 391 VPLOGF(1) << "Failed to reinit request."; 392@@ -2425,6 +2484,9 @@ bool V4L2Request::Reset() { 393 } 394 395 return true; 396+#else 397+ return false; 398+#endif 399 } 400 401 V4L2RequestRefBase::V4L2RequestRefBase(V4L2RequestRefBase&& req_base) { 402@@ -2499,6 +2561,7 @@ V4L2RequestsQueue::~V4L2RequestsQueue() { 403 absl::optional<base::ScopedFD> V4L2RequestsQueue::CreateRequestFD() { 404 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 405 406+#if !BUILDFLAG(USE_LINUX_V4L2) 407 int request_fd; 408 int ret = HANDLE_EINTR( 409 ioctl(media_fd_.get(), MEDIA_IOC_REQUEST_ALLOC, &request_fd)); 410@@ -2508,6 +2571,9 @@ absl::optional<base::ScopedFD> V4L2RequestsQueue::CreateRequestFD() { 411 } 412 413 return base::ScopedFD(request_fd); 414+#else 415+ return absl::nullopt; 416+#endif 417 } 418 419 absl::optional<V4L2RequestRef> V4L2RequestsQueue::GetFreeRequest() { 420diff --git a/media/gpu/v4l2/v4l2_video_decoder.cc b/media/gpu/v4l2/v4l2_video_decoder.cc 421index 057b28663..1df3f1a5c 100644 422--- a/media/gpu/v4l2/v4l2_video_decoder.cc 423+++ b/media/gpu/v4l2/v4l2_video_decoder.cc 424@@ -28,7 +28,10 @@ 425 #include "media/gpu/macros.h" 426 #include "media/gpu/v4l2/v4l2_status.h" 427 #include "media/gpu/v4l2/v4l2_video_decoder_backend_stateful.h" 428+ 429+#if !BUILDFLAG(USE_LINUX_V4L2) 430 #include "media/gpu/v4l2/v4l2_video_decoder_backend_stateless.h" 431+#endif 432 433 namespace media { 434 435@@ -46,7 +49,9 @@ constexpr size_t kNumInputBuffers = 8; 436 437 // Input format V4L2 fourccs this class supports. 438 constexpr uint32_t kSupportedInputFourccs[] = { 439+#if !BUILDFLAG(USE_LINUX_V4L2) 440 V4L2_PIX_FMT_H264_SLICE, V4L2_PIX_FMT_VP8_FRAME, V4L2_PIX_FMT_VP9_FRAME, 441+#endif 442 V4L2_PIX_FMT_H264, V4L2_PIX_FMT_VP8, V4L2_PIX_FMT_VP9, 443 }; 444 445@@ -320,6 +325,7 @@ V4L2Status V4L2VideoDecoder::InitializeBackend() { 446 << " and fourcc: " << FourccToString(input_format_fourcc); 447 backend_ = std::make_unique<V4L2StatefulVideoDecoderBackend>( 448 this, device_, profile_, color_space_, decoder_task_runner_); 449+#if !BUILDFLAG(USE_LINUX_V4L2) 450 } else { 451 DCHECK_EQ(preferred_api_and_format.first, kStateless); 452 VLOGF(1) << "Using a stateless API for profile: " 453@@ -327,6 +333,7 @@ V4L2Status V4L2VideoDecoder::InitializeBackend() { 454 << " and fourcc: " << FourccToString(input_format_fourcc); 455 backend_ = std::make_unique<V4L2StatelessVideoDecoderBackend>( 456 this, device_, profile_, color_space_, decoder_task_runner_); 457+#endif 458 } 459 460 if (!backend_->Initialize()) { 461-- 4622.20.1 463 464