static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, int n, int coded) { int level, i, last, run, run_diff; int dc_pred_dir; RLTable *rl; RL_VLC_ELEM *rl_vlc; const UINT8 *scan_table; int qmul, qadd; if (s->mb_intra) { qmul=1; qadd=0; /* DC coef */ set_stat(ST_DC); level = msmpeg4_decode_dc(s, n, &dc_pred_dir); #ifdef PRINT_MB { static int c; if(n==0) c=0; if(n==4) printf("%X", c); c+= c +dc_pred_dir; } #endif if (level < 0){ fprintf(stderr, "dc overflow- block: %d qscale: %d//\n", n, s->qscale); if(s->inter_intra_pred) level=0; else return -1; } if (n < 4) { rl = &rl_table[s->rl_table_index]; if(level > 256*s->y_dc_scale){ fprintf(stderr, "dc overflow+ L qscale: %d//\n", s->qscale); if(!s->inter_intra_pred) return -1; } } else { rl = &rl_table[3 + s->rl_chroma_table_index]; if(level > 256*s->c_dc_scale){ fprintf(stderr, "dc overflow+ C qscale: %d//\n", s->qscale); if(!s->inter_intra_pred) return -1; } } block[0] = level; run_diff = 0; i = 0; if (!coded) { goto not_coded; } if (s->ac_pred) { if (dc_pred_dir == 0) scan_table = s->intra_v_scantable; /* left */ else scan_table = s->intra_h_scantable; /* top */ } else { scan_table = s->intra_scantable; } set_stat(ST_INTRA_AC); rl_vlc= rl->rl_vlc[0]; } else { qmul = s->qscale << 1; qadd = (s->qscale - 1) | 1; i = -1; rl = &rl_table[3 + s->rl_table_index]; if(s->msmpeg4_version==2) run_diff = 0; else run_diff = 1; if (!coded) { s->block_last_index[n] = i; return 0; } scan_table = s->inter_scantable; set_stat(ST_INTER_AC); rl_vlc= rl->rl_vlc[s->qscale]; } { OPEN_READER(re, &s->gb); for(;;) { UPDATE_CACHE(re, &s->gb); GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2); if (level==0) { int cache; cache= GET_CACHE(re, &s->gb); /* escape */ if (s->msmpeg4_version==1 || (cache&0x80000000)==0) { if (s->msmpeg4_version==1 || (cache&0x40000000)==0) { /* third escape */ if(s->msmpeg4_version!=1) LAST_SKIP_BITS(re, &s->gb, 2); UPDATE_CACHE(re, &s->gb); if(s->msmpeg4_version<=3){ last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1); run= SHOW_UBITS(re, &s->gb, 6); SKIP_CACHE(re, &s->gb, 6); level= SHOW_SBITS(re, &s->gb, 8); LAST_SKIP_CACHE(re, &s->gb, 8); SKIP_COUNTER(re, &s->gb, 1+6+8); }else{ int sign; last= SHOW_UBITS(re, &s->gb, 1); SKIP_BITS(re, &s->gb, 1); if(!s->esc3_level_length){ int ll; //printf("ESC-3 %X at %d %d\n", show_bits(&s->gb, 24), s->mb_x, s->mb_y); if(s->qscale<8){ ll= SHOW_UBITS(re, &s->gb, 3); SKIP_BITS(re, &s->gb, 3); if(ll==0){ if(SHOW_UBITS(re, &s->gb, 1)) printf("cool a new vlc code ,contact the ffmpeg developers and upload the file\n"); SKIP_BITS(re, &s->gb, 1); ll=8; } }else{ ll=2; while(ll<8 && SHOW_UBITS(re, &s->gb, 1)==0){ ll++; SKIP_BITS(re, &s->gb, 1); } if(ll<8) SKIP_BITS(re, &s->gb, 1); } s->esc3_level_length= ll; s->esc3_run_length= SHOW_UBITS(re, &s->gb, 2) + 3; SKIP_BITS(re, &s->gb, 2); //printf("level length:%d, run length: %d\n", ll, s->esc3_run_length); UPDATE_CACHE(re, &s->gb); } run= SHOW_UBITS(re, &s->gb, s->esc3_run_length); SKIP_BITS(re, &s->gb, s->esc3_run_length); sign= SHOW_UBITS(re, &s->gb, 1); SKIP_BITS(re, &s->gb, 1); level= SHOW_UBITS(re, &s->gb, s->esc3_level_length); SKIP_BITS(re, &s->gb, s->esc3_level_length); if(sign) level= -level; } //printf("level: %d, run: %d at %d %d\n", level, run, s->mb_x, s->mb_y); #if 0 // waste of time / this will detect very few errors { const int abs_level= ABS(level); const int run1= run - rl->max_run[last][abs_level] - run_diff; if(abs_level<=MAX_LEVEL && run<=MAX_RUN){ if(abs_level <= rl->max_level[last][run]){ fprintf(stderr, "illegal 3. esc, vlc encoding possible\n"); return DECODING_AC_LOST; } if(abs_level <= rl->max_level[last][run]*2){ fprintf(stderr, "illegal 3. esc, esc 1 encoding possible\n"); return DECODING_AC_LOST; } if(run1>=0 && abs_level <= rl->max_level[last][run1]){ fprintf(stderr, "illegal 3. esc, esc 2 encoding possible\n"); return DECODING_AC_LOST; } } } #endif //level = level * qmul + (level>0) * qadd - (level<=0) * qadd ; if (level>0) level= level * qmul + qadd; else level= level * qmul - qadd; #if 0 // waste of time too :( if(level>2048 || level<-2048){ fprintf(stderr, "|level| overflow in 3. esc\n"); return DECODING_AC_LOST; } #endif i+= run + 1; if(last) i+=192; #ifdef ERROR_DETAILS if(run==66) fprintf(stderr, "illegal vlc code in ESC3 level=%d\n", level); else if((i>62 && i<192) || i>192+63) fprintf(stderr, "run overflow in ESC3 i=%d run=%d level=%d\n", i, run, level); #endif } else { /* second escape */ #if MIN_CACHE_BITS < 23 LAST_SKIP_BITS(re, &s->gb, 2); UPDATE_CACHE(re, &s->gb); #else SKIP_BITS(re, &s->gb, 2); #endif GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2); i+= run + rl->max_run[run>>7][level/qmul] + run_diff; //FIXME opt indexing level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); LAST_SKIP_BITS(re, &s->gb, 1); #ifdef ERROR_DETAILS if(run==66) fprintf(stderr, "illegal vlc code in ESC2 level=%d\n", level); else if((i>62 && i<192) || i>192+63) fprintf(stderr, "run overflow in ESC2 i=%d run=%d level=%d\n", i, run, level); #endif } } else { /* first escape */ #if MIN_CACHE_BITS < 22 LAST_SKIP_BITS(re, &s->gb, 1); UPDATE_CACHE(re, &s->gb); #else SKIP_BITS(re, &s->gb, 1); #endif GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2); i+= run; level = level + rl->max_level[run>>7][(run-1)&63] * qmul;//FIXME opt indexing level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); LAST_SKIP_BITS(re, &s->gb, 1); #ifdef ERROR_DETAILS if(run==66) fprintf(stderr, "illegal vlc code in ESC1 level=%d\n", level); else if((i>62 && i<192) || i>192+63) fprintf(stderr, "run overflow in ESC1 i=%d run=%d level=%d\n", i, run, level); #endif } } else { i+= run; level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); LAST_SKIP_BITS(re, &s->gb, 1); #ifdef ERROR_DETAILS if(run==66) fprintf(stderr, "illegal vlc code level=%d\n", level); else if((i>62 && i<192) || i>192+63) fprintf(stderr, "run overflow i=%d run=%d level=%d\n", i, run, level); #endif } if (i > 62){ i-= 192; if(i&(~63)){ if(i+192 == 64 && level/qmul==-1){ fprintf(stderr, "ignoring overflow at %d %d\n", s->mb_x, s->mb_y); break; }else{ fprintf(stderr, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); return -1; } } block[scan_table[i]] = level; break; } block[scan_table[i]] = level; } CLOSE_READER(re, &s->gb); } not_coded: if (s->mb_intra) { mpeg4_pred_ac(s, block, n, dc_pred_dir); if (s->ac_pred) { i = 63; /* XXX: not optimal */ } } if(s->msmpeg4_version==4 && i>0) i=63; //FIXME/XXX optimize s->block_last_index[n] = i; return 0; }