1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
media / mojo / clients / mojo_codec_factory.h [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_MOJO_CLIENTS_MOJO_CODEC_FACTORY_H_
#define MEDIA_MOJO_CLIENTS_MOJO_CODEC_FACTORY_H_
#include <memory>
#include "base/functional/callback_forward.h"
#include "base/task/sequenced_task_runner.h"
#include "media/base/decoder.h"
#include "media/base/media_log.h"
#include "media/base/overlay_info.h"
#include "media/base/supported_video_decoder_config.h"
#include "media/base/video_decoder.h"
#include "media/mojo/mojom/video_encode_accelerator.mojom.h"
#include "media/video/gpu_video_accelerator_factories.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/viz/public/cpp/gpu/context_provider_command_buffer.h"
namespace media {
// Assists the MojoGpuVideoAcceleratorFactories class with hardware decoder and
// encoder functionalities.
//
// It is a base class that handles the encoder resources
// via media::mojom::VideoEncodeAcceleratorProvider. Its derived classes
// implement how to connect to hardware decoder resources.
class MojoCodecFactory {
public:
// `media_task_runner` - task runner for running multi-media operations.
// `context_provider` - context provider for creating a video decoder.
// `video_decode_accelerator_enabled` - whether the video decode accelerator
// is enabled.
// `video_encode_accelerator_enabled` - whether the video encode accelerator
// is enabled.
// `pending_vea_provider_remote` - bound pending
// media::mojom::VideoEncodeAcceleratorProvider remote.
MojoCodecFactory(
scoped_refptr<base::SequencedTaskRunner> media_task_runner,
scoped_refptr<viz::ContextProviderCommandBuffer> context_provider,
bool video_decode_accelerator_enabled,
bool video_encode_accelerator_enabled,
mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider>
pending_vea_provider_remote);
MojoCodecFactory(const MojoCodecFactory&) = delete;
MojoCodecFactory& operator=(const MojoCodecFactory&) = delete;
virtual ~MojoCodecFactory();
// `gpu_factories` - pointer to the GpuVideoAcceleratorFactories that
// owns |this|.
// `media_log` - process-wide pointer to log to chrome://media-internals log.
// `request_overlay_info_cb` - callback that gets the overlay information.
// `rendering_color_space` - color space for the purpose of color conversion.
//
// Derived class should construct its own type of video decoder.
virtual std::unique_ptr<media::VideoDecoder> CreateVideoDecoder(
media::GpuVideoAcceleratorFactories* gpu_factories,
media::MediaLog* media_log,
media::RequestOverlayInfoCB request_overlay_info_cb,
const gfx::ColorSpace& rendering_color_space) = 0;
std::unique_ptr<media::VideoEncodeAccelerator> CreateVideoEncodeAccelerator();
// Returns VideoDecoderType::kUnknown in cases where IsDecoderSupportKnown()
// is false.
// Otherwise, it returns the type of decoder that provided the
// configs for the config support check.
media::VideoDecoderType GetVideoDecoderType();
// Returns a nullopt if we have not yet gotten the configs.
// Returns an optional that contains an empty vector if we have gotten the
// result and there are no supported configs.
std::optional<media::SupportedVideoDecoderConfigs>
GetSupportedVideoDecoderConfigs();
// Returns a nullopt if we have not yet gotten the profiles.
// Returns an optional that contains an empty vector if we have gotten the
// result and there are no supported profiles.
std::optional<media::VideoEncodeAccelerator::SupportedProfiles>
GetVideoEncodeAcceleratorSupportedProfiles();
// Returns true if media::SupportedVideoDecoderConfigs are populated.
bool IsDecoderSupportKnown();
// Returns true if media::VideoEncodeAccelerator::SupportedProfiles are
// populated.
bool IsEncoderSupportKnown();
// If the current decoder support is not yet known, use this to register a
// callback that is notified once the support is known. At that point, calling
// GetSupportedVideoDecoderConfigs will give the set of supported decoder
// configs.
//
// There is no way to unsubscribe a callback, it is recommended to use a
// WeakPtr if you need this feature.
void NotifyDecoderSupportKnown(base::OnceClosure callback);
// If the current encoder support is not yet known, use this to register a
// callback that is notified once the support is known. At that point, calling
// GetVideoEncodeAcceleratorSupportedProfiles will give the set of supported
// encoder profiles.
//
// There is no way to unsubscribe a callback, it is recommended to use a
// WeakPtr if you need this feature.
void NotifyEncoderSupportKnown(base::OnceClosure callback);
// Provides this instance with the gpu channel token for the
// associated gpu channel.
void OnChannelTokenReady(const base::UnguessableToken& token,
int32_t route_id);
protected:
class Notifier {
public:
Notifier();
~Notifier();
void Register(base::OnceClosure callback);
void Notify();
bool is_notified() { return is_notified_; }
private:
bool is_notified_ = false;
std::vector<base::OnceClosure> callbacks_;
};
void OnDecoderSupportFailed();
void OnGetSupportedDecoderConfigs();
void OnEncoderSupportFailed();
void OnGetVideoEncodeAcceleratorSupportedProfiles(
const media::VideoEncodeAccelerator::SupportedProfiles&
supported_profiles);
bool IsEncoderReady() EXCLUSIVE_LOCKS_REQUIRED(supported_profiles_lock_);
// Task runner on the Media thread for running multi-media operations
// (e.g., creating a video decoder).
// In Fuchsia, it needs to be started with the IO message pump for FIDL calls.
scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
// Shared pointer to a shared context provider. All access should happen only
// on the media thread.
const scoped_refptr<viz::ContextProviderCommandBuffer> context_provider_;
// Whether video acceleration encoding/decoding should be enabled.
const bool video_decode_accelerator_enabled_;
const bool video_encode_accelerator_enabled_;
base::Lock supported_profiles_lock_;
// If the Optional is empty, then we have not yet gotten the configs.
// If the Optional contains an empty vector, then we have gotten the result
// and there are no supported configs.
std::optional<media::SupportedVideoDecoderConfigs> supported_decoder_configs_
GUARDED_BY(supported_profiles_lock_);
std::optional<media::VideoEncodeAccelerator::SupportedProfiles>
supported_vea_profiles_ GUARDED_BY(supported_profiles_lock_);
media::VideoDecoderType video_decoder_type_
GUARDED_BY(supported_profiles_lock_) = media::VideoDecoderType::kUnknown;
Notifier decoder_support_notifier_ GUARDED_BY(supported_profiles_lock_);
Notifier encoder_support_notifier_ GUARDED_BY(supported_profiles_lock_);
private:
void BindOnTaskRunner(
mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider>
pending_vea_provider_remote);
mojo::Remote<media::mojom::VideoEncodeAcceleratorProvider> vea_provider_;
base::UnguessableToken channel_token_;
int32_t route_id_;
};
// MojoCodecFactoryDefault is the default derived class, which has no
// decoder provider. It does not have any supported video decoder configs and
// returns a null pointer when creating a hardware video decoder.
class MojoCodecFactoryDefault final : public MojoCodecFactory {
public:
MojoCodecFactoryDefault(
scoped_refptr<base::SequencedTaskRunner> task_runner,
scoped_refptr<viz::ContextProviderCommandBuffer> context_provider,
bool video_decode_accelerator_enabled,
bool video_encode_accelerator_enabled,
mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider>
pending_vea_provider_remote);
~MojoCodecFactoryDefault() override;
// Returns nullptr since there is no decoder provider.
std::unique_ptr<media::VideoDecoder> CreateVideoDecoder(
media::GpuVideoAcceleratorFactories* gpu_factories,
media::MediaLog* media_log,
media::RequestOverlayInfoCB request_overlay_info_cb,
const gfx::ColorSpace& rendering_color_space) override;
};
} // namespace media
#endif // MEDIA_MOJO_CLIENTS_MOJO_CODEC_FACTORY_H_