comparison mpegvideo.c @ 945:463f7260b155 libavcodec

trellis quantization
author michaelni
date Tue, 31 Dec 2002 17:23:56 +0000
parents caa77cd960c0
children 4f522c9e6099
comparison
equal deleted inserted replaced
944:927c246f1f6d 945:463f7260b155
39 DCTELEM *block, int n, int qscale); 39 DCTELEM *block, int n, int qscale);
40 static void dct_unquantize_h263_c(MpegEncContext *s, 40 static void dct_unquantize_h263_c(MpegEncContext *s,
41 DCTELEM *block, int n, int qscale); 41 DCTELEM *block, int n, int qscale);
42 static void draw_edges_c(UINT8 *buf, int wrap, int width, int height, int w); 42 static void draw_edges_c(UINT8 *buf, int wrap, int width, int height, int w);
43 static int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow); 43 static int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
44 static int dct_quantize_trellis_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
44 45
45 void (*draw_edges)(UINT8 *buf, int wrap, int width, int height, int w)= draw_edges_c; 46 void (*draw_edges)(UINT8 *buf, int wrap, int width, int height, int w)= draw_edges_c;
46 47
47 48
48 /* enable all paranoid tests for rounding, overflows, etc... */ 49 /* enable all paranoid tests for rounding, overflows, etc... */
120 /* We can safely suppose that 16 <= quant_matrix[i] <= 255 121 /* We can safely suppose that 16 <= quant_matrix[i] <= 255
121 So 16 <= qscale * quant_matrix[i] <= 7905 122 So 16 <= qscale * quant_matrix[i] <= 7905
122 so (1<<19) / 16 >= (1<<19) / (qscale * quant_matrix[i]) >= (1<<19) / 7905 123 so (1<<19) / 16 >= (1<<19) / (qscale * quant_matrix[i]) >= (1<<19) / 7905
123 so 32768 >= (1<<19) / (qscale * quant_matrix[i]) >= 67 124 so 32768 >= (1<<19) / (qscale * quant_matrix[i]) >= 67
124 */ 125 */
125 qmat [qscale][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[i]); 126 qmat[qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT) / (qscale * quant_matrix[j]));
127 // qmat [qscale][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[i]);
126 qmat16[qscale][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[j]); 128 qmat16[qscale][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[j]);
127 129
128 if(qmat16[qscale][i]==0 || qmat16[qscale][i]==128*256) qmat16[qscale][i]=128*256-1; 130 if(qmat16[qscale][i]==0 || qmat16[qscale][i]==128*256) qmat16[qscale][i]=128*256-1;
129 qmat16_bias[qscale][i]= ROUNDED_DIV(bias<<(16-QUANT_BIAS_SHIFT), qmat16[qscale][i]); 131 qmat16_bias[qscale][i]= ROUNDED_DIV(bias<<(16-QUANT_BIAS_SHIFT), qmat16[qscale][i]);
130 } 132 }
225 MPV_common_init_armv4l(s); 227 MPV_common_init_armv4l(s);
226 #endif 228 #endif
227 #ifdef ARCH_POWERPC 229 #ifdef ARCH_POWERPC
228 MPV_common_init_ppc(s); 230 MPV_common_init_ppc(s);
229 #endif 231 #endif
232
233 if(s->flags&CODEC_FLAG_TRELLIS_QUANT){
234 s->dct_quantize= dct_quantize_trellis_c; //move before MPV_common_init_*
235 }
230 236
231 switch(s->idct_permutation_type){ 237 switch(s->idct_permutation_type){
232 case FF_NO_IDCT_PERM: 238 case FF_NO_IDCT_PERM:
233 for(i=0; i<64; i++) 239 for(i=0; i<64; i++)
234 s->idct_permutation[i]= i; 240 s->idct_permutation[i]= i;
3251 s->ptr_lastgob = pbBufPtr(&s->pb); 3257 s->ptr_lastgob = pbBufPtr(&s->pb);
3252 //fprintf(stderr,"\nGOB: %2d size: %d (last)", s->gob_number, pdif); 3258 //fprintf(stderr,"\nGOB: %2d size: %d (last)", s->gob_number, pdif);
3253 } 3259 }
3254 } 3260 }
3255 3261
3262 static int dct_quantize_trellis_c(MpegEncContext *s,
3263 DCTELEM *block, int n,
3264 int qscale, int *overflow){
3265 const int *qmat;
3266 const UINT8 *scantable= s->intra_scantable.scantable;
3267 int max=0;
3268 unsigned int threshold1, threshold2;
3269 int bias=0;
3270 int run_tab[65];
3271 int last_run[65];
3272 int level_tab[65];
3273 int last_level[65];
3274 int score_tab[65];
3275 int last_score[65];
3276 int coeff[4][64];
3277 int coeff_count[64];
3278 int lambda, qmul, qadd, start_i, best_i, best_score, last_non_zero, i;
3279 const int esc_length= s->ac_esc_length;
3280 uint8_t * length;
3281 uint8_t * last_length;
3282
3283 s->fdct (block);
3284
3285 qmul= qscale*16;
3286 qadd= ((qscale-1)|1)*8;
3287
3288 if (s->mb_intra) {
3289 int q;
3290 if (!s->h263_aic) {
3291 if (n < 4)
3292 q = s->y_dc_scale;
3293 else
3294 q = s->c_dc_scale;
3295 q = q << 3;
3296 } else{
3297 /* For AIC we skip quant/dequant of INTRADC */
3298 q = 1 << 3;
3299 qadd=0;
3300 }
3301
3302 /* note: block[0] is assumed to be positive */
3303 block[0] = (block[0] + (q >> 1)) / q;
3304 start_i = 1;
3305 last_non_zero = 0;
3306 qmat = s->q_intra_matrix[qscale];
3307 if(s->mpeg_quant)
3308 bias= 1<<(QMAT_SHIFT-1);
3309 length = s->intra_ac_vlc_length;
3310 last_length= s->intra_ac_vlc_last_length;
3311 } else {
3312 start_i = 0;
3313 last_non_zero = -1;
3314 qmat = s->q_inter_matrix[qscale];
3315 length = s->inter_ac_vlc_length;
3316 last_length= s->inter_ac_vlc_last_length;
3317 }
3318
3319 threshold1= (1<<QMAT_SHIFT) - bias - 1;
3320 threshold2= (threshold1<<1);
3321 //printf("%d %d %d\n", qmat[1], QMAT_SHIFT, qscale);
3322 for(i=start_i; i<64; i++) {
3323 const int j = scantable[i];
3324 const int k= i-start_i;
3325 int level = block[j];
3326 level = level * qmat[j];
3327
3328 // if( bias+level >= (1<<(QMAT_SHIFT - 3))
3329 // || bias-level >= (1<<(QMAT_SHIFT - 3))){
3330 if(((unsigned)(level+threshold1))>threshold2){
3331 if(level>0){
3332 level= (bias + level)>>QMAT_SHIFT;
3333 coeff[0][k]= level;
3334 coeff[1][k]= level-1;
3335 coeff[2][k]= level-2;
3336 coeff[3][k]= level-3;
3337 coeff_count[k]= FFMIN(level, 4);
3338 }else{
3339 level= (bias - level)>>QMAT_SHIFT;
3340 coeff[0][k]= -level;
3341 coeff[1][k]= -level+1;
3342 coeff[2][k]= -level+2;
3343 coeff[3][k]= -level+3;
3344 coeff_count[k]= FFMIN(level, 4);
3345 }
3346 max |=level;
3347 last_non_zero = i;
3348 }else{
3349 if(level < 0)
3350 coeff[0][k]= -1;
3351 else
3352 coeff[0][k]= 1;
3353 coeff_count[k]= 1;
3354 }
3355 }
3356
3357 *overflow= s->max_qcoeff < max; //overflow might have happend
3358
3359 if(last_non_zero < start_i){
3360 memset(block + start_i, 0, (64-start_i)*sizeof(DCTELEM));
3361 return last_non_zero;
3362 }
3363
3364 lambda= (qscale*qscale*64*82 + 50)/100; //FIXME finetune
3365
3366 score_tab[0]=
3367 last_score[0]= 0;
3368 //printf("qscale:%d\n", qscale);
3369 for(i=0; i<=last_non_zero - start_i; i++){
3370 int level_index, run, j;
3371 const int dct_coeff= block[ scantable[i + start_i] ];
3372 const int zero_distoration= dct_coeff*dct_coeff;
3373 int best_score=256*256*256*120, best_last_score= 256*256*256*120;
3374
3375 //printf("%2d %5d ", i, dct_coeff);
3376
3377 for(level_index=0; level_index < coeff_count[i]; level_index++){
3378 int distoration;
3379 int level= coeff[level_index][i];
3380 int unquant_coeff;
3381
3382 assert(level);
3383
3384 if(s->out_format == FMT_H263){
3385 if(level>0){
3386 unquant_coeff= level*qmul + qadd;
3387 }else{
3388 unquant_coeff= level*qmul - qadd;
3389 }
3390 } //FIXME else
3391 //printf("(%d %d) ", level, unquant_coeff);
3392 distoration= (unquant_coeff - dct_coeff) * (unquant_coeff - dct_coeff);
3393
3394 level+=64;
3395 if((level&(~127)) == 0){
3396 for(run=0; run<=i; run++){
3397 int score= distoration + length[UNI_ENC_INDEX(run, level)]*lambda;
3398 score += score_tab[i-run];
3399
3400 if(score < best_score){
3401 best_score=
3402 score_tab[i+1]= score;
3403 run_tab[i+1]= run;
3404 level_tab[i+1]= level-64;
3405 }
3406 }
3407
3408 if(s->out_format == FMT_H263){
3409 for(run=0; run<=i; run++){
3410 int score= distoration + last_length[UNI_ENC_INDEX(run, level)]*lambda;
3411 score += score_tab[i-run];
3412 if(score < best_last_score){
3413 best_last_score=
3414 last_score[i+1]= score;
3415 last_run[i+1]= run;
3416 last_level[i+1]= level-64;
3417 }
3418 }
3419 }
3420 }else{
3421 distoration += esc_length*lambda;
3422 for(run=0; run<=i; run++){
3423 int score= distoration + score_tab[i-run];
3424
3425 if(score < best_score){
3426 best_score=
3427 score_tab[i+1]= score;
3428 run_tab[i+1]= run;
3429 level_tab[i+1]= level-64;
3430 }
3431 }
3432
3433 if(s->out_format == FMT_H263){
3434 for(run=0; run<=i; run++){
3435 int score= distoration + score_tab[i-run];
3436 if(score < best_last_score){
3437 best_last_score=
3438 last_score[i+1]= score;
3439 last_run[i+1]= run;
3440 last_level[i+1]= level-64;
3441 }
3442 }
3443 }
3444 }
3445 }
3446
3447 for(j=0; j<=i; j++){
3448 score_tab[j] += zero_distoration;
3449 // printf("%6d ", score_tab[j]);
3450 }
3451 // printf("%6d ", score_tab[j]);
3452
3453 // printf("last: ");
3454 if(s->out_format == FMT_H263){
3455 for(j=0; j<=i; j++){
3456 last_score[j] += zero_distoration;
3457 // printf("%6d ", last_score[j]);
3458 }
3459 // printf("%6d ", last_score[j]);
3460 }
3461 // printf("\n");
3462 }
3463
3464 if(s->out_format != FMT_H263){
3465 for(i=0; i<=last_non_zero - start_i + 1; i++){
3466 last_score[i]= score_tab[i];
3467 if(i) last_score[i] += lambda*2; //FIXME exacter?
3468 last_run[i]= run_tab[i];
3469 last_level[i]= level_tab[i];
3470 }
3471 }
3472
3473 //FIXME add some cbp penalty
3474 best_i= 0;
3475 best_score= 256*256*256*120;
3476 for(i=0; i<=last_non_zero - start_i + 1; i++){
3477 int score= last_score[i];
3478 if(score < best_score){
3479 best_score= score;
3480 best_i= i;
3481 }
3482 }
3483
3484 last_non_zero= best_i - 1 + start_i;
3485 memset(block + start_i, 0, (64-start_i)*sizeof(DCTELEM));
3486
3487 if(last_non_zero < start_i)
3488 return last_non_zero;
3489
3490 i= best_i;
3491 //printf("%d %d %d %d %d\n", last_level[i], i, start_i, last_non_zero, best_score);
3492 assert(last_level[i]);
3493 //FIXME use permutated scantable
3494 block[ s->idct_permutation[ scantable[last_non_zero] ] ]= last_level[i];
3495 i -= last_run[i] + 1;
3496
3497 for(;i>0 ; i -= run_tab[i] + 1){
3498 const int j= s->idct_permutation[ scantable[i - 1 + start_i] ];
3499
3500 block[j]= level_tab[i];
3501 assert(block[j]);
3502 }
3503
3504 return last_non_zero;
3505 }
3506
3256 static int dct_quantize_c(MpegEncContext *s, 3507 static int dct_quantize_c(MpegEncContext *s,
3257 DCTELEM *block, int n, 3508 DCTELEM *block, int n,
3258 int qscale, int *overflow) 3509 int qscale, int *overflow)
3259 { 3510 {
3260 int i, j, level, last_non_zero, q; 3511 int i, j, level, last_non_zero, q;