unplugged-system/external/libavc/fuzzer/svc_enc_fuzzer.cpp

1344 lines
45 KiB
C++

/******************************************************************************
*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <numeric>
#include <utility>
#include <vector>
#include "ih264_typedefs.h"
#include "iv2.h"
#include "ive2.h"
#include "isvce.h"
constexpr WORD32 kMeSpeedPreset[] = {100};
constexpr WORD32 kDeblkLevel[] = {0, 2, 3, 4};
constexpr IVE_AIR_MODE_T kAirMode[] = {IVE_AIR_MODE_NONE};
constexpr IVE_SPEED_CONFIG kEncSpeed[] = {IVE_CONFIG, IVE_SLOWEST, IVE_NORMAL,
IVE_FAST, IVE_HIGH_SPEED, IVE_FASTEST};
constexpr IV_PROFILE_T kProfile[] = {IV_PROFILE_BASE, IV_PROFILE_MAIN};
constexpr IVE_RC_MODE_T kRCMode[] = {IVE_RC_NONE, IVE_RC_STORAGE, IVE_RC_CBR_NON_LOW_DELAY,
IVE_RC_CBR_LOW_DELAY};
constexpr IV_COLOR_FORMAT_T kSupportedColorFormats[] = {IV_YUV_420P, IV_YUV_420SP_UV};
constexpr WORD32 kSupportedLevels[] = {10, 9, 11, 12, 13, 20, 21, 22,
30, 31, 32, 40, 41, 42, 50, 51};
constexpr IVE_SLICE_MODE_T kSliceMode[] = {IVE_SLICE_MODE_NONE};
constexpr IV_ARCH_T kArchs[] = {
ARCH_ARM_NONEON, ARCH_ARM_A9Q, ARCH_ARM_A9A, ARCH_ARM_A9, ARCH_ARM_A7,
ARCH_ARM_A5, ARCH_ARM_A15, ARCH_ARM_NEONINTR, ARCH_X86_GENERIC, ARCH_X86_SSSE3,
ARCH_X86_SSE42, ARCH_ARM_A53, ARCH_ARM_A57, ARCH_ARM_V8_NEON};
constexpr DOUBLE kSpatialResRatio[] = {1.5, 2};
constexpr UWORD8 kSpatialLayers[] = {1, 2, 3};
constexpr UWORD8 kTemporalLayers[] = {1, 2, 3};
constexpr size_t kAirModeNum = std::size(kAirMode);
constexpr size_t kEncSpeedNum = std::size(kEncSpeed);
constexpr size_t kMeSpeedPresetNum = std::size(kMeSpeedPreset);
constexpr size_t kDeblkLevelNum = std::size(kDeblkLevel);
constexpr size_t kProfileNum = std::size(kProfile);
constexpr size_t kRCModeNum = std::size(kRCMode);
constexpr size_t kSupportedColorFormatsNum = std::size(kSupportedColorFormats);
constexpr size_t kSupportedLevelsNum = std::size(kSupportedLevels);
constexpr size_t kSliceModeNum = std::size(kSliceMode);
constexpr size_t kSpatialResRatioNum = std::size(kSpatialResRatio);
constexpr size_t kSpatialLayersNum = std::size(kSpatialLayers);
constexpr size_t kTemporalLayersNum = std::size(kTemporalLayers);
constexpr size_t kMinQP = 0;
constexpr size_t kMaxQP = 51;
constexpr size_t kMaxWidth = 2560;
constexpr size_t kMaxHeight = 2560;
constexpr size_t kMaxBitrate = 500000000;
constexpr UWORD8 kNumSeiMdcvPrimaries = 3;
constexpr UWORD8 kNumSeiCcvPrimaries = 3;
constexpr double kSvcCompliantDimProb = 0.75;
constexpr size_t kMaxEncodeCalls = 100;
typedef enum ARG_INDICES_T
{
IDX_WD_BYTE_1,
IDX_WD_BYTE_2,
IDX_HT_BYTE_1,
IDX_HT_BYTE_2,
IDX_COLOR_FORMAT,
IDX_ARCH_TYPE,
IDX_RC_MODE,
IDX_NUM_CORES,
IDX_NUM_ARCH,
IDX_NUM_B_FRAMES,
IDX_ENC_SPEED,
IDX_CONSTRAINED_INTRA_FLAG,
IDX_INTRA_4x4,
IDX_I_FRAME_QP,
IDX_P_FRAME_QP,
IDX_B_FRAME_QP,
IDX_BITRATE_BYTE_1,
IDX_BITRATE_BYTE_2,
IDX_FRAME_RATE,
IDX_INTRA_REFRESH,
IDX_ENABLE_HALF_PEL,
IDX_ENABLE_Q_PEL,
IDX_ME_SPEED_PRESET,
IDX_AIR_MODE,
IDX_DISABLE_DEBLOCK_LEVEL,
IDX_SEARCH_RANGE_X,
IDX_SEARCH_RANGE_Y,
IDX_I_INTERVAL,
IDX_IDR_INTERVAL,
IDX_SEI_MDCV_FLAG,
IDX_SEI_CLL_FLAG,
IDX_SEI_AVE_FLAG,
IDX_SEI_CCV_FLAG,
IDX_PROFILE,
IDX_ASPECT_RATIO_FLAG,
IDX_NAL_HRD_FLAG,
IDX_VCL_HRD_FLAG,
IDX_ENABLE_FORCE_IDR,
IDX_ENABLE_DYNAMIC_BITRATE,
IDX_ENABLE_DYNAMIC_FRAME_RATE,
IDX_FORCE_IDR_INTERVAL,
IDX_DYNAMIC_BITRATE_INTERVAL,
IDX_DYNAMIC_FRAME_RATE_INTERVAL,
IDX_ENC_LEVEL,
IDX_RECON_FMT,
IDX_SLICE_MODE,
IDX_ENABLE_FAST_SAD,
IDX_NUM_SPATIAL_LAYERS,
IDX_NUM_TEMPORAL_LAYERS,
IDX_SPATIAL_RES_RATIO,
IDX_SVC_COMPLIANT_DIMS,
IDX_ENABLE_RECON,
IDX_ENABLE_NALU_INFO_EXPORT,
IDX_LAST
} ARG_INDICES_T;
class Codec
{
public:
struct FrameDims
{
size_t mWidth;
size_t mHeight;
FrameDims(size_t w, size_t h) : mWidth(w), mHeight(h) {}
FrameDims(const std::pair<size_t, size_t> &dimPair)
: FrameDims(dimPair.first, dimPair.second)
{
}
FrameDims(const FrameDims &other) : FrameDims(other.mWidth, other.mHeight) {}
void operator=(const FrameDims &other)
{
mWidth = other.mWidth;
mHeight = other.mHeight;
}
size_t getFrameSize() const { return (mWidth * mHeight * 3) / 2; };
};
struct EncBufs
{
std::vector<UWORD8> mInputBuf;
std::vector<UWORD8> mOutputBuf;
std::vector<UWORD8> mReconBuf;
std::vector<isvce_nalu_info_buf_t> mNaluInfoStructBuf;
std::vector<std::vector<UWORD8>> mNaluInfoDataBuf;
};
Codec()
: mCodecCtx(nullptr),
mMemRecords(),
mMemRecBufs(),
mEncBufs(),
mAirMode(IVE_AIR_MODE_NONE),
mEncSpeed(IVE_NORMAL),
mRCMode(IVE_RC_NONE),
mArch(ARCH_NA),
mSliceMode(IVE_SLICE_MODE_NONE),
mIvVideoColorFormat(IV_YUV_420P),
mProfile(IV_PROFILE_BASE),
mSvcCompDims{kMaxWidth, kMaxHeight},
mInputDims{kMaxWidth, kMaxHeight},
mHalfPelEnable(1),
mQPelEnable(1),
mIntra4x4(0),
mEnableFastSad(0),
mEnableAltRef(0),
mConstrainedIntraFlag(0),
mSeiCllFlag(1),
mSeiAveFlag(1),
mSeiCcvFlag(1),
mSeiMdcvFlag(1),
mAspectRatioFlag(0),
mNalHrdFlag(0),
mVclHrdFlag(0),
mIsForceIdrEnabled(false),
mIsDynamicBitRateChangeEnabled(false),
mIsDynamicFrameRateChangeEnabled(false),
mEnableRecon(false),
mEnableNaluInfoExport(false),
mAvcEncLevel(41),
mNumMemRecords(0),
mNumCores(1),
mBframes(0),
mSliceParam(256),
mMeSpeedPreset(100),
mIInterval(60),
mIDRInterval(60),
mDisableDeblockLevel(0),
m_I_QP(22),
m_P_QP(28),
m_B_QP(22),
mIntraRefresh(30),
mSearchRangeX(64),
mSearchRangeY(48),
mForceIdrInterval(0),
mDynamicBitRateInterval(0),
mDynamicFrameRateInterval(0),
mBitrate(6000000),
mFrameRate(30),
mNumSpatialLayers(1),
mNumTemporalLayers(1),
mSpatialResRatio(2)
{
}
~Codec() { delMemRecs(); };
bool initEncoder(const UWORD8 *data);
bool encodeFrames(const UWORD8 *data, size_t size);
private:
void setEncParams(iv_raw_buf_t *psInpRawBuf, std::vector<UWORD8> &buf, const FrameDims &dims,
IV_COLOR_FORMAT_T colorFormat = IV_YUV_420P);
void setFrameType(IV_PICTURE_CODING_TYPE_T eFrameType);
void setQp();
void setEncMode(IVE_ENC_MODE_T eEncMode);
void setDimensions();
void setNumCores();
void setFrameRate();
void setIpeParams();
void setBitRate();
void setAirParams();
void setMeParams();
void setGopParams();
void setProfileParams();
void setDeblockParams();
void setVbvParams();
void setDefault();
void setVuiParams();
void getBufInfo();
void setSeiMdcvParams();
void setSeiCllParams();
void setSeiAveParams();
void setSeiCcvParams();
void logVersion();
void initEncBufs();
bool initMemRecs();
void delMemRecs();
iv_obj_t *mCodecCtx;
std::vector<iv_mem_rec_t> mMemRecords;
std::vector<UWORD8 *> mMemRecBufs;
EncBufs mEncBufs;
IVE_AIR_MODE_T mAirMode;
IVE_SPEED_CONFIG mEncSpeed;
IVE_RC_MODE_T mRCMode;
IV_ARCH_T mArch;
IVE_SLICE_MODE_T mSliceMode;
IV_COLOR_FORMAT_T mIvVideoColorFormat;
IV_PROFILE_T mProfile;
FrameDims mSvcCompDims;
FrameDims mInputDims;
bool mHalfPelEnable;
bool mQPelEnable;
bool mIntra4x4;
bool mEnableFastSad;
bool mEnableAltRef;
bool mConstrainedIntraFlag;
bool mSeiCllFlag;
bool mSeiAveFlag;
bool mSeiCcvFlag;
bool mSeiMdcvFlag;
bool mAspectRatioFlag;
bool mNalHrdFlag;
bool mVclHrdFlag;
bool mIsForceIdrEnabled;
bool mIsDynamicBitRateChangeEnabled;
bool mIsDynamicFrameRateChangeEnabled;
bool mEnableRecon;
bool mEnableNaluInfoExport;
UWORD32 mAvcEncLevel;
UWORD32 mNumMemRecords;
UWORD32 mNumCores;
UWORD32 mBframes;
UWORD32 mSliceParam;
UWORD32 mMeSpeedPreset;
UWORD32 mIInterval;
UWORD32 mIDRInterval;
UWORD32 mDisableDeblockLevel;
UWORD32 m_I_QP;
UWORD32 m_P_QP;
UWORD32 m_B_QP;
UWORD32 mIntraRefresh;
UWORD32 mSearchRangeX;
UWORD32 mSearchRangeY;
/* Units - number of frames */
UWORD32 mForceIdrInterval;
/* Units - number of frames */
UWORD32 mDynamicBitRateInterval;
/* Units - number of frames */
UWORD32 mDynamicFrameRateInterval;
UWORD64 mBitrate;
DOUBLE mFrameRate;
UWORD8 mNumSpatialLayers;
UWORD8 mNumTemporalLayers;
DOUBLE mSpatialResRatio;
};
void Codec::initEncBufs()
{
size_t frameSize = mInputDims.getFrameSize();
constexpr size_t minOutBufSize = 0x800;
size_t outBufSize = std::max(minOutBufSize, frameSize * mNumSpatialLayers);
size_t naluInfoBufSize = 460 * mNumSpatialLayers;
mEncBufs.mInputBuf.resize(frameSize);
mEncBufs.mOutputBuf.resize(outBufSize);
if(mEnableRecon)
{
mEncBufs.mReconBuf.resize(frameSize);
}
if(mEnableNaluInfoExport)
{
mEncBufs.mNaluInfoStructBuf.resize(mNumSpatialLayers * 2);
mEncBufs.mNaluInfoDataBuf.resize(mNumSpatialLayers);
for(auto i = 0; i < mNumSpatialLayers; i++)
{
mEncBufs.mNaluInfoDataBuf[i].resize(naluInfoBufSize);
}
}
}
bool Codec::initMemRecs()
{
std::fill(mMemRecBufs.begin(), mMemRecBufs.end(), nullptr);
for(auto i = 0u; i < mNumMemRecords; i++)
{
mMemRecBufs[i] = reinterpret_cast<UWORD8 *>(
aligned_alloc(mMemRecords[i].u4_mem_alignment, mMemRecords[i].u4_mem_size));
mMemRecords[i].pv_base = mMemRecBufs[i];
if(nullptr == mMemRecBufs[i])
{
for(auto j = 0u; j < i; j++)
{
free(mMemRecBufs[j]);
}
return false;
}
}
return true;
}
void Codec::delMemRecs()
{
for(auto i = 0u; i < mNumMemRecords; i++)
{
if(mMemRecBufs[i])
{
free(mMemRecBufs[i]);
}
}
std::fill(mMemRecBufs.begin(), mMemRecBufs.end(), nullptr);
}
bool Codec::initEncoder(const UWORD8 *data)
{
mInputDims = FrameDims{((data[IDX_WD_BYTE_1] << 8) | data[IDX_WD_BYTE_2]) % kMaxWidth,
((data[IDX_HT_BYTE_1] << 8) | data[IDX_HT_BYTE_2]) % kMaxHeight};
mNumSpatialLayers = kSpatialLayers[data[IDX_NUM_SPATIAL_LAYERS] % kSpatialLayersNum];
mNumTemporalLayers = kTemporalLayers[data[IDX_NUM_TEMPORAL_LAYERS] % kTemporalLayersNum];
mSpatialResRatio = kSpatialResRatio[data[IDX_SPATIAL_RES_RATIO] % kSpatialResRatioNum];
bool useSvcCompliantDims =
data[IDX_SVC_COMPLIANT_DIMS] <
static_cast<UWORD8>(std::numeric_limits<UWORD8>::max() * kSvcCompliantDimProb);
if(useSvcCompliantDims)
{
auto getSvcCompliantDims = [&]() -> FrameDims
{
auto maxResRatio = pow(mSpatialResRatio, mNumSpatialLayers - 1);
UWORD32 dimPadding = 0;
UWORD32 numDecimalDigits = mNumSpatialLayers;
constexpr auto minDimGcd = 16;
UWORD32 decPtDelMultiplier = static_cast<UWORD32>(std::pow(10, numDecimalDigits));
FrameDims dims{mInputDims};
if(std::fmod(minDimGcd, maxResRatio))
{
dimPadding = std::lcm(minDimGcd * decPtDelMultiplier,
static_cast<UWORD32>(maxResRatio * decPtDelMultiplier)) /
decPtDelMultiplier;
}
else
{
dimPadding = static_cast<UWORD32>(minDimGcd * maxResRatio);
}
if(mInputDims.mWidth % dimPadding)
{
dims.mWidth = mInputDims.mWidth - ((mInputDims.mWidth) % dimPadding) + dimPadding;
}
if(mInputDims.mHeight % dimPadding)
{
dims.mHeight =
mInputDims.mHeight - ((mInputDims.mHeight) % dimPadding) + dimPadding;
}
return dims;
};
mSvcCompDims = getSvcCompliantDims();
mInputDims = mSvcCompDims;
}
mIvVideoColorFormat =
kSupportedColorFormats[data[IDX_COLOR_FORMAT] % kSupportedColorFormatsNum];
mArch = kArchs[data[IDX_ARCH_TYPE] % std::size(kArchs)];
mRCMode = kRCMode[data[IDX_RC_MODE] % kRCModeNum];
mNumCores = (data[IDX_NUM_CORES] & 0x07) + 1;
mBframes = 0;
mEncSpeed = kEncSpeed[data[IDX_ENC_SPEED] % kEncSpeedNum];
mConstrainedIntraFlag = data[IDX_CONSTRAINED_INTRA_FLAG] & 0x01;
mIntra4x4 = data[IDX_INTRA_4x4] & 0x01;
m_I_QP = data[IDX_I_FRAME_QP];
m_P_QP = data[IDX_P_FRAME_QP];
m_B_QP = data[IDX_B_FRAME_QP];
mBitrate = (((data[IDX_BITRATE_BYTE_1] << 8) | data[IDX_BITRATE_BYTE_2]) * 1000) % kMaxBitrate;
mFrameRate = data[IDX_FRAME_RATE] % 120;
mIntraRefresh = data[IDX_INTRA_REFRESH] + 1;
mHalfPelEnable = data[IDX_ENABLE_HALF_PEL] & 0x01;
mQPelEnable = data[IDX_ENABLE_Q_PEL] & 0x01;
mMeSpeedPreset = kMeSpeedPreset[data[IDX_ME_SPEED_PRESET] % kMeSpeedPresetNum];
mAirMode = kAirMode[data[IDX_AIR_MODE] % kAirModeNum];
mDisableDeblockLevel = kDeblkLevel[data[IDX_DISABLE_DEBLOCK_LEVEL] % kDeblkLevelNum];
mSearchRangeX = data[IDX_SEARCH_RANGE_X];
mSearchRangeY = data[IDX_SEARCH_RANGE_Y];
mIInterval = data[IDX_I_INTERVAL] + 1;
mIDRInterval = data[IDX_IDR_INTERVAL] + 1;
mSeiMdcvFlag = data[IDX_SEI_MDCV_FLAG] & 0x01;
mSeiCllFlag = data[IDX_SEI_CLL_FLAG] & 0x01;
mSeiAveFlag = data[IDX_SEI_AVE_FLAG] & 0x01;
mSeiCcvFlag = data[IDX_SEI_CCV_FLAG] & 0x01;
mProfile = kProfile[data[IDX_PROFILE] % kProfileNum];
mAspectRatioFlag = data[IDX_ASPECT_RATIO_FLAG] & 0x01;
mNalHrdFlag = data[IDX_NAL_HRD_FLAG] & 0x01;
mVclHrdFlag = data[IDX_VCL_HRD_FLAG] & 0x01;
mIsForceIdrEnabled = data[IDX_ENABLE_FORCE_IDR] & 0x01;
mIsDynamicBitRateChangeEnabled = data[IDX_ENABLE_DYNAMIC_BITRATE] & 0x01;
mIsDynamicFrameRateChangeEnabled = data[IDX_ENABLE_DYNAMIC_FRAME_RATE] & 0x01;
mForceIdrInterval = data[IDX_FORCE_IDR_INTERVAL] & 0x07;
mDynamicBitRateInterval = data[IDX_DYNAMIC_BITRATE_INTERVAL] & 0x07;
mDynamicFrameRateInterval = data[IDX_DYNAMIC_FRAME_RATE_INTERVAL] & 0x07;
mSliceParam = std::min(256u, static_cast<UWORD32>(mInputDims.mHeight >> 4));
mAvcEncLevel = kSupportedLevels[data[IDX_ENC_LEVEL] % kSupportedLevelsNum];
mSliceMode = kSliceMode[data[IDX_SLICE_MODE] % kSliceModeNum];
mEnableFastSad = data[IDX_ENABLE_FAST_SAD] & 0x01;
mEnableRecon = !!(data[IDX_ENABLE_RECON] & 1);
mEnableNaluInfoExport = !!(data[IDX_ENABLE_NALU_INFO_EXPORT] & 1);
isvce_num_mem_rec_ip_t s_num_mem_rec_ip{};
isvce_num_mem_rec_op_t s_num_mem_rec_op{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_GET_NUM_MEM_REC, ISVCE_CMD_CT_NA};
/* Getting Number of MemRecords */
s_num_mem_rec_ip.s_ive_ip.u4_size = sizeof(isvce_num_mem_rec_ip_t);
s_num_mem_rec_op.s_ive_op.u4_size = sizeof(isvce_num_mem_rec_op_t);
if(IV_SUCCESS != isvce_api_function(0, &s_num_mem_rec_ip, &s_num_mem_rec_op, &s_api_cmds))
{
return false;
}
mNumMemRecords = s_num_mem_rec_op.s_ive_op.u4_num_mem_rec;
mMemRecords.resize(mNumMemRecords);
mMemRecBufs.resize(mNumMemRecords);
for(auto i = 0u; i < mNumMemRecords; i++)
{
mMemRecords[i].u4_size = sizeof(iv_mem_rec_t);
mMemRecords[i].pv_base = nullptr;
mMemRecords[i].u4_mem_size = 0;
mMemRecords[i].u4_mem_alignment = 0;
mMemRecords[i].e_mem_type = IV_NA_MEM_TYPE;
}
isvce_fill_mem_rec_ip_t sFillMemRecIp{};
isvce_fill_mem_rec_op_t sFillMemRecOp{};
s_api_cmds = {ISVCE_CMD_FILL_NUM_MEM_REC, ISVCE_CMD_CT_NA};
sFillMemRecIp.s_ive_ip.u4_size = sizeof(isvce_fill_mem_rec_ip_t);
sFillMemRecOp.s_ive_op.u4_size = sizeof(isvce_fill_mem_rec_op_t);
sFillMemRecIp.s_ive_ip.ps_mem_rec = mMemRecords.data();
sFillMemRecIp.s_ive_ip.u4_num_mem_rec = mNumMemRecords;
sFillMemRecIp.s_ive_ip.u4_max_wd = mInputDims.mWidth;
sFillMemRecIp.s_ive_ip.u4_max_ht = mInputDims.mHeight;
sFillMemRecIp.u4_wd = mInputDims.mWidth;
sFillMemRecIp.u4_ht = mInputDims.mHeight;
sFillMemRecIp.s_ive_ip.u4_max_level = mAvcEncLevel;
sFillMemRecIp.s_ive_ip.e_color_format = mIvVideoColorFormat;
sFillMemRecIp.s_ive_ip.u4_max_ref_cnt = 2;
sFillMemRecIp.s_ive_ip.u4_max_reorder_cnt = 0;
sFillMemRecIp.s_ive_ip.u4_max_srch_rng_x = 256;
sFillMemRecIp.s_ive_ip.u4_max_srch_rng_y = 256;
sFillMemRecIp.s_svc_inp_params.u1_num_temporal_layers = mNumTemporalLayers;
sFillMemRecIp.s_svc_inp_params.u1_num_spatial_layers = mNumSpatialLayers;
sFillMemRecIp.s_svc_inp_params.d_spatial_res_ratio = mSpatialResRatio;
if(IV_SUCCESS != isvce_api_function(0, &sFillMemRecIp, &sFillMemRecOp, &s_api_cmds))
{
return false;
}
if(!initMemRecs())
{
return false;
}
/* Codec Instance Creation */
isvce_init_ip_t sInitIp{};
isvce_init_op_t sInitOp{};
std::vector<UWORD32> sMaxBitrates(mNumSpatialLayers, 240000000);
mCodecCtx = reinterpret_cast<iv_obj_t *>(mMemRecords[0].pv_base);
mCodecCtx->u4_size = sizeof(iv_obj_t);
mCodecCtx->pv_fxns = reinterpret_cast<void *>(isvce_api_function);
sInitIp.s_ive_ip.u4_size = sizeof(isvce_init_ip_t);
sInitOp.s_ive_op.u4_size = sizeof(isvce_init_op_t);
s_api_cmds = {ISVCE_CMD_INIT, ISVCE_CMD_CT_NA};
sInitIp.s_ive_ip.u4_num_mem_rec = mNumMemRecords;
sInitIp.s_ive_ip.ps_mem_rec = mMemRecords.data();
sInitIp.s_ive_ip.u4_max_wd = mInputDims.mWidth;
sInitIp.s_ive_ip.u4_max_ht = mInputDims.mHeight;
sInitIp.u4_wd = mInputDims.mWidth;
sInitIp.u4_ht = mInputDims.mHeight;
sInitIp.s_ive_ip.u4_max_ref_cnt = 2;
sInitIp.s_ive_ip.u4_max_reorder_cnt = 0;
sInitIp.s_ive_ip.u4_max_level = mAvcEncLevel;
sInitIp.s_ive_ip.e_inp_color_fmt = mIvVideoColorFormat;
sInitIp.s_ive_ip.u4_enable_recon = mEnableRecon;
sInitIp.s_ive_ip.e_recon_color_fmt = IV_YUV_420P;
sInitIp.b_nalu_info_export_enable = mEnableNaluInfoExport;
sInitIp.s_ive_ip.e_rc_mode = mRCMode;
sInitIp.s_ive_ip.u4_max_framerate = 120000;
sInitIp.pu4_max_bitrate = sMaxBitrates.data();
sInitIp.s_svc_inp_params.u1_num_temporal_layers = mNumTemporalLayers;
sInitIp.s_svc_inp_params.u1_num_spatial_layers = mNumSpatialLayers;
sInitIp.s_svc_inp_params.d_spatial_res_ratio = mSpatialResRatio;
sInitIp.s_ive_ip.u4_num_bframes = mBframes;
sInitIp.s_ive_ip.e_content_type = IV_PROGRESSIVE;
sInitIp.s_ive_ip.u4_max_srch_rng_x = 256;
sInitIp.s_ive_ip.u4_max_srch_rng_y = 256;
sInitIp.s_ive_ip.e_slice_mode = mSliceMode;
sInitIp.s_ive_ip.u4_slice_param = mSliceParam;
sInitIp.s_ive_ip.e_arch = mArch;
sInitIp.s_ive_ip.e_soc = SOC_GENERIC;
sInitIp.b_use_default_vui = true;
if(IV_SUCCESS != isvce_api_function(mCodecCtx, &sInitIp, &sInitOp, &s_api_cmds))
{
delMemRecs();
return false;
}
setDefault();
setNumCores();
logVersion();
getBufInfo();
setDimensions();
setFrameRate();
setIpeParams();
setBitRate();
setQp();
setAirParams();
setVbvParams();
setMeParams();
setGopParams();
setDeblockParams();
setProfileParams();
setEncMode(IVE_ENC_MODE_HEADER);
setVuiParams();
setSeiMdcvParams();
setSeiCllParams();
setSeiAveParams();
setSeiCcvParams();
initEncBufs();
return true;
}
void Codec::setDimensions()
{
isvce_ctl_set_dimensions_ip_t s_frame_dimensions_ip{};
isvce_ctl_set_dimensions_op_t s_frame_dimensions_op{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_DIMENSIONS};
s_frame_dimensions_ip.s_ive_ip.u4_ht = mInputDims.mHeight;
s_frame_dimensions_ip.s_ive_ip.u4_wd = mInputDims.mWidth;
s_frame_dimensions_ip.s_ive_ip.u4_timestamp_high = 0;
s_frame_dimensions_ip.s_ive_ip.u4_timestamp_low = 0;
s_frame_dimensions_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_set_dimensions_ip_t);
s_frame_dimensions_op.s_ive_op.u4_size = sizeof(isvce_ctl_set_dimensions_op_t);
isvce_api_function(mCodecCtx, &s_frame_dimensions_ip, &s_frame_dimensions_op, &s_api_cmds);
}
void Codec::setNumCores()
{
isvce_ctl_set_num_cores_ip_t sNumCoresIp{};
isvce_ctl_set_num_cores_op_t sNumCoresOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_NUM_CORES};
sNumCoresIp.s_ive_ip.u4_num_cores = mNumCores;
sNumCoresIp.s_ive_ip.u4_timestamp_high = 0;
sNumCoresIp.s_ive_ip.u4_timestamp_low = 0;
sNumCoresIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_num_cores_ip_t);
sNumCoresOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_num_cores_op_t);
isvce_api_function(mCodecCtx, (void *) &sNumCoresIp, (void *) &sNumCoresOp, &s_api_cmds);
}
void Codec::setDefault()
{
isvce_ctl_setdefault_ip_t sDefaultIp{};
isvce_ctl_setdefault_op_t sDefaultOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SETDEFAULT};
sDefaultIp.s_ive_ip.u4_timestamp_high = 0;
sDefaultIp.s_ive_ip.u4_timestamp_low = 0;
sDefaultIp.s_ive_ip.u4_size = sizeof(isvce_ctl_setdefault_ip_t);
sDefaultOp.s_ive_op.u4_size = sizeof(isvce_ctl_setdefault_op_t);
isvce_api_function(mCodecCtx, &sDefaultIp, &sDefaultOp, &s_api_cmds);
}
void Codec::getBufInfo()
{
isvce_ctl_getbufinfo_ip_t s_get_buf_info_ip{};
isvce_ctl_getbufinfo_op_t s_get_buf_info_op{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_GETBUFINFO};
s_get_buf_info_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_getbufinfo_ip_t);
s_get_buf_info_op.s_ive_op.u4_size = sizeof(isvce_ctl_getbufinfo_op_t);
s_get_buf_info_ip.s_ive_ip.u4_max_ht = mInputDims.mHeight;
s_get_buf_info_ip.s_ive_ip.u4_max_wd = mInputDims.mWidth;
s_get_buf_info_ip.s_ive_ip.e_inp_color_fmt = mIvVideoColorFormat;
isvce_api_function(mCodecCtx, &s_get_buf_info_ip, &s_get_buf_info_op, &s_api_cmds);
}
void Codec::setFrameRate()
{
isvce_ctl_set_frame_rate_ip_t sFrameRateIp{};
isvce_ctl_set_frame_rate_op_t sFrameRateOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_FRAMERATE};
sFrameRateIp.s_ive_ip.u4_src_frame_rate = (UWORD32) mFrameRate;
sFrameRateIp.s_ive_ip.u4_tgt_frame_rate = (UWORD32) mFrameRate;
sFrameRateIp.s_ive_ip.u4_timestamp_high = 0;
sFrameRateIp.s_ive_ip.u4_timestamp_low = 0;
sFrameRateIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_frame_rate_ip_t);
sFrameRateOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_frame_rate_op_t);
isvce_api_function(mCodecCtx, &sFrameRateIp, &sFrameRateOp, &s_api_cmds);
}
void Codec::setIpeParams()
{
isvce_ctl_set_ipe_params_ip_t sIpeParamsIp{};
isvce_ctl_set_ipe_params_op_t sIpeParamsOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_IPE_PARAMS};
sIpeParamsIp.s_ive_ip.u4_enable_intra_4x4 = mIntra4x4;
sIpeParamsIp.s_ive_ip.u4_enc_speed_preset = mEncSpeed;
sIpeParamsIp.s_ive_ip.u4_timestamp_high = 0;
sIpeParamsIp.s_ive_ip.u4_timestamp_low = 0;
sIpeParamsIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_ipe_params_ip_t);
sIpeParamsOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_ipe_params_op_t);
isvce_api_function(mCodecCtx, &sIpeParamsIp, &sIpeParamsOp, &s_api_cmds);
}
void Codec::setBitRate()
{
isvce_ctl_set_bitrate_ip_t sBitrateIp{};
isvce_ctl_set_bitrate_op_t sBitrateOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_BITRATE};
std::vector<UWORD32> sTargetBitrates(mNumSpatialLayers, mBitrate);
sBitrateIp.pu4_target_bitrate = sTargetBitrates.data();
sBitrateIp.s_ive_ip.u4_timestamp_high = 0;
sBitrateIp.s_ive_ip.u4_timestamp_low = 0;
sBitrateIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_bitrate_ip_t);
sBitrateOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_bitrate_op_t);
isvce_api_function(mCodecCtx, &sBitrateIp, &sBitrateOp, &s_api_cmds);
}
void Codec::setFrameType(IV_PICTURE_CODING_TYPE_T eFrameType)
{
isvce_ctl_set_frame_type_ip_t sFrameTypeIp{};
isvce_ctl_set_frame_type_op_t sFrameTypeOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_FRAMETYPE};
sFrameTypeIp.s_ive_ip.e_frame_type = eFrameType;
sFrameTypeIp.s_ive_ip.u4_timestamp_high = 0;
sFrameTypeIp.s_ive_ip.u4_timestamp_low = 0;
sFrameTypeIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_frame_type_ip_t);
sFrameTypeOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_frame_type_op_t);
isvce_api_function(mCodecCtx, &sFrameTypeIp, &sFrameTypeOp, &s_api_cmds);
}
void Codec::setQp()
{
constexpr UWORD8 u1NumSliceTypes = 3;
isvce_ctl_set_qp_ip_t s_QpIp{};
isvce_ctl_set_qp_op_t s_QpOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_QP};
std::vector<UWORD32> sQps(u1NumSliceTypes * mNumSpatialLayers);
std::vector<UWORD32> sMinQps(u1NumSliceTypes * mNumSpatialLayers);
std::vector<UWORD32> sMaxQps(u1NumSliceTypes * mNumSpatialLayers);
s_QpIp.pu4_i_qp = sQps.data();
s_QpIp.pu4_i_qp_min = sMinQps.data();
s_QpIp.pu4_i_qp_max = sMaxQps.data();
s_QpIp.pu4_p_qp = sQps.data() + mNumSpatialLayers;
s_QpIp.pu4_p_qp_min = sMinQps.data() + mNumSpatialLayers;
s_QpIp.pu4_p_qp_max = sMaxQps.data() + mNumSpatialLayers;
s_QpIp.pu4_b_qp = sQps.data() + mNumSpatialLayers * 2;
s_QpIp.pu4_b_qp_min = sMinQps.data() + mNumSpatialLayers * 2;
s_QpIp.pu4_b_qp_max = sMaxQps.data() + mNumSpatialLayers * 2;
for(auto i = 0; i < mNumSpatialLayers; i++)
{
s_QpIp.pu4_i_qp[i] = m_I_QP;
s_QpIp.pu4_i_qp_max[i] = kMaxQP;
s_QpIp.pu4_i_qp_min[i] = kMinQP;
s_QpIp.pu4_p_qp[i] = m_P_QP;
s_QpIp.pu4_p_qp_max[i] = kMaxQP;
s_QpIp.pu4_p_qp_min[i] = kMinQP;
s_QpIp.pu4_b_qp[i] = m_B_QP;
s_QpIp.pu4_b_qp_max[i] = kMaxQP;
s_QpIp.pu4_b_qp_min[i] = kMinQP;
}
s_QpIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_qp_ip_t);
s_QpOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_qp_op_t);
isvce_api_function(mCodecCtx, &s_QpIp, &s_QpOp, &s_api_cmds);
}
void Codec::setEncMode(IVE_ENC_MODE_T eEncMode)
{
isvce_ctl_set_enc_mode_ip_t sEncModeIp{};
isvce_ctl_set_enc_mode_op_t sEncModeOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_ENC_MODE};
sEncModeIp.s_ive_ip.e_enc_mode = eEncMode;
sEncModeIp.s_ive_ip.u4_timestamp_high = 0;
sEncModeIp.s_ive_ip.u4_timestamp_low = 0;
sEncModeIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_enc_mode_ip_t);
sEncModeOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_enc_mode_op_t);
isvce_api_function(mCodecCtx, &sEncModeIp, &sEncModeOp, &s_api_cmds);
}
void Codec::setVbvParams()
{
isvce_ctl_set_vbv_params_ip_t sVbvIp{};
isvce_ctl_set_vbv_params_op_t sVbvOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_VBV_PARAMS};
std::vector<UWORD32> sBufferDelays(mNumSpatialLayers, 1000);
sVbvIp.pu4_vbv_buffer_delay = sBufferDelays.data();
sVbvIp.s_ive_ip.u4_timestamp_high = 0;
sVbvIp.s_ive_ip.u4_timestamp_low = 0;
sVbvIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_vbv_params_ip_t);
sVbvOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_vbv_params_op_t);
isvce_api_function(mCodecCtx, &sVbvIp, &sVbvOp, &s_api_cmds);
}
void Codec::setAirParams()
{
isvce_ctl_set_air_params_ip_t sAirIp{};
isvce_ctl_set_air_params_op_t sAirOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_AIR_PARAMS};
sAirIp.s_ive_ip.e_air_mode = mAirMode;
sAirIp.s_ive_ip.u4_air_refresh_period = mIntraRefresh;
sAirIp.s_ive_ip.u4_timestamp_high = 0;
sAirIp.s_ive_ip.u4_timestamp_low = 0;
sAirIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_air_params_ip_t);
sAirOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_air_params_op_t);
isvce_api_function(mCodecCtx, &sAirIp, &sAirOp, &s_api_cmds);
}
void Codec::setMeParams()
{
isvce_ctl_set_me_params_ip_t sMeParamsIp{};
isvce_ctl_set_me_params_op_t sMeParamsOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_ME_PARAMS};
sMeParamsIp.s_ive_ip.u4_enable_fast_sad = mEnableFastSad;
sMeParamsIp.s_ive_ip.u4_enable_alt_ref = mEnableAltRef;
sMeParamsIp.s_ive_ip.u4_enable_hpel = mHalfPelEnable;
sMeParamsIp.s_ive_ip.u4_enable_qpel = mQPelEnable;
sMeParamsIp.s_ive_ip.u4_me_speed_preset = mMeSpeedPreset;
sMeParamsIp.s_ive_ip.u4_srch_rng_x = mSearchRangeX;
sMeParamsIp.s_ive_ip.u4_srch_rng_y = mSearchRangeY;
sMeParamsIp.s_ive_ip.u4_timestamp_high = 0;
sMeParamsIp.s_ive_ip.u4_timestamp_low = 0;
sMeParamsIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_me_params_ip_t);
sMeParamsOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_me_params_op_t);
isvce_api_function(mCodecCtx, &sMeParamsIp, &sMeParamsOp, &s_api_cmds);
}
void Codec::setGopParams()
{
isvce_ctl_set_gop_params_ip_t sGopParamsIp{};
isvce_ctl_set_gop_params_op_t sGopParamsOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_GOP_PARAMS};
sGopParamsIp.s_ive_ip.u4_i_frm_interval = mIInterval;
sGopParamsIp.s_ive_ip.u4_idr_frm_interval = mIDRInterval;
sGopParamsIp.s_ive_ip.u4_timestamp_high = 0;
sGopParamsIp.s_ive_ip.u4_timestamp_low = 0;
sGopParamsIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_gop_params_ip_t);
sGopParamsOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_gop_params_op_t);
isvce_api_function(mCodecCtx, &sGopParamsIp, &sGopParamsOp, &s_api_cmds);
}
void Codec::setProfileParams()
{
isvce_ctl_set_profile_params_ip_t sProfileParamsIp{};
isvce_ctl_set_profile_params_op_t sProfileParamsOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_PROFILE_PARAMS};
sProfileParamsIp.s_ive_ip.e_profile = mProfile;
if(sProfileParamsIp.s_ive_ip.e_profile == IV_PROFILE_BASE)
{
sProfileParamsIp.s_ive_ip.u4_entropy_coding_mode = 0;
}
else
{
sProfileParamsIp.s_ive_ip.u4_entropy_coding_mode = 1;
}
sProfileParamsIp.s_ive_ip.u4_timestamp_high = 0;
sProfileParamsIp.s_ive_ip.u4_timestamp_low = 0;
sProfileParamsIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_profile_params_ip_t);
sProfileParamsOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_profile_params_op_t);
isvce_api_function(mCodecCtx, &sProfileParamsIp, &sProfileParamsOp, &s_api_cmds);
}
void Codec::setDeblockParams()
{
isvce_ctl_set_deblock_params_ip_t sDeblockParamsIp{};
isvce_ctl_set_deblock_params_op_t sDeblockParamsOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_DEBLOCK_PARAMS};
sDeblockParamsIp.s_ive_ip.u4_disable_deblock_level = mDisableDeblockLevel;
sDeblockParamsIp.s_ive_ip.u4_timestamp_high = 0;
sDeblockParamsIp.s_ive_ip.u4_timestamp_low = 0;
sDeblockParamsIp.s_ive_ip.u4_size = sizeof(isvce_ctl_set_deblock_params_ip_t);
sDeblockParamsOp.s_ive_op.u4_size = sizeof(isvce_ctl_set_deblock_params_op_t);
isvce_api_function(mCodecCtx, &sDeblockParamsIp, &sDeblockParamsOp, &s_api_cmds);
}
void Codec::setVuiParams()
{
isvce_vui_ip_t sVuiParamsIp{};
isvce_vui_op_t sVuiParamsOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_VUI_PARAMS};
sVuiParamsIp.u1_aspect_ratio_info_present_flag = mAspectRatioFlag;
sVuiParamsIp.u1_aspect_ratio_idc = 0;
sVuiParamsIp.u2_sar_width = 0;
sVuiParamsIp.u2_sar_height = 0;
sVuiParamsIp.u1_overscan_info_present_flag = 0;
sVuiParamsIp.u1_overscan_appropriate_flag = 0;
sVuiParamsIp.u1_video_signal_type_present_flag = 1;
sVuiParamsIp.u1_video_format = 0;
sVuiParamsIp.u1_video_full_range_flag = 0;
sVuiParamsIp.u1_colour_description_present_flag = 0;
sVuiParamsIp.u1_colour_primaries = 0;
sVuiParamsIp.u1_transfer_characteristics = 0;
sVuiParamsIp.u1_matrix_coefficients = 0;
sVuiParamsIp.u1_chroma_loc_info_present_flag = 0;
sVuiParamsIp.u1_chroma_sample_loc_type_top_field = 0;
sVuiParamsIp.u1_chroma_sample_loc_type_bottom_field = 0;
sVuiParamsIp.u1_vui_timing_info_present_flag = 0;
sVuiParamsIp.u4_vui_num_units_in_tick = 0;
sVuiParamsIp.u4_vui_time_scale = 0;
sVuiParamsIp.u1_fixed_frame_rate_flag = 0;
sVuiParamsIp.u1_nal_hrd_parameters_present_flag = mNalHrdFlag;
sVuiParamsIp.u1_vcl_hrd_parameters_present_flag = mVclHrdFlag;
sVuiParamsIp.u1_low_delay_hrd_flag = 0;
sVuiParamsIp.u1_pic_struct_present_flag = 0;
sVuiParamsIp.u1_bitstream_restriction_flag = 0;
sVuiParamsIp.u1_motion_vectors_over_pic_boundaries_flag = 0;
sVuiParamsIp.u1_max_bytes_per_pic_denom = 0;
sVuiParamsIp.u1_max_bits_per_mb_denom = 0;
sVuiParamsIp.u1_log2_max_mv_length_horizontal = 0;
sVuiParamsIp.u1_log2_max_mv_length_vertical = 0;
sVuiParamsIp.u1_num_reorder_frames = 0;
sVuiParamsIp.u1_max_dec_frame_buffering = 0;
sVuiParamsIp.u4_size = sizeof(isvce_vui_ip_t);
sVuiParamsOp.u4_size = sizeof(isvce_vui_op_t);
isvce_api_function(mCodecCtx, &sVuiParamsIp, &sVuiParamsOp, &s_api_cmds);
}
void Codec::setSeiMdcvParams()
{
isvce_ctl_set_sei_mdcv_params_ip_t sSeiMdcvParamsIp{};
isvce_ctl_set_sei_mdcv_params_op_t sSeiMdcvParamsOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_SEI_MDCV_PARAMS};
sSeiMdcvParamsIp.u1_sei_mdcv_params_present_flag = mSeiMdcvFlag;
if(mSeiMdcvFlag)
{
for(int i4_count = 0; i4_count < kNumSeiMdcvPrimaries; ++i4_count)
{
sSeiMdcvParamsIp.au2_display_primaries_x[i4_count] = 30000;
sSeiMdcvParamsIp.au2_display_primaries_y[i4_count] = 35000;
}
sSeiMdcvParamsIp.u2_white_point_x = 30000;
sSeiMdcvParamsIp.u2_white_point_y = 35000;
sSeiMdcvParamsIp.u4_max_display_mastering_luminance = 100000000;
sSeiMdcvParamsIp.u4_min_display_mastering_luminance = 50000;
}
sSeiMdcvParamsIp.u4_timestamp_high = 0;
sSeiMdcvParamsIp.u4_timestamp_low = 0;
sSeiMdcvParamsIp.u4_size = sizeof(isvce_ctl_set_sei_mdcv_params_ip_t);
sSeiMdcvParamsOp.u4_size = sizeof(isvce_ctl_set_sei_mdcv_params_op_t);
isvce_api_function(mCodecCtx, &sSeiMdcvParamsIp, &sSeiMdcvParamsOp, &s_api_cmds);
}
void Codec::setSeiCllParams()
{
isvce_ctl_set_sei_cll_params_ip_t sSeiCllParamsIp{};
isvce_ctl_set_sei_cll_params_op_t sSeiCllParamsOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_SEI_CLL_PARAMS};
sSeiCllParamsIp.u1_sei_cll_params_present_flag = mSeiCllFlag;
if(mSeiCllFlag)
{
sSeiCllParamsIp.u2_max_content_light_level = 0;
sSeiCllParamsIp.u2_max_pic_average_light_level = 0;
}
sSeiCllParamsIp.u4_timestamp_high = 0;
sSeiCllParamsIp.u4_timestamp_low = 0;
sSeiCllParamsIp.u4_size = sizeof(isvce_ctl_set_sei_cll_params_ip_t);
sSeiCllParamsOp.u4_size = sizeof(isvce_ctl_set_sei_cll_params_op_t);
isvce_api_function(mCodecCtx, &sSeiCllParamsIp, &sSeiCllParamsOp, &s_api_cmds);
}
void Codec::setSeiAveParams()
{
isvce_ctl_set_sei_ave_params_ip_t sSeiAveParamsIp{};
isvce_ctl_set_sei_ave_params_op_t sSeiAveParamsOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_SEI_AVE_PARAMS};
sSeiAveParamsIp.u1_sei_ave_params_present_flag = mSeiAveFlag;
if(mSeiAveFlag)
{
sSeiAveParamsIp.u4_ambient_illuminance = 1;
sSeiAveParamsIp.u2_ambient_light_x = 0;
sSeiAveParamsIp.u2_ambient_light_y = 0;
}
sSeiAveParamsIp.u4_timestamp_high = 0;
sSeiAveParamsIp.u4_timestamp_low = 0;
sSeiAveParamsIp.u4_size = sizeof(isvce_ctl_set_sei_ave_params_ip_t);
sSeiAveParamsOp.u4_size = sizeof(isvce_ctl_set_sei_ave_params_op_t);
isvce_api_function(mCodecCtx, &sSeiAveParamsIp, &sSeiAveParamsOp, &s_api_cmds);
}
void Codec::setSeiCcvParams()
{
isvce_ctl_set_sei_ccv_params_ip_t sSeiCcvParamsIp{};
isvce_ctl_set_sei_ccv_params_op_t sSeiCcvParamsOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_SET_SEI_CCV_PARAMS};
sSeiCcvParamsIp.u1_sei_ccv_params_present_flag = mSeiCcvFlag;
if(mSeiCcvFlag)
{
sSeiCcvParamsIp.u1_ccv_cancel_flag = 0;
sSeiCcvParamsIp.u1_ccv_persistence_flag = 1;
sSeiCcvParamsIp.u1_ccv_primaries_present_flag = 1;
sSeiCcvParamsIp.u1_ccv_min_luminance_value_present_flag = 1;
sSeiCcvParamsIp.u1_ccv_max_luminance_value_present_flag = 1;
sSeiCcvParamsIp.u1_ccv_avg_luminance_value_present_flag = 1;
sSeiCcvParamsIp.u1_ccv_reserved_zero_2bits = 0;
for(int i4_count = 0; i4_count < kNumSeiCcvPrimaries; ++i4_count)
{
sSeiCcvParamsIp.ai4_ccv_primaries_x[i4_count] = 1;
sSeiCcvParamsIp.ai4_ccv_primaries_y[i4_count] = 1;
}
sSeiCcvParamsIp.u4_ccv_min_luminance_value = 1;
sSeiCcvParamsIp.u4_ccv_max_luminance_value = 1;
sSeiCcvParamsIp.u4_ccv_avg_luminance_value = 1;
}
sSeiCcvParamsIp.u4_timestamp_high = 0;
sSeiCcvParamsIp.u4_timestamp_low = 0;
sSeiCcvParamsIp.u4_size = sizeof(isvce_ctl_set_sei_ccv_params_ip_t);
sSeiCcvParamsOp.u4_size = sizeof(isvce_ctl_set_sei_ccv_params_op_t);
isvce_api_function(mCodecCtx, &sSeiCcvParamsIp, &sSeiCcvParamsOp, &s_api_cmds);
}
void Codec::logVersion()
{
isvce_ctl_getversioninfo_ip_t s_ctl_set_getversioninfo_ip{};
isvce_ctl_getversioninfo_op_t s_ctl_set_getversioninfo_op{};
CHAR ac_version_string[512];
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_CTL, ISVCE_CMD_CTL_GETVERSION};
s_ctl_set_getversioninfo_ip.s_ive_ip.pu1_version = (UWORD8 *) ac_version_string;
s_ctl_set_getversioninfo_ip.s_ive_ip.u4_version_bufsize = sizeof(ac_version_string);
s_ctl_set_getversioninfo_ip.s_ive_ip.u4_size = sizeof(isvce_ctl_getversioninfo_ip_t);
s_ctl_set_getversioninfo_op.s_ive_op.u4_size = sizeof(isvce_ctl_getversioninfo_op_t);
isvce_api_function(mCodecCtx, (void *) &s_ctl_set_getversioninfo_ip,
(void *) &s_ctl_set_getversioninfo_op, &s_api_cmds);
}
bool Codec::encodeFrames(const UWORD8 *data, size_t size)
{
isvce_video_encode_ip_t sEncodeIp{};
isvce_video_encode_op_t sEncodeOp{};
isvce_api_cmds_t s_api_cmds{ISVCE_CMD_VIDEO_ENCODE, ISVCE_CMD_CT_NA};
iv_raw_buf_t *psInpRawBuf = &sEncodeIp.s_ive_ip.s_inp_buf;
iv_raw_buf_t *psRecRawBuf = &sEncodeIp.s_ive_ip.s_recon_buf;
size_t frameSize = mInputDims.getFrameSize();
auto bytesLeft = std::min(size, frameSize);
auto bytesConsumed = 0;
UWORD32 numFrames = 0;
sEncodeIp.s_ive_ip.s_out_buf.pv_buf = mEncBufs.mOutputBuf.data();
sEncodeIp.s_ive_ip.s_out_buf.u4_bytes = 0;
sEncodeIp.s_ive_ip.s_out_buf.u4_bufsize = static_cast<UWORD32>(mEncBufs.mOutputBuf.size());
sEncodeOp.s_ive_op.s_out_buf.pv_buf = nullptr;
sEncodeIp.s_ive_ip.pv_bufs = nullptr;
sEncodeIp.s_ive_ip.pv_mb_info = nullptr;
sEncodeIp.s_ive_ip.pv_pic_info = nullptr;
sEncodeIp.s_ive_ip.u4_mb_info_type = 0;
sEncodeIp.s_ive_ip.u4_pic_info_type = 0;
sEncodeIp.s_ive_ip.u4_is_last = 0;
sEncodeIp.s_ive_ip.u4_timestamp_high = 0;
sEncodeIp.s_ive_ip.u4_timestamp_low = 0;
memset(psInpRawBuf, 0, sizeof(iv_raw_buf_t));
psInpRawBuf->u4_size = sizeof(iv_raw_buf_t);
psInpRawBuf->e_color_fmt = mIvVideoColorFormat;
sEncodeIp.s_ive_ip.u4_size = sizeof(isvce_video_encode_ip_t);
sEncodeOp.s_ive_op.u4_size = sizeof(isvce_video_encode_op_t);
isvce_api_function(mCodecCtx, &sEncodeIp, &sEncodeOp, &s_api_cmds);
if(mEnableNaluInfoExport)
{
sEncodeIp.ps_nalu_info_buf = mEncBufs.mNaluInfoStructBuf.data();
sEncodeOp.ps_nalu_info_buf = mEncBufs.mNaluInfoStructBuf.data() + mNumSpatialLayers;
}
while(!sEncodeOp.s_ive_op.u4_is_last && (kMaxEncodeCalls > (mNumSpatialLayers * numFrames)))
{
if(mEnableRecon)
{
setEncParams(psRecRawBuf, mEncBufs.mReconBuf, mInputDims);
}
if(mEnableNaluInfoExport)
{
for(auto i = 0; i < mNumSpatialLayers; i++)
{
sEncodeIp.ps_nalu_info_buf[i].pu1_buf = mEncBufs.mNaluInfoDataBuf[i].data();
sEncodeIp.ps_nalu_info_buf[i].u4_num_bytes = 0;
sEncodeIp.ps_nalu_info_buf[i].u4_buf_size =
static_cast<UWORD32>(mEncBufs.mNaluInfoDataBuf[i].size());
}
}
if(size > 0)
{
bytesLeft = std::min(size, frameSize);
std::copy(data, data + bytesLeft, mEncBufs.mInputBuf.begin());
std::fill(std::next(mEncBufs.mInputBuf.begin(), bytesLeft), mEncBufs.mInputBuf.end(),
data[0]);
setEncParams(psInpRawBuf, mEncBufs.mInputBuf, mInputDims, mIvVideoColorFormat);
bytesConsumed = bytesLeft;
}
else
{
sEncodeIp.s_ive_ip.u4_is_last = 1;
for(auto i = 0; i < 3; i++)
{
psInpRawBuf->apv_bufs[i] = nullptr;
}
bytesConsumed = 0;
}
if(mIsForceIdrEnabled && !sEncodeIp.s_ive_ip.u4_is_last)
{
if(numFrames == mForceIdrInterval)
{
setFrameType(IV_IDR_FRAME);
}
}
if(mIsDynamicBitRateChangeEnabled && !sEncodeIp.s_ive_ip.u4_is_last)
{
if(numFrames == mDynamicBitRateInterval)
{
if(data[0] & 0x01)
{
mBitrate *= 2;
}
else
{
mBitrate /= 2;
}
setBitRate();
}
}
if(mIsDynamicFrameRateChangeEnabled && !sEncodeIp.s_ive_ip.u4_is_last)
{
if(numFrames == mDynamicFrameRateInterval)
{
if(size > 1 && data[1] & 0x01)
{
mFrameRate *= 2;
}
else
{
mFrameRate /= 2;
}
setFrameRate();
}
}
isvce_api_function(mCodecCtx, &sEncodeIp, &sEncodeOp, &s_api_cmds);
if(!sEncodeOp.s_ive_op.u4_is_last)
{
numFrames++;
data += bytesConsumed;
size -= bytesConsumed;
}
}
return true;
}
void Codec::setEncParams(iv_raw_buf_t *psInpRawBuf, std::vector<UWORD8> &buf, const FrameDims &dims,
IV_COLOR_FORMAT_T colorFormat)
{
switch(colorFormat)
{
case IV_YUV_420SP_UV:
case IV_YUV_420SP_VU:
{
WORD32 yStride = dims.mWidth;
WORD32 uStride = dims.mWidth / 2;
psInpRawBuf->apv_bufs[0] = buf.data();
psInpRawBuf->apv_bufs[1] = buf.data() + dims.mWidth * dims.mHeight;
psInpRawBuf->au4_wd[0] = dims.mWidth;
psInpRawBuf->au4_wd[1] = dims.mWidth;
psInpRawBuf->au4_ht[0] = dims.mHeight;
psInpRawBuf->au4_ht[1] = dims.mHeight / 2;
psInpRawBuf->au4_strd[0] = yStride;
psInpRawBuf->au4_strd[1] = uStride;
break;
}
default:
{
WORD32 yStride = dims.mWidth;
WORD32 uStride = dims.mWidth / 2;
WORD32 vStride = dims.mWidth / 2;
psInpRawBuf->apv_bufs[0] = buf.data();
psInpRawBuf->apv_bufs[1] = buf.data() + dims.mWidth * dims.mHeight;
psInpRawBuf->apv_bufs[2] = buf.data() + (dims.mWidth * dims.mHeight * 5) / 4;
psInpRawBuf->au4_wd[0] = dims.mWidth;
psInpRawBuf->au4_wd[1] = dims.mWidth / 2;
psInpRawBuf->au4_wd[2] = dims.mWidth / 2;
psInpRawBuf->au4_ht[0] = dims.mHeight;
psInpRawBuf->au4_ht[1] = dims.mHeight / 2;
psInpRawBuf->au4_ht[2] = dims.mHeight / 2;
psInpRawBuf->au4_strd[0] = yStride;
psInpRawBuf->au4_strd[1] = uStride;
psInpRawBuf->au4_strd[2] = vStride;
break;
}
}
}
extern "C" int LLVMFuzzerTestOneInput(const UWORD8 *data, size_t size)
{
if(size < IDX_LAST)
{
return 0;
}
std::unique_ptr<Codec> codec = std::make_unique<Codec>();
if(codec->initEncoder(data))
{
codec->encodeFrames(data, size);
}
return 0;
}