1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

optimizing mpeg4_encode_block(), generates allso slightly shorter bitstream as some codes can be represented as esc1 and esc2 and esc2 is shorter for a few of them

Originally committed as revision 911 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Michael Niedermayer 2002-09-07 00:16:30 +00:00
parent 6ebd933b8f
commit 3db48188df

View File

@ -48,7 +48,7 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block,
int n); int n);
static void h263_encode_motion(MpegEncContext * s, int val, int fcode); static void h263_encode_motion(MpegEncContext * s, int val, int fcode);
static void h263p_encode_umotion(MpegEncContext * s, int val); static void h263p_encode_umotion(MpegEncContext * s, int val);
static void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block,
int n, int dc, UINT8 *scan_table, int n, int dc, UINT8 *scan_table,
PutBitContext *dc_pb, PutBitContext *ac_pb); PutBitContext *dc_pb, PutBitContext *ac_pb);
static int h263_decode_motion(MpegEncContext * s, int pred, int fcode); static int h263_decode_motion(MpegEncContext * s, int pred, int fcode);
@ -71,6 +71,22 @@ static UINT8 umv_fcode_tab[MAX_MV*2+1];
static UINT16 uni_DCtab_lum [512][2]; static UINT16 uni_DCtab_lum [512][2];
static UINT16 uni_DCtab_chrom[512][2]; static UINT16 uni_DCtab_chrom[512][2];
static UINT32 uni_mpeg4_intra_rl_bits[64*64*2*2];
static UINT8 uni_mpeg4_intra_rl_len [64*64*2*2];
static UINT32 uni_mpeg4_inter_rl_bits[64*64*2*2];
static UINT8 uni_mpeg4_inter_rl_len [64*64*2*2];
#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128 + (run)*256 + (level))
//#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run) + (level)*64)
/* mpeg4
inter
max level: 24/6
max run: 53/63
intra
max level: 53/16
max run: 29/41
*/
int h263_get_picture_format(int width, int height) int h263_get_picture_format(int width, int height)
{ {
@ -1085,6 +1101,91 @@ static void init_uni_dc_tab(void)
} }
} }
static void init_uni_mpeg4_rl_tab(RLTable *rl, UINT32 *bits_tab, UINT8 *len_tab){
int slevel, run, last;
assert(MAX_LEVEL >= 64);
assert(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_MPEG4_ENC_INDEX(last, run, slevel+64);
int level= slevel < 0 ? -slevel : slevel;
int sign= slevel < 0 ? 1 : 0;
int bits, len, code;
int level1, run1;
len_tab[index]= 100;
/* ESC0 */
code= get_rl_index(rl, last, run, level);
bits= rl->table_vlc[code][0];
len= rl->table_vlc[code][1];
bits=bits*2+sign; len++;
if(code!=rl->n && len < len_tab[index]){
bits_tab[index]= bits;
len_tab [index]= len;
}
#if 1
/* ESC1 */
bits= rl->table_vlc[rl->n][0];
len= rl->table_vlc[rl->n][1];
bits=bits*2; len++; //esc1
level1= level - rl->max_level[last][run];
if(level1>0){
code= get_rl_index(rl, last, run, level1);
bits<<= rl->table_vlc[code][1];
len += rl->table_vlc[code][1];
bits += rl->table_vlc[code][0];
bits=bits*2+sign; len++;
if(code!=rl->n && len < len_tab[index]){
bits_tab[index]= bits;
len_tab [index]= len;
}
}
#endif
#if 1
/* ESC2 */
bits= rl->table_vlc[rl->n][0];
len= rl->table_vlc[rl->n][1];
bits=bits*4+2; len+=2; //esc2
run1 = run - rl->max_run[last][level] - 1;
if(run1>=0){
code= get_rl_index(rl, last, run1, level);
bits<<= rl->table_vlc[code][1];
len += rl->table_vlc[code][1];
bits += rl->table_vlc[code][0];
bits=bits*2+sign; len++;
if(code!=rl->n && len < len_tab[index]){
bits_tab[index]= bits;
len_tab [index]= len;
}
}
#endif
/* ESC3 */
bits= rl->table_vlc[rl->n][0];
len = rl->table_vlc[rl->n][1];
bits=bits*4+3; len+=2; //esc3
bits=bits*2+last; len++;
bits=bits*64+run; len+=6;
bits=bits*2+1; len++; //marker
bits=bits*4096+(slevel&0xfff); len+=12;
bits=bits*2+1; len++; //marker
if(len < len_tab[index]){
bits_tab[index]= bits;
len_tab [index]= len;
}
}
}
}
}
void h263_encode_init(MpegEncContext *s) void h263_encode_init(MpegEncContext *s)
{ {
static int done = 0; static int done = 0;
@ -1098,6 +1199,9 @@ void h263_encode_init(MpegEncContext *s)
init_rl(&rl_intra); init_rl(&rl_intra);
init_rl(&rl_intra_aic); init_rl(&rl_intra_aic);
init_uni_mpeg4_rl_tab(&rl_intra, uni_mpeg4_intra_rl_bits, uni_mpeg4_intra_rl_len);
init_uni_mpeg4_rl_tab(&rl_inter, uni_mpeg4_inter_rl_bits, uni_mpeg4_inter_rl_len);
init_mv_penalty_and_fcode(s); init_mv_penalty_and_fcode(s);
} }
s->mv_penalty= mv_penalty; //FIXME exact table for msmpeg4 & h263p s->mv_penalty= mv_penalty; //FIXME exact table for msmpeg4 & h263p
@ -1529,34 +1633,69 @@ static inline void mpeg4_encode_dc(PutBitContext * s, int level, int n)
#endif #endif
} }
static void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n, int intra_dc, static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n, int intra_dc,
UINT8 *scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb) UINT8 *scan_table, PutBitContext *dc_pb, PutBitContext *ac_pb)
{ {
int level, run, last, i, j, last_index, last_non_zero, sign, slevel; int last, i, last_non_zero, sign;
int code; int code;
const RLTable *rl; const RLTable *rl;
UINT32 *bits_tab;
UINT8 *len_tab;
const int last_index = s->block_last_index[n];
if (s->mb_intra) { if (s->mb_intra) { //Note gcc (3.2.1 at least) will optimize this away
/* mpeg4 based DC predictor */ /* mpeg4 based DC predictor */
mpeg4_encode_dc(dc_pb, intra_dc, n); mpeg4_encode_dc(dc_pb, intra_dc, n);
if(last_index<1) return;
i = 1; i = 1;
rl = &rl_intra; rl = &rl_intra;
bits_tab= uni_mpeg4_intra_rl_bits;
len_tab = uni_mpeg4_intra_rl_len;
} else { } else {
if(last_index<0) return;
i = 0; i = 0;
rl = &rl_inter; rl = &rl_inter;
bits_tab= uni_mpeg4_inter_rl_bits;
len_tab = uni_mpeg4_inter_rl_len;
} }
/* AC coefs */ /* AC coefs */
last_index = s->block_last_index[n];
last_non_zero = i - 1; last_non_zero = i - 1;
for (; i <= last_index; i++) { #if 1
j = scan_table[i]; for (; i < last_index; i++) {
level = block[j]; int level = block[ scan_table[i] ];
if (level) { if (level) {
run = i - last_non_zero - 1; int run = i - last_non_zero - 1;
level+=64;
if((level&(~127)) == 0){
const int index= UNI_MPEG4_ENC_INDEX(0, run, level);
put_bits(ac_pb, len_tab[index], bits_tab[index]);
}else{ //ESC3
put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(0<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1);
}
last_non_zero = i;
}
}
/*if(i<=last_index)*/{
int level = block[ scan_table[i] ];
int run = i - last_non_zero - 1;
level+=64;
if((level&(~127)) == 0){
const int index= UNI_MPEG4_ENC_INDEX(1, run, level);
put_bits(ac_pb, len_tab[index], bits_tab[index]);
}else{ //ESC3
put_bits(ac_pb, 7+2+1+6+1+12+1, (3<<23)+(3<<21)+(1<<20)+(run<<14)+(1<<13)+(((level-64)&0xfff)<<1)+1);
}
}
#else
for (; i <= last_index; i++) {
const int slevel = block[ scan_table[i] ];
if (slevel) {
int level;
int run = i - last_non_zero - 1;
last = (i == last_index); last = (i == last_index);
sign = 0; sign = 0;
slevel = level; level = slevel;
if (level < 0) { if (level < 0) {
sign = 1; sign = 1;
level = -level; level = -level;
@ -1605,6 +1744,7 @@ static void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n, int i
last_non_zero = i; last_non_zero = i;
} }
} }
#endif
} }
@ -3831,7 +3971,7 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
printf("low_delay flag set, but shouldnt, clearing it\n"); printf("low_delay flag set, but shouldnt, clearing it\n");
s->low_delay=0; s->low_delay=0;
} }
// printf("pic: %d, qpel:%d\n", s->pict_type, s->quarter_sample); // printf("pic: %d, qpel:%d part:%d resync:%d\n", s->pict_type, s->quarter_sample, s->data_partitioning, s->resync_marker);
time_incr=0; time_incr=0;
while (get_bits1(&s->gb) != 0) while (get_bits1(&s->gb) != 0)
time_incr++; time_incr++;
@ -3935,11 +4075,10 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
if (s->pict_type == B_TYPE) { if (s->pict_type == B_TYPE) {
s->b_code = get_bits(&s->gb, 3); s->b_code = get_bits(&s->gb, 3);
//printf("b-code %d\n", s->b_code);
}else }else
s->b_code=1; s->b_code=1;
//printf("quant:%d fcode:%d bcode:%d type:%d\n", s->qscale, s->f_code, s->b_code, s->pict_type); //printf("quant:%d fcode:%d bcode:%d type:%d size:%d\n", s->qscale, s->f_code, s->b_code, s->pict_type, s->gb.size);
if(!s->scalability){ if(!s->scalability){
if (s->shape!=RECT_SHAPE && s->pict_type!=I_TYPE) { if (s->shape!=RECT_SHAPE && s->pict_type!=I_TYPE) {
skip_bits1(&s->gb); // vop shape coding type skip_bits1(&s->gb); // vop shape coding type
@ -3962,7 +4101,6 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
} }
s->picture_number++; // better than pic number==0 allways ;) s->picture_number++; // better than pic number==0 allways ;)
//printf("done\n");
s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; //FIXME add short header support s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table; //FIXME add short header support
s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table; s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;