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:
parent
6ebd933b8f
commit
3db48188df
@ -48,7 +48,7 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block,
|
||||
int n);
|
||||
static void h263_encode_motion(MpegEncContext * s, int val, int fcode);
|
||||
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,
|
||||
PutBitContext *dc_pb, PutBitContext *ac_pb);
|
||||
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_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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
static int done = 0;
|
||||
@ -1098,6 +1199,9 @@ void h263_encode_init(MpegEncContext *s)
|
||||
init_rl(&rl_intra);
|
||||
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);
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int level, run, last, i, j, last_index, last_non_zero, sign, slevel;
|
||||
int last, i, last_non_zero, sign;
|
||||
int code;
|
||||
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_encode_dc(dc_pb, intra_dc, n);
|
||||
if(last_index<1) return;
|
||||
i = 1;
|
||||
rl = &rl_intra;
|
||||
bits_tab= uni_mpeg4_intra_rl_bits;
|
||||
len_tab = uni_mpeg4_intra_rl_len;
|
||||
} else {
|
||||
if(last_index<0) return;
|
||||
i = 0;
|
||||
rl = &rl_inter;
|
||||
bits_tab= uni_mpeg4_inter_rl_bits;
|
||||
len_tab = uni_mpeg4_inter_rl_len;
|
||||
}
|
||||
|
||||
/* AC coefs */
|
||||
last_index = s->block_last_index[n];
|
||||
last_non_zero = i - 1;
|
||||
for (; i <= last_index; i++) {
|
||||
j = scan_table[i];
|
||||
level = block[j];
|
||||
#if 1
|
||||
for (; i < last_index; i++) {
|
||||
int level = block[ scan_table[i] ];
|
||||
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);
|
||||
sign = 0;
|
||||
slevel = level;
|
||||
level = slevel;
|
||||
if (level < 0) {
|
||||
sign = 1;
|
||||
level = -level;
|
||||
@ -1605,6 +1744,7 @@ static void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n, int 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");
|
||||
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;
|
||||
while (get_bits1(&s->gb) != 0)
|
||||
time_incr++;
|
||||
@ -3935,11 +4075,10 @@ int mpeg4_decode_picture_header(MpegEncContext * s)
|
||||
|
||||
if (s->pict_type == B_TYPE) {
|
||||
s->b_code = get_bits(&s->gb, 3);
|
||||
//printf("b-code %d\n", s->b_code);
|
||||
}else
|
||||
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->shape!=RECT_SHAPE && s->pict_type!=I_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 ;)
|
||||
//printf("done\n");
|
||||
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user