📄 mpvd.java
字号:
//test
/**
System.out.println(
"ma " + macroblock_type[0] +
" /mt " + motion_type[0] +
" /mv " + motion_vector_count[0] +
" /mf " + mv_format[0] +
" /ms " + mvscale[0] +
" /dm " + dmv[0] +
" /dc " + dct_type[0] +
" /qs " + quantizer_scale +
" /qt " + q_scale_type +
" /cm " + concealment_motion_vectors
);
**/
/* decode blocks */
for (comp=0; comp<block_count; comp++) {
Clear_Block(comp);
if ((coded_block_pattern & (1<<(block_count-1-comp)))>0){
if ((macroblock_type[0] & MACROBLOCK_INTRA)>0)
Decode_MPEG2_Intra_Block(comp, dc_dct_pred);
else
Decode_MPEG2_Non_Intra_Block(comp);
if (Fault_Flag>0) 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[0] & MACROBLOCK_INTRA)<1)
dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0;
/* reset motion vector predictors */
if ((macroblock_type[0] & MACROBLOCK_INTRA)>0 && concealment_motion_vectors<1 ) {
/* 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[0] & (MACROBLOCK_MOTION_FORWARD|MACROBLOCK_INTRA))<1) {
/* 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[0] = MC_FRAME;
else{
motion_type[0] = MC_FIELD;
motion_vertical_field_select[0][0] = (picture_structure==BOTTOM_FIELD)?1:0;
}
}
/* successfully decoded macroblock */
return 1 ;
}
/* decode one intra coded MPEG-2 block */
public void Decode_MPEG2_Intra_Block(int comp, int dc_dct_pred[]) {
int val=0, i, j, sign, qmat[]; //qmat woanders??
int code;
byte tab[];
short bp[]; //bp woanders array?
bp = block[comp]; //macroblock
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;
}
//test
/**
System.out.println("comp " + comp + " /dc " + val);
if (quantizer_scale > 4)
val -= 128;
**/
bp[0] = (short)(val << (3-intra_dc_precision)); //the top-left pixel value of block
/* decode AC coefficients */
for (i=1; ; i++){
code = Show_Bits(16);
if (code>=16384 && intra_vlc_format<1)
tab = DCTtabnext[(code>>12)-4];
else if (code>=1024){
if (intra_vlc_format>0)
tab = DCTtab0a[(code>>8)-4];
else
tab = DCTtab0[(code>>8)-4];
}
else if (code>=512){
if (intra_vlc_format>0)
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_Bits(tab[2]);
if (tab[0]<64){
i+= tab[0];
val = tab[1];
sign = Get_Bits(1);
}
else if (tab[0]==64) /* end_of_block */
return;
else{ /* escape */
if (profile_and_level_indication==0){
//mpeg1 //DM28112003 081.5++
i+= Get_Bits(6);
val = Get_Bits(8);
if (val==0)
val = Get_Bits(8);
else if(val==128)
val = Get_Bits(8)-128;
else if(val>128)
val-=256;
sign = 0;
}else{
//mpeg2
i+= Get_Bits(6);
val = Get_Bits(12);
if ( (sign = (val>=2048)?1:0) >0)
val = 4096 - val;
}
}
j = scan[alternate_scan][i];
val = (val * quantizer_scale * qmat[j]) >> 4;
bp[j] = (short)((sign>0) ? -val : val);
}
}
/* decode one non-intra coded MPEG-2 block */
public void Decode_MPEG2_Non_Intra_Block(int comp){
int val, i, j, sign, qmat[];
int code;
byte 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_Bits(tab[2]);
if (tab[0]<64){
i+= tab[0];
val = tab[1];
sign = Get_Bits(1);
}
else if (tab[0]==64) /* end_of_block */
return;
else { /* escape */
i+= Get_Bits(6);
val = Get_Bits(12);
if ( (sign = (val>=2048)?1:0)>0 )
val = 4096 - val;
}
j = scan[alternate_scan][i];
val = (((val<<1)+1) * quantizer_scale * qmat[j]) >> 5;
bp[j] = (short)((sign>0) ? -val : 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.
*/
public int Get_Luma_DC_dct_diff(){
int code, size, dct_diff;
/* decode length */
code = Show_Bits(5);
if (code<31){
size = DClumtab0[code][0];
Flush_Bits(DClumtab0[code][1]);
}else{
code = Show_Bits(9) - 0x1f0;
size = DClumtab1[code][0];
Flush_Bits(DClumtab1[code][1]);
}
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;
}
public int Get_Chroma_DC_dct_diff(){
int code, size, dct_diff;
/* decode length */
code = Show_Bits(5);
if (code<31){
size = DCchromtab0[code][0];
Flush_Bits(DCchromtab0[code][1]);
}else{
code = Show_Bits(10) - 0x3e0;
size = DCchromtab1[code][0];
Flush_Bits(DCchromtab1[code][1]);
}
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;
}
public int Get_coded_block_pattern(){
int code;
if ((code = Show_Bits(9))>=128) {
code >>= 4;
Flush_Bits(CBPtab0[code][1]);
return CBPtab0[code][0];
}
if (code>=8) {
code >>= 1;
Flush_Bits(CBPtab1[code][1]);
return CBPtab1[code][0];
}
if (code<1) {
Fault_Flag = 3;
return 0;
}
Flush_Bits(CBPtab2[code][1]);
return CBPtab2[code][0];
}
/* return==-1 means go to next picture */
/* the expression "start of slice" is used throughout the normative
body of the MPEG specification */
public int start_of_slice(int MBA[], int MBAinc[], int dc_dct_pred[], int PMV[][][]){
next_start_code();
int code = Get_Bits(32);
if (code<SLICE_START_CODE_MIN || code>SLICE_START_CODE_MAX){
// only slice headers are allowed in picture_data
Fault_Flag = 10;
return -1;
}
/* decode slice header (may change quantizer_scale) */
int slice_vert_pos_ext = slice_header();
/* decode macroblock address increment */
MBAinc[0] = Get_macroblock_address_increment();
if (Fault_Flag>0) return -1;
/* set current location */
/* NOTE: the arithmetic used to derive macroblock_address below is
equivalent to ISO/IEC 13818-2 section 6.3.17: Macroblock */
MBA[0] = ((slice_vert_pos_ext<<7) + (code&255) - 1) * mb_width + MBAinc[0] - 1;
MBAinc[0] = 1; // first macroblock in slice: not skipped
/* reset all DC coefficient and motion vector 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;
/* 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;
/* successfull: trigger decode macroblocks in slice */
return 1;
}
public int Get_macroblock_address_increment(){
int code=0, 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_Bits(11);
}
/* macroblock_address_increment == 1 */
/* ('1' is in the MSB position of the lookahead) */
if (code>=1024) {
Flush_Bits(1);
return (val + 1);
}
/* codes 00010 ... 011xx */
if (code>=128) {
/* remove leading zeros */
code >>= 6;
Flush_Bits(MBAtab1[code][1]);
return (val + MBAtab1[code][0]);
}
/* codes 00000011000 ... 0000111xxxx */
code-= 24; /* remove common base */
Flush_Bits(MBAtab2[code][1]);
return (val + MBAtab2[code][0]);
}
/* ISO/IEC 13818-2 sections 6.2.5.2, 6.3.17.2, and 7.6.3: Motion vectors */
public void motion_vectors(int PMV[][][],int dmvector[],
int motion_vertical_field_select[][], 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[0]==1) {
if (mv_format[0]==MV_FIELD && dmv[0]<1)
motion_vertical_field_select[1][s] =
motion_vertical_field_select[0][s] = Get_Bits(1);
motion_vector(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];
P
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -