static int encode_thread(AVCodecContext *c, void *arg){
    MpegEncContext *s= arg;
    int mb_x, mb_y, pdif = 0;
    int i, j;
    MpegEncContext best_s, backup_s;
    uint8_t bit_buf[2][MAX_MB_BYTES];
    uint8_t bit_buf2[2][MAX_MB_BYTES];
    uint8_t bit_buf_tex[2][MAX_MB_BYTES];
    PutBitContext pb[2], pb2[2], tex_pb[2];
    ff_check_alignment();
    for(i=0; i<2; i++){
        init_put_bits(&pb    [i], bit_buf    [i], MAX_MB_BYTES);
        init_put_bits(&pb2   [i], bit_buf2   [i], MAX_MB_BYTES);
        init_put_bits(&tex_pb[i], bit_buf_tex[i], MAX_MB_BYTES);
    }
    s->last_bits= put_bits_count(&s->pb);
    s->mv_bits=0;
    s->misc_bits=0;
    s->i_tex_bits=0;
    s->p_tex_bits=0;
    s->i_count=0;
    s->f_count=0;
    s->b_count=0;
    s->skip_count=0;
    for(i=0; i<3; i++){
        s->last_dc[i] = 128 << s->intra_dc_precision;
        s->current_picture.error[i] = 0;
    }
    s->mb_skip_run = 0;
    memset(s->last_mv, 0, sizeof(s->last_mv));
    s->last_mv_dir = 0;
    switch(s->codec_id){
    case CODEC_ID_H263:
    case CODEC_ID_H263P:
    case CODEC_ID_FLV1:
        if (ENABLE_H263_ENCODER || ENABLE_H263P_ENCODER || ENABLE_FLV_ENCODER)
            s->gob_index = ff_h263_get_gob_height(s);
        break;
    case CODEC_ID_MPEG4:
        if(ENABLE_MPEG4_ENCODER && s->partitioned_frame)
            ff_mpeg4_init_partitions(s);
        break;
    }
    s->resync_mb_x=0;
    s->resync_mb_y=0;
    s->first_slice_line = 1;
    s->ptr_lastgob = s->pb.buf;
    for(mb_y= s->start_mb_y; mb_y < s->end_mb_y; mb_y++) {
        s->mb_x=0;
        s->mb_y= mb_y;
        ff_set_qscale(s, s->qscale);
        ff_init_block_index(s);
        for(mb_x=0; mb_x < s->mb_width; mb_x++) {
            int xy= mb_y*s->mb_stride + mb_x;
            int mb_type= s->mb_type[xy];
            int dmin= INT_MAX;
            int dir;
            if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < MAX_MB_BYTES){
                av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
                return -1;
            }
            if(s->data_partitioning){
                if(   s->pb2   .buf_end - s->pb2   .buf - (put_bits_count(&s->    pb2)>>3) < MAX_MB_BYTES
                   || s->tex_pb.buf_end - s->tex_pb.buf - (put_bits_count(&s->tex_pb )>>3) < MAX_MB_BYTES){
                    av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
                    return -1;
                }
            }
            s->mb_x = mb_x;
            s->mb_y = mb_y;
            ff_update_block_index(s);
            if(ENABLE_H261_ENCODER && s->codec_id == CODEC_ID_H261){
                ff_h261_reorder_mb_index(s);
                xy= s->mb_y*s->mb_stride + s->mb_x;
                mb_type= s->mb_type[xy];
            }
            if(s->rtp_mode){
                int current_packet_size, is_gob_start;
                current_packet_size= ((put_bits_count(&s->pb)+7)>>3) - (s->ptr_lastgob - s->pb.buf);
                is_gob_start= s->avctx->rtp_payload_size && current_packet_size >= s->avctx->rtp_payload_size && mb_y + mb_x>0;
                if(s->start_mb_y == mb_y && mb_y > 0 && mb_x==0) is_gob_start=1;
                switch(s->codec_id){
                case CODEC_ID_H263:
                case CODEC_ID_H263P:
                    if(!s->h263_slice_structured)
                        if(s->mb_x || s->mb_y%s->gob_index) is_gob_start=0;
                    break;
                case CODEC_ID_MPEG2VIDEO:
                    if(s->mb_x==0 && s->mb_y!=0) is_gob_start=1;
                case CODEC_ID_MPEG1VIDEO:
                    if(s->mb_skip_run) is_gob_start=0;
                    break;
                }
                if(is_gob_start){
                    if(s->start_mb_y != mb_y || mb_x!=0){
                        write_slice_end(s);
                        if(ENABLE_MPEG4_ENCODER && s->codec_id==CODEC_ID_MPEG4 && s->partitioned_frame){
                            ff_mpeg4_init_partitions(s);
                        }
                    }
                    assert((put_bits_count(&s->pb)&7) == 0);
                    current_packet_size= pbBufPtr(&s->pb) - s->ptr_lastgob;
                    if(s->avctx->error_rate && s->resync_mb_x + s->resync_mb_y > 0){
                        int r= put_bits_count(&s->pb)/8 + s->picture_number + 16 + s->mb_x + s->mb_y;
                        int d= 100 / s->avctx->error_rate;
                        if(r % d == 0){
                            current_packet_size=0;
#ifndef ALT_BITSTREAM_WRITER
                            s->pb.buf_ptr= s->ptr_lastgob;
#endif
                            assert(pbBufPtr(&s->pb) == s->ptr_lastgob);
                        }
                    }
                    if (s->avctx->rtp_callback){
                        int number_mb = (mb_y - s->resync_mb_y)*s->mb_width + mb_x - s->resync_mb_x;
                        s->avctx->rtp_callback(s->avctx, s->ptr_lastgob, current_packet_size, number_mb);
                    }
                    switch(s->codec_id){
                    case CODEC_ID_MPEG4:
                        if (ENABLE_MPEG4_ENCODER) {
                            ff_mpeg4_encode_video_packet_header(s);
                            ff_mpeg4_clean_buffers(s);
                        }
                    break;
                    case CODEC_ID_MPEG1VIDEO:
                    case CODEC_ID_MPEG2VIDEO:
                        if (ENABLE_MPEG1VIDEO_ENCODER || ENABLE_MPEG2VIDEO_ENCODER) {
                            ff_mpeg1_encode_slice_header(s);
                            ff_mpeg1_clean_buffers(s);
                        }
                    break;
                    case CODEC_ID_H263:
                    case CODEC_ID_H263P:
                        if (ENABLE_H263_ENCODER || ENABLE_H263P_ENCODER)
                            h263_encode_gob_header(s, mb_y);
                    break;
                    }
                    if(s->flags&CODEC_FLAG_PASS1){
                        int bits= put_bits_count(&s->pb);
                        s->misc_bits+= bits - s->last_bits;
                        s->last_bits= bits;
                    }
                    s->ptr_lastgob += current_packet_size;
                    s->first_slice_line=1;
                    s->resync_mb_x=mb_x;
                    s->resync_mb_y=mb_y;
                }
            }
            if(  (s->resync_mb_x   == s->mb_x)
               && s->resync_mb_y+1 == s->mb_y){
                s->first_slice_line=0;
            }
            s->mb_skipped=0;
            s->dquant=0;
            if(mb_type & (mb_type-1) || (s->flags & CODEC_FLAG_QP_RD)){
                int next_block=0;
                int pb_bits_count, pb2_bits_count, tex_pb_bits_count;
                copy_context_before_encode(&backup_s, s, -1);
                backup_s.pb= s->pb;
                best_s.data_partitioning= s->data_partitioning;
                best_s.partitioned_frame= s->partitioned_frame;
                if(s->data_partitioning){
                    backup_s.pb2= s->pb2;
                    backup_s.tex_pb= s->tex_pb;
                }
                if(mb_type&CANDIDATE_MB_TYPE_INTER){
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mv_type = MV_TYPE_16X16;
                    s->mb_intra= 0;
                    s->mv[0][0][0] = s->p_mv_table[xy][0];
                    s->mv[0][0][1] = s->p_mv_table[xy][1];
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER, pb, pb2, tex_pb,
                                 &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]);
                }
                if(mb_type&CANDIDATE_MB_TYPE_INTER_I){
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mv_type = MV_TYPE_FIELD;
                    s->mb_intra= 0;
                    for(i=0; i<2; i++){
                        j= s->field_select[0][i] = s->p_field_select_table[i][xy];
                        s->mv[0][i][0] = s->p_field_mv_table[i][j][xy][0];
                        s->mv[0][i][1] = s->p_field_mv_table[i][j][xy][1];
                    }
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER_I, pb, pb2, tex_pb,
                                 &dmin, &next_block, 0, 0);
                }
                if(mb_type&CANDIDATE_MB_TYPE_SKIPPED){
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mv_type = MV_TYPE_16X16;
                    s->mb_intra= 0;
                    s->mv[0][0][0] = 0;
                    s->mv[0][0][1] = 0;
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_SKIPPED, pb, pb2, tex_pb,
                                 &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]);
                }
                if(mb_type&CANDIDATE_MB_TYPE_INTER4V){
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mv_type = MV_TYPE_8X8;
                    s->mb_intra= 0;
                    for(i=0; i<4; i++){
                        s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0];
                        s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1];
                    }
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER4V, pb, pb2, tex_pb,
                                 &dmin, &next_block, 0, 0);
                }
                if(mb_type&CANDIDATE_MB_TYPE_FORWARD){
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mv_type = MV_TYPE_16X16;
                    s->mb_intra= 0;
                    s->mv[0][0][0] = s->b_forw_mv_table[xy][0];
                    s->mv[0][0][1] = s->b_forw_mv_table[xy][1];
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_FORWARD, pb, pb2, tex_pb,
                                 &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]);
                }
                if(mb_type&CANDIDATE_MB_TYPE_BACKWARD){
                    s->mv_dir = MV_DIR_BACKWARD;
                    s->mv_type = MV_TYPE_16X16;
                    s->mb_intra= 0;
                    s->mv[1][0][0] = s->b_back_mv_table[xy][0];
                    s->mv[1][0][1] = s->b_back_mv_table[xy][1];
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BACKWARD, pb, pb2, tex_pb,
                                 &dmin, &next_block, s->mv[1][0][0], s->mv[1][0][1]);
                }
                if(mb_type&CANDIDATE_MB_TYPE_BIDIR){
                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
                    s->mv_type = MV_TYPE_16X16;
                    s->mb_intra= 0;
                    s->mv[0][0][0] = s->b_bidir_forw_mv_table[xy][0];
                    s->mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1];
                    s->mv[1][0][0] = s->b_bidir_back_mv_table[xy][0];
                    s->mv[1][0][1] = s->b_bidir_back_mv_table[xy][1];
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BIDIR, pb, pb2, tex_pb,
                                 &dmin, &next_block, 0, 0);
                }
                if(mb_type&CANDIDATE_MB_TYPE_FORWARD_I){
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mv_type = MV_TYPE_FIELD;
                    s->mb_intra= 0;
                    for(i=0; i<2; i++){
                        j= s->field_select[0][i] = s->b_field_select_table[0][i][xy];
                        s->mv[0][i][0] = s->b_field_mv_table[0][i][j][xy][0];
                        s->mv[0][i][1] = s->b_field_mv_table[0][i][j][xy][1];
                    }
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_FORWARD_I, pb, pb2, tex_pb,
                                 &dmin, &next_block, 0, 0);
                }
                if(mb_type&CANDIDATE_MB_TYPE_BACKWARD_I){
                    s->mv_dir = MV_DIR_BACKWARD;
                    s->mv_type = MV_TYPE_FIELD;
                    s->mb_intra= 0;
                    for(i=0; i<2; i++){
                        j= s->field_select[1][i] = s->b_field_select_table[1][i][xy];
                        s->mv[1][i][0] = s->b_field_mv_table[1][i][j][xy][0];
                        s->mv[1][i][1] = s->b_field_mv_table[1][i][j][xy][1];
                    }
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BACKWARD_I, pb, pb2, tex_pb,
                                 &dmin, &next_block, 0, 0);
                }
                if(mb_type&CANDIDATE_MB_TYPE_BIDIR_I){
                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
                    s->mv_type = MV_TYPE_FIELD;
                    s->mb_intra= 0;
                    for(dir=0; dir<2; dir++){
                        for(i=0; i<2; i++){
                            j= s->field_select[dir][i] = s->b_field_select_table[dir][i][xy];
                            s->mv[dir][i][0] = s->b_field_mv_table[dir][i][j][xy][0];
                            s->mv[dir][i][1] = s->b_field_mv_table[dir][i][j][xy][1];
                        }
                    }
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BIDIR_I, pb, pb2, tex_pb,
                                 &dmin, &next_block, 0, 0);
                }
                if(mb_type&CANDIDATE_MB_TYPE_INTRA){
                    s->mv_dir = 0;
                    s->mv_type = MV_TYPE_16X16;
                    s->mb_intra= 1;
                    s->mv[0][0][0] = 0;
                    s->mv[0][0][1] = 0;
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTRA, pb, pb2, tex_pb,
                                 &dmin, &next_block, 0, 0);
                    if(s->h263_pred || s->h263_aic){
                        if(best_s.mb_intra)
                            s->mbintra_table[mb_x + mb_y*s->mb_stride]=1;
                        else
                            ff_clean_intra_table_entries(s);
                    }
                }
                if((s->flags & CODEC_FLAG_QP_RD) && dmin < INT_MAX){
                    if(best_s.mv_type==MV_TYPE_16X16){
                        const int last_qp= backup_s.qscale;
                        int qpi, qp, dc[6];
                        DCTELEM ac[6][16];
                        const int mvdir= (best_s.mv_dir&MV_DIR_BACKWARD) ? 1 : 0;
                        static const int dquant_tab[4]={-1,1,-2,2};
                        assert(backup_s.dquant == 0);
                        s->mv_dir= best_s.mv_dir;
                        s->mv_type = MV_TYPE_16X16;
                        s->mb_intra= best_s.mb_intra;
                        s->mv[0][0][0] = best_s.mv[0][0][0];
                        s->mv[0][0][1] = best_s.mv[0][0][1];
                        s->mv[1][0][0] = best_s.mv[1][0][0];
                        s->mv[1][0][1] = best_s.mv[1][0][1];
                        qpi = s->pict_type == FF_B_TYPE ? 2 : 0;
                        for(; qpi<4; qpi++){
                            int dquant= dquant_tab[qpi];
                            qp= last_qp + dquant;
                            if(qp < s->avctx->qmin || qp > s->avctx->qmax)
                                continue;
                            backup_s.dquant= dquant;
                            if(s->mb_intra && s->dc_val[0]){
                                for(i=0; i<6; i++){
                                    dc[i]= s->dc_val[0][ s->block_index[i] ];
                                    memcpy(ac[i], s->ac_val[0][s->block_index[i]], sizeof(DCTELEM)*16);
                                }
                            }
                            encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER  , pb, pb2, tex_pb,
                                         &dmin, &next_block, s->mv[mvdir][0][0], s->mv[mvdir][0][1]);
                            if(best_s.qscale != qp){
                                if(s->mb_intra && s->dc_val[0]){
                                    for(i=0; i<6; i++){
                                        s->dc_val[0][ s->block_index[i] ]= dc[i];
                                        memcpy(s->ac_val[0][s->block_index[i]], ac[i], sizeof(DCTELEM)*16);
                                    }
                                }
                            }
                        }
                    }
                }
                if(ENABLE_MPEG4_ENCODER && mb_type&CANDIDATE_MB_TYPE_DIRECT){
                    int mx= s->b_direct_mv_table[xy][0];
                    int my= s->b_direct_mv_table[xy][1];
                    backup_s.dquant = 0;
                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
                    s->mb_intra= 0;
                    ff_mpeg4_set_direct_mv(s, mx, my);
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_DIRECT, pb, pb2, tex_pb,
                                 &dmin, &next_block, mx, my);
                }
                if(ENABLE_MPEG4_ENCODER && mb_type&CANDIDATE_MB_TYPE_DIRECT0){
                    backup_s.dquant = 0;
                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
                    s->mb_intra= 0;
                    ff_mpeg4_set_direct_mv(s, 0, 0);
                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_DIRECT, pb, pb2, tex_pb,
                                 &dmin, &next_block, 0, 0);
                }
                if(!best_s.mb_intra && s->flags2&CODEC_FLAG2_SKIP_RD){
                    int coded=0;
                    for(i=0; i<6; i++)
                        coded |= s->block_last_index[i];
                    if(coded){
                        int mx,my;
                        memcpy(s->mv, best_s.mv, sizeof(s->mv));
                        if(ENABLE_MPEG4_ENCODER && best_s.mv_dir & MV_DIRECT){
                            mx=my=0;
                            ff_mpeg4_set_direct_mv(s, mx, my);
                        }else if(best_s.mv_dir&MV_DIR_BACKWARD){
                            mx= s->mv[1][0][0];
                            my= s->mv[1][0][1];
                        }else{
                            mx= s->mv[0][0][0];
                            my= s->mv[0][0][1];
                        }
                        s->mv_dir= best_s.mv_dir;
                        s->mv_type = best_s.mv_type;
                        s->mb_intra= 0;
                        backup_s.dquant= 0;
                        s->skipdct=1;
                        encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER  , pb, pb2, tex_pb,
                                        &dmin, &next_block, mx, my);
                        s->skipdct=0;
                    }
                }
                s->current_picture.qscale_table[xy]= best_s.qscale;
                copy_context_after_encode(s, &best_s, -1);
                pb_bits_count= put_bits_count(&s->pb);
                flush_put_bits(&s->pb);
                ff_copy_bits(&backup_s.pb, bit_buf[next_block^1], pb_bits_count);
                s->pb= backup_s.pb;
                if(s->data_partitioning){
                    pb2_bits_count= put_bits_count(&s->pb2);
                    flush_put_bits(&s->pb2);
                    ff_copy_bits(&backup_s.pb2, bit_buf2[next_block^1], pb2_bits_count);
                    s->pb2= backup_s.pb2;
                    tex_pb_bits_count= put_bits_count(&s->tex_pb);
                    flush_put_bits(&s->tex_pb);
                    ff_copy_bits(&backup_s.tex_pb, bit_buf_tex[next_block^1], tex_pb_bits_count);
                    s->tex_pb= backup_s.tex_pb;
                }
                s->last_bits= put_bits_count(&s->pb);
                if (ENABLE_ANY_H263_ENCODER &&
                    s->out_format == FMT_H263 && s->pict_type!=FF_B_TYPE)
                    ff_h263_update_motion_val(s);
                if(next_block==0){
                    s->dsp.put_pixels_tab[0][0](s->dest[0], s->rd_scratchpad                     , s->linesize  ,16);
                    s->dsp.put_pixels_tab[1][0](s->dest[1], s->rd_scratchpad + 16*s->linesize    , s->uvlinesize, 8);
                    s->dsp.put_pixels_tab[1][0](s->dest[2], s->rd_scratchpad + 16*s->linesize + 8, s->uvlinesize, 8);
                }
                if(s->avctx->mb_decision == FF_MB_DECISION_BITS)
                    MPV_decode_mb(s, s->block);
            } else {
                int motion_x = 0, motion_y = 0;
                s->mv_type=MV_TYPE_16X16;
                switch(mb_type){
                case CANDIDATE_MB_TYPE_INTRA:
                    s->mv_dir = 0;
                    s->mb_intra= 1;
                    motion_x= s->mv[0][0][0] = 0;
                    motion_y= s->mv[0][0][1] = 0;
                    break;
                case CANDIDATE_MB_TYPE_INTER:
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mb_intra= 0;
                    motion_x= s->mv[0][0][0] = s->p_mv_table[xy][0];
                    motion_y= s->mv[0][0][1] = s->p_mv_table[xy][1];
                    break;
                case CANDIDATE_MB_TYPE_INTER_I:
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mv_type = MV_TYPE_FIELD;
                    s->mb_intra= 0;
                    for(i=0; i<2; i++){
                        j= s->field_select[0][i] = s->p_field_select_table[i][xy];
                        s->mv[0][i][0] = s->p_field_mv_table[i][j][xy][0];
                        s->mv[0][i][1] = s->p_field_mv_table[i][j][xy][1];
                    }
                    break;
                case CANDIDATE_MB_TYPE_INTER4V:
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mv_type = MV_TYPE_8X8;
                    s->mb_intra= 0;
                    for(i=0; i<4; i++){
                        s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0];
                        s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1];
                    }
                    break;
                case CANDIDATE_MB_TYPE_DIRECT:
                    if (ENABLE_MPEG4_ENCODER) {
                        s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD|MV_DIRECT;
                        s->mb_intra= 0;
                        motion_x=s->b_direct_mv_table[xy][0];
                        motion_y=s->b_direct_mv_table[xy][1];
                        ff_mpeg4_set_direct_mv(s, motion_x, motion_y);
                    }
                    break;
                case CANDIDATE_MB_TYPE_DIRECT0:
                    if (ENABLE_MPEG4_ENCODER) {
                        s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD|MV_DIRECT;
                        s->mb_intra= 0;
                        ff_mpeg4_set_direct_mv(s, 0, 0);
                    }
                    break;
                case CANDIDATE_MB_TYPE_BIDIR:
                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
                    s->mb_intra= 0;
                    s->mv[0][0][0] = s->b_bidir_forw_mv_table[xy][0];
                    s->mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1];
                    s->mv[1][0][0] = s->b_bidir_back_mv_table[xy][0];
                    s->mv[1][0][1] = s->b_bidir_back_mv_table[xy][1];
                    break;
                case CANDIDATE_MB_TYPE_BACKWARD:
                    s->mv_dir = MV_DIR_BACKWARD;
                    s->mb_intra= 0;
                    motion_x= s->mv[1][0][0] = s->b_back_mv_table[xy][0];
                    motion_y= s->mv[1][0][1] = s->b_back_mv_table[xy][1];
                    break;
                case CANDIDATE_MB_TYPE_FORWARD:
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mb_intra= 0;
                    motion_x= s->mv[0][0][0] = s->b_forw_mv_table[xy][0];
                    motion_y= s->mv[0][0][1] = s->b_forw_mv_table[xy][1];
                    break;
                case CANDIDATE_MB_TYPE_FORWARD_I:
                    s->mv_dir = MV_DIR_FORWARD;
                    s->mv_type = MV_TYPE_FIELD;
                    s->mb_intra= 0;
                    for(i=0; i<2; i++){
                        j= s->field_select[0][i] = s->b_field_select_table[0][i][xy];
                        s->mv[0][i][0] = s->b_field_mv_table[0][i][j][xy][0];
                        s->mv[0][i][1] = s->b_field_mv_table[0][i][j][xy][1];
                    }
                    break;
                case CANDIDATE_MB_TYPE_BACKWARD_I:
                    s->mv_dir = MV_DIR_BACKWARD;
                    s->mv_type = MV_TYPE_FIELD;
                    s->mb_intra= 0;
                    for(i=0; i<2; i++){
                        j= s->field_select[1][i] = s->b_field_select_table[1][i][xy];
                        s->mv[1][i][0] = s->b_field_mv_table[1][i][j][xy][0];
                        s->mv[1][i][1] = s->b_field_mv_table[1][i][j][xy][1];
                    }
                    break;
                case CANDIDATE_MB_TYPE_BIDIR_I:
                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;
                    s->mv_type = MV_TYPE_FIELD;
                    s->mb_intra= 0;
                    for(dir=0; dir<2; dir++){
                        for(i=0; i<2; i++){
                            j= s->field_select[dir][i] = s->b_field_select_table[dir][i][xy];
                            s->mv[dir][i][0] = s->b_field_mv_table[dir][i][j][xy][0];
                            s->mv[dir][i][1] = s->b_field_mv_table[dir][i][j][xy][1];
                        }
                    }
                    break;
                default:
                    av_log(s->avctx, AV_LOG_ERROR, "illegal MB type\n");
                }
                encode_mb(s, motion_x, motion_y);
                s->last_mv_dir = s->mv_dir;
                if (ENABLE_ANY_H263_ENCODER &&
                    s->out_format == FMT_H263 && s->pict_type!=FF_B_TYPE)
                    ff_h263_update_motion_val(s);
                MPV_decode_mb(s, s->block);
            }
            if(s->mb_intra  ){
                s->p_mv_table[xy][0]=0;
                s->p_mv_table[xy][1]=0;
            }
            if(s->flags&CODEC_FLAG_PSNR){
                int w= 16;
                int h= 16;
                if(s->mb_x*16 + 16 > s->width ) w= s->width - s->mb_x*16;
                if(s->mb_y*16 + 16 > s->height) h= s->height- s->mb_y*16;
                s->current_picture.error[0] += sse(
                    s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16,
                    s->dest[0], w, h, s->linesize);
                s->current_picture.error[1] += sse(
                    s, s->new_picture.data[1] + s->mb_x*8  + s->mb_y*s->uvlinesize*8,
                    s->dest[1], w>>1, h>>1, s->uvlinesize);
                s->current_picture.error[2] += sse(
                    s, s->new_picture    .data[2] + s->mb_x*8  + s->mb_y*s->uvlinesize*8,
                    s->dest[2], w>>1, h>>1, s->uvlinesize);
            }
            if(s->loop_filter){
                if(ENABLE_ANY_H263_ENCODER && s->out_format == FMT_H263)
                    ff_h263_loop_filter(s);
            }
        }
    }
    if (ENABLE_MSMPEG4_ENCODER && s->msmpeg4_version && s->msmpeg4_version<4 && s->pict_type == FF_I_TYPE)
        msmpeg4_encode_ext_header(s);
    write_slice_end(s);
    if (s->avctx->rtp_callback) {
        int number_mb = (mb_y - s->resync_mb_y)*s->mb_width - s->resync_mb_x;
        pdif = pbBufPtr(&s->pb) - s->ptr_lastgob;
        emms_c();
        s->avctx->rtp_callback(s->avctx, s->ptr_lastgob, pdif, number_mb);
    }
    return 0;
}
['static int encode_thread(AVCodecContext *c, void *arg){\n    MpegEncContext *s= arg;\n    int mb_x, mb_y, pdif = 0;\n    int i, j;\n    MpegEncContext best_s, backup_s;\n    uint8_t bit_buf[2][MAX_MB_BYTES];\n    uint8_t bit_buf2[2][MAX_MB_BYTES];\n    uint8_t bit_buf_tex[2][MAX_MB_BYTES];\n    PutBitContext pb[2], pb2[2], tex_pb[2];\n    ff_check_alignment();\n    for(i=0; i<2; i++){\n        init_put_bits(&pb    [i], bit_buf    [i], MAX_MB_BYTES);\n        init_put_bits(&pb2   [i], bit_buf2   [i], MAX_MB_BYTES);\n        init_put_bits(&tex_pb[i], bit_buf_tex[i], MAX_MB_BYTES);\n    }\n    s->last_bits= put_bits_count(&s->pb);\n    s->mv_bits=0;\n    s->misc_bits=0;\n    s->i_tex_bits=0;\n    s->p_tex_bits=0;\n    s->i_count=0;\n    s->f_count=0;\n    s->b_count=0;\n    s->skip_count=0;\n    for(i=0; i<3; i++){\n        s->last_dc[i] = 128 << s->intra_dc_precision;\n        s->current_picture.error[i] = 0;\n    }\n    s->mb_skip_run = 0;\n    memset(s->last_mv, 0, sizeof(s->last_mv));\n    s->last_mv_dir = 0;\n    switch(s->codec_id){\n    case CODEC_ID_H263:\n    case CODEC_ID_H263P:\n    case CODEC_ID_FLV1:\n        if (ENABLE_H263_ENCODER || ENABLE_H263P_ENCODER || ENABLE_FLV_ENCODER)\n            s->gob_index = ff_h263_get_gob_height(s);\n        break;\n    case CODEC_ID_MPEG4:\n        if(ENABLE_MPEG4_ENCODER && s->partitioned_frame)\n            ff_mpeg4_init_partitions(s);\n        break;\n    }\n    s->resync_mb_x=0;\n    s->resync_mb_y=0;\n    s->first_slice_line = 1;\n    s->ptr_lastgob = s->pb.buf;\n    for(mb_y= s->start_mb_y; mb_y < s->end_mb_y; mb_y++) {\n        s->mb_x=0;\n        s->mb_y= mb_y;\n        ff_set_qscale(s, s->qscale);\n        ff_init_block_index(s);\n        for(mb_x=0; mb_x < s->mb_width; mb_x++) {\n            int xy= mb_y*s->mb_stride + mb_x;\n            int mb_type= s->mb_type[xy];\n            int dmin= INT_MAX;\n            int dir;\n            if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < MAX_MB_BYTES){\n                av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\\n");\n                return -1;\n            }\n            if(s->data_partitioning){\n                if(   s->pb2   .buf_end - s->pb2   .buf - (put_bits_count(&s->    pb2)>>3) < MAX_MB_BYTES\n                   || s->tex_pb.buf_end - s->tex_pb.buf - (put_bits_count(&s->tex_pb )>>3) < MAX_MB_BYTES){\n                    av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\\n");\n                    return -1;\n                }\n            }\n            s->mb_x = mb_x;\n            s->mb_y = mb_y;\n            ff_update_block_index(s);\n            if(ENABLE_H261_ENCODER && s->codec_id == CODEC_ID_H261){\n                ff_h261_reorder_mb_index(s);\n                xy= s->mb_y*s->mb_stride + s->mb_x;\n                mb_type= s->mb_type[xy];\n            }\n            if(s->rtp_mode){\n                int current_packet_size, is_gob_start;\n                current_packet_size= ((put_bits_count(&s->pb)+7)>>3) - (s->ptr_lastgob - s->pb.buf);\n                is_gob_start= s->avctx->rtp_payload_size && current_packet_size >= s->avctx->rtp_payload_size && mb_y + mb_x>0;\n                if(s->start_mb_y == mb_y && mb_y > 0 && mb_x==0) is_gob_start=1;\n                switch(s->codec_id){\n                case CODEC_ID_H263:\n                case CODEC_ID_H263P:\n                    if(!s->h263_slice_structured)\n                        if(s->mb_x || s->mb_y%s->gob_index) is_gob_start=0;\n                    break;\n                case CODEC_ID_MPEG2VIDEO:\n                    if(s->mb_x==0 && s->mb_y!=0) is_gob_start=1;\n                case CODEC_ID_MPEG1VIDEO:\n                    if(s->mb_skip_run) is_gob_start=0;\n                    break;\n                }\n                if(is_gob_start){\n                    if(s->start_mb_y != mb_y || mb_x!=0){\n                        write_slice_end(s);\n                        if(ENABLE_MPEG4_ENCODER && s->codec_id==CODEC_ID_MPEG4 && s->partitioned_frame){\n                            ff_mpeg4_init_partitions(s);\n                        }\n                    }\n                    assert((put_bits_count(&s->pb)&7) == 0);\n                    current_packet_size= pbBufPtr(&s->pb) - s->ptr_lastgob;\n                    if(s->avctx->error_rate && s->resync_mb_x + s->resync_mb_y > 0){\n                        int r= put_bits_count(&s->pb)/8 + s->picture_number + 16 + s->mb_x + s->mb_y;\n                        int d= 100 / s->avctx->error_rate;\n                        if(r % d == 0){\n                            current_packet_size=0;\n#ifndef ALT_BITSTREAM_WRITER\n                            s->pb.buf_ptr= s->ptr_lastgob;\n#endif\n                            assert(pbBufPtr(&s->pb) == s->ptr_lastgob);\n                        }\n                    }\n                    if (s->avctx->rtp_callback){\n                        int number_mb = (mb_y - s->resync_mb_y)*s->mb_width + mb_x - s->resync_mb_x;\n                        s->avctx->rtp_callback(s->avctx, s->ptr_lastgob, current_packet_size, number_mb);\n                    }\n                    switch(s->codec_id){\n                    case CODEC_ID_MPEG4:\n                        if (ENABLE_MPEG4_ENCODER) {\n                            ff_mpeg4_encode_video_packet_header(s);\n                            ff_mpeg4_clean_buffers(s);\n                        }\n                    break;\n                    case CODEC_ID_MPEG1VIDEO:\n                    case CODEC_ID_MPEG2VIDEO:\n                        if (ENABLE_MPEG1VIDEO_ENCODER || ENABLE_MPEG2VIDEO_ENCODER) {\n                            ff_mpeg1_encode_slice_header(s);\n                            ff_mpeg1_clean_buffers(s);\n                        }\n                    break;\n                    case CODEC_ID_H263:\n                    case CODEC_ID_H263P:\n                        if (ENABLE_H263_ENCODER || ENABLE_H263P_ENCODER)\n                            h263_encode_gob_header(s, mb_y);\n                    break;\n                    }\n                    if(s->flags&CODEC_FLAG_PASS1){\n                        int bits= put_bits_count(&s->pb);\n                        s->misc_bits+= bits - s->last_bits;\n                        s->last_bits= bits;\n                    }\n                    s->ptr_lastgob += current_packet_size;\n                    s->first_slice_line=1;\n                    s->resync_mb_x=mb_x;\n                    s->resync_mb_y=mb_y;\n                }\n            }\n            if(  (s->resync_mb_x   == s->mb_x)\n               && s->resync_mb_y+1 == s->mb_y){\n                s->first_slice_line=0;\n            }\n            s->mb_skipped=0;\n            s->dquant=0;\n            if(mb_type & (mb_type-1) || (s->flags & CODEC_FLAG_QP_RD)){\n                int next_block=0;\n                int pb_bits_count, pb2_bits_count, tex_pb_bits_count;\n                copy_context_before_encode(&backup_s, s, -1);\n                backup_s.pb= s->pb;\n                best_s.data_partitioning= s->data_partitioning;\n                best_s.partitioned_frame= s->partitioned_frame;\n                if(s->data_partitioning){\n                    backup_s.pb2= s->pb2;\n                    backup_s.tex_pb= s->tex_pb;\n                }\n                if(mb_type&CANDIDATE_MB_TYPE_INTER){\n                    s->mv_dir = MV_DIR_FORWARD;\n                    s->mv_type = MV_TYPE_16X16;\n                    s->mb_intra= 0;\n                    s->mv[0][0][0] = s->p_mv_table[xy][0];\n                    s->mv[0][0][1] = s->p_mv_table[xy][1];\n                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER, pb, pb2, tex_pb,\n                                 &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]);\n                }\n                if(mb_type&CANDIDATE_MB_TYPE_INTER_I){\n                    s->mv_dir = MV_DIR_FORWARD;\n                    s->mv_type = MV_TYPE_FIELD;\n                    s->mb_intra= 0;\n                    for(i=0; i<2; i++){\n                        j= s->field_select[0][i] = s->p_field_select_table[i][xy];\n                        s->mv[0][i][0] = s->p_field_mv_table[i][j][xy][0];\n                        s->mv[0][i][1] = s->p_field_mv_table[i][j][xy][1];\n                    }\n                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER_I, pb, pb2, tex_pb,\n                                 &dmin, &next_block, 0, 0);\n                }\n                if(mb_type&CANDIDATE_MB_TYPE_SKIPPED){\n                    s->mv_dir = MV_DIR_FORWARD;\n                    s->mv_type = MV_TYPE_16X16;\n                    s->mb_intra= 0;\n                    s->mv[0][0][0] = 0;\n                    s->mv[0][0][1] = 0;\n                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_SKIPPED, pb, pb2, tex_pb,\n                                 &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]);\n                }\n                if(mb_type&CANDIDATE_MB_TYPE_INTER4V){\n                    s->mv_dir = MV_DIR_FORWARD;\n                    s->mv_type = MV_TYPE_8X8;\n                    s->mb_intra= 0;\n                    for(i=0; i<4; i++){\n                        s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0];\n                        s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1];\n                    }\n                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER4V, pb, pb2, tex_pb,\n                                 &dmin, &next_block, 0, 0);\n                }\n                if(mb_type&CANDIDATE_MB_TYPE_FORWARD){\n                    s->mv_dir = MV_DIR_FORWARD;\n                    s->mv_type = MV_TYPE_16X16;\n                    s->mb_intra= 0;\n                    s->mv[0][0][0] = s->b_forw_mv_table[xy][0];\n                    s->mv[0][0][1] = s->b_forw_mv_table[xy][1];\n                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_FORWARD, pb, pb2, tex_pb,\n                                 &dmin, &next_block, s->mv[0][0][0], s->mv[0][0][1]);\n                }\n                if(mb_type&CANDIDATE_MB_TYPE_BACKWARD){\n                    s->mv_dir = MV_DIR_BACKWARD;\n                    s->mv_type = MV_TYPE_16X16;\n                    s->mb_intra= 0;\n                    s->mv[1][0][0] = s->b_back_mv_table[xy][0];\n                    s->mv[1][0][1] = s->b_back_mv_table[xy][1];\n                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BACKWARD, pb, pb2, tex_pb,\n                                 &dmin, &next_block, s->mv[1][0][0], s->mv[1][0][1]);\n                }\n                if(mb_type&CANDIDATE_MB_TYPE_BIDIR){\n                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;\n                    s->mv_type = MV_TYPE_16X16;\n                    s->mb_intra= 0;\n                    s->mv[0][0][0] = s->b_bidir_forw_mv_table[xy][0];\n                    s->mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1];\n                    s->mv[1][0][0] = s->b_bidir_back_mv_table[xy][0];\n                    s->mv[1][0][1] = s->b_bidir_back_mv_table[xy][1];\n                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BIDIR, pb, pb2, tex_pb,\n                                 &dmin, &next_block, 0, 0);\n                }\n                if(mb_type&CANDIDATE_MB_TYPE_FORWARD_I){\n                    s->mv_dir = MV_DIR_FORWARD;\n                    s->mv_type = MV_TYPE_FIELD;\n                    s->mb_intra= 0;\n                    for(i=0; i<2; i++){\n                        j= s->field_select[0][i] = s->b_field_select_table[0][i][xy];\n                        s->mv[0][i][0] = s->b_field_mv_table[0][i][j][xy][0];\n                        s->mv[0][i][1] = s->b_field_mv_table[0][i][j][xy][1];\n                    }\n                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_FORWARD_I, pb, pb2, tex_pb,\n                                 &dmin, &next_block, 0, 0);\n                }\n                if(mb_type&CANDIDATE_MB_TYPE_BACKWARD_I){\n                    s->mv_dir = MV_DIR_BACKWARD;\n                    s->mv_type = MV_TYPE_FIELD;\n                    s->mb_intra= 0;\n                    for(i=0; i<2; i++){\n                        j= s->field_select[1][i] = s->b_field_select_table[1][i][xy];\n                        s->mv[1][i][0] = s->b_field_mv_table[1][i][j][xy][0];\n                        s->mv[1][i][1] = s->b_field_mv_table[1][i][j][xy][1];\n                    }\n                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BACKWARD_I, pb, pb2, tex_pb,\n                                 &dmin, &next_block, 0, 0);\n                }\n                if(mb_type&CANDIDATE_MB_TYPE_BIDIR_I){\n                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;\n                    s->mv_type = MV_TYPE_FIELD;\n                    s->mb_intra= 0;\n                    for(dir=0; dir<2; dir++){\n                        for(i=0; i<2; i++){\n                            j= s->field_select[dir][i] = s->b_field_select_table[dir][i][xy];\n                            s->mv[dir][i][0] = s->b_field_mv_table[dir][i][j][xy][0];\n                            s->mv[dir][i][1] = s->b_field_mv_table[dir][i][j][xy][1];\n                        }\n                    }\n                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_BIDIR_I, pb, pb2, tex_pb,\n                                 &dmin, &next_block, 0, 0);\n                }\n                if(mb_type&CANDIDATE_MB_TYPE_INTRA){\n                    s->mv_dir = 0;\n                    s->mv_type = MV_TYPE_16X16;\n                    s->mb_intra= 1;\n                    s->mv[0][0][0] = 0;\n                    s->mv[0][0][1] = 0;\n                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTRA, pb, pb2, tex_pb,\n                                 &dmin, &next_block, 0, 0);\n                    if(s->h263_pred || s->h263_aic){\n                        if(best_s.mb_intra)\n                            s->mbintra_table[mb_x + mb_y*s->mb_stride]=1;\n                        else\n                            ff_clean_intra_table_entries(s);\n                    }\n                }\n                if((s->flags & CODEC_FLAG_QP_RD) && dmin < INT_MAX){\n                    if(best_s.mv_type==MV_TYPE_16X16){\n                        const int last_qp= backup_s.qscale;\n                        int qpi, qp, dc[6];\n                        DCTELEM ac[6][16];\n                        const int mvdir= (best_s.mv_dir&MV_DIR_BACKWARD) ? 1 : 0;\n                        static const int dquant_tab[4]={-1,1,-2,2};\n                        assert(backup_s.dquant == 0);\n                        s->mv_dir= best_s.mv_dir;\n                        s->mv_type = MV_TYPE_16X16;\n                        s->mb_intra= best_s.mb_intra;\n                        s->mv[0][0][0] = best_s.mv[0][0][0];\n                        s->mv[0][0][1] = best_s.mv[0][0][1];\n                        s->mv[1][0][0] = best_s.mv[1][0][0];\n                        s->mv[1][0][1] = best_s.mv[1][0][1];\n                        qpi = s->pict_type == FF_B_TYPE ? 2 : 0;\n                        for(; qpi<4; qpi++){\n                            int dquant= dquant_tab[qpi];\n                            qp= last_qp + dquant;\n                            if(qp < s->avctx->qmin || qp > s->avctx->qmax)\n                                continue;\n                            backup_s.dquant= dquant;\n                            if(s->mb_intra && s->dc_val[0]){\n                                for(i=0; i<6; i++){\n                                    dc[i]= s->dc_val[0][ s->block_index[i] ];\n                                    memcpy(ac[i], s->ac_val[0][s->block_index[i]], sizeof(DCTELEM)*16);\n                                }\n                            }\n                            encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER  , pb, pb2, tex_pb,\n                                         &dmin, &next_block, s->mv[mvdir][0][0], s->mv[mvdir][0][1]);\n                            if(best_s.qscale != qp){\n                                if(s->mb_intra && s->dc_val[0]){\n                                    for(i=0; i<6; i++){\n                                        s->dc_val[0][ s->block_index[i] ]= dc[i];\n                                        memcpy(s->ac_val[0][s->block_index[i]], ac[i], sizeof(DCTELEM)*16);\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n                if(ENABLE_MPEG4_ENCODER && mb_type&CANDIDATE_MB_TYPE_DIRECT){\n                    int mx= s->b_direct_mv_table[xy][0];\n                    int my= s->b_direct_mv_table[xy][1];\n                    backup_s.dquant = 0;\n                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;\n                    s->mb_intra= 0;\n                    ff_mpeg4_set_direct_mv(s, mx, my);\n                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_DIRECT, pb, pb2, tex_pb,\n                                 &dmin, &next_block, mx, my);\n                }\n                if(ENABLE_MPEG4_ENCODER && mb_type&CANDIDATE_MB_TYPE_DIRECT0){\n                    backup_s.dquant = 0;\n                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;\n                    s->mb_intra= 0;\n                    ff_mpeg4_set_direct_mv(s, 0, 0);\n                    encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_DIRECT, pb, pb2, tex_pb,\n                                 &dmin, &next_block, 0, 0);\n                }\n                if(!best_s.mb_intra && s->flags2&CODEC_FLAG2_SKIP_RD){\n                    int coded=0;\n                    for(i=0; i<6; i++)\n                        coded |= s->block_last_index[i];\n                    if(coded){\n                        int mx,my;\n                        memcpy(s->mv, best_s.mv, sizeof(s->mv));\n                        if(ENABLE_MPEG4_ENCODER && best_s.mv_dir & MV_DIRECT){\n                            mx=my=0;\n                            ff_mpeg4_set_direct_mv(s, mx, my);\n                        }else if(best_s.mv_dir&MV_DIR_BACKWARD){\n                            mx= s->mv[1][0][0];\n                            my= s->mv[1][0][1];\n                        }else{\n                            mx= s->mv[0][0][0];\n                            my= s->mv[0][0][1];\n                        }\n                        s->mv_dir= best_s.mv_dir;\n                        s->mv_type = best_s.mv_type;\n                        s->mb_intra= 0;\n                        backup_s.dquant= 0;\n                        s->skipdct=1;\n                        encode_mb_hq(s, &backup_s, &best_s, CANDIDATE_MB_TYPE_INTER  , pb, pb2, tex_pb,\n                                        &dmin, &next_block, mx, my);\n                        s->skipdct=0;\n                    }\n                }\n                s->current_picture.qscale_table[xy]= best_s.qscale;\n                copy_context_after_encode(s, &best_s, -1);\n                pb_bits_count= put_bits_count(&s->pb);\n                flush_put_bits(&s->pb);\n                ff_copy_bits(&backup_s.pb, bit_buf[next_block^1], pb_bits_count);\n                s->pb= backup_s.pb;\n                if(s->data_partitioning){\n                    pb2_bits_count= put_bits_count(&s->pb2);\n                    flush_put_bits(&s->pb2);\n                    ff_copy_bits(&backup_s.pb2, bit_buf2[next_block^1], pb2_bits_count);\n                    s->pb2= backup_s.pb2;\n                    tex_pb_bits_count= put_bits_count(&s->tex_pb);\n                    flush_put_bits(&s->tex_pb);\n                    ff_copy_bits(&backup_s.tex_pb, bit_buf_tex[next_block^1], tex_pb_bits_count);\n                    s->tex_pb= backup_s.tex_pb;\n                }\n                s->last_bits= put_bits_count(&s->pb);\n                if (ENABLE_ANY_H263_ENCODER &&\n                    s->out_format == FMT_H263 && s->pict_type!=FF_B_TYPE)\n                    ff_h263_update_motion_val(s);\n                if(next_block==0){\n                    s->dsp.put_pixels_tab[0][0](s->dest[0], s->rd_scratchpad                     , s->linesize  ,16);\n                    s->dsp.put_pixels_tab[1][0](s->dest[1], s->rd_scratchpad + 16*s->linesize    , s->uvlinesize, 8);\n                    s->dsp.put_pixels_tab[1][0](s->dest[2], s->rd_scratchpad + 16*s->linesize + 8, s->uvlinesize, 8);\n                }\n                if(s->avctx->mb_decision == FF_MB_DECISION_BITS)\n                    MPV_decode_mb(s, s->block);\n            } else {\n                int motion_x = 0, motion_y = 0;\n                s->mv_type=MV_TYPE_16X16;\n                switch(mb_type){\n                case CANDIDATE_MB_TYPE_INTRA:\n                    s->mv_dir = 0;\n                    s->mb_intra= 1;\n                    motion_x= s->mv[0][0][0] = 0;\n                    motion_y= s->mv[0][0][1] = 0;\n                    break;\n                case CANDIDATE_MB_TYPE_INTER:\n                    s->mv_dir = MV_DIR_FORWARD;\n                    s->mb_intra= 0;\n                    motion_x= s->mv[0][0][0] = s->p_mv_table[xy][0];\n                    motion_y= s->mv[0][0][1] = s->p_mv_table[xy][1];\n                    break;\n                case CANDIDATE_MB_TYPE_INTER_I:\n                    s->mv_dir = MV_DIR_FORWARD;\n                    s->mv_type = MV_TYPE_FIELD;\n                    s->mb_intra= 0;\n                    for(i=0; i<2; i++){\n                        j= s->field_select[0][i] = s->p_field_select_table[i][xy];\n                        s->mv[0][i][0] = s->p_field_mv_table[i][j][xy][0];\n                        s->mv[0][i][1] = s->p_field_mv_table[i][j][xy][1];\n                    }\n                    break;\n                case CANDIDATE_MB_TYPE_INTER4V:\n                    s->mv_dir = MV_DIR_FORWARD;\n                    s->mv_type = MV_TYPE_8X8;\n                    s->mb_intra= 0;\n                    for(i=0; i<4; i++){\n                        s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0];\n                        s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1];\n                    }\n                    break;\n                case CANDIDATE_MB_TYPE_DIRECT:\n                    if (ENABLE_MPEG4_ENCODER) {\n                        s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD|MV_DIRECT;\n                        s->mb_intra= 0;\n                        motion_x=s->b_direct_mv_table[xy][0];\n                        motion_y=s->b_direct_mv_table[xy][1];\n                        ff_mpeg4_set_direct_mv(s, motion_x, motion_y);\n                    }\n                    break;\n                case CANDIDATE_MB_TYPE_DIRECT0:\n                    if (ENABLE_MPEG4_ENCODER) {\n                        s->mv_dir = MV_DIR_FORWARD|MV_DIR_BACKWARD|MV_DIRECT;\n                        s->mb_intra= 0;\n                        ff_mpeg4_set_direct_mv(s, 0, 0);\n                    }\n                    break;\n                case CANDIDATE_MB_TYPE_BIDIR:\n                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;\n                    s->mb_intra= 0;\n                    s->mv[0][0][0] = s->b_bidir_forw_mv_table[xy][0];\n                    s->mv[0][0][1] = s->b_bidir_forw_mv_table[xy][1];\n                    s->mv[1][0][0] = s->b_bidir_back_mv_table[xy][0];\n                    s->mv[1][0][1] = s->b_bidir_back_mv_table[xy][1];\n                    break;\n                case CANDIDATE_MB_TYPE_BACKWARD:\n                    s->mv_dir = MV_DIR_BACKWARD;\n                    s->mb_intra= 0;\n                    motion_x= s->mv[1][0][0] = s->b_back_mv_table[xy][0];\n                    motion_y= s->mv[1][0][1] = s->b_back_mv_table[xy][1];\n                    break;\n                case CANDIDATE_MB_TYPE_FORWARD:\n                    s->mv_dir = MV_DIR_FORWARD;\n                    s->mb_intra= 0;\n                    motion_x= s->mv[0][0][0] = s->b_forw_mv_table[xy][0];\n                    motion_y= s->mv[0][0][1] = s->b_forw_mv_table[xy][1];\n                    break;\n                case CANDIDATE_MB_TYPE_FORWARD_I:\n                    s->mv_dir = MV_DIR_FORWARD;\n                    s->mv_type = MV_TYPE_FIELD;\n                    s->mb_intra= 0;\n                    for(i=0; i<2; i++){\n                        j= s->field_select[0][i] = s->b_field_select_table[0][i][xy];\n                        s->mv[0][i][0] = s->b_field_mv_table[0][i][j][xy][0];\n                        s->mv[0][i][1] = s->b_field_mv_table[0][i][j][xy][1];\n                    }\n                    break;\n                case CANDIDATE_MB_TYPE_BACKWARD_I:\n                    s->mv_dir = MV_DIR_BACKWARD;\n                    s->mv_type = MV_TYPE_FIELD;\n                    s->mb_intra= 0;\n                    for(i=0; i<2; i++){\n                        j= s->field_select[1][i] = s->b_field_select_table[1][i][xy];\n                        s->mv[1][i][0] = s->b_field_mv_table[1][i][j][xy][0];\n                        s->mv[1][i][1] = s->b_field_mv_table[1][i][j][xy][1];\n                    }\n                    break;\n                case CANDIDATE_MB_TYPE_BIDIR_I:\n                    s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD;\n                    s->mv_type = MV_TYPE_FIELD;\n                    s->mb_intra= 0;\n                    for(dir=0; dir<2; dir++){\n                        for(i=0; i<2; i++){\n                            j= s->field_select[dir][i] = s->b_field_select_table[dir][i][xy];\n                            s->mv[dir][i][0] = s->b_field_mv_table[dir][i][j][xy][0];\n                            s->mv[dir][i][1] = s->b_field_mv_table[dir][i][j][xy][1];\n                        }\n                    }\n                    break;\n                default:\n                    av_log(s->avctx, AV_LOG_ERROR, "illegal MB type\\n");\n                }\n                encode_mb(s, motion_x, motion_y);\n                s->last_mv_dir = s->mv_dir;\n                if (ENABLE_ANY_H263_ENCODER &&\n                    s->out_format == FMT_H263 && s->pict_type!=FF_B_TYPE)\n                    ff_h263_update_motion_val(s);\n                MPV_decode_mb(s, s->block);\n            }\n            if(s->mb_intra  ){\n                s->p_mv_table[xy][0]=0;\n                s->p_mv_table[xy][1]=0;\n            }\n            if(s->flags&CODEC_FLAG_PSNR){\n                int w= 16;\n                int h= 16;\n                if(s->mb_x*16 + 16 > s->width ) w= s->width - s->mb_x*16;\n                if(s->mb_y*16 + 16 > s->height) h= s->height- s->mb_y*16;\n                s->current_picture.error[0] += sse(\n                    s, s->new_picture.data[0] + s->mb_x*16 + s->mb_y*s->linesize*16,\n                    s->dest[0], w, h, s->linesize);\n                s->current_picture.error[1] += sse(\n                    s, s->new_picture.data[1] + s->mb_x*8  + s->mb_y*s->uvlinesize*8,\n                    s->dest[1], w>>1, h>>1, s->uvlinesize);\n                s->current_picture.error[2] += sse(\n                    s, s->new_picture    .data[2] + s->mb_x*8  + s->mb_y*s->uvlinesize*8,\n                    s->dest[2], w>>1, h>>1, s->uvlinesize);\n            }\n            if(s->loop_filter){\n                if(ENABLE_ANY_H263_ENCODER && s->out_format == FMT_H263)\n                    ff_h263_loop_filter(s);\n            }\n        }\n    }\n    if (ENABLE_MSMPEG4_ENCODER && s->msmpeg4_version && s->msmpeg4_version<4 && s->pict_type == FF_I_TYPE)\n        msmpeg4_encode_ext_header(s);\n    write_slice_end(s);\n    if (s->avctx->rtp_callback) {\n        int number_mb = (mb_y - s->resync_mb_y)*s->mb_width - s->resync_mb_x;\n        pdif = pbBufPtr(&s->pb) - s->ptr_lastgob;\n        emms_c();\n        s->avctx->rtp_callback(s->avctx, s->ptr_lastgob, pdif, number_mb);\n    }\n    return 0;\n}']