| /****************************************************************************** |
| * |
| * 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 <malloc.h> |
| #include <algorithm> |
| |
| #include "ih264_defs.h" |
| #include "ih264_typedefs.h" |
| #include "ih264e.h" |
| #include "ih264e_error.h" |
| #define ive_api_function ih264e_api_function |
| |
| constexpr uint32_t kHeaderLength = 0x800; |
| constexpr int16_t kCompressionRatio = 1; |
| |
| constexpr int kMeSpeedPreset[] = {0, 50, 75, 100}; |
| constexpr IVE_AIR_MODE_T kAirMode[] = {IVE_AIR_MODE_NONE, IVE_AIR_MODE_CYCLIC, IVE_AIR_MODE_RANDOM}; |
| constexpr IVE_SPEED_CONFIG kEncSpeed[] = {IVE_CONFIG, IVE_SLOWEST, IVE_NORMAL, |
| IVE_FAST, IVE_HIGH_SPEED, IVE_FASTEST}; |
| constexpr IV_PROFILE_T kProfle[] = {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, IV_YUV_422ILE, |
| IV_YUV_420SP_VU}; |
| |
| constexpr size_t kAirModeNum = std::size(kAirMode); |
| constexpr size_t kEncSpeedNum = std::size(kEncSpeed); |
| constexpr size_t kMeSpeedPresetNum = std::size(kMeSpeedPreset); |
| constexpr size_t kProfleNum = std::size(kProfle); |
| constexpr size_t kRCModeNum = std::size(kRCMode); |
| constexpr size_t kSupportedColorFormatsNum = std::size(kSupportedColorFormats); |
| constexpr size_t kMinQP = 4; |
| constexpr size_t kMaxWidth = 10240; |
| constexpr size_t kMaxHeight = 10240; |
| constexpr size_t kMaxBitrate = 500000000; |
| |
| enum { |
| 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_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_LAST |
| }; |
| |
| class Codec { |
| public: |
| Codec() = default; |
| ~Codec() { deInitEncoder(); } |
| bool initEncoder(const uint8_t **pdata, size_t *psize); |
| void encodeFrames(const uint8_t *data, size_t size); |
| void deInitEncoder(); |
| |
| private: |
| void setEncParams(iv_raw_buf_t *psInpRawBuf, const uint8_t *data); |
| 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(); |
| bool mHalfPelEnable = 1; |
| bool mQPelEnable = 1; |
| bool mIntra4x4 = 0; |
| bool mEnableFastSad = 0; |
| bool mEnableAltRef = 0; |
| bool mConstrainedIntraFlag = 0; |
| bool mSeiCllFlag = 1; |
| bool mSeiAveFlag = 1; |
| bool mSeiCcvFlag = 1; |
| bool mSeiMdcvFlag = 1; |
| bool mAspectRatioFlag = 0; |
| bool mNalHrdFlag = 0; |
| bool mVclHrdFlag = 0; |
| bool mIsForceIdrEnabled = false; |
| bool mIsDynamicBitRateChangeEnabled = false; |
| bool mIsDynamicFrameRateChangeEnabled = false; |
| uint32_t mWidth = 2560; |
| uint32_t mHeight = 2560; |
| uint32_t mAvcEncLevel = 41; |
| uint32_t mNumMemRecords = 0; |
| uint32_t mNumCores = 1; |
| uint32_t mBframes = 0; |
| uint32_t mSliceParam = 256; |
| uint32_t mMeSpeedPreset = 100; |
| uint32_t mIInterval = 60; |
| uint32_t mIDRInterval = 60; |
| uint32_t mDisableDeblockLevel = 0; |
| uint32_t m_I_QP = 22; |
| uint32_t m_P_QP = 28; |
| uint32_t m_B_QP = 22; |
| uint32_t mIntraRefresh = 30; |
| uint32_t mSearchRangeX = 64; |
| uint32_t mSearchRangeY = 48; |
| uint32_t mForceIdrInterval = 0; // in number of frames |
| uint32_t mDynamicBitRateInterval = 0; // in number of frames |
| uint32_t mDynamicFrameRateInterval = 0; // in number of frames |
| uint64_t mBitrate = 6000000; |
| float mFrameRate = 30; |
| iv_obj_t *mCodecCtx = nullptr; |
| iv_mem_rec_t *mMemRecords = nullptr; |
| IVE_AIR_MODE_T mAirMode = IVE_AIR_MODE_NONE; |
| IVE_SPEED_CONFIG mEncSpeed = IVE_NORMAL; |
| IVE_RC_MODE_T mRCMode = IVE_RC_STORAGE; |
| IV_ARCH_T mArch = ARCH_NA; |
| IVE_SLICE_MODE_T mSliceMode = IVE_SLICE_MODE_NONE; |
| IV_COLOR_FORMAT_T mIvVideoColorFormat = IV_YUV_420P; |
| IV_COLOR_FORMAT_T mReconFormat = IV_YUV_420P; |
| IV_PROFILE_T mProfile = IV_PROFILE_BASE; |
| }; |
| |
| bool Codec::initEncoder(const uint8_t **pdata, size_t *psize) { |
| uint8_t *data = const_cast<uint8_t *>(*pdata); |
| mWidth = ((data[IDX_WD_BYTE_1] << 8) | data[IDX_WD_BYTE_2]) % kMaxWidth; |
| mHeight = ((data[IDX_HT_BYTE_1] << 8) | data[IDX_HT_BYTE_2]) % kMaxHeight; |
| |
| mIvVideoColorFormat = |
| kSupportedColorFormats[data[IDX_COLOR_FORMAT] % kSupportedColorFormatsNum]; |
| mArch = ((data[IDX_ARCH_TYPE] & 0x03) == 0x00) ? ARCH_ARM_NONEON : ARCH_NA; |
| mRCMode = kRCMode[data[IDX_RC_MODE] % kRCModeNum]; |
| mNumCores = (data[IDX_NUM_CORES] & 0x07) + 1; |
| mBframes = data[IDX_NUM_B_FRAMES] & 0x07; |
| 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] % (MAX_H264_QP - kMinQP)) + kMinQP; |
| m_P_QP = (data[IDX_P_FRAME_QP] % (MAX_H264_QP - kMinQP)) + kMinQP; |
| m_B_QP = (data[IDX_B_FRAME_QP] % (MAX_H264_QP - kMinQP)) + kMinQP; |
| mBitrate = (((data[IDX_BITRATE_BYTE_1] << 8) | data[IDX_BITRATE_BYTE_2]) * 1000) % kMaxBitrate; |
| mFrameRate = data[IDX_FRAME_RATE]; |
| 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 = data[IDX_DISABLE_DEBLOCK_LEVEL] & 0x03; |
| 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 = kProfle[data[IDX_PROFILE] % kProfleNum]; |
| 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; |
| |
| /* Getting Number of MemRecords */ |
| iv_num_mem_rec_ip_t sNumMemRecIp{}; |
| iv_num_mem_rec_op_t sNumMemRecOp{}; |
| |
| sNumMemRecIp.u4_size = sizeof(iv_num_mem_rec_ip_t); |
| sNumMemRecOp.u4_size = sizeof(iv_num_mem_rec_op_t); |
| sNumMemRecIp.e_cmd = IV_CMD_GET_NUM_MEM_REC; |
| |
| if (IV_SUCCESS != ive_api_function(nullptr, &sNumMemRecIp, &sNumMemRecOp)) { |
| return false; |
| } |
| mNumMemRecords = sNumMemRecOp.u4_num_mem_rec; |
| mMemRecords = (iv_mem_rec_t *)malloc(mNumMemRecords * sizeof(iv_mem_rec_t)); |
| if (!mMemRecords) { |
| return false; |
| } |
| iv_mem_rec_t *psMemRec; |
| psMemRec = mMemRecords; |
| for (size_t i = 0; i < mNumMemRecords; ++i) { |
| psMemRec->u4_size = sizeof(iv_mem_rec_t); |
| psMemRec->pv_base = nullptr; |
| psMemRec->u4_mem_size = 0; |
| psMemRec->u4_mem_alignment = 0; |
| psMemRec->e_mem_type = IV_NA_MEM_TYPE; |
| ++psMemRec; |
| } |
| |
| /* Getting MemRecords Attributes */ |
| iv_fill_mem_rec_ip_t sFillMemRecIp{}; |
| iv_fill_mem_rec_op_t sFillMemRecOp{}; |
| |
| sFillMemRecIp.u4_size = sizeof(iv_fill_mem_rec_ip_t); |
| sFillMemRecOp.u4_size = sizeof(iv_fill_mem_rec_op_t); |
| |
| sFillMemRecIp.e_cmd = IV_CMD_FILL_NUM_MEM_REC; |
| sFillMemRecIp.ps_mem_rec = mMemRecords; |
| sFillMemRecIp.u4_num_mem_rec = mNumMemRecords; |
| sFillMemRecIp.u4_max_wd = mWidth; |
| sFillMemRecIp.u4_max_ht = mHeight; |
| sFillMemRecIp.u4_max_level = mAvcEncLevel; |
| sFillMemRecIp.e_color_format = IV_YUV_420SP_VU; |
| sFillMemRecIp.u4_max_ref_cnt = 2; |
| sFillMemRecIp.u4_max_reorder_cnt = 0; |
| sFillMemRecIp.u4_max_srch_rng_x = 256; |
| sFillMemRecIp.u4_max_srch_rng_y = 256; |
| |
| if (IV_SUCCESS != ive_api_function(nullptr, &sFillMemRecIp, &sFillMemRecOp)) { |
| return false; |
| } |
| /* Allocating Memory for Mem Records */ |
| psMemRec = mMemRecords; |
| for (size_t i = 0; i < mNumMemRecords; ++i) { |
| posix_memalign(&psMemRec->pv_base, psMemRec->u4_mem_alignment, psMemRec->u4_mem_size); |
| if (!psMemRec->pv_base) { |
| return false; |
| } |
| ++psMemRec; |
| } |
| |
| /* Codec Instance Creation */ |
| ive_init_ip_t sInitIp{}; |
| ive_init_op_t sInitOp{}; |
| |
| mCodecCtx = (iv_obj_t *)mMemRecords[0].pv_base; |
| mCodecCtx->u4_size = sizeof(iv_obj_t); |
| mCodecCtx->pv_fxns = (void *)ive_api_function; |
| |
| sInitIp.u4_size = sizeof(ive_init_ip_t); |
| sInitOp.u4_size = sizeof(ive_init_op_t); |
| |
| sInitIp.e_cmd = IV_CMD_INIT; |
| sInitIp.u4_num_mem_rec = mNumMemRecords; |
| sInitIp.ps_mem_rec = mMemRecords; |
| sInitIp.u4_max_wd = mWidth; |
| sInitIp.u4_max_ht = mHeight; |
| sInitIp.u4_max_ref_cnt = 2; |
| sInitIp.u4_max_reorder_cnt = 0; |
| sInitIp.u4_max_level = mAvcEncLevel; |
| sInitIp.e_inp_color_fmt = mIvVideoColorFormat; |
| sInitIp.u4_enable_recon = 0; |
| sInitIp.e_recon_color_fmt = mReconFormat; |
| sInitIp.e_rc_mode = mRCMode; |
| sInitIp.u4_max_framerate = 120000; |
| sInitIp.u4_max_bitrate = 240000000; |
| sInitIp.u4_num_bframes = mBframes; |
| sInitIp.e_content_type = IV_PROGRESSIVE; |
| sInitIp.u4_max_srch_rng_x = 256; |
| sInitIp.u4_max_srch_rng_y = 256; |
| sInitIp.e_slice_mode = mSliceMode; |
| sInitIp.u4_slice_param = mSliceParam; |
| sInitIp.e_arch = mArch; |
| sInitIp.e_soc = SOC_GENERIC; |
| |
| if (IV_SUCCESS != ive_api_function(mCodecCtx, &sInitIp, &sInitOp)) { |
| return false; |
| } |
| |
| logVersion(); |
| setDefault(); |
| getBufInfo(); |
| setNumCores(); |
| setDimensions(); |
| setFrameRate(); |
| setIpeParams(); |
| setBitRate(); |
| setQp(); |
| setAirParams(); |
| setVbvParams(); |
| setMeParams(); |
| setGopParams(); |
| setDeblockParams(); |
| setVuiParams(); |
| setSeiMdcvParams(); |
| setSeiCllParams(); |
| setSeiAveParams(); |
| setSeiCcvParams(); |
| setProfileParams(); |
| setEncMode(IVE_ENC_MODE_HEADER); |
| |
| *pdata += IDX_LAST; |
| *psize -= IDX_LAST; |
| return true; |
| } |
| |
| void Codec::setDimensions() { |
| ive_ctl_set_dimensions_ip_t sDimensionsIp{}; |
| ive_ctl_set_dimensions_op_t sDimensionsOp{}; |
| |
| sDimensionsIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sDimensionsIp.e_sub_cmd = IVE_CMD_CTL_SET_DIMENSIONS; |
| sDimensionsIp.u4_ht = mHeight; |
| sDimensionsIp.u4_wd = mWidth; |
| |
| sDimensionsIp.u4_timestamp_high = -1; |
| sDimensionsIp.u4_timestamp_low = -1; |
| |
| sDimensionsIp.u4_size = sizeof(ive_ctl_set_dimensions_ip_t); |
| sDimensionsOp.u4_size = sizeof(ive_ctl_set_dimensions_op_t); |
| |
| ive_api_function(mCodecCtx, &sDimensionsIp, &sDimensionsOp); |
| return; |
| } |
| |
| void Codec::setNumCores() { |
| ive_ctl_set_num_cores_ip_t sNumCoresIp{}; |
| ive_ctl_set_num_cores_op_t sNumCoresOp{}; |
| |
| sNumCoresIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sNumCoresIp.e_sub_cmd = IVE_CMD_CTL_SET_NUM_CORES; |
| sNumCoresIp.u4_num_cores = mNumCores; |
| |
| sNumCoresIp.u4_timestamp_high = -1; |
| sNumCoresIp.u4_timestamp_low = -1; |
| |
| sNumCoresIp.u4_size = sizeof(ive_ctl_set_num_cores_ip_t); |
| sNumCoresOp.u4_size = sizeof(ive_ctl_set_num_cores_op_t); |
| |
| ive_api_function(mCodecCtx, (void *)&sNumCoresIp, (void *)&sNumCoresOp); |
| return; |
| } |
| |
| void Codec::setDefault() { |
| ive_ctl_setdefault_ip_t sDefaultIp{}; |
| ive_ctl_setdefault_op_t sDefaultOp{}; |
| |
| sDefaultIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sDefaultIp.e_sub_cmd = IVE_CMD_CTL_SETDEFAULT; |
| |
| sDefaultIp.u4_timestamp_high = -1; |
| sDefaultIp.u4_timestamp_low = -1; |
| |
| sDefaultIp.u4_size = sizeof(ive_ctl_setdefault_ip_t); |
| sDefaultOp.u4_size = sizeof(ive_ctl_setdefault_op_t); |
| |
| ive_api_function(mCodecCtx, &sDefaultIp, &sDefaultOp); |
| return; |
| } |
| |
| void Codec::getBufInfo() { |
| ih264e_ctl_getbufinfo_ip_t sGetBufInfoIp{}; |
| ih264e_ctl_getbufinfo_op_t sGetBufInfoOp{}; |
| |
| sGetBufInfoIp.s_ive_ip.u4_size = sizeof(ih264e_ctl_getbufinfo_ip_t); |
| sGetBufInfoOp.s_ive_op.u4_size = sizeof(ih264e_ctl_getbufinfo_op_t); |
| |
| sGetBufInfoIp.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; |
| sGetBufInfoIp.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_GETBUFINFO; |
| sGetBufInfoIp.s_ive_ip.u4_max_ht = mHeight; |
| sGetBufInfoIp.s_ive_ip.u4_max_wd = mWidth; |
| sGetBufInfoIp.s_ive_ip.e_inp_color_fmt = mIvVideoColorFormat; |
| |
| ih264e_api_function(mCodecCtx, &sGetBufInfoIp, &sGetBufInfoOp); |
| return; |
| } |
| |
| void Codec::setFrameRate() { |
| ive_ctl_set_frame_rate_ip_t sFrameRateIp{}; |
| ive_ctl_set_frame_rate_op_t sFrameRateOp{}; |
| |
| sFrameRateIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sFrameRateIp.e_sub_cmd = IVE_CMD_CTL_SET_FRAMERATE; |
| sFrameRateIp.u4_src_frame_rate = mFrameRate; |
| sFrameRateIp.u4_tgt_frame_rate = mFrameRate; |
| |
| sFrameRateIp.u4_timestamp_high = -1; |
| sFrameRateIp.u4_timestamp_low = -1; |
| |
| sFrameRateIp.u4_size = sizeof(ive_ctl_set_frame_rate_ip_t); |
| sFrameRateOp.u4_size = sizeof(ive_ctl_set_frame_rate_op_t); |
| |
| ive_api_function(mCodecCtx, &sFrameRateIp, &sFrameRateOp); |
| return; |
| } |
| |
| void Codec::setIpeParams() { |
| ive_ctl_set_ipe_params_ip_t sIpeParamsIp{}; |
| ive_ctl_set_ipe_params_op_t sIpeParamsOp{}; |
| |
| sIpeParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sIpeParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_IPE_PARAMS; |
| sIpeParamsIp.u4_enable_intra_4x4 = mIntra4x4; |
| sIpeParamsIp.u4_enc_speed_preset = mEncSpeed; |
| sIpeParamsIp.u4_constrained_intra_pred = mConstrainedIntraFlag; |
| |
| sIpeParamsIp.u4_timestamp_high = -1; |
| sIpeParamsIp.u4_timestamp_low = -1; |
| |
| sIpeParamsIp.u4_size = sizeof(ive_ctl_set_ipe_params_ip_t); |
| sIpeParamsOp.u4_size = sizeof(ive_ctl_set_ipe_params_op_t); |
| |
| ive_api_function(mCodecCtx, &sIpeParamsIp, &sIpeParamsOp); |
| return; |
| } |
| |
| void Codec::setBitRate() { |
| ive_ctl_set_bitrate_ip_t sBitrateIp{}; |
| ive_ctl_set_bitrate_op_t sBitrateOp{}; |
| |
| sBitrateIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sBitrateIp.e_sub_cmd = IVE_CMD_CTL_SET_BITRATE; |
| sBitrateIp.u4_target_bitrate = mBitrate; |
| |
| sBitrateIp.u4_timestamp_high = -1; |
| sBitrateIp.u4_timestamp_low = -1; |
| |
| sBitrateIp.u4_size = sizeof(ive_ctl_set_bitrate_ip_t); |
| sBitrateOp.u4_size = sizeof(ive_ctl_set_bitrate_op_t); |
| |
| ive_api_function(mCodecCtx, &sBitrateIp, &sBitrateOp); |
| return; |
| } |
| |
| void Codec::setFrameType(IV_PICTURE_CODING_TYPE_T eFrameType) { |
| ive_ctl_set_frame_type_ip_t sFrameTypeIp{}; |
| ive_ctl_set_frame_type_op_t sFrameTypeOp{}; |
| |
| sFrameTypeIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sFrameTypeIp.e_sub_cmd = IVE_CMD_CTL_SET_FRAMETYPE; |
| sFrameTypeIp.e_frame_type = eFrameType; |
| |
| sFrameTypeIp.u4_timestamp_high = -1; |
| sFrameTypeIp.u4_timestamp_low = -1; |
| |
| sFrameTypeIp.u4_size = sizeof(ive_ctl_set_frame_type_ip_t); |
| sFrameTypeOp.u4_size = sizeof(ive_ctl_set_frame_type_op_t); |
| |
| ive_api_function(mCodecCtx, &sFrameTypeIp, &sFrameTypeOp); |
| return; |
| } |
| |
| void Codec::setQp() { |
| ive_ctl_set_qp_ip_t s_QpIp{}; |
| ive_ctl_set_qp_op_t s_QpOp{}; |
| |
| s_QpIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| s_QpIp.e_sub_cmd = IVE_CMD_CTL_SET_QP; |
| |
| s_QpIp.u4_i_qp = m_I_QP; |
| s_QpIp.u4_i_qp_max = MAX_H264_QP; |
| s_QpIp.u4_i_qp_min = kMinQP; |
| |
| s_QpIp.u4_p_qp = m_P_QP; |
| s_QpIp.u4_p_qp_max = MAX_H264_QP; |
| s_QpIp.u4_p_qp_min = kMinQP; |
| |
| s_QpIp.u4_b_qp = m_B_QP; |
| s_QpIp.u4_b_qp_max = MAX_H264_QP; |
| s_QpIp.u4_b_qp_min = kMinQP; |
| |
| s_QpIp.u4_timestamp_high = -1; |
| s_QpIp.u4_timestamp_low = -1; |
| |
| s_QpIp.u4_size = sizeof(ive_ctl_set_qp_ip_t); |
| s_QpOp.u4_size = sizeof(ive_ctl_set_qp_op_t); |
| |
| ive_api_function(mCodecCtx, &s_QpIp, &s_QpOp); |
| return; |
| } |
| |
| void Codec::setEncMode(IVE_ENC_MODE_T eEncMode) { |
| ive_ctl_set_enc_mode_ip_t sEncModeIp{}; |
| ive_ctl_set_enc_mode_op_t sEncModeOp{}; |
| |
| sEncModeIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sEncModeIp.e_sub_cmd = IVE_CMD_CTL_SET_ENC_MODE; |
| sEncModeIp.e_enc_mode = eEncMode; |
| |
| sEncModeIp.u4_timestamp_high = -1; |
| sEncModeIp.u4_timestamp_low = -1; |
| |
| sEncModeIp.u4_size = sizeof(ive_ctl_set_enc_mode_ip_t); |
| sEncModeOp.u4_size = sizeof(ive_ctl_set_enc_mode_op_t); |
| |
| ive_api_function(mCodecCtx, &sEncModeIp, &sEncModeOp); |
| return; |
| } |
| |
| void Codec::setVbvParams() { |
| ive_ctl_set_vbv_params_ip_t sVbvIp{}; |
| ive_ctl_set_vbv_params_op_t sVbvOp{}; |
| |
| sVbvIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sVbvIp.e_sub_cmd = IVE_CMD_CTL_SET_VBV_PARAMS; |
| sVbvIp.u4_vbv_buf_size = 0; |
| sVbvIp.u4_vbv_buffer_delay = 1000; |
| |
| sVbvIp.u4_timestamp_high = -1; |
| sVbvIp.u4_timestamp_low = -1; |
| |
| sVbvIp.u4_size = sizeof(ive_ctl_set_vbv_params_ip_t); |
| sVbvOp.u4_size = sizeof(ive_ctl_set_vbv_params_op_t); |
| |
| ive_api_function(mCodecCtx, &sVbvIp, &sVbvOp); |
| return; |
| } |
| |
| void Codec::setAirParams() { |
| ive_ctl_set_air_params_ip_t sAirIp{}; |
| ive_ctl_set_air_params_op_t sAirOp{}; |
| |
| sAirIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sAirIp.e_sub_cmd = IVE_CMD_CTL_SET_AIR_PARAMS; |
| sAirIp.e_air_mode = mAirMode; |
| sAirIp.u4_air_refresh_period = mIntraRefresh; |
| |
| sAirIp.u4_timestamp_high = -1; |
| sAirIp.u4_timestamp_low = -1; |
| |
| sAirIp.u4_size = sizeof(ive_ctl_set_air_params_ip_t); |
| sAirOp.u4_size = sizeof(ive_ctl_set_air_params_op_t); |
| |
| ive_api_function(mCodecCtx, &sAirIp, &sAirOp); |
| return; |
| } |
| |
| void Codec::setMeParams() { |
| ive_ctl_set_me_params_ip_t sMeParamsIp{}; |
| ive_ctl_set_me_params_op_t sMeParamsOp{}; |
| |
| sMeParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sMeParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_ME_PARAMS; |
| sMeParamsIp.u4_enable_fast_sad = mEnableFastSad; |
| sMeParamsIp.u4_enable_alt_ref = mEnableAltRef; |
| |
| sMeParamsIp.u4_enable_hpel = mHalfPelEnable; |
| sMeParamsIp.u4_enable_qpel = mQPelEnable; |
| sMeParamsIp.u4_me_speed_preset = mMeSpeedPreset; |
| sMeParamsIp.u4_srch_rng_x = mSearchRangeX; |
| sMeParamsIp.u4_srch_rng_y = mSearchRangeY; |
| |
| sMeParamsIp.u4_timestamp_high = -1; |
| sMeParamsIp.u4_timestamp_low = -1; |
| |
| sMeParamsIp.u4_size = sizeof(ive_ctl_set_me_params_ip_t); |
| sMeParamsOp.u4_size = sizeof(ive_ctl_set_me_params_op_t); |
| |
| ive_api_function(mCodecCtx, &sMeParamsIp, &sMeParamsOp); |
| return; |
| } |
| |
| void Codec::setGopParams() { |
| ive_ctl_set_gop_params_ip_t sGopParamsIp{}; |
| ive_ctl_set_gop_params_op_t sGopParamsOp{}; |
| |
| sGopParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sGopParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_GOP_PARAMS; |
| |
| sGopParamsIp.u4_i_frm_interval = mIInterval; |
| sGopParamsIp.u4_idr_frm_interval = mIDRInterval; |
| |
| sGopParamsIp.u4_timestamp_high = -1; |
| sGopParamsIp.u4_timestamp_low = -1; |
| |
| sGopParamsIp.u4_size = sizeof(ive_ctl_set_gop_params_ip_t); |
| sGopParamsOp.u4_size = sizeof(ive_ctl_set_gop_params_op_t); |
| |
| ive_api_function(mCodecCtx, &sGopParamsIp, &sGopParamsOp); |
| return; |
| } |
| |
| void Codec::setProfileParams() { |
| ive_ctl_set_profile_params_ip_t sProfileParamsIp{}; |
| ive_ctl_set_profile_params_op_t sProfileParamsOp{}; |
| |
| sProfileParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sProfileParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_PROFILE_PARAMS; |
| |
| sProfileParamsIp.e_profile = mProfile; |
| if (sProfileParamsIp.e_profile == IV_PROFILE_BASE) { |
| sProfileParamsIp.u4_entropy_coding_mode = 0; |
| } else { |
| sProfileParamsIp.u4_entropy_coding_mode = 1; |
| } |
| sProfileParamsIp.u4_timestamp_high = -1; |
| sProfileParamsIp.u4_timestamp_low = -1; |
| |
| sProfileParamsIp.u4_size = sizeof(ive_ctl_set_profile_params_ip_t); |
| sProfileParamsOp.u4_size = sizeof(ive_ctl_set_profile_params_op_t); |
| |
| ive_api_function(mCodecCtx, &sProfileParamsIp, &sProfileParamsOp); |
| return; |
| } |
| |
| void Codec::setDeblockParams() { |
| ive_ctl_set_deblock_params_ip_t sDeblockParamsIp{}; |
| ive_ctl_set_deblock_params_op_t sDeblockParamsOp{}; |
| |
| sDeblockParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sDeblockParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_DEBLOCK_PARAMS; |
| |
| sDeblockParamsIp.u4_disable_deblock_level = mDisableDeblockLevel; |
| |
| sDeblockParamsIp.u4_timestamp_high = -1; |
| sDeblockParamsIp.u4_timestamp_low = -1; |
| |
| sDeblockParamsIp.u4_size = sizeof(ive_ctl_set_deblock_params_ip_t); |
| sDeblockParamsOp.u4_size = sizeof(ive_ctl_set_deblock_params_op_t); |
| |
| ive_api_function(mCodecCtx, &sDeblockParamsIp, &sDeblockParamsOp); |
| return; |
| } |
| |
| void Codec::setVuiParams() { |
| ih264e_vui_ip_t sVuiParamsIp{}; |
| ih264e_vui_op_t sVuiParamsOp{}; |
| |
| sVuiParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sVuiParamsIp.e_sub_cmd = IVE_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 = 1; |
| 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(ih264e_vui_ip_t); |
| sVuiParamsOp.u4_size = sizeof(ih264e_vui_op_t); |
| |
| ive_api_function(mCodecCtx, &sVuiParamsIp, &sVuiParamsOp); |
| return; |
| } |
| |
| void Codec::setSeiMdcvParams() { |
| ih264e_ctl_set_sei_mdcv_params_ip_t sSeiMdcvParamsIp{}; |
| ih264e_ctl_set_sei_mdcv_params_op_t sSeiMdcvParamsOp{}; |
| |
| sSeiMdcvParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sSeiMdcvParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_MDCV_PARAMS; |
| sSeiMdcvParamsIp.u1_sei_mdcv_params_present_flag = mSeiMdcvFlag; |
| if (mSeiMdcvFlag) { |
| for (int i4_count = 0; i4_count < NUM_SEI_MDCV_PRIMARIES; ++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 = -1; |
| sSeiMdcvParamsIp.u4_timestamp_low = -1; |
| |
| sSeiMdcvParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_mdcv_params_ip_t); |
| sSeiMdcvParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_mdcv_params_op_t); |
| ih264e_api_function(mCodecCtx, &sSeiMdcvParamsIp, &sSeiMdcvParamsOp); |
| return; |
| } |
| |
| void Codec::setSeiCllParams() { |
| ih264e_ctl_set_sei_cll_params_ip_t sSeiCllParamsIp{}; |
| ih264e_ctl_set_sei_cll_params_op_t sSeiCllParamsOp{}; |
| |
| sSeiCllParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sSeiCllParamsIp.e_sub_cmd = IVE_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 = -1; |
| sSeiCllParamsIp.u4_timestamp_low = -1; |
| |
| sSeiCllParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_cll_params_ip_t); |
| sSeiCllParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_cll_params_op_t); |
| |
| ih264e_api_function(mCodecCtx, &sSeiCllParamsIp, &sSeiCllParamsOp); |
| return; |
| } |
| |
| void Codec::setSeiAveParams() { |
| ih264e_ctl_set_sei_ave_params_ip_t sSeiAveParamsIp{}; |
| ih264e_ctl_set_sei_ave_params_op_t sSeiAveParamsOp{}; |
| |
| sSeiAveParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sSeiAveParamsIp.e_sub_cmd = IVE_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 = -1; |
| sSeiAveParamsIp.u4_timestamp_low = -1; |
| |
| sSeiAveParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_ave_params_ip_t); |
| sSeiAveParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_ave_params_op_t); |
| |
| ih264e_api_function(mCodecCtx, &sSeiAveParamsIp, &sSeiAveParamsOp); |
| return; |
| } |
| |
| void Codec::setSeiCcvParams() { |
| ih264e_ctl_set_sei_ccv_params_ip_t sSeiCcvParamsIp{}; |
| ih264e_ctl_set_sei_ccv_params_op_t sSeiCcvParamsOp{}; |
| |
| sSeiCcvParamsIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sSeiCcvParamsIp.e_sub_cmd = IVE_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 < NUM_SEI_CCV_PRIMARIES; ++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 = -1; |
| sSeiCcvParamsIp.u4_timestamp_low = -1; |
| |
| sSeiCcvParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_ccv_params_ip_t); |
| sSeiCcvParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_ccv_params_op_t); |
| |
| ih264e_api_function(mCodecCtx, &sSeiCcvParamsIp, &sSeiCcvParamsOp); |
| return; |
| } |
| |
| void Codec::logVersion() { |
| ive_ctl_getversioninfo_ip_t sCtlIp{}; |
| ive_ctl_getversioninfo_op_t sCtlOp{}; |
| UWORD8 au1Buf[512]; |
| |
| sCtlIp.e_cmd = IVE_CMD_VIDEO_CTL; |
| sCtlIp.e_sub_cmd = IVE_CMD_CTL_GETVERSION; |
| |
| sCtlIp.u4_size = sizeof(ive_ctl_getversioninfo_ip_t); |
| sCtlOp.u4_size = sizeof(ive_ctl_getversioninfo_op_t); |
| sCtlIp.pu1_version = au1Buf; |
| sCtlIp.u4_version_bufsize = sizeof(au1Buf); |
| |
| ive_api_function(mCodecCtx, (void *)&sCtlIp, (void *)&sCtlOp); |
| return; |
| } |
| |
| void Codec::encodeFrames(const uint8_t *data, size_t size) { |
| size_t frameSize = (mIvVideoColorFormat == IV_YUV_422ILE) ? (mWidth * mHeight * 2) |
| : ((mWidth * mHeight * 3) / 2); |
| ive_video_encode_ip_t sEncodeIp{}; |
| ive_video_encode_op_t sEncodeOp{}; |
| uint8_t header[kHeaderLength]; |
| iv_raw_buf_t *psInpRawBuf = &sEncodeIp.s_inp_buf; |
| sEncodeIp.s_out_buf.pv_buf = header; |
| sEncodeIp.s_out_buf.u4_bytes = 0; |
| sEncodeIp.s_out_buf.u4_bufsize = kHeaderLength; |
| sEncodeIp.u4_size = sizeof(ive_video_encode_ip_t); |
| sEncodeOp.u4_size = sizeof(ive_video_encode_op_t); |
| |
| sEncodeIp.e_cmd = IVE_CMD_VIDEO_ENCODE; |
| sEncodeIp.pv_bufs = nullptr; |
| sEncodeIp.pv_mb_info = nullptr; |
| sEncodeIp.pv_pic_info = nullptr; |
| sEncodeIp.u4_mb_info_type = 0; |
| sEncodeIp.u4_pic_info_type = 0; |
| sEncodeIp.u4_is_last = 0; |
| sEncodeOp.s_out_buf.pv_buf = nullptr; |
| |
| /* Initialize color formats */ |
| memset(psInpRawBuf, 0, sizeof(iv_raw_buf_t)); |
| psInpRawBuf->u4_size = sizeof(iv_raw_buf_t); |
| psInpRawBuf->e_color_fmt = mIvVideoColorFormat; |
| |
| ive_api_function(mCodecCtx, &sEncodeIp, &sEncodeOp); |
| size_t numFrame = 0; |
| while (size > 0) { |
| uint8_t *tmpData = (uint8_t *)malloc(frameSize); |
| size_t bytesConsumed = std::min(size, frameSize); |
| if (bytesConsumed < frameSize) { |
| memset(&tmpData[bytesConsumed], data[0], frameSize - bytesConsumed); |
| } |
| memcpy(tmpData, data, bytesConsumed); |
| setEncParams(psInpRawBuf, tmpData); |
| uint64_t OutputBufferSize = (frameSize / kCompressionRatio); |
| uint8_t *OutputBuffer = (uint8_t *)malloc(OutputBufferSize); |
| sEncodeIp.s_out_buf.pv_buf = OutputBuffer; |
| sEncodeIp.s_out_buf.u4_bufsize = OutputBufferSize; |
| if (mIsForceIdrEnabled) { |
| if (numFrame == mForceIdrInterval) { |
| setFrameType(IV_IDR_FRAME); |
| } |
| } |
| if (mIsDynamicBitRateChangeEnabled) { |
| if (numFrame == mDynamicBitRateInterval) { |
| if (data[0] & 0x01) { |
| mBitrate *= 2; |
| } else { |
| mBitrate /= 2; |
| } |
| setBitRate(); |
| } |
| } |
| if (mIsDynamicFrameRateChangeEnabled) { |
| if (numFrame == mDynamicFrameRateInterval) { |
| if (size > 1 && data[1] & 0x01) { |
| mFrameRate *= 2; |
| } else { |
| mFrameRate /= 2; |
| } |
| setFrameRate(); |
| } |
| } |
| ive_api_function(mCodecCtx, &sEncodeIp, &sEncodeOp); |
| ++numFrame; |
| data += bytesConsumed; |
| size -= bytesConsumed; |
| free(tmpData); |
| free(OutputBuffer); |
| } |
| } |
| |
| void Codec::setEncParams(iv_raw_buf_t *psInpRawBuf, const uint8_t *data) { |
| switch (mIvVideoColorFormat) { |
| case IV_YUV_420SP_UV: |
| [[fallthrough]]; |
| case IV_YUV_420SP_VU: { |
| uint8_t *yPlane = const_cast<uint8_t *>(data); |
| uint8_t *uPlane = const_cast<uint8_t *>(data + (mWidth * mHeight)); |
| int32_t yStride = mWidth; |
| int32_t uStride = mWidth / 2; |
| psInpRawBuf->apv_bufs[0] = yPlane; |
| psInpRawBuf->apv_bufs[1] = uPlane; |
| |
| psInpRawBuf->au4_wd[0] = mWidth; |
| psInpRawBuf->au4_wd[1] = mWidth; |
| |
| psInpRawBuf->au4_ht[0] = mHeight; |
| psInpRawBuf->au4_ht[1] = mHeight / 2; |
| |
| psInpRawBuf->au4_strd[0] = yStride; |
| psInpRawBuf->au4_strd[1] = uStride; |
| break; |
| } |
| case IV_YUV_422ILE: { |
| uint8_t *yPlane = const_cast<uint8_t *>(data); |
| psInpRawBuf->apv_bufs[0] = yPlane; |
| |
| psInpRawBuf->au4_wd[0] = mWidth * 2; |
| |
| psInpRawBuf->au4_ht[0] = mHeight; |
| |
| psInpRawBuf->au4_strd[0] = mWidth * 2; |
| break; |
| } |
| case IV_YUV_420P: |
| [[fallthrough]]; |
| default: { |
| uint8_t *yPlane = const_cast<uint8_t *>(data); |
| uint8_t *uPlane = const_cast<uint8_t *>(data + (mWidth * mHeight)); |
| uint8_t *vPlane = const_cast<uint8_t *>(data + ((mWidth * mHeight) * 5) / 4); |
| int32_t yStride = mWidth; |
| int32_t uStride = mWidth / 2; |
| int32_t vStride = mWidth / 2; |
| |
| psInpRawBuf->apv_bufs[0] = yPlane; |
| psInpRawBuf->apv_bufs[1] = uPlane; |
| psInpRawBuf->apv_bufs[2] = vPlane; |
| |
| psInpRawBuf->au4_wd[0] = mWidth; |
| psInpRawBuf->au4_wd[1] = mWidth / 2; |
| psInpRawBuf->au4_wd[2] = mWidth / 2; |
| |
| psInpRawBuf->au4_ht[0] = mHeight; |
| psInpRawBuf->au4_ht[1] = mHeight / 2; |
| psInpRawBuf->au4_ht[2] = mHeight / 2; |
| |
| psInpRawBuf->au4_strd[0] = yStride; |
| psInpRawBuf->au4_strd[1] = uStride; |
| psInpRawBuf->au4_strd[2] = vStride; |
| break; |
| } |
| } |
| return; |
| } |
| |
| void Codec::deInitEncoder() { |
| iv_mem_rec_t *ps_mem_rec = mMemRecords; |
| for (size_t i = 0; i < mNumMemRecords; ++i) { |
| if (ps_mem_rec) { |
| free(ps_mem_rec->pv_base); |
| } |
| ++ps_mem_rec; |
| } |
| if (mMemRecords) { |
| free(mMemRecords); |
| } |
| mCodecCtx = nullptr; |
| return; |
| } |
| |
| extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
| if (size < IDX_LAST) { |
| return 0; |
| } |
| Codec *codec = new Codec(); |
| if (codec->initEncoder(&data, &size)) { |
| codec->encodeFrames(data, size); |
| } |
| delete codec; |
| return 0; |
| } |