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
media / mojo / mojom / video_decoder.mojom [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module media.mojom;
import "gpu/ipc/common/sync_token.mojom";
import "media/mojo/mojom/media_log.mojom";
import "media/mojo/mojom/media_types.mojom";
import "mojo/public/mojom/base/unguessable_token.mojom";
import "ui/gfx/geometry/mojom/geometry.mojom";
import "ui/gfx/mojom/color_space.mojom";
// Serializable rule for matching VideoDecoderConfigs.
struct SupportedVideoDecoderConfig {
// Range of VideoCodecProfiles to match, inclusive.
VideoCodecProfile profile_min;
VideoCodecProfile profile_max;
// Range of coded sizes to match, inclusive in each dimension.
gfx.mojom.Size coded_size_min;
gfx.mojom.Size coded_size_max;
// Match configs that have encryption configured.
bool allow_encrypted;
// Do not match configs that do not have encryption configured. This is used
// on Android when the internal software decoder is preferred over the
// platform decoder (eg. when the platform decoder is a software decoder).
bool require_encrypted;
};
// Identifies a CommandBufferStub. MediaGpuChannelManager is responsible
// for minting |channel_token| values.
struct CommandBufferId {
mojo_base.mojom.UnguessableToken channel_token;
int32 route_id;
};
[Native]
struct OverlayInfo;
// Interface for releasing remote VideoFrames. It is separated from VideoDecoder
// so that VideoFrames can outlive their VideoDecoder.
interface VideoFrameHandleReleaser {
// Signals that the VideoFrame identified by |release_token| should be
// released. |release_sync_token| indicates the last use of the VideoFrame
// (in a GPU command buffer) by the client. If the VideoDecoder outputs frames
// that have a callback for releasing mailboxes (i.e.,
// VideoFrame::HasReleaseMailboxCB() returns true), the |release_sync_token|
// is required but may be empty, and in that case, implementations should let
// the about-to-be-released VideoFrame retain whatever SyncToken it has. For
// other frames, it's assumed that the frame can be released immediately upon
// calling ReleaseVideoFrame() and |release_sync_token| does not need to be
// supplied (and should be ignored by implementations if supplied).
ReleaseVideoFrame(mojo_base.mojom.UnguessableToken release_token,
gpu.mojom.SyncToken? release_sync_token);
};
// A Mojo equivalent of media::VideoDecoder. In practice, this is used for
// hardware decode offloading; in this case the client is a <video> tag running
// in a renderer, and the implementation is running in the GPU process.
interface VideoDecoder {
// Returns a list of supported configs as well as the decoder ID for the decoder
// which supports them. It is expected that Initialize() will fail for any config
// that does not match an entry in this list.
//
// May be called before Construct().
[Sync]
GetSupportedConfigs() =>
(array<SupportedVideoDecoderConfig> supported_configs,
VideoDecoderType decoder_type);
// Initialize the decoder. This must be called before any method other than
// GetSupportedConfigs().
//
// |client| provides asynchronous client methods to the VideoDecoder, such
// as delivery of decoded VideoFrame outputs.
//
// When a VideoFrame is delivered to |client|, the VideoDecoder may continue
// to retain a reference to the VideoFrame. In this case a |release_token| is
// included. The client shall use |video_frame_handle_releaser| to signal
// that the retained VideoFrame should be released (even after the
// VideoDecoder is torn down). This enables ordinary VideoFrames in the client
// process to depend on resources held by the service, without significantly
// complicating VideoFrame serialization.
//
// |decoder_buffer_pipe| is used to transfer the encoded data for each
// DecoderBuffer.
//
// |command_buffer_id|, when present, identifies a CommandBufferStub that
// the VideoDecoder can use for GL operations. Implementations that require GL
// will fail Initialize() if |command_buffer_id| is not provided.
//
// |implementation| selects the underlying VideoDecoder implementation. Not
// all implementations are supported. Initialize() will fail if
// |implementation| is not supported.
//
// TODO(sandersd): Rename to Initialize() if/when
// media::VideoDecoder::Initialize() is renamed to Configure().
Construct(
pending_associated_remote<VideoDecoderClient> client,
pending_remote<MediaLog> media_log,
pending_receiver<VideoFrameHandleReleaser> video_frame_handle_releaser,
handle<data_pipe_consumer> decoder_buffer_pipe,
CommandBufferId? command_buffer_id,
gfx.mojom.ColorSpace target_color_space);
// Configure (or reconfigure) the decoder. This must be called before decoding
// any frames, and must not be called while there are pending Initialize(),
// Decode(), or Reset() requests.
//
// If |low_delay| is true, the decoder must output frames as soon as possible;
// in particular, it must not wait for another Decode() request, except as
// required for frame reordering. Implementations must fail initialization if
// they cannot satisfy this requirement.
//
// On completion, the callback also includes |needs_bitstream_conversion|,
// indicating whether decode buffers need bitstream conversion, and
// |max_decode_requests|, the maximum number of concurrent Decode() requests
// the implementation supports.
//
// |cdm_id| must refer to a valid CDM if |config.is_encrypted()|. It is not
// used for unencrypted streams.
Initialize(VideoDecoderConfig config, bool low_delay,
mojo_base.mojom.UnguessableToken? cdm_id)
=> (DecoderStatus status,
bool needs_bitstream_conversion,
int32 max_decode_requests,
VideoDecoderType decoder_type);
// Request decoding of exactly one frame or an EOS buffer. This must not be
// called while there are pending Initialize(), Reset(), or Decode(EOS)
// requests.
//
// Implementations must eventually execute the callback, even if Decode() is
// not called again. It is not required that the decode status match the
// actual result of decoding the buffer, only that decode errors are
// eventually reported (such as at EOS).
//
// If |buffer| is an EOS buffer, implementations must execute all other
// pending Decode() callbacks and output all pending frames before executing
// the Decode(EOS) callback. (That is, they must flush.)
Decode(DecoderBuffer buffer) => (DecoderStatus status);
// Reset the decoder. All ongoing Decode() requests must be completed or
// aborted before executing the callback. This must not be called while there
// is a pending Initialize() request.
Reset() => ();
// Inform the decoder that new OverlayInfo is available.
OnOverlayInfoChanged(OverlayInfo overlay_info);
};
interface VideoDecoderClient {
// Output a decoded frame. Frames are output in presentation order.
//
// When |can_read_without_stalling| is false, preroll should be disabled. This
// is necessary if the decoder cannot guarantee that it can output another
// frame, for example if output buffers are limited or configuration changes
// require the return of all outstanding frames.
//
// If |release_token| is provided, the client shall call
// VideoFrameHandleReleaser::Release() when it is finished using |frame|.
OnVideoFrameDecoded(VideoFrame frame,
bool can_read_without_stalling,
mojo_base.mojom.UnguessableToken? release_token);
// Called when the remote decoder is waiting because of |reason|, e.g. waiting
// for decryption key.
OnWaiting(WaitingReason reason);
// Request to be notified when the current OverlayInfo changes. This results
// in at least one call to OnOverlayInfoChanged() for the initial OverlayInfo.
// |restart_for_transitions| sets whether the decoder should be restarted on
// overlay transitions instead of receiving a call to OnOverlayInfoChanged().
RequestOverlayInfo(bool restart_for_transitions);
};