summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h
blob: 5b4c954e8c0652aaf44ecef966c3958b799b6890 (plain)
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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SOFT_VPX_ENCODER_H_

#define SOFT_VPX_ENCODER_H_

#include "SimpleSoftOMXComponent.h"

#include <OMX_VideoExt.h>
#include <OMX_IndexExt.h>

#include <hardware/gralloc.h>

#include "vpx/vpx_encoder.h"
#include "vpx/vpx_codec.h"
#include "vpx/vp8cx.h"

namespace android {

// Exposes a vpx encoder as an OMX Component
//
// Boilerplate for callback bindings are taken care
// by the base class SimpleSoftOMXComponent and its
// parent SoftOMXComponent.
//
// Only following encoder settings are available
//    - target bitrate
//    - rate control (constant / variable)
//    - frame rate
//    - error resilience
//    - token partitioning
//    - reconstruction & loop filters (g_profile)
//
// Only following color formats are recognized
//    - YUV420Planar
//    - YUV420SemiPlanar
//    - AndroidOpaque
//
// Following settings are not configurable by the client
//    - encoding deadline is realtime
//    - multithreaded encoding utilizes a number of threads equal
// to online cpu's available
//    - the algorithm interface for encoder is vp8
//    - fractional bits of frame rate is discarded
//    - OMX timestamps are in microseconds, therefore
// encoder timebase is fixed to 1/1000000

struct SoftVPXEncoder : public SimpleSoftOMXComponent {
    SoftVPXEncoder(const char *name,
                   const OMX_CALLBACKTYPE *callbacks,
                   OMX_PTR appData,
                   OMX_COMPONENTTYPE **component);

protected:
    virtual ~SoftVPXEncoder();

    // Returns current values for requested OMX
    // parameters
    virtual OMX_ERRORTYPE internalGetParameter(
            OMX_INDEXTYPE index, OMX_PTR param);

    // Validates, extracts and stores relevant OMX
    // parameters
    virtual OMX_ERRORTYPE internalSetParameter(
            OMX_INDEXTYPE index, const OMX_PTR param);

    virtual OMX_ERRORTYPE setConfig(
            OMX_INDEXTYPE index, const OMX_PTR params);

    // OMX callback when buffers available
    // Note that both an input and output buffer
    // is expected to be available to carry out
    // encoding of the frame
    virtual void onQueueFilled(OMX_U32 portIndex);

    virtual OMX_ERRORTYPE getExtensionIndex(
            const char *name, OMX_INDEXTYPE *index);

private:
    enum TemporalReferences {
        // For 1 layer case: reference all (last, golden, and alt ref), but only
        // update last.
        kTemporalUpdateLastRefAll = 12,
        // First base layer frame for 3 temporal layers, which updates last and
        // golden with alt ref dependency.
        kTemporalUpdateLastAndGoldenRefAltRef = 11,
        // First enhancement layer with alt ref dependency.
        kTemporalUpdateGoldenRefAltRef = 10,
        // First enhancement layer with alt ref dependency.
        kTemporalUpdateGoldenWithoutDependencyRefAltRef = 9,
        // Base layer with alt ref dependency.
        kTemporalUpdateLastRefAltRef = 8,
        // Highest enhacement layer without dependency on golden with alt ref
        // dependency.
        kTemporalUpdateNoneNoRefGoldenRefAltRef = 7,
        // Second layer and last frame in cycle, for 2 layers.
        kTemporalUpdateNoneNoRefAltref = 6,
        // Highest enhancement layer.
        kTemporalUpdateNone = 5,
        // Second enhancement layer.
        kTemporalUpdateAltref = 4,
        // Second enhancement layer without dependency on previous frames in
        // the second enhancement layer.
        kTemporalUpdateAltrefWithoutDependency = 3,
        // First enhancement layer.
        kTemporalUpdateGolden = 2,
        // First enhancement layer without dependency on previous frames in
        // the first enhancement layer.
        kTemporalUpdateGoldenWithoutDependency = 1,
        // Base layer.
        kTemporalUpdateLast = 0,
    };
    enum {
        kMaxTemporalPattern = 8
    };

    // number of buffers allocated per port
    static const uint32_t kNumBuffers = 4;

    // OMX port indexes that refer to input and
    // output ports respectively
    static const uint32_t kInputPortIndex = 0;
    static const uint32_t kOutputPortIndex = 1;

    // Byte-alignment required for buffers
    static const uint32_t kInputBufferAlignment = 1;
    static const uint32_t kOutputBufferAlignment = 2;

    // Max value supported for DCT partitions
    static const uint32_t kMaxDCTPartitions = 3;

