gpu_video_decode_accelerator_factory.cc 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. // Copyright 2016 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "media/gpu/gpu_video_decode_accelerator_factory.h"
  5. #include <memory>
  6. #include "base/memory/ptr_util.h"
  7. #include "base/threading/thread_task_runner_handle.h"
  8. #include "build/build_config.h"
  9. #include "gpu/config/gpu_preferences.h"
  10. #include "media/base/media_switches.h"
  11. #include "media/gpu/buildflags.h"
  12. #include "media/gpu/gpu_video_accelerator_util.h"
  13. #include "media/gpu/macros.h"
  14. #include "media/gpu/media_gpu_export.h"
  15. #include "media/media_buildflags.h"
  16. #if BUILDFLAG(IS_WIN)
  17. #include "base/win/windows_version.h"
  18. #include "media/gpu/windows/dxva_video_decode_accelerator_win.h"
  19. #endif
  20. #if BUILDFLAG(IS_MAC)
  21. #include "media/gpu/mac/vt_video_decode_accelerator_mac.h"
  22. #endif
  23. #if BUILDFLAG(USE_VAAPI)
  24. #include "media/gpu/vaapi/vaapi_video_decode_accelerator.h"
  25. #include "ui/gl/gl_implementation.h"
  26. #elif BUILDFLAG(USE_V4L2_CODEC)
  27. #include "media/gpu/v4l2/v4l2_device.h"
  28. #include "media/gpu/v4l2/v4l2_slice_video_decode_accelerator.h"
  29. #include "media/gpu/v4l2/v4l2_video_decode_accelerator.h"
  30. #include "ui/gl/gl_surface_egl.h"
  31. #endif
  32. namespace media {
  33. namespace {
  34. gpu::VideoDecodeAcceleratorCapabilities GetDecoderCapabilitiesInternal(
  35. const gpu::GpuPreferences& gpu_preferences,
  36. const gpu::GpuDriverBugWorkarounds& workarounds) {
  37. if (gpu_preferences.disable_accelerated_video_decode)
  38. return gpu::VideoDecodeAcceleratorCapabilities();
  39. // Query VDAs for their capabilities and construct a set of supported
  40. // profiles for current platform. This must be done in the same order as in
  41. // CreateVDA(), as we currently preserve additional capabilities (such as
  42. // resolutions supported) only for the first VDA supporting the given codec
  43. // profile (instead of calculating a superset).
  44. // TODO(posciak,henryhsu): improve this so that we choose a superset of
  45. // resolutions and other supported profile parameters.
  46. VideoDecodeAccelerator::Capabilities capabilities;
  47. #if BUILDFLAG(IS_WIN)
  48. capabilities.supported_profiles =
  49. DXVAVideoDecodeAccelerator::GetSupportedProfiles(gpu_preferences,
  50. workarounds);
  51. #elif BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
  52. #if BUILDFLAG(USE_VAAPI)
  53. capabilities.supported_profiles =
  54. VaapiVideoDecodeAccelerator::GetSupportedProfiles();
  55. #elif BUILDFLAG(USE_V4L2_CODEC)
  56. GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(
  57. V4L2VideoDecodeAccelerator::GetSupportedProfiles(),
  58. &capabilities.supported_profiles);
  59. GpuVideoAcceleratorUtil::InsertUniqueDecodeProfiles(
  60. V4L2SliceVideoDecodeAccelerator::GetSupportedProfiles(),
  61. &capabilities.supported_profiles);
  62. #endif
  63. #elif BUILDFLAG(IS_MAC)
  64. capabilities.supported_profiles =
  65. VTVideoDecodeAccelerator::GetSupportedProfiles(workarounds);
  66. #endif
  67. return GpuVideoAcceleratorUtil::ConvertMediaToGpuDecodeCapabilities(
  68. capabilities);
  69. }
  70. } // namespace
  71. // static
  72. MEDIA_GPU_EXPORT std::unique_ptr<GpuVideoDecodeAcceleratorFactory>
  73. GpuVideoDecodeAcceleratorFactory::Create(
  74. const GpuVideoDecodeGLClient& gl_client) {
  75. return base::WrapUnique(new GpuVideoDecodeAcceleratorFactory(gl_client));
  76. }
  77. // static
  78. MEDIA_GPU_EXPORT gpu::VideoDecodeAcceleratorCapabilities
  79. GpuVideoDecodeAcceleratorFactory::GetDecoderCapabilities(
  80. const gpu::GpuPreferences& gpu_preferences,
  81. const gpu::GpuDriverBugWorkarounds& workarounds) {
  82. // Cache the capabilities so that they will not be computed more than once per
  83. // GPU process. It is assumed that |gpu_preferences| and |workarounds| do not
  84. // change between calls.
  85. // TODO(sandersd): Move cache to GpuMojoMediaClient once
  86. // |video_decode_accelerator_capabilities| is removed from GPUInfo.
  87. static gpu::VideoDecodeAcceleratorCapabilities capabilities =
  88. GetDecoderCapabilitiesInternal(gpu_preferences, workarounds);
  89. #if BUILDFLAG(USE_V4L2_CODEC)
  90. // V4L2-only: the decoder devices may not be visible at the time the GPU
  91. // process is starting. If the capabilities vector is empty, try to query the
  92. // devices again in the hope that they will have appeared in the meantime.
  93. // TODO(crbug.com/948147): trigger query when an device add/remove event
  94. // (e.g. via udev) has happened instead.
  95. if (capabilities.supported_profiles.empty()) {
  96. VLOGF(1) << "Capabilities empty, querying again...";
  97. capabilities = GetDecoderCapabilitiesInternal(gpu_preferences, workarounds);
  98. }
  99. #endif
  100. return capabilities;
  101. }
  102. MEDIA_GPU_EXPORT std::unique_ptr<VideoDecodeAccelerator>
  103. GpuVideoDecodeAcceleratorFactory::CreateVDA(
  104. VideoDecodeAccelerator::Client* client,
  105. const VideoDecodeAccelerator::Config& config,
  106. const gpu::GpuDriverBugWorkarounds& workarounds,
  107. const gpu::GpuPreferences& gpu_preferences,
  108. MediaLog* media_log) {
  109. DCHECK(thread_checker_.CalledOnValidThread());
  110. if (gpu_preferences.disable_accelerated_video_decode)
  111. return nullptr;
  112. // Array of Create..VDA() function pointers, potentially usable on current
  113. // platform. This list is ordered by priority, from most to least preferred,
  114. // if applicable. This list must be in the same order as the querying order
  115. // in GetDecoderCapabilities() above.
  116. using CreateVDAFp = std::unique_ptr<VideoDecodeAccelerator> (
  117. GpuVideoDecodeAcceleratorFactory::*)(const gpu::GpuDriverBugWorkarounds&,
  118. const gpu::GpuPreferences&,
  119. MediaLog* media_log) const;
  120. const CreateVDAFp create_vda_fps[] = {
  121. #if BUILDFLAG(IS_WIN)
  122. &GpuVideoDecodeAcceleratorFactory::CreateDXVAVDA,
  123. #endif
  124. // Usually only one of USE_VAAPI or USE_V4L2_CODEC is defined on ChromeOS,
  125. // except for Chromeboxes with companion video acceleration chips, which have
  126. // both. In those cases prefer the VA creation function.
  127. #if BUILDFLAG(USE_VAAPI)
  128. &GpuVideoDecodeAcceleratorFactory::CreateVaapiVDA,
  129. #elif BUILDFLAG(USE_V4L2_CODEC)
  130. &GpuVideoDecodeAcceleratorFactory::CreateV4L2VDA,
  131. &GpuVideoDecodeAcceleratorFactory::CreateV4L2SliceVDA,
  132. #endif
  133. #if BUILDFLAG(IS_MAC)
  134. &GpuVideoDecodeAcceleratorFactory::CreateVTVDA,
  135. #endif
  136. };
  137. std::unique_ptr<VideoDecodeAccelerator> vda;
  138. for (const auto& create_vda_function : create_vda_fps) {
  139. vda = (this->*create_vda_function)(workarounds, gpu_preferences, media_log);
  140. if (vda && vda->Initialize(config, client))
  141. return vda;
  142. }
  143. return nullptr;
  144. }
  145. #if BUILDFLAG(IS_WIN)
  146. std::unique_ptr<VideoDecodeAccelerator>
  147. GpuVideoDecodeAcceleratorFactory::CreateDXVAVDA(
  148. const gpu::GpuDriverBugWorkarounds& workarounds,
  149. const gpu::GpuPreferences& gpu_preferences,
  150. MediaLog* media_log) const {
  151. std::unique_ptr<VideoDecodeAccelerator> decoder;
  152. DVLOG(0) << "Initializing DXVA HW decoder for windows.";
  153. decoder.reset(new DXVAVideoDecodeAccelerator(
  154. gl_client_.get_context, gl_client_.make_context_current,
  155. gl_client_.bind_image, workarounds, gpu_preferences, media_log));
  156. return decoder;
  157. }
  158. #endif
  159. #if BUILDFLAG(USE_VAAPI)
  160. std::unique_ptr<VideoDecodeAccelerator>
  161. GpuVideoDecodeAcceleratorFactory::CreateVaapiVDA(
  162. const gpu::GpuDriverBugWorkarounds& /*workarounds*/,
  163. const gpu::GpuPreferences& /*gpu_preferences*/,
  164. MediaLog* /*media_log*/) const {
  165. std::unique_ptr<VideoDecodeAccelerator> decoder;
  166. decoder.reset(new VaapiVideoDecodeAccelerator(gl_client_.make_context_current,
  167. gl_client_.bind_image));
  168. return decoder;
  169. }
  170. #elif BUILDFLAG(USE_V4L2_CODEC)
  171. std::unique_ptr<VideoDecodeAccelerator>
  172. GpuVideoDecodeAcceleratorFactory::CreateV4L2VDA(
  173. const gpu::GpuDriverBugWorkarounds& /*workarounds*/,
  174. const gpu::GpuPreferences& /*gpu_preferences*/,
  175. MediaLog* /*media_log*/) const {
  176. std::unique_ptr<VideoDecodeAccelerator> decoder;
  177. scoped_refptr<V4L2Device> device = V4L2Device::Create();
  178. if (device.get()) {
  179. decoder.reset(new V4L2VideoDecodeAccelerator(
  180. gl::GLSurfaceEGL::GetGLDisplayEGL()->GetDisplay(),
  181. gl_client_.get_context, gl_client_.make_context_current, device));
  182. }
  183. return decoder;
  184. }
  185. std::unique_ptr<VideoDecodeAccelerator>
  186. GpuVideoDecodeAcceleratorFactory::CreateV4L2SliceVDA(
  187. const gpu::GpuDriverBugWorkarounds& /*workarounds*/,
  188. const gpu::GpuPreferences& /*gpu_preferences*/,
  189. MediaLog* /*media_log*/) const {
  190. std::unique_ptr<VideoDecodeAccelerator> decoder;
  191. scoped_refptr<V4L2Device> device = V4L2Device::Create();
  192. if (device.get()) {
  193. decoder.reset(new V4L2SliceVideoDecodeAccelerator(
  194. device, gl::GLSurfaceEGL::GetGLDisplayEGL()->GetDisplay(),
  195. gl_client_.bind_image, gl_client_.make_context_current));
  196. }
  197. return decoder;
  198. }
  199. #endif
  200. #if BUILDFLAG(IS_MAC)
  201. std::unique_ptr<VideoDecodeAccelerator>
  202. GpuVideoDecodeAcceleratorFactory::CreateVTVDA(
  203. const gpu::GpuDriverBugWorkarounds& workarounds,
  204. const gpu::GpuPreferences& gpu_preferences,
  205. MediaLog* media_log) const {
  206. std::unique_ptr<VideoDecodeAccelerator> decoder;
  207. decoder.reset(
  208. new VTVideoDecodeAccelerator(gl_client_, workarounds, media_log));
  209. return decoder;
  210. }
  211. #endif
  212. GpuVideoDecodeAcceleratorFactory::GpuVideoDecodeAcceleratorFactory(
  213. const GpuVideoDecodeGLClient& gl_client)
  214. : gl_client_(gl_client) {}
  215. GpuVideoDecodeAcceleratorFactory::~GpuVideoDecodeAcceleratorFactory() = default;
  216. } // namespace media