📄 mp4_enc_vop.cpp
字号:
}
}
Ipp32s ippVideoEncoderMPEG4::EncodeFrame(Ipp32s noMoreData)
{
Ipp32s isIVOP, isBVOP = 0, nt;
if (!mIsInit)
return MP4_STS_ERR_NOTINIT;
if (!noMoreData)
PadFrame(mFrameC->pY, mFrameC->pU, mFrameC->pV);
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;
} 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();
}
} 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) {
mFrameD = mFrameC;
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 = (Ipp32s)(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 = (Ipp32s)(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)
if (!FindTransformGMC())
VOP.vop_coding_type = MP4_VOP_TYPE_P;
nt = (Ipp32s)(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 = (Ipp32s)(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 = (Ipp32s)(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) {
mFrameD = mFrameC;
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
Ipp32s 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)
if (!FindTransformGMC())
VOP.vop_coding_type = MP4_VOP_TYPE_P;
nt = (Ipp32s)(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();
if (mNumIntraMB > mSceneChangeThreshold) {
cBS.Reset();
// not RepeatHeaders and InsertGOV here
VOP.vop_coding_type = MP4_VOP_TYPE_I;
VOP.vop_quant = mQuantPVOP;
EncodeVOP_Header();
EncodeIVOP();
mLastIVOP = mFrameCount;
}
mSyncTimeB = nt;
mIndxBVOP ++;
if (mIndxBVOP > 2 + mBVOPdist)
mIndxBVOP = 2;
// reset Sync Time
if (VOP.modulo_time_base != 0)
mSyncTime = mVOPtime - VOP.vop_time_increment;
ExpandFrame(mFrameC->pY, mFrameC->pU, mFrameC->pV);
mFrameD = mFrameC;
mp4_Swap(mFrameF, mFrameC);
} else {
isIVOP = (mFrameCount - mLastIVOP >= mIVOPdist);
isBVOP = mFrameCount % (mBVOPdist + 1);
if (!isBVOP) {
VOP.vop_coded = 1;
mFrameC = mFrameB;
if (isIVOP) {
if (mRepeatHeaders && (mFrameCount > 0)) {
EncodeHeader();
}
if (mInsertGOV) {
GOV.time_code = (Ipp32s)(mVOPtime / VOL.vop_time_increment_resolution);
if (mBVOPdist != 0 && (mFrameCount > 0)) {
Ipp32s secB = (Ipp32s)((mVOPtime - mBVOPdist * VOL.fixed_vop_time_increment) / VOL.vop_time_increment_resolution);
if (secB < GOV.time_code)
GOV.time_code = secB;
}
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)(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)
if (!FindTransformGMC())
VOP.vop_coding_type = MP4_VOP_TYPE_P;
nt = (Ipp32s)(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 = (Ipp32s)(mVOPtime / VOL.vop_time_increment_resolution);
if (mBVOPdist != 0 && (mFrameCount > 0)) {
Ipp32s secB = (Ipp32s)((mVOPtime - mBVOPdist * VOL.fixed_vop_time_increment) / VOL.vop_time_increment_resolution);
if (secB < GOV.time_code)
GOV.time_code = secB;
}
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)(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;
}
}
mSyncTimeB = nt;
ExpandFrame(mFrameC->pY, mFrameC->pU, mFrameC->pV);
// reset Sync Time
if (VOP.modulo_time_base != 0)
mSyncTime = mVOPtime - VOP.vop_time_increment;
} else if (mFrameCount > mBVOPdist) {
Ipp32s bIndx;
bIndx = mIndxBVOP + 1;
if (bIndx > 2 + mBVOPdist)
bIndx = 2;
mFrameC = &mFrame[bIndx];
mTRD = mBVOPdist + 1;
mTRB = mNumBVOP + 1;
mTframe = 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();
EncodeBVOP();
}
mFrameD = mFrameC;
// setup next frame
if (isBVOP) {
mIndxBVOP ++;
if (mIndxBVOP > 2 + mBVOPdist)
mIndxBVOP = 2;
mNumBVOP ++;
if (mNumBVOP == mBVOPdist) {
// next frame is not B
mNumBVOP = 0;
mp4_Swap(mFrameF, mFrameB);
mFrameC = mFrameB;
} else {
// next frame is B
mFrameC = &mFrame[mIndxBVOP];
}
} else {
// next frame is B
mFrameC = &mFrame[mIndxBVOP];
}
}
}
if (mFrameCount > mBVOPdist + 1 || !isBVOP) {
mBitsEncodedFrame = cBS.GetFullness() << 3;
mBitsEncodedTotal += mBitsEncodedFrame;
if (mRateControl == 1) {
mRC.PostFrame(VOP.vop_coding_type, mBitsEncodedTotal);
mQuantIVOP = mRC.GetQP(MP4_VOP_TYPE_I);
mQuantPVOP = mRC.GetQP(MP4_VOP_TYPE_P);
mQuantBVOP = mRC.GetQP(MP4_VOP_TYPE_B);
} else if (mRateControl == 2) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -