📄 mbenc.cpp
字号:
/*************************************************************************
This software module was originally developed by
Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation
Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation
Simon Winder (swinder@microsoft.com), Microsoft Corporation
(date: June, 1997)
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
Fujitsu Laboratories Ltd. (contact: Eishi Morimatsu)
and also edited by
Takefumi Nagumo (nagumo@av.crl.sony.co.jp) Sony Corporation
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:
MBenc.cpp
Abstract:
MacroBlock encoder
Revision History:
This software module was edited by
Hiroyuki Katata (katata@imgsl.mkhar.sharp.co.jp), Sharp Corporation
Norio Ito (norio@imgsl.mkhar.sharp.co.jp), Sharp Corporation
Shuichi Watanabe (watanabe@imgsl.mkhar.sharp.co.jp), Sharp Corporation
(date: October, 1997)
for object based temporal scalability.
Dec 20, 1997: Interlaced tools added by NextLevel Systems X.Chen, B. Eifrig
May. 9 1998: add boundary by Hyundai Electronics
Cheol-Soo Park (cspark@super5.hyundai.co.kr)
Feb. 23 1999: GMC added by Yoshinori Suzuki(Hitachi, Ltd.)
May 9, 1999: tm5 rate control by DemoGraFX, duhoff@mediaone.net
NOTE:
m_pvopfCurrQ holds the original data until it is texture quantized
Sep.06 1999 : RRV added by Eishi Morimatsu (Fujitsu Laboratories Ltd.)
Feb.01 2000 : Bug fixed OBSS by Takefumi Nagumo (Sony)
*************************************************************************/
#include <stdlib.h>
#include <math.h>
#include <iostream.h>
#include "typeapi.h"
#include "codehead.h"
#include "mode.hpp"
#include "global.hpp"
#include "entropy/bitstrm.hpp"
#include "entropy/entropy.hpp"
#include "entropy/huffman.hpp"
#include "vopses.hpp"
#include "vopseenc.hpp"
// 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::encodePVOPMBWithShape (
PixelC* ppxlcRefMBY, PixelC* ppxlcRefMBU, PixelC* ppxlcRefMBV,
PixelC* ppxlcRefMBA, PixelC* ppxlcRefBY,
CMBMode* pmbmd, const CMotionVector* pmv, CMotionVector* pmvBY,
ShapeMode shpmdColocatedMB,
Int imbX, Int imbY,
CoordI x, CoordI y, Int& iQPPrev)
{
encodePVOPMBJustShape(ppxlcRefBY,pmbmd,shpmdColocatedMB,pmv,pmvBY,x,y,imbX,imbY);
dumpCachedShapeBits();
encodePVOPMBTextureWithShape(ppxlcRefMBY,ppxlcRefMBU,ppxlcRefMBV,ppxlcRefMBA,pmbmd,
pmv,imbX,imbY,x,y,iQPPrev);
}*/
Void CVideoObjectEncoder::encodePVOPMBJustShape(
PixelC* ppxlcRefBY, CMBMode* pmbmd, ShapeMode shpmdColocatedMB,
const CMotionVector* pmv, CMotionVector* pmvBY,
CoordI x, CoordI y, Int imbX, Int imbY)
{
//OBSS_SAIT_991015
//OBSSFIX_MODE3
if(!(m_volmd.bSpatialScalability && m_volmd.iHierarchyType==0) ||
(m_volmd.bSpatialScalability && m_volmd.iHierarchyType==0 && m_volmd.volType == ENHN_LAYER && m_volmd.iEnhnType!=0 && m_volmd.iuseRefShape ==1)){
// if(!(m_volmd.bSpatialScalability && m_volmd.iHierarchyType==0)){
//~OBSSFIX_MODE3
m_statsMB.nBitsShape += codeInterShape (
ppxlcRefBY, m_pvopcRefQ0, pmbmd, shpmdColocatedMB,
pmv, pmvBY, x, y, imbX, imbY);
}
else{
if((m_volmd.volType == BASE_LAYER) || (!(m_volmd.iEnhnType==0 || m_volmd.iuseRefShape ==0) && !m_volmd.bShapeOnly) )
m_statsMB.nBitsShape += codeInterShape (
ppxlcRefBY, m_pvopcRefQ0, pmbmd, shpmdColocatedMB,
pmv, pmvBY, x, y, imbX, imbY);
else
m_statsMB.nBitsShape += codeSIShapePVOP (
ppxlcRefBY, m_pvopcRefQ0, pmbmd, shpmdColocatedMB,
pmv, pmvBY, x, y, imbX, imbY);
}
//~OBSS_SAIT_991015
// change pmbmd to inter if all transparent
decideTransparencyStatus (pmbmd, m_ppxlcCurrMBBY);
}
Void CVideoObjectEncoder::dumpCachedShapeBits()
{
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace("INSERTING PRE-ENCODED MB SHAPE STREAM HERE\n");
m_pbitstrmOut->trace(m_pbitstrmOut->getCounter(),"Location Before");
#endif // __TRACE_AND_STATS_
m_pbitstrmOut->putBitStream(*m_pbitstrmShapeMBOut);
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace(m_pbitstrmOut->getCounter(),"Location After");
#endif // __TRACE_AND_STATS_
m_pbitstrmShapeMBOut->flush();
m_pbitstrmShapeMBOut->resetAll();
}
// HHI Schueuer: added const PixelC *ppxlcCurrMBBY, const PixelC *ppxlcCurrMBBUV for sadct
Void CVideoObjectEncoder::encodePVOPMBTextureWithShape(
PixelC* ppxlcRefMBY,
PixelC* ppxlcRefMBU,
PixelC* ppxlcRefMBV,
PixelC** pppxlcRefMBA,
CMBMode* pmbmd,
const CMotionVector* pmv,
Int imbX,
Int imbY,
CoordI x,
CoordI y,
Int& iQPPrev,
Int& iQPPrevAlpha,
Bool& bUseNewQPForVlcThr,
const PixelC *ppxlcCurrMBBY,
const PixelC *ppxlcCurrMBBUV)
{
// update quantiser
pmbmd->m_stepSize = iQPPrev + pmbmd->m_intStepDelta;
if(bUseNewQPForVlcThr)
pmbmd->m_stepSizeDelayed = pmbmd->m_stepSize;
else
pmbmd->m_stepSizeDelayed = iQPPrev;
iQPPrev = pmbmd->m_stepSize;
if (pmbmd -> m_dctMd == INTRA || pmbmd -> m_dctMd == INTRAQ) {
if(pmbmd -> m_rgTranspStatus [0] == PARTIAL)
LPEPadding (pmbmd);
if (m_volmd.fAUsage == EIGHT_BIT) {
// update alpha quant
if(!m_volmd.bNoGrayQuantUpdate)
{
iQPPrevAlpha = (iQPPrev * m_vopmd.intStepPAlpha[0]) / m_vopmd.intStep;
if(iQPPrevAlpha<1)
iQPPrevAlpha=1;
}
pmbmd->m_stepSizeAlpha = iQPPrevAlpha;
}
assert (pmbmd -> m_rgTranspStatus [0] != ALL);
/*BBM// Added for Boundary by Hyundai(1998-5-9)
if (m_vopmd.bInterlace && pmbmd -> m_rgTranspStatus [0] == PARTIAL)
boundaryMacroBlockMerge (pmbmd);
// End of Hyundai(1998-5-9)*/
// HHI Schueuer: sadct
if (!m_volmd.bSadctDisable)
quantizeTextureIntraMB (imbX, imbY, pmbmd, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, pppxlcRefMBA, ppxlcCurrMBBY, ppxlcCurrMBBUV);
else
quantizeTextureIntraMB (imbX, imbY, pmbmd, ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV, pppxlcRefMBA);
// end HHI
codeMBTextureHeadOfPVOP (pmbmd);
sendDCTCoefOfIntraMBTexture (pmbmd);
if (m_volmd.fAUsage == EIGHT_BIT) {
for(Int iAuxComp=0;iAuxComp<m_volmd.iAuxCompCount;iAuxComp++) { // MAC (SB) 29-Nov-99
codeMBAlphaHeadOfPVOP (pmbmd,iAuxComp);
sendDCTCoefOfIntraMBAlpha (pmbmd,iAuxComp);
}
}
/*BBM// Added for Boundary by Hyundai(1998-5-9)
if (m_vopmd.bInterlace && pmbmd -> m_bMerged[0])
mergedMacroBlockSplit (pmbmd, ppxlcRefMBY, ppxlcRefMBA);
// End of Hyundai(1998-5-9)*/
bUseNewQPForVlcThr = FALSE;
}
else { // INTER or skipped
if (m_volmd.fAUsage == EIGHT_BIT) {
// update alpha quant
if(!m_volmd.bNoGrayQuantUpdate)
iQPPrevAlpha = (iQPPrev * m_vopmd.intStepPAlpha[0]) / m_vopmd.intStep;
pmbmd->m_stepSizeAlpha = iQPPrevAlpha;
}
if (pmbmd -> m_rgTranspStatus [0] == PARTIAL) {
CoordI xRefUV, yRefUV;
// GMC
if(pmbmd->m_bMCSEL) {
FindGlobalChromPredForGMC(x,y,m_ppxlcPredMBU,m_ppxlcPredMBV);
}else{
// ~GMC
// INTERLACE
// new changes
if(pmbmd->m_bFieldMV) {
CoordI xRefUV1, yRefUV1;
mvLookupUV (pmbmd, pmv, xRefUV, yRefUV, xRefUV1, yRefUV1);
motionCompFieldUV(m_ppxlcPredMBU, m_ppxlcPredMBV,
m_pvopcRefQ0, x, y, xRefUV, yRefUV, pmbmd->m_bForwardTop,
&m_rctRefVOPY0); // added by Y.Suzuki for the extended bounding box support
motionCompFieldUV(m_ppxlcPredMBU + BLOCK_SIZE, m_ppxlcPredMBV + BLOCK_SIZE,
m_pvopcRefQ0, x, y, xRefUV1, yRefUV1, pmbmd->m_bForwardBottom,
&m_rctRefVOPY0); // added by Y.Suzuki for the extended bounding box support
}
else {
// ~INTERLACE
mvLookupUVWithShape (pmbmd, pmv, xRefUV, yRefUV);
motionCompUV (m_ppxlcPredMBU, m_ppxlcPredMBV, m_pvopcRefQ0, x, y,
xRefUV, yRefUV, m_vopmd.iRoundingControl,&m_rctRefVOPY0);
}
// GMC
}
// ~GMC
motionCompMBYEnc (pmv, pmbmd, imbX, imbY, x, y, &m_rctRefVOPY0);
computeTextureErrorWithShape ();
}
else {
// not partial
CoordI xRefUV, yRefUV, xRefUV1, yRefUV1;
// GMC
if(pmbmd->m_bMCSEL) {
FindGlobalChromPredForGMC(x,y,m_ppxlcPredMBU,m_ppxlcPredMBV);
}else{
// ~GMC
mvLookupUV (pmbmd, pmv, xRefUV, yRefUV, xRefUV1, yRefUV1);
// INTERLACE
// new changes
if(pmbmd->m_bFieldMV) {
motionCompFieldUV(m_ppxlcPredMBU, m_ppxlcPredMBV,
m_pvopcRefQ0, x, y, xRefUV, yRefUV, pmbmd->m_bForwardTop,
&m_rctRefVOPY0); // added by Y.Suzuki for the extended bounding box support
motionCompFieldUV(m_ppxlcPredMBU + BLOCK_SIZE, m_ppxlcPredMBV + BLOCK_SIZE,
m_pvopcRefQ0, x, y, xRefUV1, yRefUV1, pmbmd->m_bForwardBottom,
&m_rctRefVOPY0); // added by Y.Suzuki for the extended bounding box support
}
else {
// ~INTERLACE
motionCompUV (m_ppxlcPredMBU, m_ppxlcPredMBV, m_pvopcRefQ0, x, y,
xRefUV, yRefUV, m_vopmd.iRoundingControl, &m_rctRefVOPY0);
}
// GMC
}
// ~GMC
motionCompMBYEnc (pmv, pmbmd, imbX, imbY, x, y, &m_rctRefVOPY0);
computeTextureError ();
}
Bool bSkip = pmbmd->m_bhas4MVForward ? (pmv [1].isZero () && pmv [2].isZero () && pmv [3].isZero () && pmv [4].isZero ())
: (!pmbmd->m_bFieldMV && pmv->isZero()) ;
// GMC
if(pmbmd -> m_bMCSEL)
bSkip= TRUE;
// ~GMC
/*BBM// Added for Boundary by Hyundai(1998-5-9)
if (m_vopmd.bInterlace && pmbmd -> m_rgTranspStatus [0] == PARTIAL)
boundaryMacroBlockMerge (pmbmd);
// End of Hyundai(1998-5-9)*/
if(!m_volmd.bAllowSkippedPMBs)
bSkip = FALSE;
// HHI Schueuer: sadct
if (!m_volmd.bSadctDisable)
quantizeTextureInterMB (pmbmd, pmv, pppxlcRefMBA, bSkip, ppxlcCurrMBBY, ppxlcCurrMBBUV); // decide COD here
else
quantizeTextureInterMB (pmbmd, pmv, pppxlcRefMBA, bSkip); // decide COD here
// end HHI
// GMC
if((m_uiSprite == 2 && m_vopmd.vopPredType == SPRITE))
if(pmbmd -> m_bSkip && !pmbmd -> m_bMCSEL)
pmbmd -> m_bSkip = FALSE;
// ~GMC
codeMBTextureHeadOfPVOP (pmbmd);
if (!(pmbmd -> m_bSkip && !pmbmd -> m_bMCSEL)) { // GMC
/*BBM// Added for Boundary by Hyundai(1998-5-9)
if (m_vopmd.bInterlace && pmbmd -> m_bMerged[0])
swapTransparentModes (pmbmd, BBS);
// End of Hyundai(1998-5-9)*/
//OBSS_SAIT_991015
if(!(m_volmd.volType == ENHN_LAYER && m_vopmd.iRefSelectCode == 3) && !pmbmd -> m_bMCSEL) //for zero-MV of OBSS(P-VOP)
m_statsMB.nBitsMV += encodeMVWithShape (pmv, pmbmd, imbX, imbY);
//~OBSS_SAIT_991015
/*BBM// Added for Boundary by Hyundai(1998-5-9)
if (m_vopmd.bInterlace && pmbmd -> m_bMerged[0])
swapTransparentModes (pmbmd, BBM);
// End of Hyundai(1998-5-9)*/
// GMC
if (pmbmd -> m_bSkip)
assignPredToCurrQ (ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV);
else
// ~GMC
sendDCTCoefOfInterMBTexture (pmbmd);
// addErrorAndPredToCurrQ (ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV); // delete by Hyundai, ok swinder
}
else
assignPredToCurrQ (ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV);
if (m_volmd.fAUsage == EIGHT_BIT) {
for(Int iAuxComp=0;iAuxComp<m_volmd.iAuxCompCount;iAuxComp++) { // MAC (SB) 29-Nov-99
codeMBAlphaHeadOfPVOP (pmbmd, iAuxComp );
if (pmbmd -> m_pCODAlpha[iAuxComp] == ALPHA_CODED) {
sendDCTCoefOfInterMBAlpha (pmbmd, iAuxComp);
}
else if(pmbmd -> m_pCODAlpha[iAuxComp] == ALPHA_SKIPPED)
assignAlphaPredToCurrQ (pppxlcRefMBA[iAuxComp],iAuxComp);
}
}
/*BBM// Added for Boundary by Hyundai(1998-5-9)
if (m_vopmd.bInterlace && pmbmd -> m_bMerged[0])
mergedMacroBlockSplit (pmbmd);
// End of Hyundai(1998-5-9)*/
if (!pmbmd -> m_bSkip)
{
bUseNewQPForVlcThr = FALSE;
addErrorAndPredToCurrQ (ppxlcRefMBY, ppxlcRefMBU, ppxlcRefMBV);
}
if (m_volmd.fAUsage == EIGHT_BIT) {
for(Int iAuxComp=0;iAuxComp<m_volmd.iAuxCompCount;iAuxComp++) { // MAC (SB) 29-Nov-99
if (pmbmd -> m_pCODAlpha[iAuxComp] == ALPHA_CODED)
addAlphaErrorAndPredToCurrQ (pppxlcRefMBA[iAuxComp],iAuxComp);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -