📄 getpic.c
字号:
motion_vectors(PMV, dmvector, motion_vertical_field_select, 0,
motion_vector_count, mv_format, f_code[0][0]-1, f_code[0][1]-1, dmv, mvscale);
if (Fault_Flag) return 0; // trigger: go to next slice
/* decode backward motion vectors */
if (*macroblock_type & MACROBLOCK_MOTION_BACKWARD)
motion_vectors(PMV, dmvector, motion_vertical_field_select, 1,
motion_vector_count,mv_format, f_code[1][0]-1, f_code[1][1]-1, 0, mvscale);
if (Fault_Flag) return 0; // trigger: go to next slice
if ((*macroblock_type & MACROBLOCK_INTRA) && concealment_motion_vectors)
Flush_Buffer(1); // marker bit
/* macroblock_pattern */
/* ISO/IEC 13818-2 section 6.3.17.4: Coded block pattern */
if (*macroblock_type & MACROBLOCK_PATTERN)
{
coded_block_pattern = Get_coded_block_pattern();
if (chroma_format==CHROMA422)
coded_block_pattern = (coded_block_pattern<<2) | Get_Bits(2);
else if (chroma_format==CHROMA444)
coded_block_pattern = (coded_block_pattern<<6) | Get_Bits(6);
}
else
coded_block_pattern = (*macroblock_type & MACROBLOCK_INTRA) ? (1<<block_count)-1 : 0;
if (Fault_Flag) return 0; // trigger: go to next slice
Clear_Block(block_count);
/* decode blocks */
for (comp=0; comp<block_count; comp++)
{
if (coded_block_pattern & (1<<(block_count-1-comp)))
{
if (*macroblock_type & MACROBLOCK_INTRA)
Decode_MPEG2_Intra_Block(comp, dc_dct_pred);
else
Decode_MPEG2_Non_Intra_Block(comp);
if (Fault_Flag) return 0; // trigger: go to next slice
}
}
/* reset intra_dc predictors */
/* ISO/IEC 13818-2 section 7.2.1: DC coefficients in intra blocks */
if (!(*macroblock_type & MACROBLOCK_INTRA))
dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0;
/* reset motion vector predictors */
if ((*macroblock_type & MACROBLOCK_INTRA) && !concealment_motion_vectors)
{
/* 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 ((picture_coding_type==P_TYPE)
&& !(*macroblock_type & (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 (picture_structure==FRAME_PICTURE)
*motion_type = MC_FRAME;
else
{
*motion_type = MC_FIELD;
motion_vertical_field_select[0][0] = (picture_structure==BOTTOM_FIELD);
}
}
/* successfully decoded macroblock */
return 1 ;
}
/* decode one intra coded MPEG-2 block */
static void Decode_MPEG2_Intra_Block(int comp, int dc_dct_pred[])
{
int val, i, j, sign, *qmat;
unsigned int code;
DCTtab *tab;
short *bp;
bp = block[comp];
qmat = (comp<4 || chroma_format==CHROMA420)
? intra_quantizer_matrix : chroma_intra_quantizer_matrix;
/* ISO/IEC 13818-2 section 7.2.1: decode DC coefficients */
switch (cc_table[comp])
{
case 0:
val = (dc_dct_pred[0]+= Get_Luma_DC_dct_diff());
break;
case 1:
val = (dc_dct_pred[1]+= Get_Chroma_DC_dct_diff());
break;
case 2:
val = (dc_dct_pred[2]+= Get_Chroma_DC_dct_diff());
break;
}
bp[0] = val << (3-intra_dc_precision);
/* decode AC coefficients */
for (i=1; ; i++)
{
code = Show_Bits(16);
if (code>=16384 && !intra_vlc_format)
tab = &DCTtabnext[(code>>12)-4];
else if (code>=1024)
{
if (intra_vlc_format)
tab = &DCTtab0a[(code>>8)-4];
else
tab = &DCTtab0[(code>>8)-4];
}
else if (code>=512)
{
if (intra_vlc_format)
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
{
Fault_Flag = 1;
return;
}
Flush_Buffer(tab->len);
if (tab->run<64)
{
i+= tab->run;
val = tab->level;
sign = Get_Bits(1);
}
else if (tab->run==64) /* end_of_block */
return;
else /* escape */
{
i+= Get_Bits(6);
val = Get_Bits(12);
if (sign = (val>=2048))
val = 4096 - val;
}
j = scan[alternate_scan][i];
val = (val * quantizer_scale * qmat[j]) >> 4;
bp[j] = sign ? -val : val;
}
}
/* decode one non-intra coded MPEG-2 block */
static void Decode_MPEG2_Non_Intra_Block(int comp)
{
int val, i, j, sign, *qmat;
unsigned int code;
DCTtab *tab;
short *bp;
bp = block[comp];
qmat = (comp<4 || chroma_format==CHROMA420)
? non_intra_quantizer_matrix : chroma_non_intra_quantizer_matrix;
/* decode AC coefficients */
for (i=0; ; i++)
{
code = Show_Bits(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
{
Fault_Flag = 1;
return;
}
Flush_Buffer(tab->len);
if (tab->run<64)
{
i+= tab->run;
val = tab->level;
sign = Get_Bits(1);
}
else if (tab->run==64) /* end_of_block */
return;
else /* escape */
{
i+= Get_Bits(6);
val = Get_Bits(12);
if (sign = (val>=2048))
val = 4096 - val;
}
j = scan[alternate_scan][i];
val = (((val<<1)+1) * quantizer_scale * qmat[j]) >> 5;
bp[j] = sign ? -val : val;
}
}
static int Get_macroblock_type()
{
int macroblock_type;
switch (picture_coding_type)
{
case I_TYPE:
macroblock_type = Get_I_macroblock_type();
break;
case P_TYPE:
macroblock_type = Get_P_macroblock_type();
break;
case B_TYPE:
macroblock_type = Get_B_macroblock_type();
break;
}
return macroblock_type;
}
static int Get_I_macroblock_type()
{
if (Get_Bits(1))
return 1;
if (!Get_Bits(1))
Fault_Flag = 2;
return 17;
}
static int Get_P_macroblock_type()
{
int code;
if ((code = Show_Bits(6))>=8)
{
code >>= 3;
Flush_Buffer(PMBtab0[code].len);
return PMBtab0[code].val;
}
if (code==0)
{
Fault_Flag = 2;
return 0;
}
Flush_Buffer(PMBtab1[code].len);
return PMBtab1[code].val;
}
static int Get_B_macroblock_type()
{
int code;
if ((code = Show_Bits(6))>=8)
{
code >>= 2;
Flush_Buffer(BMBtab0[code].len);
return BMBtab0[code].val;
}
if (code==0)
{
Fault_Flag = 2;
return 0;
}
Flush_Buffer(BMBtab1[code].len);
return BMBtab1[code].val;
}
static int Get_coded_block_pattern()
{
int code;
if ((code = Show_Bits(9))>=128)
{
code >>= 4;
Flush_Buffer(CBPtab0[code].len);
return CBPtab0[code].val;
}
if (code>=8)
{
code >>= 1;
Flush_Buffer(CBPtab1[code].len);
return CBPtab1[code].val;
}
if (code<1)
{
Fault_Flag = 3;
return 0;
}
Flush_Buffer(CBPtab2[code].len);
return CBPtab2[code].val;
}
static int Get_macroblock_address_increment()
{
int code, val;
val = 0;
while ((code = Show_Bits(11))<24)
{
if (code!=15) /* if not macroblock_stuffing */
{
if (code==8) /* if macroblock_escape */
val+= 33;
else
{
Fault_Flag = 4;
return 1;
}
}
Flush_Buffer(11);
}
/* macroblock_address_increment == 1 */
/* ('1' is in the MSB position of the lookahead) */
if (code>=1024)
{
Flush_Buffer(1);
return val + 1;
}
/* codes 00010 ... 011xx */
if (code>=128)
{
/* remove leading zeros */
code >>= 6;
Flush_Buffer(MBAtab1[code].len);
return val + MBAtab1[code].val;
}
/* codes 00000011000 ... 0000111xxxx */
code-= 24; /* remove common base */
Flush_Buffer(MBAtab2[code].len);
return val + MBAtab2[code].val;
}
/*
parse VLC and perform dct_diff arithmetic.
MPEG-2: ISO/IEC 13818-2 section 7.2.1
Note: the arithmetic here is presented more elegantly than
the spec, yet the results, dct_diff, are the same.
*/
static int Get_Luma_DC_dct_diff()
{
int code, size, dct_diff;
/* decode length */
code = Show_Bits(5);
if (code<31)
{
size = DClumtab0[code].val;
Flush_Buffer(DClumtab0[code].len);
}
else
{
code = Show_Bits(9) - 0x1f0;
size = DClumtab1[code].val;
Flush_Buffer(DClumtab1[code].len);
}
if (size==0)
dct_diff = 0;
else
{
dct_diff = Get_Bits(size);
if ((dct_diff & (1<<(size-1)))==0)
dct_diff-= (1<<size) - 1;
}
return dct_diff;
}
static int Get_Chroma_DC_dct_diff()
{
int code, size, dct_diff;
/* decode length */
code = Show_Bits(5);
if (code<31)
{
size = DCchromtab0[code].val;
Flush_Buffer(DCchromtab0[code].len);
}
else
{
code = Show_Bits(10) - 0x3e0;
size = DCchromtab1[code].val;
Flush_Buffer(DCchromtab1[code].len);
}
if (size==0)
dct_diff = 0;
else
{
dct_diff = Get_Bits(size);
if ((dct_diff & (1<<(size-1)))==0)
dct_diff-= (1<<size) - 1;
}
return dct_diff;
}
static void form_predictions(int bx, int by, int macroblock_type, int motion_type,
int PMV[2][2][2], int motion_vertical_field_select[2][2],
int dmvector[2])
{
static int currentfield;
static unsigned char **predframe;
static int DMV[2][2];
static int stw;
stw = 0;
if ((macroblock_type & MACROBLOCK_MOTION_FORWARD) || (picture_coding_type==P_TYPE))
{
if (picture_structure==FRAME_PICTURE)
{
if ((motion_type==MC_FRAME) || !(macroblock_type & MACROBLOCK_MOTION_FORWARD))
{
/* frame-based prediction (broken into top and bottom halves
for spatial scalability prediction purposes) */
form_prediction(forward_reference_frame, 0, current_frame, 0, Coded_Picture_Width,
Coded_Picture_Width<<1, 16, 8, bx, by, PMV[0][0][0], PMV[0][0][1], stw);
form_prediction(forward_reference_frame, 1, current_frame, 1, Coded_Picture_Width,
Coded_Picture_Width<<1, 16, 8, bx, by, PMV[0][0][0], PMV[0][0][1], stw);
}
else if (motion_type==MC_FIELD) /* field-based prediction */
{
/* top field prediction */
form_prediction(forward_reference_frame, motion_vertical_field_select[0][0],
current_frame, 0, Coded_Picture_Width<<1, Coded_Picture_Width<<1, 16, 8,
bx, by>>1, PMV[0][0][0], PMV[0][0][1]>>1, stw);
/* bottom field prediction */
form_prediction(forward_reference_frame, motion_vertical_field_select[1][0],
current_frame, 1, Coded_Picture_Width<<1, Coded_Picture_Width<<1, 16, 8,
bx, by>>1, PMV[1][0][0], PMV[1][0][1]>>1, stw);
}
else if (motion_type==MC_DMV) /* dual prime prediction */
{
/* calculate derived motion vectors */
Dual_Prime_Arithmetic(DMV, dmvector, PMV[0][0][0], PMV[0][0][1]>>1);
/* predict top field from top field */
form_prediction(forward_reference_frame, 0, current_frame, 0,
Coded_Picture_Width<<1, Coded_Picture_Width<<1, 16, 8, bx, by>>1,
PMV[0][0][0], PMV[0][0][1]>>1, 0);
/* predict and add to top field from bottom field */
form_prediction(forward_reference_frame, 1, current_frame, 0,
Coded_Picture_Width<<1, Coded_Picture_Width<<1, 16, 8, bx, by>>1,
DMV[0][0], DMV[0][1], 1);
/* predict bottom field from bottom field */
form_prediction(forward_reference_frame, 1, current_frame, 1,
Coded_Picture_Width<<1, Coded_Picture_Width<<1, 16, 8, bx, by>>1,
PMV[0][0][0], PMV[0][0][1]>>1, 0);
/* predict and add to bottom field from top field */
form_prediction(forward_reference_frame, 0, current_frame, 1,
Coded_Picture_Width<<1, Coded_Picture_Width<<1, 16, 8, bx, by>>1,
DMV[1][0], DMV[1][1], 1);
}
else
Fault_Flag = 5;
}
else
{
/* field picture */
currentfield = (picture_structure==BOTTOM_FIELD);
/* determine which frame to use for prediction */
if (picture_coding_type==P_TYPE && Second_Field && currentfield!=motion_vertical_field_select[0][0])
predframe = backward_reference_frame;
else
predframe = forward_reference_frame;
if ((motion_type==MC_FIELD) || !(macroblock_type & MACROBLOCK_MOTION_FORWARD))
{
form_prediction(predframe, motion_vertical_field_select[0][0], current_frame, 0,
Coded_Picture_Width<<1, Coded_Picture_Width<<1, 16, 16, bx, by,
PMV[0][0][0], PMV[0][0][1], stw);
}
else if (motion_type==MC_16X8)
{
form_prediction(predframe, motion_vertical_field_select[0][0], current_frame, 0,
Coded_Picture_Width<<1, Coded_Picture_Width<<1, 16, 8, bx, by,
PMV[0][0][0], PMV[0][0][1], stw);
if (picture_coding_type==P_TYPE && Second_Field && currentfield!=motion_vertical_field_select[1][0])
predframe = backward_reference_frame;
else
predframe = forward_reference_frame;
form_prediction(predframe, motion_vertical_field_select[1][0], current_frame,
0, Coded_Picture_Width<<1, Coded_Picture_Width<<1, 16, 8, bx, by+8,
PMV[1][0][0], PMV[1][0][1], stw);
}
else if (motion_type==MC_DMV)
{
if (Second_Field)
predframe = backward_reference_frame;
else
predframe = forward_reference_frame;
/* calculate derived motion vectors */
Dual_Prime_Arithmetic(DMV, dmvector, PMV[0][0][0], PMV[0][0][1]);
/* predict from field of same parity */
form_prediction(forward_reference_frame, currentfield, current_frame, 0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -