X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmsmpeg4.c;h=d62c572cb015f8b73d4b1da8ea6e475e2c3e6e51;hb=ac0c66382d313b581c71c21d356fe08746e3fbc0;hp=ae821517f2bfb0152d0ef056e7ce60a61df61925;hpb=44273f19512f96a6e7bd1a4cbcec6c75c93ab488;p=ffmpeg diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c index ae821517f2b..d62c572cb01 100644 --- a/libavcodec/msmpeg4.c +++ b/libavcodec/msmpeg4.c @@ -18,10 +18,15 @@ * * msmpeg4v1 & v2 stuff by Michael Niedermayer */ + +/** + * @file msmpeg4.c + * MSMPEG4 backend for ffmpeg encoder and decoder. + */ + #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" -//#define PRINT_MB /* * You can also call this codec : MPEG4 with a twist ! @@ -48,23 +53,28 @@ #define II_BITRATE 128*1024 #define MBAC_BITRATE 50*1024 -static UINT32 v2_dc_lum_table[512][2]; -static UINT32 v2_dc_chroma_table[512][2]; +#define DEFAULT_INTER_INDEX 3 + +static uint32_t v2_dc_lum_table[512][2]; +static uint32_t v2_dc_chroma_table[512][2]; static inline void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n); static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, - int n, int coded); + int n, int coded, const uint8_t *scantable); static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr); 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); +#ifdef CONFIG_ENCODERS +static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run, int level, int intra); +#endif //CONFIG_ENCODERS +static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64]); +static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]); +static int wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64]); - -extern UINT32 inverse[256]; - #ifdef DEBUG int intra_count = 0; int frame_count = 0; @@ -72,6 +82,10 @@ int frame_count = 0; #include "msmpeg4data.h" +#ifdef CONFIG_ENCODERS //strangely gcc includes this even if its not references +static uint8_t rl_length[NB_RL_TABLES][MAX_LEVEL+1][MAX_RUN+1][2]; +#endif //CONFIG_ENCODERS + #ifdef STATS const char *st_names[ST_NB] = { @@ -156,47 +170,36 @@ static void common_init(MpegEncContext * s) } break; case 4: + case 5: s->y_dc_scale_table= wmv1_y_dc_scale_table; s->c_dc_scale_table= wmv1_c_dc_scale_table; break; } - if(s->msmpeg4_version==4){ - s->intra_scantable = wmv1_scantable[1]; - s->intra_h_scantable= wmv1_scantable[2]; - s->intra_v_scantable= wmv1_scantable[3]; - s->inter_scantable = wmv1_scantable[0]; - }else{ - s->intra_scantable = zigzag_direct; - s->intra_h_scantable= ff_alternate_horizontal_scan; - s->intra_v_scantable= ff_alternate_vertical_scan; - s->inter_scantable = zigzag_direct; + + if(s->msmpeg4_version>=4){ + ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable , wmv1_scantable[1]); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, wmv1_scantable[2]); + ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, wmv1_scantable[3]); + ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable , wmv1_scantable[0]); } + //Note the default tables are set in common_init in mpegvideo.c if(!inited){ - int i; inited=1; init_h263_dc_for_msmpeg4(); - - /* permute for IDCT */ - for(i=0; itable_mv_index = av_malloc(sizeof(UINT16) * 4096); + tab->table_mv_index = av_malloc(sizeof(uint16_t) * 4096); /* mark all entries as not used */ for(i=0;i<4096;i++) tab->table_mv_index[i] = tab->n; @@ -236,6 +239,19 @@ void ff_msmpeg4_encode_init(MpegEncContext *s) init_mv_table(&mv_tables[1]); for(i=0;iac_stats[0][0][level][run][last] + s->ac_stats[0][1][level][run][last]; int intra_luma_count = s->ac_stats[1][0][level][run][last]; int intra_chroma_count= s->ac_stats[1][1][level][run][last]; - + if(s->pict_type==I_TYPE){ - size += intra_luma_count *get_size_of_code(s, &rl_table[ i], last, run, level,1); - chroma_size+= intra_chroma_count*get_size_of_code(s, &rl_table[3+i], last, run, level,1); + size += intra_luma_count *rl_length[i ][level][run][last]; + chroma_size+= intra_chroma_count*rl_length[i+3][level][run][last]; }else{ - size+= intra_luma_count *get_size_of_code(s, &rl_table[ i], last, run, level,1) - +intra_chroma_count*get_size_of_code(s, &rl_table[3+i], last, run, level,1) - +inter_count *get_size_of_code(s, &rl_table[3+i], last, run, level,0); + size+= intra_luma_count *rl_length[i ][level][run][last] + +intra_chroma_count*rl_length[i+3][level][run][last] + +inter_count *rl_length[i+3][level][run][last]; } } + if(last_size == size+chroma_size) break; } } if(sizepict_type, best, s->qscale, s->mb_var_sum, s->mc_mb_var_sum, best_size); @@ -363,10 +381,11 @@ 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<=II_BITRATE && s->pict_type==P_TYPE); + if(s->msmpeg4_version==4) + s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE && s->pict_type==P_TYPE); +//printf("%d %d %d %d %d\n", s->pict_type, s->bit_rate, s->inter_intra_pred, s->width, s->height); if (s->pict_type == I_TYPE) { - s->no_rounding = 1; s->slice_height= s->mb_height/1; put_bits(&s->pb, 5, 0x16 + s->mb_height/s->slice_height); @@ -398,12 +417,6 @@ void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number) put_bits(&s->pb, 1, s->mv_table_index); } - - if(s->flipflop_rounding){ - s->no_rounding ^= 1; - }else{ - s->no_rounding = 0; - } } s->esc3_level_length= 0; @@ -417,20 +430,20 @@ void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number) 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, 5, s->avctx->frame_rate / s->avctx->frame_rate_base); //yes 29.97 -> 29 - put_bits(&s->pb, 11, MIN(s->bit_rate/1024, 2047)); + put_bits(&s->pb, 11, FFMIN(s->bit_rate/1024, 2047)); - if(s->msmpeg4_version<3) - s->flipflop_rounding=0; - else{ - s->flipflop_rounding=1; + if(s->msmpeg4_version>=3) put_bits(&s->pb, 1, s->flipflop_rounding); - } + else + assert(s->flipflop_rounding==0); } +#endif //CONFIG_ENCODERS + /* predict coded block */ -static inline int coded_block_pred(MpegEncContext * s, int n, UINT8 **coded_block_ptr) +static inline int coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr) { int xy, wrap, pred, a, b, c; @@ -456,6 +469,8 @@ static inline int coded_block_pred(MpegEncContext * s, int n, UINT8 **coded_bloc return pred; } +#ifdef CONFIG_ENCODERS + static void msmpeg4_encode_motion(MpegEncContext * s, int mx, int my) { @@ -498,27 +513,8 @@ 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); + if(s->msmpeg4_version < 4){ + ff_mpeg4_clean_buffers(s); } s->first_slice_line = 1; } else { @@ -533,7 +529,7 @@ void msmpeg4_encode_mb(MpegEncContext * s, { int cbp, coded_cbp, i; int pred_x, pred_y; - UINT8 *coded_block; + uint8_t *coded_block; handle_slices(s); @@ -548,6 +544,10 @@ void msmpeg4_encode_mb(MpegEncContext * s, if (s->use_skip_mb_code && (cbp | motion_x | motion_y) == 0) { /* skip macroblock */ put_bits(&s->pb, 1, 1); + s->last_bits++; + s->misc_bits++; + s->skip_count++; + return; } if (s->use_skip_mb_code) @@ -563,7 +563,9 @@ void msmpeg4_encode_mb(MpegEncContext * s, put_bits(&s->pb, cbpy_tab[coded_cbp>>2][1], cbpy_tab[coded_cbp>>2][0]); - + + s->misc_bits += get_bits_diff(s); + h263_pred_motion(s, 0, &pred_x, &pred_y); msmpeg4v2_encode_motion(s, motion_x - pred_x); msmpeg4v2_encode_motion(s, motion_y - pred_y); @@ -572,11 +574,20 @@ void msmpeg4_encode_mb(MpegEncContext * s, table_mb_non_intra[cbp + 64][1], table_mb_non_intra[cbp + 64][0]); + s->misc_bits += get_bits_diff(s); + /* motion vector */ h263_pred_motion(s, 0, &pred_x, &pred_y); msmpeg4_encode_motion(s, motion_x - pred_x, motion_y - pred_y); } + + s->mv_bits += get_bits_diff(s); + + for (i = 0; i < 6; i++) { + msmpeg4_encode_block(s, block[i], i); + } + s->p_tex_bits += get_bits_diff(s); } else { /* compute cbp */ cbp = 0; @@ -632,15 +643,20 @@ void msmpeg4_encode_mb(MpegEncContext * s, put_bits(&s->pb, table_inter_intra[s->h263_aic_dir][1], table_inter_intra[s->h263_aic_dir][0]); } } - } + s->misc_bits += get_bits_diff(s); - for (i = 0; i < 6; i++) { - msmpeg4_encode_block(s, block[i], i); + for (i = 0; i < 6; i++) { + msmpeg4_encode_block(s, block[i], i); + } + s->i_tex_bits += get_bits_diff(s); + s->i_count++; } } +#endif //CONFIG_ENCODERS + /* old ffmpeg msmpeg4v3 mode */ -void ff_old_msmpeg4_dc_scale(MpegEncContext * s) +static void ff_old_msmpeg4_dc_scale(MpegEncContext * s) { if (s->qscale < 5){ s->y_dc_scale = 8; @@ -655,7 +671,7 @@ void ff_old_msmpeg4_dc_scale(MpegEncContext * s) } static inline int msmpeg4v1_pred_dc(MpegEncContext * s, int n, - INT32 **dc_val_ptr) + int32_t **dc_val_ptr) { int i; @@ -679,15 +695,15 @@ static int get_dc(uint8_t *src, int stride, int scale) sum+=src[x + y*stride]; } } - return (sum + (scale>>1))/scale; + return FASTDIV((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) + uint16_t **dc_val_ptr, int *dir_ptr) { int a, b, c, wrap, pred, scale; - INT16 *dc_val; + int16_t *dc_val; /* find prediction */ if (n < 4) { @@ -705,6 +721,10 @@ static inline int msmpeg4_pred_dc(MpegEncContext * s, int n, a = dc_val[ - 1]; b = dc_val[ - 1 - wrap]; c = dc_val[ - wrap]; + + if(s->first_slice_line && (n&2)==0 && s->msmpeg4_version<4){ + b=c=1024; + } /* XXX: the following solution consumes divisions, but it does not necessitate to modify mpegvideo.c. The problem comes from the @@ -739,9 +759,9 @@ static inline int msmpeg4_pred_dc(MpegEncContext * s, int n, b = (b + (8 >> 1)) / 8; c = (c + (8 >> 1)) / 8; } else { - a = (a + (scale >> 1)) / scale; - b = (b + (scale >> 1)) / scale; - c = (c + (scale >> 1)) / scale; + a = FASTDIV((a + (scale >> 1)), scale); + b = FASTDIV((b + (scale >> 1)), scale); + c = FASTDIV((c + (scale >> 1)), scale); } #endif /* XXX: WARNING: they did not choose the same test as MPEG4. This @@ -768,10 +788,10 @@ static inline int msmpeg4_pred_dc(MpegEncContext * s, int n, }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; + dest= s->current_picture.data[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; + dest= s->current_picture.data[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); @@ -834,13 +854,13 @@ static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr int pred; if(s->msmpeg4_version==1){ - INT32 *dc_val; + int32_t *dc_val; pred = msmpeg4v1_pred_dc(s, n, &dc_val); /* update predictor */ *dc_val= level; }else{ - UINT16 *dc_val; + uint16_t *dc_val; pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr); /* update predictor */ @@ -906,7 +926,7 @@ static inline void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int int last_non_zero, sign, slevel; int code, run_diff, dc_pred_dir; const RLTable *rl; - const UINT8 *scantable; + const uint8_t *scantable; if (s->mb_intra) { set_stat(ST_DC); @@ -918,7 +938,7 @@ static inline void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int rl = &rl_table[3 + s->rl_chroma_table_index]; } run_diff = 0; - scantable= s->intra_scantable; + scantable= s->intra_scantable.permutated; set_stat(ST_INTRA_AC); } else { i = 0; @@ -927,15 +947,16 @@ static inline void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int run_diff = 0; else run_diff = 1; - scantable= s->inter_scantable; + scantable= s->inter_scantable.permutated; set_stat(ST_INTER_AC); } /* recalculate block_last_index for M$ wmv1 */ - if(scantable!=zigzag_direct && s->block_last_index[n]>0){ + if(s->msmpeg4_version>=4 && s->block_last_index[n]>0){ for(last_index=63; last_index>=0; last_index--){ if(block[scantable[last_index]]) break; } + s->block_last_index[n]= last_index; }else last_index = s->block_last_index[n]; /* AC coefs */ @@ -952,6 +973,7 @@ static inline void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int sign = 1; level = -level; } + if(level<=MAX_LEVEL && run<=MAX_RUN){ s->ac_stats[s->mb_intra][n>3][level][run][last]++; } @@ -982,7 +1004,7 @@ else /* third escape */ put_bits(&s->pb, 1, 0); put_bits(&s->pb, 1, last); - if(s->msmpeg4_version==4){ + if(s->msmpeg4_version>=4){ if(s->esc3_level_length==0){ s->esc3_level_length=8; s->esc3_run_length= 6; @@ -1021,7 +1043,7 @@ else /****************************************/ /* decoding stuff */ -static VLC mb_non_intra_vlc; +static VLC mb_non_intra_vlc[4]; static VLC mb_intra_vlc; static VLC dc_lum_vlc[2]; static VLC dc_chroma_vlc[2]; @@ -1146,9 +1168,12 @@ int ff_msmpeg4_decode_init(MpegEncContext *s) &mvtab[0][1], 2, 1, &mvtab[0][0], 2, 1); - 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); + for(i=0; i<4; i++){ + init_vlc(&mb_non_intra_vlc[i], MB_NON_INTRA_VLC_BITS, 128, + &wmv2_inter_table[i][0][1], 8, 4, + &wmv2_inter_table[i][0][0], 8, 4); //FIXME name? + } + init_vlc(&mb_intra_vlc, MB_INTRA_VLC_BITS, 64, &table_mb_intra[0][1], 4, 2, &table_mb_intra[0][0], 4, 2); @@ -1164,6 +1189,23 @@ int ff_msmpeg4_decode_init(MpegEncContext *s) &table_inter_intra[0][1], 2, 1, &table_inter_intra[0][0], 2, 1); } + + switch(s->msmpeg4_version){ + case 1: + case 2: + s->decode_mb= msmpeg4v12_decode_mb; + break; + case 3: + case 4: + s->decode_mb= msmpeg4v34_decode_mb; + break; + case 5: + s->decode_mb= wmv2_decode_mb; + break; + } + + s->slice_height= s->mb_height; //to avoid 1/0 if the first frame isnt a keyframe + return 0; } @@ -1184,7 +1226,7 @@ int msmpeg4_decode_picture_header(MpegEncContext * s) #if 0 { int i; -for(i=0; igb.size*8; i++) +for(i=0; igb.size_in_bits; i++) printf("%d", get_bits1(&s->gb)); // get_bits1(&s->gb); printf("END\n"); @@ -1217,6 +1259,10 @@ return -1; } #endif s->qscale = get_bits(&s->gb, 5); + if(s->qscale==0){ + fprintf(stderr, "invalid qscale\n"); + return -1; + } if (s->pict_type == I_TYPE) { code = get_bits(&s->gb, 5); @@ -1267,13 +1313,14 @@ return -1; break; } s->no_rounding = 1; -/* printf("qscale:%d rlc:%d rl:%d dc:%d mbrl:%d slice:%d \n", + if(s->avctx->debug&FF_DEBUG_PICT_INFO) + 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->slice_height);*/ + s->slice_height); } else { switch(s->msmpeg4_version){ case 1: @@ -1313,20 +1360,24 @@ return -1; s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE); break; } -/* printf("skip:%d rl:%d rlc:%d dc:%d mv:%d mbrl:%d qp:%d \n", + + if(s->avctx->debug&FF_DEBUG_PICT_INFO) + 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->qscale);*/ + s->qscale); + if(s->flipflop_rounding){ s->no_rounding ^= 1; }else{ s->no_rounding = 0; } } +//printf("%d %d %d %d %d\n", s->pict_type, s->bit_rate, s->inter_intra_pred, s->width, s->height); s->esc3_level_length= 0; s->esc3_run_length= 0; @@ -1358,7 +1409,8 @@ int msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size) else if(leftflipflop_rounding= 0; - printf("ext header missing, %d left\n", left); + if(s->msmpeg4_version != 2) + printf("ext header missing, %d left\n", left); } else { @@ -1422,10 +1474,12 @@ static int msmpeg4v2_decode_motion(MpegEncContext * s, int pred, int f_code) return pred; sign = get_bits1(&s->gb); shift = f_code - 1; - val = (code - 1) << shift; - if (shift > 0) + val = code; + if (shift) { + val = (val - 1) << shift; val |= get_bits(&s->gb, shift); - val++; + val++; + } if (sign) val = -val; @@ -1438,11 +1492,10 @@ static int msmpeg4v2_decode_motion(MpegEncContext * s, int pred, int f_code) return val; } - -static int msmpeg4v12_decode_mb(MpegEncContext *s, - DCTELEM block[6][64]) +static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) { int cbp, code, i; + if (s->pict_type == P_TYPE) { if (s->use_skip_mb_code) { if (get_bits1(&s->gb)) { @@ -1515,7 +1568,7 @@ static int msmpeg4v12_decode_mb(MpegEncContext *s, } for (i = 0; i < 6; i++) { - if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1) < 0) + if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) { fprintf(stderr,"\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); return -1; @@ -1524,23 +1577,12 @@ static int msmpeg4v12_decode_mb(MpegEncContext *s, return 0; } -int msmpeg4_decode_mb(MpegEncContext *s, - DCTELEM block[6][64]) +static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) { int cbp, code, i; - UINT8 *coded_val; + uint8_t *coded_val; + uint32_t * const mb_type_ptr= &s->current_picture.mb_type[ s->mb_x + s->mb_y*s->mb_stride ]; -#ifdef PRINT_MB -if(s->mb_x==0){ - printf("\n"); - if(s->mb_y==0) printf("\n"); -} -#endif - /* special slice handling */ - handle_slices(s); - - if(s->msmpeg4_version<=2) return msmpeg4v12_decode_mb(s, block); //FIXME export function & call from outside perhaps - if (s->pict_type == P_TYPE) { set_stat(ST_INTER_MB); if (s->use_skip_mb_code) { @@ -1554,14 +1596,13 @@ if(s->mb_x==0){ s->mv[0][0][0] = 0; s->mv[0][0][1] = 0; s->mb_skiped = 1; -#ifdef PRINT_MB -printf("S "); -#endif + *mb_type_ptr = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16; + return 0; } } - code = get_vlc2(&s->gb, mb_non_intra_vlc.table, MB_NON_INTRA_VLC_BITS, 3); + code = get_vlc2(&s->gb, mb_non_intra_vlc[DEFAULT_INTER_INDEX].table, MB_NON_INTRA_VLC_BITS, 3); if (code < 0) return -1; //s->mb_intra = (code & 0x40) ? 0 : 1; @@ -1602,16 +1643,12 @@ printf("S "); s->mv_type = MV_TYPE_16X16; s->mv[0][0][0] = mx; s->mv[0][0][1] = my; -#ifdef PRINT_MB -printf("P "); -#endif + *mb_type_ptr = MB_TYPE_L0 | MB_TYPE_16x16; } else { //printf("I at %d %d %d %06X\n", s->mb_x, s->mb_y, ((cbp&3)? 1 : 0) +((cbp&0x3C)? 2 : 0), show_bits(&s->gb, 24)); set_stat(ST_INTRA_MB); s->ac_pred = get_bits1(&s->gb); -#ifdef PRINT_MB -printf("%c", s->ac_pred ? 'A' : 'I'); -#endif + *mb_type_ptr = MB_TYPE_INTRA; 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); @@ -1623,7 +1660,7 @@ printf("%c", s->ac_pred ? 'A' : 'I'); } for (i = 0; i < 6; i++) { - if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1) < 0) + if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0) { fprintf(stderr,"\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i); return -1; @@ -1634,13 +1671,12 @@ printf("%c", s->ac_pred ? 'A' : 'I'); } //#define ERROR_DETAILS static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, - int n, int coded) + int n, int coded, const uint8_t *scan_table) { 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) { @@ -1650,14 +1686,7 @@ static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, /* 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; @@ -1685,11 +1714,11 @@ static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, } if (s->ac_pred) { if (dc_pred_dir == 0) - scan_table = s->intra_v_scantable; /* left */ + scan_table = s->intra_v_scantable.permutated; /* left */ else - scan_table = s->intra_h_scantable; /* top */ + scan_table = s->intra_h_scantable.permutated; /* top */ } else { - scan_table = s->intra_scantable; + scan_table = s->intra_scantable.permutated; } set_stat(ST_INTRA_AC); rl_vlc= rl->rl_vlc[0]; @@ -1708,7 +1737,8 @@ static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, s->block_last_index[n] = i; return 0; } - scan_table = s->inter_scantable; + if(!scan_table) + scan_table = s->inter_scantable.permutated; set_stat(ST_INTER_AC); rl_vlc= rl->rl_vlc[s->qscale]; } @@ -1859,7 +1889,8 @@ static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, if (i > 62){ i-= 192; if(i&(~63)){ - if(s->error_resilience<0){ + const int left= s->gb.size_in_bits - get_bits_count(&s->gb); + if(((i+192 == 64 && level/qmul==-1) || s->error_resilience<=1) && left>=0){ fprintf(stderr, "ignoring overflow at %d %d\n", s->mb_x, s->mb_y); break; }else{ @@ -1883,7 +1914,7 @@ static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, i = 63; /* XXX: not optimal */ } } - if(s->msmpeg4_version==4 && i>0) i=63; //FIXME/XXX optimize + if(s->msmpeg4_version>=4 && i>0) i=63; //FIXME/XXX optimize s->block_last_index[n] = i; return 0; @@ -1924,14 +1955,14 @@ static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr) } if(s->msmpeg4_version==1){ - INT32 *dc_val; + int32_t *dc_val; pred = msmpeg4v1_pred_dc(s, n, &dc_val); level += pred; /* update predictor */ *dc_val= level; }else{ - UINT16 *dc_val; + uint16_t *dc_val; pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr); level += pred; @@ -1984,3 +2015,9 @@ static int msmpeg4_decode_motion(MpegEncContext * s, *my_ptr = my; return 0; } + +/* cleanest way to support it + * there is too much shared between versions so that we cant have 1 file per version & 1 common + * as allmost everything would be in the common file + */ +#include "wmv2.c"