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