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