📄 mp4_enc_vop.cpp
字号:
mRC_MB.PostFrame(mBitsEncodedFrame, mQuantSum);
mQuantIVOP = mQuantPVOP = mQuantBVOP = mRC_MB.GetQP();
}
if (VOP.vop_coding_type == MP4_VOP_TYPE_I) {
VOP.vop_rounding_type = 0; // reset rounding_type for next P-VOP
} else if (VOP.vop_coding_type != MP4_VOP_TYPE_B) {
if (mRoundingControl)
VOP.vop_rounding_type ^= 1; // switch rounding_type
}
}
mVOPtime += VOL.fixed_vop_time_increment;
mFrameCount ++;
return (mFrameCount > mBVOPdist + 1 || !isBVOP) ? MP4_STS_NOERR : MP4_STS_BUFFERED;
}
/*
Ipp32s ippVideoEncoderMPEG4::EncodeFrame(Ipp32s noMoreData, Ipp32s vop_type, Ipp64s vop_time)
{
Ipp32s isIVOP, isBVOP, nt;
if (!mIsInit)
return MP4_STS_ERR_NOTINIT;
if (noMoreData)
return MP4_STS_NODATA;
if (vop_time < mSyncTime)
return MP4_STS_ERR_PARAM;
if (VOL.sprite_enable == MP4_SPRITE_STATIC) {
// static sprites
VOP.vop_coded = 1;
if (mFrameCount == 0 && vop_type == MP4_VOP_TYPE_I) {
VOP.vop_coding_type = MP4_VOP_TYPE_I;
VOP.vop_quant = mQuantIVOP;
EncodeVOP_Header();
EncodeIVOP();
ExpandFrame(mCurrPtrY, mCurrPtrU, mCurrPtrV);
mQuantSum = VOP.vop_quant * mNumMacroBlockPerVOP;
} else if (mFrameCount > 0 && vop_type != MP4_VOP_TYPE_S) {
VOP.vop_coding_type = MP4_VOP_TYPE_S;
nt = (Ipp32s)(vop_time - mSyncTime);
VOP.modulo_time_base = nt / VOL.vop_time_increment_resolution;
VOP.vop_time_increment = nt % VOL.vop_time_increment_resolution;
if (VOP.modulo_time_base != 0)
mSyncTime = vop_time - VOP.vop_time_increment;
EncodeVOP_Header();
EncodeSVOP();
mQuantSum = 0;
} else
return MP4_STS_ERR_PARAM;
} else if (VOL.short_video_header) {
// short_video_header
nt = (Ipp32s)(vop_time - mSyncTime);
mSyncTime = vop_time;
VOP.temporal_reference = nt / 1001;
VOP.vop_coded = 1;
if (vop_type == MP4_VOP_TYPE_I) {
VOP.vop_coding_type = VOP.picture_coding_type = MP4_VOP_TYPE_I;
VOP.vop_quant = mQuantIVOP;
EncodeVOPSH_Header();
EncodeIVOPSH();
} else if (vop_type == MP4_VOP_TYPE_P) {
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();
}
} else
return MP4_STS_ERR_PARAM;
mp4_Swap(mForwPtrY, mCurrPtrY);
mp4_Swap(mForwPtrU, mCurrPtrU);
mp4_Swap(mForwPtrV, mCurrPtrV);
} else {
VOP.vop_coded = 1;
if (vop_type == MP4_VOP_TYPE_I) {
if (mRepeatHeaders && (mFrameCount != 0)) {
EncodeHeader();
}
if (mInsertGOV) {
GOV.time_code = (Ipp32s)(vop_time / 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 = (Ipp32s)(vop_time - mSyncTime);
VOP.modulo_time_base = nt / VOL.vop_time_increment_resolution;
VOP.vop_time_increment = nt % VOL.vop_time_increment_resolution;
EncodeVOP_Header();
EncodeIVOP();
mSyncTimeB = nt;
} else if (vop_type == MP4_VOP_TYPE_P || ((VOL.sprite_enable == MP4_SPRITE_GMC) && (vop_type == MP4_VOP_TYPE_S))) {
VOP.vop_coding_type = vop_type;
VOP.vop_quant = mQuantPVOP;
VOP.vop_fcode_forward = mPVOPfcodeForw;
if (VOP.vop_coding_type == MP4_VOP_TYPE_S)
if (!FindTransformGMC())
VOP.vop_coding_type = MP4_VOP_TYPE_P;
nt = (Ipp32s)(vop_time - 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 = (Ipp32s)(vop_time / 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 = (Ipp32s)(vop_time - mSyncTime);
VOP.modulo_time_base = nt / VOL.vop_time_increment_resolution;
VOP.vop_time_increment = nt % VOL.vop_time_increment_resolution;
EncodeVOP_Header();
EncodeIVOP();
} else if (mNumNotCodedMB >= mNumMacroBlockPerVOP) {
VOP.vop_coded = 0;
cBS.Reset();
EncodeVOP_Header();
EncodeStuffingBitsAlign();
}
mSyncTimeB = nt;
} else if (vop_type == MP4_VOP_TYPE_B) {
//mTRD = mBVOPdist + 1;
//mTRB = mNumBVOP + 1;
VOP.vop_coding_type = MP4_VOP_TYPE_B;
VOP.vop_quant = mQuantBVOP;
VOP.vop_fcode_forward = mBVOPfcodeForw;
VOP.vop_fcode_backward = mBVOPfcodeBack;
//nt = mSyncTimeB - (mBVOPdist - mNumBVOP) * 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();
// if ref in the future is not coded, these B are not coded also
if (VOP.vop_coded)
EncodeBVOP();
} else
return MP4_STS_ERR_PARAM;
if (vop_type != MP4_VOP_TYPE_B) {
ExpandFrame(mCurrPtrY, mCurrPtrU, mCurrPtrV);
mp4_Swap(mForwPtrY, mCurrPtrY);
mp4_Swap(mForwPtrU, mCurrPtrU);
mp4_Swap(mForwPtrV, mCurrPtrV);
if (VOP.modulo_time_base != 0)
mSyncTime = vop_time - VOP.vop_time_increment;
}
}
mBitsEncodedFrame = cBS.GetFullness() << 3;
mBitsEncodedTotal += mBitsEncodedFrame;
if (mRateControl == 1)
PostFrameRC();
if (VOP.vop_coding_type == MP4_VOP_TYPE_I) {
VOP.vop_rounding_type = 0; // reset rounding_type for next P-VOP
} else if (VOP.vop_coding_type != MP4_VOP_TYPE_B) {
if (mRoundingControl)
VOP.vop_rounding_type ^= 1; // switch rounding_type
}
mFrameCount ++;
return MP4_STS_NOERR;
}
*/
static void mp4_MergeBuffersDP(ippBitStream &cBS, ippBitStream &cBS_1, ippBitStream &cBS_2)
{
Ipp32s nBits_1, nBits_2;
// merge buffer with dp_buff_1
nBits_1 = cBS_1.GetNumBits();
ippsCopy_1u(cBS_1.mBuffer, 0, cBS.mPtr, cBS.mBitOff, nBits_1);
cBS.MovePtr(nBits_1);
cBS_1.Reset();
// merge buffer with dp_buff_2
nBits_2 = cBS_2.GetNumBits();
ippsCopy_1u(cBS_2.mBuffer, 0, cBS.mPtr, cBS.mBitOff, nBits_2);
cBS.MovePtr(nBits_2);
cBS_2.Reset();
}
// used for short_viseo_header
void ippVideoEncoderMPEG4::PredictMV(mp4_MacroBlock *MBcurr, Ipp32s i, Ipp32s j, IppMotionVector *mvPred)
{
IppMotionVector *mvLeft, *mvTop, *mvRight;
mvLeft = MBcurr[-1].mv;
mvTop = MBcurr[-mNumMacroBlockPerRow].mv;
mvRight = MBcurr[-mNumMacroBlockPerRow+1].mv;
if (mInsertResync)
i = (VOP.source_format <= 3) ? 0 : (i & ((VOP.source_format == 4) ? 1 : 3));
if (i == 0 && j == 0) {
mvPred[0].dx = mvPred[0].dy = 0;
} else if (j == 0) {
mvPred[0].dx = mp4_Median(0, mvTop[0].dx, mvRight[0].dx);
mvPred[0].dy = mp4_Median(0, mvTop[0].dy, mvRight[0].dy);
} else if (i == 0) {
mvPred[0] = mvLeft[0];
} else if (j == mNumMacroBlockPerRow - 1) {
mvPred[0].dx = mp4_Median(0, mvLeft[0].dx, mvTop[0].dx);
mvPred[0].dy = mp4_Median(0, mvLeft[0].dy, mvTop[0].dy);
} else {
mvPred[0].dx = mp4_Median(mvLeft[0].dx, mvTop[0].dx, mvRight[0].dx);
mvPred[0].dy = mp4_Median(mvLeft[0].dy, mvTop[0].dy, mvRight[0].dy);
}
}
void ippVideoEncoderMPEG4::Predict1MV(mp4_MacroBlock *MBcurr, Ipp32s i, Ipp32s j, IppMotionVector *mvPred)
{
IppMotionVector *mvLeft, *mvTop, *mvRight;
// block 0
mvLeft = MBcurr[-1].mv;
mvTop = MBcurr[-mNumMacroBlockPerRow].mv;
mvRight = MBcurr[-mNumMacroBlockPerRow+1].mv;
if (!mInsertResync) {
if (i == 0 && j == 0) {
mvPred[0].dx = mvPred[0].dy = 0;
} else if (j == 0) {
mvPred[0].dx = mp4_Median(0, mvTop[2].dx, mvRight[2].dx);
mvPred[0].dy = mp4_Median(0, mvTop[2].dy, mvRight[2].dy);
} else if (i == 0) {
mvPred[0] = mvLeft[1];
} else if (j == mNumMacroBlockPerRow - 1) {
mvPred[0].dx = mp4_Median(0, mvLeft[1].dx, mvTop[2].dx);
mvPred[0].dy = mp4_Median(0, mvLeft[1].dy, mvTop[2].dy);
} else {
mvPred[0].dx = mp4_Median(mvLeft[1].dx, mvTop[2].dx, mvRight[2].dx);
mvPred[0].dy = mp4_Median(mvLeft[1].dy, mvTop[2].dy, mvRight[2].dy);
}
} else {
Ipp32s validLeft, validTop, validRight;
if (j > 0)
validLeft = MBcurr[-1].validPredInter;
else
validLeft = 0;
if (i > 0)
validTop = MBcurr[-mNumMacroBlockPerRow].validPredInter;
else
validTop = 0;
if ((i > 0) && (j < mNumMacroBlockPerRow - 1))
validRight = MBcurr[-mNumMacroBlockPerRow+1].validPredInter;
else
validRight = 0;
switch ((validLeft << 2) | (validTop << 1) | validRight) {
case 7:
mvPred[0].dx = mp4_Median(mvLeft[1].dx, mvTop[2].dx, mvRight[2].dx);
mvPred[0].dy = mp4_Median(mvLeft[1].dy, mvTop[2].dy, mvRight[2].dy);
break;
case 6:
mvPred[0].dx = mp4_Median(mvLeft[1].dx, mvTop[2].dx, 0);
mvPred[0].dy = mp4_Median(mvLeft[1].dy, mvTop[2].dy, 0);
break;
case 5:
mvPred[0].dx = mp4_Median(mvLeft[1].dx, 0, mvRight[2].dx);
mvPred[0].dy = mp4_Median(mvLeft[1].dy, 0, mvRight[2].dy);
break;
case 4:
mvPred[0] = mvLeft[1];
break;
case 3:
mvPred[0].dx = mp4_Median(0, mvTop[2].dx, mvRight[2].dx);
mvPred[0].dy = mp4_Median(0, mvTop[2].dy, mvRight[2].dy);
break;
case 2:
mvPred[0] = mvTop[2];
break;
case 1:
mvPred[0] = mvRight[2];
break;
default:
mvPred[0].dx = mvPred[0].dy = 0;
break;
}
}
}
void ippVideoEncoderMPEG4::Predict3MV(mp4_MacroBlock *MBcurr, Ipp32s i, Ipp32s j, IppMotionVector *mvPred, IppMotionVector *mvCurr)
{
IppMotionVector *mvLeft, *mvTop, *mvRight;
mvLeft = MBcurr[-1].mv;
mvTop = MBcurr[-mNumMacroBlockPerRow].mv;
mvRight = MBcurr[-mNumMacroBlockPerRow+1].mv;
if (!mInsertResync) {
// block 1
if (i == 0) {
mvPred[1] = mvCurr[0];
} else if (j == mNumMacroBlockPerRow - 1) {
mvPred[1].dx = mp4_Median(mvCurr[0].dx, mvTop[3].dx, 0);
mvPred[1].dy = mp4_Median(mvCurr[0].dy, mvTop[3].dy, 0);
} else {
mvPred[1].dx = mp4_Median(mvCurr[0].dx, mvTop[3].dx, mvRight[2].dx);
mvPred[1].dy = mp4_Median(mvCurr[0].dy, mvTop[3].dy, mvRight[2].dy);
}
// block 2
if (j == 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -