1From f62053a3a3cc31905586e657edcac18f4c6ad8e4 Mon Sep 17 00:00:00 2001 2From: Maksim Sisov <msisov@igalia.com> 3Date: Wed, 31 Jul 2019 09:56:24 +0300 4Subject: [PATCH 02/17] 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 | 43 ++++++------ 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, 118 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 30267d96c..0c8f78de1 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 0e55ef47e..2096dc619 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 defined(OS_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 defined(OS_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 defined(OS_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 a80cac212..1021af34a 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 defined(OS_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 0322bbf7f..e7a8743d4 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,24 +51,34 @@ 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_chromium.cc", 191- "v4l2_video_decoder_delegate_vp9_chromium.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_decode_surface.cc", 201+ "v4l2_decode_surface.h", 202+ "v4l2_decode_surface_handler.h", 203+ "v4l2_slice_video_decode_accelerator.cc", 204+ "v4l2_slice_video_decode_accelerator.h", 205+ "v4l2_video_decoder_backend_stateless.cc", 206+ "v4l2_video_decoder_backend_stateless.h", 207+ "v4l2_video_decoder_delegate_h264.cc", 208+ "v4l2_video_decoder_delegate_h264.h", 209+ "v4l2_video_decoder_delegate_h264_legacy.cc", 210+ "v4l2_video_decoder_delegate_h264_legacy.h", 211+ "v4l2_video_decoder_delegate_vp8.cc", 212+ "v4l2_video_decoder_delegate_vp8.h", 213+ "v4l2_video_decoder_delegate_vp8_legacy.cc", 214+ "v4l2_video_decoder_delegate_vp8_legacy.h", 215+ "v4l2_video_decoder_delegate_vp9_chromium.cc", 216+ "v4l2_video_decoder_delegate_vp9_chromium.h", 217+ "v4l2_video_decoder_delegate_vp9_legacy.cc", 218+ "v4l2_video_decoder_delegate_vp9_legacy.h", 219+ ] 220+ } 221+ 222 libs = [ 223 "EGL", 224 "GLESv2", 225diff --git a/media/gpu/v4l2/generic_v4l2_device.cc b/media/gpu/v4l2/generic_v4l2_device.cc 226index b64c9bd0f..92ec1b607 100644 227--- a/media/gpu/v4l2/generic_v4l2_device.cc 228+++ b/media/gpu/v4l2/generic_v4l2_device.cc 229@@ -441,7 +441,11 @@ bool GenericV4L2Device::OpenDevicePath(const std::string& path, Type type) { 230 return false; 231 232 #if BUILDFLAG(USE_LIBV4L2) 233+#if BUILDFLAG(USE_LINUX_V4L2) 234+ if ( 235+#else 236 if (type == Type::kEncoder && 237+#endif 238 HANDLE_EINTR(v4l2_fd_open(device_fd_.get(), V4L2_DISABLE_CONVERSION)) != 239 -1) { 240 DVLOGF(3) << "Using libv4l2 for " << path; 241diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc 242index ee99d095f..98a0d51fa 100644 243--- a/media/gpu/v4l2/v4l2_device.cc 244+++ b/media/gpu/v4l2/v4l2_device.cc 245@@ -853,7 +853,9 @@ void V4L2WritableBufferRef::SetConfigStore(uint32_t config_store) { 246 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 247 DCHECK(buffer_data_); 248 249+#if !BUILDFLAG(USE_LINUX_V4L2) 250 buffer_data_->v4l2_buffer_.config_store = config_store; 251+#endif 252 } 253 254 V4L2ReadableBuffer::V4L2ReadableBuffer(const struct v4l2_buffer& v4l2_buffer, 255@@ -996,10 +998,12 @@ V4L2Queue::V4L2Queue(scoped_refptr<V4L2Device> dev, 256 return; 257 } 258 259+#if !BUILDFLAG(USE_LINUX_V4L2) 260 if (reqbufs.capabilities & V4L2_BUF_CAP_SUPPORTS_REQUESTS) { 261 supports_requests_ = true; 262 DVLOGF(4) << "Queue supports request API."; 263 } 264+#endif 265 } 266 267 V4L2Queue::~V4L2Queue() { 268@@ -1527,6 +1531,23 @@ scoped_refptr<V4L2Device> V4L2Device::Create() { 269 // static 270 uint32_t V4L2Device::VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile, 271 bool slice_based) { 272+#if BUILDFLAG(USE_LINUX_V4L2) 273+ if (slice_based) { 274+ LOG(ERROR) << "Slice not supported"; 275+ return 0; 276+ } 277+ 278+ if (profile >= H264PROFILE_MIN && profile <= H264PROFILE_MAX) { 279+ return V4L2_PIX_FMT_H264; 280+ } else if (profile >= VP8PROFILE_MIN && profile <= VP8PROFILE_MAX) { 281+ return V4L2_PIX_FMT_VP8; 282+ } else if (profile >= VP9PROFILE_MIN && profile <= VP9PROFILE_MAX) { 283+ return V4L2_PIX_FMT_VP9; 284+ } else { 285+ DVLOGF(1) << "Unsupported profile: " << GetProfileName(profile); 286+ return 0; 287+ } 288+#else 289 if (profile >= H264PROFILE_MIN && profile <= H264PROFILE_MAX) { 290 if (slice_based) 291 return V4L2_PIX_FMT_H264_SLICE; 292@@ -1546,8 +1567,10 @@ uint32_t V4L2Device::VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile, 293 DVLOGF(1) << "Unsupported profile: " << GetProfileName(profile); 294 return 0; 295 } 296+#endif 297 } 298 299+#if !BUILDFLAG(USE_LINUX_V4L2) 300 namespace { 301 302 VideoCodecProfile V4L2ProfileToVideoCodecProfile(VideoCodec codec, 303@@ -1594,9 +1617,11 @@ VideoCodecProfile V4L2ProfileToVideoCodecProfile(VideoCodec codec, 304 } 305 306 } // namespace 307+#endif 308 309 std::vector<VideoCodecProfile> V4L2Device::V4L2PixFmtToVideoCodecProfiles( 310 uint32_t pix_fmt) { 311+#if !BUILDFLAG(USE_LINUX_V4L2) 312 auto get_supported_profiles = [this]( 313 VideoCodec codec, 314 std::vector<VideoCodecProfile>* profiles) { 315@@ -1667,6 +1692,27 @@ std::vector<VideoCodecProfile> V4L2Device::V4L2PixFmtToVideoCodecProfiles( 316 VLOGF(1) << "Unhandled pixelformat " << FourccToString(pix_fmt); 317 return {}; 318 } 319+#else 320+ std::vector<VideoCodecProfile> profiles; 321+ switch (pix_fmt) { 322+ case V4L2_PIX_FMT_H264: 323+ profiles = { 324+ H264PROFILE_BASELINE, 325+ H264PROFILE_MAIN, 326+ H264PROFILE_HIGH, 327+ }; 328+ break; 329+ case V4L2_PIX_FMT_VP8: 330+ profiles = {VP8PROFILE_ANY}; 331+ break; 332+ case V4L2_PIX_FMT_VP9: 333+ profiles = {VP9PROFILE_PROFILE0}; 334+ break; 335+ default: 336+ VLOGF(1) << "Unhandled pixelformat " << FourccToString(pix_fmt); 337+ return {}; 338+ } 339+#endif 340 341 // Erase duplicated profiles. 342 std::sort(profiles.begin(), profiles.end()); 343@@ -2334,10 +2380,14 @@ bool V4L2Request::ApplyCtrls(struct v4l2_ext_controls* ctrls) { 344 return false; 345 } 346 347+#if !BUILDFLAG(USE_LINUX_V4L2) 348 ctrls->which = V4L2_CTRL_WHICH_REQUEST_VAL; 349 ctrls->request_fd = request_fd_.get(); 350 351 return true; 352+#else 353+ return false; 354+#endif 355 } 356 357 bool V4L2Request::ApplyQueueBuffer(struct v4l2_buffer* buffer) { 358@@ -2349,10 +2399,14 @@ bool V4L2Request::ApplyQueueBuffer(struct v4l2_buffer* buffer) { 359 return false; 360 } 361 362+#if !BUILDFLAG(USE_LINUX_V4L2) 363 buffer->flags |= V4L2_BUF_FLAG_REQUEST_FD; 364 buffer->request_fd = request_fd_.get(); 365 366 return true; 367+#else 368+ return false; 369+#endif 370 } 371 372 bool V4L2Request::Submit() { 373@@ -2363,7 +2417,11 @@ bool V4L2Request::Submit() { 374 return false; 375 } 376 377+#if !BUILDFLAG(USE_LINUX_V4L2) 378 return HANDLE_EINTR(ioctl(request_fd_.get(), MEDIA_REQUEST_IOC_QUEUE)) == 0; 379+#else 380+ return false; 381+#endif 382 } 383 384 bool V4L2Request::IsCompleted() { 385@@ -2406,6 +2464,7 @@ bool V4L2Request::Reset() { 386 return false; 387 } 388 389+#if !BUILDFLAG(USE_LINUX_V4L2) 390 // Reinit the request to make sure we can use it for a new submission. 391 if (HANDLE_EINTR(ioctl(request_fd_.get(), MEDIA_REQUEST_IOC_REINIT)) < 0) { 392 VPLOGF(1) << "Failed to reinit request."; 393@@ -2413,6 +2472,9 @@ bool V4L2Request::Reset() { 394 } 395 396 return true; 397+#else 398+ return false; 399+#endif 400 } 401 402 V4L2RequestRefBase::V4L2RequestRefBase(V4L2RequestRefBase&& req_base) { 403@@ -2487,6 +2549,7 @@ V4L2RequestsQueue::~V4L2RequestsQueue() { 404 absl::optional<base::ScopedFD> V4L2RequestsQueue::CreateRequestFD() { 405 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 406 407+#if !BUILDFLAG(USE_LINUX_V4L2) 408 int request_fd; 409 int ret = HANDLE_EINTR( 410 ioctl(media_fd_.get(), MEDIA_IOC_REQUEST_ALLOC, &request_fd)); 411@@ -2496,6 +2559,9 @@ absl::optional<base::ScopedFD> V4L2RequestsQueue::CreateRequestFD() { 412 } 413 414 return base::ScopedFD(request_fd); 415+#else 416+ return absl::nullopt; 417+#endif 418 } 419 420 absl::optional<V4L2RequestRef> V4L2RequestsQueue::GetFreeRequest() { 421diff --git a/media/gpu/v4l2/v4l2_video_decoder.cc b/media/gpu/v4l2/v4l2_video_decoder.cc 422index 7534052f9..afde6b8e4 100644 423--- a/media/gpu/v4l2/v4l2_video_decoder.cc 424+++ b/media/gpu/v4l2/v4l2_video_decoder.cc 425@@ -27,7 +27,10 @@ 426 #include "media/gpu/macros.h" 427 #include "media/gpu/v4l2/v4l2_status.h" 428 #include "media/gpu/v4l2/v4l2_video_decoder_backend_stateful.h" 429+ 430+#if !BUILDFLAG(USE_LINUX_V4L2) 431 #include "media/gpu/v4l2/v4l2_video_decoder_backend_stateless.h" 432+#endif 433 434 namespace media { 435 436@@ -45,7 +48,9 @@ constexpr size_t kNumInputBuffers = 8; 437 438 // Input format V4L2 fourccs this class supports. 439 constexpr uint32_t kSupportedInputFourccs[] = { 440+#if !BUILDFLAG(USE_LINUX_V4L2) 441 V4L2_PIX_FMT_H264_SLICE, V4L2_PIX_FMT_VP8_FRAME, V4L2_PIX_FMT_VP9_FRAME, 442+#endif 443 V4L2_PIX_FMT_H264, V4L2_PIX_FMT_VP8, V4L2_PIX_FMT_VP9, 444 }; 445 446@@ -317,6 +322,7 @@ V4L2Status V4L2VideoDecoder::InitializeBackend() { 447 << " and fourcc: " << FourccToString(input_format_fourcc); 448 backend_ = std::make_unique<V4L2StatefulVideoDecoderBackend>( 449 this, device_, profile_, decoder_task_runner_); 450+#if !BUILDFLAG(USE_LINUX_V4L2) 451 } else { 452 DCHECK_EQ(preferred_api_and_format.first, kStateless); 453 VLOGF(1) << "Using a stateless API for profile: " 454@@ -324,6 +330,7 @@ V4L2Status V4L2VideoDecoder::InitializeBackend() { 455 << " and fourcc: " << FourccToString(input_format_fourcc); 456 backend_ = std::make_unique<V4L2StatelessVideoDecoderBackend>( 457 this, device_, profile_, decoder_task_runner_); 458+#endif 459 } 460 461 if (!backend_->Initialize()) { 462-- 4632.20.1 464 465