comparison snow.c @ 3051:c0fde3eb7784 libavcodec

obmc-aware 4mv
author lorenm
date Tue, 17 Jan 2006 08:27:39 +0000
parents 0b546eab515d
children 2991dc513726
comparison
equal deleted inserted replaced
3050:61e47d203191 3051:c0fde3eb7784
3045 *b= backup; 3045 *b= backup;
3046 3046
3047 return clip(((ab<<6) + aa/2)/aa, 0, 255); //FIXME we shouldnt need cliping 3047 return clip(((ab<<6) + aa/2)/aa, 0, 255); //FIXME we shouldnt need cliping
3048 } 3048 }
3049 3049
3050 static inline int get_block_bits(SnowContext *s, int x, int y, int w){
3051 const int b_stride = s->b_width << s->block_max_depth;
3052 const int b_height = s->b_height<< s->block_max_depth;
3053 int index= x + y*b_stride;
3054 BlockNode *b = &s->block[index];
3055 BlockNode *left = x ? &s->block[index-1] : &null_block;
3056 BlockNode *top = y ? &s->block[index-b_stride] : &null_block;
3057 BlockNode *tl = y && x ? &s->block[index-b_stride-1] : left;
3058 BlockNode *tr = y && x+w<b_stride ? &s->block[index-b_stride+w] : tl;
3059 int dmx, dmy;
3060 // int mx_context= av_log2(2*ABS(left->mx - top->mx));
3061 // int my_context= av_log2(2*ABS(left->my - top->my));
3062
3063 if(x<0 || x>=b_stride || y>=b_height)
3064 return 0;
3065 dmx= b->mx - mid_pred(left->mx, top->mx, tr->mx);
3066 dmy= b->my - mid_pred(left->my, top->my, tr->my);
3067 /*
3068 1 0 0
3069 01X 1-2 1
3070 001XX 3-6 2-3
3071 0001XXX 7-14 4-7
3072 00001XXXX 15-30 8-15
3073 */
3074 //FIXME try accurate rate
3075 //FIXME intra and inter predictors if surrounding blocks arent the same type
3076 if(b->type & BLOCK_INTRA){
3077 return 3+2*( av_log2(2*ABS(left->color[0] - b->color[0]))
3078 + av_log2(2*ABS(left->color[1] - b->color[1]))
3079 + av_log2(2*ABS(left->color[2] - b->color[2])));
3080 }else
3081 return 2*(1 + av_log2(2*ABS(dmx))
3082 + av_log2(2*ABS(dmy))); //FIXME kill the 2* can be merged in lambda
3083 }
3084
3050 static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, const uint8_t *obmc_edged){ 3085 static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, const uint8_t *obmc_edged){
3051 Plane *p= &s->plane[plane_index]; 3086 Plane *p= &s->plane[plane_index];
3052 const int block_size = MB_SIZE >> s->block_max_depth; 3087 const int block_size = MB_SIZE >> s->block_max_depth;
3053 const int block_w = plane_index ? block_size/2 : block_size; 3088 const int block_w = plane_index ? block_size/2 : block_size;
3054 const uint8_t *obmc = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth]; 3089 const uint8_t *obmc = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth];
3106 for(i=0; i<4; i++){ 3141 for(i=0; i<4; i++){
3107 /* ..RRr 3142 /* ..RRr
3108 * .RXx. 3143 * .RXx.
3109 * rxx.. 3144 * rxx..
3110 */ 3145 */
3111 int x= mb_x + (i&1) - (i>>1); 3146 rate += get_block_bits(s, mb_x + (i&1) - (i>>1), mb_y + (i>>1), 1);
3112 int y= mb_y + (i>>1); 3147 }
3113 int index= x + y*b_stride; 3148 }
3114 BlockNode *b = &s->block[index]; 3149 return distortion + rate*penalty_factor;
3115 BlockNode *left = x ? &s->block[index-1] : &null_block; 3150 }
3116 BlockNode *top = y ? &s->block[index-b_stride] : &null_block; 3151
3117 BlockNode *tl = y && x ? &s->block[index-b_stride-1] : left; 3152 static int get_4block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index){
3118 BlockNode *tr = y && x+1<b_stride ? &s->block[index-b_stride+1] : tl; 3153 int i, y2;
3119 int dmx, dmy; 3154 Plane *p= &s->plane[plane_index];
3120 // int mx_context= av_log2(2*ABS(left->mx - top->mx)); 3155 const int block_size = MB_SIZE >> s->block_max_depth;
3121 // int my_context= av_log2(2*ABS(left->my - top->my)); 3156 const int block_w = plane_index ? block_size/2 : block_size;
3122 3157 const uint8_t *obmc = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth];
3123 if(x<0 || x>=b_stride || y>=b_height) 3158 const int obmc_stride= plane_index ? block_size : 2*block_size;
3124 continue; 3159 const int ref_stride= s->current_picture.linesize[plane_index];
3125 dmx= b->mx - mid_pred(left->mx, top->mx, tr->mx); 3160 uint8_t *ref= s-> last_picture.data[plane_index];
3126 dmy= b->my - mid_pred(left->my, top->my, tr->my); 3161 uint8_t *dst= s->current_picture.data[plane_index];
3127 /* 3162 uint8_t *src= s-> input_picture.data[plane_index];
3128 1 0 0 3163 const static DWTELEM zero_dst[4096]; //FIXME
3129 01X 1-2 1 3164 const int b_stride = s->b_width << s->block_max_depth;
3130 001XX 3-6 2-3 3165 const int b_height = s->b_height<< s->block_max_depth;
3131 0001XXX 7-14 4-7 3166 const int w= p->width;
3132 00001XXXX 15-30 8-15 3167 const int h= p->height;
3133 */ 3168 int distortion= 0;
3134 //FIXME try accurate rate 3169 int rate= 0;
3135 //FIXME intra and inter predictors if surrounding blocks arent the same type 3170 const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp);
3136 if(b->type & BLOCK_INTRA){ 3171
3137 rate += 3+2*( av_log2(2*ABS(left->color[0] - b->color[0])) 3172 for(i=0; i<9; i++){
3138 + av_log2(2*ABS(left->color[1] - b->color[1])) 3173 int mb_x2= mb_x + (i%3) - 1;
3139 + av_log2(2*ABS(left->color[2] - b->color[2]))); 3174 int mb_y2= mb_y + (i/3) - 1;
3140 }else 3175 int x= block_w*mb_x2 + block_w/2;
3141 rate += 2*(1 + av_log2(2*ABS(dmx)) 3176 int y= block_w*mb_y2 + block_w/2;
3142 + av_log2(2*ABS(dmy))); //FIXME kill the 2* can be merged in lambda 3177
3143 } 3178 add_yblock(s, zero_dst, dst, ref, obmc,
3144 } 3179 x, y, block_w, block_w, w, h, /*dst_stride*/0, ref_stride, obmc_stride, mb_x2, mb_y2, 1, 1, plane_index);
3145 3180
3181 //FIXME find a cleaner/simpler way to skip the outside stuff
3182 for(y2= y; y2<0; y2++)
3183 memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w);
3184 for(y2= h; y2<y+block_w; y2++)
3185 memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w);
3186 if(x<0){
3187 for(y2= y; y2<y+block_w; y2++)
3188 memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, -x);
3189 }
3190 if(x+block_w > w){
3191 for(y2= y; y2<y+block_w; y2++)
3192 memcpy(dst + w + y2*ref_stride, src + w + y2*ref_stride, x+block_w - w);
3193 }
3194
3195 assert(block_w== 8 || block_w==16);
3196 distortion += s->dsp.me_cmp[block_w==8](&s->m, src + x + y*ref_stride, dst + x + y*ref_stride, ref_stride, block_w);
3197 }
3198
3199 if(plane_index==0){
3200 BlockNode *b= &s->block[mb_x+mb_y*b_stride];
3201 int merged= same_block(b,b+1) && same_block(b,b+b_stride) && same_block(b,b+b_stride+1);
3202
3203 /* ..RRRr
3204 * .RXXx.
3205 * .RXXx.
3206 * rxxx.
3207 */
3208 if(merged)
3209 rate = get_block_bits(s, mb_x, mb_y, 2);
3210 for(i=merged?4:0; i<9; i++){
3211 static const int dxy[9][2] = {{0,0},{1,0},{0,1},{1,1},{2,0},{2,1},{-1,2},{0,2},{1,2}};
3212 rate += get_block_bits(s, mb_x + dxy[i][0], mb_y + dxy[i][1], 1);
3213 }
3214 }
3146 return distortion + rate*penalty_factor; 3215 return distortion + rate*penalty_factor;
3147 } 3216 }
3148 3217
3149 static always_inline int check_block(SnowContext *s, int mb_x, int mb_y, int p[3], int intra, const uint8_t *obmc_edged, int *best_rd){ 3218 static always_inline int check_block(SnowContext *s, int mb_x, int mb_y, int p[3], int intra, const uint8_t *obmc_edged, int *best_rd){
3150 const int b_stride= s->b_width << s->block_max_depth; 3219 const int b_stride= s->b_width << s->block_max_depth;
3186 3255
3187 /* special case for int[2] args we discard afterward, fixes compilation prob with gcc 2.95 */ 3256 /* special case for int[2] args we discard afterward, fixes compilation prob with gcc 2.95 */
3188 static always_inline int check_block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, int intra, const uint8_t *obmc_edged, int *best_rd){ 3257 static always_inline int check_block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, int intra, const uint8_t *obmc_edged, int *best_rd){
3189 int p[2] = {p0, p1}; 3258 int p[2] = {p0, p1};
3190 return check_block(s, mb_x, mb_y, p, intra, obmc_edged, best_rd); 3259 return check_block(s, mb_x, mb_y, p, intra, obmc_edged, best_rd);
3260 }
3261
3262 static always_inline int check_4block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, int *best_rd){
3263 const int b_stride= s->b_width << s->block_max_depth;
3264 BlockNode *block= &s->block[mb_x + mb_y * b_stride];
3265 BlockNode backup[4]= {block[0], block[1], block[b_stride], block[b_stride+1]};
3266 int rd, index, value;
3267
3268 assert(mb_x>=0 && mb_y>=0);
3269 assert(mb_x<b_stride);
3270 assert(((mb_x|mb_y)&1) == 0);
3271
3272 index= (p0 + 31*p1) & (ME_CACHE_SIZE-1);
3273 value= s->me_cache_generation + (p0>>10) + (p1<<6);
3274 if(s->me_cache[index] == value)
3275 return 0;
3276 s->me_cache[index]= value;
3277
3278 block->mx= p0;
3279 block->my= p1;
3280 block->type &= ~BLOCK_INTRA;
3281 block[1]= block[b_stride]= block[b_stride+1]= *block;
3282
3283 rd= get_4block_rd(s, mb_x, mb_y, 0);
3284
3285 //FIXME chroma
3286 if(rd < *best_rd){
3287 *best_rd= rd;
3288 return 1;
3289 }else{
3290 block[0]= backup[0];
3291 block[1]= backup[1];
3292 block[b_stride]= backup[2];
3293 block[b_stride+1]= backup[3];
3294 return 0;
3295 }
3191 } 3296 }
3192 3297
3193 static void iterative_me(SnowContext *s){ 3298 static void iterative_me(SnowContext *s){
3194 int pass, mb_x, mb_y; 3299 int pass, mb_x, mb_y;
3195 const int b_width = s->b_width << s->block_max_depth; 3300 const int b_width = s->b_width << s->block_max_depth;
3331 } 3436 }
3332 av_log(NULL, AV_LOG_ERROR, "pass:%d changed:%d\n", pass, change); 3437 av_log(NULL, AV_LOG_ERROR, "pass:%d changed:%d\n", pass, change);
3333 if(!change) 3438 if(!change)
3334 break; 3439 break;
3335 } 3440 }
3441
3442 if(s->block_max_depth == 1){
3443 int change= 0;
3444 for(mb_y= 0; mb_y<b_height; mb_y+=2){
3445 for(mb_x= 0; mb_x<b_width; mb_x+=2){
3446 int dia_change, i, j;
3447 int best_rd, init_rd;
3448 const int index= mb_x + mb_y * b_stride;
3449 BlockNode *b[4];
3450
3451 b[0]= &s->block[index];
3452 b[1]= b[0]+1;
3453 b[2]= b[0]+b_stride;
3454 b[3]= b[2]+1;
3455 if(same_block(b[0], b[1]) &&
3456 same_block(b[0], b[2]) &&
3457 same_block(b[0], b[3]))
3458 continue;
3459
3460 if(!s->me_cache_generation)
3461 memset(s->me_cache, 0, sizeof(s->me_cache));
3462 s->me_cache_generation += 1<<22;
3463
3464 init_rd= best_rd= get_4block_rd(s, mb_x, mb_y, 0);
3465
3466 check_4block_inter(s, mb_x, mb_y,
3467 (b[0]->mx + b[1]->mx + b[2]->mx + b[3]->mx + 2) >> 2,
3468 (b[0]->my + b[1]->my + b[2]->my + b[3]->my + 2) >> 2, &best_rd);
3469
3470 for(i=0; i<4; i++)
3471 if(!(b[i]->type&BLOCK_INTRA))
3472 check_4block_inter(s, mb_x, mb_y, b[i]->mx, b[i]->my, &best_rd);
3473
3474 if(init_rd != best_rd)
3475 change++;
3476 }
3477 }
3478 av_log(NULL, AV_LOG_ERROR, "pass:4mv changed:%d\n", change*4);
3479 }
3336 } 3480 }
3337 3481
3338 static void quantize(SnowContext *s, SubBand *b, DWTELEM *src, int stride, int bias){ 3482 static void quantize(SnowContext *s, SubBand *b, DWTELEM *src, int stride, int bias){
3339 const int level= b->level; 3483 const int level= b->level;
3340 const int w= b->width; 3484 const int w= b->width;