📄 vopmbenc.cpp
字号:
/*************************************************************************
This software module was originally developed by
Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation
Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation
Bruce Lin (blin@microsoft.com), Microsoft Corporation
Chuang Gu (chuanggu@microsoft.com), Microsoft Corporation
Simon Winder (swinder@microsoft.com), Microsoft Corporation
(date: March, 1996)
and edited by
Wei Wu (weiwu@stallion.risc.rockwell.com) Rockwell Science Center
and also edited by
Yoshihiro Kikuchi (TOSHIBA CORPORATION)
Takeshi Nagai (TOSHIBA CORPORATION)
Toshiaki Watanabe (TOSHIBA CORPORATION)
Noboru Yamaguchi (TOSHIBA CORPORATION)
and also edited by
Yoshinori Suzuki (Hitachi, Ltd.)
and also edited by
Hideaki Kimata (NTT)
and also edited by
Fujitsu Laboratories Ltd. (contact: Eishi Morimatsu)
and also edited by
Takefumi Nagumo (naugmo@av.crl.sony.co.jp)
Sehoon Son (shson@unitel.co.kr) Samsung AIT
in the course of development of the MPEG-4 Video (ISO/IEC 14496-2).
This software module is an implementation of a part of one or more MPEG-4 Video tools
as specified by the MPEG-4 Video.
ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications
thereof for use in hardware or software products claiming conformance to the MPEG-4 Video.
Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents.
The original developer of this software module and his/her company,
the subsequent editors and their companies,
and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation.
Copyright is not released for non MPEG-4 Video conforming products.
Microsoft retains full right to use the code for his/her own purpose,
assign or donate the code to a third party and to inhibit third parties from using the code for non <MPEG standard> conforming products.
This copyright notice must be included in all copies or derivative works.
Copyright (c) 1996, 1997.
Module Name:
vopmbEnc.cpp
Abstract:
Encode MB's for each VOP (I-, P-, and B-VOP's)
Revision History:
Dec. 11, 1997: Interlaced tools added by NextLevel Systems (GI)
B. Eifrig, (beifrig@nlvl.com) X. Chen, (xchen@nlvl.com)
May. 9 1998: add boundary by Hyundai Electronics
Cheol-Soo Park (cspark@super5.hyundai.co.kr)
May. 9 1998: add field based MC padding by Hyundai Electronics
Cheol-Soo Park (cspark@super5.hyundai.co.kr)
Feb.24 1999: GMC added by Yoshinori Suzuki (Hitachi, Ltd.)
May 9, 1999: tm5 rate control by DemoGraFX, duhoff@mediaone.net
Aug.24, 1999: NEWPRED added by Hideaki Kimata (NTT)
Sep.06 1999 : RRV added by Eishi Morimatsu (Fujitsu Laboratories Ltd.)
Feb.01 2000 : Bug fix OBSS by Takefumi Nagumo (SONY)
*************************************************************************/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <iostream.h>
#include "typeapi.h"
#include "codehead.h"
#include "entropy/bitstrm.hpp"
#include "entropy/entropy.hpp"
#include "entropy/huffman.hpp"
#include "mode.hpp"
#include "global.hpp"
#include "vopses.hpp"
#include "vopseenc.hpp"
// NEWPRED
#include "newpred.hpp"
// ~NEWPRED
// RRV insertion
#include "rrv.hpp"
// ~RRV
#ifdef __MFC_
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
#endif // __MFC_
Void CVideoObjectEncoder::encodeVOP ()
{
if (m_uiRateControl>=RC_TM5) {
m_tm5rc.tm5rc_init_pict(m_vopmd.vopPredType,
m_pvopcOrig->pixelsBoundY (),
m_iFrameWidthY,
m_iNumMBX,
m_iNumMBY);
}
// RRV insertion
assert((m_iRRVScale == 1)||(m_iRRVScale == 2));
// ~RRV
// Added for Data Partitioning mode by Toshiba(1998-1-16)
if( m_volmd.bDataPartitioning ) {
if (m_volmd.fAUsage == RECTANGLE) {
switch( m_vopmd.vopPredType ) {
case PVOP:
encodeNSForPVOP_DP ();
break;
// GMC
case SPRITE:
encodeNSForPVOP_DP ();
break;
// ~GMC
case IVOP:
encodeNSForIVOP_DP ();
break;
case BVOP:
encodeNSForBVOP ();
break;
default:
assert(FALSE); // B-VOP and Sprite-VOP are not supported in DP-mode
}
} else {
switch( m_vopmd.vopPredType ) {
case PVOP:
encodeNSForPVOP_WithShape_DP ();
break;
// GMC
case SPRITE:
encodeNSForPVOP_WithShape_DP ();
break;
// ~GMC
case IVOP:
encodeNSForIVOP_WithShape_DP ();
break;
case BVOP:
encodeNSForBVOP_WithShape ();
break;
default:
assert(FALSE); // B-VOP and Sprite-VOP are not supported in DP-mode
}
}
} else
// End Toshiba(1998-1-16)
if (m_volmd.fAUsage == RECTANGLE) {
if (m_vopmd.vopPredType == PVOP || (m_uiSprite == 2 && m_vopmd.vopPredType == SPRITE)) // GMC
encodeNSForPVOP ();
else if (m_vopmd.vopPredType == IVOP)
encodeNSForIVOP ();
else
encodeNSForBVOP ();
}
else {
if (m_vopmd.vopPredType == PVOP || (m_uiSprite == 2 && m_vopmd.vopPredType == SPRITE)) { // GMC
if (m_uiSprite == 1 && m_sptMode != BASIC_SPRITE && m_vopmd.SpriteXmitMode != STOP)
encodeNSForPVOP ();
else
encodeNSForPVOP_WithShape ();
}
else if (m_vopmd.vopPredType == IVOP)
encodeNSForIVOP_WithShape ();
else
encodeNSForBVOP_WithShape ();
}
if (m_uiRateControl>=RC_TM5) {
m_tm5rc.tm5rc_update_pict(m_vopmd.vopPredType, m_statsVOP.total());
}
}
//
// size:
// m_pvopcCurr: original size (QCIF or CIF), same memory through out the session
// m_pvopfRef: expanded original size (QCIF or CIF expanded by 16), same memory through out the session
// pmbmd and pmv: VOP. need to reallocate every time
//
// things don't need to recompute:
// m_iWidthY, m_iWidthUV, m_iWidthRefY, m_iWidthRefUV
// need to recompute:
// m_uintNumMBX, m_uintNumMBY, m_uintNumMB
//
Void CVideoObjectEncoder::encodeNSForIVOP ()
{
//in case the IVOP is used as an ref for direct mode
memset (m_rgmv, 0, m_iNumMB * PVOP_MV_PER_REF_PER_MB * sizeof (CMotionVector));
CMBMode* pmbmd = m_rgmbmd;
Int iQPPrev = m_vopmd.intStepI; //初始化
PixelC* ppxlcRefY = (PixelC*) m_pvopcRefQ1->pixelsY () + m_iStartInRefToCurrRctY;
PixelC* ppxlcRefU = (PixelC*) m_pvopcRefQ1->pixelsU () + m_iStartInRefToCurrRctUV;
PixelC* ppxlcRefV = (PixelC*) m_pvopcRefQ1->pixelsV () + m_iStartInRefToCurrRctUV;
PixelC* ppxlcOrigY = (PixelC*) m_pvopcOrig->pixelsBoundY ();
PixelC* ppxlcOrigU = (PixelC*) m_pvopcOrig->pixelsBoundU ();
PixelC* ppxlcOrigV = (PixelC*) m_pvopcOrig->pixelsBoundV ();
//宏块码率控制
Int iIndexofQ = 0;
Int rgiQ [4] = {-1, -2, 1, 2};
if (m_uiRateControl>=RC_TM5) iQPPrev = m_tm5rc.tm5rc_start_mb();
Bool bRestartDelayedQP = TRUE;
// RRV_2 insertion
Int iVideoPacketNumber = 0;
// ~RRV_2
Int iMBX, iMBY, iMB = 0;
Int iMaxQP = (1<<m_volmd.uiQuantPrecision)-1; //量化精度
for (iMBY = 0; iMBY < m_iNumMBY; iMBY++) {
PixelC* ppxlcRefMBY = ppxlcRefY;
PixelC* ppxlcRefMBU = ppxlcRefU;
PixelC* ppxlcRefMBV = ppxlcRefV;
PixelC* ppxlcOrigMBY = ppxlcOrigY;
PixelC* ppxlcOrigMBU = ppxlcOrigU;
PixelC* ppxlcOrigMBV = ppxlcOrigV;
//在一个给定的sprite对象,确定当前宏块是否为应该进行编码
Bool bSptMB_NOT_HOLE= TRUE;
if (m_uiSprite == 1 && m_sptMode != BASIC_SPRITE && m_vopmd.SpriteXmitMode != STOP) {
bSptMB_NOT_HOLE = SptPieceMB_NOT_HOLE(0, iMBY, pmbmd);
RestoreMBmCurrRow (iMBY, m_rgpmbmCurr);
}
for (iMBX = 0; iMBX < m_iNumMBX; iMBX++, iMB++) {
//如果当前宏块不是一个空洞,那么完成编码
m_bSptMB_NOT_HOLE = bSptMB_NOT_HOLE;
if (!m_bSptMB_NOT_HOLE) //低延迟
goto EOMB1;
#ifdef __TRACE_AND_STATS_
m_statsMB.reset ();
m_pbitstrmOut->trace (CSite (iMBX, iMBY), "MB_X_Y");
#endif // __TRACE_AND_STATS_
pmbmd->m_intStepDelta = 0;
//宏块码率控制
if (m_uiRateControl>=RC_TM5) {
pmbmd->m_intStepDelta = m_tm5rc.tm5rc_calc_mquant(iMB,
m_statsVOP.total()) - iQPPrev;
if (pmbmd->m_intStepDelta>2) pmbmd->m_intStepDelta = 2;
else if (pmbmd->m_intStepDelta<-2) pmbmd->m_intStepDelta = -2;
}
#ifdef _MBQP_CHANGE_
iIndexofQ = (iIndexofQ + 1) % 4;
pmbmd->m_intStepDelta = rgiQ [iIndexofQ];
#endif //_MBQP_CHANGE_
pmbmd->m_bSkip = FALSE; //为直接编码模式复位
pmbmd->m_bMCSEL = FALSE; //为直接编码模式复位
pmbmd->m_stepSize = iQPPrev + pmbmd->m_intStepDelta;
assert (pmbmd->m_stepSize <= iMaxQP && pmbmd->m_stepSize > 0);
if ( m_volmd.bVPBitTh >= 0) {
Int iCounter = m_pbitstrmOut -> getCounter();
// NEWPRED
if( ((m_volmd.bNewpredEnable) && (m_volmd.bNewpredSegmentType == 0)) ?
// RRV modification
g_pNewPredEnc->CheckSlice((iMBX *m_iRRVScale),(iMBY *m_iRRVScale),FALSE) : (iCounter - m_iVPCounter > m_volmd.bVPBitTh) ){
pmbmd->m_intStepDelta = 0; //在视频平面头,复位DQ,采用QP
//视频包头信息
codeVideoPacketHeader (iMBX, iMBY, pmbmd->m_stepSize);
m_iVPCounter = iCounter;
bRestartDelayedQP = TRUE;
iVideoPacketNumber ++;
}
}
if(bRestartDelayedQP)
{
pmbmd->m_stepSizeDelayed = pmbmd->m_stepSize;
bRestartDelayedQP = FALSE;
}
else
pmbmd->m_stepSizeDelayed = iQPPrev;
iQPPrev = pmbmd->m_stepSize;
if (pmbmd->m_intStepDelta == 0)
pmbmd->m_dctMd = INTRA;
else
pmbmd->m_dctMd = INTRAQ;
pmbmd->m_bFieldMV = 0;
copyToCurrBuff (ppxlcOrigMBY, ppxlcOrigMBU, ppxlcOrigMBV, m_iFrameWidthY, m_iFrameWidthUV);
if(m_vopmd.RRVmode.iRRVOnOff == 1)
{
pmbmd->m_iVideoPacketNumber = iVideoPacketNumber;
DownSamplingTextureForRRV(m_ppxlcCurrMBY,
m_ppxlcCurrMBY,
(MB_SIZE *m_iRRVScale),
(MB_SIZE *m_iRRVScale));
DownSamplingTextureForRRV(m_ppxlcCurrMBU,
m_ppxlcCurrMBU,
(BLOCK_SIZE* m_iRRVScale),
(BLOCK_SIZE* m_iRRVScale));
DownSamplingTextureForRRV(m_ppxlcCurrMBV,
m_ppxlcCurrMBV,
(BLOCK_SIZE* m_iRRVScale),
(BLOCK_SIZE* m_iRRVScale));
}
quantizeTextureIntraMB (iMBX, iMBY, pmbmd, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, NULL);
if(m_vopmd.RRVmode.iRRVOnOff == 1)
{
UpSamplingTextureForRRV(ppxlcRefMBY, ppxlcRefMBY,
MB_SIZE, MB_SIZE,
m_iFrameWidthY);
UpSamplingTextureForRRV(ppxlcRefMBU, ppxlcRefMBU,
BLOCK_SIZE, BLOCK_SIZE,
m_iFrameWidthUV);
UpSamplingTextureForRRV(ppxlcRefMBV, ppxlcRefMBV,
BLOCK_SIZE, BLOCK_SIZE,
m_iFrameWidthUV);
}
codeMBTextureHeadOfIVOP (pmbmd);
sendDCTCoefOfIntraMBTexture (pmbmd);
EOMB1:
pmbmd++;
#ifdef __TRACE_AND_STATS_
m_statsVOP += m_statsMB;
#endif // __TRACE_AND_STATS_
ppxlcRefMBY += (MB_SIZE *m_iRRVScale);
ppxlcRefMBU += (BLOCK_SIZE *m_iRRVScale);
ppxlcRefMBV += (BLOCK_SIZE *m_iRRVScale);
ppxlcOrigMBY += (MB_SIZE *m_iRRVScale);
ppxlcOrigMBU += (BLOCK_SIZE *m_iRRVScale);
ppxlcOrigMBV += (BLOCK_SIZE *m_iRRVScale);
if (m_uiSprite == 1 && m_sptMode != BASIC_SPRITE) {
bSptMB_NOT_HOLE = SptPieceMB_NOT_HOLE(iMBX+1, iMBY, pmbmd);
m_iNumSptMB++ ;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -