mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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
This commit is contained in:
parent
9981dfc662
commit
c442d75c6e
@ -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];
|
||||
|
Loading…
Reference in New Issue
Block a user