xref: /aosp_15_r20/external/libavc/fuzzer/avc_enc_fuzzer.cpp (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
1 /******************************************************************************
2  *
3  * Copyright (C) 2020 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19  */
20 #include <malloc.h>
21 #include <algorithm>
22 #include <string.h>
23 #include <tuple>
24 #include <vector>
25 
26 #include "ih264_defs.h"
27 #include "ih264_typedefs.h"
28 #include "ih264e.h"
29 #include "ih264e_error.h"
30 #define ive_api_function ih264e_api_function
31 typedef std::tuple<uint8_t *, uint8_t *, uint8_t *> bufferPtrs;
32 
33 constexpr static int kMaxNumEncodeCalls = 100;
34 constexpr uint32_t kHeaderLength = 0x800;
35 constexpr int16_t kCompressionRatio = 1;
36 
37 constexpr int kMeSpeedPreset[] = {0, 50, 75, 100};
38 constexpr IVE_AIR_MODE_T kAirMode[] = {IVE_AIR_MODE_NONE, IVE_AIR_MODE_CYCLIC, IVE_AIR_MODE_RANDOM};
39 constexpr IVE_SPEED_CONFIG kEncSpeed[] = {IVE_CONFIG, IVE_SLOWEST,    IVE_NORMAL,
40                                           IVE_FAST,   IVE_HIGH_SPEED, IVE_FASTEST};
41 constexpr IV_PROFILE_T kProfle[] = {IV_PROFILE_BASE, IV_PROFILE_MAIN};
42 constexpr IVE_RC_MODE_T kRCMode[] = {IVE_RC_NONE, IVE_RC_STORAGE, IVE_RC_CBR_NON_LOW_DELAY,
43                                      IVE_RC_CBR_LOW_DELAY};
44 constexpr IV_COLOR_FORMAT_T kSupportedColorFormats[] = {IV_YUV_420P, IV_YUV_420SP_UV, IV_YUV_422ILE,
45                                                         IV_YUV_420SP_VU};
46 
47 constexpr size_t kAirModeNum = std::size(kAirMode);
48 constexpr size_t kEncSpeedNum = std::size(kEncSpeed);
49 constexpr size_t kMeSpeedPresetNum = std::size(kMeSpeedPreset);
50 constexpr size_t kProfleNum = std::size(kProfle);
51 constexpr size_t kRCModeNum = std::size(kRCMode);
52 constexpr size_t kSupportedColorFormatsNum = std::size(kSupportedColorFormats);
53 constexpr size_t kMinQP = 4;
54 constexpr size_t kMaxWidth = 10240;
55 constexpr size_t kMaxHeight = 10240;
56 constexpr size_t kMaxBitrate = 500000000;
57 
58 enum {
59     IDX_WD_BYTE_1,
60     IDX_WD_BYTE_2,
61     IDX_HT_BYTE_1,
62     IDX_HT_BYTE_2,
63     IDX_COLOR_FORMAT,
64     IDX_ARCH_TYPE,
65     IDX_RC_MODE,
66     IDX_NUM_CORES,
67     IDX_NUM_B_FRAMES,
68     IDX_ENC_SPEED,
69     IDX_CONSTRAINED_INTRA_FLAG,
70     IDX_INTRA_4x4,
71     IDX_I_FRAME_QP,
72     IDX_P_FRAME_QP,
73     IDX_B_FRAME_QP,
74     IDX_BITRATE_BYTE_1,
75     IDX_BITRATE_BYTE_2,
76     IDX_FRAME_RATE,
77     IDX_INTRA_REFRESH,
78     IDX_ENABLE_HALF_PEL,
79     IDX_ENABLE_Q_PEL,
80     IDX_ME_SPEED_PRESET,
81     IDX_AIR_MODE,
82     IDX_DISABLE_DEBLOCK_LEVEL,
83     IDX_SEARCH_RANGE_X,
84     IDX_SEARCH_RANGE_Y,
85     IDX_I_INTERVAL,
86     IDX_IDR_INTERVAL,
87     IDX_SEI_MDCV_FLAG,
88     IDX_SEI_CLL_FLAG,
89     IDX_SEI_AVE_FLAG,
90     IDX_SEI_CCV_FLAG,
91     IDX_SEI_SII_FLAG,
92     IDX_PROFILE,
93     IDX_ASPECT_RATIO_FLAG,
94     IDX_NAL_HRD_FLAG,
95     IDX_VCL_HRD_FLAG,
96     IDX_ENABLE_FORCE_IDR,
97     IDX_ENABLE_DYNAMIC_BITRATE,
98     IDX_ENABLE_DYNAMIC_FRAME_RATE,
99     IDX_FORCE_IDR_INTERVAL,
100     IDX_DYNAMIC_BITRATE_INTERVAL,
101     IDX_DYNAMIC_FRAME_RATE_INTERVAL,
102     IDX_SEND_EOS_WITH_LAST_FRAME,
103     IDX_LAST
104 };
105 
106 class Codec {
107    public:
108     Codec() = default;
~Codec()109     ~Codec() { deInitEncoder(); }
110     bool initEncoder(const uint8_t **pdata, size_t *psize);
111     void encodeFrames(const uint8_t *data, size_t size);
112     void deInitEncoder();
113 
114    private:
115     bufferPtrs setEncParams(iv_raw_buf_t *psInpRawBuf, const uint8_t *data, size_t frameSize);
116     void setFrameType(IV_PICTURE_CODING_TYPE_T eFrameType);
117     void setQp();
118     void setEncMode(IVE_ENC_MODE_T eEncMode);
119     void setDimensions();
120     void setNumCores();
121     void setFrameRate();
122     void setIpeParams();
123     void setBitRate();
124     void setAirParams();
125     void setMeParams();
126     void setGopParams();
127     void setProfileParams();
128     void setDeblockParams();
129     void setVbvParams();
130     void setDefault();
131     void setVuiParams();
132     void getBufInfo();
133     void setSeiMdcvParams();
134     void setSeiCllParams();
135     void setSeiAveParams();
136     void setSeiCcvParams();
137     void setSeiSiiParams();
138     void logVersion();
139     bool mHalfPelEnable = 1;
140     bool mQPelEnable = 1;
141     bool mIntra4x4 = 0;
142     bool mEnableFastSad = 0;
143     bool mEnableAltRef = 0;
144     bool mConstrainedIntraFlag = 0;
145     bool mSeiCllFlag = 1;
146     bool mSeiAveFlag = 1;
147     bool mSeiCcvFlag = 1;
148     bool mSeiMdcvFlag = 1;
149     bool mSeiSiiFlag = 1;
150     bool mAspectRatioFlag = 0;
151     bool mNalHrdFlag = 0;
152     bool mVclHrdFlag = 0;
153     bool mIsForceIdrEnabled = false;
154     bool mIsDynamicBitRateChangeEnabled = false;
155     bool mIsDynamicFrameRateChangeEnabled = false;
156     bool mSendEosWithLastFrame = false;
157     uint32_t mWidth = 2560;
158     uint32_t mHeight = 2560;
159     uint32_t mAvcEncLevel = 41;
160     uint32_t mNumMemRecords = 0;
161     uint32_t mNumCores = 1;
162     uint32_t mBframes = 0;
163     uint32_t mSliceParam = 256;
164     uint32_t mMeSpeedPreset = 100;
165     uint32_t mIInterval = 60;
166     uint32_t mIDRInterval = 60;
167     uint32_t mDisableDeblockLevel = 0;
168     uint32_t m_I_QP = 22;
169     uint32_t m_P_QP = 28;
170     uint32_t m_B_QP = 22;
171     uint32_t mIntraRefresh = 30;
172     uint32_t mSearchRangeX = 64;
173     uint32_t mSearchRangeY = 48;
174     uint32_t mForceIdrInterval = 0;          // in number of frames
175     uint32_t mDynamicBitRateInterval = 0;    // in number of frames
176     uint32_t mDynamicFrameRateInterval = 0;  // in number of frames
177     uint64_t mBitrate = 6000000;
178     float mFrameRate = 30;
179     iv_obj_t *mCodecCtx = nullptr;
180     iv_mem_rec_t *mMemRecords = nullptr;
181     IVE_AIR_MODE_T mAirMode = IVE_AIR_MODE_NONE;
182     IVE_SPEED_CONFIG mEncSpeed = IVE_NORMAL;
183     IVE_RC_MODE_T mRCMode = IVE_RC_STORAGE;
184     IV_ARCH_T mArch = ARCH_NA;
185     IVE_SLICE_MODE_T mSliceMode = IVE_SLICE_MODE_NONE;
186     IV_COLOR_FORMAT_T mIvVideoColorFormat = IV_YUV_420P;
187     IV_COLOR_FORMAT_T mReconFormat = IV_YUV_420P;
188     IV_PROFILE_T mProfile = IV_PROFILE_BASE;
189 };
190 
initEncoder(const uint8_t ** pdata,size_t * psize)191 bool Codec::initEncoder(const uint8_t **pdata, size_t *psize) {
192     uint8_t *data = const_cast<uint8_t *>(*pdata);
193     mWidth = ((data[IDX_WD_BYTE_1] << 8) | data[IDX_WD_BYTE_2]) % kMaxWidth;
194     mHeight = ((data[IDX_HT_BYTE_1] << 8) | data[IDX_HT_BYTE_2]) % kMaxHeight;
195 
196     mIvVideoColorFormat =
197         kSupportedColorFormats[data[IDX_COLOR_FORMAT] % kSupportedColorFormatsNum];
198     mArch = ((data[IDX_ARCH_TYPE] & 0x03) == 0x00) ? ARCH_ARM_NONEON : ARCH_NA;
199     mRCMode = kRCMode[data[IDX_RC_MODE] % kRCModeNum];
200     mNumCores = (data[IDX_NUM_CORES] & 0x07) + 1;
201     mBframes = data[IDX_NUM_B_FRAMES] & 0x07;
202     mEncSpeed = kEncSpeed[data[IDX_ENC_SPEED] % kEncSpeedNum];
203     mConstrainedIntraFlag = data[IDX_CONSTRAINED_INTRA_FLAG] & 0x01;
204     mIntra4x4 = data[IDX_INTRA_4x4] & 0x01;
205     m_I_QP = (data[IDX_I_FRAME_QP] % (MAX_H264_QP - kMinQP)) + kMinQP;
206     m_P_QP = (data[IDX_P_FRAME_QP] % (MAX_H264_QP - kMinQP)) + kMinQP;
207     m_B_QP = (data[IDX_B_FRAME_QP] % (MAX_H264_QP - kMinQP)) + kMinQP;
208     mBitrate = (((data[IDX_BITRATE_BYTE_1] << 8) | data[IDX_BITRATE_BYTE_2]) * 1000) % kMaxBitrate;
209     mFrameRate = data[IDX_FRAME_RATE];
210     mIntraRefresh = data[IDX_INTRA_REFRESH] + 1;
211     mHalfPelEnable = data[IDX_ENABLE_HALF_PEL] & 0x01;
212     mQPelEnable = data[IDX_ENABLE_Q_PEL] & 0x01;
213     mMeSpeedPreset = kMeSpeedPreset[data[IDX_ME_SPEED_PRESET] % kMeSpeedPresetNum];
214     mAirMode = kAirMode[data[IDX_AIR_MODE] % kAirModeNum];
215     mDisableDeblockLevel = data[IDX_DISABLE_DEBLOCK_LEVEL] & 0x03;
216     mSearchRangeX = data[IDX_SEARCH_RANGE_X];
217     mSearchRangeY = data[IDX_SEARCH_RANGE_Y];
218     mIInterval = data[IDX_I_INTERVAL] + 1;
219     mIDRInterval = data[IDX_IDR_INTERVAL] + 1;
220     mSeiMdcvFlag = data[IDX_SEI_MDCV_FLAG] & 0x01;
221     mSeiCllFlag = data[IDX_SEI_CLL_FLAG] & 0x01;
222     mSeiAveFlag = data[IDX_SEI_AVE_FLAG] & 0x01;
223     mSeiCcvFlag = data[IDX_SEI_CCV_FLAG] & 0x01;
224     mSeiSiiFlag = data[IDX_SEI_SII_FLAG] & 0x01;
225     mProfile = kProfle[data[IDX_PROFILE] % kProfleNum];
226     mAspectRatioFlag = data[IDX_ASPECT_RATIO_FLAG] & 0x01;
227     mNalHrdFlag = data[IDX_NAL_HRD_FLAG] & 0x01;
228     mVclHrdFlag = data[IDX_VCL_HRD_FLAG] & 0x01;
229     mIsForceIdrEnabled = data[IDX_ENABLE_FORCE_IDR] & 0x01;
230     mIsDynamicBitRateChangeEnabled = data[IDX_ENABLE_DYNAMIC_BITRATE] & 0x01;
231     mIsDynamicFrameRateChangeEnabled = data[IDX_ENABLE_DYNAMIC_FRAME_RATE] & 0x01;
232     mSendEosWithLastFrame = data[IDX_SEND_EOS_WITH_LAST_FRAME] & 0x01;
233     mForceIdrInterval = data[IDX_FORCE_IDR_INTERVAL] & 0x07;
234     mDynamicBitRateInterval = data[IDX_DYNAMIC_BITRATE_INTERVAL] & 0x07;
235     mDynamicFrameRateInterval = data[IDX_DYNAMIC_FRAME_RATE_INTERVAL] & 0x07;
236 
237     /* Getting Number of MemRecords */
238     iv_num_mem_rec_ip_t sNumMemRecIp{};
239     iv_num_mem_rec_op_t sNumMemRecOp{};
240 
241     sNumMemRecIp.u4_size = sizeof(iv_num_mem_rec_ip_t);
242     sNumMemRecOp.u4_size = sizeof(iv_num_mem_rec_op_t);
243     sNumMemRecIp.e_cmd = IV_CMD_GET_NUM_MEM_REC;
244 
245     if (IV_SUCCESS != ive_api_function(nullptr, &sNumMemRecIp, &sNumMemRecOp)) {
246         return false;
247     }
248     mNumMemRecords = sNumMemRecOp.u4_num_mem_rec;
249     mMemRecords = (iv_mem_rec_t *)malloc(mNumMemRecords * sizeof(iv_mem_rec_t));
250     if (!mMemRecords) {
251         return false;
252     }
253     iv_mem_rec_t *psMemRec;
254     psMemRec = mMemRecords;
255     for (size_t i = 0; i < mNumMemRecords; ++i) {
256         psMemRec->u4_size = sizeof(iv_mem_rec_t);
257         psMemRec->pv_base = nullptr;
258         psMemRec->u4_mem_size = 0;
259         psMemRec->u4_mem_alignment = 0;
260         psMemRec->e_mem_type = IV_NA_MEM_TYPE;
261         ++psMemRec;
262     }
263 
264     /* Getting MemRecords Attributes */
265     iv_fill_mem_rec_ip_t sFillMemRecIp{};
266     iv_fill_mem_rec_op_t sFillMemRecOp{};
267 
268     sFillMemRecIp.u4_size = sizeof(iv_fill_mem_rec_ip_t);
269     sFillMemRecOp.u4_size = sizeof(iv_fill_mem_rec_op_t);
270 
271     sFillMemRecIp.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
272     sFillMemRecIp.ps_mem_rec = mMemRecords;
273     sFillMemRecIp.u4_num_mem_rec = mNumMemRecords;
274     sFillMemRecIp.u4_max_wd = mWidth;
275     sFillMemRecIp.u4_max_ht = mHeight;
276     sFillMemRecIp.u4_max_level = mAvcEncLevel;
277     sFillMemRecIp.e_color_format = IV_YUV_420SP_VU;
278     sFillMemRecIp.u4_max_ref_cnt = 2;
279     sFillMemRecIp.u4_max_reorder_cnt = 0;
280     sFillMemRecIp.u4_max_srch_rng_x = 256;
281     sFillMemRecIp.u4_max_srch_rng_y = 256;
282 
283     if (IV_SUCCESS != ive_api_function(nullptr, &sFillMemRecIp, &sFillMemRecOp)) {
284         return false;
285     }
286     /* Allocating Memory for Mem Records */
287     psMemRec = mMemRecords;
288     for (size_t i = 0; i < mNumMemRecords; ++i) {
289         posix_memalign(&psMemRec->pv_base, psMemRec->u4_mem_alignment, psMemRec->u4_mem_size);
290         if (!psMemRec->pv_base) {
291             return false;
292         }
293         ++psMemRec;
294     }
295 
296     /* Codec Instance Creation */
297     ive_init_ip_t sInitIp{};
298     ive_init_op_t sInitOp{};
299 
300     mCodecCtx = (iv_obj_t *)mMemRecords[0].pv_base;
301     mCodecCtx->u4_size = sizeof(iv_obj_t);
302     mCodecCtx->pv_fxns = (void *)ive_api_function;
303 
304     sInitIp.u4_size = sizeof(ive_init_ip_t);
305     sInitOp.u4_size = sizeof(ive_init_op_t);
306 
307     sInitIp.e_cmd = IV_CMD_INIT;
308     sInitIp.u4_num_mem_rec = mNumMemRecords;
309     sInitIp.ps_mem_rec = mMemRecords;
310     sInitIp.u4_max_wd = mWidth;
311     sInitIp.u4_max_ht = mHeight;
312     sInitIp.u4_max_ref_cnt = 2;
313     sInitIp.u4_max_reorder_cnt = 0;
314     sInitIp.u4_max_level = mAvcEncLevel;
315     sInitIp.e_inp_color_fmt = mIvVideoColorFormat;
316     sInitIp.u4_enable_recon = 0;
317     sInitIp.e_recon_color_fmt = mReconFormat;
318     sInitIp.e_rc_mode = mRCMode;
319     sInitIp.u4_max_framerate = 120000;
320     sInitIp.u4_max_bitrate = 240000000;
321     sInitIp.u4_num_bframes = mBframes;
322     sInitIp.e_content_type = IV_PROGRESSIVE;
323     sInitIp.u4_max_srch_rng_x = 256;
324     sInitIp.u4_max_srch_rng_y = 256;
325     sInitIp.e_slice_mode = mSliceMode;
326     sInitIp.u4_slice_param = mSliceParam;
327     sInitIp.e_arch = mArch;
328     sInitIp.e_soc = SOC_GENERIC;
329 
330     if (IV_SUCCESS != ive_api_function(mCodecCtx, &sInitIp, &sInitOp)) {
331         return false;
332     }
333 
334     logVersion();
335     setDefault();
336     getBufInfo();
337     setNumCores();
338     setDimensions();
339     setFrameRate();
340     setIpeParams();
341     setBitRate();
342     setQp();
343     setAirParams();
344     setVbvParams();
345     setMeParams();
346     setGopParams();
347     setDeblockParams();
348     setVuiParams();
349     setSeiMdcvParams();
350     setSeiCllParams();
351     setSeiAveParams();
352     setSeiCcvParams();
353     setSeiSiiParams();
354     setProfileParams();
355     setEncMode(IVE_ENC_MODE_HEADER);
356 
357     *pdata += IDX_LAST;
358     *psize -= IDX_LAST;
359     return true;
360 }
361 
setDimensions()362 void Codec::setDimensions() {
363     ive_ctl_set_dimensions_ip_t sDimensionsIp{};
364     ive_ctl_set_dimensions_op_t sDimensionsOp{};
365 
366     sDimensionsIp.e_cmd = IVE_CMD_VIDEO_CTL;
367     sDimensionsIp.e_sub_cmd = IVE_CMD_CTL_SET_DIMENSIONS;
368     sDimensionsIp.u4_ht = mHeight;
369     sDimensionsIp.u4_wd = mWidth;
370 
371     sDimensionsIp.u4_timestamp_high = -1;
372     sDimensionsIp.u4_timestamp_low = -1;
373 
374     sDimensionsIp.u4_size = sizeof(ive_ctl_set_dimensions_ip_t);
375     sDimensionsOp.u4_size = sizeof(ive_ctl_set_dimensions_op_t);
376 
377     ive_api_function(mCodecCtx, &sDimensionsIp, &sDimensionsOp);
378     return;
379 }
380 
setNumCores()381 void Codec::setNumCores() {
382     ive_ctl_set_num_cores_ip_t sNumCoresIp{};
383     ive_ctl_set_num_cores_op_t sNumCoresOp{};
384 
385     sNumCoresIp.e_cmd = IVE_CMD_VIDEO_CTL;
386     sNumCoresIp.e_sub_cmd = IVE_CMD_CTL_SET_NUM_CORES;
387     sNumCoresIp.u4_num_cores = mNumCores;
388 
389     sNumCoresIp.u4_timestamp_high = -1;
390     sNumCoresIp.u4_timestamp_low = -1;
391 
392     sNumCoresIp.u4_size = sizeof(ive_ctl_set_num_cores_ip_t);
393     sNumCoresOp.u4_size = sizeof(ive_ctl_set_num_cores_op_t);
394 
395     ive_api_function(mCodecCtx, (void *)&sNumCoresIp, (void *)&sNumCoresOp);
396     return;
397 }
398 
setDefault()399 void Codec::setDefault() {
400     ive_ctl_setdefault_ip_t sDefaultIp{};
401     ive_ctl_setdefault_op_t sDefaultOp{};
402 
403     sDefaultIp.e_cmd = IVE_CMD_VIDEO_CTL;
404     sDefaultIp.e_sub_cmd = IVE_CMD_CTL_SETDEFAULT;
405 
406     sDefaultIp.u4_timestamp_high = -1;
407     sDefaultIp.u4_timestamp_low = -1;
408 
409     sDefaultIp.u4_size = sizeof(ive_ctl_setdefault_ip_t);
410     sDefaultOp.u4_size = sizeof(ive_ctl_setdefault_op_t);
411 
412     ive_api_function(mCodecCtx, &sDefaultIp, &sDefaultOp);
413     return;
414 }
415 
getBufInfo()416 void Codec::getBufInfo() {
417     ih264e_ctl_getbufinfo_ip_t sGetBufInfoIp{};
418     ih264e_ctl_getbufinfo_op_t sGetBufInfoOp{};
419 
420     sGetBufInfoIp.s_ive_ip.u4_size = sizeof(ih264e_ctl_getbufinfo_ip_t);
421     sGetBufInfoOp.s_ive_op.u4_size = sizeof(ih264e_ctl_getbufinfo_op_t);
422 
423     sGetBufInfoIp.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL;
424     sGetBufInfoIp.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_GETBUFINFO;
425     sGetBufInfoIp.s_ive_ip.u4_max_ht = mHeight;
426     sGetBufInfoIp.s_ive_ip.u4_max_wd = mWidth;
427     sGetBufInfoIp.s_ive_ip.e_inp_color_fmt = mIvVideoColorFormat;
428 
429     ih264e_api_function(mCodecCtx, &sGetBufInfoIp, &sGetBufInfoOp);
430     return;
431 }
432 
setFrameRate()433 void Codec::setFrameRate() {
434     ive_ctl_set_frame_rate_ip_t sFrameRateIp{};
435     ive_ctl_set_frame_rate_op_t sFrameRateOp{};
436 
437     sFrameRateIp.e_cmd = IVE_CMD_VIDEO_CTL;
438     sFrameRateIp.e_sub_cmd = IVE_CMD_CTL_SET_FRAMERATE;
439     sFrameRateIp.u4_src_frame_rate = mFrameRate;
440     sFrameRateIp.u4_tgt_frame_rate = mFrameRate;
441 
442     sFrameRateIp.u4_timestamp_high = -1;
443     sFrameRateIp.u4_timestamp_low = -1;
444 
445     sFrameRateIp.u4_size = sizeof(ive_ctl_set_frame_rate_ip_t);
446     sFrameRateOp.u4_size = sizeof(ive_ctl_set_frame_rate_op_t);
447 
448     ive_api_function(mCodecCtx, &sFrameRateIp, &sFrameRateOp);
449     return;
450 }
451 
setIpeParams()452 void Codec::setIpeParams() {
453     ive_ctl_set_ipe_params_ip_t sIpeParamsIp{};
454     ive_ctl_set_ipe_params_op_t sIpeParamsOp{};
455 
456     sIpeParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
457     sIpeParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_IPE_PARAMS;
458     sIpeParamsIp.u4_enable_intra_4x4 = mIntra4x4;
459     sIpeParamsIp.u4_enc_speed_preset = mEncSpeed;
460     sIpeParamsIp.u4_constrained_intra_pred = mConstrainedIntraFlag;
461 
462     sIpeParamsIp.u4_timestamp_high = -1;
463     sIpeParamsIp.u4_timestamp_low = -1;
464 
465     sIpeParamsIp.u4_size = sizeof(ive_ctl_set_ipe_params_ip_t);
466     sIpeParamsOp.u4_size = sizeof(ive_ctl_set_ipe_params_op_t);
467 
468     ive_api_function(mCodecCtx, &sIpeParamsIp, &sIpeParamsOp);
469     return;
470 }
471 
setBitRate()472 void Codec::setBitRate() {
473     ive_ctl_set_bitrate_ip_t sBitrateIp{};
474     ive_ctl_set_bitrate_op_t sBitrateOp{};
475 
476     sBitrateIp.e_cmd = IVE_CMD_VIDEO_CTL;
477     sBitrateIp.e_sub_cmd = IVE_CMD_CTL_SET_BITRATE;
478     sBitrateIp.u4_target_bitrate = mBitrate;
479 
480     sBitrateIp.u4_timestamp_high = -1;
481     sBitrateIp.u4_timestamp_low = -1;
482 
483     sBitrateIp.u4_size = sizeof(ive_ctl_set_bitrate_ip_t);
484     sBitrateOp.u4_size = sizeof(ive_ctl_set_bitrate_op_t);
485 
486     ive_api_function(mCodecCtx, &sBitrateIp, &sBitrateOp);
487     return;
488 }
489 
setFrameType(IV_PICTURE_CODING_TYPE_T eFrameType)490 void Codec::setFrameType(IV_PICTURE_CODING_TYPE_T eFrameType) {
491     ive_ctl_set_frame_type_ip_t sFrameTypeIp{};
492     ive_ctl_set_frame_type_op_t sFrameTypeOp{};
493 
494     sFrameTypeIp.e_cmd = IVE_CMD_VIDEO_CTL;
495     sFrameTypeIp.e_sub_cmd = IVE_CMD_CTL_SET_FRAMETYPE;
496     sFrameTypeIp.e_frame_type = eFrameType;
497 
498     sFrameTypeIp.u4_timestamp_high = -1;
499     sFrameTypeIp.u4_timestamp_low = -1;
500 
501     sFrameTypeIp.u4_size = sizeof(ive_ctl_set_frame_type_ip_t);
502     sFrameTypeOp.u4_size = sizeof(ive_ctl_set_frame_type_op_t);
503 
504     ive_api_function(mCodecCtx, &sFrameTypeIp, &sFrameTypeOp);
505     return;
506 }
507 
setQp()508 void Codec::setQp() {
509     ive_ctl_set_qp_ip_t s_QpIp{};
510     ive_ctl_set_qp_op_t s_QpOp{};
511 
512     s_QpIp.e_cmd = IVE_CMD_VIDEO_CTL;
513     s_QpIp.e_sub_cmd = IVE_CMD_CTL_SET_QP;
514 
515     s_QpIp.u4_i_qp = m_I_QP;
516     s_QpIp.u4_i_qp_max = MAX_H264_QP;
517     s_QpIp.u4_i_qp_min = kMinQP;
518 
519     s_QpIp.u4_p_qp = m_P_QP;
520     s_QpIp.u4_p_qp_max = MAX_H264_QP;
521     s_QpIp.u4_p_qp_min = kMinQP;
522 
523     s_QpIp.u4_b_qp = m_B_QP;
524     s_QpIp.u4_b_qp_max = MAX_H264_QP;
525     s_QpIp.u4_b_qp_min = kMinQP;
526 
527     s_QpIp.u4_timestamp_high = -1;
528     s_QpIp.u4_timestamp_low = -1;
529 
530     s_QpIp.u4_size = sizeof(ive_ctl_set_qp_ip_t);
531     s_QpOp.u4_size = sizeof(ive_ctl_set_qp_op_t);
532 
533     ive_api_function(mCodecCtx, &s_QpIp, &s_QpOp);
534     return;
535 }
536 
setEncMode(IVE_ENC_MODE_T eEncMode)537 void Codec::setEncMode(IVE_ENC_MODE_T eEncMode) {
538     ive_ctl_set_enc_mode_ip_t sEncModeIp{};
539     ive_ctl_set_enc_mode_op_t sEncModeOp{};
540 
541     sEncModeIp.e_cmd = IVE_CMD_VIDEO_CTL;
542     sEncModeIp.e_sub_cmd = IVE_CMD_CTL_SET_ENC_MODE;
543     sEncModeIp.e_enc_mode = eEncMode;
544 
545     sEncModeIp.u4_timestamp_high = -1;
546     sEncModeIp.u4_timestamp_low = -1;
547 
548     sEncModeIp.u4_size = sizeof(ive_ctl_set_enc_mode_ip_t);
549     sEncModeOp.u4_size = sizeof(ive_ctl_set_enc_mode_op_t);
550 
551     ive_api_function(mCodecCtx, &sEncModeIp, &sEncModeOp);
552     return;
553 }
554 
setVbvParams()555 void Codec::setVbvParams() {
556     ive_ctl_set_vbv_params_ip_t sVbvIp{};
557     ive_ctl_set_vbv_params_op_t sVbvOp{};
558 
559     sVbvIp.e_cmd = IVE_CMD_VIDEO_CTL;
560     sVbvIp.e_sub_cmd = IVE_CMD_CTL_SET_VBV_PARAMS;
561     sVbvIp.u4_vbv_buf_size = 0;
562     sVbvIp.u4_vbv_buffer_delay = 1000;
563 
564     sVbvIp.u4_timestamp_high = -1;
565     sVbvIp.u4_timestamp_low = -1;
566 
567     sVbvIp.u4_size = sizeof(ive_ctl_set_vbv_params_ip_t);
568     sVbvOp.u4_size = sizeof(ive_ctl_set_vbv_params_op_t);
569 
570     ive_api_function(mCodecCtx, &sVbvIp, &sVbvOp);
571     return;
572 }
573 
setAirParams()574 void Codec::setAirParams() {
575     ive_ctl_set_air_params_ip_t sAirIp{};
576     ive_ctl_set_air_params_op_t sAirOp{};
577 
578     sAirIp.e_cmd = IVE_CMD_VIDEO_CTL;
579     sAirIp.e_sub_cmd = IVE_CMD_CTL_SET_AIR_PARAMS;
580     sAirIp.e_air_mode = mAirMode;
581     sAirIp.u4_air_refresh_period = mIntraRefresh;
582 
583     sAirIp.u4_timestamp_high = -1;
584     sAirIp.u4_timestamp_low = -1;
585 
586     sAirIp.u4_size = sizeof(ive_ctl_set_air_params_ip_t);
587     sAirOp.u4_size = sizeof(ive_ctl_set_air_params_op_t);
588 
589     ive_api_function(mCodecCtx, &sAirIp, &sAirOp);
590     return;
591 }
592 
setMeParams()593 void Codec::setMeParams() {
594     ive_ctl_set_me_params_ip_t sMeParamsIp{};
595     ive_ctl_set_me_params_op_t sMeParamsOp{};
596 
597     sMeParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
598     sMeParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_ME_PARAMS;
599     sMeParamsIp.u4_enable_fast_sad = mEnableFastSad;
600     sMeParamsIp.u4_enable_alt_ref = mEnableAltRef;
601 
602     sMeParamsIp.u4_enable_hpel = mHalfPelEnable;
603     sMeParamsIp.u4_enable_qpel = mQPelEnable;
604     sMeParamsIp.u4_me_speed_preset = mMeSpeedPreset;
605     sMeParamsIp.u4_srch_rng_x = mSearchRangeX;
606     sMeParamsIp.u4_srch_rng_y = mSearchRangeY;
607 
608     sMeParamsIp.u4_timestamp_high = -1;
609     sMeParamsIp.u4_timestamp_low = -1;
610 
611     sMeParamsIp.u4_size = sizeof(ive_ctl_set_me_params_ip_t);
612     sMeParamsOp.u4_size = sizeof(ive_ctl_set_me_params_op_t);
613 
614     ive_api_function(mCodecCtx, &sMeParamsIp, &sMeParamsOp);
615     return;
616 }
617 
setGopParams()618 void Codec::setGopParams() {
619     ive_ctl_set_gop_params_ip_t sGopParamsIp{};
620     ive_ctl_set_gop_params_op_t sGopParamsOp{};
621 
622     sGopParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
623     sGopParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_GOP_PARAMS;
624 
625     sGopParamsIp.u4_i_frm_interval = mIInterval;
626     sGopParamsIp.u4_idr_frm_interval = mIDRInterval;
627 
628     sGopParamsIp.u4_timestamp_high = -1;
629     sGopParamsIp.u4_timestamp_low = -1;
630 
631     sGopParamsIp.u4_size = sizeof(ive_ctl_set_gop_params_ip_t);
632     sGopParamsOp.u4_size = sizeof(ive_ctl_set_gop_params_op_t);
633 
634     ive_api_function(mCodecCtx, &sGopParamsIp, &sGopParamsOp);
635     return;
636 }
637 
setProfileParams()638 void Codec::setProfileParams() {
639     ive_ctl_set_profile_params_ip_t sProfileParamsIp{};
640     ive_ctl_set_profile_params_op_t sProfileParamsOp{};
641 
642     sProfileParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
643     sProfileParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_PROFILE_PARAMS;
644 
645     sProfileParamsIp.e_profile = mProfile;
646     if (sProfileParamsIp.e_profile == IV_PROFILE_BASE) {
647         sProfileParamsIp.u4_entropy_coding_mode = 0;
648     } else {
649         sProfileParamsIp.u4_entropy_coding_mode = 1;
650     }
651     sProfileParamsIp.u4_timestamp_high = -1;
652     sProfileParamsIp.u4_timestamp_low = -1;
653 
654     sProfileParamsIp.u4_size = sizeof(ive_ctl_set_profile_params_ip_t);
655     sProfileParamsOp.u4_size = sizeof(ive_ctl_set_profile_params_op_t);
656 
657     ive_api_function(mCodecCtx, &sProfileParamsIp, &sProfileParamsOp);
658     return;
659 }
660 
setDeblockParams()661 void Codec::setDeblockParams() {
662     ive_ctl_set_deblock_params_ip_t sDeblockParamsIp{};
663     ive_ctl_set_deblock_params_op_t sDeblockParamsOp{};
664 
665     sDeblockParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
666     sDeblockParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_DEBLOCK_PARAMS;
667 
668     sDeblockParamsIp.u4_disable_deblock_level = mDisableDeblockLevel;
669 
670     sDeblockParamsIp.u4_timestamp_high = -1;
671     sDeblockParamsIp.u4_timestamp_low = -1;
672 
673     sDeblockParamsIp.u4_size = sizeof(ive_ctl_set_deblock_params_ip_t);
674     sDeblockParamsOp.u4_size = sizeof(ive_ctl_set_deblock_params_op_t);
675 
676     ive_api_function(mCodecCtx, &sDeblockParamsIp, &sDeblockParamsOp);
677     return;
678 }
679 
setVuiParams()680 void Codec::setVuiParams() {
681     ih264e_vui_ip_t sVuiParamsIp{};
682     ih264e_vui_op_t sVuiParamsOp{};
683 
684     sVuiParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
685     sVuiParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_VUI_PARAMS;
686 
687     sVuiParamsIp.u1_aspect_ratio_info_present_flag = mAspectRatioFlag;
688     sVuiParamsIp.u1_aspect_ratio_idc = 0;
689     sVuiParamsIp.u2_sar_width = 0;
690     sVuiParamsIp.u2_sar_height = 0;
691     sVuiParamsIp.u1_overscan_info_present_flag = 0;
692     sVuiParamsIp.u1_overscan_appropriate_flag = 0;
693     sVuiParamsIp.u1_video_signal_type_present_flag = 1;
694     sVuiParamsIp.u1_video_format = 0;
695     sVuiParamsIp.u1_video_full_range_flag = 0;
696     sVuiParamsIp.u1_colour_description_present_flag = 1;
697     sVuiParamsIp.u1_colour_primaries = 0;
698     sVuiParamsIp.u1_transfer_characteristics = 0;
699     sVuiParamsIp.u1_matrix_coefficients = 0;
700     sVuiParamsIp.u1_chroma_loc_info_present_flag = 0;
701     sVuiParamsIp.u1_chroma_sample_loc_type_top_field = 0;
702     sVuiParamsIp.u1_chroma_sample_loc_type_bottom_field = 0;
703     sVuiParamsIp.u1_vui_timing_info_present_flag = 0;
704     sVuiParamsIp.u4_vui_num_units_in_tick = 0;
705     sVuiParamsIp.u4_vui_time_scale = 0;
706     sVuiParamsIp.u1_fixed_frame_rate_flag = 0;
707     sVuiParamsIp.u1_nal_hrd_parameters_present_flag = mNalHrdFlag;
708     sVuiParamsIp.u1_vcl_hrd_parameters_present_flag = mVclHrdFlag;
709     sVuiParamsIp.u1_low_delay_hrd_flag = 0;
710     sVuiParamsIp.u1_pic_struct_present_flag = 0;
711     sVuiParamsIp.u1_bitstream_restriction_flag = 0;
712     sVuiParamsIp.u1_motion_vectors_over_pic_boundaries_flag = 0;
713     sVuiParamsIp.u1_max_bytes_per_pic_denom = 0;
714     sVuiParamsIp.u1_max_bits_per_mb_denom = 0;
715     sVuiParamsIp.u1_log2_max_mv_length_horizontal = 0;
716     sVuiParamsIp.u1_log2_max_mv_length_vertical = 0;
717     sVuiParamsIp.u1_num_reorder_frames = 0;
718     sVuiParamsIp.u1_max_dec_frame_buffering = 0;
719 
720     sVuiParamsIp.u4_size = sizeof(ih264e_vui_ip_t);
721     sVuiParamsOp.u4_size = sizeof(ih264e_vui_op_t);
722 
723     ive_api_function(mCodecCtx, &sVuiParamsIp, &sVuiParamsOp);
724     return;
725 }
726 
setSeiMdcvParams()727 void Codec::setSeiMdcvParams() {
728     ih264e_ctl_set_sei_mdcv_params_ip_t sSeiMdcvParamsIp{};
729     ih264e_ctl_set_sei_mdcv_params_op_t sSeiMdcvParamsOp{};
730 
731     sSeiMdcvParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
732     sSeiMdcvParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_MDCV_PARAMS;
733     sSeiMdcvParamsIp.u1_sei_mdcv_params_present_flag = mSeiMdcvFlag;
734     if (mSeiMdcvFlag) {
735         for (int i4_count = 0; i4_count < NUM_SEI_MDCV_PRIMARIES; ++i4_count) {
736             sSeiMdcvParamsIp.au2_display_primaries_x[i4_count] = 30000;
737             sSeiMdcvParamsIp.au2_display_primaries_y[i4_count] = 35000;
738         }
739         sSeiMdcvParamsIp.u2_white_point_x = 30000;
740         sSeiMdcvParamsIp.u2_white_point_y = 35000;
741         sSeiMdcvParamsIp.u4_max_display_mastering_luminance = 100000000;
742         sSeiMdcvParamsIp.u4_min_display_mastering_luminance = 50000;
743     }
744 
745     sSeiMdcvParamsIp.u4_timestamp_high = -1;
746     sSeiMdcvParamsIp.u4_timestamp_low = -1;
747 
748     sSeiMdcvParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_mdcv_params_ip_t);
749     sSeiMdcvParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_mdcv_params_op_t);
750     ih264e_api_function(mCodecCtx, &sSeiMdcvParamsIp, &sSeiMdcvParamsOp);
751     return;
752 }
753 
setSeiCllParams()754 void Codec::setSeiCllParams() {
755     ih264e_ctl_set_sei_cll_params_ip_t sSeiCllParamsIp{};
756     ih264e_ctl_set_sei_cll_params_op_t sSeiCllParamsOp{};
757 
758     sSeiCllParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
759     sSeiCllParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_CLL_PARAMS;
760     sSeiCllParamsIp.u1_sei_cll_params_present_flag = mSeiCllFlag;
761     if (mSeiCllFlag) {
762         sSeiCllParamsIp.u2_max_content_light_level = 0;
763         sSeiCllParamsIp.u2_max_pic_average_light_level = 0;
764     }
765 
766     sSeiCllParamsIp.u4_timestamp_high = -1;
767     sSeiCllParamsIp.u4_timestamp_low = -1;
768 
769     sSeiCllParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_cll_params_ip_t);
770     sSeiCllParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_cll_params_op_t);
771 
772     ih264e_api_function(mCodecCtx, &sSeiCllParamsIp, &sSeiCllParamsOp);
773     return;
774 }
775 
setSeiAveParams()776 void Codec::setSeiAveParams() {
777     ih264e_ctl_set_sei_ave_params_ip_t sSeiAveParamsIp{};
778     ih264e_ctl_set_sei_ave_params_op_t sSeiAveParamsOp{};
779 
780     sSeiAveParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
781     sSeiAveParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_AVE_PARAMS;
782     sSeiAveParamsIp.u1_sei_ave_params_present_flag = mSeiAveFlag;
783     if (mSeiAveFlag) {
784         sSeiAveParamsIp.u4_ambient_illuminance = 1;
785         sSeiAveParamsIp.u2_ambient_light_x = 0;
786         sSeiAveParamsIp.u2_ambient_light_y = 0;
787     }
788 
789     sSeiAveParamsIp.u4_timestamp_high = -1;
790     sSeiAveParamsIp.u4_timestamp_low = -1;
791 
792     sSeiAveParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_ave_params_ip_t);
793     sSeiAveParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_ave_params_op_t);
794 
795     ih264e_api_function(mCodecCtx, &sSeiAveParamsIp, &sSeiAveParamsOp);
796     return;
797 }
798 
setSeiCcvParams()799 void Codec::setSeiCcvParams() {
800     ih264e_ctl_set_sei_ccv_params_ip_t sSeiCcvParamsIp{};
801     ih264e_ctl_set_sei_ccv_params_op_t sSeiCcvParamsOp{};
802 
803     sSeiCcvParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
804     sSeiCcvParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_CCV_PARAMS;
805     sSeiCcvParamsIp.u1_sei_ccv_params_present_flag = mSeiCcvFlag;
806     if (mSeiCcvFlag) {
807         sSeiCcvParamsIp.u1_ccv_cancel_flag = 0;
808         sSeiCcvParamsIp.u1_ccv_persistence_flag = 1;
809         sSeiCcvParamsIp.u1_ccv_primaries_present_flag = 1;
810         sSeiCcvParamsIp.u1_ccv_min_luminance_value_present_flag = 1;
811         sSeiCcvParamsIp.u1_ccv_max_luminance_value_present_flag = 1;
812         sSeiCcvParamsIp.u1_ccv_avg_luminance_value_present_flag = 1;
813         sSeiCcvParamsIp.u1_ccv_reserved_zero_2bits = 0;
814         for (int i4_count = 0; i4_count < NUM_SEI_CCV_PRIMARIES; ++i4_count) {
815             sSeiCcvParamsIp.ai4_ccv_primaries_x[i4_count] = 1;
816             sSeiCcvParamsIp.ai4_ccv_primaries_y[i4_count] = 1;
817         }
818         sSeiCcvParamsIp.u4_ccv_min_luminance_value = 1;
819         sSeiCcvParamsIp.u4_ccv_max_luminance_value = 1;
820         sSeiCcvParamsIp.u4_ccv_avg_luminance_value = 1;
821     }
822 
823     sSeiCcvParamsIp.u4_timestamp_high = -1;
824     sSeiCcvParamsIp.u4_timestamp_low = -1;
825 
826     sSeiCcvParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_ccv_params_ip_t);
827     sSeiCcvParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_ccv_params_op_t);
828 
829     ih264e_api_function(mCodecCtx, &sSeiCcvParamsIp, &sSeiCcvParamsOp);
830     return;
831 }
832 
setSeiSiiParams()833 void Codec::setSeiSiiParams() {
834     ih264e_ctl_set_sei_sii_params_ip_t sSeiSiiParamsIp{};
835     ih264e_ctl_set_sei_sii_params_op_t sSeiSiiParamsOp{};
836 
837     sSeiSiiParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
838     sSeiSiiParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_SII_PARAMS;
839     sSeiSiiParamsIp.u1_shutter_interval_info_present_flag = mSeiSiiFlag;
840     if(mSeiSiiFlag) {
841         sSeiSiiParamsIp.u4_sii_sub_layer_idx = 0;
842         sSeiSiiParamsIp.u1_shutter_interval_info_present_flag = 1;
843         sSeiSiiParamsIp.u4_sii_time_scale = 24000000;
844         sSeiSiiParamsIp.u1_fixed_shutter_interval_within_cvs_flag = 0;
845         sSeiSiiParamsIp.u4_sii_num_units_in_shutter_interval = 480000;
846         sSeiSiiParamsIp.u1_sii_max_sub_layers_minus1 = 7;
847         for(int count = 0; count <= sSeiSiiParamsIp.u1_sii_max_sub_layers_minus1; ++count) {
848             sSeiSiiParamsIp.au4_sub_layer_num_units_in_shutter_interval[count] = 480000;
849         }
850         sSeiSiiParamsIp.au4_sub_layer_num_units_in_shutter_interval
851             [sSeiSiiParamsIp.u1_sii_max_sub_layers_minus1] = 240000;
852     }
853 
854     sSeiSiiParamsIp.u4_timestamp_high = -1;
855     sSeiSiiParamsIp.u4_timestamp_low = -1;
856 
857     sSeiSiiParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_sii_params_ip_t);
858     sSeiSiiParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_sii_params_op_t);
859 
860     ih264e_api_function(mCodecCtx, &sSeiSiiParamsIp, &sSeiSiiParamsOp);
861     return;
862 }
863 
logVersion()864 void Codec::logVersion() {
865     ive_ctl_getversioninfo_ip_t sCtlIp{};
866     ive_ctl_getversioninfo_op_t sCtlOp{};
867     UWORD8 au1Buf[512];
868 
869     sCtlIp.e_cmd = IVE_CMD_VIDEO_CTL;
870     sCtlIp.e_sub_cmd = IVE_CMD_CTL_GETVERSION;
871 
872     sCtlIp.u4_size = sizeof(ive_ctl_getversioninfo_ip_t);
873     sCtlOp.u4_size = sizeof(ive_ctl_getversioninfo_op_t);
874     sCtlIp.pu1_version = au1Buf;
875     sCtlIp.u4_version_bufsize = sizeof(au1Buf);
876 
877     ive_api_function(mCodecCtx, (void *)&sCtlIp, (void *)&sCtlOp);
878     return;
879 }
880 
encodeFrames(const uint8_t * data,size_t size)881 void Codec::encodeFrames(const uint8_t *data, size_t size) {
882     size_t frameSize = (mIvVideoColorFormat == IV_YUV_422ILE) ? (mWidth * mHeight * 2)
883                                                               : ((mWidth * mHeight * 3) / 2);
884     ive_video_encode_ip_t sEncodeIp{};
885     ive_video_encode_op_t sEncodeOp{};
886     uint8_t header[kHeaderLength];
887     int32_t numEncodeCalls = 0;
888     iv_raw_buf_t *psInpRawBuf = &sEncodeIp.s_inp_buf;
889     sEncodeIp.s_out_buf.pv_buf = header;
890     sEncodeIp.s_out_buf.u4_bytes = 0;
891     sEncodeIp.s_out_buf.u4_bufsize = kHeaderLength;
892     sEncodeIp.u4_size = sizeof(ive_video_encode_ip_t);
893     sEncodeOp.u4_size = sizeof(ive_video_encode_op_t);
894 
895     sEncodeIp.e_cmd = IVE_CMD_VIDEO_ENCODE;
896     sEncodeIp.pv_bufs = nullptr;
897     sEncodeIp.pv_mb_info = nullptr;
898     sEncodeIp.pv_pic_info = nullptr;
899     sEncodeIp.u4_mb_info_type = 0;
900     sEncodeIp.u4_pic_info_type = 0;
901     sEncodeOp.s_out_buf.pv_buf = nullptr;
902 
903     /* Initialize color formats */
904     memset(psInpRawBuf, 0, sizeof(iv_raw_buf_t));
905     psInpRawBuf->u4_size = sizeof(iv_raw_buf_t);
906     psInpRawBuf->e_color_fmt = mIvVideoColorFormat;
907 
908     ive_api_function(mCodecCtx, &sEncodeIp, &sEncodeOp);
909     size_t numFrame = 0;
910     std::vector<bufferPtrs> inBuffers;
911     uint64_t outputBufferSize = (frameSize / kCompressionRatio);
912     while (!sEncodeOp.u4_is_last && numEncodeCalls < kMaxNumEncodeCalls) {
913         uint8_t *outputBuffer = (uint8_t *)malloc(outputBufferSize);
914         sEncodeIp.s_out_buf.pv_buf = outputBuffer;
915         sEncodeIp.s_out_buf.u4_bufsize = outputBufferSize;
916         if (size > 0) {
917             uint8_t *tmpData = (uint8_t *)malloc(frameSize);
918             size_t bytesConsumed = std::min(size, frameSize);
919             if (bytesConsumed < frameSize) {
920                 memset(&tmpData[bytesConsumed], data[0], frameSize - bytesConsumed);
921             }
922             memcpy(tmpData, data, bytesConsumed);
923             bufferPtrs inBuffer = setEncParams(psInpRawBuf, tmpData, frameSize);
924             inBuffers.push_back(inBuffer);
925             free(tmpData);
926             sEncodeIp.u4_is_last = 0;
927             if (mSendEosWithLastFrame && size == bytesConsumed) {
928                 sEncodeIp.u4_is_last = 1;
929             }
930             if (mIsForceIdrEnabled) {
931                 if (numFrame == mForceIdrInterval) {
932                     setFrameType(IV_IDR_FRAME);
933                 }
934             }
935             if (mIsDynamicBitRateChangeEnabled) {
936                 if (numFrame == mDynamicBitRateInterval) {
937                     if (data[0] & 0x01) {
938                         mBitrate *= 2;
939                     } else {
940                         mBitrate /= 2;
941                     }
942                     setBitRate();
943                 }
944             }
945             if (mIsDynamicFrameRateChangeEnabled) {
946                 if (numFrame == mDynamicFrameRateInterval) {
947                     if (size > 1 && data[1] & 0x01) {
948                         mFrameRate *= 2;
949                     } else {
950                         mFrameRate /= 2;
951                     }
952                     setFrameRate();
953                 }
954             }
955             ++numFrame;
956             data += bytesConsumed;
957             size -= bytesConsumed;
958         } else {
959             sEncodeIp.u4_is_last = 1;
960             psInpRawBuf->apv_bufs[0] = nullptr;
961             psInpRawBuf->apv_bufs[1] = nullptr;
962             psInpRawBuf->apv_bufs[2] = nullptr;
963         }
964         ive_api_function(mCodecCtx, &sEncodeIp, &sEncodeOp);
965         if (sEncodeOp.s_inp_buf.apv_bufs[0]) {
966             std::vector<bufferPtrs>::iterator iter;
967             uint8_t *inputbuf = (uint8_t *)sEncodeOp.s_inp_buf.apv_bufs[0];
968             iter = std::find_if(
969                 inBuffers.begin(), inBuffers.end(),
970                 [=, &inputbuf](const bufferPtrs &buf) { return std::get<0>(buf) == inputbuf; });
971             if (iter != inBuffers.end()) {
972                 inBuffers.erase(iter);
973                 free(sEncodeOp.s_inp_buf.apv_bufs[0]);
974                 if (sEncodeOp.s_inp_buf.apv_bufs[1]) {
975                     free(sEncodeOp.s_inp_buf.apv_bufs[1]);
976                 }
977                 if (sEncodeOp.s_inp_buf.apv_bufs[2]) {
978                     free(sEncodeOp.s_inp_buf.apv_bufs[2]);
979                 }
980             }
981         }
982         ++numEncodeCalls;
983         free(outputBuffer);
984     }
985     for (const auto &buffer : inBuffers) {
986         free(std::get<0>(buffer));
987         if (std::get<1>(buffer)) {
988             free(std::get<1>(buffer));
989         }
990         if (std::get<2>(buffer)) {
991             free(std::get<2>(buffer));
992         }
993     }
994     inBuffers.clear();
995 }
996 
setEncParams(iv_raw_buf_t * psInpRawBuf,const uint8_t * data,size_t frameSize)997 bufferPtrs Codec::setEncParams(iv_raw_buf_t *psInpRawBuf, const uint8_t *data, size_t frameSize) {
998     bufferPtrs inBuffer;
999     switch (mIvVideoColorFormat) {
1000         case IV_YUV_420SP_UV:
1001             [[fallthrough]];
1002         case IV_YUV_420SP_VU: {
1003             uint8_t *yPlane = (uint8_t *)malloc(mWidth * mHeight);
1004             uint8_t *uPlane = (uint8_t *)malloc(frameSize - (mWidth * mHeight));
1005             memcpy(yPlane, data, mWidth * mHeight);
1006             memcpy(uPlane, data + (mWidth * mHeight), frameSize - (mWidth * mHeight));
1007             int32_t yStride = mWidth;
1008             int32_t uStride = mWidth / 2;
1009             psInpRawBuf->apv_bufs[0] = yPlane;
1010             psInpRawBuf->apv_bufs[1] = uPlane;
1011 
1012             psInpRawBuf->au4_wd[0] = mWidth;
1013             psInpRawBuf->au4_wd[1] = mWidth;
1014 
1015             psInpRawBuf->au4_ht[0] = mHeight;
1016             psInpRawBuf->au4_ht[1] = mHeight / 2;
1017 
1018             psInpRawBuf->au4_strd[0] = yStride;
1019             psInpRawBuf->au4_strd[1] = uStride;
1020             inBuffer = std::make_tuple(yPlane, uPlane, nullptr);
1021             break;
1022         }
1023         case IV_YUV_422ILE: {
1024             uint8_t *yPlane = (uint8_t *)malloc(frameSize);
1025             memcpy(yPlane, data, frameSize);
1026             psInpRawBuf->apv_bufs[0] = yPlane;
1027 
1028             psInpRawBuf->au4_wd[0] = mWidth * 2;
1029 
1030             psInpRawBuf->au4_ht[0] = mHeight;
1031 
1032             psInpRawBuf->au4_strd[0] = mWidth * 2;
1033             inBuffer = std::make_tuple(yPlane, nullptr, nullptr);
1034             break;
1035         }
1036         case IV_YUV_420P:
1037             [[fallthrough]];
1038         default: {
1039             uint8_t *yPlane = (uint8_t *)malloc(mWidth * mHeight);
1040             uint8_t *uPlane = (uint8_t *)malloc((mWidth * mHeight) / 4);
1041             uint8_t *vPlane = (uint8_t *)malloc(frameSize - ((mWidth * mHeight) * 5) / 4);
1042             memcpy(yPlane, data, mWidth * mHeight);
1043             memcpy(uPlane, data + (mWidth * mHeight), (mWidth * mHeight) / 4);
1044             memcpy(vPlane, data + ((mWidth * mHeight) * 5) / 4,
1045                    frameSize - ((mWidth * mHeight) * 5) / 4);
1046             int32_t yStride = mWidth;
1047             int32_t uStride = mWidth / 2;
1048             int32_t vStride = mWidth / 2;
1049 
1050             psInpRawBuf->apv_bufs[0] = yPlane;
1051             psInpRawBuf->apv_bufs[1] = uPlane;
1052             psInpRawBuf->apv_bufs[2] = vPlane;
1053 
1054             psInpRawBuf->au4_wd[0] = mWidth;
1055             psInpRawBuf->au4_wd[1] = mWidth / 2;
1056             psInpRawBuf->au4_wd[2] = mWidth / 2;
1057 
1058             psInpRawBuf->au4_ht[0] = mHeight;
1059             psInpRawBuf->au4_ht[1] = mHeight / 2;
1060             psInpRawBuf->au4_ht[2] = mHeight / 2;
1061 
1062             psInpRawBuf->au4_strd[0] = yStride;
1063             psInpRawBuf->au4_strd[1] = uStride;
1064             psInpRawBuf->au4_strd[2] = vStride;
1065             inBuffer = std::make_tuple(yPlane, uPlane, vPlane);
1066             break;
1067         }
1068     }
1069     return inBuffer;
1070 }
1071 
deInitEncoder()1072 void Codec::deInitEncoder() {
1073     iv_mem_rec_t *ps_mem_rec = mMemRecords;
1074     for (size_t i = 0; i < mNumMemRecords; ++i) {
1075         if (ps_mem_rec) {
1076             free(ps_mem_rec->pv_base);
1077         }
1078         ++ps_mem_rec;
1079     }
1080     if (mMemRecords) {
1081         free(mMemRecords);
1082     }
1083     mCodecCtx = nullptr;
1084     return;
1085 }
1086 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)1087 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
1088     if (size < IDX_LAST) {
1089         return 0;
1090     }
1091     Codec *codec = new Codec();
1092     if (codec->initEncoder(&data, &size)) {
1093         codec->encodeFrames(data, size);
1094     }
1095     delete codec;
1096     return 0;
1097 }
1098