diff options
Diffstat (limited to 'src/libffmpeg/libavcodec/msmpeg4.c')
-rw-r--r-- | src/libffmpeg/libavcodec/msmpeg4.c | 430 |
1 files changed, 283 insertions, 147 deletions
diff --git a/src/libffmpeg/libavcodec/msmpeg4.c b/src/libffmpeg/libavcodec/msmpeg4.c index 0cac44457..34dc3569d 100644 --- a/src/libffmpeg/libavcodec/msmpeg4.c +++ b/src/libffmpeg/libavcodec/msmpeg4.c @@ -32,6 +32,19 @@ */ //#define DEBUG +#define DC_VLC_BITS 9 +#define CBPY_VLC_BITS 6 +#define INTER_INTRA_VLC_BITS 3 +#define V1_INTRA_CBPC_VLC_BITS 6 +#define V1_INTER_CBPC_VLC_BITS 6 +#define V2_INTRA_CBPC_VLC_BITS 3 +#define V2_MB_TYPE_VLC_BITS 7 +#define MV_VLC_BITS 9 +#define V2_MV_VLC_BITS 9 +#define TEX_VLC_BITS 9 +#define MB_NON_INTRA_VLC_BITS 9 +#define MB_INTRA_VLC_BITS 9 + static UINT32 v2_dc_lum_table[512][2]; static UINT32 v2_dc_chroma_table[512][2]; @@ -43,6 +56,8 @@ static int msmpeg4_decode_motion(MpegEncContext * s, int *mx_ptr, int *my_ptr); static void msmpeg4v2_encode_motion(MpegEncContext * s, int val); static void init_h263_dc_for_msmpeg4(void); +static inline void msmpeg4_memsetw(short *tab, int val, int n); + extern UINT32 inverse[256]; @@ -345,14 +360,17 @@ void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number) s->mv_table_index = 1; /* only if P frame */ s->use_skip_mb_code = 1; /* only if P frame */ s->per_mb_rl_table = 0; + s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=128 && s->pict_type==P_TYPE); if (s->pict_type == I_TYPE) { s->no_rounding = 1; - put_bits(&s->pb, 5, 0x17); /* indicate only one "slice" */ + s->slice_height= s->mb_height/1; + put_bits(&s->pb, 5, 0x16 + s->mb_height/s->slice_height); if(s->msmpeg4_version==4){ msmpeg4_encode_ext_header(s); - put_bits(&s->pb, 1, s->per_mb_rl_table); + if(s->bit_rate>50) + put_bits(&s->pb, 1, s->per_mb_rl_table); } if(s->msmpeg4_version>2){ @@ -366,7 +384,7 @@ void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number) } else { put_bits(&s->pb, 1, s->use_skip_mb_code); - if(s->msmpeg4_version==4) + if(s->msmpeg4_version==4 && s->bit_rate>50) put_bits(&s->pb, 1, s->per_mb_rl_table); if(s->msmpeg4_version>2){ @@ -398,7 +416,7 @@ void msmpeg4_encode_ext_header(MpegEncContext * s) { put_bits(&s->pb, 5, s->frame_rate / FRAME_RATE_BASE); //yes 29.97 -> 29 - put_bits(&s->pb, 11, MIN(s->bit_rate, 2047)); + put_bits(&s->pb, 11, MIN(s->bit_rate, 2047)); if(s->msmpeg4_version<3) s->flipflop_rounding=0; @@ -474,6 +492,38 @@ static void msmpeg4_encode_motion(MpegEncContext * s, } } +static inline void handle_slices(MpegEncContext *s){ + if (s->mb_x == 0) { + if (s->slice_height && (s->mb_y % s->slice_height) == 0) { + if(s->msmpeg4_version != 4){ + int wrap; + /* reset DC pred (set previous line to 1024) */ + wrap = 2 * s->mb_width + 2; + msmpeg4_memsetw(&s->dc_val[0][(1) + (2 * s->mb_y) * wrap], + 1024, 2 * s->mb_width); + wrap = s->mb_width + 2; + msmpeg4_memsetw(&s->dc_val[1][(1) + (s->mb_y) * wrap], + 1024, s->mb_width); + msmpeg4_memsetw(&s->dc_val[2][(1) + (s->mb_y) * wrap], + 1024, s->mb_width); + + /* reset AC pred (set previous line to 0) */ + wrap = s->mb_width * 2 + 2; + msmpeg4_memsetw(s->ac_val[0][0] + (1 + (2 * s->mb_y) * wrap)*16, + 0, 2 * s->mb_width*16); + wrap = s->mb_width + 2; + msmpeg4_memsetw(s->ac_val[1][0] + (1 + (s->mb_y) * wrap)*16, + 0, s->mb_width*16); + msmpeg4_memsetw(s->ac_val[2][0] + (1 + (s->mb_y) * wrap)*16, + 0, s->mb_width*16); + } + s->first_slice_line = 1; + } else { + s->first_slice_line = 0; + } + } +} + void msmpeg4_encode_mb(MpegEncContext * s, DCTELEM block[6][64], int motion_x, int motion_y) @@ -482,6 +532,8 @@ void msmpeg4_encode_mb(MpegEncContext * s, int pred_x, pred_y; UINT8 *coded_block; + handle_slices(s); + if (!s->mb_intra) { /* compute cbp */ set_stat(ST_INTER_MB); @@ -610,6 +662,19 @@ static inline int msmpeg4v1_pred_dc(MpegEncContext * s, int n, return s->last_dc[i]; } +static int get_dc(uint8_t *src, int stride, int scale) +{ + int y; + int sum=0; + for(y=0; y<8; y++){ + int x; + for(x=0; x<8; x++){ + sum+=src[x + y*stride]; + } + } + return (sum + (scale>>1))/scale; +} + /* dir = 0: left, dir = 1: top prediction */ static inline int msmpeg4_pred_dc(MpegEncContext * s, int n, UINT16 **dc_val_ptr, int *dir_ptr) @@ -675,12 +740,69 @@ static inline int msmpeg4_pred_dc(MpegEncContext * s, int n, /* XXX: WARNING: they did not choose the same test as MPEG4. This is very important ! */ if(s->msmpeg4_version>3){ - if (abs(a - b) < abs(b - c)) { - pred = c; - *dir_ptr = 1; - } else { - pred = a; - *dir_ptr = 0; + if(s->inter_intra_pred){ + uint8_t *dest; + int wrap; + + if(n==1){ + pred=a; + *dir_ptr = 0; + }else if(n==2){ + pred=c; + *dir_ptr = 1; + }else if(n==3){ + if (abs(a - b) < abs(b - c)) { + pred = c; + *dir_ptr = 1; + } else { + pred = a; + *dir_ptr = 0; + } + }else{ + if(n<4){ + wrap= s->linesize; + dest= s->current_picture[0] + (((n>>1) + 2*s->mb_y) * 8* wrap ) + ((n&1) + 2*s->mb_x) * 8; + }else{ + wrap= s->uvlinesize; + dest= s->current_picture[n-3] + (s->mb_y * 8 * wrap) + s->mb_x * 8; + } + if(s->mb_x==0) a= (1024 + (scale>>1))/scale; + else a= get_dc(dest-8, wrap, scale*8); + if(s->mb_y==0) c= (1024 + (scale>>1))/scale; + else c= get_dc(dest-8*wrap, wrap, scale*8); + + if (s->h263_aic_dir==0) { + pred= a; + *dir_ptr = 0; + }else if (s->h263_aic_dir==1) { + if(n==0){ + pred= c; + *dir_ptr = 1; + }else{ + pred= a; + *dir_ptr = 0; + } + }else if (s->h263_aic_dir==2) { + if(n==0){ + pred= a; + *dir_ptr = 0; + }else{ + pred= c; + *dir_ptr = 1; + } + } else { + pred= c; + *dir_ptr = 1; + } + } + }else{ + if (abs(a - b) < abs(b - c)) { + pred = c; + *dir_ptr = 1; + } else { + pred = a; + *dir_ptr = 0; + } } }else{ if (abs(a - b) <= abs(b - c)) { @@ -904,6 +1026,7 @@ static VLC v2_mb_type_vlc; static VLC v2_mv_vlc; static VLC v1_intra_cbpc_vlc; static VLC v1_inter_cbpc_vlc; +static VLC inter_intra_vlc; /* this table is practically identical to the one from h263 except that its inverted */ static void init_h263_dc_for_msmpeg4(void) @@ -978,57 +1101,61 @@ int ff_msmpeg4_decode_init(MpegEncContext *s) } for(i=0;i<2;i++) { mv = &mv_tables[i]; - init_vlc(&mv->vlc, 9, mv->n + 1, + init_vlc(&mv->vlc, MV_VLC_BITS, mv->n + 1, mv->table_mv_bits, 1, 1, mv->table_mv_code, 2, 2); } - init_vlc(&dc_lum_vlc[0], 9, 120, + init_vlc(&dc_lum_vlc[0], DC_VLC_BITS, 120, &table0_dc_lum[0][1], 8, 4, &table0_dc_lum[0][0], 8, 4); - init_vlc(&dc_chroma_vlc[0], 9, 120, + init_vlc(&dc_chroma_vlc[0], DC_VLC_BITS, 120, &table0_dc_chroma[0][1], 8, 4, &table0_dc_chroma[0][0], 8, 4); - init_vlc(&dc_lum_vlc[1], 9, 120, + init_vlc(&dc_lum_vlc[1], DC_VLC_BITS, 120, &table1_dc_lum[0][1], 8, 4, &table1_dc_lum[0][0], 8, 4); - init_vlc(&dc_chroma_vlc[1], 9, 120, + init_vlc(&dc_chroma_vlc[1], DC_VLC_BITS, 120, &table1_dc_chroma[0][1], 8, 4, &table1_dc_chroma[0][0], 8, 4); - init_vlc(&v2_dc_lum_vlc, 9, 512, + init_vlc(&v2_dc_lum_vlc, DC_VLC_BITS, 512, &v2_dc_lum_table[0][1], 8, 4, &v2_dc_lum_table[0][0], 8, 4); - init_vlc(&v2_dc_chroma_vlc, 9, 512, + init_vlc(&v2_dc_chroma_vlc, DC_VLC_BITS, 512, &v2_dc_chroma_table[0][1], 8, 4, &v2_dc_chroma_table[0][0], 8, 4); - init_vlc(&cbpy_vlc, 6, 16, + init_vlc(&cbpy_vlc, CBPY_VLC_BITS, 16, &cbpy_tab[0][1], 2, 1, &cbpy_tab[0][0], 2, 1); - init_vlc(&v2_intra_cbpc_vlc, 3, 4, + init_vlc(&v2_intra_cbpc_vlc, V2_INTRA_CBPC_VLC_BITS, 4, &v2_intra_cbpc[0][1], 2, 1, &v2_intra_cbpc[0][0], 2, 1); - init_vlc(&v2_mb_type_vlc, 5, 8, + init_vlc(&v2_mb_type_vlc, V2_MB_TYPE_VLC_BITS, 8, &v2_mb_type[0][1], 2, 1, &v2_mb_type[0][0], 2, 1); - init_vlc(&v2_mv_vlc, 9, 33, + init_vlc(&v2_mv_vlc, V2_MV_VLC_BITS, 33, &mvtab[0][1], 2, 1, &mvtab[0][0], 2, 1); - init_vlc(&mb_non_intra_vlc, 9, 128, + init_vlc(&mb_non_intra_vlc, MB_NON_INTRA_VLC_BITS, 128, &table_mb_non_intra[0][1], 8, 4, &table_mb_non_intra[0][0], 8, 4); - init_vlc(&mb_intra_vlc, 9, 64, + init_vlc(&mb_intra_vlc, MB_INTRA_VLC_BITS, 64, &table_mb_intra[0][1], 4, 2, &table_mb_intra[0][0], 4, 2); - init_vlc(&v1_intra_cbpc_vlc, 6, 8, + init_vlc(&v1_intra_cbpc_vlc, V1_INTRA_CBPC_VLC_BITS, 8, intra_MCBPC_bits, 1, 1, intra_MCBPC_code, 1, 1); - init_vlc(&v1_inter_cbpc_vlc, 6, 25, + init_vlc(&v1_inter_cbpc_vlc, V1_INTER_CBPC_VLC_BITS, 25, inter_MCBPC_bits, 1, 1, inter_MCBPC_code, 1, 1); + + init_vlc(&inter_intra_vlc, INTER_INTRA_VLC_BITS, 4, + &table_inter_intra[0][1], 2, 1, + &table_inter_intra[0][0], 2, 1); } return 0; } @@ -1075,7 +1202,13 @@ return -1; fprintf(stderr, "invalid picture type\n"); return -1; } - +#if 0 +{ + static int had_i=0; + if(s->pict_type == I_TYPE) had_i=1; + if(!had_i) return -1; +} +#endif s->qscale = get_bits(&s->gb, 5); if (s->pict_type == I_TYPE) { @@ -1089,8 +1222,10 @@ return -1; s->slice_height = code; }else{ /* 0x17: one slice, 0x18: two slices, ... */ - if (code < 0x17) + if (code < 0x17){ + fprintf(stderr, "error, slice code was %X\n", code); return -1; + } s->slice_height = s->mb_height / (code - 0x16); } @@ -1112,24 +1247,27 @@ return -1; case 4: msmpeg4_decode_ext_header(s, (2+5+5+17+7)/8); - s->per_mb_rl_table= get_bits1(&s->gb); + if(s->bit_rate > 50) s->per_mb_rl_table= get_bits1(&s->gb); + else s->per_mb_rl_table= 0; + if(!s->per_mb_rl_table){ s->rl_chroma_table_index = decode012(&s->gb); s->rl_table_index = decode012(&s->gb); } s->dc_table_index = get_bits1(&s->gb); + s->inter_intra_pred= 0; break; } s->no_rounding = 1; -/* printf(" %d %d %d %d %d \n", +/* printf("qscale:%d rlc:%d rl:%d dc:%d mbrl:%d slice:%d \n", s->qscale, s->rl_chroma_table_index, s->rl_table_index, s->dc_table_index, - s->per_mb_rl_table);*/ + s->per_mb_rl_table, + s->slice_height);*/ } else { - switch(s->msmpeg4_version){ case 1: case 2: @@ -1153,7 +1291,10 @@ return -1; break; case 4: s->use_skip_mb_code = get_bits1(&s->gb); - s->per_mb_rl_table= get_bits1(&s->gb); + + if(s->bit_rate > 50) s->per_mb_rl_table= get_bits1(&s->gb); + else s->per_mb_rl_table= 0; + if(!s->per_mb_rl_table){ s->rl_table_index = decode012(&s->gb); s->rl_chroma_table_index = s->rl_table_index; @@ -1162,15 +1303,17 @@ return -1; s->dc_table_index = get_bits1(&s->gb); s->mv_table_index = get_bits1(&s->gb); + s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=128); break; } -/* printf(" %d %d %d %d %d %d \n", +/* printf("skip:%d rl:%d rlc:%d dc:%d mv:%d mbrl:%d qp:%d \n", s->use_skip_mb_code, s->rl_table_index, s->rl_chroma_table_index, s->dc_table_index, s->mv_table_index, - s->per_mb_rl_table);*/ + s->per_mb_rl_table, + s->qscale);*/ if(s->flipflop_rounding){ s->no_rounding ^= 1; }else{ @@ -1263,7 +1406,7 @@ static int msmpeg4v2_decode_motion(MpegEncContext * s, int pred, int f_code) { int code, val, sign, shift; - code = get_vlc(&s->gb, &v2_mv_vlc); + code = get_vlc2(&s->gb, v2_mv_vlc.table, V2_MV_VLC_BITS, 2); // printf("MV code %d at %d %d pred: %d\n", code, s->mb_x,s->mb_y, pred); if (code < 0) return 0xffff; @@ -1310,9 +1453,9 @@ static int msmpeg4v12_decode_mb(MpegEncContext *s, } if(s->msmpeg4_version==2) - code = get_vlc(&s->gb, &v2_mb_type_vlc); + code = get_vlc2(&s->gb, v2_mb_type_vlc.table, V2_MB_TYPE_VLC_BITS, 1); else - code = get_vlc(&s->gb, &v1_inter_cbpc_vlc); + code = get_vlc2(&s->gb, v1_inter_cbpc_vlc.table, V1_INTER_CBPC_VLC_BITS, 3); if(code<0 || code>7){ fprintf(stderr, "cbpc %d invalid at %d %d\n", code, s->mb_x, s->mb_y); return -1; @@ -1324,9 +1467,9 @@ static int msmpeg4v12_decode_mb(MpegEncContext *s, } else { s->mb_intra = 1; if(s->msmpeg4_version==2) - cbp= get_vlc(&s->gb, &v2_intra_cbpc_vlc); + cbp= get_vlc2(&s->gb, v2_intra_cbpc_vlc.table, V2_INTRA_CBPC_VLC_BITS, 1); else - cbp= get_vlc(&s->gb, &v1_intra_cbpc_vlc); + cbp= get_vlc2(&s->gb, v1_intra_cbpc_vlc.table, V1_INTRA_CBPC_VLC_BITS, 1); if(cbp<0 || cbp>3){ fprintf(stderr, "cbpc %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y); return -1; @@ -1336,7 +1479,7 @@ static int msmpeg4v12_decode_mb(MpegEncContext *s, if (!s->mb_intra) { int mx, my, cbpy; - cbpy= get_vlc(&s->gb, &cbpy_vlc); + cbpy= get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1); if(cbpy<0){ fprintf(stderr, "cbpy %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y); return -1; @@ -1356,10 +1499,10 @@ static int msmpeg4v12_decode_mb(MpegEncContext *s, } else { if(s->msmpeg4_version==2){ s->ac_pred = get_bits1(&s->gb); - cbp|= get_vlc(&s->gb, &cbpy_vlc)<<2; //FIXME check errors + cbp|= get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors } else{ s->ac_pred = 0; - cbp|= get_vlc(&s->gb, &cbpy_vlc)<<2; //FIXME check errors + cbp|= get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors if(s->pict_type==P_TYPE) cbp^=0x3C; } } @@ -1387,34 +1530,7 @@ if(s->mb_x==0){ } #endif /* special slice handling */ - if (s->mb_x == 0) { - if (s->slice_height && (s->mb_y % s->slice_height) == 0) { - int wrap; - /* reset DC pred (set previous line to 1024) */ - wrap = 2 * s->mb_width + 2; - msmpeg4_memsetw(&s->dc_val[0][(1) + (2 * s->mb_y) * wrap], - 1024, 2 * s->mb_width); - wrap = s->mb_width + 2; - msmpeg4_memsetw(&s->dc_val[1][(1) + (s->mb_y) * wrap], - 1024, s->mb_width); - msmpeg4_memsetw(&s->dc_val[2][(1) + (s->mb_y) * wrap], - 1024, s->mb_width); - - /* reset AC pred (set previous line to 0) */ - wrap = s->mb_width * 2 + 2; - msmpeg4_memsetw(s->ac_val[0][0] + (1 + (2 * s->mb_y) * wrap)*16, - 0, 2 * s->mb_width*16); - wrap = s->mb_width + 2; - msmpeg4_memsetw(s->ac_val[1][0] + (1 + (s->mb_y) * wrap)*16, - 0, s->mb_width*16); - msmpeg4_memsetw(s->ac_val[2][0] + (1 + (s->mb_y) * wrap)*16, - 0, s->mb_width*16); - - s->first_slice_line = 1; - } else { - s->first_slice_line = 0; - } - } + handle_slices(s); if(s->msmpeg4_version<=2) return msmpeg4v12_decode_mb(s, block); //FIXME export function & call from outside perhaps @@ -1438,7 +1554,7 @@ printf("S "); } } - code = get_vlc(&s->gb, &mb_non_intra_vlc); + code = get_vlc2(&s->gb, mb_non_intra_vlc.table, MB_NON_INTRA_VLC_BITS, 3); if (code < 0) return -1; //s->mb_intra = (code & 0x40) ? 0 : 1; @@ -1448,7 +1564,7 @@ printf("S "); } else { set_stat(ST_INTRA_MB); s->mb_intra = 1; - code = get_vlc(&s->gb, &mb_intra_vlc); + code = get_vlc2(&s->gb, mb_intra_vlc.table, MB_INTRA_VLC_BITS, 2); if (code < 0) return -1; /* predict coded block pattern */ @@ -1489,6 +1605,10 @@ printf("P "); #ifdef PRINT_MB printf("%c", s->ac_pred ? 'A' : 'I'); #endif + if(s->inter_intra_pred){ + s->h263_aic_dir= get_vlc2(&s->gb, inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1); +// printf("%d%d %d %d/", s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y); + } if(s->per_mb_rl_table && cbp){ s->rl_table_index = decode012(&s->gb); s->rl_chroma_table_index = s->rl_table_index; @@ -1509,9 +1629,10 @@ printf("%c", s->ac_pred ? 'A' : 'I'); static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, int n, int coded) { - int code, level, i, j, last, run, run_diff; + 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; @@ -1532,25 +1653,26 @@ static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, #endif if (level < 0){ fprintf(stderr, "dc overflow- block: %d qscale: %d//\n", n, s->qscale); - return -1; + 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); - return -1; + 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); - return -1; + if(!s->inter_intra_pred) return -1; } } block[0] = level; run_diff = 0; - i = 1; + i = 0; if (!coded) { goto not_coded; } @@ -1563,10 +1685,11 @@ static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, 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 = 0; + i = -1; rl = &rl_table[3 + s->rl_table_index]; if(s->msmpeg4_version==2) @@ -1575,53 +1698,66 @@ static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, run_diff = 1; if (!coded) { - s->block_last_index[n] = i - 1; + 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(;;) { - code = get_vlc(&s->gb, &rl->vlc); - if (code < 0){ - fprintf(stderr, "illegal AC-VLC code at %d %d\n", s->mb_x, s->mb_y); - return -1; - } - if (code == rl->n) { + 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 || get_bits1(&s->gb) == 0) { - if (s->msmpeg4_version==1 || get_bits1(&s->gb) == 0) { + 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= get_bits1(&s->gb); - run= get_bits(&s->gb, 6); - level= get_bits(&s->gb, 8); - level= ((int8_t)level); - }else{ + 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= get_bits1(&s->gb); + 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= get_bits(&s->gb, 3); + ll= SHOW_UBITS(re, &s->gb, 3); SKIP_BITS(re, &s->gb, 3); if(ll==0){ - if(get_bits1(&s->gb)) printf("cool a new vlc code ,contact the ffmpeg developers and upload the file\n"); + 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 && get_bits1(&s->gb)==0) ll++; + while(ll<8 && SHOW_UBITS(re, &s->gb, 1)==0){ + ll++; + SKIP_BITS(re, &s->gb, 1); + } + SKIP_BITS(re, &s->gb, 1); } s->esc3_level_length= ll; - s->esc3_run_length= get_bits(&s->gb, 2) + 3; + 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); } - run= get_bits(&s->gb, s->esc3_run_length); - sign= get_bits1(&s->gb); - level= get_bits(&s->gb, s->esc3_level_length); + 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); @@ -1654,64 +1790,64 @@ static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, return DECODING_AC_LOST; } #endif + i+= run + 1; + if(last) i+=192; } else { /* second escape */ - code = get_vlc(&s->gb, &rl->vlc); - if (code < 0 || code >= rl->n){ - fprintf(stderr, "illegal ESC2-VLC code %d at %d %d\n", code, s->mb_x, s->mb_y); - return -1; - } - run = rl->table_run[code]; - level = rl->table_level[code]; - last = code >= rl->last; - run += rl->max_run[last][level] + run_diff; - level= level * qmul + qadd; - if (get_bits1(&s->gb)) - level = -level; +#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); } } else { /* first escape */ - code = get_vlc(&s->gb, &rl->vlc); - if (code < 0 || code >= rl->n){ - fprintf(stderr, "illegal ESC2-VLC code %d at %d %d\n", code, s->mb_x, s->mb_y); - return -1; - } - run = rl->table_run[code]; - level = rl->table_level[code]; - last = code >= rl->last; - level += rl->max_level[last][run]; - level= level * qmul + qadd; - if (get_bits1(&s->gb)) - level = -level; +#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); } } else { - run = rl->table_run[code]; - level = rl->table_level[code] * qmul + qadd; - last = code >= rl->last; - if (get_bits1(&s->gb)) - level = -level; - } - i += run; - if (i >= 64){ - fprintf(stderr, "run too long at %d %d\n", s->mb_x, s->mb_y); - return -1; + i+= run; + level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); + LAST_SKIP_BITS(re, &s->gb, 1); } + if (i > 62){ + i-= 192; + if(i&(~63)){ + fprintf(stderr, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); + return -1; + } - j = scan_table[i]; - block[j] = level; - i++; - if (last) + 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 = 64; /* XXX: not optimal */ + i = 63; /* XXX: not optimal */ } } - if(s->msmpeg4_version==4 && i>1) i=64; //FIXME/XXX optimize - s->block_last_index[n] = i - 1; + if(s->msmpeg4_version==4 && i>0) i=63; //FIXME/XXX optimize + s->block_last_index[n] = i; return 0; } @@ -1722,18 +1858,18 @@ static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) if(s->msmpeg4_version<=2){ if (n < 4) { - level = get_vlc(&s->gb, &v2_dc_lum_vlc); + level = get_vlc2(&s->gb, v2_dc_lum_vlc.table, DC_VLC_BITS, 3); } else { - level = get_vlc(&s->gb, &v2_dc_chroma_vlc); + level = get_vlc2(&s->gb, v2_dc_chroma_vlc.table, DC_VLC_BITS, 3); } if (level < 0) return -1; level-=256; }else{ //FIXME optimize use unified tables & index if (n < 4) { - level = get_vlc(&s->gb, &dc_lum_vlc[s->dc_table_index]); + level = get_vlc2(&s->gb, dc_lum_vlc[s->dc_table_index].table, DC_VLC_BITS, 3); } else { - level = get_vlc(&s->gb, &dc_chroma_vlc[s->dc_table_index]); + level = get_vlc2(&s->gb, dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3); } if (level < 0){ fprintf(stderr, "illegal dc vlc\n"); @@ -1781,7 +1917,7 @@ static int msmpeg4_decode_motion(MpegEncContext * s, mv = &mv_tables[s->mv_table_index]; - code = get_vlc(&s->gb, &mv->vlc); + code = get_vlc2(&s->gb, mv->vlc.table, MV_VLC_BITS, 2); if (code < 0){ fprintf(stderr, "illegal MV code at %d %d\n", s->mb_x, s->mb_y); return -1; |