1 // Copyright 2021 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.
5 #include "media/mojo/services/gpu_mojo_media_client.h"
7 #include "base/metrics/histogram_functions.h"
8 #include "base/task/sequenced_task_runner.h"
9 #include "chromeos/components/cdm_factory_daemon/chromeos_cdm_factory.h"
10 #include "media/base/audio_decoder.h"
11 #include "media/base/audio_encoder.h"
12 #include "media/base/media_switches.h"
13 #include "media/gpu/chromeos/mailbox_video_frame_converter.h"
14 #include "media/gpu/chromeos/platform_video_frame_pool.h"
15 #include "media/gpu/chromeos/video_decoder_pipeline.h"
16 #include "media/gpu/ipc/service/vda_video_decoder.h"
22 std::vector<Fourcc> GetPreferredRenderableFourccs(
23 const gpu::GpuPreferences& gpu_preferences) {
24 return VideoDecoderPipeline::DefaultPreferredRenderableFourccs();
27 VideoDecoderType GetActualPlatformDecoderImplementation(
28 const gpu::GpuPreferences& gpu_preferences) {
29 // TODO(b/195769334): eventually, we may turn off USE_VAAPI and USE_V4L2_CODEC
30 // on LaCrOS if we delegate all video acceleration to ash-chrome. In those
31 // cases, GetActualPlatformDecoderImplementation() won't be able to determine
32 // the video API in LaCrOS.
33 if (gpu_preferences.disable_accelerated_video_decode) {
34 return VideoDecoderType::kUnknown;
37 if (IsOutOfProcessVideoDecodingEnabled()) {
38 return VideoDecoderType::kOutOfProcess;
41 if (gpu_preferences.enable_chromeos_direct_video_decoder) {
42 #if BUILDFLAG(USE_VAAPI)
43 return VideoDecoderType::kVaapi;
44 #elif BUILDFLAG(USE_V4L2_CODEC)
45 return VideoDecoderType::kV4L2;
48 return VideoDecoderType::kVda;
53 std::unique_ptr<VideoDecoder> CreatePlatformVideoDecoder(
54 VideoDecoderTraits& traits) {
55 const auto decoder_type =
56 GetActualPlatformDecoderImplementation(traits.gpu_preferences);
57 // The browser process guarantees this CHECK.
58 CHECK_EQ(!!traits.oop_video_decoder,
59 (decoder_type == VideoDecoderType::kOutOfProcess));
61 switch (decoder_type) {
62 case VideoDecoderType::kOutOfProcess: {
63 // TODO(b/195769334): for out-of-process video decoding, we don't need a
64 // |frame_pool| because the buffers will be allocated and managed
66 auto frame_pool = std::make_unique<PlatformVideoFramePool>();
68 auto frame_converter = MailboxVideoFrameConverter::Create(
69 traits.gpu_task_runner, traits.get_command_buffer_stub_cb);
70 return VideoDecoderPipeline::Create(
71 *traits.gpu_workarounds, traits.task_runner, std::move(frame_pool),
72 std::move(frame_converter),
73 GetPreferredRenderableFourccs(traits.gpu_preferences),
74 traits.media_log->Clone(), std::move(traits.oop_video_decoder));
76 case VideoDecoderType::kVaapi:
77 case VideoDecoderType::kV4L2: {
78 auto frame_pool = std::make_unique<PlatformVideoFramePool>();
79 auto frame_converter = MailboxVideoFrameConverter::Create(
80 traits.gpu_task_runner, traits.get_command_buffer_stub_cb);
81 return VideoDecoderPipeline::Create(
82 *traits.gpu_workarounds, traits.task_runner, std::move(frame_pool),
83 std::move(frame_converter),
84 GetPreferredRenderableFourccs(traits.gpu_preferences),
85 traits.media_log->Clone(), /*oop_video_decoder=*/{});
87 case VideoDecoderType::kVda: {
88 return VdaVideoDecoder::Create(
89 traits.task_runner, traits.gpu_task_runner, traits.media_log->Clone(),
90 *traits.target_color_space, traits.gpu_preferences,
91 *traits.gpu_workarounds, traits.get_command_buffer_stub_cb,
92 VideoDecodeAccelerator::Config::OutputMode::kAllocate);
100 void NotifyPlatformDecoderSupport(
101 const gpu::GpuPreferences& gpu_preferences,
102 const gpu::GPUInfo& gpu_info,
103 mojo::PendingRemote<stable::mojom::StableVideoDecoder> oop_video_decoder,
105 void(mojo::PendingRemote<stable::mojom::StableVideoDecoder>)> cb) {
106 switch (GetActualPlatformDecoderImplementation(gpu_preferences)) {
107 case VideoDecoderType::kOutOfProcess:
108 case VideoDecoderType::kVaapi:
109 case VideoDecoderType::kV4L2:
110 VideoDecoderPipeline::NotifySupportKnown(std::move(oop_video_decoder),
114 std::move(cb).Run(std::move(oop_video_decoder));
118 absl::optional<SupportedVideoDecoderConfigs>
119 GetPlatformSupportedVideoDecoderConfigs(
120 base::WeakPtr<MediaGpuChannelManager> manager,
121 gpu::GpuDriverBugWorkarounds gpu_workarounds,
122 gpu::GpuPreferences gpu_preferences,
123 const gpu::GPUInfo& gpu_info,
124 base::OnceCallback<SupportedVideoDecoderConfigs()> get_vda_configs) {
125 VideoDecoderType decoder_implementation =
126 GetActualPlatformDecoderImplementation(gpu_preferences);
127 switch (decoder_implementation) {
128 case VideoDecoderType::kVda:
129 return std::move(get_vda_configs).Run();
130 case VideoDecoderType::kOutOfProcess:
131 case VideoDecoderType::kVaapi:
132 case VideoDecoderType::kV4L2:
133 return VideoDecoderPipeline::GetSupportedConfigs(decoder_implementation,
136 return absl::nullopt;
140 VideoDecoderType GetPlatformDecoderImplementationType(
141 gpu::GpuDriverBugWorkarounds gpu_workarounds,
142 gpu::GpuPreferences gpu_preferences,
143 const gpu::GPUInfo& gpu_info) {
144 // Determine the preferred decoder based purely on compile-time and run-time
145 // flags. This is not intended to determine whether the selected decoder can
146 // be successfully initialized or used to decode.
147 return GetActualPlatformDecoderImplementation(gpu_preferences);
150 std::unique_ptr<AudioDecoder> CreatePlatformAudioDecoder(
151 scoped_refptr<base::SequencedTaskRunner> task_runner,
152 std::unique_ptr<MediaLog> media_log) {
156 std::unique_ptr<AudioEncoder> CreatePlatformAudioEncoder(
157 scoped_refptr<base::SequencedTaskRunner> task_runner) {
161 std::unique_ptr<CdmFactory> CreatePlatformCdmFactory(
162 mojom::FrameInterfaceFactory* frame_interfaces) {
163 return std::make_unique<chromeos::ChromeOsCdmFactory>(frame_interfaces);