static int encode_block(SVQ1Context *s, uint8_t *src, uint8_t *ref, uint8_t *decoded, int stride, int level, int threshold, int lambda, int intra){
    int count, y, x, i, j, split, best_mean, best_score, best_count;
    int best_vector[6];
    int block_sum[7]= {0, 0, 0, 0, 0, 0};
    int w= 2<<((level+2)>>1);
    int h= 2<<((level+1)>>1);
    int size=w*h;
    int16_t block[7][256];
    const int8_t *codebook_sum, *codebook;
    const uint16_t (*mean_vlc)[2];
    const uint8_t (*multistage_vlc)[2];
    best_score=0;
    if(intra){
        codebook_sum= svq1_intra_codebook_sum[level];
        codebook= ff_svq1_intra_codebooks[level];
        mean_vlc= ff_svq1_intra_mean_vlc;
        multistage_vlc= ff_svq1_intra_multistage_vlc[level];
        for(y=0; y<h; y++){
            for(x=0; x<w; x++){
                int v= src[x + y*stride];
                block[0][x + w*y]= v;
                best_score += v*v;
                block_sum[0] += v;
            }
        }
    }else{
        codebook_sum= svq1_inter_codebook_sum[level];
        codebook= ff_svq1_inter_codebooks[level];
        mean_vlc= ff_svq1_inter_mean_vlc + 256;
        multistage_vlc= ff_svq1_inter_multistage_vlc[level];
        for(y=0; y<h; y++){
            for(x=0; x<w; x++){
                int v= src[x + y*stride] - ref[x + y*stride];
                block[0][x + w*y]= v;
                best_score += v*v;
                block_sum[0] += v;
            }
        }
    }
    best_count=0;
    best_score -= ((block_sum[0]*block_sum[0])>>(level+3));
    best_mean= (block_sum[0] + (size>>1)) >> (level+3);
    if(level<4){
        for(count=1; count<7; count++){
            int best_vector_score= INT_MAX;
            int best_vector_sum=-999, best_vector_mean=-999;
            const int stage= count-1;
            const int8_t *vector;
            for(i=0; i<16; i++){
                int sum= codebook_sum[stage*16 + i];
                int sqr, diff, score;
                vector = codebook + stage*size*16 + i*size;
                sqr = s->dsp.ssd_int8_vs_int16(vector, block[stage], size);
                diff= block_sum[stage] - sum;
                score= sqr - ((diff*(int64_t)diff)>>(level+3));
                if(score < best_vector_score){
                    int mean= (diff + (size>>1)) >> (level+3);
                    assert(mean >-300 && mean<300);
                    mean= av_clip(mean, intra?0:-256, 255);
                    best_vector_score= score;
                    best_vector[stage]= i;
                    best_vector_sum= sum;
                    best_vector_mean= mean;
                }
            }
            assert(best_vector_mean != -999);
            vector= codebook + stage*size*16 + best_vector[stage]*size;
            for(j=0; j<size; j++){
                block[stage+1][j] = block[stage][j] - vector[j];
            }
            block_sum[stage+1]= block_sum[stage] - best_vector_sum;
            best_vector_score +=
                lambda*(+ 1 + 4*count
                        + multistage_vlc[1+count][1]
                        + mean_vlc[best_vector_mean][1]);
            if(best_vector_score < best_score){
                best_score= best_vector_score;
                best_count= count;
                best_mean= best_vector_mean;
            }
        }
    }
    split=0;
    if(best_score > threshold && level){
        int score=0;
        int offset= (level&1) ? stride*h/2 : w/2;
        PutBitContext backup[6];
        for(i=level-1; i>=0; i--){
            backup[i]= s->reorder_pb[i];
        }
        score += encode_block(s, src         , ref         , decoded         , stride, level-1, threshold>>1, lambda, intra);
        score += encode_block(s, src + offset, ref + offset, decoded + offset, stride, level-1, threshold>>1, lambda, intra);
        score += lambda;
        if(score < best_score){
            best_score= score;
            split=1;
        }else{
            for(i=level-1; i>=0; i--){
                s->reorder_pb[i]= backup[i];
            }
        }
    }
    if (level > 0)
        put_bits(&s->reorder_pb[level], 1, split);
    if(!split){
        assert((best_mean >= 0 && best_mean<256) || !intra);
        assert(best_mean >= -256 && best_mean<256);
        assert(best_count >=0 && best_count<7);
        assert(level<4 || best_count==0);
        put_bits(&s->reorder_pb[level],
            multistage_vlc[1 + best_count][1],
            multistage_vlc[1 + best_count][0]);
        put_bits(&s->reorder_pb[level], mean_vlc[best_mean][1],
            mean_vlc[best_mean][0]);
        for (i = 0; i < best_count; i++){
            assert(best_vector[i]>=0 && best_vector[i]<16);
            put_bits(&s->reorder_pb[level], 4, best_vector[i]);
        }
        for(y=0; y<h; y++){
            for(x=0; x<w; x++){
                decoded[x + y*stride]= src[x + y*stride] - block[best_count][x + w*y] + best_mean;
            }
        }
    }
    return best_score;
}
['static int svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane, unsigned char *ref_plane, unsigned char *decoded_plane,\n    int width, int height, int src_stride, int stride)\n{\n    int x, y;\n    int i;\n    int block_width, block_height;\n    int level;\n    int threshold[6];\n    const int lambda= (s->picture.quality*s->picture.quality) >> (2*FF_LAMBDA_SHIFT);\n    threshold[5] = QUALITY_THRESHOLD;\n    for (level = 4; level >= 0; level--)\n        threshold[level] = threshold[level + 1] * THRESHOLD_MULTIPLIER;\n    block_width = (width + 15) / 16;\n    block_height = (height + 15) / 16;\n    if(s->picture.pict_type == FF_P_TYPE){\n        s->m.avctx= s->avctx;\n        s->m.current_picture_ptr= &s->m.current_picture;\n        s->m.last_picture_ptr   = &s->m.last_picture;\n        s->m.last_picture.data[0]= ref_plane;\n        s->m.linesize=\n        s->m.last_picture.linesize[0]=\n        s->m.new_picture.linesize[0]=\n        s->m.current_picture.linesize[0]= stride;\n        s->m.width= width;\n        s->m.height= height;\n        s->m.mb_width= block_width;\n        s->m.mb_height= block_height;\n        s->m.mb_stride= s->m.mb_width+1;\n        s->m.b8_stride= 2*s->m.mb_width+1;\n        s->m.f_code=1;\n        s->m.pict_type= s->picture.pict_type;\n        s->m.me_method= s->avctx->me_method;\n        s->m.me.scene_change_score=0;\n        s->m.flags= s->avctx->flags;\n        s->m.lambda= s->picture.quality;\n        s->m.qscale= (s->m.lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7);\n        s->m.lambda2= (s->m.lambda*s->m.lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT;\n        if(!s->motion_val8[plane]){\n            s->motion_val8 [plane]= av_mallocz((s->m.b8_stride*block_height*2 + 2)*2*sizeof(int16_t));\n            s->motion_val16[plane]= av_mallocz((s->m.mb_stride*(block_height + 2) + 1)*2*sizeof(int16_t));\n        }\n        s->m.mb_type= s->mb_type;\n        s->m.current_picture.mb_mean=   (uint8_t *)s->dummy;\n        s->m.current_picture.mb_var=    (uint16_t*)s->dummy;\n        s->m.current_picture.mc_mb_var= (uint16_t*)s->dummy;\n        s->m.current_picture.mb_type= s->dummy;\n        s->m.current_picture.motion_val[0]= s->motion_val8[plane] + 2;\n        s->m.p_mv_table= s->motion_val16[plane] + s->m.mb_stride + 1;\n        s->m.dsp= s->dsp;\n        ff_init_me(&s->m);\n        s->m.me.dia_size= s->avctx->dia_size;\n        s->m.first_slice_line=1;\n        for (y = 0; y < block_height; y++) {\n            uint8_t src[stride*16];\n            s->m.new_picture.data[0]= src - y*16*stride;\n            s->m.mb_y= y;\n            for(i=0; i<16 && i + 16*y<height; i++){\n                memcpy(&src[i*stride], &src_plane[(i+16*y)*src_stride], width);\n                for(x=width; x<16*block_width; x++)\n                    src[i*stride+x]= src[i*stride+x-1];\n            }\n            for(; i<16 && i + 16*y<16*block_height; i++)\n                memcpy(&src[i*stride], &src[(i-1)*stride], 16*block_width);\n            for (x = 0; x < block_width; x++) {\n                s->m.mb_x= x;\n                ff_init_block_index(&s->m);\n                ff_update_block_index(&s->m);\n                ff_estimate_p_frame_motion(&s->m, x, y);\n            }\n            s->m.first_slice_line=0;\n        }\n        ff_fix_long_p_mvs(&s->m);\n        ff_fix_long_mvs(&s->m, NULL, 0, s->m.p_mv_table, s->m.f_code, CANDIDATE_MB_TYPE_INTER, 0);\n    }\n    s->m.first_slice_line=1;\n    for (y = 0; y < block_height; y++) {\n        uint8_t src[stride*16];\n        for(i=0; i<16 && i + 16*y<height; i++){\n            memcpy(&src[i*stride], &src_plane[(i+16*y)*src_stride], width);\n            for(x=width; x<16*block_width; x++)\n                src[i*stride+x]= src[i*stride+x-1];\n        }\n        for(; i<16 && i + 16*y<16*block_height; i++)\n            memcpy(&src[i*stride], &src[(i-1)*stride], 16*block_width);\n        s->m.mb_y= y;\n        for (x = 0; x < block_width; x++) {\n            uint8_t reorder_buffer[3][6][7*32];\n            int count[3][6];\n            int offset = y * 16 * stride + x * 16;\n            uint8_t *decoded= decoded_plane + offset;\n            uint8_t *ref= ref_plane + offset;\n            int score[4]={0,0,0,0}, best;\n            uint8_t temp[16*stride];\n            if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 3000){\n                av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\\n");\n                return -1;\n            }\n            s->m.mb_x= x;\n            ff_init_block_index(&s->m);\n            ff_update_block_index(&s->m);\n            if(s->picture.pict_type == FF_I_TYPE || (s->m.mb_type[x + y*s->m.mb_stride]&CANDIDATE_MB_TYPE_INTRA)){\n                for(i=0; i<6; i++){\n                    init_put_bits(&s->reorder_pb[i], reorder_buffer[0][i], 7*32);\n                }\n                if(s->picture.pict_type == FF_P_TYPE){\n                    const uint8_t *vlc= ff_svq1_block_type_vlc[SVQ1_BLOCK_INTRA];\n                    put_bits(&s->reorder_pb[5], vlc[1], vlc[0]);\n                    score[0]= vlc[1]*lambda;\n                }\n                score[0]+= encode_block(s, src+16*x, NULL, temp, stride, 5, 64, lambda, 1);\n                for(i=0; i<6; i++){\n                    count[0][i]= put_bits_count(&s->reorder_pb[i]);\n                    flush_put_bits(&s->reorder_pb[i]);\n                }\n            }else\n                score[0]= INT_MAX;\n            best=0;\n            if(s->picture.pict_type == FF_P_TYPE){\n                const uint8_t *vlc= ff_svq1_block_type_vlc[SVQ1_BLOCK_INTER];\n                int mx, my, pred_x, pred_y, dxy;\n                int16_t *motion_ptr;\n                motion_ptr= h263_pred_motion(&s->m, 0, 0, &pred_x, &pred_y);\n                if(s->m.mb_type[x + y*s->m.mb_stride]&CANDIDATE_MB_TYPE_INTER){\n                    for(i=0; i<6; i++)\n                        init_put_bits(&s->reorder_pb[i], reorder_buffer[1][i], 7*32);\n                    put_bits(&s->reorder_pb[5], vlc[1], vlc[0]);\n                    s->m.pb= s->reorder_pb[5];\n                    mx= motion_ptr[0];\n                    my= motion_ptr[1];\n                    assert(mx>=-32 && mx<=31);\n                    assert(my>=-32 && my<=31);\n                    assert(pred_x>=-32 && pred_x<=31);\n                    assert(pred_y>=-32 && pred_y<=31);\n                    ff_h263_encode_motion(&s->m, mx - pred_x, 1);\n                    ff_h263_encode_motion(&s->m, my - pred_y, 1);\n                    s->reorder_pb[5]= s->m.pb;\n                    score[1] += lambda*put_bits_count(&s->reorder_pb[5]);\n                    dxy= (mx&1) + 2*(my&1);\n                    s->dsp.put_pixels_tab[0][dxy](temp+16, ref + (mx>>1) + stride*(my>>1), stride, 16);\n                    score[1]+= encode_block(s, src+16*x, temp+16, decoded, stride, 5, 64, lambda, 0);\n                    best= score[1] <= score[0];\n                    vlc= ff_svq1_block_type_vlc[SVQ1_BLOCK_SKIP];\n                    score[2]= s->dsp.sse[0](NULL, src+16*x, ref, stride, 16);\n                    score[2]+= vlc[1]*lambda;\n                    if(score[2] < score[best] && mx==0 && my==0){\n                        best=2;\n                        s->dsp.put_pixels_tab[0][0](decoded, ref, stride, 16);\n                        for(i=0; i<6; i++){\n                            count[2][i]=0;\n                        }\n                        put_bits(&s->pb, vlc[1], vlc[0]);\n                    }\n                }\n                if(best==1){\n                    for(i=0; i<6; i++){\n                        count[1][i]= put_bits_count(&s->reorder_pb[i]);\n                        flush_put_bits(&s->reorder_pb[i]);\n                    }\n                }else{\n                    motion_ptr[0                 ] = motion_ptr[1                 ]=\n                    motion_ptr[2                 ] = motion_ptr[3                 ]=\n                    motion_ptr[0+2*s->m.b8_stride] = motion_ptr[1+2*s->m.b8_stride]=\n                    motion_ptr[2+2*s->m.b8_stride] = motion_ptr[3+2*s->m.b8_stride]=0;\n                }\n            }\n            s->rd_total += score[best];\n            for(i=5; i>=0; i--){\n                ff_copy_bits(&s->pb, reorder_buffer[best][i], count[best][i]);\n            }\n            if(best==0){\n                s->dsp.put_pixels_tab[0][0](decoded, temp, stride, 16);\n            }\n        }\n        s->m.first_slice_line=0;\n    }\n    return 0;\n}', 'static int encode_block(SVQ1Context *s, uint8_t *src, uint8_t *ref, uint8_t *decoded, int stride, int level, int threshold, int lambda, int intra){\n    int count, y, x, i, j, split, best_mean, best_score, best_count;\n    int best_vector[6];\n    int block_sum[7]= {0, 0, 0, 0, 0, 0};\n    int w= 2<<((level+2)>>1);\n    int h= 2<<((level+1)>>1);\n    int size=w*h;\n    int16_t block[7][256];\n    const int8_t *codebook_sum, *codebook;\n    const uint16_t (*mean_vlc)[2];\n    const uint8_t (*multistage_vlc)[2];\n    best_score=0;\n    if(intra){\n        codebook_sum= svq1_intra_codebook_sum[level];\n        codebook= ff_svq1_intra_codebooks[level];\n        mean_vlc= ff_svq1_intra_mean_vlc;\n        multistage_vlc= ff_svq1_intra_multistage_vlc[level];\n        for(y=0; y<h; y++){\n            for(x=0; x<w; x++){\n                int v= src[x + y*stride];\n                block[0][x + w*y]= v;\n                best_score += v*v;\n                block_sum[0] += v;\n            }\n        }\n    }else{\n        codebook_sum= svq1_inter_codebook_sum[level];\n        codebook= ff_svq1_inter_codebooks[level];\n        mean_vlc= ff_svq1_inter_mean_vlc + 256;\n        multistage_vlc= ff_svq1_inter_multistage_vlc[level];\n        for(y=0; y<h; y++){\n            for(x=0; x<w; x++){\n                int v= src[x + y*stride] - ref[x + y*stride];\n                block[0][x + w*y]= v;\n                best_score += v*v;\n                block_sum[0] += v;\n            }\n        }\n    }\n    best_count=0;\n    best_score -= ((block_sum[0]*block_sum[0])>>(level+3));\n    best_mean= (block_sum[0] + (size>>1)) >> (level+3);\n    if(level<4){\n        for(count=1; count<7; count++){\n            int best_vector_score= INT_MAX;\n            int best_vector_sum=-999, best_vector_mean=-999;\n            const int stage= count-1;\n            const int8_t *vector;\n            for(i=0; i<16; i++){\n                int sum= codebook_sum[stage*16 + i];\n                int sqr, diff, score;\n                vector = codebook + stage*size*16 + i*size;\n                sqr = s->dsp.ssd_int8_vs_int16(vector, block[stage], size);\n                diff= block_sum[stage] - sum;\n                score= sqr - ((diff*(int64_t)diff)>>(level+3));\n                if(score < best_vector_score){\n                    int mean= (diff + (size>>1)) >> (level+3);\n                    assert(mean >-300 && mean<300);\n                    mean= av_clip(mean, intra?0:-256, 255);\n                    best_vector_score= score;\n                    best_vector[stage]= i;\n                    best_vector_sum= sum;\n                    best_vector_mean= mean;\n                }\n            }\n            assert(best_vector_mean != -999);\n            vector= codebook + stage*size*16 + best_vector[stage]*size;\n            for(j=0; j<size; j++){\n                block[stage+1][j] = block[stage][j] - vector[j];\n            }\n            block_sum[stage+1]= block_sum[stage] - best_vector_sum;\n            best_vector_score +=\n                lambda*(+ 1 + 4*count\n                        + multistage_vlc[1+count][1]\n                        + mean_vlc[best_vector_mean][1]);\n            if(best_vector_score < best_score){\n                best_score= best_vector_score;\n                best_count= count;\n                best_mean= best_vector_mean;\n            }\n        }\n    }\n    split=0;\n    if(best_score > threshold && level){\n        int score=0;\n        int offset= (level&1) ? stride*h/2 : w/2;\n        PutBitContext backup[6];\n        for(i=level-1; i>=0; i--){\n            backup[i]= s->reorder_pb[i];\n        }\n        score += encode_block(s, src         , ref         , decoded         , stride, level-1, threshold>>1, lambda, intra);\n        score += encode_block(s, src + offset, ref + offset, decoded + offset, stride, level-1, threshold>>1, lambda, intra);\n        score += lambda;\n        if(score < best_score){\n            best_score= score;\n            split=1;\n        }else{\n            for(i=level-1; i>=0; i--){\n                s->reorder_pb[i]= backup[i];\n            }\n        }\n    }\n    if (level > 0)\n        put_bits(&s->reorder_pb[level], 1, split);\n    if(!split){\n        assert((best_mean >= 0 && best_mean<256) || !intra);\n        assert(best_mean >= -256 && best_mean<256);\n        assert(best_count >=0 && best_count<7);\n        assert(level<4 || best_count==0);\n        put_bits(&s->reorder_pb[level],\n            multistage_vlc[1 + best_count][1],\n            multistage_vlc[1 + best_count][0]);\n        put_bits(&s->reorder_pb[level], mean_vlc[best_mean][1],\n            mean_vlc[best_mean][0]);\n        for (i = 0; i < best_count; i++){\n            assert(best_vector[i]>=0 && best_vector[i]<16);\n            put_bits(&s->reorder_pb[level], 4, best_vector[i]);\n        }\n        for(y=0; y<h; y++){\n            for(x=0; x<w; x++){\n                decoded[x + y*stride]= src[x + y*stride] - block[best_count][x + w*y] + best_mean;\n            }\n        }\n    }\n    return best_score;\n}']