    // Number of supported input color formats
    static const uint32_t kNumberOfSupportedColorFormats = 3;

    // vpx specific opaque data structure that
    // stores encoder state
    vpx_codec_ctx_t* mCodecContext;

    // vpx specific data structure that
    // stores encoder configuration
    vpx_codec_enc_cfg_t* mCodecConfiguration;

    // vpx specific read-only data structure
    // that specifies algorithm interface (e.g. vp8)
    vpx_codec_iface_t* mCodecInterface;

    // Width of the input frames
    int32_t mWidth;

    // Height of the input frames
    int32_t mHeight;

    // Target bitrate set for the encoder, in bits per second.
    uint32_t mBitrate;

    // Target framerate set for the encoder.
    uint32_t mFramerate;

    // If a request for a change it bitrate has been received.
    bool mBitrateUpdated;

    // Bitrate control mode, either constant or variable
    vpx_rc_mode mBitrateControlMode;

    // vp8 specific configuration parameter
    // that enables token partitioning of
    // the stream into substreams
    int32_t mDCTPartitions;

    // Parameter that denotes whether error resilience
    // is enabled in encoder
    OMX_BOOL mErrorResilience;

    // Color format for the input port
    OMX_COLOR_FORMATTYPE mColorFormat;

    // Encoder profile corresponding to OMX level parameter
    //
    // The inconsistency in the naming is caused by
    // OMX spec referring vpx profiles (g_profile)
    // as "levels" whereas using the name "profile" for
    // something else.
    OMX_VIDEO_VP8LEVELTYPE mLevel;

    // Key frame interval in frames
    uint32_t mKeyFrameInterval;

    // Minimum (best quality) quantizer
    uint32_t mMinQuantizer;

    // Maximum (worst quality) quantizer
    uint32_t mMaxQuantizer;

    // Number of coding temporal layers to be used.
    size_t mTemporalLayers;

    // Temporal layer bitrare ratio in percentage
    uint32_t mTemporalLayerBitrateRatio[OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS];

    // Temporal pattern type
    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE mTemporalPatternType;

    // Temporal pattern length
    size_t mTemporalPatternLength;

    // Temporal pattern current index
    size_t mTemporalPatternIdx;

    // Frame type temporal pattern
    TemporalReferences mTemporalPattern[kMaxTemporalPattern];

    // Last input buffer timestamp
    OMX_TICKS mLastTimestamp;

    // Conversion buffer is needed to convert semi
    // planar yuv420 to planar format
    // It is only allocated if input format is
    // indeed YUV420SemiPlanar.
    uint8_t* mConversionBuffer;

    bool mInputDataIsMeta;
    const hw_module_t *mGrallocModule;

    bool mKeyFrameRequested;

    // Initializes input and output OMX ports with sensible
    // default values.
    void initPorts();

    // Initializes vpx encoder with available settings.
    status_t initEncoder();

    // Releases vpx encoder instance, with it's associated
    // data structures.
    //
    // Unless called earlier, this is handled by the
    // dtor.
    status_t releaseEncoder();

    // Get current encode flags
    vpx_enc_frame_flags_t getEncodeFlags();

    // Handles port changes with respect to color formats
    OMX_ERRORTYPE internalSetFormatParams(
        const OMX_VIDEO_PARAM_PORTFORMATTYPE* format);

    // Verifies the component role tried to be set to this OMX component is
    // strictly video_encoder.vp8
    OMX_ERRORTYPE internalSetRoleParams(
        const OMX_PARAM_COMPONENTROLETYPE* role);

    // Updates bitrate to reflect port settings.
    OMX_ERRORTYPE internalSetBitrateParams(
        const OMX_VIDEO_PARAM_BITRATETYPE* bitrate);

    // Handles port definition changes.
    OMX_ERRORTYPE internalSetPortParams(
        const OMX_PARAM_PORTDEFINITIONTYPE* port);

    // Handles vp8 specific parameters.
    OMX_ERRORTYPE internalSetVp8Params(
        const OMX_VIDEO_PARAM_VP8TYPE* vp8Params);

    // Handles Android vp8 specific parameters.
    OMX_ERRORTYPE internalSetAndroidVp8Params(
        const OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE* vp8AndroidParams);

    // Updates encoder profile
    OMX_ERRORTYPE internalSetProfileLevel(
        const OMX_VIDEO_PARAM_PROFILELEVELTYPE* profileAndLevel);

    DISALLOW_EVIL_CONSTRUCTORS(SoftVPXEncoder);
};

}  // namespace android

#endif  // SOFT_VPX_ENCODER_H_