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 <media/stagefright/omx/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// Base class for a VPX Encoder 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 (codec specific settings might
41// be available in the sub-classes):
42//    - target bitrate
43//    - rate control (constant / variable)
44//    - frame rate
45//    - error resilience
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 decided by the sub-class in use
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                   const char* role,
68                   OMX_VIDEO_CODINGTYPE codingType,
69                   const char* mimeType,
70                   int32_t minCompressionRatio,
71                   const CodecProfileLevel *profileLevels,
72                   size_t numProfileLevels);
73
74protected:
75    virtual ~SoftVPXEncoder();
76
77    // Returns current values for requested OMX
78    // parameters
79    virtual OMX_ERRORTYPE internalGetParameter(
80            OMX_INDEXTYPE index, OMX_PTR param);
81
82    // Validates, extracts and stores relevant OMX
83    // parameters
84    virtual OMX_ERRORTYPE internalSetParameter(
85            OMX_INDEXTYPE index, const OMX_PTR param);
86
87    virtual OMX_ERRORTYPE setConfig(
88            OMX_INDEXTYPE index, const OMX_PTR params);
89
90    // OMX callback when buffers available
91    // Note that both an input and output buffer
92    // is expected to be available to carry out
93    // encoding of the frame
94    virtual void onQueueFilled(OMX_U32 portIndex);
95
96    virtual void onReset();
97
98    // Initializes vpx encoder with available settings.
99    status_t initEncoder();
100
101    // Populates mCodecInterface with codec specific settings.
102    virtual void setCodecSpecificInterface() = 0;
103
104    // Sets codec specific configuration.
105    virtual void setCodecSpecificConfiguration() = 0;
106
107    // Sets codec specific encoder controls.
108    virtual vpx_codec_err_t setCodecSpecificControls() = 0;
109
110    // Get current encode flags.
111    virtual vpx_enc_frame_flags_t getEncodeFlags();
112
113    // Releases vpx encoder instance, with it's associated
114    // data structures.
115    //
116    // Unless called earlier, this is handled by the
117    // dtor.
118    status_t releaseEncoder();
119
120    // Get bitrate parameters.
121    virtual OMX_ERRORTYPE internalGetBitrateParams(
122        OMX_VIDEO_PARAM_BITRATETYPE* bitrate);
123
124    // Updates bitrate to reflect port settings.
125    virtual OMX_ERRORTYPE internalSetBitrateParams(
126        const OMX_VIDEO_PARAM_BITRATETYPE* bitrate);
127
128    // Gets Android vpx specific parameters.
129    OMX_ERRORTYPE internalGetAndroidVpxParams(
130            OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *vpxAndroidParams);
131
132    // Handles Android vpx specific parameters.
133    OMX_ERRORTYPE internalSetAndroidVpxParams(
134            const OMX_VIDEO_PARAM_ANDROID_VP8ENCODERTYPE *vpxAndroidParams);
135
136    enum TemporalReferences {
137        // For 1 layer case: reference all (last, golden, and alt ref), but only
138        // update last.
139        kTemporalUpdateLastRefAll = 12,
140        // First base layer frame for 3 temporal layers, which updates last and
141        // golden with alt ref dependency.
142        kTemporalUpdateLastAndGoldenRefAltRef = 11,
143        // First enhancement layer with alt ref dependency.
144        kTemporalUpdateGoldenRefAltRef = 10,
145        // First enhancement layer with alt ref dependency.
146        kTemporalUpdateGoldenWithoutDependencyRefAltRef = 9,
147        // Base layer with alt ref dependency.
148        kTemporalUpdateLastRefAltRef = 8,
149        // Highest enhacement layer without dependency on golden with alt ref
150        // dependency.
151        kTemporalUpdateNoneNoRefGoldenRefAltRef = 7,
152        // Second layer and last frame in cycle, for 2 layers.
153        kTemporalUpdateNoneNoRefAltref = 6,
154        // Highest enhancement layer.
155        kTemporalUpdateNone = 5,
156        // Second enhancement layer.
157        kTemporalUpdateAltref = 4,
158        // Second enhancement layer without dependency on previous frames in
159        // the second enhancement layer.
160        kTemporalUpdateAltrefWithoutDependency = 3,
161        // First enhancement layer.
162        kTemporalUpdateGolden = 2,
163        // First enhancement layer without dependency on previous frames in
164        // the first enhancement layer.
165        kTemporalUpdateGoldenWithoutDependency = 1,
166        // Base layer.
167        kTemporalUpdateLast = 0,
168    };
169    enum {
170        kMaxTemporalPattern = 8
171    };
172
173    // number of buffers allocated per port
174    static const uint32_t kNumBuffers = 4;
175
176    // OMX port indexes that refer to input and
177    // output ports respectively
178    static const uint32_t kInputPortIndex = 0;
179    static const uint32_t kOutputPortIndex = 1;
180
181    // Byte-alignment required for buffers
182    static const uint32_t kInputBufferAlignment = 1;
183    static const uint32_t kOutputBufferAlignment = 2;
184
185    // Number of supported input color formats
186    static const uint32_t kNumberOfSupportedColorFormats = 3;
187
188    // vpx specific opaque data structure that
189    // stores encoder state
190    vpx_codec_ctx_t* mCodecContext;
191
192    // vpx specific data structure that
193    // stores encoder configuration
194    vpx_codec_enc_cfg_t* mCodecConfiguration;
195
196    // vpx specific read-only data structure
197    // that specifies algorithm interface (e.g. vp8)
198    vpx_codec_iface_t* mCodecInterface;
199
200    // If a request for a change it bitrate has been received.
201    bool mBitrateUpdated;
202
203    // Bitrate control mode, either constant or variable
204    vpx_rc_mode mBitrateControlMode;
205
206    // Parameter that denotes whether error resilience
207    // is enabled in encoder
208    OMX_BOOL mErrorResilience;
209
210    // Key frame interval in frames
211    uint32_t mKeyFrameInterval;
212
213    // Minimum (best quality) quantizer
214    uint32_t mMinQuantizer;
215
216    // Maximum (worst quality) quantizer
217    uint32_t mMaxQuantizer;
218
219    // Number of coding temporal layers to be used.
220    size_t mTemporalLayers;
221
222    // Temporal layer bitrare ratio in percentage
223    uint32_t mTemporalLayerBitrateRatio[OMX_VIDEO_ANDROID_MAXVP8TEMPORALLAYERS];
224
225    // Temporal pattern type
226    OMX_VIDEO_ANDROID_VPXTEMPORALLAYERPATTERNTYPE mTemporalPatternType;
227
228    // Temporal pattern length
229    size_t mTemporalPatternLength;
230
231    // Temporal pattern current index
232    size_t mTemporalPatternIdx;
233
234    // Frame type temporal pattern
235    TemporalReferences mTemporalPattern[kMaxTemporalPattern];
236
237    // Last input buffer timestamp
238    OMX_TICKS mLastTimestamp;
239
240    // Conversion buffer is needed to convert semi
241    // planar yuv420 to planar format
242    // It is only allocated if input format is
243    // indeed YUV420SemiPlanar.
244    uint8_t* mConversionBuffer;
245
246    bool mKeyFrameRequested;
247
248    DISALLOW_EVIL_CONSTRUCTORS(SoftVPXEncoder);
249};
250
251}  // namespace android
252
253#endif  // SOFT_VPX_ENCODER_H_
254