Commit c442d75c authored by Michael Niedermayer's avatar Michael Niedermayer

trellis quantization for mpeg1

rounding bugfix for mpeg1 (seems this was introduced during the ME changes)

Originally committed as revision 1382 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 9981dfc6
......@@ -66,9 +66,14 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s,
int n);
static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred);
#ifdef CONFIG_ENCODERS
static UINT16 mv_penalty[MAX_FCODE+1][MAX_MV*2+1];
static UINT8 fcode_tab[MAX_MV*2+1];
static uint32_t uni_mpeg1_ac_vlc_bits[64*64*2];
static uint8_t uni_mpeg1_ac_vlc_len [64*64*2];
#endif
static inline int get_bits_diff(MpegEncContext *s){
int bits,ret;
......@@ -118,6 +123,51 @@ static void init_2d_vlc_rl(RLTable *rl)
}
}
static void init_uni_ac_vlc(RLTable *rl, uint32_t *uni_ac_vlc_bits, uint8_t *uni_ac_vlc_len){
int i;
for(i=0; i<128; i++){
int level= i-64;
int run;
for(run=0; run<64; run++){
int len, bits, code;
int alevel= ABS(level);
int sign= (level>>31)&1;
if (alevel > rl->max_level[0][run])
code= 111; /*rl->n*/
else
code= rl->index_run[0][run] + alevel - 1;
if (code < 111 /* rl->n */) {
/* store the vlc & sign at once */
len= mpeg1_vlc[code][1]+1;
bits= (mpeg1_vlc[code][0]<<1) + sign;
} else {
len= mpeg1_vlc[111/*rl->n*/][1]+6;
bits= mpeg1_vlc[111/*rl->n*/][0]<<6;
bits|= run;
if (alevel < 128) {
bits<<=8; len+=8;
bits|= level & 0xff;
} else {
bits<<=16; len+=16;
bits|= level & 0xff;
if (level < 0) {
bits|= 0x8001 + level + 255;
} else {
bits|= level & 0xffff;
}
}
}
uni_ac_vlc_bits[UNI_AC_ENC_INDEX(run, i)]= bits;
uni_ac_vlc_len [UNI_AC_ENC_INDEX(run, i)]= len;
}
}
}
static void put_header(MpegEncContext *s, int header)
{
......@@ -465,12 +515,14 @@ void ff_mpeg1_encode_init(MpegEncContext *s)
done=1;
init_rl(&rl_mpeg1);
for(i=0; i<64; i++)
{
mpeg1_max_level[0][i]= rl_mpeg1.max_level[0][i];
mpeg1_index_run[0][i]= rl_mpeg1.index_run[0][i];
}
init_uni_ac_vlc(&rl_mpeg1, uni_mpeg1_ac_vlc_bits, uni_mpeg1_ac_vlc_len);
/* build unified dc encoding tables */
for(i=-255; i<256; i++)
......@@ -532,6 +584,8 @@ void ff_mpeg1_encode_init(MpegEncContext *s)
s->max_qcoeff= 255;
s->intra_quant_bias= 3<<(QUANT_BIAS_SHIFT-3); //(a + x*3/8)/x
s->inter_quant_bias= 0;
s->intra_ac_vlc_length=
s->inter_ac_vlc_length= uni_mpeg1_ac_vlc_len;
}
static inline void encode_dc(MpegEncContext *s, int diff, int component)
......@@ -602,12 +656,8 @@ static void mpeg1_encode_block(MpegEncContext *s,
sign&=1;
// code = get_rl_index(rl, 0, run, alevel);
if (alevel > mpeg1_max_level[0][run])
code= 111; /*rl->n*/
else
if (alevel <= mpeg1_max_level[0][run]){
code= mpeg1_index_run[0][run] + alevel - 1;
if (code < 111 /* rl->n */) {
/* store the vlc & sign at once */
put_bits(&s->pb, mpeg1_vlc[code][1]+1, (mpeg1_vlc[code][0]<<1) + sign);
} else {
......
......@@ -2780,7 +2780,7 @@ static void encode_picture(MpegEncContext *s, int picture_number)
s->no_rounding=1;
else if(s->flipflop_rounding)
s->no_rounding ^= 1;
}else{
}else if(s->out_format == FMT_H263){
if(s->pict_type==I_TYPE)
s->no_rounding=0;
else if(s->pict_type!=B_TYPE)
......@@ -3307,7 +3307,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
start_i = 1;
last_non_zero = 0;
qmat = s->q_intra_matrix[qscale];
if(s->mpeg_quant)
if(s->mpeg_quant || s->codec_id== CODEC_ID_MPEG1VIDEO)
bias= 1<<(QMAT_SHIFT-1);
length = s->intra_ac_vlc_length;
last_length= s->intra_ac_vlc_last_length;
......@@ -3381,13 +3381,33 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
}else{
unquant_coeff= level*qmul - qadd;
}
} //FIXME else
}else{ //MPEG1
j= s->idct_permutation[ scantable[i + start_i] ]; //FIXME optimize
if(s->mb_intra){
if (level < 0) {
unquant_coeff = (int)((-level) * qscale * s->intra_matrix[j]) >> 3;
unquant_coeff = -((unquant_coeff - 1) | 1);
} else {
unquant_coeff = (int)( level * qscale * s->intra_matrix[j]) >> 3;
unquant_coeff = (unquant_coeff - 1) | 1;
}
}else{
if (level < 0) {
unquant_coeff = ((((-level) << 1) + 1) * qscale * ((int) s->inter_matrix[j])) >> 4;
unquant_coeff = -((unquant_coeff - 1) | 1);
} else {
unquant_coeff = ((( level << 1) + 1) * qscale * ((int) s->inter_matrix[j])) >> 4;
unquant_coeff = (unquant_coeff - 1) | 1;
}
}
unquant_coeff<<= 3;
}
distoration= (unquant_coeff - dct_coeff) * (unquant_coeff - dct_coeff);
level+=64;
if((level&(~127)) == 0){
for(run=0; run<=i - left_limit; run++){
int score= distoration + length[UNI_ENC_INDEX(run, level)]*lambda;
int score= distoration + length[UNI_AC_ENC_INDEX(run, level)]*lambda;
score += score_tab[i-run];
if(score < best_score){
......@@ -3400,7 +3420,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
if(s->out_format == FMT_H263){
for(run=0; run<=i - left_limit; run++){
int score= distoration + last_length[UNI_ENC_INDEX(run, level)]*lambda;
int score= distoration + last_length[UNI_AC_ENC_INDEX(run, level)]*lambda;
score += score_tab[i-run];
if(score < last_score){
last_score= score;
......@@ -3452,11 +3472,12 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
if(s->out_format != FMT_H263){
last_score= 256*256*256*120;
for(i=0; i<=last_non_zero - start_i + 1; i++){
for(i= left_limit; i<=last_non_zero - start_i + 1; i++){
int score= score_tab[i];
if(i) score += lambda*2; //FIXME exacter?
if(score < last_score){
last_score= score;
if(i) last_score += lambda*2; //FIXME exacter?
last_i= i;
last_level= level_tab[i];
last_run= run_tab[i];
......
......@@ -312,7 +312,7 @@ typedef struct MpegEncContext {
uint8_t *intra_ac_vlc_last_length;
uint8_t *inter_ac_vlc_length;
uint8_t *inter_ac_vlc_last_length;
#define UNI_ENC_INDEX(run,level) ((run)*128 + (level))
#define UNI_AC_ENC_INDEX(run,level) ((run)*128 + (level))
/* precomputed matrix (combine qscale and DCT renorm) */
int __align8 q_intra_matrix[32][64];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment