1 // Copyright 2013 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
5 #include "content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h"
6
7 #include <GLES2/gl2.h>
8 #include <GLES2/gl2ext.h>
9
10 #include "base/bind.h"
11 #include "base/memory/ptr_util.h"
12 #include "base/memory/unsafe_shared_memory_region.h"
13 #include "base/metrics/histogram_macros.h"
14 #include "base/sequenced_task_runner.h"
15 #include "base/unguessable_token.h"
16 #include "build/build_config.h"
17 #include "components/viz/common/gpu/context_provider.h"
18 #include "content/child/child_thread_impl.h"
19 #include "content/public/common/content_features.h"
20 #include "content/public/common/service_names.mojom.h"
21 #include "content/renderer/render_thread_impl.h"
22 #include "gpu/command_buffer/client/context_support.h"
23 #include "gpu/command_buffer/client/gles2_interface.h"
24 #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
25 #include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
26 #include "gpu/ipc/client/command_buffer_proxy_impl.h"
27 #include "gpu/ipc/client/gpu_channel_host.h"
28 #include "gpu/ipc/common/gpu_memory_buffer_support.h"
29 #include "media/base/bind_to_current_loop.h"
30 #include "media/gpu/gpu_video_accelerator_util.h"
31 #include "media/gpu/ipc/common/media_messages.h"
32 #include "media/mojo/buildflags.h"
33 #include "media/mojo/clients/mojo_video_decoder.h"
34 #include "media/mojo/clients/mojo_video_encode_accelerator.h"
35 #include "media/video/video_encode_accelerator.h"
36 #include "services/viz/public/cpp/gpu/context_provider_command_buffer.h"
37 #include "third_party/skia/include/core/SkTypes.h"
38
39 namespace content {
40
41 namespace {
42
43 // This enum values match ContextProviderPhase in histograms.xml
44 enum ContextProviderPhase {
45 CONTEXT_PROVIDER_ACQUIRED = 0,
46 CONTEXT_PROVIDER_RELEASED = 1,
47 CONTEXT_PROVIDER_RELEASED_MAX_VALUE = CONTEXT_PROVIDER_RELEASED,
48 };
49
RecordContextProviderPhaseUmaEnum(const ContextProviderPhase phase)50 void RecordContextProviderPhaseUmaEnum(const ContextProviderPhase phase) {
51 UMA_HISTOGRAM_ENUMERATION("Media.GPU.HasEverLostContext", phase,
52 CONTEXT_PROVIDER_RELEASED_MAX_VALUE + 1);
53 }
54
55 } // namespace
56
57 GpuVideoAcceleratorFactoriesImpl::Notifier::Notifier() = default;
58 GpuVideoAcceleratorFactoriesImpl::Notifier::~Notifier() = default;
59
Register(base::OnceClosure callback)60 void GpuVideoAcceleratorFactoriesImpl::Notifier::Register(
61 base::OnceClosure callback) {
62 if (is_notified_) {
63 std::move(callback).Run();
64 return;
65 }
66 callbacks_.push_back(std::move(callback));
67 }
68
Notify()69 void GpuVideoAcceleratorFactoriesImpl::Notifier::Notify() {
70 DCHECK(!is_notified_);
71 is_notified_ = true;
72 for (auto& callback : callbacks_)
73 std::move(callback).Run();
74 callbacks_.clear();
75 }
76
77 // static
78 std::unique_ptr<GpuVideoAcceleratorFactoriesImpl>
Create(scoped_refptr<gpu::GpuChannelHost> gpu_channel_host,const scoped_refptr<base::SequencedTaskRunner> & main_thread_task_runner,const scoped_refptr<base::SequencedTaskRunner> & task_runner,const scoped_refptr<viz::ContextProviderCommandBuffer> & context_provider,bool enable_video_gpu_memory_buffers,bool enable_media_stream_gpu_memory_buffers,bool enable_video_accelerator,mojo::PendingRemote<media::mojom::InterfaceFactory> interface_factory_remote,mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> vea_provider_remote)79 GpuVideoAcceleratorFactoriesImpl::Create(
80 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host,
81 const scoped_refptr<base::SequencedTaskRunner>& main_thread_task_runner,
82 const scoped_refptr<base::SequencedTaskRunner>& task_runner,
83 const scoped_refptr<viz::ContextProviderCommandBuffer>& context_provider,
84 bool enable_video_gpu_memory_buffers,
85 bool enable_media_stream_gpu_memory_buffers,
86 bool enable_video_accelerator,
87 mojo::PendingRemote<media::mojom::InterfaceFactory>
88 interface_factory_remote,
89 mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider>
90 vea_provider_remote) {
91 RecordContextProviderPhaseUmaEnum(
92 ContextProviderPhase::CONTEXT_PROVIDER_ACQUIRED);
93 return base::WrapUnique(new GpuVideoAcceleratorFactoriesImpl(
94 std::move(gpu_channel_host), main_thread_task_runner, task_runner,
95 context_provider, enable_video_gpu_memory_buffers,
96 enable_media_stream_gpu_memory_buffers, enable_video_accelerator,
97 std::move(interface_factory_remote), std::move(vea_provider_remote)));
98 }
99
GpuVideoAcceleratorFactoriesImpl(scoped_refptr<gpu::GpuChannelHost> gpu_channel_host,const scoped_refptr<base::SequencedTaskRunner> & main_thread_task_runner,const scoped_refptr<base::SequencedTaskRunner> & task_runner,const scoped_refptr<viz::ContextProviderCommandBuffer> & context_provider,bool enable_video_gpu_memory_buffers,bool enable_media_stream_gpu_memory_buffers,bool enable_video_accelerator,mojo::PendingRemote<media::mojom::InterfaceFactory> interface_factory_remote,mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> vea_provider_remote)100 GpuVideoAcceleratorFactoriesImpl::GpuVideoAcceleratorFactoriesImpl(
101 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host,
102 const scoped_refptr<base::SequencedTaskRunner>& main_thread_task_runner,
103 const scoped_refptr<base::SequencedTaskRunner>& task_runner,
104 const scoped_refptr<viz::ContextProviderCommandBuffer>& context_provider,
105 bool enable_video_gpu_memory_buffers,
106 bool enable_media_stream_gpu_memory_buffers,
107 bool enable_video_accelerator,
108 mojo::PendingRemote<media::mojom::InterfaceFactory>
109 interface_factory_remote,
110 mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider>
111 vea_provider_remote)
112 : main_thread_task_runner_(main_thread_task_runner),
113 task_runner_(task_runner),
114 gpu_channel_host_(std::move(gpu_channel_host)),
115 context_provider_(context_provider),
116 enable_video_gpu_memory_buffers_(enable_video_gpu_memory_buffers),
117 enable_media_stream_gpu_memory_buffers_(
118 enable_media_stream_gpu_memory_buffers),
119 video_accelerator_enabled_(enable_video_accelerator),
120 gpu_memory_buffer_manager_(
121 RenderThreadImpl::current()->GetGpuMemoryBufferManager()) {
122 DCHECK(main_thread_task_runner_);
123 DCHECK(gpu_channel_host_);
124
125 task_runner_->PostTask(
126 FROM_HERE,
127 base::BindOnce(&GpuVideoAcceleratorFactoriesImpl::BindOnTaskRunner,
128 base::Unretained(this),
129 std::move(interface_factory_remote),
130 std::move(vea_provider_remote)));
131 }
132
~GpuVideoAcceleratorFactoriesImpl()133 GpuVideoAcceleratorFactoriesImpl::~GpuVideoAcceleratorFactoriesImpl() {}
134
BindOnTaskRunner(mojo::PendingRemote<media::mojom::InterfaceFactory> interface_factory_remote,mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> vea_provider_remote)135 void GpuVideoAcceleratorFactoriesImpl::BindOnTaskRunner(
136 mojo::PendingRemote<media::mojom::InterfaceFactory>
137 interface_factory_remote,
138 mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider>
139 vea_provider_remote) {
140 DCHECK(task_runner_->RunsTasksInCurrentSequence());
141 DCHECK(context_provider_);
142
143 interface_factory_.Bind(std::move(interface_factory_remote));
144 vea_provider_.Bind(std::move(vea_provider_remote));
145
146 if (context_provider_->BindToCurrentThread() !=
147 gpu::ContextResult::kSuccess) {
148 OnDecoderSupportFailed();
149 OnEncoderSupportFailed();
150 OnContextLost();
151 return;
152 }
153
154 context_provider_->AddObserver(this);
155
156 if (video_accelerator_enabled_) {
157 {
158 // TODO(crbug.com/709631): This should be removed.
159 base::AutoLock lock(supported_profiles_lock_);
160 supported_vea_profiles_ =
161 media::GpuVideoAcceleratorUtil::ConvertGpuToMediaEncodeProfiles(
162 gpu_channel_host_->gpu_info()
163 .video_encode_accelerator_supported_profiles);
164 }
165
166 vea_provider_.set_disconnect_handler(base::BindOnce(
167 &GpuVideoAcceleratorFactoriesImpl::OnEncoderSupportFailed,
168 base::Unretained(this)));
169 vea_provider_->GetVideoEncodeAcceleratorSupportedProfiles(
170 base::BindOnce(&GpuVideoAcceleratorFactoriesImpl::
171 OnGetVideoEncodeAcceleratorSupportedProfiles,
172 base::Unretained(this)));
173 } else {
174 OnEncoderSupportFailed();
175 }
176
177 #if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER)
178 // Note: This is a bit of a hack, since we don't specify the implementation
179 // before asking for the map of supported configs. We do this because it
180 // (a) saves an ipc call, and (b) makes the return of those configs atomic.
181 // Otherwise, we might have received configs for kDefault but not yet
182 // kAlternate, for example.
183 interface_factory_->CreateVideoDecoder(
184 video_decoder_.BindNewPipeAndPassReceiver());
185 video_decoder_.set_disconnect_handler(
186 base::BindOnce(&GpuVideoAcceleratorFactoriesImpl::OnDecoderSupportFailed,
187 base::Unretained(this)));
188 video_decoder_->GetSupportedConfigs(base::BindOnce(
189 &GpuVideoAcceleratorFactoriesImpl::OnSupportedDecoderConfigs,
190 base::Unretained(this)));
191 #else
192 OnDecoderSupportFailed();
193 #endif // BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER)
194 }
195
IsDecoderSupportKnown()196 bool GpuVideoAcceleratorFactoriesImpl::IsDecoderSupportKnown() {
197 base::AutoLock lock(supported_profiles_lock_);
198 return decoder_support_notifier_.is_notified();
199 }
200
NotifyDecoderSupportKnown(base::OnceClosure callback)201 void GpuVideoAcceleratorFactoriesImpl::NotifyDecoderSupportKnown(
202 base::OnceClosure callback) {
203 base::AutoLock lock(supported_profiles_lock_);
204 decoder_support_notifier_.Register(
205 media::BindToCurrentLoop(std::move(callback)));
206 }
207
OnSupportedDecoderConfigs(const media::SupportedVideoDecoderConfigMap & supported_configs)208 void GpuVideoAcceleratorFactoriesImpl::OnSupportedDecoderConfigs(
209 const media::SupportedVideoDecoderConfigMap& supported_configs) {
210 base::AutoLock lock(supported_profiles_lock_);
211 video_decoder_.reset();
212 supported_decoder_configs_ = supported_configs;
213 decoder_support_notifier_.Notify();
214 }
215
OnDecoderSupportFailed()216 void GpuVideoAcceleratorFactoriesImpl::OnDecoderSupportFailed() {
217 base::AutoLock lock(supported_profiles_lock_);
218 video_decoder_.reset();
219 if (decoder_support_notifier_.is_notified())
220 return;
221 supported_decoder_configs_ = media::SupportedVideoDecoderConfigMap();
222 decoder_support_notifier_.Notify();
223 }
224
IsEncoderSupportKnown()225 bool GpuVideoAcceleratorFactoriesImpl::IsEncoderSupportKnown() {
226 base::AutoLock lock(supported_profiles_lock_);
227 return encoder_support_notifier_.is_notified();
228 }
229
NotifyEncoderSupportKnown(base::OnceClosure callback)230 void GpuVideoAcceleratorFactoriesImpl::NotifyEncoderSupportKnown(
231 base::OnceClosure callback) {
232 base::AutoLock lock(supported_profiles_lock_);
233 encoder_support_notifier_.Register(
234 media::BindToCurrentLoop(std::move(callback)));
235 }
236
237 void GpuVideoAcceleratorFactoriesImpl::
OnGetVideoEncodeAcceleratorSupportedProfiles(const media::VideoEncodeAccelerator::SupportedProfiles & supported_profiles)238 OnGetVideoEncodeAcceleratorSupportedProfiles(
239 const media::VideoEncodeAccelerator::SupportedProfiles&
240 supported_profiles) {
241 base::AutoLock lock(supported_profiles_lock_);
242 supported_vea_profiles_ = supported_profiles;
243 encoder_support_notifier_.Notify();
244 }
245
OnEncoderSupportFailed()246 void GpuVideoAcceleratorFactoriesImpl::OnEncoderSupportFailed() {
247 base::AutoLock lock(supported_profiles_lock_);
248 if (encoder_support_notifier_.is_notified())
249 return;
250 supported_vea_profiles_ = media::VideoEncodeAccelerator::SupportedProfiles();
251 encoder_support_notifier_.Notify();
252 }
253
CheckContextLost()254 bool GpuVideoAcceleratorFactoriesImpl::CheckContextLost() {
255 DCHECK(task_runner_->RunsTasksInCurrentSequence());
256 if (context_provider_lost_on_media_thread_)
257 return true;
258 if (context_provider_->ContextGL()->GetGraphicsResetStatusKHR() !=
259 GL_NO_ERROR) {
260 OnContextLost();
261 return true;
262 }
263 return false;
264 }
265
DestroyContext()266 void GpuVideoAcceleratorFactoriesImpl::DestroyContext() {
267 DCHECK(task_runner_->RunsTasksInCurrentSequence());
268 DCHECK(context_provider_lost_on_media_thread_);
269
270 if (!context_provider_)
271 return;
272
273 context_provider_->RemoveObserver(this);
274 context_provider_ = nullptr;
275 RecordContextProviderPhaseUmaEnum(
276 ContextProviderPhase::CONTEXT_PROVIDER_RELEASED);
277 }
278
IsGpuVideoAcceleratorEnabled()279 bool GpuVideoAcceleratorFactoriesImpl::IsGpuVideoAcceleratorEnabled() {
280 return video_accelerator_enabled_;
281 }
282
GetChannelToken()283 base::UnguessableToken GpuVideoAcceleratorFactoriesImpl::GetChannelToken() {
284 DCHECK(task_runner_->RunsTasksInCurrentSequence());
285 if (CheckContextLost())
286 return base::UnguessableToken();
287
288 if (channel_token_.is_empty()) {
289 context_provider_->GetCommandBufferProxy()->channel()->Send(
290 new GpuCommandBufferMsg_GetChannelToken(&channel_token_));
291 }
292
293 return channel_token_;
294 }
295
GetCommandBufferRouteId()296 int32_t GpuVideoAcceleratorFactoriesImpl::GetCommandBufferRouteId() {
297 DCHECK(task_runner_->RunsTasksInCurrentSequence());
298 if (CheckContextLost())
299 return 0;
300 return context_provider_->GetCommandBufferProxy()->route_id();
301 }
302
303 media::GpuVideoAcceleratorFactories::Supported
IsDecoderConfigSupported(media::VideoDecoderImplementation implementation,const media::VideoDecoderConfig & config)304 GpuVideoAcceleratorFactoriesImpl::IsDecoderConfigSupported(
305 media::VideoDecoderImplementation implementation,
306 const media::VideoDecoderConfig& config) {
307 // There is no support for alpha channel hardware decoding yet.
308 if (config.alpha_mode() == media::VideoDecoderConfig::AlphaMode::kHasAlpha) {
309 DVLOG(1) << "Alpha transparency formats are not supported.";
310 return Supported::kFalse;
311 }
312
313 base::AutoLock lock(supported_profiles_lock_);
314
315 // If GetSupportedConfigs() has not completed (or was never started), report
316 // that all configs are supported. Clients will find out that configs are not
317 // supported when VideoDecoder::Initialize() fails.
318 if (!supported_decoder_configs_)
319 return Supported::kUnknown;
320
321 auto iter = supported_decoder_configs_->find(implementation);
322 // If the decoder implementation wasn't listed, then fail. This means that
323 // there is no such decoder implementation.
324 if (iter == supported_decoder_configs_->end())
325 return Supported::kFalse;
326
327 // Iterate over the supported configs for |impl|.
328 for (const auto& supported : iter->second) {
329 if (supported.Matches(config))
330 return Supported::kTrue;
331 }
332 return Supported::kFalse;
333 }
334
335 std::unique_ptr<media::VideoDecoder>
CreateVideoDecoder(media::MediaLog * media_log,media::VideoDecoderImplementation implementation,media::RequestOverlayInfoCB request_overlay_info_cb)336 GpuVideoAcceleratorFactoriesImpl::CreateVideoDecoder(
337 media::MediaLog* media_log,
338 media::VideoDecoderImplementation implementation,
339 media::RequestOverlayInfoCB request_overlay_info_cb) {
340 DCHECK(video_accelerator_enabled_);
341 DCHECK(task_runner_->RunsTasksInCurrentSequence());
342 DCHECK(interface_factory_.is_bound());
343
344 #if BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER)
345 if (CheckContextLost())
346 return nullptr;
347
348 mojo::PendingRemote<media::mojom::VideoDecoder> video_decoder;
349 interface_factory_->CreateVideoDecoder(
350 video_decoder.InitWithNewPipeAndPassReceiver());
351 return std::make_unique<media::MojoVideoDecoder>(
352 task_runner_, this, media_log, std::move(video_decoder), implementation,
353 std::move(request_overlay_info_cb), rendering_color_space_);
354 #else
355 return nullptr;
356 #endif // BUILDFLAG(ENABLE_MOJO_VIDEO_DECODER)
357 }
358
359 std::unique_ptr<media::VideoEncodeAccelerator>
CreateVideoEncodeAccelerator()360 GpuVideoAcceleratorFactoriesImpl::CreateVideoEncodeAccelerator() {
361 DCHECK(video_accelerator_enabled_);
362 DCHECK(task_runner_->RunsTasksInCurrentSequence());
363 DCHECK(vea_provider_.is_bound());
364 if (CheckContextLost())
365 return nullptr;
366
367 base::AutoLock lock(supported_profiles_lock_);
368 // When |supported_vea_profiles_| is empty, no hw encoder is available or
369 // we have not yet gotten the supported profiles.
370 if (!supported_vea_profiles_) {
371 DVLOG(2) << "VEA's profiles have not yet been gotten";
372 } else if (supported_vea_profiles_->empty()) {
373 // There is no profile supported by VEA.
374 return nullptr;
375 }
376
377 mojo::PendingRemote<media::mojom::VideoEncodeAccelerator> vea;
378 vea_provider_->CreateVideoEncodeAccelerator(
379 vea.InitWithNewPipeAndPassReceiver());
380
381 if (!vea)
382 return nullptr;
383
384 return std::unique_ptr<media::VideoEncodeAccelerator>(
385 new media::MojoVideoEncodeAccelerator(
386 std::move(vea),
387 supported_vea_profiles_.value_or(
388 media::VideoEncodeAccelerator::SupportedProfiles())));
389 }
390
391 std::unique_ptr<gfx::GpuMemoryBuffer>
CreateGpuMemoryBuffer(const gfx::Size & size,gfx::BufferFormat format,gfx::BufferUsage usage)392 GpuVideoAcceleratorFactoriesImpl::CreateGpuMemoryBuffer(
393 const gfx::Size& size,
394 gfx::BufferFormat format,
395 gfx::BufferUsage usage) {
396 return gpu_memory_buffer_manager_->CreateGpuMemoryBuffer(
397 size, format, usage, gpu::kNullSurfaceHandle);
398 }
ShouldUseGpuMemoryBuffersForVideoFrames(bool for_media_stream) const399 bool GpuVideoAcceleratorFactoriesImpl::ShouldUseGpuMemoryBuffersForVideoFrames(
400 bool for_media_stream) const {
401 return for_media_stream ? enable_media_stream_gpu_memory_buffers_
402 : enable_video_gpu_memory_buffers_;
403 }
404
ImageTextureTarget(gfx::BufferFormat format)405 unsigned GpuVideoAcceleratorFactoriesImpl::ImageTextureTarget(
406 gfx::BufferFormat format) {
407 DCHECK(context_provider_);
408 return gpu::GetBufferTextureTarget(gfx::BufferUsage::SCANOUT_CPU_READ_WRITE,
409 format,
410 context_provider_->ContextCapabilities());
411 }
412
413 media::GpuVideoAcceleratorFactories::OutputFormat
VideoFrameOutputFormat(media::VideoPixelFormat pixel_format)414 GpuVideoAcceleratorFactoriesImpl::VideoFrameOutputFormat(
415 media::VideoPixelFormat pixel_format) {
416 DCHECK(task_runner_->RunsTasksInCurrentSequence());
417 if (CheckContextLost())
418 return media::GpuVideoAcceleratorFactories::OutputFormat::UNDEFINED;
419 #if defined(OS_CHROMEOS) && defined(USE_OZONE)
420 // TODO(sugoi): This configuration is currently used only for testing ChromeOS
421 // on Linux and doesn't support hardware acceleration. OSMesa did not support
422 // any hardware acceleration here, so this was never an issue, but SwiftShader
423 // revealed this issue. See https://crbug.com/859946
424 if (gpu_channel_host_->gpu_info().gl_renderer.find("SwiftShader") !=
425 std::string::npos) {
426 return media::GpuVideoAcceleratorFactories::OutputFormat::UNDEFINED;
427 }
428 #endif
429 auto capabilities = context_provider_->ContextCapabilities();
430 const size_t bit_depth = media::BitDepth(pixel_format);
431 if (bit_depth > 8) {
432 #if !defined(OS_MAC)
433 // TODO(crbug.com/1101041): Enable P010 support for macOS.
434 if (capabilities.image_ycbcr_p010 && bit_depth == 10)
435 return media::GpuVideoAcceleratorFactories::OutputFormat::P010;
436
437 // If high bit depth rendering is enabled, bail here, otherwise try and use
438 // XR30 storage, and if not and we support RG textures, use those, albeit at
439 // a reduced bit depth of 8 bits per component.
440 // TODO(mcasas): continue working on this, avoiding dropping information as
441 // long as the hardware may support it https://crbug.com/798485.
442 if (rendering_color_space_.IsHDR())
443 return media::GpuVideoAcceleratorFactories::OutputFormat::UNDEFINED;
444 #endif
445
446 #if !defined(OS_WIN)
447 // TODO(mcasas): enable Win https://crbug.com/803451.
448 // TODO(mcasas): remove the |bit_depth| check when libyuv supports more than
449 // just x010ToAR30 conversions, https://crbug.com/libyuv/751.
450 if (bit_depth == 10) {
451 if (capabilities.image_ar30)
452 return media::GpuVideoAcceleratorFactories::OutputFormat::XR30;
453 else if (capabilities.image_ab30)
454 return media::GpuVideoAcceleratorFactories::OutputFormat::XB30;
455 }
456 #endif
457 if (capabilities.texture_rg)
458 return media::GpuVideoAcceleratorFactories::OutputFormat::I420;
459 return media::GpuVideoAcceleratorFactories::OutputFormat::UNDEFINED;
460 }
461
462 if (pixel_format == media::PIXEL_FORMAT_I420A) {
463 #if SK_PMCOLOR_BYTE_ORDER(B, G, R, A)
464 return media::GpuVideoAcceleratorFactories::OutputFormat::BGRA;
465 #elif SK_PMCOLOR_BYTE_ORDER(R, G, B, A)
466 return media::GpuVideoAcceleratorFactories::OutputFormat::RGBA;
467 #endif
468 }
469
470 if (capabilities.image_ycbcr_420v &&
471 !capabilities.image_ycbcr_420v_disabled_for_video_frames) {
472 return media::GpuVideoAcceleratorFactories::OutputFormat::NV12_SINGLE_GMB;
473 }
474 if (capabilities.texture_rg)
475 return media::GpuVideoAcceleratorFactories::OutputFormat::NV12_DUAL_GMB;
476 return media::GpuVideoAcceleratorFactories::OutputFormat::UNDEFINED;
477 }
478
479 gpu::SharedImageInterface*
SharedImageInterface()480 GpuVideoAcceleratorFactoriesImpl::SharedImageInterface() {
481 return CheckContextLost() ? nullptr
482 : context_provider_->SharedImageInterface();
483 }
484
485 gpu::GpuMemoryBufferManager*
GpuMemoryBufferManager()486 GpuVideoAcceleratorFactoriesImpl::GpuMemoryBufferManager() {
487 return gpu_memory_buffer_manager_;
488 }
489
490 base::UnsafeSharedMemoryRegion
CreateSharedMemoryRegion(size_t size)491 GpuVideoAcceleratorFactoriesImpl::CreateSharedMemoryRegion(size_t size) {
492 // If necessary, this call will make a synchronous request to a privileged
493 // process to create the shared region.
494 return base::UnsafeSharedMemoryRegion::Create(size);
495 }
496
497 scoped_refptr<base::SequencedTaskRunner>
GetTaskRunner()498 GpuVideoAcceleratorFactoriesImpl::GetTaskRunner() {
499 return task_runner_;
500 }
501
502 base::Optional<media::VideoEncodeAccelerator::SupportedProfiles>
GetVideoEncodeAcceleratorSupportedProfiles()503 GpuVideoAcceleratorFactoriesImpl::GetVideoEncodeAcceleratorSupportedProfiles() {
504 base::AutoLock lock(supported_profiles_lock_);
505 return supported_vea_profiles_;
506 }
507
508 viz::RasterContextProvider*
GetMediaContextProvider()509 GpuVideoAcceleratorFactoriesImpl::GetMediaContextProvider() {
510 return CheckContextLost() ? nullptr : context_provider_.get();
511 }
512
SetRenderingColorSpace(const gfx::ColorSpace & color_space)513 void GpuVideoAcceleratorFactoriesImpl::SetRenderingColorSpace(
514 const gfx::ColorSpace& color_space) {
515 rendering_color_space_ = color_space;
516 }
517
CheckContextProviderLostOnMainThread()518 bool GpuVideoAcceleratorFactoriesImpl::CheckContextProviderLostOnMainThread() {
519 DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
520 return context_provider_lost_;
521 }
522
OnContextLost()523 void GpuVideoAcceleratorFactoriesImpl::OnContextLost() {
524 DCHECK(task_runner_->RunsTasksInCurrentSequence());
525 TRACE_EVENT0("media", "GpuVideoAcceleratorFactoriesImpl::OnContextLost");
526
527 // Don't delete the |context_provider_| here, we could be in the middle of
528 // it notifying about the loss, and we'd be destroying it while it's on
529 // the stack.
530 context_provider_lost_on_media_thread_ = true;
531 // Inform the main thread of the loss as well, so that this class can be
532 // replaced.
533 main_thread_task_runner_->PostTask(
534 FROM_HERE,
535 base::BindOnce(
536 &GpuVideoAcceleratorFactoriesImpl::SetContextProviderLostOnMainThread,
537 base::Unretained(this)));
538 }
539
SetContextProviderLostOnMainThread()540 void GpuVideoAcceleratorFactoriesImpl::SetContextProviderLostOnMainThread() {
541 DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence());
542 context_provider_lost_ = true;
543 }
544
545 } // namespace content
546