[M120 Migration][MM][CAPI] Fix the logic for media using capi player.
[platform/framework/web/chromium-efl.git] / media / mojo / services / gpu_mojo_media_client.cc
1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/mojo/services/gpu_mojo_media_client.h"
6
7 #include <utility>
8
9 #include "base/feature_list.h"
10 #include "base/functional/bind.h"
11 #include "base/memory/ptr_util.h"
12 #include "base/metrics/histogram_functions.h"
13 #include "base/task/sequenced_task_runner.h"
14 #include "base/task/single_thread_task_runner.h"
15 #include "build/build_config.h"
16 #include "build/chromeos_buildflags.h"
17 #include "gpu/ipc/service/gpu_channel.h"
18 #include "media/base/audio_decoder.h"
19 #include "media/base/audio_encoder.h"
20 #include "media/base/cdm_factory.h"
21 #include "media/base/media_log.h"
22 #include "media/base/media_switches.h"
23 #include "media/base/media_util.h"
24 #include "media/base/video_decoder.h"
25 #include "media/gpu/gpu_video_accelerator_util.h"
26 #include "media/gpu/gpu_video_decode_accelerator_factory.h"
27 #include "media/gpu/gpu_video_decode_accelerator_helpers.h"
28 #include "media/gpu/ipc/service/media_gpu_channel_manager.h"
29 #include "media/mojo/mojom/video_decoder.mojom.h"
30 #include "media/video/video_decode_accelerator.h"
31 #include "third_party/abseil-cpp/absl/types/optional.h"
32
33 namespace media {
34
35 namespace {
36
37 gpu::CommandBufferStub* GetCommandBufferStub(
38     scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner,
39     base::WeakPtr<MediaGpuChannelManager> media_gpu_channel_manager,
40     base::UnguessableToken channel_token,
41     int32_t route_id) {
42   DCHECK(gpu_task_runner->BelongsToCurrentThread());
43   if (!media_gpu_channel_manager)
44     return nullptr;
45
46   gpu::GpuChannel* channel =
47       media_gpu_channel_manager->LookupChannel(channel_token);
48   if (!channel)
49     return nullptr;
50
51   gpu::CommandBufferStub* stub = channel->LookupCommandBuffer(route_id);
52   if (!stub)
53     return nullptr;
54
55   // Only allow stubs that have a ContextGroup, that is, the GLES2 ones. Later
56   // code assumes the ContextGroup is valid.
57   if (!stub->decoder_context()->GetContextGroup())
58     return nullptr;
59
60   return stub;
61 }
62
63 SupportedVideoDecoderConfigs GetVDAVideoDecoderConfigs(
64     const gpu::GpuPreferences& gpu_preferences,
65     const gpu::GpuDriverBugWorkarounds& gpu_workarounds) {
66   VideoDecodeAccelerator::Capabilities capabilities =
67       GpuVideoAcceleratorUtil::ConvertGpuToMediaDecodeCapabilities(
68           GpuVideoDecodeAcceleratorFactory::GetDecoderCapabilities(
69               gpu_preferences, gpu_workarounds));
70   return ConvertFromSupportedProfiles(
71       capabilities.supported_profiles,
72       capabilities.flags &
73           VideoDecodeAccelerator::Capabilities::SUPPORTS_ENCRYPTED_STREAMS);
74 }
75
76 }  // namespace
77
78 VideoDecoderTraits::~VideoDecoderTraits() = default;
79 VideoDecoderTraits::VideoDecoderTraits(
80     scoped_refptr<base::SequencedTaskRunner> task_runner,
81     scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner,
82     std::unique_ptr<MediaLog> media_log,
83     RequestOverlayInfoCB request_overlay_info_cb,
84     const gfx::ColorSpace* target_color_space,
85     gpu::GpuPreferences gpu_preferences,
86     gpu::GpuFeatureInfo gpu_feature_info,
87     gpu::GPUInfo gpu_info,
88     const gpu::GpuDriverBugWorkarounds* gpu_workarounds,
89     gpu::GpuMemoryBufferFactory* gpu_memory_buffer_factory,
90     GetConfigCacheCB get_cached_configs_cb,
91     GetCommandBufferStubCB get_command_buffer_stub_cb,
92     AndroidOverlayMojoFactoryCB android_overlay_factory_cb,
93     mojo::PendingRemote<stable::mojom::StableVideoDecoder> oop_video_decoder,
94     base::WeakPtr<MediaGpuChannelManager> media_gpu_channel_manager)
95     : task_runner(std::move(task_runner)),
96       gpu_task_runner(std::move(gpu_task_runner)),
97       media_log(std::move(media_log)),
98       request_overlay_info_cb(request_overlay_info_cb),
99       target_color_space(target_color_space),
100       gpu_preferences(gpu_preferences),
101       gpu_feature_info(gpu_feature_info),
102       gpu_info(gpu_info),
103       gpu_workarounds(gpu_workarounds),
104       gpu_memory_buffer_factory(gpu_memory_buffer_factory),
105       get_cached_configs_cb(std::move(get_cached_configs_cb)),
106       get_command_buffer_stub_cb(std::move(get_command_buffer_stub_cb)),
107       android_overlay_factory_cb(std::move(android_overlay_factory_cb)),
108       oop_video_decoder(std::move(oop_video_decoder)),
109       media_gpu_channel_manager(media_gpu_channel_manager) {}
110
111 GpuMojoMediaClient::GpuMojoMediaClient(
112     const gpu::GpuPreferences& gpu_preferences,
113     const gpu::GpuDriverBugWorkarounds& gpu_workarounds,
114     const gpu::GpuFeatureInfo& gpu_feature_info,
115     const gpu::GPUInfo& gpu_info,
116     scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner,
117     base::WeakPtr<MediaGpuChannelManager> media_gpu_channel_manager,
118     gpu::GpuMemoryBufferFactory* gpu_memory_buffer_factory,
119     AndroidOverlayMojoFactoryCB android_overlay_factory_cb)
120     : gpu_preferences_(gpu_preferences),
121       gpu_workarounds_(gpu_workarounds),
122       gpu_feature_info_(gpu_feature_info),
123       gpu_info_(gpu_info),
124       gpu_task_runner_(std::move(gpu_task_runner)),
125       media_gpu_channel_manager_(std::move(media_gpu_channel_manager)),
126       android_overlay_factory_cb_(std::move(android_overlay_factory_cb)),
127       gpu_memory_buffer_factory_(gpu_memory_buffer_factory) {
128   base::UmaHistogramEnumeration("Media.GPU.VideoDecoderType",
129                                 GetDecoderImplementationType());
130 }
131
132 GpuMojoMediaClient::~GpuMojoMediaClient() = default;
133
134 std::unique_ptr<AudioDecoder> GpuMojoMediaClient::CreateAudioDecoder(
135     scoped_refptr<base::SequencedTaskRunner> task_runner,
136     std::unique_ptr<MediaLog> media_log) {
137   return CreatePlatformAudioDecoder(std::move(task_runner),
138                                     std::move(media_log));
139 }
140
141 std::unique_ptr<AudioEncoder> GpuMojoMediaClient::CreateAudioEncoder(
142     scoped_refptr<base::SequencedTaskRunner> task_runner) {
143   return base::FeatureList::IsEnabled(kPlatformAudioEncoder)
144              ? CreatePlatformAudioEncoder(std::move(task_runner))
145              : nullptr;
146 }
147
148 VideoDecoderType GpuMojoMediaClient::GetDecoderImplementationType() {
149   return GetPlatformDecoderImplementationType(gpu_workarounds_,
150                                               gpu_preferences_, gpu_info_);
151 }
152
153 SupportedVideoDecoderConfigs
154 GpuMojoMediaClient::GetSupportedVideoDecoderConfigs() {
155   if (!supported_config_cache_) {
156     supported_config_cache_ = GetSupportedVideoDecoderConfigsStatic(
157         media_gpu_channel_manager_, gpu_preferences_, gpu_workarounds_,
158         gpu_info_);
159
160     // Once per GPU process record accelerator information. Profile support is
161     // often just manufactured and not tested, so just record the base codec.
162     bool has_accelerated_h264 = false;
163     bool has_accelerated_h265 = false;
164     bool has_accelerated_vp9 = false;
165     bool has_accelerated_av1 = false;
166     if (supported_config_cache_) {
167       for (const auto& config : *supported_config_cache_) {
168         if (config.profile_min >= H264PROFILE_MIN &&
169             config.profile_max <= H264PROFILE_MAX) {
170           has_accelerated_h264 = true;
171         } else if (config.profile_min >= VP9PROFILE_MIN &&
172                    config.profile_max <= VP9PROFILE_MAX) {
173           has_accelerated_vp9 = true;
174         } else if (config.profile_min >= AV1PROFILE_MIN &&
175                    config.profile_max <= AV1PROFILE_MAX) {
176           has_accelerated_av1 = true;
177         } else if ((config.profile_min >= HEVCPROFILE_MIN &&
178                     config.profile_max <= HEVCPROFILE_MAX) ||
179                    (config.profile_min >= HEVCPROFILE_EXT_MIN &&
180                     config.profile_max <= HEVCPROFILE_EXT_MAX)) {
181           has_accelerated_h265 = true;
182         }
183       }
184     }
185
186     base::UmaHistogramBoolean("Media.HasAcceleratedVideoDecode.H264",
187                               has_accelerated_h264);
188     base::UmaHistogramBoolean("Media.HasAcceleratedVideoDecode.H265",
189                               has_accelerated_h265);
190     base::UmaHistogramBoolean("Media.HasAcceleratedVideoDecode.VP9",
191                               has_accelerated_vp9);
192     base::UmaHistogramBoolean("Media.HasAcceleratedVideoDecode.AV1",
193                               has_accelerated_av1);
194   }
195   return supported_config_cache_.value_or(SupportedVideoDecoderConfigs{});
196 }
197
198 absl::optional<SupportedVideoDecoderConfigs>
199 GpuMojoMediaClient::GetSupportedVideoDecoderConfigsStatic(
200     base::WeakPtr<MediaGpuChannelManager> manager,
201     const gpu::GpuPreferences& gpu_preferences,
202     const gpu::GpuDriverBugWorkarounds& gpu_workarounds,
203     const gpu::GPUInfo& gpu_info) {
204   return GetPlatformSupportedVideoDecoderConfigs(
205       manager, gpu_workarounds, gpu_preferences, gpu_info,
206       base::BindOnce(&GetVDAVideoDecoderConfigs, gpu_preferences,
207                      gpu_workarounds));
208 }
209
210 #if BUILDFLAG(ALLOW_OOP_VIDEO_DECODER)
211 void GpuMojoMediaClient::NotifyDecoderSupportKnown(
212     mojo::PendingRemote<stable::mojom::StableVideoDecoder> oop_video_decoder,
213     base::OnceCallback<
214         void(mojo::PendingRemote<stable::mojom::StableVideoDecoder>)> cb) {
215 #if BUILDFLAG(USE_VAAPI) || BUILDFLAG(USE_V4L2_CODEC)
216   // TODO(b/195769334): this call should ideally be guarded only by
217   // BUILDFLAG(ALLOW_OOP_VIDEO_DECODER) because eventually, the GPU process
218   // should not need to know what video acceleration API is used. Until then, we
219   // must guard this with (USE_VAAPI || USE_V4L2_CODEC) to be able to compile
220   // Linux/CrOS builds that don't use either API (e.g., linux-x64-castos).
221   NotifyPlatformDecoderSupport(gpu_preferences_, gpu_info_,
222                                std::move(oop_video_decoder), std::move(cb));
223 #else
224   DCHECK(!oop_video_decoder);
225   std::move(cb).Run(std::move(oop_video_decoder));
226 #endif  // BUILDFLAG(USE_VAAPI) || BUILDFLAG(USE_V4L2_CODEC)
227 }
228 #endif  // BUILDFLAG(ALLOW_OOP_VIDEO_DECODER)
229
230 std::unique_ptr<VideoDecoder> GpuMojoMediaClient::CreateVideoDecoder(
231     scoped_refptr<base::SequencedTaskRunner> task_runner,
232     MediaLog* media_log,
233     mojom::CommandBufferIdPtr command_buffer_id,
234     RequestOverlayInfoCB request_overlay_info_cb,
235     const gfx::ColorSpace& target_color_space,
236     mojo::PendingRemote<stable::mojom::StableVideoDecoder> oop_video_decoder) {
237   // All implementations require a command buffer.
238   if (!command_buffer_id)
239     return nullptr;
240   std::unique_ptr<MediaLog> log =
241       media_log ? media_log->Clone() : std::make_unique<media::NullMediaLog>();
242   auto get_stub_cb = base::BindRepeating(
243       &GetCommandBufferStub, gpu_task_runner_, media_gpu_channel_manager_,
244       command_buffer_id->channel_token, command_buffer_id->route_id);
245   VideoDecoderTraits traits(
246       task_runner, gpu_task_runner_, std::move(log),
247       std::move(request_overlay_info_cb), &target_color_space, gpu_preferences_,
248       gpu_feature_info_, gpu_info_, &gpu_workarounds_,
249       gpu_memory_buffer_factory_,
250       // CreatePlatformVideoDecoder does not keep a reference to |traits|
251       // so this bound method will not outlive |this|
252       base::BindRepeating(&GpuMojoMediaClient::GetSupportedVideoDecoderConfigs,
253                           base::Unretained(this)),
254       get_stub_cb, android_overlay_factory_cb_, std::move(oop_video_decoder),
255       media_gpu_channel_manager_);
256
257   return CreatePlatformVideoDecoder(traits);
258 }
259
260 std::unique_ptr<CdmFactory> GpuMojoMediaClient::CreateCdmFactory(
261     mojom::FrameInterfaceFactory* frame_interfaces) {
262   return CreatePlatformCdmFactory(frame_interfaces);
263 }
264
265 }  // namespace media