📄 ippvideoencodermpeg4_vop.cpp
字号:
/* /////////////////////////////////////////////////////////////////////////// INTEL CORPORATION PROPRIETARY INFORMATION// This software is supplied under the terms of a license agreement or// nondisclosure agreement with Intel Corporation and may not be copied// or disclosed except in accordance with the terms of that agreement.// Copyright (c) 2003-2005 Intel Corporation. All Rights Reserved.//// Description: class ippVideoEncoderMPEG4 (encode VOPs)//*/#include "ippvideoencodermpeg4.hpp"#pragma warning(disable : 981) // operands are evaluated in unspecified order#pragma warning(disable : 279) // controlling expression is constant#pragma warning(disable : 4127) // conditional expression is constantinline void mp4_ComputeChromaMV(const IppMotionVector *mvLuma, IppMotionVector *mvChroma){ mvChroma->dx = (Ipp16s)mp4_Div2Round(mvLuma->dx); mvChroma->dy = (Ipp16s)mp4_Div2Round(mvLuma->dy);}inline void mp4_ComputeChromaMVQ(const IppMotionVector *mvLuma, IppMotionVector *mvChroma){ int dx, dy; dx = mp4_Div2(mvLuma->dx); dy = mp4_Div2(mvLuma->dy); mvChroma->dx = (Ipp16s)mp4_Div2Round(dx); mvChroma->dy = (Ipp16s)mp4_Div2Round(dy);}static void mp4_ComputeChroma4MV(const IppMotionVector mvLuma[4], IppMotionVector *mvChroma){ int dx, dy, cdx, cdy, adx, ady; dx = mvLuma[0].dx + mvLuma[1].dx + mvLuma[2].dx + mvLuma[3].dx; dy = mvLuma[0].dy + mvLuma[1].dy + mvLuma[2].dy + mvLuma[3].dy; adx = mp4_Abs(dx); ady = mp4_Abs(dy); cdx = mp4_cCbCrMvRound16_[adx & 15] + (adx >> 4) * 2; cdy = mp4_cCbCrMvRound16_[ady & 15] + (ady >> 4) * 2; mvChroma->dx = (Ipp16s)((dx >= 0) ? cdx : -cdx); mvChroma->dy = (Ipp16s)((dy >= 0) ? cdy : -cdy);}static void mp4_ComputeChroma4MVQ(const IppMotionVector mvLuma[4], IppMotionVector *mvChroma){ int dx, dy, cdx, cdy, adx, ady; dx = mp4_Div2(mvLuma[0].dx) + mp4_Div2(mvLuma[1].dx) + mp4_Div2(mvLuma[2].dx) + mp4_Div2(mvLuma[3].dx); dy = mp4_Div2(mvLuma[0].dy) + mp4_Div2(mvLuma[1].dy) + mp4_Div2(mvLuma[2].dy) + mp4_Div2(mvLuma[3].dy); adx = mp4_Abs(dx); ady = mp4_Abs(dy); cdx = mp4_cCbCrMvRound16_[adx & 15] + (adx >> 4) * 2; cdy = mp4_cCbCrMvRound16_[ady & 15] + (ady >> 4) * 2; mvChroma->dx = (Ipp16s)((dx >= 0) ? cdx : -cdx); mvChroma->dy = (Ipp16s)((dy >= 0) ? cdy : -cdy);}static void mp4_Set8x8_8u(Ipp8u *p, int step, Ipp8u level){ Ipp32u val; val = level + (level << 8); val += val << 16; ((Ipp32u*)p)[0] = val; ((Ipp32u*)p)[1] = val; p += step; ((Ipp32u*)p)[0] = val; ((Ipp32u*)p)[1] = val; p += step; ((Ipp32u*)p)[0] = val; ((Ipp32u*)p)[1] = val; p += step; ((Ipp32u*)p)[0] = val; ((Ipp32u*)p)[1] = val; p += step; ((Ipp32u*)p)[0] = val; ((Ipp32u*)p)[1] = val; p += step; ((Ipp32u*)p)[0] = val; ((Ipp32u*)p)[1] = val; p += step; ((Ipp32u*)p)[0] = val; ((Ipp32u*)p)[1] = val; p += step; ((Ipp32u*)p)[0] = val; ((Ipp32u*)p)[1] = val;}inline int mp4_CalcMSE_16x16(Ipp8u *pSrc1, int stepSrc1, Ipp8u *pSrc2, int stepSrc2){ int e; ippiSqrDiff16x16_8u32s(pSrc1, stepSrc1, pSrc2, stepSrc2, IPPVC_MC_APX_FF, &e); return e;}inline int mp4_CalcMSE_8x8(Ipp8u *pSrc1, int stepSrc1, Ipp8u *pSrc2, int stepSrc2){ int e; ippiSSD8x8_8u32s_C1R(pSrc1, stepSrc1, pSrc2, stepSrc2, &e, IPPVC_MC_APX_FF); return e;}inline Ipp16s mp4_Median(Ipp16s a, Ipp16s b, Ipp16s c){ if (a > b) { Ipp16s t = a; a = b; b = t; } return (b <= c) ? b : (c >= a) ? c : a;}inline void mp4_MV_CheckRange(IppMotionVector *mvD, int fMin, int fMax, int fRange){ if (mvD->dx < fMin) mvD->dx = (Ipp16s)(mvD->dx + fRange); else if (mvD->dx > fMax) mvD->dx = (Ipp16s)(mvD->dx - fRange); if (mvD->dy < fMin) mvD->dy = (Ipp16s)(mvD->dy + fRange); else if (mvD->dy > fMax) mvD->dy = (Ipp16s)(mvD->dy - fRange);}#define mp4_SetPatternInter(pattern, nzCount) \ pattern = 0; \ pattern |= (nzCount[0] > 0) ? 32 : 0; \ pattern |= (nzCount[1] > 0) ? 16 : 0; \ pattern |= (nzCount[2] > 0) ? 8 : 0; \ pattern |= (nzCount[3] > 0) ? 4 : 0; \ pattern |= (nzCount[4] > 0) ? 2 : 0; \ pattern |= (nzCount[5] > 0) ? 1 : 0#define mp4_SetPatternIntra(pattern, nzCount, coeff, use_intra_dc_vlc) \ pattern = 0; \ if (use_intra_dc_vlc) { \ int i, pm = 32; \ for (i = 0; i < 6; i ++) { \ if ((nzCount[i] > 1) || ((nzCount[i] == 1) && (coeff[i*64] == 0))) \ pattern |= pm; \ pm >>= 1; \ } \ } else { \ pattern |= (nzCount[0] > 0) ? 32 : 0; \ pattern |= (nzCount[1] > 0) ? 16 : 0; \ pattern |= (nzCount[2] > 0) ? 8 : 0; \ pattern |= (nzCount[3] > 0) ? 4 : 0; \ pattern |= (nzCount[4] > 0) ? 2 : 0; \ pattern |= (nzCount[5] > 0) ? 1 : 0; \ }inline void mp4_NonZeroCount(Ipp16s *coeff, int *nzCount){ int i; Ipp32u c; for (i = 0; i < 6; i ++) { ippiCountZeros8x8_16s_C1(coeff+i*64, &c); nzCount[i] = 64 - c; }}inline void ippVideoEncoderMPEG4::EncodeMarkerDC(){ cBS.PutBits(0x6B001, 19); // 110 1011 0000 0000 0001}inline void ippVideoEncoderMPEG4::EncodeMarkerMV(){ cBS.PutBits(0x1F001, 17); // 1 1111 0000 0000 0001}int ippVideoEncoderMPEG4::EncodeFrame(int noMoreData){ int isIVOP, isBVOP = 0, nt; if (!mIsInit) return MP4_STS_ERR_NOTINIT; mQuantSum = 0; mPSNR_Y = mPSNR_U = mPSNR_V = 0; mNumIntraMB = 0; mNumNotCodedMB = 0; if (VOL.sprite_enable == MP4_SPRITE_STATIC) { // static sprites if (noMoreData) return MP4_STS_NODATA; VOP.vop_coded = 1; if (mFrameCount == 0) { VOP.vop_coding_type = MP4_VOP_TYPE_I; VOP.vop_quant = mQuantIVOP; EncodeVOP_Header(); EncodeIVOP(); ExpandFrame(mFrameC->pY, mFrameC->pU, mFrameC->pV); VOP.vop_time_increment = -VOL.fixed_vop_time_increment; mQuantSum = VOP.vop_quant * mNumMacroBlockPerVOP; } else { VOP.vop_coding_type = MP4_VOP_TYPE_S; nt = VOP.vop_time_increment + VOL.fixed_vop_time_increment; VOP.modulo_time_base = nt / VOL.vop_time_increment_resolution; VOP.vop_time_increment = nt % VOL.vop_time_increment_resolution; EncodeVOP_Header(); EncodeSVOP(); mQuantSum = 0; } } else if (VOL.short_video_header) { // short_video_header if (noMoreData) return MP4_STS_NODATA; VOP.vop_coded = 1; isIVOP = (mFrameCount - mLastIVOP >= mIVOPdist); if (isIVOP) { VOP.vop_coding_type = VOP.picture_coding_type = MP4_VOP_TYPE_I; VOP.vop_quant = mQuantIVOP; EncodeVOPSH_Header(); EncodeIVOPSH(); mLastIVOP = mFrameCount; } else { VOP.vop_coding_type = VOP.picture_coding_type = MP4_VOP_TYPE_P; VOP.vop_quant = mQuantPVOP; EncodeVOPSH_Header(); EncodePVOPSH(); if (mNumIntraMB > mSceneChangeThreshold) { cBS.Reset(); VOP.vop_coding_type = VOP.picture_coding_type = MP4_VOP_TYPE_I; VOP.vop_quant = mQuantIVOP; EncodeVOPSH_Header(); EncodeIVOPSH(); mLastIVOP = mFrameCount; } } if (mIVOPdist != 1) mp4_Swap(mFrameF, mFrameC); VOP.temporal_reference += VOP.temporal_reference_increment; } else if (mBVOPdist == 0) { // without B-frames if (noMoreData) return MP4_STS_NODATA; VOP.vop_coded = 1; isIVOP = (mFrameCount - mLastIVOP >= mIVOPdist); if (isIVOP) { if (mRepeatHeaders && (mFrameCount != 0)) { EncodeHeader(); } if (mInsertGOV) { GOV.time_code = (int)(mVOPtime / VOL.vop_time_increment_resolution); mSyncTime = (Ipp64s)GOV.time_code * (Ipp64s)VOL.vop_time_increment_resolution; EncodeGOV_Header(); } VOP.vop_coding_type = MP4_VOP_TYPE_I; VOP.vop_quant = mQuantIVOP; nt = (int)(mVOPtime - mSyncTime); VOP.modulo_time_base = nt / VOL.vop_time_increment_resolution; VOP.vop_time_increment = nt % VOL.vop_time_increment_resolution; EncodeVOP_Header(); EncodeIVOP(); mLastIVOP = mFrameCount; } else { VOP.vop_coding_type = (VOL.sprite_enable == MP4_SPRITE_GMC) ? MP4_VOP_TYPE_S : MP4_VOP_TYPE_P; VOP.vop_quant = mQuantPVOP; VOP.vop_fcode_forward = mPVOPfcodeForw; if (VOP.vop_coding_type == MP4_VOP_TYPE_S) FindTransformGMC(); nt = (int)(mVOPtime - mSyncTime); VOP.modulo_time_base = nt / VOL.vop_time_increment_resolution; VOP.vop_time_increment = nt % VOL.vop_time_increment_resolution; EncodeVOP_Header(); if (VOP.vop_coding_type == MP4_VOP_TYPE_P) EncodePVOP(); else EncodeSVOP(); if (mNumIntraMB > mSceneChangeThreshold) { cBS.Reset(); if (mRepeatHeaders && (mFrameCount != 0)) { EncodeHeader(); } if (mInsertGOV) { GOV.time_code = (int)(mVOPtime / VOL.vop_time_increment_resolution); mSyncTime = (Ipp64s)GOV.time_code * (Ipp64s)VOL.vop_time_increment_resolution; EncodeGOV_Header(); } VOP.vop_coding_type = MP4_VOP_TYPE_I; VOP.vop_quant = mQuantPVOP; nt = (int)(mVOPtime - mSyncTime); VOP.modulo_time_base = nt / VOL.vop_time_increment_resolution; VOP.vop_time_increment = nt % VOL.vop_time_increment_resolution; EncodeVOP_Header(); EncodeIVOP(); mLastIVOP = mFrameCount; } else if (mNumNotCodedMB >= mNumMacroBlockPerVOP) { VOP.vop_coded = 0; cBS.Reset(); EncodeVOP_Header(); EncodeStuffingBitsAlign(); } } if (mIVOPdist != 1) { ExpandFrame(mFrameC->pY, mFrameC->pU, mFrameC->pV); mp4_Swap(mFrameF, mFrameC); } // reset Sync Time if (VOP.modulo_time_base != 0) mSyncTime = mVOPtime - VOP.vop_time_increment; } else { // with B-frames if (noMoreData) { if (mNumOfFrames == -1) mNumOfFrames = mFrameCount; if (mFrameCount >= mNumOfFrames + mBVOPdist) return MP4_STS_NODATA; } if (noMoreData && (mFrameCount >= mNumOfFrames + mBVOPdist - (mNumOfFrames - 1) % (mBVOPdist + 1))) { // last not closed B-frames are coded as P int bIndx; VOP.vop_coded = 1; bIndx = mIndxBVOP + 1; if (bIndx > 2 + mBVOPdist) bIndx = 2; mFrameC = &mFrame[bIndx]; VOP.vop_coding_type = (VOL.sprite_enable == MP4_SPRITE_GMC) ? MP4_VOP_TYPE_S : MP4_VOP_TYPE_P; VOP.vop_quant = mQuantPVOP; VOP.vop_fcode_forward = mPVOPfcodeForw; if (VOP.vop_coding_type == MP4_VOP_TYPE_S) FindTransformGMC(); nt = (int)(mVOPtime - mBVOPdist * VOL.fixed_vop_time_increment - mSyncTime); VOP.modulo_time_base = nt / VOL.vop_time_increment_resolution; VOP.vop_time_increment = nt % VOL.vop_time_increment_resolution; EncodeVOP_Header(); if (VOP.vop_coding_type == MP4_VOP_TYPE_P) EncodePVOP(); else EncodeSVOP();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -