SoftVPXEncoder.h revision 2edda09a2ad1d112c52acd37d323f63f0a492d67
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SOFT_VPX_ENCODER_H_
18
19#define SOFT_VPX_ENCODER_H_
20
21#include "SoftVideoEncoderOMXComponent.h"
22
23#include <OMX_VideoExt.h>
24#include <OMX_IndexExt.h>
25
26#include <hardware/gralloc.h>
27
28#include "vpx/vpx_encoder.h"
29#include "vpx/vpx_codec.h"
30#include "vpx/vp8cx.h"
31
32namespace android {
33
34// Exposes a vpx encoder as an OMX Component
35//
36// Boilerplate for callback bindings are taken care
37// by the base class SimpleSoftOMXComponent and its
38// parent SoftOMXComponent.
39//
40// Only following encoder settings are available
41//    - target bitrate
42//    - rate control (constant / variable)
43//    - frame rate
44//    - error resilience
45//    - token partitioning
46//    - reconstruction & loop filters (g_profile)
47//
48// Only following color formats are recognized
49//    - YUV420Planar
50//    - YUV420SemiPlanar
51//    - AndroidOpaque
52//
53// Following settings are not configurable by the client
54//    - encoding deadline is realtime
55//    - multithreaded encoding utilizes a number of threads equal
56// to online cpu's available
57//    - the algorithm interface for encoder is vp8
58//    - fractional bits of frame rate is discarded
59//    - OMX timestamps are in microseconds, therefore
60// encoder timebase is fixed to 1/1000000
61
62struct SoftVPXEncoder : public SoftVideoEncoderOMXComponent {
63    SoftVPXEncoder(const char *name,
64                   const OMX_CALLBACKTYPE *callbacks,
65                   OMX_PTR appData,
66                   OMX_COMPONENTTYPE **component);
67
68protected:
69    virtual ~SoftVPXEncoder();
70
71    // Returns current values for requested OMX
72    // parameters
73    virtual OMX_ERRORTYPE internalGetParameter(
74            OMX_INDEXTYPE index, OMX_PTR param);
75
76    // Validates, extracts and stores relevant OMX
77    // parameters
78    virtual OMX_ERRORTYPE internalSetParameter(
79            OMX_INDEXTYPE index, const OMX_PTR param);
80
81    virtual OMX_ERRORTYPE setConfig(
82            OMX_INDEXTYPE index, const OMX_PTR params);
83
84    // OMX callback when buffers available
85    // Note that both an input and output buffer
86    // is expected to be available to carry out
87    // encoding of the frame
88    virtual void onQueueFilled(OMX_U32 portIndex);
89
90private:
91    enum TemporalReferences {
92        // For 1 layer case: reference all (last, golden, and alt ref), but only
93        // update last.
94        kTemporalUpdateLastRefAll = 12,
95        // First base layer frame for 3 temporal layers, which updates last and
96        // golden with alt ref dependency.
97        kTemporalUpdateLastAndGoldenRefAltRef = 11,
98        // First enhancement layer with alt ref dependency.
99        kTemporalUpdateGoldenRefAltRef = 10,
100        // First enhancement layer with alt ref dependency.
101        kTemporalUpdateGoldenWithoutDependencyRefAltRef = 9,
102        // Base layer with alt ref dependency.
103        kTemporalUpdateLastRefAltRef = 8,
104        // Highest enhacement layer without dependency on golden with alt ref
105        // dependency.
106        kTemporalUpdateNoneNoRefGoldenRefAltRef = 7,
107        // Second layer and last frame in cycle, for 2 layers.
108        kTemporalUpdateNoneNoRefAltref = 6,
109        // Highest enhancement layer.
110        kTemporalUpdateNone = 5,
111        // Second enhancement layer.
112        kTemporalUpdateAltref = 4,
113        // Second enhancement layer without dependency on previous frames in
114        // the second enhancement layer.
115        kTemporalUpdateAltrefWithoutDependency = 3,
116        // First enhancement layer.
117        kTemporalUpdateGolden = 2,
118        // First enhancement layer without dependency on previous frames in
119        // the first enhancement layer.
120        kTemporalUpdateGoldenWithoutDependency = 1,
121        // Base layer.
122        kTemporalUpdateLast = 0,
123    };
124    enum {
125        kMaxTemporalPattern = 8
126    };
127
128    // number of buffers allocated per port
129    static const uint32_t kNumBuffers = 4;
130
131    // OMX port indexes that refer to input and
132    // output ports respectively
133    static const uint32_t kInputPortIndex = 0;
134    static const uint32_t kOutputPortIndex = 1;
135
136    // Byte-alignment required for buffers
137    static const uint32_t kInputBufferAlignment = 1;
138    static const uint32_t kOutputBufferAlignment = 2;
139
140    // Max value supported for DCT partitions
141    static const uint32_t kMaxDCTPartitions = 3;
142
143    // Number of supported input color formats
144    static const uint32_t kNumberOfSupportedColorFormats = 3;
145
146    // vpx specific opaque data structure that
147    // stores encoder state
148    vpx_codec_ctx_t* mCodecContext;
149
150    // vpx specific data structure that
151    // stores encoder configuration
152    vpx_codec_enc_cfg_t* mCodecConfiguration;
153
154    // vpx specific read-only data structure
155    // that specifies algorithm interface (e.g. vp8)
156    vpx_codec_iface_t* mCodecInterface;
157
158    // Width of the input frames
159    int32_t mWidth;
160
161    // Height of the input frames
162    int32_t mHeight;
163
164    // Target bitrate set for the encoder, in bits per second.
165    uint32_t mBitrate;
166
167    // Target framerate set for the encoder.
168    uint32_t mFramerate;
169
170    // If a request for a change it bitrate has been received.
171    bool mBitrateUpdated;
172
173    // Bitrate control mode, either constant or variable
174    vpx_rc_mode mBitrateControlMode;
175
176    // vp8 specific configuration parameter
177    // that enables token partitioning of
178    // the stream into substreams
179    int32_t mDCTPartitions;
180
181    // Parameter that denotes whether error resilience
182    // is enabled in encoder
183    OMX_BOOL mErrorResilience;
184
185    // Color format for the input port
186    OMX_COLOR_FORMATTYPE mColorFormat;
187
188    // Encoder profile corresponding to OMX level parameter
189    //
190    // The inconsistency in the naming is caused by
191    // OMX spec referring vpx profiles (g_profile)
192    // as "levels" whereas using the name "profile" for
193    // something else.
194    OMX_VIDEO_VP8LEVELTYPE mLevel;
195
196    // Key frame interval in frames
197    uint32_t mKeyFrameInterval;
198
199    // Minimum (best quality) quantizer
200    uint32_t mMinQuantizer;
201
202    // Maximum (worst quality) quantizer
203    uint32_t mMaxQuantizer;
204
205    // Number of coding temporal layers to be used.
206    size_t mTemporalLayers;
207
208    // Temporal layer bitrare ratio in percentage
209    uint32_t mTemporalLayerBitrateRatio[OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS];
210
211    // Temporal pattern type
212    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE mTemporalPatternType;
213
214    // Temporal pattern length
215    size_t mTemporalPatternLength;
216
217    // Temporal pattern current index
218    size_t mTemporalPatternIdx;
219
220    // Frame type temporal pattern
221    TemporalReferences mTemporalPattern[kMaxTemporalPattern];
222
223    // Last input buffer timestamp
224    OMX_TICKS mLastTimestamp;
225
226    // Conversion buffer is needed to convert semi
227    // planar yuv420 to planar format
228    // It is only allocated if input format is
229    // indeed YUV420SemiPlanar.
230    uint8_t* mConversionBuffer;
231
232    bool mInputDataIsMeta;
233
234    bool mKeyFrameRequested;
235
236    // Initializes input and output OMX ports with sensible
237    // default values.
238    void initPorts();
239
240    // Initializes vpx encoder with available settings.
241    status_t initEncoder();
242
243    // Releases vpx encoder instance, with it's associated
244    // data structures.
245    //
246    // Unless called earlier, this is handled by the
247    // dtor.
248    status_t releaseEncoder();
249
250    // Get current encode flags
251    vpx_enc_frame_flags_t getEncodeFlags();
252
253    // Handles port changes with respect to color formats
254    OMX_ERRORTYPE internalSetFormatParams(
255        const OMX_VIDEO_PARAM_PORTFORMATTYPE* format);
256
257    // Verifies the component role tried to be set to this OMX component is
258    // strictly video_encoder.vp8
259    OMX_ERRORTYPE internalSetRoleParams(
260        const OMX_PARAM_COMPONENTROLETYPE* role);
261
262    // Updates bitrate to reflect port settings.
263    OMX_ERRORTYPE internalSetBitrateParams(
264        const OMX_VIDEO_PARAM_BITRATETYPE* bitrate);
265
266    // Handles port definition changes.
267    OMX_ERRORTYPE internalSetPortParams(
268        const OMX_PARAM_PORTDEFINITIONTYPE* port);
269
270    // Handles vp8 specific parameters.
271    OMX_ERRORTYPE internalSetVp8Params(
272        const OMX_VIDEO_PARAM_VP8TYPE* vp8Params);
273
274    // Handles Android vp8 specific parameters.
275    OMX_ERRORTYPE internalSetAndroidVp8Params(
276        const OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE* vp8AndroidParams);
277
278    // Updates encoder profile
279    OMX_ERRORTYPE internalSetProfileLevel(
280        const OMX_VIDEO_PARAM_PROFILELEVELTYPE* profileAndLevel);
281
282    DISALLOW_EVIL_CONSTRUCTORS(SoftVPXEncoder);
283};
284
285}  // namespace android
286
287#endif  // SOFT_VPX_ENCODER_H_
288