|  |  | @@ -369,6 +369,7 @@ static const uint8_t *obmc_tab[4]={ | 
		
	
		
			
			|  |  |  | typedef struct BlockNode{ | 
		
	
		
			
			|  |  |  | int16_t mx; | 
		
	
		
			
			|  |  |  | int16_t my; | 
		
	
		
			
			|  |  |  | uint8_t ref; | 
		
	
		
			
			|  |  |  | uint8_t color[3]; | 
		
	
		
			
			|  |  |  | uint8_t type; | 
		
	
		
			
			|  |  |  | //#define TYPE_SPLIT    1 | 
		
	
	
		
			
				|  |  | @@ -382,6 +383,7 @@ static const BlockNode null_block= { //FIXME add border maybe | 
		
	
		
			
			|  |  |  | .color= {128,128,128}, | 
		
	
		
			
			|  |  |  | .mx= 0, | 
		
	
		
			
			|  |  |  | .my= 0, | 
		
	
		
			
			|  |  |  | .ref= 0, | 
		
	
		
			
			|  |  |  | .type= 0, | 
		
	
		
			
			|  |  |  | .level= 0, | 
		
	
		
			
			|  |  |  | }; | 
		
	
	
		
			
				|  |  | @@ -424,7 +426,7 @@ typedef struct SnowContext{ | 
		
	
		
			
			|  |  |  | AVFrame new_picture; | 
		
	
		
			
			|  |  |  | AVFrame input_picture;              ///< new_picture with the internal linesizes | 
		
	
		
			
			|  |  |  | AVFrame current_picture; | 
		
	
		
			
			|  |  |  | AVFrame last_picture; | 
		
	
		
			
			|  |  |  | AVFrame last_picture[MAX_REF_FRAMES]; | 
		
	
		
			
			|  |  |  | AVFrame mconly_picture; | 
		
	
		
			
			|  |  |  | //     uint8_t q_context[16]; | 
		
	
		
			
			|  |  |  | uint8_t header_state[32]; | 
		
	
	
		
			
				|  |  | @@ -436,6 +438,10 @@ typedef struct SnowContext{ | 
		
	
		
			
			|  |  |  | int temporal_decomposition_type; | 
		
	
		
			
			|  |  |  | int spatial_decomposition_count; | 
		
	
		
			
			|  |  |  | int temporal_decomposition_count; | 
		
	
		
			
			|  |  |  | int max_ref_frames; | 
		
	
		
			
			|  |  |  | int ref_frames; | 
		
	
		
			
			|  |  |  | int16_t (*ref_mvs[MAX_REF_FRAMES])[2]; | 
		
	
		
			
			|  |  |  | uint32_t *ref_scores[MAX_REF_FRAMES]; | 
		
	
		
			
			|  |  |  | DWTELEM *spatial_dwt_buffer; | 
		
	
		
			
			|  |  |  | int colorspace_type; | 
		
	
		
			
			|  |  |  | int chroma_h_shift; | 
		
	
	
		
			
				|  |  | @@ -1905,7 +1911,7 @@ static int pix_norm1(uint8_t * pix, int line_size, int w) | 
		
	
		
			
			|  |  |  | return s; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static inline void set_blocks(SnowContext *s, int level, int x, int y, int l, int cb, int cr, int mx, int my, int type){ | 
		
	
		
			
			|  |  |  | static inline void set_blocks(SnowContext *s, int level, int x, int y, int l, int cb, int cr, int mx, int my, int ref, int type){ | 
		
	
		
			
			|  |  |  | const int w= s->b_width << s->block_max_depth; | 
		
	
		
			
			|  |  |  | const int rem_depth= s->block_max_depth - level; | 
		
	
		
			
			|  |  |  | const int index= (x + y*w) << rem_depth; | 
		
	
	
		
			
				|  |  | @@ -1918,6 +1924,7 @@ static inline void set_blocks(SnowContext *s, int level, int x, int y, int l, in | 
		
	
		
			
			|  |  |  | block.color[2]= cr; | 
		
	
		
			
			|  |  |  | block.mx= mx; | 
		
	
		
			
			|  |  |  | block.my= my; | 
		
	
		
			
			|  |  |  | block.ref= ref; | 
		
	
		
			
			|  |  |  | block.type= type; | 
		
	
		
			
			|  |  |  | block.level= level; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -1989,13 +1996,15 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ | 
		
	
		
			
			|  |  |  | int qpel= !!(s->avctx->flags & CODEC_FLAG_QPEL); //unused | 
		
	
		
			
			|  |  |  | const int shift= 1+qpel; | 
		
	
		
			
			|  |  |  | MotionEstContext *c= &s->m.me; | 
		
	
		
			
			|  |  |  | int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref); | 
		
	
		
			
			|  |  |  | int mx_context= av_log2(2*ABS(left->mx - top->mx)); | 
		
	
		
			
			|  |  |  | int my_context= av_log2(2*ABS(left->my - top->my)); | 
		
	
		
			
			|  |  |  | int s_context= 2*left->level + 2*top->level + tl->level + tr->level; | 
		
	
		
			
			|  |  |  | int ref, best_ref, ref_score, ref_mx, ref_my; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | assert(sizeof(s->block_state) >= 256); | 
		
	
		
			
			|  |  |  | if(s->keyframe){ | 
		
	
		
			
			|  |  |  | set_blocks(s, level, x, y, pl, pcb, pcr, pmx, pmy, BLOCK_INTRA); | 
		
	
		
			
			|  |  |  | set_blocks(s, level, x, y, pl, pcb, pcr, pmx, pmy, 0, BLOCK_INTRA); | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -2020,8 +2029,6 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ | 
		
	
		
			
			|  |  |  | s->m.mb_y= 0; | 
		
	
		
			
			|  |  |  | s->m.me.skip= 0; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | init_ref(c, current_data, s->last_picture.data, NULL, block_w*x, block_w*y, 0); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | assert(s->m.me.  stride ==   stride); | 
		
	
		
			
			|  |  |  | assert(s->m.me.uvstride == uvstride); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -2054,16 +2061,34 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ | 
		
	
		
			
			|  |  |  | c->pred_y = P_MEDIAN[1]; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | score= ff_epzs_motion_search(&s->m, &mx, &my, P, 0, /*ref_index*/ 0, last_mv, | 
		
	
		
			
			|  |  |  | (1<<16)>>shift, level-LOG2_MB_SIZE+4, block_w); | 
		
	
		
			
			|  |  |  | score= INT_MAX; | 
		
	
		
			
			|  |  |  | best_ref= 0; | 
		
	
		
			
			|  |  |  | for(ref=0; ref<s->ref_frames; ref++){ | 
		
	
		
			
			|  |  |  | init_ref(c, current_data, s->last_picture[ref].data, NULL, block_w*x, block_w*y, 0); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | ref_score= ff_epzs_motion_search(&s->m, &ref_mx, &ref_my, P, 0, /*ref_index*/ 0, last_mv, | 
		
	
		
			
			|  |  |  | (1<<16)>>shift, level-LOG2_MB_SIZE+4, block_w); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | assert(mx >= c->xmin); | 
		
	
		
			
			|  |  |  | assert(mx <= c->xmax); | 
		
	
		
			
			|  |  |  | assert(my >= c->ymin); | 
		
	
		
			
			|  |  |  | assert(my <= c->ymax); | 
		
	
		
			
			|  |  |  | assert(ref_mx >= c->xmin); | 
		
	
		
			
			|  |  |  | assert(ref_mx <= c->xmax); | 
		
	
		
			
			|  |  |  | assert(ref_my >= c->ymin); | 
		
	
		
			
			|  |  |  | assert(ref_my <= c->ymax); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | score= s->m.me.sub_motion_search(&s->m, &mx, &my, score, 0, 0, level-LOG2_MB_SIZE+4, block_w); | 
		
	
		
			
			|  |  |  | score= ff_get_mb_score(&s->m, mx, my, 0, 0, level-LOG2_MB_SIZE+4, block_w, 0); | 
		
	
		
			
			|  |  |  | ref_score= s->m.me.sub_motion_search(&s->m, &ref_mx, &ref_my, ref_score, 0, 0, level-LOG2_MB_SIZE+4, block_w); | 
		
	
		
			
			|  |  |  | ref_score= ff_get_mb_score(&s->m, ref_mx, ref_my, 0, 0, level-LOG2_MB_SIZE+4, block_w, 0); | 
		
	
		
			
			|  |  |  | ref_score+= 2*av_log2(2*ref)*c->penalty_factor; | 
		
	
		
			
			|  |  |  | if(s->ref_mvs[ref]){ | 
		
	
		
			
			|  |  |  | s->ref_mvs[ref][index][0]= ref_mx; | 
		
	
		
			
			|  |  |  | s->ref_mvs[ref][index][1]= ref_my; | 
		
	
		
			
			|  |  |  | s->ref_scores[ref][index]= ref_score; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | if(score > ref_score){ | 
		
	
		
			
			|  |  |  | score= ref_score; | 
		
	
		
			
			|  |  |  | best_ref= ref; | 
		
	
		
			
			|  |  |  | mx= ref_mx; | 
		
	
		
			
			|  |  |  | my= ref_my; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | //FIXME if mb_cmp != SSE then intra cant be compared currently and mb_penalty vs. lambda2 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //  subpel search | 
		
	
	
		
			
				|  |  | @@ -2075,8 +2100,10 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ | 
		
	
		
			
			|  |  |  | if(level!=s->block_max_depth) | 
		
	
		
			
			|  |  |  | put_rac(&pc, &p_state[4 + s_context], 1); | 
		
	
		
			
			|  |  |  | put_rac(&pc, &p_state[1 + left->type + top->type], 0); | 
		
	
		
			
			|  |  |  | put_symbol(&pc, &p_state[128 + 32*mx_context], mx - pmx, 1); | 
		
	
		
			
			|  |  |  | put_symbol(&pc, &p_state[128 + 32*my_context], my - pmy, 1); | 
		
	
		
			
			|  |  |  | if(s->ref_frames > 1) | 
		
	
		
			
			|  |  |  | put_symbol(&pc, &p_state[128 + 1024 + 32*ref_context], best_ref, 0); | 
		
	
		
			
			|  |  |  | put_symbol(&pc, &p_state[128 + 32*(mx_context + 16*!!best_ref)], mx - pmx, 1); | 
		
	
		
			
			|  |  |  | put_symbol(&pc, &p_state[128 + 32*(my_context + 16*!!best_ref)], my - pmy, 1); | 
		
	
		
			
			|  |  |  | p_len= pc.bytestream - pc.bytestream_start; | 
		
	
		
			
			|  |  |  | score += (s->lambda2*(p_len*8 | 
		
	
		
			
			|  |  |  | + (pc.outstanding_count - s->c.outstanding_count)*8 | 
		
	
	
		
			
				|  |  | @@ -2144,7 +2171,7 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ | 
		
	
		
			
			|  |  |  | s->c= ic; | 
		
	
		
			
			|  |  |  | s->c.bytestream_start= pbbak_start; | 
		
	
		
			
			|  |  |  | s->c.bytestream= pbbak + i_len; | 
		
	
		
			
			|  |  |  | set_blocks(s, level, x, y, l, cb, cr, pmx, pmy, BLOCK_INTRA); | 
		
	
		
			
			|  |  |  | set_blocks(s, level, x, y, l, cb, cr, pmx, pmy, 0, BLOCK_INTRA); | 
		
	
		
			
			|  |  |  | memcpy(s->block_state, i_state, sizeof(s->block_state)); | 
		
	
		
			
			|  |  |  | return iscore; | 
		
	
		
			
			|  |  |  | }else{ | 
		
	
	
		
			
				|  |  | @@ -2152,7 +2179,7 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ | 
		
	
		
			
			|  |  |  | s->c= pc; | 
		
	
		
			
			|  |  |  | s->c.bytestream_start= pbbak_start; | 
		
	
		
			
			|  |  |  | s->c.bytestream= pbbak + p_len; | 
		
	
		
			
			|  |  |  | set_blocks(s, level, x, y, pl, pcb, pcr, mx, my, 0); | 
		
	
		
			
			|  |  |  | set_blocks(s, level, x, y, pl, pcb, pcr, mx, my, best_ref, 0); | 
		
	
		
			
			|  |  |  | memcpy(s->block_state, p_state, sizeof(s->block_state)); | 
		
	
		
			
			|  |  |  | return score; | 
		
	
		
			
			|  |  |  | } | 
		
	
	
		
			
				|  |  | @@ -2162,7 +2189,7 @@ static always_inline int same_block(BlockNode *a, BlockNode *b){ | 
		
	
		
			
			|  |  |  | if((a->type&BLOCK_INTRA) && (b->type&BLOCK_INTRA)){ | 
		
	
		
			
			|  |  |  | return !((a->color[0] - b->color[0]) | (a->color[1] - b->color[1]) | (a->color[2] - b->color[2])); | 
		
	
		
			
			|  |  |  | }else{ | 
		
	
		
			
			|  |  |  | return !((a->mx - b->mx) | (a->my - b->my) | ((a->type ^ b->type)&BLOCK_INTRA)); | 
		
	
		
			
			|  |  |  | return !((a->mx - b->mx) | (a->my - b->my) | (a->ref - b->ref) | ((a->type ^ b->type)&BLOCK_INTRA)); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -2181,12 +2208,13 @@ static void encode_q_branch2(SnowContext *s, int level, int x, int y){ | 
		
	
		
			
			|  |  |  | int pcr= left->color[2]; | 
		
	
		
			
			|  |  |  | int pmx= mid_pred(left->mx, top->mx, tr->mx); | 
		
	
		
			
			|  |  |  | int pmy= mid_pred(left->my, top->my, tr->my); | 
		
	
		
			
			|  |  |  | int mx_context= av_log2(2*ABS(left->mx - top->mx)); | 
		
	
		
			
			|  |  |  | int my_context= av_log2(2*ABS(left->my - top->my)); | 
		
	
		
			
			|  |  |  | int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref); | 
		
	
		
			
			|  |  |  | int mx_context= av_log2(2*ABS(left->mx - top->mx)) + 16*!!b->ref; | 
		
	
		
			
			|  |  |  | int my_context= av_log2(2*ABS(left->my - top->my)) + 16*!!b->ref; | 
		
	
		
			
			|  |  |  | int s_context= 2*left->level + 2*top->level + tl->level + tr->level; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(s->keyframe){ | 
		
	
		
			
			|  |  |  | set_blocks(s, level, x, y, pl, pcb, pcr, pmx, pmy, BLOCK_INTRA); | 
		
	
		
			
			|  |  |  | set_blocks(s, level, x, y, pl, pcb, pcr, pmx, pmy, 0, BLOCK_INTRA); | 
		
	
		
			
			|  |  |  | return; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -2207,12 +2235,14 @@ static void encode_q_branch2(SnowContext *s, int level, int x, int y){ | 
		
	
		
			
			|  |  |  | put_symbol(&s->c, &s->block_state[32], b->color[0]-pl , 1); | 
		
	
		
			
			|  |  |  | put_symbol(&s->c, &s->block_state[64], b->color[1]-pcb, 1); | 
		
	
		
			
			|  |  |  | put_symbol(&s->c, &s->block_state[96], b->color[2]-pcr, 1); | 
		
	
		
			
			|  |  |  | set_blocks(s, level, x, y, b->color[0], b->color[1], b->color[2], pmx, pmy, BLOCK_INTRA); | 
		
	
		
			
			|  |  |  | set_blocks(s, level, x, y, b->color[0], b->color[1], b->color[2], pmx, pmy, 0, BLOCK_INTRA); | 
		
	
		
			
			|  |  |  | }else{ | 
		
	
		
			
			|  |  |  | put_rac(&s->c, &s->block_state[1 + (left->type&1) + (top->type&1)], 0); | 
		
	
		
			
			|  |  |  | if(s->ref_frames > 1) | 
		
	
		
			
			|  |  |  | put_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], b->ref, 0); | 
		
	
		
			
			|  |  |  | put_symbol(&s->c, &s->block_state[128 + 32*mx_context], b->mx - pmx, 1); | 
		
	
		
			
			|  |  |  | put_symbol(&s->c, &s->block_state[128 + 32*my_context], b->my - pmy, 1); | 
		
	
		
			
			|  |  |  | set_blocks(s, level, x, y, pl, pcb, pcr, b->mx, b->my, 0); | 
		
	
		
			
			|  |  |  | set_blocks(s, level, x, y, pl, pcb, pcr, b->mx, b->my, b->ref, 0); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -2228,7 +2258,7 @@ static void decode_q_branch(SnowContext *s, int level, int x, int y){ | 
		
	
		
			
			|  |  |  | int s_context= 2*left->level + 2*top->level + tl->level + tr->level; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(s->keyframe){ | 
		
	
		
			
			|  |  |  | set_blocks(s, level, x, y, null_block.color[0], null_block.color[1], null_block.color[2], null_block.mx, null_block.my, BLOCK_INTRA); | 
		
	
		
			
			|  |  |  | set_blocks(s, level, x, y, null_block.color[0], null_block.color[1], null_block.color[2], null_block.mx, null_block.my, null_block.ref, BLOCK_INTRA); | 
		
	
		
			
			|  |  |  | return; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -2239,6 +2269,8 @@ static void decode_q_branch(SnowContext *s, int level, int x, int y){ | 
		
	
		
			
			|  |  |  | int cr= left->color[2]; | 
		
	
		
			
			|  |  |  | int mx= mid_pred(left->mx, top->mx, tr->mx); | 
		
	
		
			
			|  |  |  | int my= mid_pred(left->my, top->my, tr->my); | 
		
	
		
			
			|  |  |  | int ref = 0; | 
		
	
		
			
			|  |  |  | int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref); | 
		
	
		
			
			|  |  |  | int mx_context= av_log2(2*ABS(left->mx - top->mx)) + 0*av_log2(2*ABS(tr->mx - top->mx)); | 
		
	
		
			
			|  |  |  | int my_context= av_log2(2*ABS(left->my - top->my)) + 0*av_log2(2*ABS(tr->my - top->my)); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -2249,10 +2281,12 @@ static void decode_q_branch(SnowContext *s, int level, int x, int y){ | 
		
	
		
			
			|  |  |  | cb+= get_symbol(&s->c, &s->block_state[64], 1); | 
		
	
		
			
			|  |  |  | cr+= get_symbol(&s->c, &s->block_state[96], 1); | 
		
	
		
			
			|  |  |  | }else{ | 
		
	
		
			
			|  |  |  | mx+= get_symbol(&s->c, &s->block_state[128 + 32*mx_context], 1); | 
		
	
		
			
			|  |  |  | my+= get_symbol(&s->c, &s->block_state[128 + 32*my_context], 1); | 
		
	
		
			
			|  |  |  | if(s->ref_frames > 1) | 
		
	
		
			
			|  |  |  | ref= get_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], 0); | 
		
	
		
			
			|  |  |  | mx+= get_symbol(&s->c, &s->block_state[128 + 32*(mx_context + 16*!!ref)], 1); | 
		
	
		
			
			|  |  |  | my+= get_symbol(&s->c, &s->block_state[128 + 32*(my_context + 16*!!ref)], 1); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | set_blocks(s, level, x, y, l, cb, cr, mx, my, type); | 
		
	
		
			
			|  |  |  | set_blocks(s, level, x, y, l, cb, cr, mx, my, ref, type); | 
		
	
		
			
			|  |  |  | }else{ | 
		
	
		
			
			|  |  |  | decode_q_branch(s, level+1, 2*x+0, 2*y+0); | 
		
	
		
			
			|  |  |  | decode_q_branch(s, level+1, 2*x+1, 2*y+0); | 
		
	
	
		
			
				|  |  | @@ -2380,7 +2414,7 @@ mca( 8, 0,8) | 
		
	
		
			
			|  |  |  | mca( 0, 8,8) | 
		
	
		
			
			|  |  |  | mca( 8, 8,8) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static void pred_block(SnowContext *s, uint8_t *dst, uint8_t *src, uint8_t *tmp, int stride, int sx, int sy, int b_w, int b_h, BlockNode *block, int plane_index, int w, int h){ | 
		
	
		
			
			|  |  |  | static void pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride, int sx, int sy, int b_w, int b_h, BlockNode *block, int plane_index, int w, int h){ | 
		
	
		
			
			|  |  |  | if(block->type & BLOCK_INTRA){ | 
		
	
		
			
			|  |  |  | int x, y; | 
		
	
		
			
			|  |  |  | const int color = block->color[plane_index]; | 
		
	
	
		
			
				|  |  | @@ -2420,6 +2454,7 @@ static void pred_block(SnowContext *s, uint8_t *dst, uint8_t *src, uint8_t *tmp, | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | }else{ | 
		
	
		
			
			|  |  |  | uint8_t *src= s->last_picture[block->ref].data[plane_index]; | 
		
	
		
			
			|  |  |  | const int scale= plane_index ?  s->mv_scale : 2*s->mv_scale; | 
		
	
		
			
			|  |  |  | int mx= block->mx*scale; | 
		
	
		
			
			|  |  |  | int my= block->my*scale; | 
		
	
	
		
			
				|  |  | @@ -2494,7 +2529,7 @@ void ff_snow_inner_add_yblock(uint8_t *obmc, const int obmc_stride, uint8_t * * | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //FIXME name clenup (b_w, block_w, b_width stuff) | 
		
	
		
			
			|  |  |  | static always_inline void add_yblock_buffered(SnowContext *s, slice_buffer * sb, DWTELEM *old_dst, uint8_t *dst8, uint8_t *src, uint8_t *obmc, int src_x, int src_y, int b_w, int b_h, int w, int h, int dst_stride, int src_stride, int obmc_stride, int b_x, int b_y, int add, int plane_index){ | 
		
	
		
			
			|  |  |  | static always_inline void add_yblock_buffered(SnowContext *s, slice_buffer * sb, DWTELEM *old_dst, uint8_t *dst8, uint8_t *obmc, int src_x, int src_y, int b_w, int b_h, int w, int h, int dst_stride, int src_stride, int obmc_stride, int b_x, int b_y, int add, int plane_index){ | 
		
	
		
			
			|  |  |  | DWTELEM * dst = NULL; | 
		
	
		
			
			|  |  |  | const int b_width = s->b_width  << s->block_max_depth; | 
		
	
		
			
			|  |  |  | const int b_height= s->b_height << s->block_max_depth; | 
		
	
	
		
			
				|  |  | @@ -2549,14 +2584,14 @@ assert(src_stride > 2*MB_SIZE + 5); | 
		
	
		
			
			|  |  |  | ptmp= tmp + 3*tmp_step; | 
		
	
		
			
			|  |  |  | block[0]= ptmp; | 
		
	
		
			
			|  |  |  | ptmp+=tmp_step; | 
		
	
		
			
			|  |  |  | pred_block(s, block[0], src, tmp, src_stride, src_x, src_y, b_w, b_h, lt, plane_index, w, h); | 
		
	
		
			
			|  |  |  | pred_block(s, block[0], tmp, src_stride, src_x, src_y, b_w, b_h, lt, plane_index, w, h); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(same_block(lt, rt)){ | 
		
	
		
			
			|  |  |  | block[1]= block[0]; | 
		
	
		
			
			|  |  |  | }else{ | 
		
	
		
			
			|  |  |  | block[1]= ptmp; | 
		
	
		
			
			|  |  |  | ptmp+=tmp_step; | 
		
	
		
			
			|  |  |  | pred_block(s, block[1], src, tmp, src_stride, src_x, src_y, b_w, b_h, rt, plane_index, w, h); | 
		
	
		
			
			|  |  |  | pred_block(s, block[1], tmp, src_stride, src_x, src_y, b_w, b_h, rt, plane_index, w, h); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(same_block(lt, lb)){ | 
		
	
	
		
			
				|  |  | @@ -2566,7 +2601,7 @@ assert(src_stride > 2*MB_SIZE + 5); | 
		
	
		
			
			|  |  |  | }else{ | 
		
	
		
			
			|  |  |  | block[2]= ptmp; | 
		
	
		
			
			|  |  |  | ptmp+=tmp_step; | 
		
	
		
			
			|  |  |  | pred_block(s, block[2], src, tmp, src_stride, src_x, src_y, b_w, b_h, lb, plane_index, w, h); | 
		
	
		
			
			|  |  |  | pred_block(s, block[2], tmp, src_stride, src_x, src_y, b_w, b_h, lb, plane_index, w, h); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(same_block(lt, rb) ){ | 
		
	
	
		
			
				|  |  | @@ -2577,7 +2612,7 @@ assert(src_stride > 2*MB_SIZE + 5); | 
		
	
		
			
			|  |  |  | block[3]= block[2]; | 
		
	
		
			
			|  |  |  | }else{ | 
		
	
		
			
			|  |  |  | block[3]= ptmp; | 
		
	
		
			
			|  |  |  | pred_block(s, block[3], src, tmp, src_stride, src_x, src_y, b_w, b_h, rb, plane_index, w, h); | 
		
	
		
			
			|  |  |  | pred_block(s, block[3], tmp, src_stride, src_x, src_y, b_w, b_h, rb, plane_index, w, h); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | #if 0 | 
		
	
		
			
			|  |  |  | for(y=0; y<b_h; y++){ | 
		
	
	
		
			
				|  |  | @@ -2624,7 +2659,7 @@ assert(src_stride > 2*MB_SIZE + 5); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //FIXME name clenup (b_w, block_w, b_width stuff) | 
		
	
		
			
			|  |  |  | static always_inline void add_yblock(SnowContext *s, DWTELEM *dst, uint8_t *dst8, uint8_t *src, uint8_t *obmc, int src_x, int src_y, int b_w, int b_h, int w, int h, int dst_stride, int src_stride, int obmc_stride, int b_x, int b_y, int add, int offset_dst, int plane_index){ | 
		
	
		
			
			|  |  |  | static always_inline void add_yblock(SnowContext *s, DWTELEM *dst, uint8_t *dst8, uint8_t *obmc, int src_x, int src_y, int b_w, int b_h, int w, int h, int dst_stride, int src_stride, int obmc_stride, int b_x, int b_y, int add, int offset_dst, int plane_index){ | 
		
	
		
			
			|  |  |  | const int b_width = s->b_width  << s->block_max_depth; | 
		
	
		
			
			|  |  |  | const int b_height= s->b_height << s->block_max_depth; | 
		
	
		
			
			|  |  |  | const int b_stride= b_width; | 
		
	
	
		
			
				|  |  | @@ -2683,14 +2718,14 @@ assert(src_stride > 2*MB_SIZE + 5); | 
		
	
		
			
			|  |  |  | ptmp= tmp + 3*tmp_step; | 
		
	
		
			
			|  |  |  | block[0]= ptmp; | 
		
	
		
			
			|  |  |  | ptmp+=tmp_step; | 
		
	
		
			
			|  |  |  | pred_block(s, block[0], src, tmp, src_stride, src_x, src_y, b_w, b_h, lt, plane_index, w, h); | 
		
	
		
			
			|  |  |  | pred_block(s, block[0], tmp, src_stride, src_x, src_y, b_w, b_h, lt, plane_index, w, h); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(same_block(lt, rt)){ | 
		
	
		
			
			|  |  |  | block[1]= block[0]; | 
		
	
		
			
			|  |  |  | }else{ | 
		
	
		
			
			|  |  |  | block[1]= ptmp; | 
		
	
		
			
			|  |  |  | ptmp+=tmp_step; | 
		
	
		
			
			|  |  |  | pred_block(s, block[1], src, tmp, src_stride, src_x, src_y, b_w, b_h, rt, plane_index, w, h); | 
		
	
		
			
			|  |  |  | pred_block(s, block[1], tmp, src_stride, src_x, src_y, b_w, b_h, rt, plane_index, w, h); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(same_block(lt, lb)){ | 
		
	
	
		
			
				|  |  | @@ -2700,7 +2735,7 @@ assert(src_stride > 2*MB_SIZE + 5); | 
		
	
		
			
			|  |  |  | }else{ | 
		
	
		
			
			|  |  |  | block[2]= ptmp; | 
		
	
		
			
			|  |  |  | ptmp+=tmp_step; | 
		
	
		
			
			|  |  |  | pred_block(s, block[2], src, tmp, src_stride, src_x, src_y, b_w, b_h, lb, plane_index, w, h); | 
		
	
		
			
			|  |  |  | pred_block(s, block[2], tmp, src_stride, src_x, src_y, b_w, b_h, lb, plane_index, w, h); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(same_block(lt, rb) ){ | 
		
	
	
		
			
				|  |  | @@ -2711,7 +2746,7 @@ assert(src_stride > 2*MB_SIZE + 5); | 
		
	
		
			
			|  |  |  | block[3]= block[2]; | 
		
	
		
			
			|  |  |  | }else{ | 
		
	
		
			
			|  |  |  | block[3]= ptmp; | 
		
	
		
			
			|  |  |  | pred_block(s, block[3], src, tmp, src_stride, src_x, src_y, b_w, b_h, rb, plane_index, w, h); | 
		
	
		
			
			|  |  |  | pred_block(s, block[3], tmp, src_stride, src_x, src_y, b_w, b_h, rb, plane_index, w, h); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | #if 0 | 
		
	
		
			
			|  |  |  | for(y=0; y<b_h; y++){ | 
		
	
	
		
			
				|  |  | @@ -2787,7 +2822,6 @@ static always_inline void predict_slice_buffered(SnowContext *s, slice_buffer * | 
		
	
		
			
			|  |  |  | const uint8_t *obmc  = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth]; | 
		
	
		
			
			|  |  |  | int obmc_stride= plane_index ? block_size : 2*block_size; | 
		
	
		
			
			|  |  |  | int ref_stride= s->current_picture.linesize[plane_index]; | 
		
	
		
			
			|  |  |  | uint8_t *ref  = s->last_picture.data[plane_index]; | 
		
	
		
			
			|  |  |  | uint8_t *dst8= s->current_picture.data[plane_index]; | 
		
	
		
			
			|  |  |  | int w= p->width; | 
		
	
		
			
			|  |  |  | int h= p->height; | 
		
	
	
		
			
				|  |  | @@ -2830,7 +2864,7 @@ static always_inline void predict_slice_buffered(SnowContext *s, slice_buffer * | 
		
	
		
			
			|  |  |  | for(mb_x=0; mb_x<=mb_w; mb_x++){ | 
		
	
		
			
			|  |  |  | START_TIMER | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | add_yblock_buffered(s, sb, old_buffer, dst8, ref, obmc, | 
		
	
		
			
			|  |  |  | add_yblock_buffered(s, sb, old_buffer, dst8, obmc, | 
		
	
		
			
			|  |  |  | block_w*mb_x - block_w/2, | 
		
	
		
			
			|  |  |  | block_w*mb_y - block_w/2, | 
		
	
		
			
			|  |  |  | block_w, block_w, | 
		
	
	
		
			
				|  |  | @@ -2855,7 +2889,6 @@ static always_inline void predict_slice(SnowContext *s, DWTELEM *buf, int plane_ | 
		
	
		
			
			|  |  |  | const uint8_t *obmc  = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth]; | 
		
	
		
			
			|  |  |  | const int obmc_stride= plane_index ? block_size : 2*block_size; | 
		
	
		
			
			|  |  |  | int ref_stride= s->current_picture.linesize[plane_index]; | 
		
	
		
			
			|  |  |  | uint8_t *ref  = s->last_picture.data[plane_index]; | 
		
	
		
			
			|  |  |  | uint8_t *dst8= s->current_picture.data[plane_index]; | 
		
	
		
			
			|  |  |  | int w= p->width; | 
		
	
		
			
			|  |  |  | int h= p->height; | 
		
	
	
		
			
				|  |  | @@ -2888,7 +2921,7 @@ static always_inline void predict_slice(SnowContext *s, DWTELEM *buf, int plane_ | 
		
	
		
			
			|  |  |  | for(mb_x=0; mb_x<=mb_w; mb_x++){ | 
		
	
		
			
			|  |  |  | START_TIMER | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | add_yblock(s, buf, dst8, ref, obmc, | 
		
	
		
			
			|  |  |  | add_yblock(s, buf, dst8, obmc, | 
		
	
		
			
			|  |  |  | block_w*mb_x - block_w/2, | 
		
	
		
			
			|  |  |  | block_w*mb_y - block_w/2, | 
		
	
		
			
			|  |  |  | block_w, block_w, | 
		
	
	
		
			
				|  |  | @@ -2918,7 +2951,6 @@ static int get_dc(SnowContext *s, int mb_x, int mb_y, int plane_index){ | 
		
	
		
			
			|  |  |  | const uint8_t *obmc  = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth]; | 
		
	
		
			
			|  |  |  | const int obmc_stride= plane_index ? block_size : 2*block_size; | 
		
	
		
			
			|  |  |  | const int ref_stride= s->current_picture.linesize[plane_index]; | 
		
	
		
			
			|  |  |  | uint8_t *ref= s->   last_picture.data[plane_index]; | 
		
	
		
			
			|  |  |  | uint8_t *src= s-> input_picture.data[plane_index]; | 
		
	
		
			
			|  |  |  | DWTELEM *dst= (DWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4; | 
		
	
		
			
			|  |  |  | const int b_stride = s->b_width << s->block_max_depth; | 
		
	
	
		
			
				|  |  | @@ -2940,7 +2972,7 @@ static int get_dc(SnowContext *s, int mb_x, int mb_y, int plane_index){ | 
		
	
		
			
			|  |  |  | int x= block_w*mb_x2 + block_w/2; | 
		
	
		
			
			|  |  |  | int y= block_w*mb_y2 + block_w/2; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | add_yblock(s, dst + ((i&1)+(i>>1)*obmc_stride)*block_w, NULL, ref, obmc, | 
		
	
		
			
			|  |  |  | add_yblock(s, dst + ((i&1)+(i>>1)*obmc_stride)*block_w, NULL, obmc, | 
		
	
		
			
			|  |  |  | x, y, block_w, block_w, w, h, obmc_stride, ref_stride, obmc_stride, mb_x2, mb_y2, 0, 0, plane_index); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for(y2= FFMAX(y, 0); y2<FFMIN(h, y+block_w); y2++){ | 
		
	
	
		
			
				|  |  | @@ -2997,8 +3029,9 @@ static inline int get_block_bits(SnowContext *s, int x, int y, int w){ | 
		
	
		
			
			|  |  |  | + av_log2(2*ABS(left->color[1] - b->color[1])) | 
		
	
		
			
			|  |  |  | + av_log2(2*ABS(left->color[2] - b->color[2]))); | 
		
	
		
			
			|  |  |  | }else | 
		
	
		
			
			|  |  |  | return 2*(1 + av_log2(2*ABS(dmx)) | 
		
	
		
			
			|  |  |  | + av_log2(2*ABS(dmy))); //FIXME kill the 2* can be merged in lambda | 
		
	
		
			
			|  |  |  | return 2*(1 + av_log2(2*ABS(dmx)) //FIXME kill the 2* can be merged in lambda | 
		
	
		
			
			|  |  |  | + av_log2(2*ABS(dmy)) | 
		
	
		
			
			|  |  |  | + av_log2(2*b->ref)); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, const uint8_t *obmc_edged){ | 
		
	
	
		
			
				|  |  | @@ -3008,7 +3041,6 @@ static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, con | 
		
	
		
			
			|  |  |  | const uint8_t *obmc  = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth]; | 
		
	
		
			
			|  |  |  | const int obmc_stride= plane_index ? block_size : 2*block_size; | 
		
	
		
			
			|  |  |  | const int ref_stride= s->current_picture.linesize[plane_index]; | 
		
	
		
			
			|  |  |  | uint8_t *ref= s->   last_picture.data[plane_index]; | 
		
	
		
			
			|  |  |  | uint8_t *dst= s->current_picture.data[plane_index]; | 
		
	
		
			
			|  |  |  | uint8_t *src= s->  input_picture.data[plane_index]; | 
		
	
		
			
			|  |  |  | DWTELEM *pred= (DWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4; | 
		
	
	
		
			
				|  |  | @@ -3029,7 +3061,7 @@ static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, con | 
		
	
		
			
			|  |  |  | int y1= FFMIN(block_w*2, h-sy); | 
		
	
		
			
			|  |  |  | int i,x,y; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | pred_block(s, cur, ref, tmp, ref_stride, sx, sy, block_w*2, block_w*2, &s->block[mb_x + mb_y*b_stride], plane_index, w, h); | 
		
	
		
			
			|  |  |  | pred_block(s, cur, tmp, ref_stride, sx, sy, block_w*2, block_w*2, &s->block[mb_x + mb_y*b_stride], plane_index, w, h); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for(y=y0; y<y1; y++){ | 
		
	
		
			
			|  |  |  | const uint8_t *obmc1= obmc_edged + y*obmc_stride; | 
		
	
	
		
			
				|  |  | @@ -3094,7 +3126,6 @@ static int get_4block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index){ | 
		
	
		
			
			|  |  |  | const uint8_t *obmc  = plane_index ? obmc_tab[s->block_max_depth+1] : obmc_tab[s->block_max_depth]; | 
		
	
		
			
			|  |  |  | const int obmc_stride= plane_index ? block_size : 2*block_size; | 
		
	
		
			
			|  |  |  | const int ref_stride= s->current_picture.linesize[plane_index]; | 
		
	
		
			
			|  |  |  | uint8_t *ref= s->   last_picture.data[plane_index]; | 
		
	
		
			
			|  |  |  | uint8_t *dst= s->current_picture.data[plane_index]; | 
		
	
		
			
			|  |  |  | uint8_t *src= s-> input_picture.data[plane_index]; | 
		
	
		
			
			|  |  |  | const static DWTELEM zero_dst[4096]; //FIXME | 
		
	
	
		
			
				|  |  | @@ -3112,7 +3143,7 @@ static int get_4block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index){ | 
		
	
		
			
			|  |  |  | int x= block_w*mb_x2 + block_w/2; | 
		
	
		
			
			|  |  |  | int y= block_w*mb_y2 + block_w/2; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | add_yblock(s, zero_dst, dst, ref, obmc, | 
		
	
		
			
			|  |  |  | add_yblock(s, zero_dst, dst, obmc, | 
		
	
		
			
			|  |  |  | x, y, block_w, block_w, w, h, /*dst_stride*/0, ref_stride, obmc_stride, mb_x2, mb_y2, 1, 1, plane_index); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //FIXME find a cleaner/simpler way to skip the outside stuff | 
		
	
	
		
			
				|  |  | @@ -3168,7 +3199,7 @@ static always_inline int check_block(SnowContext *s, int mb_x, int mb_y, int p[3 | 
		
	
		
			
			|  |  |  | block->type |= BLOCK_INTRA; | 
		
	
		
			
			|  |  |  | }else{ | 
		
	
		
			
			|  |  |  | index= (p[0] + 31*p[1]) & (ME_CACHE_SIZE-1); | 
		
	
		
			
			|  |  |  | value= s->me_cache_generation + (p[0]>>10) + (p[1]<<6); | 
		
	
		
			
			|  |  |  | value= s->me_cache_generation + (p[0]>>10) + (p[1]<<6) + (block->ref<<12); | 
		
	
		
			
			|  |  |  | if(s->me_cache[index] == value) | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | s->me_cache[index]= value; | 
		
	
	
		
			
				|  |  | @@ -3196,7 +3227,7 @@ static always_inline int check_block_inter(SnowContext *s, int mb_x, int mb_y, i | 
		
	
		
			
			|  |  |  | return check_block(s, mb_x, mb_y, p, 0, obmc_edged, best_rd); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static always_inline int check_4block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, int *best_rd){ | 
		
	
		
			
			|  |  |  | static always_inline int check_4block_inter(SnowContext *s, int mb_x, int mb_y, int p0, int p1, int ref, int *best_rd){ | 
		
	
		
			
			|  |  |  | const int b_stride= s->b_width << s->block_max_depth; | 
		
	
		
			
			|  |  |  | BlockNode *block= &s->block[mb_x + mb_y * b_stride]; | 
		
	
		
			
			|  |  |  | BlockNode backup[4]= {block[0], block[1], block[b_stride], block[b_stride+1]}; | 
		
	
	
		
			
				|  |  | @@ -3207,13 +3238,14 @@ static always_inline int check_4block_inter(SnowContext *s, int mb_x, int mb_y, | 
		
	
		
			
			|  |  |  | assert(((mb_x|mb_y)&1) == 0); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | index= (p0 + 31*p1) & (ME_CACHE_SIZE-1); | 
		
	
		
			
			|  |  |  | value= s->me_cache_generation + (p0>>10) + (p1<<6); | 
		
	
		
			
			|  |  |  | value= s->me_cache_generation + (p0>>10) + (p1<<6) + (block->ref<<12); | 
		
	
		
			
			|  |  |  | if(s->me_cache[index] == value) | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | s->me_cache[index]= value; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | block->mx= p0; | 
		
	
		
			
			|  |  |  | block->my= p1; | 
		
	
		
			
			|  |  |  | block->ref= ref; | 
		
	
		
			
			|  |  |  | block->type &= ~BLOCK_INTRA; | 
		
	
		
			
			|  |  |  | block[1]= block[b_stride]= block[b_stride+1]= *block; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -3255,9 +3287,9 @@ static void iterative_me(SnowContext *s){ | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for(mb_y= 0; mb_y<b_height; mb_y++){ | 
		
	
		
			
			|  |  |  | for(mb_x= 0; mb_x<b_width; mb_x++){ | 
		
	
		
			
			|  |  |  | int dia_change, i, j; | 
		
	
		
			
			|  |  |  | int best_rd= INT_MAX; | 
		
	
		
			
			|  |  |  | BlockNode backup; | 
		
	
		
			
			|  |  |  | int dia_change, i, j, ref; | 
		
	
		
			
			|  |  |  | int best_rd= INT_MAX, ref_rd; | 
		
	
		
			
			|  |  |  | BlockNode backup, ref_b; | 
		
	
		
			
			|  |  |  | const int index= mb_x + mb_y * b_stride; | 
		
	
		
			
			|  |  |  | BlockNode *block= &s->block[index]; | 
		
	
		
			
			|  |  |  | BlockNode *tb =                   mb_y            ? &s->block[index-b_stride  ] : &null_block; | 
		
	
	
		
			
				|  |  | @@ -3343,33 +3375,57 @@ static void iterative_me(SnowContext *s){ | 
		
	
		
			
			|  |  |  | }else | 
		
	
		
			
			|  |  |  | check_block_inter(s, mb_x, mb_y, block->mx, block->my, *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | check_block_inter(s, mb_x, mb_y, 0, 0, *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | check_block_inter(s, mb_x, mb_y, tb->mx, tb->my, *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | check_block_inter(s, mb_x, mb_y, lb->mx, lb->my, *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | check_block_inter(s, mb_x, mb_y, rb->mx, rb->my, *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | check_block_inter(s, mb_x, mb_y, bb->mx, bb->my, *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /* fullpel ME */ | 
		
	
		
			
			|  |  |  | //FIXME avoid subpel interpol / round to nearest integer | 
		
	
		
			
			|  |  |  | do{ | 
		
	
		
			
			|  |  |  | dia_change=0; | 
		
	
		
			
			|  |  |  | for(i=0; i<FFMAX(s->avctx->dia_size, 1); i++){ | 
		
	
		
			
			|  |  |  | for(j=0; j<i; j++){ | 
		
	
		
			
			|  |  |  | dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+4*(i-j), block->my+(4*j), *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | dia_change |= check_block_inter(s, mb_x, mb_y, block->mx-4*(i-j), block->my-(4*j), *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+4*(i-j), block->my-(4*j), *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | dia_change |= check_block_inter(s, mb_x, mb_y, block->mx-4*(i-j), block->my+(4*j), *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | ref_b= *block; | 
		
	
		
			
			|  |  |  | ref_rd= best_rd; | 
		
	
		
			
			|  |  |  | for(ref=0; ref < s->ref_frames; ref++){ | 
		
	
		
			
			|  |  |  | int16_t (*mvr)[2]= &s->ref_mvs[ref][index]; | 
		
	
		
			
			|  |  |  | if(s->ref_scores[ref][index] > s->ref_scores[ref_b.ref][index]*3/2) //FIXME tune threshold | 
		
	
		
			
			|  |  |  | continue; | 
		
	
		
			
			|  |  |  | block->ref= ref; | 
		
	
		
			
			|  |  |  | best_rd= INT_MAX; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | check_block_inter(s, mb_x, mb_y, mvr[0][0], mvr[0][1], *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | check_block_inter(s, mb_x, mb_y, 0, 0, *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | if(tb!=&null_block) | 
		
	
		
			
			|  |  |  | check_block_inter(s, mb_x, mb_y, mvr[-b_stride][0], mvr[-b_stride][1], *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | if(lb!=&null_block) | 
		
	
		
			
			|  |  |  | check_block_inter(s, mb_x, mb_y, mvr[-1][0], mvr[-1][1], *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | if(rb!=&null_block) | 
		
	
		
			
			|  |  |  | check_block_inter(s, mb_x, mb_y, mvr[1][0], mvr[1][1], *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | if(bb!=&null_block) | 
		
	
		
			
			|  |  |  | check_block_inter(s, mb_x, mb_y, mvr[b_stride][0], mvr[b_stride][1], *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /* fullpel ME */ | 
		
	
		
			
			|  |  |  | //FIXME avoid subpel interpol / round to nearest integer | 
		
	
		
			
			|  |  |  | do{ | 
		
	
		
			
			|  |  |  | dia_change=0; | 
		
	
		
			
			|  |  |  | for(i=0; i<FFMAX(s->avctx->dia_size, 1); i++){ | 
		
	
		
			
			|  |  |  | for(j=0; j<i; j++){ | 
		
	
		
			
			|  |  |  | dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+4*(i-j), block->my+(4*j), *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | dia_change |= check_block_inter(s, mb_x, mb_y, block->mx-4*(i-j), block->my-(4*j), *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+4*(i-j), block->my-(4*j), *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | dia_change |= check_block_inter(s, mb_x, mb_y, block->mx-4*(i-j), block->my+(4*j), *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | }while(dia_change); | 
		
	
		
			
			|  |  |  | /* subpel ME */ | 
		
	
		
			
			|  |  |  | do{ | 
		
	
		
			
			|  |  |  | static const int square[8][2]= {{+1, 0},{-1, 0},{ 0,+1},{ 0,-1},{+1,+1},{-1,-1},{+1,-1},{-1,+1},}; | 
		
	
		
			
			|  |  |  | dia_change=0; | 
		
	
		
			
			|  |  |  | for(i=0; i<8; i++) | 
		
	
		
			
			|  |  |  | dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+square[i][0], block->my+square[i][1], *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | }while(dia_change); | 
		
	
		
			
			|  |  |  | //FIXME or try the standard 2 pass qpel or similar | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | mvr[0][0]= block->mx; | 
		
	
		
			
			|  |  |  | mvr[0][1]= block->my; | 
		
	
		
			
			|  |  |  | if(ref_rd > best_rd){ | 
		
	
		
			
			|  |  |  | ref_rd= best_rd; | 
		
	
		
			
			|  |  |  | ref_b= *block; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | }while(dia_change); | 
		
	
		
			
			|  |  |  | /* subpel ME */ | 
		
	
		
			
			|  |  |  | do{ | 
		
	
		
			
			|  |  |  | static const int square[8][2]= {{+1, 0},{-1, 0},{ 0,+1},{ 0,-1},{+1,+1},{-1,-1},{+1,-1},{-1,+1},}; | 
		
	
		
			
			|  |  |  | dia_change=0; | 
		
	
		
			
			|  |  |  | for(i=0; i<8; i++) | 
		
	
		
			
			|  |  |  | dia_change |= check_block_inter(s, mb_x, mb_y, block->mx+square[i][0], block->my+square[i][1], *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | }while(dia_change); | 
		
	
		
			
			|  |  |  | //FIXME or try the standard 2 pass qpel or similar | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | best_rd= ref_rd; | 
		
	
		
			
			|  |  |  | *block= ref_b; | 
		
	
		
			
			|  |  |  | #if 1 | 
		
	
		
			
			|  |  |  | check_block(s, mb_x, mb_y, color, 1, *obmc_edged, &best_rd); | 
		
	
		
			
			|  |  |  | //FIXME RD style color selection | 
		
	
	
		
			
				|  |  | @@ -3416,13 +3472,14 @@ static void iterative_me(SnowContext *s){ | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | init_rd= best_rd= get_4block_rd(s, mb_x, mb_y, 0); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //FIXME more multiref search? | 
		
	
		
			
			|  |  |  | check_4block_inter(s, mb_x, mb_y, | 
		
	
		
			
			|  |  |  | (b[0]->mx + b[1]->mx + b[2]->mx + b[3]->mx + 2) >> 2, | 
		
	
		
			
			|  |  |  | (b[0]->my + b[1]->my + b[2]->my + b[3]->my + 2) >> 2, &best_rd); | 
		
	
		
			
			|  |  |  | (b[0]->my + b[1]->my + b[2]->my + b[3]->my + 2) >> 2, 0, &best_rd); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for(i=0; i<4; i++) | 
		
	
		
			
			|  |  |  | if(!(b[i]->type&BLOCK_INTRA)) | 
		
	
		
			
			|  |  |  | check_4block_inter(s, mb_x, mb_y, b[i]->mx, b[i]->my, &best_rd); | 
		
	
		
			
			|  |  |  | check_4block_inter(s, mb_x, mb_y, b[i]->mx, b[i]->my, b[i]->ref, &best_rd); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(init_rd != best_rd) | 
		
	
		
			
			|  |  |  | change++; | 
		
	
	
		
			
				|  |  | @@ -3648,6 +3705,7 @@ static void encode_header(SnowContext *s){ | 
		
	
		
			
			|  |  |  | put_symbol(&s->c, s->header_state, s->chroma_v_shift, 0); | 
		
	
		
			
			|  |  |  | put_rac(&s->c, s->header_state, s->spatial_scalability); | 
		
	
		
			
			|  |  |  | //        put_rac(&s->c, s->header_state, s->rate_scalability); | 
		
	
		
			
			|  |  |  | put_symbol(&s->c, s->header_state, s->max_ref_frames-1, 0); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for(plane_index=0; plane_index<2; plane_index++){ | 
		
	
		
			
			|  |  |  | for(level=0; level<s->spatial_decomposition_count; level++){ | 
		
	
	
		
			
				|  |  | @@ -3689,6 +3747,7 @@ static int decode_header(SnowContext *s){ | 
		
	
		
			
			|  |  |  | s->chroma_v_shift= get_symbol(&s->c, s->header_state, 0); | 
		
	
		
			
			|  |  |  | s->spatial_scalability= get_rac(&s->c, s->header_state); | 
		
	
		
			
			|  |  |  | //        s->rate_scalability= get_rac(&s->c, s->header_state); | 
		
	
		
			
			|  |  |  | s->max_ref_frames= get_symbol(&s->c, s->header_state, 0)+1; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for(plane_index=0; plane_index<3; plane_index++){ | 
		
	
		
			
			|  |  |  | for(level=0; level<s->spatial_decomposition_count; level++){ | 
		
	
	
		
			
				|  |  | @@ -3951,6 +4010,8 @@ static int encode_init(AVCodecContext *avctx) | 
		
	
		
			
			|  |  |  | s->m.obmc_scratchpad= av_mallocz(MB_SIZE*MB_SIZE*12*sizeof(uint32_t)); | 
		
	
		
			
			|  |  |  | h263_encode_init(&s->m); //mv_penalty | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | s->max_ref_frames = FFMAX(FFMIN(avctx->refs, MAX_REF_FRAMES), 1); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(avctx->flags&CODEC_FLAG_PASS1){ | 
		
	
		
			
			|  |  |  | if(!avctx->stats_out) | 
		
	
		
			
			|  |  |  | avctx->stats_out = av_mallocz(256); | 
		
	
	
		
			
				|  |  | @@ -3992,6 +4053,15 @@ static int encode_init(AVCodecContext *avctx) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | s->avctx->get_buffer(s->avctx, &s->input_picture); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(s->avctx->me_method == ME_ITER){ | 
		
	
		
			
			|  |  |  | int i; | 
		
	
		
			
			|  |  |  | int size= s->b_width * s->b_height << 2*s->block_max_depth; | 
		
	
		
			
			|  |  |  | for(i=0; i<s->max_ref_frames; i++){ | 
		
	
		
			
			|  |  |  | s->ref_mvs[i]= av_mallocz(size*sizeof(int16_t[2])); | 
		
	
		
			
			|  |  |  | s->ref_scores[i]= av_mallocz(size*sizeof(uint32_t)); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -4006,16 +4076,29 @@ static int frame_start(SnowContext *s){ | 
		
	
		
			
			|  |  |  | draw_edges(s->current_picture.data[2], s->current_picture.linesize[2], w>>1, h>>1, EDGE_WIDTH/2); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | tmp= s->last_picture; | 
		
	
		
			
			|  |  |  | s->last_picture= s->current_picture; | 
		
	
		
			
			|  |  |  | tmp= s->last_picture[s->max_ref_frames-1]; | 
		
	
		
			
			|  |  |  | memmove(s->last_picture+1, s->last_picture, (s->max_ref_frames-1)*sizeof(AVFrame)); | 
		
	
		
			
			|  |  |  | s->last_picture[0]= s->current_picture; | 
		
	
		
			
			|  |  |  | s->current_picture= tmp; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(s->keyframe){ | 
		
	
		
			
			|  |  |  | s->ref_frames= 0; | 
		
	
		
			
			|  |  |  | }else{ | 
		
	
		
			
			|  |  |  | int i; | 
		
	
		
			
			|  |  |  | for(i=0; i<s->max_ref_frames && s->last_picture[i].data[0]; i++) | 
		
	
		
			
			|  |  |  | if(i && s->last_picture[i-1].key_frame) | 
		
	
		
			
			|  |  |  | break; | 
		
	
		
			
			|  |  |  | s->ref_frames= i; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | s->current_picture.reference= 1; | 
		
	
		
			
			|  |  |  | if(s->avctx->get_buffer(s->avctx, &s->current_picture) < 0){ | 
		
	
		
			
			|  |  |  | av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | 
		
	
		
			
			|  |  |  | return -1; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | s->current_picture.key_frame= s->keyframe; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -4066,7 +4149,6 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, | 
		
	
		
			
			|  |  |  | }//else keep previous frame's qlog until after motion est | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | frame_start(s); | 
		
	
		
			
			|  |  |  | s->current_picture.key_frame= s->keyframe; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | s->m.current_picture_ptr= &s->m.current_picture; | 
		
	
		
			
			|  |  |  | if(pict->pict_type == P_TYPE){ | 
		
	
	
		
			
				|  |  | @@ -4075,11 +4157,11 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, | 
		
	
		
			
			|  |  |  | int stride= s->current_picture.linesize[0]; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | assert(s->current_picture.data[0]); | 
		
	
		
			
			|  |  |  | assert(s->last_picture.data[0]); | 
		
	
		
			
			|  |  |  | assert(s->last_picture[0].data[0]); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | s->m.avctx= s->avctx; | 
		
	
		
			
			|  |  |  | s->m.current_picture.data[0]= s->current_picture.data[0]; | 
		
	
		
			
			|  |  |  | s->m.   last_picture.data[0]= s->   last_picture.data[0]; | 
		
	
		
			
			|  |  |  | s->m.   last_picture.data[0]= s->last_picture[0].data[0]; | 
		
	
		
			
			|  |  |  | s->m.    new_picture.data[0]= s->  input_picture.data[0]; | 
		
	
		
			
			|  |  |  | s->m.   last_picture_ptr= &s->m.   last_picture; | 
		
	
		
			
			|  |  |  | s->m.linesize= | 
		
	
	
		
			
				|  |  | @@ -4145,6 +4227,7 @@ redo_frame: | 
		
	
		
			
			|  |  |  | ff_build_rac_states(c, 0.05*(1LL<<32), 256-8); | 
		
	
		
			
			|  |  |  | pict->pict_type= FF_I_TYPE; | 
		
	
		
			
			|  |  |  | s->keyframe=1; | 
		
	
		
			
			|  |  |  | s->current_picture.key_frame=1; | 
		
	
		
			
			|  |  |  | reset_contexts(s); | 
		
	
		
			
			|  |  |  | goto redo_frame; | 
		
	
		
			
			|  |  |  | } | 
		
	
	
		
			
				|  |  | @@ -4211,8 +4294,8 @@ STOP_TIMER("pred-conv")} | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(s->last_picture.data[0]) | 
		
	
		
			
			|  |  |  | avctx->release_buffer(avctx, &s->last_picture); | 
		
	
		
			
			|  |  |  | if(s->last_picture[s->max_ref_frames-1].data[0]) | 
		
	
		
			
			|  |  |  | avctx->release_buffer(avctx, &s->last_picture[s->max_ref_frames-1]); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | s->current_picture.coded_picture_number = avctx->frame_number; | 
		
	
		
			
			|  |  |  | s->current_picture.pict_type = pict->pict_type; | 
		
	
	
		
			
				|  |  | @@ -4235,7 +4318,7 @@ STOP_TIMER("pred-conv")} | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static void common_end(SnowContext *s){ | 
		
	
		
			
			|  |  |  | int plane_index, level, orientation; | 
		
	
		
			
			|  |  |  | int plane_index, level, orientation, i; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | av_freep(&s->spatial_dwt_buffer); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -4246,6 +4329,13 @@ static void common_end(SnowContext *s){ | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | av_freep(&s->block); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for(i=0; i<MAX_REF_FRAMES; i++){ | 
		
	
		
			
			|  |  |  | av_freep(&s->ref_mvs[i]); | 
		
	
		
			
			|  |  |  | av_freep(&s->ref_scores[i]); | 
		
	
		
			
			|  |  |  | if(s->last_picture[i].data[0]) | 
		
	
		
			
			|  |  |  | s->avctx->release_buffer(s->avctx, &s->last_picture[i]); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for(plane_index=0; plane_index<3; plane_index++){ | 
		
	
		
			
			|  |  |  | for(level=s->spatial_decomposition_count-1; level>=0; level--){ | 
		
	
		
			
			|  |  |  | for(orientation=level ? 1 : 0; orientation<4; orientation++){ | 
		
	
	
		
			
				|  |  | @@ -4419,8 +4509,8 @@ STOP_TIMER("idwt + predict_slices")} | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | emms_c(); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(s->last_picture.data[0]) | 
		
	
		
			
			|  |  |  | avctx->release_buffer(avctx, &s->last_picture); | 
		
	
		
			
			|  |  |  | if(s->last_picture[s->max_ref_frames-1].data[0]) | 
		
	
		
			
			|  |  |  | avctx->release_buffer(avctx, &s->last_picture[s->max_ref_frames-1]); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(!(s->avctx->debug&2048)) | 
		
	
		
			
			|  |  |  | *picture= s->current_picture; | 
		
	
	
		
			
				|  |  | 
 |