xref: /aosp_15_r20/external/libavc/fuzzer/svc_enc_fuzzer.cpp (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
1 /******************************************************************************
2  *
3  * Copyright (C) 2020 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19  */
20 #include <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