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 <cmath>
21 #include <cstdlib>
22 #include <cstring>
23 #include <memory>
24 #include <numeric>
25 #include <utility>
26 #include <vector>
27
28 #include "ih264_typedefs.h"
29 #include "iv2.h"
30 #include "ive2.h"
31 #include "isvce.h"
32
33 constexpr WORD32 kMeSpeedPreset[] = {100};
34 constexpr WORD32 kDeblkLevel[] = {0, 2, 3, 4};
35 constexpr IVE_AIR_MODE_T kAirMode[] = {IVE_AIR_MODE_NONE};
36 constexpr IVE_SPEED_CONFIG kEncSpeed[] = {IVE_CONFIG, IVE_SLOWEST, IVE_NORMAL,
37 IVE_FAST, IVE_HIGH_SPEED, IVE_FASTEST};
38 constexpr IV_PROFILE_T kProfile[] = {IV_PROFILE_BASE, IV_PROFILE_MAIN};
39 constexpr IVE_RC_MODE_T kRCMode[] = {IVE_RC_NONE, IVE_RC_STORAGE, IVE_RC_CBR_NON_LOW_DELAY,
40 IVE_RC_CBR_LOW_DELAY};
41 constexpr IV_COLOR_FORMAT_T kSupportedColorFormats[] = {IV_YUV_420P, IV_YUV_420SP_UV};
42 constexpr WORD32 kSupportedLevels[] = {10, 9, 11, 12, 13, 20, 21, 22,
43 30, 31, 32, 40, 41, 42, 50, 51};
44 constexpr IVE_SLICE_MODE_T kSliceMode[] = {IVE_SLICE_MODE_NONE};
45 constexpr IV_ARCH_T kArchs[] = {
46 ARCH_ARM_NONEON, ARCH_ARM_A9Q, ARCH_ARM_A9A, ARCH_ARM_A9, ARCH_ARM_A7,
47 ARCH_ARM_A5, ARCH_ARM_A15, ARCH_ARM_NEONINTR, ARCH_X86_GENERIC, ARCH_X86_SSSE3,
48 ARCH_X86_SSE42, ARCH_ARM_A53, ARCH_ARM_A57, ARCH_ARM_V8_NEON};
49 constexpr DOUBLE kSpatialResRatio[] = {1.5, 2};
50 constexpr UWORD8 kSpatialLayers[] = {1, 2, 3};
51 constexpr UWORD8 kTemporalLayers[] = {1, 2, 3};
52 constexpr size_t kAirModeNum = std::size(kAirMode);
53 constexpr size_t kEncSpeedNum = std::size(kEncSpeed);
54 constexpr size_t kMeSpeedPresetNum = std::size(kMeSpeedPreset);
55 constexpr size_t kDeblkLevelNum = std::size(kDeblkLevel);
56 constexpr size_t kProfileNum = std::size(kProfile);
57 constexpr size_t kRCModeNum = std::size(kRCMode);
58 constexpr size_t kSupportedColorFormatsNum = std::size(kSupportedColorFormats);
59 constexpr size_t kSupportedLevelsNum = std::size(kSupportedLevels);
60 constexpr size_t kSliceModeNum = std::size(kSliceMode);
61 constexpr size_t kSpatialResRatioNum = std::size(kSpatialResRatio);
62 constexpr size_t kSpatialLayersNum = std::size(kSpatialLayers);
63 constexpr size_t kTemporalLayersNum = std::size(kTemporalLayers);
64 constexpr size_t kMinQP = 0;
65 constexpr size_t kMaxQP = 51;
66 constexpr size_t kMaxWidth = 2560;
67 constexpr size_t kMaxHeight = 2560;
68 constexpr size_t kMaxBitrate = 500000000;
69 constexpr UWORD8 kNumSeiMdcvPrimaries = 3;
70 constexpr UWORD8 kNumSeiCcvPrimaries = 3;
71 constexpr double kSvcCompliantDimProb = 0.75;
72 constexpr size_t kMaxEncodeCalls = 100;
73
74 typedef enum ARG_INDICES_T
75 {
76 IDX_WD_BYTE_1,
77 IDX_WD_BYTE_2,
78 IDX_HT_BYTE_1,
79 IDX_HT_BYTE_2,
80 IDX_COLOR_FORMAT,
81 IDX_ARCH_TYPE,
82 IDX_RC_MODE,
83 IDX_NUM_CORES,
84 IDX_NUM_ARCH,
85 IDX_NUM_B_FRAMES,
86 IDX_ENC_SPEED,
87 IDX_CONSTRAINED_INTRA_FLAG,
88 IDX_INTRA_4x4,
89 IDX_I_FRAME_QP,
90 IDX_P_FRAME_QP,
91 IDX_B_FRAME_QP,
92 IDX_BITRATE_BYTE_1,
93 IDX_BITRATE_BYTE_2,
94 IDX_FRAME_RATE,
95 IDX_INTRA_REFRESH,
96 IDX_ENABLE_HALF_PEL,
97 IDX_ENABLE_Q_PEL,
98 IDX_ME_SPEED_PRESET,
99 IDX_AIR_MODE,
100 IDX_DISABLE_DEBLOCK_LEVEL,
101 IDX_SEARCH_RANGE_X,
102 IDX_SEARCH_RANGE_Y,
103 IDX_I_INTERVAL,
104 IDX_IDR_INTERVAL,
105 IDX_SEI_MDCV_FLAG,
106 IDX_SEI_CLL_FLAG,
107 IDX_SEI_AVE_FLAG,
108 IDX_SEI_CCV_FLAG,
109 IDX_PROFILE,
110 IDX_ASPECT_RATIO_FLAG,
111 IDX_NAL_HRD_FLAG,
112 IDX_VCL_HRD_FLAG,
113 IDX_ENABLE_FORCE_IDR,
114 IDX_ENABLE_DYNAMIC_BITRATE,
115 IDX_ENABLE_DYNAMIC_FRAME_RATE,
116 IDX_FORCE_IDR_INTERVAL,
117 IDX_DYNAMIC_BITRATE_INTERVAL,
118 IDX_DYNAMIC_FRAME_RATE_INTERVAL,
119 IDX_ENC_LEVEL,
120 IDX_RECON_FMT,
121 IDX_SLICE_MODE,
122 IDX_ENABLE_FAST_SAD,
123 IDX_NUM_SPATIAL_LAYERS,
124 IDX_NUM_TEMPORAL_LAYERS,
125 IDX_SPATIAL_RES_RATIO,
126 IDX_SVC_COMPLIANT_DIMS,
127 IDX_ENABLE_RECON,
128 IDX_ENABLE_NALU_INFO_EXPORT,
129 IDX_LAST
130 } ARG_INDICES_T;
131
132 class Codec
133 {
134 public:
135 struct FrameDims
136 {
137 size_t mWidth;
138 size_t mHeight;
139
FrameDimsCodec::FrameDims140 FrameDims(size_t w, size_t h) : mWidth(w), mHeight(h) {}
FrameDimsCodec::FrameDims141 FrameDims(const std::pair<size_t, size_t> &dimPair)
142 : FrameDims(dimPair.first, dimPair.second)
143 {
144 }
FrameDimsCodec::FrameDims145 FrameDims(const FrameDims &other) : FrameDims(other.mWidth, other.mHeight) {}
146
operator =Codec::FrameDims147 void operator=(const FrameDims &other)
148 {
149 mWidth = other.mWidth;
150 mHeight = other.mHeight;
151 }
152
getFrameSizeCodec::FrameDims153 size_t getFrameSize() const { return (mWidth * mHeight * 3) / 2; };
154 };
155
156 struct EncBufs
157 {
158 std::vector<UWORD8> mInputBuf;
159 std::vector<UWORD8> mOutputBuf;
160 std::vector<UWORD8> mReconBuf;
161 std::vector<isvce_nalu_info_buf_t> mNaluInfoStructBuf;
162 std::vector<std::vector<UWORD8>> mNaluInfoDataBuf;
163 };
164
Codec()165 Codec()
166 : mCodecCtx(nullptr),
167 mMemRecords(),
168 mMemRecBufs(),
169 mEncBufs(),
170 mAirMode(IVE_AIR_MODE_NONE),
171 mEncSpeed(IVE_NORMAL),
172 mRCMode(IVE_RC_NONE),
173 mArch(ARCH_NA),
174 mSliceMode(IVE_SLICE_MODE_NONE),
175 mIvVideoColorFormat(IV_YUV_420P),
176 mProfile(IV_PROFILE_BASE),
177 mSvcCompDims{kMaxWidth, kMaxHeight},
178 mInputDims{kMaxWidth, kMaxHeight},
179 mHalfPelEnable(1),
180 mQPelEnable(1),
181 mIntra4x4(0),
182 mEnableFastSad(0),
183 mEnableAltRef(0),
184 mConstrainedIntraFlag(0),
185 mSeiCllFlag(1),
186 mSeiAveFlag(1),
187 mSeiCcvFlag(1),
188 mSeiMdcvFlag(1),
189 mAspectRatioFlag(0),
190 mNalHrdFlag(0),
191 mVclHrdFlag(0),
192 mIsForceIdrEnabled(false),
193 mIsDynamicBitRateChangeEnabled(false),
194 mIsDynamicFrameRateChangeEnabled(false),
195 mEnableRecon(false),
196 mEnableNaluInfoExport(false),
197 mAvcEncLevel(41),
198 mNumMemRecords(0),
199 mNumCores(1),
200 mBframes(0),
201 mSliceParam(256),
202 mMeSpeedPreset(100),
203 mIInterval(60),
204 mIDRInterval(60),
205 mDisableDeblockLevel(0),
206 m_I_QP(22),
207 m_P_QP(28),
208 m_B_QP(22),
209 mIntraRefresh(30),
210 mSearchRangeX(64),
211 mSearchRangeY(48),
212 mForceIdrInterval(0),
213 mDynamicBitRateInterval(0),
214 mDynamicFrameRateInterval(0),
215 mBitrate(6000000),
216 mFrameRate(30),
217 mNumSpatialLayers(1),
218 mNumTemporalLayers(1),
219 mSpatialResRatio(2)
220 {
221 }
222
~Codec()223 ~Codec() { delMemRecs(); };
224
225 bool initEncoder(const UWORD8 *data);
226 bool encodeFrames(const UWORD8 *data, size_t size);
227
228 private:
229 void setEncParams(iv_raw_buf_t *psInpRawBuf, std::vector<UWORD8> &buf, const FrameDims &dims,
230 IV_COLOR_FORMAT_T colorFormat = IV_YUV_420P);
231 void setFrameType(IV_PICTURE_CODING_TYPE_T eFrameType);
232 void setQp();
233 void setEncMode(IVE_ENC_MODE_T eEncMode);
234 void setDimensions();
235 void setNumCores();
236 void setFrameRate();
237 void setIpeParams();
238 void setBitRate();
239 void setAirParams();
240 void setMeParams();
241 void setGopParams();
242 void setProfileParams();
243 void setDeblockParams();
244 void setVbvParams();
245 void setDefault();
246 void setVuiParams();
247 void getBufInfo();
248 void setSeiMdcvParams();
249 void setSeiCllParams();
250 void setSeiAveParams();
251 void setSeiCcvParams();
252 void logVersion();
253 void initEncBufs();
254 bool initMemRecs();
255 void delMemRecs();
256
257 iv_obj_t *mCodecCtx;
258 std::vector<iv_mem_rec_t> mMemRecords;
259 std::vector<UWORD8 *> mMemRecBufs;
260 EncBufs mEncBufs;
261
262 IVE_AIR_MODE_T mAirMode;
263 IVE_SPEED_CONFIG mEncSpeed;
264 IVE_RC_MODE_T mRCMode;
265 IV_ARCH_T mArch;
266 IVE_SLICE_MODE_T mSliceMode;
267 IV_COLOR_FORMAT_T mIvVideoColorFormat;
268 IV_PROFILE_T mProfile;
269 FrameDims mSvcCompDims;
270 FrameDims mInputDims;
271
272 bool mHalfPelEnable;
273 bool mQPelEnable;
274 bool mIntra4x4;
275 bool mEnableFastSad;
276 bool mEnableAltRef;
277 bool mConstrainedIntraFlag;
278 bool mSeiCllFlag;
279 bool mSeiAveFlag;
280 bool mSeiCcvFlag;
281 bool mSeiMdcvFlag;
282 bool mAspectRatioFlag;
283 bool mNalHrdFlag;
284 bool mVclHrdFlag;
285 bool mIsForceIdrEnabled;
286 bool mIsDynamicBitRateChangeEnabled;
287 bool mIsDynamicFrameRateChangeEnabled;
288 bool mEnableRecon;
289 bool mEnableNaluInfoExport;
290 UWORD32 mAvcEncLevel;
291 UWORD32 mNumMemRecords;
292 UWORD32 mNumCores;
293 UWORD32 mBframes;
294 UWORD32 mSliceParam;
295 UWORD32 mMeSpeedPreset;
296 UWORD32 mIInterval;
297 UWORD32 mIDRInterval;
298 UWORD32 mDisableDeblockLevel;
299 UWORD32 m_I_QP;
300 UWORD32 m_P_QP;
301 UWORD32 m_B_QP;
302 UWORD32 mIntraRefresh;
303 UWORD32 mSearchRangeX;
304 UWORD32 mSearchRangeY;
305 /* Units - number of frames */
306 UWORD32 mForceIdrInterval;
307 /* Units - number of frames */
308 UWORD32 mDynamicBitRateInterval;
309 /* Units - number of frames */
310 UWORD32 mDynamicFrameRateInterval;
311 UWORD64 mBitrate;
312 DOUBLE mFrameRate;
313 UWORD8 mNumSpatialLayers;
314 UWORD8 mNumTemporalLayers;
315 DOUBLE mSpatialResRatio;
316 };
317
initEncBufs()318 void Codec::initEncBufs()
319 {
320 size_t frameSize = mInputDims.getFrameSize();
321 constexpr size_t minOutBufSize = 0x800;
322 size_t outBufSize = std::max(minOutBufSize, frameSize * mNumSpatialLayers);
323 size_t naluInfoBufSize = 460 * mNumSpatialLayers;
324
325 mEncBufs.mInputBuf.resize(frameSize);
326 mEncBufs.mOutputBuf.resize(outBufSize);
327
328 if(mEnableRecon)
329 {
330 mEncBufs.mReconBuf.resize(frameSize);
331 }
332
333 if(mEnableNaluInfoExport)
334 {
335 mEncBufs.mNaluInfoStructBuf.resize(mNumSpatialLayers * 2);
336 mEncBufs.mNaluInfoDataBuf.resize(mNumSpatialLayers);
337
338 for(auto i = 0; i < mNumSpatialLayers; i++)
339 {
340 mEncBufs.mNaluInfoDataBuf[i].resize(naluInfoBufSize);
341 }
342 }
343 }
344
initMemRecs()345 bool Codec::initMemRecs()
346 {
347 std::fill(mMemRecBufs.begin(), mMemRecBufs.end(), nullptr);
348
349 for(auto i = 0u; i < mNumMemRecords; i++)
350 {
351 mMemRecBufs[i] = reinterpret_cast<UWORD8 *>(
352 aligned_alloc(mMemRecords[i].u4_mem_alignment, mMemRecords[i].u4_mem_size));
353 mMemRecords[i].pv_base = mMemRecBufs[i];
354
355 if(nullptr == mMemRecBufs[i])
356 {
357 for(auto j = 0u; j < i; j++)
358 {
359 free(mMemRecBufs[j]);
360 }
361
362 return false;
363 }
364 }
365
366 return true;
367 }
368
delMemRecs()369 void Codec::delMemRecs()
370 {
371 for(auto i = 0u; i < mNumMemRecords; i++)
372 {
373 if(mMemRecBufs[i])
374 {
375 free(mMemRecBufs[i]);
376 }
377 }
378
379 std::fill(mMemRecBufs.begin(), mMemRecBufs.end(), nullptr);
380 }
381
initEncoder(const UWORD8 * data)382 bool Codec::initEncoder(const UWORD8 *data)
383 {
384 mInputDims = FrameDims{((data[IDX_WD_BYTE_1] << 8) | data[IDX_WD_BYTE_2]) % kMaxWidth,
385 ((data[IDX_HT_BYTE_1] << 8) | data[IDX_HT_BYTE_2]) % kMaxHeight};
386
387 mNumSpatialLayers = kSpatialLayers[data[IDX_NUM_SPATIAL_LAYERS] % kSpatialLayersNum];
388 mNumTemporalLayers = kTemporalLayers[data[IDX_NUM_TEMPORAL_LAYERS] % kTemporalLayersNum];
389 mSpatialResRatio = kSpatialResRatio[data[IDX_SPATIAL_RES_RATIO] % kSpatialResRatioNum];
390 bool useSvcCompliantDims =
391 data[IDX_SVC_COMPLIANT_DIMS] <
392 static_cast<UWORD8>(std::numeric_limits<UWORD8>::max() * kSvcCompliantDimProb);
393
394 if(useSvcCompliantDims)
395 {
396 auto getSvcCompliantDims = [&]() -> FrameDims
397 {
398 auto maxResRatio = pow(mSpatialResRatio, mNumSpatialLayers - 1);
399 UWORD32 dimPadding = 0;
400 UWORD32 numDecimalDigits = mNumSpatialLayers;
401 constexpr auto minDimGcd = 16;
402 UWORD32 decPtDelMultiplier = static_cast<UWORD32>(std::pow(10, numDecimalDigits));
403 FrameDims dims{mInputDims};
404
405 if(std::fmod(minDimGcd, maxResRatio))
406 {
407 dimPadding = std::lcm(minDimGcd * decPtDelMultiplier,
408 static_cast<UWORD32>(maxResRatio * decPtDelMultiplier)) /
409 decPtDelMultiplier;
410 }
411 else
412 {
413 dimPadding = static_cast<UWORD32>(minDimGcd * maxResRatio);
414 }
415
416 if(mInputDims.mWidth % dimPadding)
417 {
418 dims.mWidth = mInputDims.mWidth - ((mInputDims.mWidth) % dimPadding) + dimPadding;
419 }
420
421 if(mInputDims.mHeight % dimPadding)
422 {
423 dims.mHeight =
424 mInputDims.mHeight - ((mInputDims.mHeight) % dimPadding) + dimPadding;
425 }
426
427 return dims;
428 };
429
430 mSvcCompDims = getSvcCompliantDims();
431 mInputDims = mSvcCompDims;
432 }
433
434 mIvVideoColorFormat =
435 kSupportedColorFormats[data[IDX_COLOR_FORMAT] % kSupportedColorFormatsNum];
436 mArch = kArchs[data[IDX_ARCH_TYPE] % std::size(kArchs)];
437 mRCMode = kRCMode[data[IDX_RC_MODE] % kRCModeNum];
438 mNumCores = (data[IDX_NUM_CORES] & 0x07) + 1;
439 mBframes = 0;
440
441 mEncSpeed = kEncSpeed[data[IDX_ENC_SPEED] % kEncSpeedNum];
442 mConstrainedIntraFlag = data[IDX_CONSTRAINED_INTRA_FLAG] & 0x01;
443 mIntra4x4 = data[IDX_INTRA_4x4] & 0x01;
444 m_I_QP = data[IDX_I_FRAME_QP];
445 m_P_QP = data[IDX_P_FRAME_QP];
446 m_B_QP = data[IDX_B_FRAME_QP];
447 mBitrate = (((data[IDX_BITRATE_BYTE_1] << 8) | data[IDX_BITRATE_BYTE_2]) * 1000) % kMaxBitrate;
448 mFrameRate = data[IDX_FRAME_RATE] % 120;
449 mIntraRefresh = data[IDX_INTRA_REFRESH] + 1;
450 mHalfPelEnable = data[IDX_ENABLE_HALF_PEL] & 0x01;
451 mQPelEnable = data[IDX_ENABLE_Q_PEL] & 0x01;
452 mMeSpeedPreset = kMeSpeedPreset[data[IDX_ME_SPEED_PRESET] % kMeSpeedPresetNum];
453 mAirMode = kAirMode[data[IDX_AIR_MODE] % kAirModeNum];
454 mDisableDeblockLevel = kDeblkLevel[data[IDX_DISABLE_DEBLOCK_LEVEL] % kDeblkLevelNum];
455 mSearchRangeX = data[IDX_SEARCH_RANGE_X];
456 mSearchRangeY = data[IDX_SEARCH_RANGE_Y];
457 mIInterval = data[IDX_I_INTERVAL] + 1;
458 mIDRInterval = data[IDX_IDR_INTERVAL] + 1;
459 mSeiMdcvFlag = data[IDX_SEI_MDCV_FLAG] & 0x01;
460 mSeiCllFlag = data[IDX_SEI_CLL_FLAG] & 0x01;
461 mSeiAveFlag = data[IDX_SEI_AVE_FLAG] & 0x01;
462 mSeiCcvFlag = data[IDX_SEI_CCV_FLAG] & 0x01;
463 mProfile = kProfile[data[IDX_PROFILE] % kProfileNum];
464 mAspectRatioFlag = data[IDX_ASPECT_RATIO_FLAG] & 0x01;
465 mNalHrdFlag = data[IDX_NAL_HRD_FLAG] & 0x01;
466 mVclHrdFlag = data[IDX_VCL_HRD_FLAG] & 0x01;
467 mIsForceIdrEnabled = data[IDX_ENABLE_FORCE_IDR] & 0x01;
468 mIsDynamicBitRateChangeEnabled = data[IDX_ENABLE_DYNAMIC_BITRATE] & 0x01;
469 mIsDynamicFrameRateChangeEnabled = data[IDX_ENABLE_DYNAMIC_FRAME_RATE] & 0x01;
470 mForceIdrInterval = data[IDX_FORCE_IDR_INTERVAL] & 0x07;
471 mDynamicBitRateInterval = data[IDX_DYNAMIC_BITRATE_INTERVAL] & 0x07;
472 mDynamicFrameRateInterval = data[IDX_DYNAMIC_FRAME_RATE_INTERVAL] & 0x07;
473
474 mSliceParam = std::min(256u, static_cast<UWORD32>(mInputDims.mHeight >> 4));
475 mAvcEncLevel = kSupportedLevels[data[IDX_ENC_LEVEL] % kSupportedLevelsNum];
476 mSliceMode = kSliceMode[data[IDX_SLICE_MODE] % kSliceModeNum];
477 mEnableFastSad = data[IDX_ENABLE_FAST_SAD] & 0x01;
478
479 mEnableRecon = !!(data[IDX_ENABLE_RECON] & 1);
480 mEnableNaluInfoExport = !!(data[IDX_ENABLE_NALU_INFO_EXPORT] & 1);
481
482 isvce_num_mem_rec_ip_t s_num_mem_rec_ip{};
483 isvce_num_mem_rec_op_t s_num_mem_rec_op{};
484
485 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_GET_NUM_MEM_REC, ISVCE_CMD_CT_NA};
486
487 /* Getting Number of MemRecords */
488 s_num_mem_rec_ip.s_ive_ip.u4_size = sizeof(isvce_num_mem_rec_ip_t);
489 s_num_mem_rec_op.s_ive_op.u4_size = sizeof(isvce_num_mem_rec_op_t);
490
491 if(IV_SUCCESS != isvce_api_function(0, &s_num_mem_rec_ip, &s_num_mem_rec_op, &s_api_cmds))
492 {
493 return false;
494 }
495
496 mNumMemRecords = s_num_mem_rec_op.s_ive_op.u4_num_mem_rec;
497 mMemRecords.resize(mNumMemRecords);
498 mMemRecBufs.resize(mNumMemRecords);
499
500 for(auto i = 0u; i < mNumMemRecords; i++)
501 {
502 mMemRecords[i].u4_size = sizeof(iv_mem_rec_t);
503 mMemRecords[i].pv_base = nullptr;
504 mMemRecords[i].u4_mem_size = 0;
505 mMemRecords[i].u4_mem_alignment = 0;
506 mMemRecords[i].e_mem_type = IV_NA_MEM_TYPE;
507 }
508
509 isvce_fill_mem_rec_ip_t sFillMemRecIp{};
510 isvce_fill_mem_rec_op_t sFillMemRecOp{};
511
512 s_api_cmds = {ISVCE_CMD_FILL_NUM_MEM_REC, ISVCE_CMD_CT_NA};
513
514 sFillMemRecIp.s_ive_ip.u4_size = sizeof(isvce_fill_mem_rec_ip_t);
515 sFillMemRecOp.s_ive_op.u4_size = sizeof(isvce_fill_mem_rec_op_t);
516
517 sFillMemRecIp.s_ive_ip.ps_mem_rec = mMemRecords.data();
518 sFillMemRecIp.s_ive_ip.u4_num_mem_rec = mNumMemRecords;
519 sFillMemRecIp.s_ive_ip.u4_max_wd = mInputDims.mWidth;
520 sFillMemRecIp.s_ive_ip.u4_max_ht = mInputDims.mHeight;
521 sFillMemRecIp.u4_wd = mInputDims.mWidth;
522 sFillMemRecIp.u4_ht = mInputDims.mHeight;
523 sFillMemRecIp.s_ive_ip.u4_max_level = mAvcEncLevel;
524 sFillMemRecIp.s_ive_ip.e_color_format = mIvVideoColorFormat;
525 sFillMemRecIp.s_ive_ip.u4_max_ref_cnt = 2;
526 sFillMemRecIp.s_ive_ip.u4_max_reorder_cnt = 0;
527 sFillMemRecIp.s_ive_ip.u4_max_srch_rng_x = 256;
528 sFillMemRecIp.s_ive_ip.u4_max_srch_rng_y = 256;
529
530 sFillMemRecIp.s_svc_inp_params.u1_num_temporal_layers = mNumTemporalLayers;
531 sFillMemRecIp.s_svc_inp_params.u1_num_spatial_layers = mNumSpatialLayers;
532 sFillMemRecIp.s_svc_inp_params.d_spatial_res_ratio = mSpatialResRatio;
533
534 if(IV_SUCCESS != isvce_api_function(0, &sFillMemRecIp, &sFillMemRecOp, &s_api_cmds))
535 {
536 return false;
537 }
538
539 if(!initMemRecs())
540 {
541 return false;
542 }
543
544 /* Codec Instance Creation */
545 isvce_init_ip_t sInitIp{};
546 isvce_init_op_t sInitOp{};
547
548 std::vector<UWORD32> sMaxBitrates(mNumSpatialLayers, 240000000);
549
550 mCodecCtx = reinterpret_cast<iv_obj_t *>(mMemRecords[0].pv_base);
551 mCodecCtx->u4_size = sizeof(iv_obj_t);
552 mCodecCtx->pv_fxns = reinterpret_cast<void *>(isvce_api_function);
553
554 sInitIp.s_ive_ip.u4_size = sizeof(isvce_init_ip_t);
555 sInitOp.s_ive_op.u4_size = sizeof(isvce_init_op_t);
556
557 s_api_cmds = {ISVCE_CMD_INIT, ISVCE_CMD_CT_NA};
558
559 sInitIp.s_ive_ip.u4_num_mem_rec = mNumMemRecords;
560 sInitIp.s_ive_ip.ps_mem_rec = mMemRecords.data();
561 sInitIp.s_ive_ip.u4_max_wd = mInputDims.mWidth;
562 sInitIp.s_ive_ip.u4_max_ht = mInputDims.mHeight;
563 sInitIp.u4_wd = mInputDims.mWidth;
564 sInitIp.u4_ht = mInputDims.mHeight;
565
566 sInitIp.s_ive_ip.u4_max_ref_cnt = 2;
567 sInitIp.s_ive_ip.u4_max_reorder_cnt = 0;
568 sInitIp.s_ive_ip.u4_max_level = mAvcEncLevel;
569 sInitIp.s_ive_ip.e_inp_color_fmt = mIvVideoColorFormat;
570
571 sInitIp.s_ive_ip.u4_enable_recon = mEnableRecon;
572 sInitIp.s_ive_ip.e_recon_color_fmt = IV_YUV_420P;
573 sInitIp.b_nalu_info_export_enable = mEnableNaluInfoExport;
574 sInitIp.s_ive_ip.e_rc_mode = mRCMode;
575 sInitIp.s_ive_ip.u4_max_framerate = 120000;
576 sInitIp.pu4_max_bitrate = sMaxBitrates.data();
577 sInitIp.s_svc_inp_params.u1_num_temporal_layers = mNumTemporalLayers;
578 sInitIp.s_svc_inp_params.u1_num_spatial_layers = mNumSpatialLayers;
579 sInitIp.s_svc_inp_params.d_spatial_res_ratio = mSpatialResRatio;
580
581 sInitIp.s_ive_ip.u4_num_bframes = mBframes;
582 sInitIp.s_ive_ip.e_content_type = IV_PROGRESSIVE;
583 sInitIp.s_ive_ip.u4_max_srch_rng_x = 256;
584 sInitIp.s_ive_ip.u4_max_srch_rng_y = 256;
585 sInitIp.s_ive_ip.e_slice_mode = mSliceMode;
586 sInitIp.s_ive_ip.u4_slice_param = mSliceParam;
587 sInitIp.s_ive_ip.e_arch = mArch;
588 sInitIp.s_ive_ip.e_soc = SOC_GENERIC;
589 sInitIp.b_use_default_vui = true;
590
591 if(IV_SUCCESS != isvce_api_function(mCodecCtx, &sInitIp, &sInitOp, &s_api_cmds))
592 {
593 delMemRecs();
594
595 return false;
596 }
597
598 setDefault();
599 setNumCores();
600 logVersion();
601 getBufInfo();
602 setDimensions();
603 setFrameRate();
604 setIpeParams();
605 setBitRate();
606 setQp();
607 setAirParams();
608 setVbvParams();
609 setMeParams();
610 setGopParams();
611 setDeblockParams();
612 setProfileParams();
613 setEncMode(IVE_ENC_MODE_HEADER);
614 setVuiParams();
615 setSeiMdcvParams();
616 setSeiCllParams();
617 setSeiAveParams();
618 setSeiCcvParams();
619
620 initEncBufs();
621
622 return true;
623 }
624
setDimensions()625 void Codec::setDimensions()
626 {
627 isvce_ctl_set_dimensions_ip_t s_frame_dimensions_ip{};
628 isvce_ctl_set_dimensions_op_t s_frame_dimensions_op{};
629
630 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_DIMENSIONS};
631
632 s_frame_dimensions_ip.s_ive_ip.u4_ht = mInputDims.mHeight;
633 s_frame_dimensions_ip.s_ive_ip.u4_wd = mInputDims.mWidth;
634
635 s_frame_dimensions_ip.s_ive_ip.u4_timestamp_high = 0;
636 s_frame_dimensions_ip.s_ive_ip.u4_timestamp_low = 0;
637
638 s_frame_dimensions_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_set_dimensions_ip_t);
639 s_frame_dimensions_op.s_ive_op.u4_size = sizeof(isvce_ctl_set_dimensions_op_t);
640
641 isvce_api_function(mCodecCtx, &s_frame_dimensions_ip, &s_frame_dimensions_op, &s_api_cmds);
642 }
643
setNumCores()644 void Codec::setNumCores()
645 {
646 isvce_ctl_set_num_cores_ip_t sNumCoresIp{};
647 isvce_ctl_set_num_cores_op_t sNumCoresOp{};
648
649 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_NUM_CORES};
650
651 sNumCoresIp.s_ive_ip.u4_num_cores = mNumCores;
652
653 sNumCoresIp.s_ive_ip.u4_timestamp_high = 0;
654 sNumCoresIp.s_ive_ip.u4_timestamp_low = 0;
655
656 sNumCoresIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_num_cores_ip_t);
657 sNumCoresOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_num_cores_op_t);
658
659 isvce_api_function(mCodecCtx, (void *) &sNumCoresIp, (void *) &sNumCoresOp, &s_api_cmds);
660 }
661
setDefault()662 void Codec::setDefault()
663 {
664 isvce_ctl_setdefault_ip_t sDefaultIp{};
665 isvce_ctl_setdefault_op_t sDefaultOp{};
666
667 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SETDEFAULT};
668
669 sDefaultIp.s_ive_ip.u4_timestamp_high = 0;
670 sDefaultIp.s_ive_ip.u4_timestamp_low = 0;
671
672 sDefaultIp.s_ive_ip.u4_size = sizeof(isvce_ctl_setdefault_ip_t);
673 sDefaultOp.s_ive_op.u4_size = sizeof(isvce_ctl_setdefault_op_t);
674
675 isvce_api_function(mCodecCtx, &sDefaultIp, &sDefaultOp, &s_api_cmds);
676 }
677
getBufInfo()678 void Codec::getBufInfo()
679 {
680 isvce_ctl_getbufinfo_ip_t s_get_buf_info_ip{};
681 isvce_ctl_getbufinfo_op_t s_get_buf_info_op{};
682
683 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_GETBUFINFO};
684
685 s_get_buf_info_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_getbufinfo_ip_t);
686 s_get_buf_info_op.s_ive_op.u4_size = sizeof(isvce_ctl_getbufinfo_op_t);
687
688 s_get_buf_info_ip.s_ive_ip.u4_max_ht = mInputDims.mHeight;
689 s_get_buf_info_ip.s_ive_ip.u4_max_wd = mInputDims.mWidth;
690 s_get_buf_info_ip.s_ive_ip.e_inp_color_fmt = mIvVideoColorFormat;
691
692 isvce_api_function(mCodecCtx, &s_get_buf_info_ip, &s_get_buf_info_op, &s_api_cmds);
693 }
694
setFrameRate()695 void Codec::setFrameRate()
696 {
697 isvce_ctl_set_frame_rate_ip_t sFrameRateIp{};
698 isvce_ctl_set_frame_rate_op_t sFrameRateOp{};
699
700 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_FRAMERATE};
701
702 sFrameRateIp.s_ive_ip.u4_src_frame_rate = (UWORD32) mFrameRate;
703 sFrameRateIp.s_ive_ip.u4_tgt_frame_rate = (UWORD32) mFrameRate;
704
705 sFrameRateIp.s_ive_ip.u4_timestamp_high = 0;
706 sFrameRateIp.s_ive_ip.u4_timestamp_low = 0;
707
708 sFrameRateIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_frame_rate_ip_t);
709 sFrameRateOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_frame_rate_op_t);
710
711 isvce_api_function(mCodecCtx, &sFrameRateIp, &sFrameRateOp, &s_api_cmds);
712 }
713
setIpeParams()714 void Codec::setIpeParams()
715 {
716 isvce_ctl_set_ipe_params_ip_t sIpeParamsIp{};
717 isvce_ctl_set_ipe_params_op_t sIpeParamsOp{};
718
719 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_IPE_PARAMS};
720
721 sIpeParamsIp.s_ive_ip.u4_enable_intra_4x4 = mIntra4x4;
722 sIpeParamsIp.s_ive_ip.u4_enc_speed_preset = mEncSpeed;
723
724 sIpeParamsIp.s_ive_ip.u4_timestamp_high = 0;
725 sIpeParamsIp.s_ive_ip.u4_timestamp_low = 0;
726
727 sIpeParamsIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_ipe_params_ip_t);
728 sIpeParamsOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_ipe_params_op_t);
729
730 isvce_api_function(mCodecCtx, &sIpeParamsIp, &sIpeParamsOp, &s_api_cmds);
731 }
732
setBitRate()733 void Codec::setBitRate()
734 {
735 isvce_ctl_set_bitrate_ip_t sBitrateIp{};
736 isvce_ctl_set_bitrate_op_t sBitrateOp{};
737
738 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_BITRATE};
739 std::vector<UWORD32> sTargetBitrates(mNumSpatialLayers, mBitrate);
740
741 sBitrateIp.pu4_target_bitrate = sTargetBitrates.data();
742
743 sBitrateIp.s_ive_ip.u4_timestamp_high = 0;
744 sBitrateIp.s_ive_ip.u4_timestamp_low = 0;
745
746 sBitrateIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_bitrate_ip_t);
747 sBitrateOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_bitrate_op_t);
748
749 isvce_api_function(mCodecCtx, &sBitrateIp, &sBitrateOp, &s_api_cmds);
750 }
751
setFrameType(IV_PICTURE_CODING_TYPE_T eFrameType)752 void Codec::setFrameType(IV_PICTURE_CODING_TYPE_T eFrameType)
753 {
754 isvce_ctl_set_frame_type_ip_t sFrameTypeIp{};
755 isvce_ctl_set_frame_type_op_t sFrameTypeOp{};
756
757 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_FRAMETYPE};
758
759 sFrameTypeIp.s_ive_ip.e_frame_type = eFrameType;
760
761 sFrameTypeIp.s_ive_ip.u4_timestamp_high = 0;
762 sFrameTypeIp.s_ive_ip.u4_timestamp_low = 0;
763
764 sFrameTypeIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_frame_type_ip_t);
765 sFrameTypeOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_frame_type_op_t);
766
767 isvce_api_function(mCodecCtx, &sFrameTypeIp, &sFrameTypeOp, &s_api_cmds);
768 }
769
setQp()770 void Codec::setQp()
771 {
772 constexpr UWORD8 u1NumSliceTypes = 3;
773 isvce_ctl_set_qp_ip_t s_QpIp{};
774 isvce_ctl_set_qp_op_t s_QpOp{};
775
776 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_QP};
777 std::vector<UWORD32> sQps(u1NumSliceTypes * mNumSpatialLayers);
778 std::vector<UWORD32> sMinQps(u1NumSliceTypes * mNumSpatialLayers);
779 std::vector<UWORD32> sMaxQps(u1NumSliceTypes * mNumSpatialLayers);
780
781 s_QpIp.pu4_i_qp = sQps.data();
782 s_QpIp.pu4_i_qp_min = sMinQps.data();
783 s_QpIp.pu4_i_qp_max = sMaxQps.data();
784
785 s_QpIp.pu4_p_qp = sQps.data() + mNumSpatialLayers;
786 s_QpIp.pu4_p_qp_min = sMinQps.data() + mNumSpatialLayers;
787 s_QpIp.pu4_p_qp_max = sMaxQps.data() + mNumSpatialLayers;
788
789 s_QpIp.pu4_b_qp = sQps.data() + mNumSpatialLayers * 2;
790 s_QpIp.pu4_b_qp_min = sMinQps.data() + mNumSpatialLayers * 2;
791 s_QpIp.pu4_b_qp_max = sMaxQps.data() + mNumSpatialLayers * 2;
792
793 for(auto i = 0; i < mNumSpatialLayers; i++)
794 {
795 s_QpIp.pu4_i_qp[i] = m_I_QP;
796 s_QpIp.pu4_i_qp_max[i] = kMaxQP;
797 s_QpIp.pu4_i_qp_min[i] = kMinQP;
798
799 s_QpIp.pu4_p_qp[i] = m_P_QP;
800 s_QpIp.pu4_p_qp_max[i] = kMaxQP;
801 s_QpIp.pu4_p_qp_min[i] = kMinQP;
802
803 s_QpIp.pu4_b_qp[i] = m_B_QP;
804 s_QpIp.pu4_b_qp_max[i] = kMaxQP;
805 s_QpIp.pu4_b_qp_min[i] = kMinQP;
806 }
807
808 s_QpIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_qp_ip_t);
809 s_QpOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_qp_op_t);
810
811 isvce_api_function(mCodecCtx, &s_QpIp, &s_QpOp, &s_api_cmds);
812 }
813
setEncMode(IVE_ENC_MODE_T eEncMode)814 void Codec::setEncMode(IVE_ENC_MODE_T eEncMode)
815 {
816 isvce_ctl_set_enc_mode_ip_t sEncModeIp{};
817 isvce_ctl_set_enc_mode_op_t sEncModeOp{};
818
819 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_ENC_MODE};
820
821 sEncModeIp.s_ive_ip.e_enc_mode = eEncMode;
822
823 sEncModeIp.s_ive_ip.u4_timestamp_high = 0;
824 sEncModeIp.s_ive_ip.u4_timestamp_low = 0;
825
826 sEncModeIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_enc_mode_ip_t);
827 sEncModeOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_enc_mode_op_t);
828
829 isvce_api_function(mCodecCtx, &sEncModeIp, &sEncModeOp, &s_api_cmds);
830 }
831
setVbvParams()832 void Codec::setVbvParams()
833 {
834 isvce_ctl_set_vbv_params_ip_t sVbvIp{};
835 isvce_ctl_set_vbv_params_op_t sVbvOp{};
836
837 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_VBV_PARAMS};
838 std::vector<UWORD32> sBufferDelays(mNumSpatialLayers, 1000);
839
840 sVbvIp.pu4_vbv_buffer_delay = sBufferDelays.data();
841
842 sVbvIp.s_ive_ip.u4_timestamp_high = 0;
843 sVbvIp.s_ive_ip.u4_timestamp_low = 0;
844
845 sVbvIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_vbv_params_ip_t);
846 sVbvOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_vbv_params_op_t);
847
848 isvce_api_function(mCodecCtx, &sVbvIp, &sVbvOp, &s_api_cmds);
849 }
850
setAirParams()851 void Codec::setAirParams()
852 {
853 isvce_ctl_set_air_params_ip_t sAirIp{};
854 isvce_ctl_set_air_params_op_t sAirOp{};
855
856 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_AIR_PARAMS};
857
858 sAirIp.s_ive_ip.e_air_mode = mAirMode;
859 sAirIp.s_ive_ip.u4_air_refresh_period = mIntraRefresh;
860
861 sAirIp.s_ive_ip.u4_timestamp_high = 0;
862 sAirIp.s_ive_ip.u4_timestamp_low = 0;
863
864 sAirIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_air_params_ip_t);
865 sAirOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_air_params_op_t);
866
867 isvce_api_function(mCodecCtx, &sAirIp, &sAirOp, &s_api_cmds);
868 }
869
setMeParams()870 void Codec::setMeParams()
871 {
872 isvce_ctl_set_me_params_ip_t sMeParamsIp{};
873 isvce_ctl_set_me_params_op_t sMeParamsOp{};
874
875 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_ME_PARAMS};
876
877 sMeParamsIp.s_ive_ip.u4_enable_fast_sad = mEnableFastSad;
878 sMeParamsIp.s_ive_ip.u4_enable_alt_ref = mEnableAltRef;
879
880 sMeParamsIp.s_ive_ip.u4_enable_hpel = mHalfPelEnable;
881 sMeParamsIp.s_ive_ip.u4_enable_qpel = mQPelEnable;
882 sMeParamsIp.s_ive_ip.u4_me_speed_preset = mMeSpeedPreset;
883 sMeParamsIp.s_ive_ip.u4_srch_rng_x = mSearchRangeX;
884 sMeParamsIp.s_ive_ip.u4_srch_rng_y = mSearchRangeY;
885
886 sMeParamsIp.s_ive_ip.u4_timestamp_high = 0;
887 sMeParamsIp.s_ive_ip.u4_timestamp_low = 0;
888
889 sMeParamsIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_me_params_ip_t);
890 sMeParamsOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_me_params_op_t);
891
892 isvce_api_function(mCodecCtx, &sMeParamsIp, &sMeParamsOp, &s_api_cmds);
893 }
894
setGopParams()895 void Codec::setGopParams()
896 {
897 isvce_ctl_set_gop_params_ip_t sGopParamsIp{};
898 isvce_ctl_set_gop_params_op_t sGopParamsOp{};
899
900 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_GOP_PARAMS};
901
902 sGopParamsIp.s_ive_ip.u4_i_frm_interval = mIInterval;
903 sGopParamsIp.s_ive_ip.u4_idr_frm_interval = mIDRInterval;
904
905 sGopParamsIp.s_ive_ip.u4_timestamp_high = 0;
906 sGopParamsIp.s_ive_ip.u4_timestamp_low = 0;
907
908 sGopParamsIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_gop_params_ip_t);
909 sGopParamsOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_gop_params_op_t);
910
911 isvce_api_function(mCodecCtx, &sGopParamsIp, &sGopParamsOp, &s_api_cmds);
912 }
913
setProfileParams()914 void Codec::setProfileParams()
915 {
916 isvce_ctl_set_profile_params_ip_t sProfileParamsIp{};
917 isvce_ctl_set_profile_params_op_t sProfileParamsOp{};
918
919 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_PROFILE_PARAMS};
920
921 sProfileParamsIp.s_ive_ip.e_profile = mProfile;
922 if(sProfileParamsIp.s_ive_ip.e_profile == IV_PROFILE_BASE)
923 {
924 sProfileParamsIp.s_ive_ip.u4_entropy_coding_mode = 0;
925 }
926 else
927 {
928 sProfileParamsIp.s_ive_ip.u4_entropy_coding_mode = 1;
929 }
930
931 sProfileParamsIp.s_ive_ip.u4_timestamp_high = 0;
932 sProfileParamsIp.s_ive_ip.u4_timestamp_low = 0;
933
934 sProfileParamsIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_profile_params_ip_t);
935 sProfileParamsOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_profile_params_op_t);
936
937 isvce_api_function(mCodecCtx, &sProfileParamsIp, &sProfileParamsOp, &s_api_cmds);
938 }
939
setDeblockParams()940 void Codec::setDeblockParams()
941 {
942 isvce_ctl_set_deblock_params_ip_t sDeblockParamsIp{};
943 isvce_ctl_set_deblock_params_op_t sDeblockParamsOp{};
944
945 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_DEBLOCK_PARAMS};
946
947 sDeblockParamsIp.s_ive_ip.u4_disable_deblock_level = mDisableDeblockLevel;
948
949 sDeblockParamsIp.s_ive_ip.u4_timestamp_high = 0;
950 sDeblockParamsIp.s_ive_ip.u4_timestamp_low = 0;
951
952 sDeblockParamsIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_deblock_params_ip_t);
953 sDeblockParamsOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_deblock_params_op_t);
954
955 isvce_api_function(mCodecCtx, &sDeblockParamsIp, &sDeblockParamsOp, &s_api_cmds);
956 }
957
setVuiParams()958 void Codec::setVuiParams()
959 {
960 isvce_vui_ip_t sVuiParamsIp{};
961 isvce_vui_op_t sVuiParamsOp{};
962
963 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_VUI_PARAMS};
964
965 sVuiParamsIp.u1_aspect_ratio_info_present_flag = mAspectRatioFlag;
966 sVuiParamsIp.u1_aspect_ratio_idc = 0;
967 sVuiParamsIp.u2_sar_width = 0;
968 sVuiParamsIp.u2_sar_height = 0;
969 sVuiParamsIp.u1_overscan_info_present_flag = 0;
970 sVuiParamsIp.u1_overscan_appropriate_flag = 0;
971 sVuiParamsIp.u1_video_signal_type_present_flag = 1;
972 sVuiParamsIp.u1_video_format = 0;
973 sVuiParamsIp.u1_video_full_range_flag = 0;
974 sVuiParamsIp.u1_colour_description_present_flag = 0;
975 sVuiParamsIp.u1_colour_primaries = 0;
976 sVuiParamsIp.u1_transfer_characteristics = 0;
977 sVuiParamsIp.u1_matrix_coefficients = 0;
978 sVuiParamsIp.u1_chroma_loc_info_present_flag = 0;
979 sVuiParamsIp.u1_chroma_sample_loc_type_top_field = 0;
980 sVuiParamsIp.u1_chroma_sample_loc_type_bottom_field = 0;
981 sVuiParamsIp.u1_vui_timing_info_present_flag = 0;
982 sVuiParamsIp.u4_vui_num_units_in_tick = 0;
983 sVuiParamsIp.u4_vui_time_scale = 0;
984 sVuiParamsIp.u1_fixed_frame_rate_flag = 0;
985 sVuiParamsIp.u1_nal_hrd_parameters_present_flag = mNalHrdFlag;
986 sVuiParamsIp.u1_vcl_hrd_parameters_present_flag = mVclHrdFlag;
987 sVuiParamsIp.u1_low_delay_hrd_flag = 0;
988 sVuiParamsIp.u1_pic_struct_present_flag = 0;
989 sVuiParamsIp.u1_bitstream_restriction_flag = 0;
990 sVuiParamsIp.u1_motion_vectors_over_pic_boundaries_flag = 0;
991 sVuiParamsIp.u1_max_bytes_per_pic_denom = 0;
992 sVuiParamsIp.u1_max_bits_per_mb_denom = 0;
993 sVuiParamsIp.u1_log2_max_mv_length_horizontal = 0;
994 sVuiParamsIp.u1_log2_max_mv_length_vertical = 0;
995 sVuiParamsIp.u1_num_reorder_frames = 0;
996 sVuiParamsIp.u1_max_dec_frame_buffering = 0;
997
998 sVuiParamsIp.u4_size = sizeof(isvce_vui_ip_t);
999 sVuiParamsOp.u4_size = sizeof(isvce_vui_op_t);
1000
1001 isvce_api_function(mCodecCtx, &sVuiParamsIp, &sVuiParamsOp, &s_api_cmds);
1002 }
1003
setSeiMdcvParams()1004 void Codec::setSeiMdcvParams()
1005 {
1006 isvce_ctl_set_sei_mdcv_params_ip_t sSeiMdcvParamsIp{};
1007 isvce_ctl_set_sei_mdcv_params_op_t sSeiMdcvParamsOp{};
1008
1009 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_SEI_MDCV_PARAMS};
1010
1011 sSeiMdcvParamsIp.u1_sei_mdcv_params_present_flag = mSeiMdcvFlag;
1012 if(mSeiMdcvFlag)
1013 {
1014 for(int i4_count = 0; i4_count < kNumSeiMdcvPrimaries; ++i4_count)
1015 {
1016 sSeiMdcvParamsIp.au2_display_primaries_x[i4_count] = 30000;
1017 sSeiMdcvParamsIp.au2_display_primaries_y[i4_count] = 35000;
1018 }
1019 sSeiMdcvParamsIp.u2_white_point_x = 30000;
1020 sSeiMdcvParamsIp.u2_white_point_y = 35000;
1021 sSeiMdcvParamsIp.u4_max_display_mastering_luminance = 100000000;
1022 sSeiMdcvParamsIp.u4_min_display_mastering_luminance = 50000;
1023 }
1024
1025 sSeiMdcvParamsIp.u4_timestamp_high = 0;
1026 sSeiMdcvParamsIp.u4_timestamp_low = 0;
1027
1028 sSeiMdcvParamsIp.u4_size = sizeof(isvce_ctl_set_sei_mdcv_params_ip_t);
1029 sSeiMdcvParamsOp.u4_size = sizeof(isvce_ctl_set_sei_mdcv_params_op_t);
1030
1031 isvce_api_function(mCodecCtx, &sSeiMdcvParamsIp, &sSeiMdcvParamsOp, &s_api_cmds);
1032 }
1033
setSeiCllParams()1034 void Codec::setSeiCllParams()
1035 {
1036 isvce_ctl_set_sei_cll_params_ip_t sSeiCllParamsIp{};
1037 isvce_ctl_set_sei_cll_params_op_t sSeiCllParamsOp{};
1038
1039 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_SEI_CLL_PARAMS};
1040
1041 sSeiCllParamsIp.u1_sei_cll_params_present_flag = mSeiCllFlag;
1042
1043 if(mSeiCllFlag)
1044 {
1045 sSeiCllParamsIp.u2_max_content_light_level = 0;
1046 sSeiCllParamsIp.u2_max_pic_average_light_level = 0;
1047 }
1048
1049 sSeiCllParamsIp.u4_timestamp_high = 0;
1050 sSeiCllParamsIp.u4_timestamp_low = 0;
1051
1052 sSeiCllParamsIp.u4_size = sizeof(isvce_ctl_set_sei_cll_params_ip_t);
1053 sSeiCllParamsOp.u4_size = sizeof(isvce_ctl_set_sei_cll_params_op_t);
1054
1055 isvce_api_function(mCodecCtx, &sSeiCllParamsIp, &sSeiCllParamsOp, &s_api_cmds);
1056 }
1057
setSeiAveParams()1058 void Codec::setSeiAveParams()
1059 {
1060 isvce_ctl_set_sei_ave_params_ip_t sSeiAveParamsIp{};
1061 isvce_ctl_set_sei_ave_params_op_t sSeiAveParamsOp{};
1062
1063 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_SEI_AVE_PARAMS};
1064
1065 sSeiAveParamsIp.u1_sei_ave_params_present_flag = mSeiAveFlag;
1066
1067 if(mSeiAveFlag)
1068 {
1069 sSeiAveParamsIp.u4_ambient_illuminance = 1;
1070 sSeiAveParamsIp.u2_ambient_light_x = 0;
1071 sSeiAveParamsIp.u2_ambient_light_y = 0;
1072 }
1073
1074 sSeiAveParamsIp.u4_timestamp_high = 0;
1075 sSeiAveParamsIp.u4_timestamp_low = 0;
1076
1077 sSeiAveParamsIp.u4_size = sizeof(isvce_ctl_set_sei_ave_params_ip_t);
1078 sSeiAveParamsOp.u4_size = sizeof(isvce_ctl_set_sei_ave_params_op_t);
1079
1080 isvce_api_function(mCodecCtx, &sSeiAveParamsIp, &sSeiAveParamsOp, &s_api_cmds);
1081 }
1082
setSeiCcvParams()1083 void Codec::setSeiCcvParams()
1084 {
1085 isvce_ctl_set_sei_ccv_params_ip_t sSeiCcvParamsIp{};
1086 isvce_ctl_set_sei_ccv_params_op_t sSeiCcvParamsOp{};
1087
1088 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_SEI_CCV_PARAMS};
1089
1090 sSeiCcvParamsIp.u1_sei_ccv_params_present_flag = mSeiCcvFlag;
1091
1092 if(mSeiCcvFlag)
1093 {
1094 sSeiCcvParamsIp.u1_ccv_cancel_flag = 0;
1095 sSeiCcvParamsIp.u1_ccv_persistence_flag = 1;
1096 sSeiCcvParamsIp.u1_ccv_primaries_present_flag = 1;
1097 sSeiCcvParamsIp.u1_ccv_min_luminance_value_present_flag = 1;
1098 sSeiCcvParamsIp.u1_ccv_max_luminance_value_present_flag = 1;
1099 sSeiCcvParamsIp.u1_ccv_avg_luminance_value_present_flag = 1;
1100 sSeiCcvParamsIp.u1_ccv_reserved_zero_2bits = 0;
1101 for(int i4_count = 0; i4_count < kNumSeiCcvPrimaries; ++i4_count)
1102 {
1103 sSeiCcvParamsIp.ai4_ccv_primaries_x[i4_count] = 1;
1104 sSeiCcvParamsIp.ai4_ccv_primaries_y[i4_count] = 1;
1105 }
1106 sSeiCcvParamsIp.u4_ccv_min_luminance_value = 1;
1107 sSeiCcvParamsIp.u4_ccv_max_luminance_value = 1;
1108 sSeiCcvParamsIp.u4_ccv_avg_luminance_value = 1;
1109 }
1110
1111 sSeiCcvParamsIp.u4_timestamp_high = 0;
1112 sSeiCcvParamsIp.u4_timestamp_low = 0;
1113
1114 sSeiCcvParamsIp.u4_size = sizeof(isvce_ctl_set_sei_ccv_params_ip_t);
1115 sSeiCcvParamsOp.u4_size = sizeof(isvce_ctl_set_sei_ccv_params_op_t);
1116
1117 isvce_api_function(mCodecCtx, &sSeiCcvParamsIp, &sSeiCcvParamsOp, &s_api_cmds);
1118 }
1119
logVersion()1120 void Codec::logVersion()
1121 {
1122 isvce_ctl_getversioninfo_ip_t s_ctl_set_getversioninfo_ip{};
1123 isvce_ctl_getversioninfo_op_t s_ctl_set_getversioninfo_op{};
1124
1125 CHAR ac_version_string[512];
1126
1127 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_GETVERSION};
1128
1129 s_ctl_set_getversioninfo_ip.s_ive_ip.pu1_version = (UWORD8 *) ac_version_string;
1130 s_ctl_set_getversioninfo_ip.s_ive_ip.u4_version_bufsize = sizeof(ac_version_string);
1131 s_ctl_set_getversioninfo_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_getversioninfo_ip_t);
1132 s_ctl_set_getversioninfo_op.s_ive_op.u4_size = sizeof(isvce_ctl_getversioninfo_op_t);
1133
1134 isvce_api_function(mCodecCtx, (void *) &s_ctl_set_getversioninfo_ip,
1135 (void *) &s_ctl_set_getversioninfo_op, &s_api_cmds);
1136 }
1137
encodeFrames(const UWORD8 * data,size_t size)1138 bool Codec::encodeFrames(const UWORD8 *data, size_t size)
1139 {
1140 isvce_video_encode_ip_t sEncodeIp{};
1141 isvce_video_encode_op_t sEncodeOp{};
1142
1143 isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_ENCODE, ISVCE_CMD_CT_NA};
1144 iv_raw_buf_t *psInpRawBuf = &sEncodeIp.s_ive_ip.s_inp_buf;
1145 iv_raw_buf_t *psRecRawBuf = &sEncodeIp.s_ive_ip.s_recon_buf;
1146
1147 size_t frameSize = mInputDims.getFrameSize();
1148 auto bytesLeft = std::min(size, frameSize);
1149 auto bytesConsumed = 0;
1150 UWORD32 numFrames = 0;
1151
1152 sEncodeIp.s_ive_ip.s_out_buf.pv_buf = mEncBufs.mOutputBuf.data();
1153 sEncodeIp.s_ive_ip.s_out_buf.u4_bytes = 0;
1154 sEncodeIp.s_ive_ip.s_out_buf.u4_bufsize = static_cast<UWORD32>(mEncBufs.mOutputBuf.size());
1155 sEncodeOp.s_ive_op.s_out_buf.pv_buf = nullptr;
1156 sEncodeIp.s_ive_ip.pv_bufs = nullptr;
1157 sEncodeIp.s_ive_ip.pv_mb_info = nullptr;
1158 sEncodeIp.s_ive_ip.pv_pic_info = nullptr;
1159 sEncodeIp.s_ive_ip.u4_mb_info_type = 0;
1160 sEncodeIp.s_ive_ip.u4_pic_info_type = 0;
1161 sEncodeIp.s_ive_ip.u4_is_last = 0;
1162
1163 sEncodeIp.s_ive_ip.u4_timestamp_high = 0;
1164 sEncodeIp.s_ive_ip.u4_timestamp_low = 0;
1165
1166 memset(psInpRawBuf, 0, sizeof(iv_raw_buf_t));
1167 psInpRawBuf->u4_size = sizeof(iv_raw_buf_t);
1168 psInpRawBuf->e_color_fmt = mIvVideoColorFormat;
1169
1170 sEncodeIp.s_ive_ip.u4_size = sizeof(isvce_video_encode_ip_t);
1171 sEncodeOp.s_ive_op.u4_size = sizeof(isvce_video_encode_op_t);
1172
1173 isvce_api_function(mCodecCtx, &sEncodeIp, &sEncodeOp, &s_api_cmds);
1174
1175 if(mEnableNaluInfoExport)
1176 {
1177 sEncodeIp.ps_nalu_info_buf = mEncBufs.mNaluInfoStructBuf.data();
1178 sEncodeOp.ps_nalu_info_buf = mEncBufs.mNaluInfoStructBuf.data() + mNumSpatialLayers;
1179 }
1180
1181 while(!sEncodeOp.s_ive_op.u4_is_last && (kMaxEncodeCalls > (mNumSpatialLayers * numFrames)))
1182 {
1183 if(mEnableRecon)
1184 {
1185 setEncParams(psRecRawBuf, mEncBufs.mReconBuf, mInputDims);
1186 }
1187
1188 if(mEnableNaluInfoExport)
1189 {
1190 for(auto i = 0; i < mNumSpatialLayers; i++)
1191 {
1192 sEncodeIp.ps_nalu_info_buf[i].pu1_buf = mEncBufs.mNaluInfoDataBuf[i].data();
1193 sEncodeIp.ps_nalu_info_buf[i].u4_num_bytes = 0;
1194 sEncodeIp.ps_nalu_info_buf[i].u4_buf_size =
1195 static_cast<UWORD32>(mEncBufs.mNaluInfoDataBuf[i].size());
1196 }
1197 }
1198
1199 if(size > 0)
1200 {
1201 bytesLeft = std::min(size, frameSize);
1202 std::copy(data, data + bytesLeft, mEncBufs.mInputBuf.begin());
1203 std::fill(std::next(mEncBufs.mInputBuf.begin(), bytesLeft), mEncBufs.mInputBuf.end(),
1204 data[0]);
1205 setEncParams(psInpRawBuf, mEncBufs.mInputBuf, mInputDims, mIvVideoColorFormat);
1206
1207 bytesConsumed = bytesLeft;
1208 }
1209 else
1210 {
1211 sEncodeIp.s_ive_ip.u4_is_last = 1;
1212
1213 for(auto i = 0; i < 3; i++)
1214 {
1215 psInpRawBuf->apv_bufs[i] = nullptr;
1216 }
1217
1218 bytesConsumed = 0;
1219 }
1220
1221 if(mIsForceIdrEnabled && !sEncodeIp.s_ive_ip.u4_is_last)
1222 {
1223 if(numFrames == mForceIdrInterval)
1224 {
1225 setFrameType(IV_IDR_FRAME);
1226 }
1227 }
1228
1229 if(mIsDynamicBitRateChangeEnabled && !sEncodeIp.s_ive_ip.u4_is_last)
1230 {
1231 if(numFrames == mDynamicBitRateInterval)
1232 {
1233 if(data[0] & 0x01)
1234 {
1235 mBitrate *= 2;
1236 }
1237 else
1238 {
1239 mBitrate /= 2;
1240 }
1241
1242 setBitRate();
1243 }
1244 }
1245
1246 if(mIsDynamicFrameRateChangeEnabled && !sEncodeIp.s_ive_ip.u4_is_last)
1247 {
1248 if(numFrames == mDynamicFrameRateInterval)
1249 {
1250 if(size > 1 && data[1] & 0x01)
1251 {
1252 mFrameRate *= 2;
1253 }
1254 else
1255 {
1256 mFrameRate /= 2;
1257 }
1258
1259 setFrameRate();
1260 }
1261 }
1262
1263 isvce_api_function(mCodecCtx, &sEncodeIp, &sEncodeOp, &s_api_cmds);
1264
1265 if(!sEncodeOp.s_ive_op.u4_is_last)
1266 {
1267 numFrames++;
1268 data += bytesConsumed;
1269 size -= bytesConsumed;
1270 }
1271 }
1272
1273 return true;
1274 }
1275
setEncParams(iv_raw_buf_t * psInpRawBuf,std::vector<UWORD8> & buf,const FrameDims & dims,IV_COLOR_FORMAT_T colorFormat)1276 void Codec::setEncParams(iv_raw_buf_t *psInpRawBuf, std::vector<UWORD8> &buf, const FrameDims &dims,
1277 IV_COLOR_FORMAT_T colorFormat)
1278 {
1279 switch(colorFormat)
1280 {
1281 case IV_YUV_420SP_UV:
1282 case IV_YUV_420SP_VU:
1283 {
1284 WORD32 yStride = dims.mWidth;
1285 WORD32 uStride = dims.mWidth / 2;
1286
1287 psInpRawBuf->apv_bufs[0] = buf.data();
1288 psInpRawBuf->apv_bufs[1] = buf.data() + dims.mWidth * dims.mHeight;
1289
1290 psInpRawBuf->au4_wd[0] = dims.mWidth;
1291 psInpRawBuf->au4_wd[1] = dims.mWidth;
1292
1293 psInpRawBuf->au4_ht[0] = dims.mHeight;
1294 psInpRawBuf->au4_ht[1] = dims.mHeight / 2;
1295
1296 psInpRawBuf->au4_strd[0] = yStride;
1297 psInpRawBuf->au4_strd[1] = uStride;
1298
1299 break;
1300 }
1301 default:
1302 {
1303 WORD32 yStride = dims.mWidth;
1304 WORD32 uStride = dims.mWidth / 2;
1305 WORD32 vStride = dims.mWidth / 2;
1306
1307 psInpRawBuf->apv_bufs[0] = buf.data();
1308 psInpRawBuf->apv_bufs[1] = buf.data() + dims.mWidth * dims.mHeight;
1309 psInpRawBuf->apv_bufs[2] = buf.data() + (dims.mWidth * dims.mHeight * 5) / 4;
1310
1311 psInpRawBuf->au4_wd[0] = dims.mWidth;
1312 psInpRawBuf->au4_wd[1] = dims.mWidth / 2;
1313 psInpRawBuf->au4_wd[2] = dims.mWidth / 2;
1314
1315 psInpRawBuf->au4_ht[0] = dims.mHeight;
1316 psInpRawBuf->au4_ht[1] = dims.mHeight / 2;
1317 psInpRawBuf->au4_ht[2] = dims.mHeight / 2;
1318
1319 psInpRawBuf->au4_strd[0] = yStride;
1320 psInpRawBuf->au4_strd[1] = uStride;
1321 psInpRawBuf->au4_strd[2] = vStride;
1322
1323 break;
1324 }
1325 }
1326 }
1327
LLVMFuzzerTestOneInput(const UWORD8 * data,size_t size)1328 extern "C" int LLVMFuzzerTestOneInput(const UWORD8 *data, size_t size)
1329 {
1330 if(size < IDX_LAST)
1331 {
1332 return 0;
1333 }
1334
1335 std::unique_ptr<Codec> codec = std::make_unique<Codec>();
1336
1337 if(codec->initEncoder(data))
1338 {
1339 codec->encodeFrames(data, size);
1340 }
1341
1342 return 0;
1343 }
1344