Fixes ticket3143 Signed-off-by: Michael Niedermayer <michaelni@gmx.at>tags/n2.2-rc1
| @@ -32,6 +32,9 @@ | |||
| #include "h263.h" | |||
| #include "h261.h" | |||
| static uint8_t uni_h261_rl_len [64*64*2*2]; | |||
| #define UNI_ENC_INDEX(last,run,level) ((last)*128*64 + (run)*128 + (level)) | |||
| int ff_h261_get_picture_format(int width, int height) | |||
| { | |||
| // QCIF | |||
| @@ -313,6 +316,47 @@ void ff_h261_encode_mb(MpegEncContext *s, int16_t block[6][64], | |||
| } | |||
| } | |||
| static av_cold void init_uni_h261_rl_tab(RLTable *rl, uint32_t *bits_tab, | |||
| uint8_t *len_tab) | |||
| { | |||
| int slevel, run, last; | |||
| av_assert0(MAX_LEVEL >= 64); | |||
| av_assert0(MAX_RUN >= 63); | |||
| for(slevel=-64; slevel<64; slevel++){ | |||
| if(slevel==0) continue; | |||
| for(run=0; run<64; run++){ | |||
| for(last=0; last<=1; last++){ | |||
| const int index= UNI_ENC_INDEX(last, run, slevel+64); | |||
| int level= slevel < 0 ? -slevel : slevel; | |||
| int sign= slevel < 0 ? 1 : 0; | |||
| int bits, len, code; | |||
| len_tab[index]= 100; | |||
| /* ESC0 */ | |||
| code= get_rl_index(rl, 0, run, level); | |||
| len= rl->table_vlc[code][1] + 1; | |||
| if(last) | |||
| len += 2; | |||
| if(code!=rl->n && len < len_tab[index]){ | |||
| len_tab [index]= len; | |||
| } | |||
| /* ESC */ | |||
| len = rl->table_vlc[rl->n][1]; | |||
| if(last) | |||
| len += 2; | |||
| if(len < len_tab[index]){ | |||
| len_tab [index]= len; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| av_cold void ff_h261_encode_init(MpegEncContext *s) | |||
| { | |||
| ff_h261_common_init(); | |||
| @@ -321,6 +365,12 @@ av_cold void ff_h261_encode_init(MpegEncContext *s) | |||
| s->max_qcoeff = 127; | |||
| s->y_dc_scale_table = | |||
| s->c_dc_scale_table = ff_mpeg1_dc_scale_table; | |||
| s->ac_esc_length = 6+6+8; | |||
| init_uni_h261_rl_tab(&ff_h261_rl_tcoeff, NULL, uni_h261_rl_len); | |||
| s->intra_ac_vlc_length = s->inter_ac_vlc_length = uni_h261_rl_len; | |||
| s->intra_ac_vlc_last_length = s->inter_ac_vlc_last_length = uni_h261_rl_len + 128*64; | |||
| } | |||
| FF_MPV_GENERIC_CLASS(h261) | |||
| @@ -3602,7 +3602,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s, | |||
| av_assert2(level); | |||
| if(s->out_format == FMT_H263){ | |||
| if(s->out_format == FMT_H263 || s->out_format == FMT_H261){ | |||
| unquant_coeff= alevel*qmul + qadd; | |||
| }else{ //MPEG1 | |||
| j= s->dsp.idct_permutation[ scantable[i] ]; //FIXME optimize | |||
| @@ -3631,7 +3631,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s, | |||
| } | |||
| } | |||
| if(s->out_format == FMT_H263){ | |||
| if(s->out_format == FMT_H263 || s->out_format == FMT_H261){ | |||
| for(j=survivor_count-1; j>=0; j--){ | |||
| int run= i - survivor[j]; | |||
| int score= distortion + last_length[UNI_AC_ENC_INDEX(run, level)]*lambda; | |||
| @@ -3657,7 +3657,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s, | |||
| } | |||
| } | |||
| if(s->out_format == FMT_H263){ | |||
| if(s->out_format == FMT_H263 || s->out_format == FMT_H261){ | |||
| for(j=survivor_count-1; j>=0; j--){ | |||
| int run= i - survivor[j]; | |||
| int score= distortion + score_tab[i-run]; | |||
| @@ -3690,7 +3690,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s, | |||
| survivor[ survivor_count++ ]= i+1; | |||
| } | |||
| if(s->out_format != FMT_H263){ | |||
| if(s->out_format != FMT_H263 && s->out_format != FMT_H261){ | |||
| last_score= 256*256*256*120; | |||
| for(i= survivor[0]; i<=last_non_zero + 1; i++){ | |||
| int score= score_tab[i]; | |||
| @@ -3723,7 +3723,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s, | |||
| int alevel= FFABS(level); | |||
| int unquant_coeff, score, distortion; | |||
| if(s->out_format == FMT_H263){ | |||
| if(s->out_format == FMT_H263 || s->out_format == FMT_H261){ | |||
| unquant_coeff= (alevel*qmul + qadd)>>3; | |||
| }else{ //MPEG1 | |||
| unquant_coeff = ((( alevel << 1) + 1) * qscale * ((int) s->inter_matrix[0])) >> 4; | |||