📄 iframe.cpp
字号:
// Decode AC coefficients
for (i=1; ; i++)
{
if (m_bStopVideoDemux)
return;
code = ShowBits(16);
if (code>=16384)
tab = &DCTtabnext[(code>>12)-4];
else if (code>=1024)
tab = &DCTtab0[(code>>8)-4];
else if (code>=512)
tab = &DCTtab1[(code>>6)-8];
else if (code>=256)
tab = &DCTtab2[(code>>4)-16];
else if (code>=128)
tab = &DCTtab3[(code>>3)-16];
else if (code>=64)
tab = &DCTtab4[(code>>2)-16];
else if (code>=32)
tab = &DCTtab5[(code>>1)-16];
else if (code>=16)
tab = &DCTtab6[code-16];
else
throw -1;
FlushBits(tab->len);
if (tab->run==64) // end_of_block
return;
if (tab->run==65) // escape
{
i+= GetBits(6);
val = GetBits(8);
if (val==0)
val = GetBits(8);
else if (val==128)
val = GetBits(0) - 256;
else if (val>128)
val -= 256;
sign = val < 0;
if (sign)
val = -val;
}
else
{
i+= tab->run;
val = tab->level;
sign = GetBits(1);
}
if (i>=64)
throw -1;
j = scan[ZIG_ZAG][i];
val = (val * m_iQuantiserScale * m_iIntraQuantiserMatrix[j]) >> 3;
// mismatch control ('oddification')
if (val!=0) // should always be true, but it's not guaranteed
val = (val-1) | 1; // equivalent to: if ((val&1)==0) val = val - 1;
// saturation
if (!sign)
bp[j] = short((val>2047) ? 2047 : val); // positive
else
bp[j] = short((val>2048) ? -2048 : -val); // negative
}
}
////////////////////////////////////////////////////////////////////
// decode one non-intra coded MPEG-1 block
void CIFrame::Decode_MPEG1_Non_Intra_Block(int comp)
{
int val, i, j, sign;
unsigned int code;
DCTtab *tab;
short *bp;
bp = block[comp];
// decode AC coefficients
for (i=0; ; i++)
{
if (m_bStopVideoDemux)
return;
code = ShowBits(16);
if (code>=16384)
{
if (i==0)
tab = &DCTtabfirst[(code>>12)-4];
else
tab = &DCTtabnext[(code>>12)-4];
}
else if (code>=1024)
tab = &DCTtab0[(code>>8)-4];
else if (code>=512)
tab = &DCTtab1[(code>>6)-8];
else if (code>=256)
tab = &DCTtab2[(code>>4)-16];
else if (code>=128)
tab = &DCTtab3[(code>>3)-16];
else if (code>=64)
tab = &DCTtab4[(code>>2)-16];
else if (code>=32)
tab = &DCTtab5[(code>>1)-16];
else if (code>=16)
tab = &DCTtab6[code-16];
else
throw -1;
FlushBits(tab->len);
if (tab->run==64) // end_of_block
return;
if (tab->run==65) // escape
{
i+= GetBits(6);
val = GetBits(8);
if (val==0)
val = GetBits(8);
else if (val==128)
val = GetBits(8) - 256;
else if (val>128)
val -= 256;
sign = val < 0;
if(sign)
val = -val;
}
else
{
i+= tab->run;
val = tab->level;
sign = GetBits(1);
}
if (i>=64)
throw -1;
j = scan[ZIG_ZAG][i];
val = (((val<<1)+1) * m_iQuantiserScale * m_iNonIntraQuantiserMatrix[j]) >> 4;
// mismatch control ('oddification')
if (val!=0) // should always be true, but it's not guaranteed
val = (val-1) | 1; // equivalent to: if ((val&1)==0) val = val - 1;
// saturation
if (!sign)
bp[j] = short((val>2047) ? 2047 : val); // positive
else
bp[j] = short((val>2048) ? -2048 : -val); // negative
}
}
////////////////////////////////////////////////////////////////////
void CIFrame::DecodeMPEG2IntraBlock(int comp, int dc_dct_pred[])
{
int val, i, j, sign, nc, cc, run;
unsigned int code;
DCTtab *tab;
short *bp;
int *qmat;
// with data partitioning, data always goes to base layer
bp = block[comp];
cc = (comp < 4) ? 0 : (comp & 1)+1;
qmat = (comp<4 || m_iChromaFormat == CHROMA420)
? m_iIntraQuantiserMatrix : m_iChromaIntraQuantiserMatrix;
// ISO/IEC 13818-2 section 7.2.1: decode DC coefficients
if (cc==0)
val = (dc_dct_pred[0]+= Get_Luma_DC_dct_diff());
else if (cc==1)
val = (dc_dct_pred[1]+= Get_Chroma_DC_dct_diff());
else
val = (dc_dct_pred[2]+= Get_Chroma_DC_dct_diff());
bp[0] = short(val << (3 - m_iIntraDcPrecision));
nc=0;
// Decode AC coefficients
for (i=1; ; i++)
{
if (m_bStopVideoDemux)
return;
code = ShowBits(16);
if (code >= 16384 && !m_iIntraVlcFormat)
tab = &DCTtabnext[(code>>12)-4];
else if (code>=1024)
{
if (m_iIntraVlcFormat)
tab = &DCTtab0a[(code>>8)-4];
else
tab = &DCTtab0[(code>>8)-4];
}
else if (code>=512)
{
if (m_iIntraVlcFormat)
tab = &DCTtab1a[(code>>6)-8];
else
tab = &DCTtab1[(code>>6)-8];
}
else if (code>=256)
tab = &DCTtab2[(code>>4)-16];
else if (code>=128)
tab = &DCTtab3[(code>>3)-16];
else if (code>=64)
tab = &DCTtab4[(code>>2)-16];
else if (code>=32)
tab = &DCTtab5[(code>>1)-16];
else if (code>=16)
tab = &DCTtab6[code-16];
else
throw -1;
FlushBits(tab->len);
if (tab->run==64) // end_of_block
return;
if (tab->run==65) // escape
{
i+= run = GetBits(6);
val = GetBits(12);
if ((val&2047)==0) // invalid escape
throw -1;
sign = val >= 2048;
if(sign)
val = 4096 - val;
}
else
{
i+= run = tab->run;
val = tab->level;
sign = GetBits(1);
}
if (i>=64) // DCT coeff index (i) out of bounds (intra2)";
throw -1;
j = scan[m_iAlternateScan][i];
val = (val * m_iQuantiserScale * qmat[j]) >> 4;
bp[j] = short(sign ? -val : val);
nc++;
}
}
////////////////////////////////////////////////////////////////////
// decode one non-intra coded MPEG-2 block
void CIFrame::Decode_MPEG2_Non_Intra_Block(int comp)
{
int val, i, j, sign, nc, run;
unsigned int code;
DCTtab *tab;
short *bp;
int *qmat;
// with data partitioning, data always goes to base layer
bp = block[comp];
qmat = (comp<4 || m_iChromaFormat == CHROMA420)
? m_iNonIntraQuantiserMatrix
: m_iChromaNonIntraQuantiserMatrix;
nc = 0;
// decode AC coefficients
for (i=0; ; i++)
{
if (m_bStopVideoDemux)
return;
code = ShowBits(16);
if (code>=16384)
{
if (i==0)
tab = &DCTtabfirst[(code>>12)-4];
else
tab = &DCTtabnext[(code>>12)-4];
}
else if (code>=1024)
tab = &DCTtab0[(code>>8)-4];
else if (code>=512)
tab = &DCTtab1[(code>>6)-8];
else if (code>=256)
tab = &DCTtab2[(code>>4)-16];
else if (code>=128)
tab = &DCTtab3[(code>>3)-16];
else if (code>=64)
tab = &DCTtab4[(code>>2)-16];
else if (code>=32)
tab = &DCTtab5[(code>>1)-16];
else if (code>=16)
tab = &DCTtab6[code-16];
else // invalid Huffman code
throw -1;
FlushBits(tab->len);
if (tab->run==64) // end_of_block
return;
if (tab->run==65) // escape
{
i+= run = GetBits(6);
val = GetBits(12);
if ((val&2047)==0)
throw -1;
sign = val >= 2048;
if(sign)
val = 4096 - val;
}
else
{
i+= run = tab->run;
val = tab->level;
sign = GetBits(1);
}
if (i>=64)
throw -1;
j = scan[m_iAlternateScan][i];
val = (((val<<1)+1) * m_iQuantiserScale * qmat[j]) >> 5;
bp[j] = short(sign ? -val : val);
nc++;
}
}
////////////////////////////////////////////////////////////////////
int CIFrame::Get_Luma_DC_dct_diff()
{
int code, size, dct_diff;
// decode length
code = ShowBits(5);
if (code<31)
{
size = DClumtab0[code].val;
FlushBits(DClumtab0[code].len);
}
else
{
code = ShowBits(9) - 0x1f0;
size = DClumtab1[code].val;
FlushBits(DClumtab1[code].len);
}
if (size==0)
dct_diff = 0;
else
{
dct_diff = GetBits(size);
if ((dct_diff & (1<<(size-1)))==0)
dct_diff-= (1<<size) - 1;
}
return dct_diff;
}
////////////////////////////////////////////////////////////////////
int CIFrame::Get_Chroma_DC_dct_diff()
{
int code, size, dct_diff;
// decode length
code = ShowBits(5);
if (code<31)
{
size = DCchromtab0[code].val;
FlushBits(DCchromtab0[code].len);
}
else
{
code = ShowBits(10) - 0x3e0;
size = DCchromtab1[code].val;
FlushBits(DCchromtab1[code].len);
}
if (size==0)
dct_diff = 0;
else
{
dct_diff = GetBits(size);
if ((dct_diff & (1<<(size-1)))==0)
dct_diff-= (1<<size) - 1;
}
return dct_diff;
}
////////////////////////////////////////////////////////////////////
// macroblock_type for pictures with spatial scalability
int CIFrame::Get_I_Spatial_macroblock_type()
{
int code;
code = ShowBits(4);
if (code == 0)
throw -1;
FlushBits(spIMBtab[code].len);
return spIMBtab[code].val;
}
////////////////////////////////////////////////////////////////////
int CIFrame::Get_P_Spatial_macroblock_type()
{
int code;
code = ShowBits(7);
if (code < 2)
throw -1;
if (code >= 16)
{
code >>= 3;
FlushBits(spPMBtab0[code].len);
return spPMBtab0[code].val;
}
FlushBits(spPMBtab1[code].len);
return spPMBtab1[code].val;
}
////////////////////////////////////////////////////////////////////
int CIFrame::Get_B_Spatial_macroblock_type()
{
int code;
VLCtab *p;
code = ShowBits(9);
if (code >= 64)
p = &spBMBtab0[(code>>5)-2];
else if (code >= 16)
p = &spBMBtab1[(code>>2)-4];
else if (code >= 8)
p = &spBMBtab2[code-8];
else
throw -1;
FlushBits(p->len);
return p->val;
}
////////////////////////////////////////////////////////////////////
int CIFrame::Get_SNR_macroblock_type()
{
int code;
code = ShowBits(3);
if (code == 0)
throw -1;
FlushBits(SNRMBtab[code].len);
return SNRMBtab[code].val;
}
////////////////////////////////////////////////////////////////////
int CIFrame::Get_I_macroblock_type()
{
if (GetBits(1))
return 1;
if (!GetBits(1))
throw -1;
return 17;
}
////////////////////////////////////////////////////////////////////
int CIFrame::Get_P_macroblock_type()
{
int code;
if ((code = ShowBits(6)) >= 8)
{
code >>= 3;
FlushBits(PMBtab0[code].len);
return PMBtab0[code].val;
}
if (code == 0)
throw -1;
FlushBits(PMBtab1[code].len);
return PMBtab1[code].val;
}
////////////////////////////////////////////////////////////////////
int CIFrame::Get_B_macroblock_type()
{
int code;
if ((code = ShowBits(6)) >= 8)
{
code >>= 2;
FlushBits(BMBtab0[code].len);
return BMBtab0[code].val;
}
if (code == 0)
throw -1;
FlushBits(BMBtab1[code].len);
return BMBtab1[code].val;
}
////////////////////////////////////////////////////////////////////
int CIFrame::Get_D_macroblock_type()
{
if (!GetBits(1))
throw -1;
return 1;
}
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -