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 <media/stagefright/omx/SoftVideoEncoderOMXComponent.h>
25 
26 namespace 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         240000000
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 
120 struct 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 
136 protected:
137     virtual ~SoftAVC();
138 
139     virtual void onReset();
140 
141 private:
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 internalSetConfig(
223         OMX_INDEXTYPE index, const OMX_PTR _params, bool *frameConfig);
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