1 /*
2  * Copyright 2018 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 ANDROID_C2_SOFT_AVC_ENC_H__
18 #define ANDROID_C2_SOFT_AVC_ENC_H__
19 
20 #include <map>
21 
22 #include <utils/Vector.h>
23 
24 #include <SimpleC2Component.h>
25 
26 #include "ih264_typedefs.h"
27 #include "iv2.h"
28 #include "ive2.h"
29 
30 namespace android {
31 
32 #define CODEC_MAX_CORES          4
33 #define LEN_STATUS_BUFFER        (10  * 1024)
34 #define MAX_VBV_BUFF_SIZE        (120 * 16384)
35 #define MAX_NUM_IO_BUFS           3
36 
37 #define DEFAULT_MAX_REF_FRM         2
38 #define DEFAULT_MAX_REORDER_FRM     0
39 #define DEFAULT_QP_MIN              10
40 #define DEFAULT_QP_MAX              40
41 #define DEFAULT_MAX_BITRATE         20000000
42 #define DEFAULT_MAX_SRCH_RANGE_X    256
43 #define DEFAULT_MAX_SRCH_RANGE_Y    256
44 #define DEFAULT_MAX_FRAMERATE       120000
45 #define DEFAULT_NUM_CORES           1
46 #define DEFAULT_NUM_CORES_PRE_ENC   0
47 #define DEFAULT_FPS                 30
48 #define DEFAULT_ENC_SPEED           IVE_NORMAL
49 
50 #define DEFAULT_MEM_REC_CNT         0
51 #define DEFAULT_RECON_ENABLE        0
52 #define DEFAULT_CHKSUM_ENABLE       0
53 #define DEFAULT_START_FRM           0
54 #define DEFAULT_NUM_FRMS            0xFFFFFFFF
55 #define DEFAULT_INP_COLOR_FORMAT       IV_YUV_420SP_VU
56 #define DEFAULT_RECON_COLOR_FORMAT     IV_YUV_420P
57 #define DEFAULT_LOOPBACK            0
58 #define DEFAULT_SRC_FRAME_RATE      30
59 #define DEFAULT_TGT_FRAME_RATE      30
60 #define DEFAULT_MAX_WD              1920
61 #define DEFAULT_MAX_HT              1920
62 #define DEFAULT_MAX_LEVEL           41
63 #define DEFAULT_STRIDE              0
64 #define DEFAULT_WD                  1280
65 #define DEFAULT_HT                  720
66 #define DEFAULT_PSNR_ENABLE         0
67 #define DEFAULT_ME_SPEED            100
68 #define DEFAULT_ENABLE_FAST_SAD     0
69 #define DEFAULT_ENABLE_ALT_REF      0
70 #define DEFAULT_RC_MODE             IVE_RC_STORAGE
71 #define DEFAULT_BITRATE             6000000
72 #define DEFAULT_I_QP                22
73 #define DEFAULT_I_QP_MAX            DEFAULT_QP_MAX
74 #define DEFAULT_I_QP_MIN            DEFAULT_QP_MIN
75 #define DEFAULT_P_QP                28
76 #define DEFAULT_P_QP_MAX            DEFAULT_QP_MAX
77 #define DEFAULT_P_QP_MIN            DEFAULT_QP_MIN
78 #define DEFAULT_B_QP                22
79 #define DEFAULT_B_QP_MAX            DEFAULT_QP_MAX
80 #define DEFAULT_B_QP_MIN            DEFAULT_QP_MIN
81 #define DEFAULT_AIR                 IVE_AIR_MODE_NONE
82 #define DEFAULT_AIR_REFRESH_PERIOD  30
83 #define DEFAULT_SRCH_RNG_X          64
84 #define DEFAULT_SRCH_RNG_Y          48
85 #define DEFAULT_I_INTERVAL          30
86 #define DEFAULT_IDR_INTERVAL        1000
87 #define DEFAULT_B_FRAMES            0
88 #define DEFAULT_DISABLE_DEBLK_LEVEL 0
89 #define DEFAULT_HPEL                1
90 #define DEFAULT_QPEL                1
91 #define DEFAULT_I4                  1
92 #define DEFAULT_EPROFILE            IV_PROFILE_BASE
93 #define DEFAULT_ENTROPY_MODE        0
94 #define DEFAULT_SLICE_MODE          IVE_SLICE_MODE_NONE
95 #define DEFAULT_SLICE_PARAM         256
96 #define DEFAULT_ARCH                ARCH_ARM_A9Q
97 #define DEFAULT_SOC                 SOC_GENERIC
98 #define DEFAULT_INTRA4x4            0
99 #define STRLENGTH                   500
100 #define DEFAULT_CONSTRAINED_INTRA   0
101 
102 #define MIN(a, b) ((a) < (b))? (a) : (b)
103 #define MAX(a, b) ((a) > (b))? (a) : (b)
104 #define ALIGN16(x) ((((x) + 15) >> 4) << 4)
105 #define ALIGN128(x) ((((x) + 127) >> 7) << 7)
106 #define ALIGN4096(x) ((((x) + 4095) >> 12) << 12)
107 
108 /** Used to remove warnings about unused parameters */
109 #define UNUSED(x) ((void)(x))
110 
111 /** Get time */
112 #define GETTIME(a, b) gettimeofday(a, b);
113 
114 /** Compute difference between start and end */
115 #define TIME_DIFF(start, end, diff) \
116     diff = (((end).tv_sec - (start).tv_sec) * 1000000) + \
117             ((end).tv_usec - (start).tv_usec);
118 
119 #define ive_aligned_malloc(alignment, size) memalign(alignment, size)
120 #define ive_aligned_free(buf) free(buf)
121 
122 struct C2SoftAvcEnc : public SimpleC2Component {
123     class IntfImpl;
124 
125     C2SoftAvcEnc(const char *name, c2_node_id_t id, const std::shared_ptr<IntfImpl> &intfImpl);
126 
127     // From SimpleC2Component
128     c2_status_t onInit() override;
129     c2_status_t onStop() override;
130     void onReset() override;
131     void onRelease() override;
132     c2_status_t onFlush_sm() override;
133     void process(
134             const std::unique_ptr<C2Work> &work,
135             const std::shared_ptr<C2BlockPool> &pool) override;
136     c2_status_t drain(
137             uint32_t drainMode,
138             const std::shared_ptr<C2BlockPool> &pool) override;
139 
140 protected:
141     virtual ~C2SoftAvcEnc();
142 
143 private:
144     enum {
145         kUpdateBitrate            = 1 << 0,
146         kRequestKeyFrame          = 1 << 1,
147         kUpdateAIRMode            = 1 << 2,
148     };
149 
150     // OMX input buffer's timestamp and flags
151     typedef struct {
152         int64_t mTimeUs;
153         int32_t mFlags;
154     } InputBufferInfo;
155 
156     std::shared_ptr<IntfImpl> mIntf;
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 __unused;
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     iv_obj_t *mCodecCtx;         // Codec context
190     iv_mem_rec_t *mMemRecords;   // Memory records requested by the codec
191     size_t mNumMemRecords;       // Number of memory records requested by codec
192     size_t mNumCores;            // Number of cores used by the codec
193 
194     uint32_t mWidth __unused;
195     uint32_t mHeight __unused;
196     uint32_t mFramerate __unused;
197     uint32_t mBitrate __unused;
198     uint32_t mOutBufferSize;
199     UWORD32 mHeaderGenerated;
200     UWORD32 mBframes;
201     IV_ARCH_T mArch;
202     IVE_SLICE_MODE_T mSliceMode;
203     UWORD32 mSliceParam;
204     bool mHalfPelEnable;
205     UWORD32 mIInterval;
206     UWORD32 mIDRInterval;
207     UWORD32 mDisableDeblkLevel;
208     IVE_AIR_MODE_T mAIRMode;
209     UWORD32 mAIRRefreshPeriod;
210     std::map<const void *, std::shared_ptr<C2Buffer>> mBuffers;
211     MemoryBlockPool mConversionBuffers;
212     std::map<const void *, MemoryBlock> mConversionBuffersInUse;
213 
214     void initEncParams();
215     c2_status_t initEncoder();
216     c2_status_t releaseEncoder();
217 
218     c2_status_t setFrameType(IV_PICTURE_CODING_TYPE_T  e_frame_type);
219     c2_status_t setQp();
220     c2_status_t setEncMode(IVE_ENC_MODE_T e_enc_mode);
221     c2_status_t setDimensions();
222     c2_status_t setNumCores();
223     c2_status_t setFrameRate();
224     c2_status_t setIpeParams();
225     c2_status_t setBitRate();
226     c2_status_t setAirParams();
227     c2_status_t setMeParams();
228     c2_status_t setGopParams();
229     c2_status_t setProfileParams();
230     c2_status_t setDeblockParams();
231     c2_status_t setVbvParams();
232     void logVersion();
233     c2_status_t setEncodeArgs(
234             ive_video_encode_ip_t *ps_encode_ip,
235             ive_video_encode_op_t *ps_encode_op,
236             const C2GraphicView *const input,
237             uint8_t *base,
238             uint32_t capacity,
239             uint64_t timestamp);
240 
241     C2_DO_NOT_COPY(C2SoftAvcEnc);
242 };
243 
244 #ifdef FILE_DUMP_ENABLE
245 
246 #define INPUT_DUMP_PATH     "/sdcard/media/avce_input"
247 #define INPUT_DUMP_EXT      "yuv"
248 #define OUTPUT_DUMP_PATH    "/sdcard/media/avce_output"
249 #define OUTPUT_DUMP_EXT     "h264"
250 
251 #define GENERATE_FILE_NAMES() {                         \
252     GETTIME(&mTimeStart, NULL);                         \
253     strcpy(mInFile, "");                                \
254     sprintf(mInFile, "%s_%ld.%ld.%s", INPUT_DUMP_PATH,  \
255             mTimeStart.tv_sec, mTimeStart.tv_usec,      \
256             INPUT_DUMP_EXT);                            \
257     strcpy(mOutFile, "");                               \
258     sprintf(mOutFile, "%s_%ld.%ld.%s", OUTPUT_DUMP_PATH,\
259             mTimeStart.tv_sec, mTimeStart.tv_usec,      \
260             OUTPUT_DUMP_EXT);                           \
261 }
262 
263 #define CREATE_DUMP_FILE(m_filename) {                  \
264     FILE *fp = fopen(m_filename, "wb");                 \
265     if (fp != NULL) {                                   \
266         ALOGD("Opened file %s", m_filename);            \
267         fclose(fp);                                     \
268     } else {                                            \
269         ALOGD("Could not open file %s", m_filename);    \
270     }                                                   \
271 }
272 #define DUMP_TO_FILE(m_filename, m_buf, m_size)         \
273 {                                                       \
274     FILE *fp = fopen(m_filename, "ab");                 \
275     if (fp != NULL && m_buf != NULL) {                  \
276         int i;                                          \
277         i = fwrite(m_buf, 1, m_size, fp);               \
278         ALOGD("fwrite ret %d to write %d", i, m_size);  \
279         if (i != (int)m_size) {                         \
280             ALOGD("Error in fwrite, returned %d", i);   \
281             perror("Error in write to file");           \
282         }                                               \
283         fclose(fp);                                     \
284     } else {                                            \
285         ALOGD("Could not write to file %s", m_filename);\
286         if (fp != NULL)                                 \
287             fclose(fp);                                 \
288     }                                                   \
289 }
290 #else /* FILE_DUMP_ENABLE */
291 #define INPUT_DUMP_PATH
292 #define INPUT_DUMP_EXT
293 #define OUTPUT_DUMP_PATH
294 #define OUTPUT_DUMP_EXT
295 #define GENERATE_FILE_NAMES()
296 #define CREATE_DUMP_FILE(m_filename)
297 #define DUMP_TO_FILE(m_filename, m_buf, m_size)
298 #endif /* FILE_DUMP_ENABLE */
299 
300 }  // namespace android
301 
302 #endif  // ANDROID_C2_SOFT_AVC_ENC_H__
303