1/*
2 * Copyright 2012 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_AVC_ENC_H__
18#define __SOFT_AVC_ENC_H__
19
20
21#include <media/stagefright/foundation/ABase.h>
22#include <utils/Vector.h>
23
24#include "SoftVideoEncoderOMXComponent.h"
25
26namespace android {
27
28#define MAX_INPUT_BUFFER_HEADERS 4
29#define MAX_CONVERSION_BUFFERS   4
30#define CODEC_MAX_CORES          4
31#define LEN_STATUS_BUFFER        (10  * 1024)
32#define MAX_VBV_BUFF_SIZE        (120 * 16384)
33#define MAX_NUM_IO_BUFS           3
34
35#define DEFAULT_MAX_REF_FRM         2
36#define DEFAULT_MAX_REORDER_FRM     0
37#define DEFAULT_QP_MIN              10
38#define DEFAULT_QP_MAX              40
39#define DEFAULT_MAX_BITRATE         20000000
40#define DEFAULT_MAX_SRCH_RANGE_X    256
41#define DEFAULT_MAX_SRCH_RANGE_Y    256
42#define DEFAULT_MAX_FRAMERATE       120000
43#define DEFAULT_NUM_CORES           1
44#define DEFAULT_NUM_CORES_PRE_ENC   0
45#define DEFAULT_FPS                 30
46#define DEFAULT_ENC_SPEED           IVE_NORMAL
47
48#define DEFAULT_MEM_REC_CNT         0
49#define DEFAULT_RECON_ENABLE        0
50#define DEFAULT_CHKSUM_ENABLE       0
51#define DEFAULT_START_FRM           0
52#define DEFAULT_NUM_FRMS            0xFFFFFFFF
53#define DEFAULT_INP_COLOR_FORMAT       IV_YUV_420SP_VU
54#define DEFAULT_RECON_COLOR_FORMAT     IV_YUV_420P
55#define DEFAULT_LOOPBACK            0
56#define DEFAULT_SRC_FRAME_RATE      30
57#define DEFAULT_TGT_FRAME_RATE      30
58#define DEFAULT_MAX_WD              1920
59#define DEFAULT_MAX_HT              1920
60#define DEFAULT_MAX_LEVEL           41
61#define DEFAULT_STRIDE              0
62#define DEFAULT_WD                  1280
63#define DEFAULT_HT                  720
64#define DEFAULT_PSNR_ENABLE         0
65#define DEFAULT_ME_SPEED            100
66#define DEFAULT_ENABLE_FAST_SAD     0
67#define DEFAULT_ENABLE_ALT_REF      0
68#define DEFAULT_RC_MODE             IVE_RC_STORAGE
69#define DEFAULT_BITRATE             6000000
70#define DEFAULT_I_QP                22
71#define DEFAULT_I_QP_MAX            DEFAULT_QP_MAX
72#define DEFAULT_I_QP_MIN            DEFAULT_QP_MIN
73#define DEFAULT_P_QP                28
74#define DEFAULT_P_QP_MAX            DEFAULT_QP_MAX
75#define DEFAULT_P_QP_MIN            DEFAULT_QP_MIN
76#define DEFAULT_B_QP                22
77#define DEFAULT_B_QP_MAX            DEFAULT_QP_MAX
78#define DEFAULT_B_QP_MIN            DEFAULT_QP_MIN
79#define DEFAULT_AIR                 IVE_AIR_MODE_NONE
80#define DEFAULT_AIR_REFRESH_PERIOD  30
81#define DEFAULT_SRCH_RNG_X          64
82#define DEFAULT_SRCH_RNG_Y          48
83#define DEFAULT_I_INTERVAL          30
84#define DEFAULT_IDR_INTERVAL        1000
85#define DEFAULT_B_FRAMES            0
86#define DEFAULT_DISABLE_DEBLK_LEVEL 0
87#define DEFAULT_HPEL                1
88#define DEFAULT_QPEL                1
89#define DEFAULT_I4                  1
90#define DEFAULT_EPROFILE            IV_PROFILE_BASE
91#define DEFAULT_ENTROPY_MODE        0
92#define DEFAULT_SLICE_MODE          IVE_SLICE_MODE_NONE
93#define DEFAULT_SLICE_PARAM         256
94#define DEFAULT_ARCH                ARCH_ARM_A9Q
95#define DEFAULT_SOC                 SOC_GENERIC
96#define DEFAULT_INTRA4x4            0
97#define STRLENGTH                   500
98#define DEFAULT_CONSTRAINED_INTRA   0
99
100#define MIN(a, b) ((a) < (b))? (a) : (b)
101#define MAX(a, b) ((a) > (b))? (a) : (b)
102#define ALIGN16(x) ((((x) + 15) >> 4) << 4)
103#define ALIGN128(x) ((((x) + 127) >> 7) << 7)
104#define ALIGN4096(x) ((((x) + 4095) >> 12) << 12)
105
106/** Used to remove warnings about unused parameters */
107#define UNUSED(x) ((void)(x))
108
109/** Get time */
110#define GETTIME(a, b) gettimeofday(a, b);
111
112/** Compute difference between start and end */
113#define TIME_DIFF(start, end, diff) \
114    diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
115            ((end).tv_usec - (start).tv_usec);
116
117#define ive_aligned_malloc(alignment, size) memalign(alignment, size)
118#define ive_aligned_free(buf) free(buf)
119
120struct SoftAVC : public SoftVideoEncoderOMXComponent {
121    SoftAVC(
122            const char *name,
123            const OMX_CALLBACKTYPE *callbacks,
124            OMX_PTR appData,
125            OMX_COMPONENTTYPE **component);
126
127    // Override SimpleSoftOMXComponent methods
128    virtual OMX_ERRORTYPE internalGetParameter(
129            OMX_INDEXTYPE index, OMX_PTR params);
130
131    virtual OMX_ERRORTYPE internalSetParameter(
132            OMX_INDEXTYPE index, const OMX_PTR params);
133
134    virtual void onQueueFilled(OMX_U32 portIndex);
135
136protected:
137    virtual ~SoftAVC();
138
139    virtual void onReset();
140
141private:
142    enum {
143        kNumBuffers = 2,
144    };
145
146    enum {
147        kUpdateBitrate            = 1 << 0,
148        kRequestKeyFrame          = 1 << 1,
149        kUpdateAIRMode            = 1 << 2,
150    };
151
152    // OMX input buffer's timestamp and flags
153    typedef struct {
154        int64_t mTimeUs;
155        int32_t mFlags;
156    } InputBufferInfo;
157
158    int32_t  mStride;
159
160    struct timeval mTimeStart;   // Time at the start of decode()
161    struct timeval mTimeEnd;     // Time at the end of decode()
162
163    int mUpdateFlag;
164
165#ifdef FILE_DUMP_ENABLE
166    char mInFile[200];
167    char mOutFile[200];
168#endif /* FILE_DUMP_ENABLE */
169
170    IV_COLOR_FORMAT_T mIvVideoColorFormat;
171
172    IV_PROFILE_T mAVCEncProfile;
173    WORD32   mAVCEncLevel;
174    bool     mStarted;
175    bool     mSpsPpsHeaderReceived;
176
177    bool     mSawInputEOS;
178    bool     mSawOutputEOS;
179    bool     mSignalledError;
180    bool     mIntra4x4;
181    bool     mEnableFastSad;
182    bool     mEnableAltRef;
183    bool     mReconEnable;
184    bool     mPSNREnable;
185    bool     mEntropyMode;
186    bool     mConstrainedIntraFlag;
187    IVE_SPEED_CONFIG     mEncSpeed;
188
189    uint8_t *mConversionBuffers[MAX_CONVERSION_BUFFERS];
190    bool     mConversionBuffersFree[MAX_CONVERSION_BUFFERS];
191    BufferInfo *mInputBufferInfo[MAX_INPUT_BUFFER_HEADERS];
192    iv_obj_t *mCodecCtx;         // Codec context
193    iv_mem_rec_t *mMemRecords;   // Memory records requested by the codec
194    size_t mNumMemRecords;       // Number of memory records requested by codec
195    size_t mNumCores;            // Number of cores used by the codec
196
197    UWORD32 mHeaderGenerated;
198    UWORD32 mBframes;
199    IV_ARCH_T mArch;
200    IVE_SLICE_MODE_T mSliceMode;
201    UWORD32 mSliceParam;
202    bool mHalfPelEnable;
203    UWORD32 mIInterval;
204    UWORD32 mIDRInterval;
205    UWORD32 mDisableDeblkLevel;
206    IVE_AIR_MODE_T mAIRMode;
207    UWORD32 mAIRRefreshPeriod;
208
209    void initEncParams();
210    OMX_ERRORTYPE initEncoder();
211    OMX_ERRORTYPE releaseEncoder();
212
213    // Verifies the component role tried to be set to this OMX component is
214    // strictly video_encoder.avc
215    OMX_ERRORTYPE internalSetRoleParams(
216        const OMX_PARAM_COMPONENTROLETYPE *role);
217
218    // Updates bitrate to reflect port settings.
219    OMX_ERRORTYPE internalSetBitrateParams(
220        const OMX_VIDEO_PARAM_BITRATETYPE *bitrate);
221
222    OMX_ERRORTYPE setConfig(
223        OMX_INDEXTYPE index, const OMX_PTR _params);
224
225    OMX_ERRORTYPE getConfig(
226        OMX_INDEXTYPE index, const OMX_PTR _params);
227
228    // Handles port definition changes.
229    OMX_ERRORTYPE internalSetPortParams(
230        const OMX_PARAM_PORTDEFINITIONTYPE *port);
231
232    OMX_ERRORTYPE internalSetFormatParams(
233        const OMX_VIDEO_PARAM_PORTFORMATTYPE *format);
234
235    OMX_ERRORTYPE setFrameType(IV_PICTURE_CODING_TYPE_T  e_frame_type);
236    OMX_ERRORTYPE setQp();
237    OMX_ERRORTYPE setEncMode(IVE_ENC_MODE_T e_enc_mode);
238    OMX_ERRORTYPE setDimensions();
239    OMX_ERRORTYPE setNumCores();
240    OMX_ERRORTYPE setFrameRate();
241    OMX_ERRORTYPE setIpeParams();
242    OMX_ERRORTYPE setBitRate();
243    OMX_ERRORTYPE setAirParams();
244    OMX_ERRORTYPE setMeParams();
245    OMX_ERRORTYPE setGopParams();
246    OMX_ERRORTYPE setProfileParams();
247    OMX_ERRORTYPE setDeblockParams();
248    OMX_ERRORTYPE setVbvParams();
249    void logVersion();
250    OMX_ERRORTYPE setEncodeArgs(
251        ive_video_encode_ip_t *ps_encode_ip,
252        ive_video_encode_op_t *ps_encode_op,
253        OMX_BUFFERHEADERTYPE *inputBufferHeader,
254        OMX_BUFFERHEADERTYPE *outputBufferHeader);
255
256    DISALLOW_EVIL_CONSTRUCTORS(SoftAVC);
257};
258
259#ifdef FILE_DUMP_ENABLE
260
261#define INPUT_DUMP_PATH     "/sdcard/media/avce_input"
262#define INPUT_DUMP_EXT      "yuv"
263#define OUTPUT_DUMP_PATH    "/sdcard/media/avce_output"
264#define OUTPUT_DUMP_EXT     "h264"
265
266#define GENERATE_FILE_NAMES() {                         \
267    GETTIME(&mTimeStart, NULL);                         \
268    strcpy(mInFile, "");                                \
269    sprintf(mInFile, "%s_%ld.%ld.%s", INPUT_DUMP_PATH,  \
270            mTimeStart.tv_sec, mTimeStart.tv_usec,      \
271            INPUT_DUMP_EXT);                            \
272    strcpy(mOutFile, "");                               \
273    sprintf(mOutFile, "%s_%ld.%ld.%s", OUTPUT_DUMP_PATH,\
274            mTimeStart.tv_sec, mTimeStart.tv_usec,      \
275            OUTPUT_DUMP_EXT);                           \
276}
277
278#define CREATE_DUMP_FILE(m_filename) {                  \
279    FILE *fp = fopen(m_filename, "wb");                 \
280    if (fp != NULL) {                                   \
281        ALOGD("Opened file %s", m_filename);            \
282        fclose(fp);                                     \
283    } else {                                            \
284        ALOGD("Could not open file %s", m_filename);    \
285    }                                                   \
286}
287#define DUMP_TO_FILE(m_filename, m_buf, m_size)         \
288{                                                       \
289    FILE *fp = fopen(m_filename, "ab");                 \
290    if (fp != NULL && m_buf != NULL) {                  \
291        int i;                                          \
292        i = fwrite(m_buf, 1, m_size, fp);               \
293        ALOGD("fwrite ret %d to write %d", i, m_size);  \
294        if (i != (int)m_size) {                         \
295            ALOGD("Error in fwrite, returned %d", i);   \
296            perror("Error in write to file");           \
297        }                                               \
298        fclose(fp);                                     \
299    } else {                                            \
300        ALOGD("Could not write to file %s", m_filename);\
301        if (fp != NULL)                                 \
302            fclose(fp);                                 \
303    }                                                   \
304}
305#else /* FILE_DUMP_ENABLE */
306#define INPUT_DUMP_PATH
307#define INPUT_DUMP_EXT
308#define OUTPUT_DUMP_PATH
309#define OUTPUT_DUMP_EXT
310#define GENERATE_FILE_NAMES()
311#define CREATE_DUMP_FILE(m_filename)
312#define DUMP_TO_FILE(m_filename, m_buf, m_size)
313#endif /* FILE_DUMP_ENABLE */
314
315}  // namespace android
316
317#endif  // __SOFT_AVC_ENC_H__
318