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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
media / base / android / media_codec_bridge.h [blame]
// Copyright 2013 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_BASE_ANDROID_MEDIA_CODEC_BRIDGE_H_
#define MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_H_
#include <stddef.h>
#include <stdint.h>
#include <optional>
#include <string>
#include <vector>
#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
#include "base/containers/span.h"
#include "base/time/time.h"
#include "media/base/decrypt_config.h"
#include "media/base/encryption_pattern.h"
#include "media/base/encryption_scheme.h"
#include "media/base/media_export.h"
#include "media/base/status.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/size.h"
namespace media {
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.media
enum class CodecType {
kAny,
kSecure, // Note that all secure codecs are HW codecs.
kSoftware, // In some cases hardware codecs could hang the GPU process.
};
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.media
// GENERATED_JAVA_PREFIX_TO_STRIP: MEDIA_CODEC_
// These enums are also reported to UMA so values should not be renumbered or
// reused.
enum MediaCodecStatus {
MEDIA_CODEC_OK = 0,
MEDIA_CODEC_TRY_AGAIN_LATER = 1,
MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED = 2,
MEDIA_CODEC_OUTPUT_FORMAT_CHANGED = 3,
MEDIA_CODEC_NO_KEY = 4,
MEDIA_CODEC_ERROR = 5,
MEDIA_CODEC_KEY_EXPIRED = 6,
MEDIA_CODEC_RESOURCE_BUSY = 7,
MEDIA_CODEC_INSUFFICIENT_OUTPUT_PROTECTION = 8,
MEDIA_CODEC_SESSION_NOT_OPENED = 9,
MEDIA_CODEC_UNSUPPORTED_OPERATION = 10,
MEDIA_CODEC_INSUFFICIENT_SECURITY = 11,
MEDIA_CODEC_FRAME_TOO_LARGE = 12,
MEDIA_CODEC_LOST_STATE = 13,
MEDIA_CODEC_GENERIC_OEM = 14,
MEDIA_CODEC_GENERIC_PLUGIN = 15,
MEDIA_CODEC_LICENSE_PARSE = 16,
MEDIA_CODEC_MEDIA_FRAMEWORK = 17,
MEDIA_CODEC_ZERO_SUBSAMPLES = 18,
MEDIA_CODEC_UNKNOWN_CIPHER_MODE = 19,
MEDIA_CODEC_PATTERN_ENCRYPTION_NOT_SUPPORTED = 20,
MEDIA_CODEC_INSUFFICIENT_RESOURCE = 21,
MEDIA_CODEC_RECLAIMED = 22,
MEDIA_CODEC_INPUT_SLOT_UNAVAILABLE = 23,
MEDIA_CODEC_ILLEGAL_STATE = 24,
MEDIA_CODEC_UNKNOWN_CRYPTO_EXCEPTION = 25,
MEDIA_CODEC_UNKNOWN_MEDIADRM_EXCEPTION = 26,
MEDIA_CODEC_UNKNOWN_CODEC_EXCEPTION = 27,
MEDIA_CODEC_LINEAR_BLOCK_EXCEPTION = 28,
MEDIA_CODEC_MAX = MEDIA_CODEC_UNKNOWN_CODEC_EXCEPTION,
};
struct MediaCodecResultTraits {
enum class Codes : StatusCodeType {
kOk,
kTryAgainLater,
kOutputBuffersChanged,
kOutputFormatChanged,
kNoKey,
kError,
};
static constexpr StatusGroupType Group() { return "MediaCodecResult"; }
};
using MediaCodecResult = TypedStatus<MediaCodecResultTraits>;
// An interface for a bridge to an Android MediaCodec.
class MEDIA_EXPORT MediaCodecBridge {
public:
MediaCodecBridge() = default;
MediaCodecBridge(const MediaCodecBridge&) = delete;
MediaCodecBridge& operator=(const MediaCodecBridge&) = delete;
virtual ~MediaCodecBridge() = default;
// Calls MediaCodec#stop(). However, due to buggy implementations (b/8125974)
// Stop() followed by Start() may not work on some devices. For reliability,
// it's recommended to delete the instance and create a new one instead.
virtual void Stop() = 0;
// Calls MediaCodec#flush(). The codec takes ownership of all input and output
// buffers previously dequeued when this is called. Returns kError
// if an unexpected error happens, or kOk otherwise.
virtual MediaCodecResult Flush() = 0;
// Returns the output size. This is valid after DequeueOutputBuffer()
// signals a format change by returning OUTPUT_FORMAT_CHANGED.
// Returns kError if an error occurs, or kOk otherwise.
virtual MediaCodecResult GetOutputSize(gfx::Size* size) = 0;
// Gets the sampling rate. This is valid after DequeueOutputBuffer()
// signals a format change by returning kOutputFormatChanged.
// Returns kError if an error occurs, or kOk otherwise.
virtual MediaCodecResult GetOutputSamplingRate(int* sampling_rate) = 0;
// Fills |channel_count| with the number of audio channels. This is valid
// after DequeueOutputBuffer() signals a format change by returning
// kOutputFormatChanged. Returns kError if an error occurs,
// or kOk otherwise.
virtual MediaCodecResult GetOutputChannelCount(int* channel_count) = 0;
// Fills in |color_space| with the color space of the decoded video. This
// is valid after DequeueOutputBuffer() signals a format change. Will return
// kOk on success, with |color_space| initialized, or
// kError with |color_space| unmodified otherwise.
virtual MediaCodecResult GetOutputColorSpace(
gfx::ColorSpace* color_space) = 0;
// Fills in |stride| with required Y-plane stride in the encoder's input
// buffer. Returns kOk on success, with |stride| initialized, or
// kError with |stride| unmodified otherwise.
// Fills in |slice_height| with required Y-plane height in the encoder's input
// buffer. (i.e. the number of rows that must be skipped to get from the top
// of the Y plane to the top of the UV plane in the bytebuffer.)
// Fills in |encoded_size| with actual size the encoder was configured for,
// which may differ if the codec requires 16x16 aligned resolutions.
// (see MediaFormat#KEY_STRIDE for more details)
virtual MediaCodecResult GetInputFormat(int* stride,
int* slice_height,
gfx::Size* encoded_size) = 0;
// Submits a byte array to the given input buffer. Call this after getting an
// available buffer from DequeueInputBuffer(). `data` will be copied into the
// input buffer.
virtual MediaCodecResult QueueInputBuffer(
int index,
base::span<const uint8_t> data,
base::TimeDelta presentation_time) = 0;
// Similar to QueueInputBuffer() but submits the input buffer referenced by
// `index` assuming it has already been filled.
virtual MediaCodecResult QueueFilledInputBuffer(
int index,
size_t data_size,
base::TimeDelta presentation_time) = 0;
// As above but for encrypted buffers. NULL |subsamples| indicates the
// whole buffer is encrypted.
virtual MediaCodecResult QueueSecureInputBuffer(
int index,
base::span<const uint8_t> data,
base::TimeDelta presentation_time,
const DecryptConfig& decrypt_config) = 0;
// Submits an empty buffer with the END_OF_STREAM flag set.
virtual MediaCodecResult QueueEOS(int input_buffer_index) = 0;
// Returns:
// kOk if an input buffer is ready to be filled with valid data,
// kTryAgainLater if no such buffer is available, or
// kError if unexpected error happens.
virtual MediaCodecResult DequeueInputBuffer(base::TimeDelta timeout,
int* index) = 0;
// Dequeues an output buffer, block for up to |timeout|.
// Returns the status of this operation. If OK is returned, the output
// parameters should be populated. Otherwise, the values of output parameters
// should not be used. Output parameters other than index/offset/size are
// optional and only set if not NULL.
virtual MediaCodecResult DequeueOutputBuffer(
base::TimeDelta timeout,
int* index,
size_t* offset,
size_t* size,
base::TimeDelta* presentation_time,
bool* end_of_stream,
bool* key_frame) = 0;
// Returns the buffer to the codec. If you previously specified a surface when
// configuring this video decoder you can optionally render the buffer.
virtual void ReleaseOutputBuffer(int index, bool render) = 0;
// Returns an input buffer's base pointer and capacity.
virtual base::span<uint8_t> GetInputBuffer(int input_buffer_index) = 0;
// Copies |num| bytes from output buffer |index|'s |offset| into the memory
// region pointed to by |dst|. Returns kError if an error occurs, or kOk
// otherwise.
virtual MediaCodecResult CopyFromOutputBuffer(int index,
size_t offset,
base::span<uint8_t> dst) = 0;
// Gets the component name. Before API level 18 this returns an empty string.
virtual std::string GetName() = 0;
// Returns whether the media codec implementation is software codec.
virtual bool IsSoftwareCodec() = 0;
// Changes the output surface for the MediaCodec. May only be used on API
// level 23 and higher (Marshmallow).
virtual bool SetSurface(const base::android::JavaRef<jobject>& surface) = 0;
// Sets the video encoder target bitrate and framerate.
virtual void SetVideoBitrate(int bps, int frame_rate) = 0;
// Requests that the video encoder insert a key frame.
virtual void RequestKeyFrameSoon() = 0;
// When the MediaCodec has been configured in async mode, this is called when
// input or output buffers are available.
virtual void OnBuffersAvailable(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj) = 0;
// Returns the CodecType this codec was created with.
virtual CodecType GetCodecType() const = 0;
// Returns the max input size we configured the codec with.
virtual size_t GetMaxInputSize() = 0;
};
} // namespace media
#endif // MEDIA_BASE_ANDROID_MEDIA_CODEC_BRIDGE_H_