c->xmin = - x*block_w - 16; c->ymin = - y*block_w - 16; c->xmax = - (x+1)*block_w + (w<<(LOG2_MB_SIZE - s->block_max_depth)) + 16; c->ymax = - (y+1)*block_w + (h<<(LOG2_MB_SIZE - s->block_max_depth)) + 16;
c->xmin = - x*block_w - 16+2; c->ymin = - y*block_w - 16+2; c->xmax = - (x+1)*block_w + (w<<(LOG2_MB_SIZE - s->block_max_depth)) + 16-2; c->ymax = - (y+1)*block_w + (h<<(LOG2_MB_SIZE - s->block_max_depth)) + 16-2;
static int encode_q_branch(SnowContext *s, int level, int x, int y){    uint8_t p_buffer[1024];    uint8_t i_buffer[1024];    uint8_t p_state[sizeof(s->block_state)];    uint8_t i_state[sizeof(s->block_state)];    CABACContext pc, ic;    PutBitContext pbbak= s->c.pb;    int score, score2, iscore, i_len, p_len, block_s, sum;    const int w= s->b_width  << s->block_max_depth;    const int h= s->b_height << s->block_max_depth;    const int rem_depth= s->block_max_depth - level;    const int index= (x + y*w) << rem_depth;    const int block_w= 1<<(LOG2_MB_SIZE - level);    static BlockNode null_block= { //FIXME add border maybe        .color= {128,128,128},        .mx= 0,        .my= 0,        .type= 0,        .level= 0,    };    int trx= (x+1)<<rem_depth;    int try= (y+1)<<rem_depth;    BlockNode *left  = x ? &s->block[index-1] : &null_block;    BlockNode *top   = y ? &s->block[index-w] : &null_block;    BlockNode *right = trx<w ? &s->block[index+1] : &null_block;    BlockNode *bottom= try<h ? &s->block[index+w] : &null_block;    BlockNode *tl    = y && x ? &s->block[index-w-1] : left;    BlockNode *tr    = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt    int pl = left->color[0];    int pcb= left->color[1];    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=0, my=0;    int l,cr,cb, i;    const int stride= s->current_picture.linesize[0];    const int uvstride= s->current_picture.linesize[1];    const int instride= s->input_picture.linesize[0];    const int uvinstride= s->input_picture.linesize[1];    uint8_t *new_l = s->input_picture.data[0] + (x + y*  instride)*block_w;    uint8_t *new_cb= s->input_picture.data[1] + (x + y*uvinstride)*block_w/2;    uint8_t *new_cr= s->input_picture.data[2] + (x + y*uvinstride)*block_w/2;    uint8_t current_mb[3][stride*block_w];    uint8_t *current_data[3]= {&current_mb[0][0], &current_mb[1][0], &current_mb[2][0]};    int P[10][2];    int16_t last_mv[3][2];    int qpel= !!(s->avctx->flags & CODEC_FLAG_QPEL); //unused    const int shift= 1+qpel;    MotionEstContext *c= &s->m.me;    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;    assert(sizeof(s->block_state) >= 256);    if(s->keyframe){        set_blocks(s, level, x, y, pl, pcb, pcr, pmx, pmy, BLOCK_INTRA);        return 0;    }    //FIXME optimize    for(i=0; i<block_w; i++)        memcpy(&current_mb[0][0] +   stride*i, new_l  +   instride*i, block_w);    for(i=0; i<block_w>>1; i++)        memcpy(&current_mb[1][0] + uvstride*i, new_cb + uvinstride*i, block_w>>1);    for(i=0; i<block_w>>1; i++)        memcpy(&current_mb[2][0] + uvstride*i, new_cr + uvinstride*i, block_w>>1);//    clip predictors / edge ?    P_LEFT[0]= left->mx;    P_LEFT[1]= left->my;    P_TOP [0]= top->mx;    P_TOP [1]= top->my;    P_TOPRIGHT[0]= tr->mx;    P_TOPRIGHT[1]= tr->my;        last_mv[0][0]= s->block[index].mx;    last_mv[0][1]= s->block[index].my;    last_mv[1][0]= right->mx;    last_mv[1][1]= right->my;    last_mv[2][0]= bottom->mx;    last_mv[2][1]= bottom->my;        s->m.mb_stride=2;    s->m.mb_x=     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);        c->penalty_factor    = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp);    c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp);    c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp);    c->current_mv_penalty= c->mv_penalty[s->m.f_code=1] + MAX_MV;        c->xmin = - x*block_w - 16;    c->ymin = - y*block_w - 16;    c->xmax = - (x+1)*block_w + (w<<(LOG2_MB_SIZE - s->block_max_depth)) + 16;    c->ymax = - (y+1)*block_w + (h<<(LOG2_MB_SIZE - s->block_max_depth)) + 16;    if(P_LEFT[0]     > (c->xmax<<shift)) P_LEFT[0]    = (c->xmax<<shift);    if(P_LEFT[1]     > (c->ymax<<shift)) P_LEFT[1]    = (c->ymax<<shift);     if(P_TOP[0]      > (c->xmax<<shift)) P_TOP[0]     = (c->xmax<<shift);    if(P_TOP[1]      > (c->ymax<<shift)) P_TOP[1]     = (c->ymax<<shift);    if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);    if(P_TOPRIGHT[0] > (c->xmax<<shift)) P_TOPRIGHT[0]= (c->xmax<<shift); //due to pmx no clip    if(P_TOPRIGHT[1] > (c->ymax<<shift)) P_TOPRIGHT[1]= (c->ymax<<shift);    P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);    P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);    if (!y) {        c->pred_x= P_LEFT[0];        c->pred_y= P_LEFT[1];    } else {        c->pred_x = P_MEDIAN[0];        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);    assert(mx >= c->xmin);    assert(mx <= c->xmax);    assert(my >= c->ymin);    assert(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);    //FIXME if mb_cmp != SSE then intra cant be compared currently and mb_penalty vs. lambda2                               //  subpel search    pc= s->c;    init_put_bits(&pc.pb, p_buffer, sizeof(p_buffer));    memcpy(p_state, s->block_state, sizeof(s->block_state));    if(level!=s->block_max_depth)        put_cabac(&pc, &p_state[4 + s_context], 1);    put_cabac(&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);    p_len= put_bits_count(&pc.pb);    score += (s->lambda2*(p_len + pc.outstanding_count - s->c.outstanding_count))>>FF_LAMBDA_SHIFT;    block_s= block_w*block_w;    sum = pix_sum(&current_mb[0][0], stride, block_w);    l= (sum + block_s/2)/block_s;    iscore = pix_norm1(&current_mb[0][0], stride, block_w) - 2*l*sum + l*l*block_s;        block_s= block_w*block_w>>2;    sum = pix_sum(&current_mb[1][0], uvstride, block_w>>1);    cb= (sum + block_s/2)/block_s;//    iscore += pix_norm1(&current_mb[1][0], uvstride, block_w>>1) - 2*cb*sum + cb*cb*block_s;    sum = pix_sum(&current_mb[2][0], uvstride, block_w>>1);    cr= (sum + block_s/2)/block_s;//    iscore += pix_norm1(&current_mb[2][0], uvstride, block_w>>1) - 2*cr*sum + cr*cr*block_s;    ic= s->c;    init_put_bits(&ic.pb, i_buffer, sizeof(i_buffer));    memcpy(i_state, s->block_state, sizeof(s->block_state));    if(level!=s->block_max_depth)        put_cabac(&ic, &i_state[4 + s_context], 1);    put_cabac(&ic, &i_state[1 + left->type + top->type], 1);    put_symbol(&ic, &i_state[32],  l-pl , 1);    put_symbol(&ic, &i_state[64], cb-pcb, 1);    put_symbol(&ic, &i_state[96], cr-pcr, 1);    i_len= put_bits_count(&ic.pb);    iscore += (s->lambda2*(i_len + ic.outstanding_count - s->c.outstanding_count))>>FF_LAMBDA_SHIFT;//    assert(score==256*256*256*64-1);    assert(iscore < 255*255*256 + s->lambda2*10);    assert(iscore >= 0);    assert(l>=0 && l<=255);    assert(pl>=0 && pl<=255);    if(level==0){        int varc= iscore >> 8;        int vard= score >> 8;        if (vard <= 64 || vard < varc)            c->scene_change_score+= ff_sqrt(vard) - ff_sqrt(varc);        else            c->scene_change_score+= s->m.qscale;    }            if(level!=s->block_max_depth){        put_cabac(&s->c, &s->block_state[4 + s_context], 0);        score2 = encode_q_branch(s, level+1, 2*x+0, 2*y+0);        score2+= encode_q_branch(s, level+1, 2*x+1, 2*y+0);        score2+= encode_q_branch(s, level+1, 2*x+0, 2*y+1);        score2+= encode_q_branch(s, level+1, 2*x+1, 2*y+1);        score2+= s->lambda2>>FF_LAMBDA_SHIFT; //FIXME exact split overhead            if(score2 < score && score2 < iscore)            return score2;    }        if(iscore < score){        flush_put_bits(&ic.pb);        ff_copy_bits(&pbbak, i_buffer, i_len);        s->c= ic;        s->c.pb= pbbak;        set_blocks(s, level, x, y, l, cb, cr, pmx, pmy, BLOCK_INTRA);        memcpy(s->block_state, i_state, sizeof(s->block_state));        return iscore;    }else{        flush_put_bits(&pc.pb);        ff_copy_bits(&pbbak, p_buffer, p_len);        s->c= pc;        s->c.pb= pbbak;        set_blocks(s, level, x, y, pl, pcb, pcr, mx, my, 0);        memcpy(s->block_state, p_state, sizeof(s->block_state));        return score;    }}