📄 shpenc.cpp
字号:
}
else{
pmvBY->iMVX = (((pmvBaseBY->iMVX)*m_volmd.ihor_sampling_factor_n_shape+(SIGN(pmvBaseBY->iMVX))*m_volmd.ihor_sampling_factor_m_shape/2)/m_volmd.ihor_sampling_factor_m_shape);
pmvBY->iMVY = (((pmvBaseBY->iMVY)*m_volmd.iver_sampling_factor_n_shape+(SIGN(pmvBaseBY->iMVY))*m_volmd.iver_sampling_factor_m_shape/2)/m_volmd.iver_sampling_factor_m_shape);
pmbmd->m_shpssmd = INTER_CODED; //INTER_NO_UPDATE
}
}
assert(pmbmd->m_shpssmd == INTER_CODED);
if (m_bNoShapeChg)
copyReconShapeToRef (ppxlcSrcFrm, m_ppxlcReconCurrBAB, TOTAL_BAB_SIZE, BAB_BORDER);
else
copyReconShapeToMbAndRef (m_ppxlcCurrMBBY, ppxlcSrcFrm, m_ppxlcReconCurrBAB, TOTAL_BAB_SIZE, BAB_BORDER);
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace ((PixelC *)m_puciPredBAB->pixels(), MC_BAB_SIZE, MC_BAB_SIZE, "MB_MC_PRED_BAB");
m_pbitstrmOut->trace (m_ppxlcReconCurrBAB, TOTAL_BAB_SIZE, TOTAL_BAB_SIZE, "MB_RECON_BAB (Ignore Borders)");
m_pbitstrmOut->trace (m_rgpxlcCaeSymbol, m_iWidthCurrBAB , m_iWidthCurrBAB , "MB_ENCODED_BAB");
#endif // __TRACE_AND_STATS_
// make borders
makeRightBottomBorder (m_ppxlcReconCurrBAB, TOTAL_BAB_SIZE);
m_pbitstrmShapeMBOut->setBookmark ();
// try inter
UInt nBitsModeInter = codeShapeModeSSInter (pmbmd->m_shpssmd, shpmdColocatedMB);
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace ("SCALABLE_SHAPE_INTER_CODED_CODING_VERTICAL (TRIAL)");
#endif // __TRACE_AND_STATS_
UInt nBitsVInter = encodeCAEInter (INTER_CAE_MVDZ, VERTICAL);
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace ("SCALABLE_SHAPE_INTER_CODED_CODING_HORIZONTAL (TRIAL)");
#endif // __TRACE_AND_STATS_
UInt nBitsHInter = encodeCAEInter (INTER_CAE_MVDZ, HORIZONTAL);
UInt nBitsInter = nBitsModeInter + min (nBitsVInter, nBitsHInter);
m_pbitstrmShapeMBOut->gotoBookmark ();
if (nBitsInter < nBitsIntra){
// choose inter coding
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace ("MB_CAE_INTER_CODING (REAL)");
m_pbitstrmOut->trace (*pmvBY, "MB_SHP_MV (half pel)");
#endif // __TRACE_AND_STATS_
codeShapeModeSSInter (pmbmd->m_shpssmd, shpmdColocatedMB);
if(nBitsVInter<nBitsHInter) encodeCAEInter (INTER_CAE_MVDZ, VERTICAL);
else encodeCAEInter (INTER_CAE_MVDZ, HORIZONTAL);
return nBitsInter;
}
else{
motionCompLowerBY ((PixelC*) m_puciPredBAB->pixels (),
(PixelC*) pvopcRefQ1->getPlane (BY_PLANE)->pixels (),
iX-1,
iY-1); //-1 due to 18x18 motion comp
// make borders
makeRightBottomBorder ( m_ppxlcReconCurrBAB,
TOTAL_BAB_SIZE,
(PixelC*)((pvopcRefQ1->getPlane (BY_PLANE)->pixels ())+(iY + EXPANDY_REF_FRAME) * m_iFrameWidthY + iX + EXPANDY_REF_FRAME),
m_iFrameWidthY);
// choose intra coding
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace ("MB_SI_INTRA_CODING (REAL)");
#endif // __TRACE_AND_STATS_
pmvBY->iMVX = NOT_MV;
pmvBY->iMVY = NOT_MV;
//for st_order
motionCompLowerBY ((PixelC*) m_puciPredBAB->pixels (),
(PixelC*) pvopcRefQ1->getPlane (BY_PLANE)->pixels (),
iX-1,
iY-1); //-1 due to 18x18 motion comp
pmbmd->m_shpssmd = INTRA_CODED;
codeShapeModeSSInter (pmbmd->m_shpssmd, shpmdColocatedMB);
encodeSIIntra (INTRA_CODED, (pvopcRefQ1->getPlane (BY_PLANE)->m_pbHorSamplingChk)+iX, (pvopcRefQ1->getPlane (BY_PLANE)->m_pbVerSamplingChk)+iY);
return nBitsIntra;
}
return FALSE;
}
//shape mode coding for OBSS
UInt CVideoObjectEncoder::codeShapeModeSSIntra (const ShapeSSMode& shpmd, const ShapeMode& shpmdColocatedMB)
{
UInt nBits = 0;
CEntropyEncoder* pentrenc = m_pentrencSet->m_ppentrencShapeSSModeIntra [0];
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace ((Int) shpmd, "MB_Curr_ShpSSMd");
#endif // __TRACE_AND_STATS_
pentrenc->attachStream(*m_pbitstrmShapeMBOut);
nBits += pentrenc->encodeSymbol (shpmd, "MB_Shape_SS_Mode");
pentrenc->attachStream(*m_pbitstrmOut);
return nBits;
}
UInt CVideoObjectEncoder::codeShapeModeSSInter (const ShapeSSMode& shpmd, const ShapeMode& shpmdColocatedMB)
{
assert (shpmdColocatedMB != UNKNOWN && shpmd != UNDEFINED);
UInt nBits = 0;
Int colocatedIndex[7]={0,0,1,3,3,2,2};
CEntropyEncoder* pentrenc = m_pentrencSet->m_ppentrencShapeSSModeInter [colocatedIndex[shpmdColocatedMB]];
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace ((Int) shpmdColocatedMB, "MB_Colocated_ShpMd");
m_pbitstrmOut->trace ((Int) shpmd, "MB_Curr_ShpSSMd");
#endif // __TRACE_AND_STATS_
pentrenc->attachStream(*m_pbitstrmShapeMBOut);
nBits += pentrenc->encodeSymbol (shpmd, "MB_Shape_SS_Mode");
pentrenc->attachStream(*m_pbitstrmOut);
return nBits;
}
//for SI shape encoding
UInt CVideoObjectEncoder::encodeSIIntra (ShapeSSMode shpmd, Bool* HorSamplingChk, Bool* VerSamplingChk)
{
assert (shpmd == INTRA_CODED);
UInt nBits = 0;
const PixelC *ppxlcPredBAB = m_puciPredBAB->pixels();
Int iSizeMB = m_iWidthCurrBAB-BAB_BORDER*2;
Int iSizePredBAB = iSizeMB+MC_BAB_BORDER*2;
PixelC* ppxlcReconCurrBABTr; //for st_order
Int scan_order =0;
double h_factor = log((double)m_volmd.ihor_sampling_factor_n_shape/m_volmd.ihor_sampling_factor_m_shape)/log(2);
int h_factor_int = (int)floor(h_factor+0.000001);
double v_factor = log((double)m_volmd.iver_sampling_factor_n_shape/m_volmd.iver_sampling_factor_m_shape)/log(2);
int v_factor_int = (int)floor(v_factor+0.000001);
Int NumTwoPowerLoopX = h_factor_int;
Bool ResidualLoopX = 0;
if(h_factor - h_factor_int > 0.000001 ) ResidualLoopX = 1;
Int NumTwoPowerLoopY = v_factor_int ;
Bool ResidualLoopY = 0 ;
if(v_factor - v_factor_int > 0.000001 ) ResidualLoopY = 1;
if ( m_volmd.ihor_sampling_factor_n_shape == 2 && m_volmd.ihor_sampling_factor_m_shape == 1 &&
m_volmd.iver_sampling_factor_n_shape == 2 && m_volmd.iver_sampling_factor_m_shape == 1) {
scan_order = decideScanOrder((PixelC*) m_puciPredBAB->pixels ()); //for st_order
/*-- Curr BAB transposing --*/
if (scan_order){
ppxlcReconCurrBABTr = new PixelC [BAB_SIZE * BAB_SIZE];
for(Int j=0; j<BAB_SIZE; j++)
for(Int i=0; i<BAB_SIZE; i++)
ppxlcReconCurrBABTr[j*BAB_SIZE+i]=m_ppxlcReconCurrBAB[i*BAB_SIZE+j];
m_rgpxlcCaeSymbol = ppxlcReconCurrBABTr;
Bool *tmp;
tmp = HorSamplingChk;
HorSamplingChk = VerSamplingChk;
VerSamplingChk = tmp;
}
}
//the real arithmatic encoding
StartArCoder (m_parcodec);
Int no_mismatch=0, q=0;
Int no_mismatch_v=0, no_match_v=0, no_xor_v=0, type_id_mis_v[256][4];
Int no_mismatch_h=0, no_match_h=0, no_xor_h=0, type_id_mis_h[256][4];
if ( h_factor > 0.000001 )
// Vertical Scan
VerticalScanning(&no_mismatch_v,&no_match_v,&no_xor_v,type_id_mis_v,NumTwoPowerLoopX,NumTwoPowerLoopY,ResidualLoopX,ResidualLoopY,HorSamplingChk,VerSamplingChk);
if ( v_factor > 0.000001 )
// Horizontal Scan
HorizontalScanning(&no_mismatch_h,&no_match_h,&no_xor_h,type_id_mis_h,NumTwoPowerLoopX,NumTwoPowerLoopY,ResidualLoopX,ResidualLoopY,HorSamplingChk,VerSamplingChk);
no_mismatch = no_mismatch_v + no_mismatch_h;
if(no_mismatch==0){
q=SI_bab_type_prob[0];
ArCodeSymbol (0,q,m_parcodec,m_pbitstrmShapeMBOut);
if(ResidualLoopX == 1 || h_factor_int>0) ExclusiveORcoding(no_xor_v, type_id_mis_v, V_SCANNING);
if(ResidualLoopY == 1 || v_factor_int>0) ExclusiveORcoding(no_xor_h, type_id_mis_h, H_SCANNING);
}
else{
q=SI_bab_type_prob[0];
ArCodeSymbol(1,q,m_parcodec,m_pbitstrmShapeMBOut);
if(ResidualLoopX == 1 || h_factor_int>0) FullCoding(no_match_v,type_id_mis_v, V_SCANNING);
if(ResidualLoopY == 1 || v_factor_int>0) FullCoding(no_match_h,type_id_mis_h, H_SCANNING);
}
StopArCoder (m_parcodec, m_pbitstrmShapeMBOut);
if ( m_volmd.ihor_sampling_factor_n_shape == 2 && m_volmd.ihor_sampling_factor_m_shape == 1 &&
m_volmd.iver_sampling_factor_n_shape == 2 && m_volmd.iver_sampling_factor_m_shape == 1) {
if (scan_order){
m_rgpxlcCaeSymbol = m_ppxlcReconCurrBAB;
delete [] ppxlcReconCurrBABTr;
Bool *tmp;
tmp = HorSamplingChk;
HorSamplingChk = VerSamplingChk;
VerSamplingChk = tmp;
}
}
nBits += m_parcodec->nBits;
return nBits;
}
//XOR data coding
Void CVideoObjectEncoder::ExclusiveORcoding(Int no_xor, Int type_id_mis[256][4], SIDirection md_scan)
{
int i=0,j=0, index=0;
int bit=0, q=0;
if(no_xor!=0){
do{
index=type_id_mis[j][1];
if((index==2) || (index==3)){
bit=index-2;
if(md_scan==V_SCANNING) q=enh_intra_v_prob[type_id_mis[j][0]];
else q=enh_intra_h_prob[type_id_mis[j][0]];
ArCodeSymbol(bit,q,m_parcodec,m_pbitstrmShapeMBOut);
i++;
}
j++;
}while(i<no_xor);
}
}
//Full coding for the mismatch data existed case
Void CVideoObjectEncoder::FullCoding(Int no_match, Int type_id_mis[256][4], SIDirection md_scan)
{
int j=0, index=0;
int bit=0, q=0;
do{
index=type_id_mis[j][1];
bit=(int)index%2;
if(md_scan==V_SCANNING) q=enh_intra_v_prob[type_id_mis[j][0]];
else q=enh_intra_h_prob[type_id_mis[j][0]];
ArCodeSymbol(bit,q,m_parcodec,m_pbitstrmShapeMBOut);
j++;
}while(j<no_match);
}
//~OBSS_SAIT_991015
UInt CVideoObjectEncoder::codeShapeModeIntra (ShapeMode shpmd, const CMBMode* pmbmd, Int iMBX, Int iMBY)
{
UInt nBits = 0;
assert (shpmd == ALL_TRANSP || shpmd == ALL_OPAQUE || shpmd == INTRA_CAE);
static Int iLeftTopMostMB = 0;
Int iRightMostMB = m_iNumMBX - 1;
//get previous shape codes;
Bool bLeftBndry, bRightTopBndry, bTopBndry, bLeftTopBndry;
Int iMBnum = VPMBnum(iMBX, iMBY);
bLeftBndry = bVPNoLeft(iMBnum, iMBX);
bTopBndry = bVPNoTop(iMBnum);
bRightTopBndry = bVPNoRightTop(iMBnum, iMBX);
bLeftTopBndry = bVPNoLeftTop(iMBnum, iMBX);
ShapeMode shpmdTop = ALL_TRANSP;
ShapeMode shpmdTopRight = ALL_TRANSP;
ShapeMode shpmdTopLeft = ALL_TRANSP;
ShapeMode shpmdLeft = ALL_TRANSP;
// Modified for error resilient mode by Toshiba(1997-11-14)
if (!bTopBndry)
shpmdTop = (pmbmd - m_iNumMBX)->m_shpmd;
if (!bRightTopBndry)
shpmdTopRight = (pmbmd - m_iNumMBX + 1)->m_shpmd;
if (!bLeftBndry)
shpmdLeft = (pmbmd - 1)->m_shpmd;
if (!bLeftTopBndry)
shpmdTopLeft = (pmbmd - m_iNumMBX - 1)->m_shpmd;
//if (iMBY > iLeftTopMostMB) {
// shpmdTop = (pmbmd - m_iNumMBX)->m_shpmd;
// if (iMBX < iRightMostMB)
// shpmdTopRight = (pmbmd - m_iNumMBX + 1)->m_shpmd;
//}
//if (iMBX > iLeftTopMostMB) {
// shpmdLeft = (pmbmd - 1)->m_shpmd;
// if (iMBY > iLeftTopMostMB)
// shpmdTopLeft = (pmbmd - m_iNumMBX - 1)->m_shpmd;
//}
// End Toshiba(1997-11-14)
assert (shpmdTop != UNKNOWN && shpmdTopRight != UNKNOWN &&
shpmdTopLeft != UNKNOWN && shpmdLeft != UNKNOWN);
//get code and its size
UInt uiTblIndex = shpmdTopLeft * 81 + shpmdTop * 27 +
shpmdTopRight * 9 + shpmdLeft * 3 + shpmd;
assert (uiTblIndex >= 0 && uiTblIndex < 243);
assert (grgchFirstShpCd [uiTblIndex] == 0 || grgchFirstShpCd [uiTblIndex] == 2 ||
grgchFirstShpCd [uiTblIndex] == 3);
// Modified for error resilient mode by Toshiba(1997-11-14)
UInt nCodeSize = (grgchFirstShpCd [uiTblIndex] == 0) ? 1
: grgchFirstShpCd [uiTblIndex];
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace ((Int) shpmd, "MB_Curr_ShpMd");
#endif // __TRACE_AND_STATS_
m_pbitstrmShapeMBOut->putBits ((Int) 1, nCodeSize, "MB_Shape_Mode");
// End Toshiba(1997-11-14)
nBits += nCodeSize;
return nBits;
}
UInt CVideoObjectEncoder::codeShapeModeInter (const ShapeMode& shpmd, const ShapeMode& shpmdColocatedMB)
{
assert (shpmdColocatedMB != UNKNOWN && shpmd != UNKNOWN);
UInt nBits = 0;
CEntropyEncoder* pentrenc = m_pentrencSet->m_ppentrencShapeMode [shpmdColocatedMB];
#ifdef __TRACE_AND_STATS_
m_pbitstrmOut->trace ((Int) shpmdColocatedMB, "MB_Colocated_ShpMd");
m_pbitstrmOut->trace ((Int) shpmd, "MB_Curr_ShpMd");
#endif // __TRACE_AND_STATS_
pentrenc->attachStream(*m_pbitstrmShapeMBOut);
nBits += pentrenc->encodeSymbol (shpmd, "MB_Shape_Mode");
pentrenc->attachStream(*m_pbitstrmOut);
return nBits;
}
// find appropriate size for coded babs
ShapeMode CVideoObjectEncoder::round (PixelC* ppxlcSrcFrm, const CMBMode* pmbmd) //only to partial BABs
{
ShapeMode shpmd;
Bool bIsErrorLarge;
if (m_volmd.bNoCrChange == FALSE)
{
// attempt to reduce bab size
m_bNoShapeChg = FALSE;
static iThreshD4 = 7 * OPAQUE;
// reduce by factor 4
downSampleShape (m_ppxlcCurrMBBY,
m_rgiSubBlkIndx16x16,
m_ppxlcCurrMBBYDown4,
m_rgiPxlIndx8x8,
4, iThreshD4, 16);
// see if this size is acceptable
shpmd = INTRA_CAE;
m_iInverseCR = 4;
m_iWidthCurrBAB = 8;
// subsample border before upsample to original size
subsampleLeftTopBorderFromVOP (ppxlcSrcFrm, m_ppxlcCurrMBBYDown4);
makeRightBottomBorder (m_ppxlcCurrMBBYDown4, 8);
upSampleShape(ppxlcSrcFrm,m_ppxlcCurrMBBYDown4,m_ppxlcReconCurrBAB);
// check if approximation is acceptable
bIsErrorLarge = isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16,
m_ppxlcReconCurrBAB, m_rgiSubBlkIndx20x20, 20, pmbmd);
if(!bIsErrorLarge)
{
// ok, so assign encoding buffer
m_rgpxlcCaeSymbol = m_ppxlcCurrMBBYDown4;
return shpmd;
}
static iThreshD2 = OPAQUE;
// factor 4 failed, so try to reduce by factor 2
downSampleShape (m_ppxlcCurrMBBY,
m_rgiSSubBlkIndx16x16,
m_ppxlcCurrMBBYDown2,
m_rgiPxlIndx12x12,
2, iThreshD2, 64);
// mixed, so see if this size is acceptable
shpmd = INTRA_CAE;
m_iInverseCR = 2;
m_iWidthCurrBAB = 12;
// subsample border before upsample to original size
subsampleLeftTopBorderFromVOP (ppxlcSrcFrm, m_ppxlcCurrMBBYDown2);
makeRightBottomBorder (m_ppxlcCurrMBBYDown2, 12);
upSampleShape(ppxlcSrcFrm,m_ppxlcCurrMBBYDown2, m_ppxlcReconCurrBAB);
// check if approximation is acceptable
bIsErrorLarge = isErrorLarge (m_ppxlcCurrMBBY, m_rgiSubBlkIndx16x16, 16,
m_ppxlcReconCurrBAB, m_rgiSubBlkIndx20x20, 20, pmbmd);
if(!bIsErrorLarge)
{
// ok, so assign encoding buffer
m_rgpxlcCaeSymbol = m_ppxlcCurrMBBYDown2;
return shpmd;
}
}
// has to be original size
m_bNoShapeChg = TRUE;
shpmd = INTRA_CAE;
m_iInverseCR = 1;
m_iWidthCurrBAB = BAB_SIZE;
// copy data to ReconCurrBAB
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -