📄 mp4_enc.hpp
字号:
#ifdef USE_ME_SADBUFF
Ipp32s *mMEfastSAD;
Ipp32s mMEfastSADsize;
#endif
Ipp32s mRoundingControl;
Ipp32s mReconstructAlways;
Ipp32s mMBNlength;
Ipp32s mVideoPacketLength;
Ipp64s mVOPtime, mSyncTime;
Ipp32s mNumBVOP, mIndxBVOP, mTRB, mTRD, mTframe, mSyncTimeB;
Ipp32s mPadType;
Ipp32s mInsertGOV;
Ipp32s mInsertResync;
Ipp32s mRepeatHeaders;
Ipp32s mRateControl, mBitRate, mBitsEncodedFrame;
Ipp64s mBitsEncodedTotal;
MPEG4_RC mRC;
MPEG4_RC_MB mRC_MB;
Ipp32s mSceneChangeThreshold, mNumIntraMB, mNumNotCodedMB;
Ipp32s mQuantSum;
mp4_Frame *mFrameC, *mFrameF, *mFrameB, *mFrameD;
mp4_Slice mSlice;
mp4_VisualObjectSequence VOS;
mp4_VisualObject VO;
mp4_VideoObjectLayer VOL;
mp4_GroupOfVideoObjectPlane GOV;
mp4_VideoObjectPlane VOP;
// info for each macroblock
mp4_MacroBlock *MBinfo;
// additional buffers for data_partitioned
Ipp8u *mBuffer_1;
Ipp8u *mBuffer_2;
// ippVC specs
IppiWarpSpec_MPEG4 *mWarpSpec;
IppiQuantInterSpec_MPEG4 *mQuantInterSpec;
IppiQuantIntraSpec_MPEG4 *mQuantIntraSpec;
IppiQuantInvInterSpec_MPEG4 *mQuantInvInterSpec;
IppiQuantInvIntraSpec_MPEG4 *mQuantInvIntraSpec;
// buffer for GMC predict of the row of macroblocks
Ipp8u *mGMCPredY, *mGMCPredU, *mGMCPredV;
#ifdef USE_CV_GME
// GMC pyramids
IppiPyramid *mPyramid[2], *mPyrC, *mPyrR;
Ipp32s mPyrLevel, mOptFlowNumPoint, mOptFlowNumPointX, mOptFlowNumPointY, mOptFlowWinSize;
IppiOptFlowPyrLK_8u_C1R *mOptFlowState;
IppiPoint_32f *mOptFlowPoints, *mOptFlowPtC, *mOptFlowPtR;
Ipp8s *mOptFlowPtSts, *mOptFlowMask;
Ipp32f *mOptFlowPatchDiff;
#endif
// buffers for RPT support
Ipp8u *mMBquant;
IppMotionVector *mMBpredMV;
Ipp32u *mMBpos;
public :
Ipp32s mLumaPlaneSize;
Ipp32s mChromaPlaneSize;
Ipp32s mPlanes;
Ipp32s mExpandSizeA;
Ipp32s mStepLuma;
Ipp32s mStepChroma;
mp4_Frame *mFrame;
int Init(mp4_Param *par, int numThreads);
void Close();
ippVideoEncoderMPEG4() { mIsInit = false; };
ippVideoEncoderMPEG4(mp4_Param *par) { mIsInit = false; Init(par, 0); };
~ippVideoEncoderMPEG4() { Close(); };
Ipp32s EncodeHeader();
Ipp32s EncodeFrame(Ipp32s noMoreData);
void InitBuffer(Ipp8u *ptr, Ipp32s size) { cBS.Init(ptr, size); };
Ipp8u* GetBufferPtr() { return cBS.GetPtr(); };
Ipp32s GetBufferFullness() { return cBS.GetFullness(); };
void GetBufferPos(Ipp8u **ptr, Ipp32s *bitOff) { cBS.GetPos(ptr, bitOff); };
void ResetBuffer() { cBS.Reset(); };
Ipp32s GetFrameQuantSum() { return mQuantSum; };
Ipp32s GetFrameMacroBlockPerRow() { return mNumMacroBlockPerRow; };
Ipp32s GetFrameMacroBlockPerCol() { return mNumMacroBlockPerCol; };
Ipp32s GetFrameType() { return VOL.short_video_header ? VOP.picture_coding_type : VOP.vop_coding_type; };
Ipp32s GetCurrentFrameInfo(Ipp8u **pY, Ipp8u **pU, Ipp8u **pV, Ipp32s *stepLuma, Ipp32s *stepChroma);
Ipp32s GetDecodedFrameInfo(Ipp8u **pY, Ipp8u **pU, Ipp8u **pV, Ipp32s *stepLuma, Ipp32s *stepChroma);
Ipp64s GetFrameBytesEncoded() { return GetBufferFullness(); };
Ipp32s SetFrameBasicSpriteWarpCoeffs(Ipp32s *du, Ipp32s *dv, Ipp32s bcf);
// for RTP support
Ipp8u* GetFrameQuant() { return mMBquant; };
IppMotionVector* GetFrameMVpred() { return mMBpredMV; };
Ipp32u* GetFrameMBpos() { return mMBpos; };
void ResetRC(Ipp32s bitRate, Ipp64f frameRate);
protected :
void ErrorMessage(const vm_char *msg);
void EncodeStartCode(Ipp8u sc);
void EncodeZeroBitsAlign();
void EncodeStuffingBitsAlign();
void EncodeVideoPacketHeader(ippBitStream &cBS, Ipp32s mbn, Ipp32s quant);
void EncodeGOBHeader(ippBitStream &cBS, Ipp32s gob_number, Ipp32s quant);
void EncodeVOS_Header();
void EncodeVO_Header();
void EncodeVOL_Header();
void EncodeGOV_Header();
void EncodeVOP_Header();
void EncodeVOPSH_Header();
void EncodeIVOP();
void EncodePVOP();
void EncodeBVOP();
void EncodeSVOP();
void EncodeIVOPSH();
void EncodePVOPSH();
void ExpandFrame(Ipp8u *pY, Ipp8u *pU, Ipp8u *pV);
void PadFrame(Ipp8u *pY, Ipp8u *pU, Ipp8u *pV);
void PredictMV(mp4_MacroBlock *MBcurr, Ipp32s i, Ipp32s j, IppMotionVector *mvPred);
void Predict1MV(mp4_MacroBlock *MBcurr, Ipp32s i, Ipp32s j, IppMotionVector *mvPred);
void Predict3MV(mp4_MacroBlock *MBcurr, Ipp32s i, Ipp32s j, IppMotionVector *mvPred, IppMotionVector *mvCurr);
void Predict3MV(mp4_MacroBlock *MBcurr, Ipp32s i, Ipp32s j, IppMotionVector *mvPred, Ipp32s nB);
void PredictIntraDCAC(mp4_MacroBlock *MBcurr, Ipp16s *dcCurr, Ipp32s quant, Ipp32s *predictDir, Ipp32s predAC, Ipp32s *pSum0, Ipp32s *pSum1, Ipp32s *nzCount, Ipp32s nRow);
Ipp32s TransMacroBlockIntra_H263(Ipp8u *pY, Ipp8u *pU, Ipp8u *pV, Ipp16s *coeffMB, Ipp32s *nzCount, Ipp32s quant);
Ipp32s TransMacroBlockInter_H263(Ipp8u *pY, Ipp8u *pU, Ipp8u *pV, Ipp16s *coeffMB, Ipp32s *nzCount, Ipp32s quant, Ipp8u *mcPred, Ipp32s lumaErr);
int TransMacroBlockIntra_MPEG4(Ipp8u *pY, Ipp8u *pU, Ipp8u *pV, Ipp16s *coeffMB, Ipp32s *nzCount, int quant, int row, int col, int *dct_type, int use_intra_dc_vlc, mp4_MacroBlock *MBcurr, int *predDir, int startRow, int *ac_pred, int *pat, int *costRD);
int TransMacroBlockInter_MPEG4(Ipp8u *pYc, Ipp8u *pUc, Ipp8u *pVc, Ipp16s *coeffMB, Ipp32s *nzCount, int quant, Ipp8u *mcPred, int row, int col, int *dct_type, int trellis, int *costRD);
void ReconMacroBlockNotCoded(Ipp8u *pYc, Ipp8u *pUc, Ipp8u *pVc, Ipp8u *mcPred);
void ReconMacroBlockIntra_H263(Ipp8u *pY, Ipp8u *pU, Ipp8u *pV, Ipp16s *coeffMB, Ipp32s quant, Ipp32s pattern);
void ReconMacroBlockInter_H263(Ipp8u *pYc, Ipp8u *pUc, Ipp8u *pVc, Ipp8u *mcPred, Ipp16s *coeffMB, Ipp32s quant, Ipp32s pattern);
void ReconMacroBlockIntra_MPEG4(Ipp8u *pY, Ipp8u *pU, Ipp8u *pV, Ipp16s *coeffMB, Ipp32s quant, mp4_MacroBlock *MBcurr, Ipp32s pattern, Ipp32s dct_type);
void ReconMacroBlockInter_MPEG4(Ipp8u *pYc, Ipp8u *pUc, Ipp8u *pVc, Ipp8u *mcPred, Ipp16s *coeffMB, Ipp32s quant, Ipp32s pattern, Ipp32s dct_type);
void ME_MacroBlock_PSH(mp4_Data_ME *meData, Ipp32s startRow, Ipp32s endRow);
void ME_MacroBlock_P(mp4_Data_ME *meData, Ipp32s startRow, Ipp32s endRow);
void ME_MacroBlock_S(mp4_Data_ME *meData, Ipp32s startRow, Ipp32s endRow);
void ME_Slice(mp4_Slice *slice);
void EncodeISliceSH(mp4_Slice *slice);
void EncodePSliceSH(mp4_Slice *slice);
void EncodeISlice(mp4_Slice *slice);
void EncodePSlice(mp4_Slice *slice);
void EncodeSSlice(mp4_Slice *slice);
void EncodeBSlice(mp4_Slice *slice);
bool FindTransformGMC();
#ifdef USE_CV_GME
void PyramidCalc(const Ipp8u* img, IppiPyramid* pyramid);
#endif
void AdjustSearchRange();
void LimitMV(IppMotionVector *pMV, Ipp32s x, Ipp32s y);
void LimitMVQ(IppMotionVector *pMV, Ipp32s x, Ipp32s y);
void Limit4MV(IppMotionVector *pMV, Ipp32s x, Ipp32s y);
void Limit4MVQ(IppMotionVector *pMV, Ipp32s x, Ipp32s y);
void LimitFMV(IppMotionVector *pMV, Ipp32s x, Ipp32s y);
void LimitFMVQ(IppMotionVector *pMV, Ipp32s x, Ipp32s y);
void LimitCMV(IppMotionVector *pMV, Ipp32s x, Ipp32s y);
#ifdef _OMP_KARABAS
// for threading method 0
void EncodeIRowSH(Ipp32s curRow, Ipp32s threadNum, Ipp32s *nmb);
void EncodePRowSH(Ipp32s curRow, Ipp32s threadNum, Ipp32s *nmb);
void EncodeIRow(Ipp32s curRow, Ipp32s threadNum);
void EncodePRow(Ipp32s curRow, Ipp32s threadNum, Ipp32s *numNotCodedMB);
void EncodeBRow(Ipp32s curRow, Ipp32s threadNum);
void EncodeSRow(Ipp32s curRow, Ipp32s threadNum);
void ME_VOP();
#endif // _OMP_KARABAS
};
#if defined(__INTEL_COMPILER) && !defined(_WIN32_WCE)
#define __ALIGN16(type, name, size) \
__declspec (align(16)) type name[size]
#else
#if defined(_WIN64) || defined(WIN64) || defined(LINUX64)
#define __ALIGN16(type, name, size) \
Ipp8u _a16_##name[(size)*sizeof(type)+15]; type *name = (type*)(((Ipp64s)(_a16_##name) + 15) & ~15)
#else
#define __ALIGN16(type, name, size) \
Ipp8u _a16_##name[(size)*sizeof(type)+15]; type *name = (type*)(((Ipp32s)(_a16_##name) + 15) & ~15)
#endif
#endif
#define mp4_Zero4MV(mv) (mv)[0].dx = (mv)[0].dy = (mv)[1].dx = (mv)[1].dy =(mv)[2].dx = (mv)[2].dy =(mv)[3].dx = (mv)[3].dy = 0
#define mp4_Div2(a) ((a) >= 0 ? ((a) >> 1) : (((a)+1) >> 1))
#define mp4_Div2Round(a) (((a) >> 1) | ((a) & 1))
#define mp4_DivRoundInf(a, b) ((((a) + (((a) >= 0) ? ((b) >> 1) : -((b) >> 1))) / (b)))
#define mp4_Clip(a, l, r) if (a < (l)) a = l; else if (a > (r)) a = r;
#define mp4_ClipL(a, l) if (a < (l)) a = l;
#define mp4_ClipR(a, r) if (a > (r)) a = r;
#define mp4_Abs(a) ((a) >= 0 ? (a) : -(a))
#define mp4_GetNumBits(oPtr, oOff, nPtr, nOff) (Ipp32s)(((nPtr) - (oPtr)) << 3) + (nOff) - (oOff)
#define USE_TABLE_INTRA_DIV
#ifndef USE_TABLE_INTRA_DIV
#define mp4_DivIntraDC(a, b) (((a) + ((b) >> 1)) / (b))
#define mp4_DivIntraAC(a, b) mp4_DivRoundInf(a, b)
#else
// tested on (-2047..2047) // (1..46)
#define mp4_DivIntraDC(a, b) (((a) * mp4_DivIntraDivisor[b] + (1 << 17)) >> 18)
#define mp4_DivIntraAC(a, b) mp4_DivIntraDC(a, b)
#endif
#define MP4_MV_OFF_HP(dx, dy, step) \
(((dx) >> 1) + (step) * ((dy) >> 1))
#define MP4_MV_ACC_HP(dx, dy) \
((((dy) & 1) << 1) + ((dx) & 1))
#define MP4_MV_OFF_QP(dx, dy, step) \
(((dx) >> 2) + (step) * ((dy) >> 2))
#define MP4_MV_ACC_QP(dx, dy) \
((((dy) & 3) << 2) + ((dx) & 3))
#define MP4_MV_ACC_HP_SAD(dx, dy) \
((((dx) & 1) << 3) + (((dy) & 1) << 2))
#define mp4_Copy8x4HP_8u(pSrc, srcStep, pDst, dstStep, mv, rc) \
ippiCopy8x4HP_8u_C1R(pSrc + MP4_MV_OFF_HP((mv)->dx, (mv)->dy, srcStep), srcStep, pDst, dstStep, MP4_MV_ACC_HP((mv)->dx, (mv)->dy), rc)
#define mp4_Copy8x8HP_8u(pSrc, srcStep, pDst, dstStep, mv, rc) \
ippiCopy8x8HP_8u_C1R(pSrc + MP4_MV_OFF_HP((mv)->dx, (mv)->dy, srcStep), srcStep, pDst, dstStep, MP4_MV_ACC_HP((mv)->dx, (mv)->dy), rc)
#define mp4_Copy16x8HP_8u(pSrc, srcStep, pDst, dstStep, mv, rc) \
ippiCopy16x8HP_8u_C1R(pSrc + MP4_MV_OFF_HP((mv)->dx, (mv)->dy, srcStep), srcStep, pDst, dstStep, MP4_MV_ACC_HP((mv)->dx, (mv)->dy), rc)
#define mp4_Copy16x16HP_8u(pSrc, srcStep, pDst, dstStep, mv, rc) \
ippiCopy16x16HP_8u_C1R(pSrc + MP4_MV_OFF_HP((mv)->dx, (mv)->dy, srcStep), srcStep, pDst, dstStep, MP4_MV_ACC_HP((mv)->dx, (mv)->dy), rc)
#define mp4_Copy8x8QP_8u(pSrc, srcStep, pDst, dstStep, mv, rc) \
ippiCopy8x8QP_MPEG4_8u_C1R(pSrc + MP4_MV_OFF_QP((mv)->dx, (mv)->dy, srcStep), srcStep, pDst, dstStep, MP4_MV_ACC_QP((mv)->dx, (mv)->dy), rc)
#define mp4_Copy16x8QP_8u(pSrc, srcStep, pDst, dstStep, mv, rc) \
ippiCopy16x8QP_MPEG4_8u_C1R(pSrc + MP4_MV_OFF_QP((mv)->dx, (mv)->dy, srcStep), srcStep, pDst, dstStep, MP4_MV_ACC_QP((mv)->dx, (mv)->dy), rc)
#define mp4_Copy16x16QP_8u(pSrc, srcStep, pDst, dstStep, mv, rc) \
ippiCopy16x16QP_MPEG4_8u_C1R(pSrc + MP4_MV_OFF_QP((mv)->dx, (mv)->dy, srcStep), srcStep, pDst, dstStep, MP4_MV_ACC_QP((mv)->dx, (mv)->dy), rc)
#define mp4_Add8x8_16s8u(pSrcDst, pResid, srcDstStep) \
ippiAdd8x8_16s8u_C1IRS(pResid, 16, pSrcDst, srcDstStep)
//--------------------- defines to control ME process -------------------------
#define SAD_MAX (16 * 16 * 256)
#define SAD_FAVOR_ZERO 0
#define SAD_FAVOR_PRED (- SAD_FAVOR_ZERO / 2)
#define SAD_FAVOR_DIRECT (quant * 3) //(129 / 2)
#define SAD_FAVOR_INTER mp4_Inter_Favor[quant]
//(quant * 64) // ((quant * quant * 5) >> 1) // 500 H.263 App III
#define SAD_FAVOR_16x16 (quant * 25) // 200 H.263 App III
#define SAD_FAVOR_FIELD (quant * 6)
#define SAD_FAVOR_GMC (SAD_FAVOR_ZERO + SAD_FAVOR_16x16 + 1)
#define SAD_NOTCODED_THR_LUMA 10
#define SAD_NOTCODED_THR_CHROMA 20
#define DEV_FAVOR_INTRA (mp4_Inter_Favor[quant] >> 2)
//(quant * 16)
#define ME_HP 2 // use Half-Pel ME
#define ME_QP 4 // use Quarter-Pel ME
#define ME_4MV 8 // use 4 MV
#define ME_HP_FAST 16 // use Fast Half-Pel algorithm
#define ME_CHROMA 32 // do Chroma ME additionally to the Luma
#define ME_USE_MVWEIGHT 64 // use MV length
#define ME_SUBPEL_FINE 128 // fine subpel search
#define ME_USE_THRESHOLD 256 // use threshold in ME (faster but worse)
#define ME_AUTO_RANGE 512 // auto detect search window
#define ME_FIELD 1024 // use field ME
#define ME_FRAME 2048 // use frame ME
#define ME_USE_MANYPRED 4096 // use many predictors
#define ME_ZERO_MV 8192 // disable ME
#define RD_TRELLIS 16384 // use Trellis quantization
#define RD_MODE_DECISION 32768 // use RD for Inter/Intra decision
#define RD_MUL 8
enum {
ME_SEARCH_FULL_RECT,
ME_SEARCH_DIAMOND_SMALL,
ME_SEARCH_DIAMOND_BIG,
ME_SEARCH_SQUARE,
ME_SEARCH_LOG,
ME_SEARCH_FULL_INVOLUTE = 15,
};
extern void mp4_ME_SAD(mp4_Data_ME *meData);
extern Ipp32s mp4_WeightMV(Ipp32s dx, Ipp32s dy, IppMotionVector mvPred, Ipp32s fcode, Ipp32s quant, Ipp32s qpel);
extern void mp4_ComputeChroma4MV(const IppMotionVector mvLuma[4], IppMotionVector *mvChroma);
extern void mp4_ComputeChroma4MVQ(const IppMotionVector mvLuma[4], IppMotionVector *mvChroma);
extern int mp4_CalcBitsMV(IppMotionVector *mv, int fcode);
extern int mp4_CalcBitsCoeffsIntra(const Ipp16s* pCoeffs, int countNonZero, int rvlcFlag, int dc_vlc, const Ipp8u* pScanTable, int blockNum);
extern int mp4_CalcBitsCoeffsInter(const Ipp16s* pCoeffs, int countNonZero, int rvlcFlag, const Ipp8u* pScanTable);
template <class T> inline void mp4_Swap(T &a, T &b)
{
T t;
t = a; a = b; b = t;
}
// tables
extern const Ipp8u mp4_DefaultIntraQuantMatrix[];
extern const Ipp8u mp4_DefaultNonIntraQuantMatrix[];
extern const Ipp8u mp4_ZigZagScan[];
extern const Ipp8u mp4_AltVertScan[];
extern const Ipp8u mp4_HorScan[];
extern const int mp4_DC_VLC_Threshold[];
extern const Ipp8u mp4_cCbCrMvRound16[];
extern const Ipp8u mp4_DCScalerLuma[];
extern const Ipp8u mp4_DCScalerChroma[];
extern const mp4_VLC mp4_VLC_CBPY_TB8[];
extern const mp4_VLC mp4_VLC_MCBPC_TB7[];
extern const mp4_VLC mp4_VLC_MVD_TB12[];
extern const Ipp32s mp4_DivIntraDivisor[];
extern const Ipp8u mp4_MV_Weigth[];
extern const Ipp32s mp4_Inter_Favor[];
extern const Ipp8u mp4_VLC_DCSIZE_TB13_len[];
extern const Ipp8u mp4_VLC_DCSIZE_TB14_len[];
extern const mp4_VLC_TCOEF mp4_VLC_TB16;
extern const mp4_VLC_TCOEF mp4_VLC_TB17;
extern const mp4_VLC mp4_VLC_RMAX_TB21[2][7];
extern const mp4_VLC mp4_VLC_RMAX_TB22[2][6];
extern const mp4_VLC_TCOEF mp4_VLC_TB23a;
extern const mp4_VLC_TCOEF mp4_VLC_TB23b;
#ifdef _OMP_KARABAS
#ifdef _OPENMP
#define mp4_MT_get_thread_num() omp_get_thread_num()
#define mp4_MT_set_lock(lock) omp_set_lock(lock)
#define mp4_MT_unset_lock(lock) omp_unset_lock(lock)
#else
#define mp4_MT_get_thread_num() 0
#define mp4_MT_set_lock(lock)
#define mp4_MT_unset_lock(lock)
#endif
#endif // _OMP_KARABAS
} //namespace MPEG4_ENC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -