📄 iframe.cpp
字号:
int iDmv = 0;
int iMvScale = 0;
int iCodedBlockPattern = 0;
int comp;
int iQuantiserScaleCode = 0;
/* ISO/IEC 13818-2 section 6.3.17.1: Macroblock modes */
MacroblockModes (pMacroblockType, pStwType, pStwClass, pMotionType,
&iMotionVectorCount, &iMvFormat, &iDmv, &iMvScale, pDctType);
if (*pMacroblockType & MACROBLOCK_QUANT)
{
iQuantiserScaleCode = GetBits(5);
// ISO/IEC 13818-2 section 7.4.2.2: Quantizer scale factor
if (MPEG2_Flag)
m_iQuantiserScale = m_iQScaleType ? Non_Linear_quantizer_scale[iQuantiserScaleCode]
: (iQuantiserScaleCode << 1);
else
m_iQuantiserScale = iQuantiserScaleCode;
}
// Decode forward motion vectors
if ((*pMacroblockType & MACROBLOCK_MOTION_FORWARD)
|| ((*pMacroblockType & MACROBLOCK_INTRA)
&& m_iConcealmentMotionVectors))
{
if (MPEG2_Flag)
MotionVectors (PMV, dmvector, motion_vertical_field_select,
0, iMotionVectorCount, iMvFormat, f_code[0][0] - 1, f_code[0][1] - 1, iDmv, iMvScale);
else
MotionVector (PMV[0][0],dmvector,
m_iForwardFCode - 1, m_iForwardFCode - 1,0,0, m_iFullPelForwardVector);
}
// Decode backward motion vectors
if (*pMacroblockType & MACROBLOCK_MOTION_BACKWARD)
{
if (MPEG2_Flag)
MotionVectors(PMV, dmvector, motion_vertical_field_select,
1, iMotionVectorCount, iMvFormat, f_code[1][0] - 1, f_code[1][1] - 1, 0, iMvScale);
else
MotionVector(PMV[0][1], dmvector, m_iBackwardFCode - 1,
m_iBackwardFCode - 1, 0, 0, m_iFullPelBackwardVector);
}
// Remove marker_bit
if ((*pMacroblockType & MACROBLOCK_INTRA) && m_iConcealmentMotionVectors)
FlushBits(1);
// Macroblock_pattern
if (*pMacroblockType & MACROBLOCK_PATTERN)
{
iCodedBlockPattern = GetCodedBlockPattern();
// coded_block_pattern_1
if (m_iChromaFormat == CHROMA422)
iCodedBlockPattern = (iCodedBlockPattern << 2) | GetBits(2);
// coded_block_pattern_2
else if (m_iChromaFormat==CHROMA444)
iCodedBlockPattern = (iCodedBlockPattern << 6) | GetBits(6);
}
else
iCodedBlockPattern = (*pMacroblockType & MACROBLOCK_INTRA) ? (1 << block_count ) -1 : 0;
// Decode blocks
for (comp = 0; comp < block_count; comp++)
{
if (m_bStopVideoDemux)
return 1;
// SCALABILITY: Data Partitioning
if (m_iScalableMode == SC_DP)
Clear_Block(comp);
if (iCodedBlockPattern & (1<<(block_count - 1 - comp)))
{
if (*pMacroblockType & MACROBLOCK_INTRA)
{
if (MPEG2_Flag)
DecodeMPEG2IntraBlock(comp,dc_dct_pred);
else
Decode_MPEG1_Intra_Block(comp,dc_dct_pred);
}
else
{
if (MPEG2_Flag)
Decode_MPEG2_Non_Intra_Block(comp);
else
Decode_MPEG1_Non_Intra_Block(comp);
}
}
}
if(m_iPictureCodeType == D_TYPE)
{
/* remove end_of_macroblock (always 1, prevents startcode emulation) */
/* ISO/IEC 11172-2 section 2.4.2.7 and 2.4.3.6 */
GetBits(1);
}
// reset intra_dc predictors
// ISO/IEC 13818-2 section 7.2.1: DC coefficients in intra blocks
if (!(*pMacroblockType & MACROBLOCK_INTRA))
dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0;
// reset motion vector predictors
if ((*pMacroblockType & MACROBLOCK_INTRA) && !m_iConcealmentMotionVectors)
{
// intra mb without concealment motion vectors
// ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors
PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;
PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0;
}
// special "No_MC" macroblock_type case
// ISO/IEC 13818-2 section 7.6.3.5: Prediction in P pictures
if ((m_iPictureCodeType == P_TYPE) && !(*pMacroblockType & (MACROBLOCK_MOTION_FORWARD | MACROBLOCK_INTRA)))
{
// non-intra mb without forward mv in a P picture
// ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors
PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;
// derive motion_type
// ISO/IEC 13818-2 section 6.3.17.1: Macroblock modes, frame_motion_type
if (m_iPictureStructure == FRAME_PICTURE)
*pMotionType = MC_FRAME;
else
{
*pMotionType = MC_FIELD;
/* predict from field of same parity */
motion_vertical_field_select[0][0] = (m_iPictureStructure == BOTTOM_FIELD);
}
}
if (*pStwClass==4)
{
// purely spatially predicted macroblock
// ISO/IEC 13818-2 section 7.7.5.1: Resetting motion vector predictions
PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;
PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0;
}
// successfully decoded macroblock
return 1;
}
////////////////////////////////////////////////////////////////////
void CIFrame::SkipMacroblock(int dc_dct_pred[3], int PMV[2][2][2], int* pMotionType,
int iMotionVerticalFieldSelect[2][2], int *pStwType, int* pMacroblockType)
{
int comp;
for (comp=0; comp < block_count; comp++)
Clear_Block(comp);
// reset intra_dc predictors
// ISO/IEC 13818-2 section 7.2.1: DC coefficients in intra blocks
dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0;
// reset motion vector predictors
// ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors
if (m_iPictureCodeType == P_TYPE)
PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0;
// derive motion_type
if (m_iPictureStructure == FRAME_PICTURE)
*pMotionType = MC_FRAME;
else
{
*pMotionType = MC_FIELD;
// predict from field of same parity
// ISO/IEC 13818-2 section 7.6.6.1 and 7.6.6.3: P field picture and B field picture
iMotionVerticalFieldSelect[0][0] = iMotionVerticalFieldSelect[0][1] =
(m_iPictureStructure == BOTTOM_FIELD);
}
// skipped I are spatial-only predicted,
// skipped P and B are temporal-only predicted
// ISO/IEC 13818-2 section 7.7.6: Skipped macroblocks
*pStwType = (m_iPictureCodeType == I_TYPE) ? 8 : 0;
// IMPLEMENTATION: clear MACROBLOCK_INTRA
*pMacroblockType &= ~MACROBLOCK_INTRA;
}
////////////////////////////////////////////////////////////////////
int CIFrame::MacroblockModes (int* pMacroblockType, int* pStwType,
int* pStwClass, int* pMotionType, int* pMotionVectorCount,
int* pMvFormat, int* pDmv, int* pMvScale, int* pDctType)
{
int macroblock_type;
int stwtype, stwcode, stwclass;
int motion_type = 0;
int motion_vector_count, mv_format, dmv, mvscale;
int dct_type;
static unsigned char stwc_table[3][4]
= { {6,3,7,4}, {2,1,5,4}, {2,5,7,4} };
static unsigned char stwclass_table[9]
= {0, 1, 2, 1, 1, 2, 3, 3, 4};
macroblock_type = GetMacroblockType();
// Get spatial_temporal_weight_code
if (macroblock_type & MB_WEIGHT)
{
if (m_iSpatialTemporalWeightCodeTableIndex == 0)
stwtype = 4;
else
{
stwcode = GetBits(2);
stwtype = stwc_table[m_iSpatialTemporalWeightCodeTableIndex - 1][stwcode];
}
}
else
stwtype = (macroblock_type & MB_CLASS4) ? 8 : 0;
// SCALABILITY: derive spatial_temporal_weight_class (Table 7-18)
stwclass = stwclass_table[stwtype];
// Get frame/field motion type
if (macroblock_type & (MACROBLOCK_MOTION_FORWARD | MACROBLOCK_MOTION_BACKWARD))
{
if (m_iPictureStructure == FRAME_PICTURE) // frame_motion_type
motion_type = m_iFramePredFrameDct ? MC_FRAME : GetBits(2);
else // field_motion_type
motion_type = GetBits(2);
}
else if ((macroblock_type & MACROBLOCK_INTRA) && m_iConcealmentMotionVectors)
{
// concealment motion vectors
motion_type = (m_iPictureStructure == FRAME_PICTURE) ? MC_FRAME : MC_FIELD;
}
// Derive motion_vector_count, mv_format and dmv, (table 6-17, 6-18) */
if (m_iPictureStructure == FRAME_PICTURE)
{
motion_vector_count = (motion_type == MC_FIELD && stwclass<2) ? 2 : 1;
mv_format = (motion_type==MC_FRAME) ? MV_FRAME : MV_FIELD;
}
else
{
motion_vector_count = (motion_type == MC_16X8) ? 2 : 1;
mv_format = MV_FIELD;
}
dmv = (motion_type==MC_DMV); // Dual prime
mvscale = ((mv_format==MV_FIELD) && (m_iPictureStructure == FRAME_PICTURE));
// get dct_type (frame DCT / field DCT)
dct_type = (m_iPictureStructure == FRAME_PICTURE)
&& (!m_iFramePredFrameDct)
&& (macroblock_type & (MACROBLOCK_PATTERN | MACROBLOCK_INTRA))
? GetBits(1) : 0;
// return values
*pMacroblockType = macroblock_type;
*pStwType = stwtype;
*pStwClass = stwclass;
*pMotionType = motion_type;
*pMotionVectorCount = motion_vector_count;
*pMvFormat = mv_format;
*pDmv = dmv;
*pMvScale = mvscale;
*pDctType = dct_type;
return 0;
}
////////////////////////////////////////////////////////////////////
int CIFrame::MacroblockAddrIncrement ()
{
int code, val;
val = 0;
// Get macroblock_address_increment
while ((code = ShowBits(11)) < 24)
{
if (m_bStopVideoDemux)
return -1;
if (code!=15) // if not macroblock_stuffing
{
if (code==8) // if macroblock_escape
val+= 33;
else
return -1;
}
else // macroblock suffing
{
}
FlushBits(11);
}
// macroblock_address_increment == 1
// ('1' is in the MSB position of the lookahead)
if (code >= 1024)
{
FlushBits(1);
return val + 1;
}
// codes 00010 ... 011xx
if (code >= 128)
{
/* remove leading zeros */
code >>= 6;
FlushBits(MBAtab1[code].len);
return val + MBAtab1[code].val;
}
// codes 00000011000 ... 0000111xxxx
code -= 24; // remove common base
FlushBits(MBAtab2[code].len);
return val + MBAtab2[code].val;
}
////////////////////////////////////////////////////////////////////
int CIFrame::GetMacroblockType ()
{
int macroblock_type = 0;
if (m_iScalableMode==SC_SNR)
macroblock_type = Get_SNR_macroblock_type();
else
{
switch (m_iPictureCodeType)
{
case I_TYPE:
macroblock_type = m_iPictScal ? Get_I_Spatial_macroblock_type() : Get_I_macroblock_type();
break;
case P_TYPE:
macroblock_type = m_iPictScal ? Get_P_Spatial_macroblock_type() : Get_P_macroblock_type();
break;
case B_TYPE:
macroblock_type = m_iPictScal ? Get_B_Spatial_macroblock_type() : Get_B_macroblock_type();
break;
case D_TYPE:
macroblock_type = Get_D_macroblock_type();
break;
default:
break;
}
}
return macroblock_type;
}
////////////////////////////////////////////////////////////////////
/* calculate motion vector component */
/* ISO/IEC 13818-2 section 7.6.3.1: Decoding the motion vectors */
/* Note: the arithmetic here is more elegant than that which is shown
in 7.6.3.1. The end results (PMV[][][]) should, however, be the same. */
void CIFrame::DecodeMotionVector(int *pred, int r_size,int motion_code,
int motion_residual, int full_pel_vector)
{
int lim, vec;
lim = 16<<r_size;
vec = full_pel_vector ? (*pred >> 1) : (*pred);
if (motion_code>0)
{
vec+= ((motion_code-1)<<r_size) + motion_residual + 1;
if (vec>=lim)
vec-= lim + lim;
}
else if (motion_code<0)
{
vec-= ((-motion_code-1)<<r_size) + motion_residual + 1;
if (vec<-lim)
vec+= lim + lim;
}
*pred = full_pel_vector ? (vec<<1) : vec;
}
////////////////////////////////////////////////////////////////////
int CIFrame::GetDmVector()
{
if (GetBits(1))
return GetBits(1) ? -1 : 1;
else
return 0;
}
////////////////////////////////////////////////////////////////////
int CIFrame::GetMotionCode()
{
int code;
if (GetBits(1))
return 0;
if ((code = ShowBits(9))>=64)
{
code >>= 6;
FlushBits(MVtab0[code].len);
return GetBits(1)?-MVtab0[code].val:MVtab0[code].val;
}
if (code>=24)
{
code >>= 3;
FlushBits(MVtab1[code].len);
return GetBits(1)?-MVtab1[code].val:MVtab1[code].val;
}
if ((code-=12)<0)
throw -1;
FlushBits(MVtab2[code].len);
return GetBits(1) ? -MVtab2[code].val : MVtab2[code].val;
}
////////////////////////////////////////////////////////////////////
void CIFrame::MotionVector(int *PMV,int *dmvector, int h_r_size,int v_r_size,
int dmv,int mvscale,int full_pel_vector)
{
int motion_code, motion_residual;
// horizontal component
// ISO/IEC 13818-2 Table B-10
motion_code = GetMotionCode();
motion_residual = (h_r_size!=0 && motion_code!=0) ?
GetBits(h_r_size) : 0;
DecodeMotionVector(&PMV[0],h_r_size,motion_code,motion_residual,full_pel_vector);
if (dmv)
dmvector[0] = GetDmVector();
// vertical component
motion_code = GetMotionCode();
motion_residual = (v_r_size!=0 && motion_code!=0) ? GetBits(v_r_size) : 0;
if (mvscale)
PMV[1] >>= 1; // DIV 2
DecodeMotionVector(&PMV[1],v_r_size,motion_code,motion_residual,full_pel_vector);
if (mvscale)
PMV[1] <<= 1;
if (dmv)
dmvector[1] = GetDmVector();
}
////////////////////////////////////////////////////////////////////
void CIFrame::MotionVectors( int PMV[2][2][2],int dmvector[2], int motion_vertical_field_select[2][2],
int s,int motion_vector_count,int mv_format,int h_r_size,int v_r_size,int dmv, int mvscale)
{
if (motion_vector_count==1)
{
if (mv_format==MV_FIELD && !dmv)
{
motion_vertical_field_select[1][s] = motion_vertical_field_select[0][s] = GetBits(1);
}
MotionVector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
// update other motion vector predictors
PMV[1][s][0] = PMV[0][s][0];
PMV[1][s][1] = PMV[0][s][1];
}
else
{
motion_vertical_field_select[0][s] = GetBits(1);
MotionVector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
motion_vertical_field_select[1][s] = GetBits(1);
MotionVector(PMV[1][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0);
}
}
////////////////////////////////////////////////////////////////////
// IMPLEMENTATION: set scratch pad macroblock to zero
void CIFrame::Clear_Block(int comp)
{
short *Block_Ptr;
int i;
Block_Ptr = block[comp];
for (i=0; i<64; i++)
*Block_Ptr++ = 0;
}
////////////////////////////////////////////////////////////////////
int CIFrame::GetCodedBlockPattern()
{
int code;
if ((code = ShowBits(9))>=128)
{
code >>= 4;
FlushBits(CBPtab0[code].len);
return CBPtab0[code].val;
}
if (code>=8)
{
code >>= 1;
FlushBits(CBPtab1[code].len);
return CBPtab1[code].val;
}
if (code<1)
throw -1;
FlushBits(CBPtab2[code].len);
return CBPtab2[code].val;
}
////////////////////////////////////////////////////////////////////
// decode one intra coded MPEG-1 block
void CIFrame::Decode_MPEG1_Intra_Block(int comp,int dc_dct_pred[])
{
int val, i, j, sign;
unsigned int code;
DCTtab *tab;
short *bp;
bp = block[comp];
// ISO/IEC 11172-2 section 2.4.3.7: Block layer.
// decode DC coefficients
if (comp<4)
bp[0] = (short)((dc_dct_pred[0]+=Get_Luma_DC_dct_diff()) << 3);
else if (comp==4)
bp[0] = (short)((dc_dct_pred[1]+=Get_Chroma_DC_dct_diff()) << 3);
else
bp[0] = (short)((dc_dct_pred[2]+=Get_Chroma_DC_dct_diff()) << 3);
// D-pictures do not contain AC coefficients
if (m_iPictureCodeType == D_TYPE)
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -