📄 getpic.cpp
字号:
{ // Read DQUANT if necessary
if (syntax_arith_coding)
{
DQUANT_index = m_sacode.decode_a_symbol(cumf_DQUANT);
DQUANT = dquanttab[DQUANT_index] - 2;
quant +=DQUANT;
if (trace)
{
outshow.Format("DQUANT Index: %d DQUANT %d \n",DQUANT_index, DQUANT);
AfxMessageBox(outshow);
}
}
else
{
DQUANT = m_getbits.getbits(2);
quant += DQ_tab[DQUANT];
}
if (trace)
{
outshow.Format("DQUANT:%d tab=%d ",DQUANT,DQ_tab[DQUANT]);
AfxMessageBox(outshow);
}
//调整量化因子到预定的范围内
if (quant > 31 || quant < 1)
{
if (!quiet)
AfxMessageBox("Quantizer out of range: clipping!");
quant = mmax(1,mmin(31,quant));
// could set fault-flag and resync here
}
}//end of (dquant decode)
//解码 motion vectors**********************************
if (Mode == MODE_INTER || Mode == MODE_INTER_Q
||Mode == MODE_INTER4V || pb_frame)
{
if (Mode == MODE_INTER4V)
{
startmv = 1;
stopmv = 4;
}
else
{
startmv = 0;
stopmv = 0;
}
for (k = startmv; k <= stopmv; k++)
{
if (syntax_arith_coding)
{
mvx_index = m_sacode.decode_a_symbol(cumf_MVD);
mvx = mvdtab[mvx_index];
mvy_index = m_sacode.decode_a_symbol(cumf_MVD);
mvy = mvdtab[mvy_index];
if (trace)
{
outshow.Format("mvx_index: %d mvy_index: %d \n", mvy_index, mvx_index);
AfxMessageBox(outshow);
}
}
else //Get Mv in HuffMan
{
mvx = m_getvlc.getTMNMV();
mvy = m_getvlc.getTMNMV();
}
pmv0 = find_pmv(xpos,ypos,k,0);
pmv1 = find_pmv(xpos,ypos,k,1);
mvx = motion_decode(mvx, pmv0);
mvy = motion_decode(mvy, pmv1);
if (trace)
{
outshow.Format("mvx: %d mvy: %d", mvx,mvy);
AfxMessageBox(outshow);
}
//检测运动矢量是否指向图像内部
if (!mv_outside_frame)
{
bsize = k ? 8 : 16;
offset = k ? (((k-1)&1)<<3) : 0;
//仅检测整象素(mvx/2)的MV
if((xpos<<4) + (mvx/2) + offset < 0 ||
(xpos<<4) + (mvx/2) + offset > (mb_width<<4) - bsize)
{
if (!quiet)
AfxMessageBox("mvx out of range: searching for sync!");
fault = 1;
}
offset = k ? (((k-1)&2)<<2) : 0;
if((ypos<<4) + (mvy/2) + offset < 0 ||
(ypos<<4) + (mvy/2) + offset > (mb_height<<4) - bsize)
{
if(!quiet)
AfxMessageBox("mvy out of range: searching for sync!");
fault = 1;
}
}//end of(!mv_outside_frame)
MV[0][k][ypos+1][xpos+1] = mvx;
MV[1][k][ypos+1][xpos+1] = mvy;
}//end of ( normal MV Decode)
// PB frame delta vectors
if (pb_frame)
{
if (MODB == PBMODE_MVDB || MODB == PBMODE_CBPB_MVDB)
{
if (syntax_arith_coding)
{
mvdbx_index = m_sacode.decode_a_symbol(cumf_MVD);
mvdbx = mvdtab[mvdbx_index];
mvdby_index = m_sacode.decode_a_symbol(cumf_MVD);
mvdby = mvdtab[mvdby_index];
}
else//Huff_Decode
{
mvdbx = m_getvlc.getTMNMV();
mvdby = m_getvlc.getTMNMV();
}
mvdbx = motion_decode(mvdbx, 0);
mvdby = motion_decode(mvdby, 0);
if (trace)
{
outshow.Format("MVDB x: %d MVDB y: %d ", mvdbx, mvdby);
AfxMessageBox(outshow);
}
}
else
{
mvdbx = 0;
mvdby = 0;
}
}//end of(pb_frame)
}//end of(MV Decode)
if(fault)
goto resync;
}
else //COD=1 没有块头信息 进行下一宏块的编码
{ // COD == 1 -->跳空 MB
if(MBA>=MBAmax)
return; // all macroblocks decoded
if (!syntax_arith_coding)
if (pict_type == PCT_INTER)
m_getbits.flushbits(1);
Mode = MODE_INTER;
//Reset CBP
CBP = CBPB = 0;
//Reset motion vectors
MV[0][0][ypos+1][xpos+1] = 0;
MV[1][0][ypos+1][xpos+1] = 0;
mvdbx = 0;
mvdby = 0;
}
// Store Mode
modemap[ypos+1][xpos+1] = Mode;
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
if (!pb_frame)
MV[0][0][ypos+1][xpos+1]=MV[1][0][ypos+1][xpos+1] = 0;
/*************************************************************/
//3.解码前一宏块的块数据信息(重建预测块,IDCT Pre+Idct)
/************************************************************/
reconstruct_mb:
// 前一宏块中的象素左上角的坐标 // one delayed because of OBMC
if (xpos > 0)
{
bx = 16*(xpos-1);
by = 16*ypos;
}
else
{
bx = coded_picture_width-16;
by = 16*(ypos-1);
}
if (MBA > 0)
{
Mode = modemap[by/16+1][bx/16+1];
// 前向运动补偿 for B-frame
if (pb_frame)
m_recon.reconstruct(bx,by,0,pmvdbx,pmvdby);//P=0 B模式
// 运动补偿 for P-frame
if (Mode == MODE_INTER || Mode == MODE_INTER_Q || Mode == MODE_INTER4V)
m_recon.reconstruct(bx,by,1,0,0);//P=1 预测模式
//copy or add block data into P-picture
for (comp=0; comp<blk_cnt; comp++)
{
// inverse DCT
if(Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
{
m_idct.idct(ld->block[comp]);//ld->block中存放IDCT数据
addblock(comp,bx,by,0);//将ld->block中的数据放入图像中
}
else if( (pCBP & (1<<(blk_cnt-1-comp))) )
{
//No need to to do this for blocks with no coeffs
m_idct.idct(ld->block[comp]);
addblock(comp,bx,by,1);//将ld->block中的数据放入图像中
}
}//解码宏块(normal)
if (pb_frame)
{
// add block data into B-picture
for (comp = 6; comp<blk_cnt+6; comp++)
{
if(!pCOD || adv_pred_mode)
reconblock_b(comp-6,bx,by,Mode,pmvdbx,pmvdby);
if( (pCBPB & (1<<(blk_cnt-1-comp%6))) )
{
m_idct.idct(ld->block[comp]);
addblock(comp,bx,by,1);
}
}
}//end of(pb_frame)
} // end if (MBA > 0)
/***************************************************************/
//4.根据(COD,Mode,CBP,)从缓存中得到比特书并放入ld->block中
/***************************************************************/
if (!COD)
{
Mode = modemap[ypos+1][xpos+1];
// decode blocks
for (comp=0; comp<blk_cnt; comp++)
{
clearblock(comp);//将ld->block中的数据首先清零
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
{ // Intra
bp = ld->block[comp];//传递地址 结果在ld->block中
if(syntax_arith_coding)
{
INTRADC_index = m_sacode.decode_a_symbol(cumf_INTRADC);
bp[0] = intradctab[INTRADC_index];
if (trace)
{
outshow.Format("INTRADC Index: %d INTRADC: %d \n", INTRADC_index, bp[0]);
AfxMessageBox(outshow);
}
}
else
bp[0] = m_getbits.getbits(8);//直流分量
if (trace)
{
outshow.Format("DC[%d]is: %d",comp,(int)bp[0]);
AfxMessageBox(outshow);
}
if (bp[0] == 128)
if(!quiet)
AfxMessageBox("Illegal DC-coeff: 1000000!");
if (bp[0] == 255)//标准中所定
bp[0] = 128;
bp[0] *= 8; // Iquant
//解码交流分量
if( (CBP & (1<<(blk_cnt-1-comp))) )
{ //从比特流中得到数据放入ld->block[]中
if(!syntax_arith_coding)
m_getblk.getblock(comp,0);
else
m_getblk.get_sac_block(comp,0);
}
}//end of (Intra)
else
{ // Inter 没有直流系数 直接解码交流系数
if ( (CBP & (1<<(blk_cnt-1-comp))) )
{ //从比特流中得到数据放入ld->block[]中
if(!syntax_arith_coding)
m_getblk.getblock(comp,1);
else
m_getblk.get_sac_block(comp,1);
}
}//end block decode
if (fault)
goto resync;
}
// Decode B blocks
if (pb_frame)
{
for (comp=6; comp<blk_cnt+6; comp++)
{
clearblock(comp);
if ( (CBPB & (1<<(blk_cnt-1-comp%6))) )
{
if (!syntax_arith_coding)
m_getblk.getblock(comp,1);
else
m_getblk.get_sac_block(comp,1);
}
if (fault)
goto resync;
}
}//end of(pb_frame)
}
//进行下一MB解码
MBA++;
pCBP = CBP;
pCBPB = CBPB;
pCOD = COD;
pmvdbx = mvdbx;
pmvdby = mvdby;
fflush(stdout);
if (MBA >= MBAmax && !last_done)
{
COD = 1;
xpos = 0;
ypos++;
last_done = 1;
goto reconstruct_mb;
}
}//end of(for)
}
void CGetpic::clearblock(int comp)
{
int *bp;
int i;
bp = (int *)ld->block[comp];
for (i=0; i<8; i++)
{
bp[0] = bp[1] = bp[2] = bp[3] = 0;
bp += 4;
}
}
int CGetpic::motion_decode(int vec, int pmv)
{
if (vec > 31)
vec -= 64;
vec += pmv;
if (!long_vectors)
{
if (vec > 31)
vec -= 64;
if (vec < -32)
vec += 64;
}
else
{
if (pmv < -31 && vec < -63)
vec += 64;
if (pmv > 32 && vec > 63)
vec -= 64;
}
return vec;
}
int CGetpic::find_pmv(int x, int y, int block, int comp)
{
int p1,p2,p3;
int xin1,xin2,xin3;
int yin1,yin2,yin3;
int vec1,vec2,vec3;
int l8,o8,or8;
x++;y++;
l8 = (modemap[y][x-1] == MODE_INTER4V ? 1 : 0);
o8 = (modemap[y-1][x] == MODE_INTER4V ? 1 : 0);
or8 = (modemap[y-1][x+1] == MODE_INTER4V ? 1 : 0);
switch (block)
{
case 0:
vec1 = (l8 ? 2 : 0) ; yin1 = y ; xin1 = x-1;
vec2 = (o8 ? 3 : 0) ; yin2 = y-1; xin2 = x;
vec3 = (or8? 3 : 0) ; yin3 = y-1; xin3 = x+1;
break;
case 1:
vec1 = (l8 ? 2 : 0) ; yin1 = y ; xin1 = x-1;
vec2 = (o8 ? 3 : 0) ; yin2 = y-1; xin2 = x;
vec3 = (or8? 3 : 0) ; yin3 = y-1; xin3 = x+1;
break;
case 2:
vec1 = 1 ; yin1 = y ; xin1 = x;
vec2 = (o8 ? 4 : 0) ; yin2 = y-1; xin2 = x;
vec3 = (or8? 3 : 0) ; yin3 = y-1; xin3 = x+1;
break;
case 3:
vec1 = (l8 ? 4 : 0) ; yin1 = y ; xin1 = x-1;
vec2 = 1 ; yin2 = y ; xin2 = x;
vec3 = 2 ; yin3 = y ; xin3 = x;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -