Mercurial > libavcodec.hg
comparison snow.c @ 3325:c2a017de6bea libavcodec
Snow: scale predicted mv based on which reference frame the neighbors used.
author | lorenm |
---|---|
date | Tue, 30 May 2006 16:42:29 +0000 |
parents | dbb617c134ff |
children | fb245e797c5d |
comparison
equal
deleted
inserted
replaced
3324:dbb617c134ff | 3325:c2a017de6bea |
---|---|
364 | 364 |
365 static const uint8_t *obmc_tab[4]={ | 365 static const uint8_t *obmc_tab[4]={ |
366 obmc32, obmc16, obmc8, obmc4 | 366 obmc32, obmc16, obmc8, obmc4 |
367 }; | 367 }; |
368 | 368 |
369 static int scale_mv_ref[MAX_REF_FRAMES][MAX_REF_FRAMES]; | |
370 | |
369 typedef struct BlockNode{ | 371 typedef struct BlockNode{ |
370 int16_t mx; | 372 int16_t mx; |
371 int16_t my; | 373 int16_t my; |
372 uint8_t ref; | 374 uint8_t ref; |
373 uint8_t color[3]; | 375 uint8_t color[3]; |
1947 c->ref[0][i]= ref [i] + offset[i]; | 1949 c->ref[0][i]= ref [i] + offset[i]; |
1948 } | 1950 } |
1949 assert(!ref_index); | 1951 assert(!ref_index); |
1950 } | 1952 } |
1951 | 1953 |
1954 static inline void pred_mv(SnowContext *s, int *mx, int *my, int ref, | |
1955 BlockNode *left, BlockNode *top, BlockNode *tr){ | |
1956 if(s->ref_frames == 1){ | |
1957 *mx = mid_pred(left->mx, top->mx, tr->mx); | |
1958 *my = mid_pred(left->my, top->my, tr->my); | |
1959 }else{ | |
1960 const int *scale = scale_mv_ref[ref]; | |
1961 *mx = mid_pred(left->mx * scale[left->ref] + 128 >>8, | |
1962 top ->mx * scale[top ->ref] + 128 >>8, | |
1963 tr ->mx * scale[tr ->ref] + 128 >>8); | |
1964 *my = mid_pred(left->my * scale[left->ref] + 128 >>8, | |
1965 top ->my * scale[top ->ref] + 128 >>8, | |
1966 tr ->my * scale[tr ->ref] + 128 >>8); | |
1967 } | |
1968 } | |
1969 | |
1952 //FIXME copy&paste | 1970 //FIXME copy&paste |
1953 #define P_LEFT P[1] | 1971 #define P_LEFT P[1] |
1954 #define P_TOP P[2] | 1972 #define P_TOP P[2] |
1955 #define P_TOPRIGHT P[3] | 1973 #define P_TOPRIGHT P[3] |
1956 #define P_MEDIAN P[4] | 1974 #define P_MEDIAN P[4] |
1980 BlockNode *tl = y && x ? &s->block[index-w-1] : left; | 1998 BlockNode *tl = y && x ? &s->block[index-w-1] : left; |
1981 BlockNode *tr = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt | 1999 BlockNode *tr = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt |
1982 int pl = left->color[0]; | 2000 int pl = left->color[0]; |
1983 int pcb= left->color[1]; | 2001 int pcb= left->color[1]; |
1984 int pcr= left->color[2]; | 2002 int pcr= left->color[2]; |
1985 int pmx= mid_pred(left->mx, top->mx, tr->mx); | 2003 int pmx, pmy; |
1986 int pmy= mid_pred(left->my, top->my, tr->my); | |
1987 int mx=0, my=0; | 2004 int mx=0, my=0; |
1988 int l,cr,cb; | 2005 int l,cr,cb; |
1989 const int stride= s->current_picture.linesize[0]; | 2006 const int stride= s->current_picture.linesize[0]; |
1990 const int uvstride= s->current_picture.linesize[1]; | 2007 const int uvstride= s->current_picture.linesize[1]; |
1991 uint8_t *current_data[3]= { s->input_picture.data[0] + (x + y* stride)*block_w, | 2008 uint8_t *current_data[3]= { s->input_picture.data[0] + (x + y* stride)*block_w, |
2002 int s_context= 2*left->level + 2*top->level + tl->level + tr->level; | 2019 int s_context= 2*left->level + 2*top->level + tl->level + tr->level; |
2003 int ref, best_ref, ref_score, ref_mx, ref_my; | 2020 int ref, best_ref, ref_score, ref_mx, ref_my; |
2004 | 2021 |
2005 assert(sizeof(s->block_state) >= 256); | 2022 assert(sizeof(s->block_state) >= 256); |
2006 if(s->keyframe){ | 2023 if(s->keyframe){ |
2007 set_blocks(s, level, x, y, pl, pcb, pcr, pmx, pmy, 0, BLOCK_INTRA); | 2024 set_blocks(s, level, x, y, pl, pcb, pcr, 0, 0, 0, BLOCK_INTRA); |
2008 return 0; | 2025 return 0; |
2009 } | 2026 } |
2010 | 2027 |
2011 // clip predictors / edge ? | 2028 // clip predictors / edge ? |
2012 | 2029 |
2100 if(level!=s->block_max_depth) | 2117 if(level!=s->block_max_depth) |
2101 put_rac(&pc, &p_state[4 + s_context], 1); | 2118 put_rac(&pc, &p_state[4 + s_context], 1); |
2102 put_rac(&pc, &p_state[1 + left->type + top->type], 0); | 2119 put_rac(&pc, &p_state[1 + left->type + top->type], 0); |
2103 if(s->ref_frames > 1) | 2120 if(s->ref_frames > 1) |
2104 put_symbol(&pc, &p_state[128 + 1024 + 32*ref_context], best_ref, 0); | 2121 put_symbol(&pc, &p_state[128 + 1024 + 32*ref_context], best_ref, 0); |
2122 pred_mv(s, &pmx, &pmy, best_ref, left, top, tr); | |
2105 put_symbol(&pc, &p_state[128 + 32*(mx_context + 16*!!best_ref)], mx - pmx, 1); | 2123 put_symbol(&pc, &p_state[128 + 32*(mx_context + 16*!!best_ref)], mx - pmx, 1); |
2106 put_symbol(&pc, &p_state[128 + 32*(my_context + 16*!!best_ref)], my - pmy, 1); | 2124 put_symbol(&pc, &p_state[128 + 32*(my_context + 16*!!best_ref)], my - pmy, 1); |
2107 p_len= pc.bytestream - pc.bytestream_start; | 2125 p_len= pc.bytestream - pc.bytestream_start; |
2108 score += (s->lambda2*(p_len*8 | 2126 score += (s->lambda2*(p_len*8 |
2109 + (pc.outstanding_count - s->c.outstanding_count)*8 | 2127 + (pc.outstanding_count - s->c.outstanding_count)*8 |
2165 if(score2 < score && score2 < iscore) | 2183 if(score2 < score && score2 < iscore) |
2166 return score2; | 2184 return score2; |
2167 } | 2185 } |
2168 | 2186 |
2169 if(iscore < score){ | 2187 if(iscore < score){ |
2188 pred_mv(s, &pmx, &pmy, 0, left, top, tr); | |
2170 memcpy(pbbak, i_buffer, i_len); | 2189 memcpy(pbbak, i_buffer, i_len); |
2171 s->c= ic; | 2190 s->c= ic; |
2172 s->c.bytestream_start= pbbak_start; | 2191 s->c.bytestream_start= pbbak_start; |
2173 s->c.bytestream= pbbak + i_len; | 2192 s->c.bytestream= pbbak + i_len; |
2174 set_blocks(s, level, x, y, l, cb, cr, pmx, pmy, 0, BLOCK_INTRA); | 2193 set_blocks(s, level, x, y, l, cb, cr, pmx, pmy, 0, BLOCK_INTRA); |
2204 BlockNode *tl = y && x ? &s->block[index-w-1] : left; | 2223 BlockNode *tl = y && x ? &s->block[index-w-1] : left; |
2205 BlockNode *tr = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt | 2224 BlockNode *tr = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt |
2206 int pl = left->color[0]; | 2225 int pl = left->color[0]; |
2207 int pcb= left->color[1]; | 2226 int pcb= left->color[1]; |
2208 int pcr= left->color[2]; | 2227 int pcr= left->color[2]; |
2209 int pmx= mid_pred(left->mx, top->mx, tr->mx); | 2228 int pmx, pmy; |
2210 int pmy= mid_pred(left->my, top->my, tr->my); | |
2211 int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref); | 2229 int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref); |
2212 int mx_context= av_log2(2*ABS(left->mx - top->mx)) + 16*!!b->ref; | 2230 int mx_context= av_log2(2*ABS(left->mx - top->mx)) + 16*!!b->ref; |
2213 int my_context= av_log2(2*ABS(left->my - top->my)) + 16*!!b->ref; | 2231 int my_context= av_log2(2*ABS(left->my - top->my)) + 16*!!b->ref; |
2214 int s_context= 2*left->level + 2*top->level + tl->level + tr->level; | 2232 int s_context= 2*left->level + 2*top->level + tl->level + tr->level; |
2215 | 2233 |
2216 if(s->keyframe){ | 2234 if(s->keyframe){ |
2217 set_blocks(s, level, x, y, pl, pcb, pcr, pmx, pmy, 0, BLOCK_INTRA); | 2235 set_blocks(s, level, x, y, pl, pcb, pcr, 0, 0, 0, BLOCK_INTRA); |
2218 return; | 2236 return; |
2219 } | 2237 } |
2220 | 2238 |
2221 if(level!=s->block_max_depth){ | 2239 if(level!=s->block_max_depth){ |
2222 if(same_block(b,b+1) && same_block(b,b+w) && same_block(b,b+w+1)){ | 2240 if(same_block(b,b+1) && same_block(b,b+w) && same_block(b,b+w+1)){ |
2229 encode_q_branch2(s, level+1, 2*x+1, 2*y+1); | 2247 encode_q_branch2(s, level+1, 2*x+1, 2*y+1); |
2230 return; | 2248 return; |
2231 } | 2249 } |
2232 } | 2250 } |
2233 if(b->type & BLOCK_INTRA){ | 2251 if(b->type & BLOCK_INTRA){ |
2252 pred_mv(s, &pmx, &pmy, 0, left, top, tr); | |
2234 put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 1); | 2253 put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 1); |
2235 put_symbol(&s->c, &s->block_state[32], b->color[0]-pl , 1); | 2254 put_symbol(&s->c, &s->block_state[32], b->color[0]-pl , 1); |
2236 put_symbol(&s->c, &s->block_state[64], b->color[1]-pcb, 1); | 2255 put_symbol(&s->c, &s->block_state[64], b->color[1]-pcb, 1); |
2237 put_symbol(&s->c, &s->block_state[96], b->color[2]-pcr, 1); | 2256 put_symbol(&s->c, &s->block_state[96], b->color[2]-pcr, 1); |
2238 set_blocks(s, level, x, y, b->color[0], b->color[1], b->color[2], pmx, pmy, 0, BLOCK_INTRA); | 2257 set_blocks(s, level, x, y, b->color[0], b->color[1], b->color[2], pmx, pmy, 0, BLOCK_INTRA); |
2239 }else{ | 2258 }else{ |
2259 pred_mv(s, &pmx, &pmy, b->ref, left, top, tr); | |
2240 put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 0); | 2260 put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 0); |
2241 if(s->ref_frames > 1) | 2261 if(s->ref_frames > 1) |
2242 put_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], b->ref, 0); | 2262 put_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], b->ref, 0); |
2243 put_symbol(&s->c, &s->block_state[128 + 32*mx_context], b->mx - pmx, 1); | 2263 put_symbol(&s->c, &s->block_state[128 + 32*mx_context], b->mx - pmx, 1); |
2244 put_symbol(&s->c, &s->block_state[128 + 32*my_context], b->my - pmy, 1); | 2264 put_symbol(&s->c, &s->block_state[128 + 32*my_context], b->my - pmy, 1); |
2275 int my_context= av_log2(2*ABS(left->my - top->my)) + 0*av_log2(2*ABS(tr->my - top->my)); | 2295 int my_context= av_log2(2*ABS(left->my - top->my)) + 0*av_log2(2*ABS(tr->my - top->my)); |
2276 | 2296 |
2277 type= get_rac(&s->c, &s->block_state[1 + left->type + top->type]) ? BLOCK_INTRA : 0; | 2297 type= get_rac(&s->c, &s->block_state[1 + left->type + top->type]) ? BLOCK_INTRA : 0; |
2278 | 2298 |
2279 if(type){ | 2299 if(type){ |
2300 pred_mv(s, &mx, &my, 0, left, top, tr); | |
2280 l += get_symbol(&s->c, &s->block_state[32], 1); | 2301 l += get_symbol(&s->c, &s->block_state[32], 1); |
2281 cb+= get_symbol(&s->c, &s->block_state[64], 1); | 2302 cb+= get_symbol(&s->c, &s->block_state[64], 1); |
2282 cr+= get_symbol(&s->c, &s->block_state[96], 1); | 2303 cr+= get_symbol(&s->c, &s->block_state[96], 1); |
2283 }else{ | 2304 }else{ |
2284 if(s->ref_frames > 1) | 2305 if(s->ref_frames > 1) |
2285 ref= get_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], 0); | 2306 ref= get_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], 0); |
2307 pred_mv(s, &mx, &my, ref, left, top, tr); | |
2286 mx+= get_symbol(&s->c, &s->block_state[128 + 32*(mx_context + 16*!!ref)], 1); | 2308 mx+= get_symbol(&s->c, &s->block_state[128 + 32*(mx_context + 16*!!ref)], 1); |
2287 my+= get_symbol(&s->c, &s->block_state[128 + 32*(my_context + 16*!!ref)], 1); | 2309 my+= get_symbol(&s->c, &s->block_state[128 + 32*(my_context + 16*!!ref)], 1); |
2288 } | 2310 } |
2289 set_blocks(s, level, x, y, l, cb, cr, mx, my, ref, type); | 2311 set_blocks(s, level, x, y, l, cb, cr, mx, my, ref, type); |
2290 }else{ | 2312 }else{ |
3011 // int mx_context= av_log2(2*ABS(left->mx - top->mx)); | 3033 // int mx_context= av_log2(2*ABS(left->mx - top->mx)); |
3012 // int my_context= av_log2(2*ABS(left->my - top->my)); | 3034 // int my_context= av_log2(2*ABS(left->my - top->my)); |
3013 | 3035 |
3014 if(x<0 || x>=b_stride || y>=b_height) | 3036 if(x<0 || x>=b_stride || y>=b_height) |
3015 return 0; | 3037 return 0; |
3016 dmx= b->mx - mid_pred(left->mx, top->mx, tr->mx); | |
3017 dmy= b->my - mid_pred(left->my, top->my, tr->my); | |
3018 /* | 3038 /* |
3019 1 0 0 | 3039 1 0 0 |
3020 01X 1-2 1 | 3040 01X 1-2 1 |
3021 001XX 3-6 2-3 | 3041 001XX 3-6 2-3 |
3022 0001XXX 7-14 4-7 | 3042 0001XXX 7-14 4-7 |
3026 //FIXME intra and inter predictors if surrounding blocks arent the same type | 3046 //FIXME intra and inter predictors if surrounding blocks arent the same type |
3027 if(b->type & BLOCK_INTRA){ | 3047 if(b->type & BLOCK_INTRA){ |
3028 return 3+2*( av_log2(2*ABS(left->color[0] - b->color[0])) | 3048 return 3+2*( av_log2(2*ABS(left->color[0] - b->color[0])) |
3029 + av_log2(2*ABS(left->color[1] - b->color[1])) | 3049 + av_log2(2*ABS(left->color[1] - b->color[1])) |
3030 + av_log2(2*ABS(left->color[2] - b->color[2]))); | 3050 + av_log2(2*ABS(left->color[2] - b->color[2]))); |
3031 }else | 3051 }else{ |
3052 pred_mv(s, &dmx, &dmy, b->ref, left, top, tr); | |
3053 dmx-= b->mx; | |
3054 dmy-= b->my; | |
3032 return 2*(1 + av_log2(2*ABS(dmx)) //FIXME kill the 2* can be merged in lambda | 3055 return 2*(1 + av_log2(2*ABS(dmx)) //FIXME kill the 2* can be merged in lambda |
3033 + av_log2(2*ABS(dmy)) | 3056 + av_log2(2*ABS(dmy)) |
3034 + av_log2(2*b->ref)); | 3057 + av_log2(2*b->ref)); |
3058 } | |
3035 } | 3059 } |
3036 | 3060 |
3037 static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, const uint8_t *obmc_edged){ | 3061 static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, const uint8_t *obmc_edged){ |
3038 Plane *p= &s->plane[plane_index]; | 3062 Plane *p= &s->plane[plane_index]; |
3039 const int block_size = MB_SIZE >> s->block_max_depth; | 3063 const int block_size = MB_SIZE >> s->block_max_depth; |
3804 | 3828 |
3805 static int common_init(AVCodecContext *avctx){ | 3829 static int common_init(AVCodecContext *avctx){ |
3806 SnowContext *s = avctx->priv_data; | 3830 SnowContext *s = avctx->priv_data; |
3807 int width, height; | 3831 int width, height; |
3808 int level, orientation, plane_index, dec; | 3832 int level, orientation, plane_index, dec; |
3833 int i, j; | |
3809 | 3834 |
3810 s->avctx= avctx; | 3835 s->avctx= avctx; |
3811 | 3836 |
3812 dsputil_init(&s->dsp, avctx); | 3837 dsputil_init(&s->dsp, avctx); |
3813 | 3838 |
3908 } | 3933 } |
3909 w= (w+1)>>1; | 3934 w= (w+1)>>1; |
3910 h= (h+1)>>1; | 3935 h= (h+1)>>1; |
3911 } | 3936 } |
3912 } | 3937 } |
3938 | |
3939 for(i=0; i<MAX_REF_FRAMES; i++) | |
3940 for(j=0; j<MAX_REF_FRAMES; j++) | |
3941 scale_mv_ref[i][j] = 256*(i+1)/(j+1); | |
3913 | 3942 |
3914 reset_contexts(s); | 3943 reset_contexts(s); |
3915 /* | 3944 /* |
3916 width= s->width= avctx->width; | 3945 width= s->width= avctx->width; |
3917 height= s->height= avctx->height; | 3946 height= s->height= avctx->height; |