s->mb_type[i] = 1;
s->mb_type[i] &= ~MB_TYPE_INTER; s->mb_type[i] |= MB_TYPE_INTRA;
static void encode_picture(MpegEncContext *s, int picture_number){    int mb_x, mb_y, wrap, last_gob, pdif = 0;    UINT8 *ptr;    int i, motion_x, motion_y;    int bits;    s->picture_number = picture_number;    s->last_mc_mb_var = s->mc_mb_var;    /* Reset the average MB variance */    s->avg_mb_var = 0;    s->mc_mb_var = 0;    /* Estimate motion for every MB */    for(mb_y=0; mb_y < s->mb_height; mb_y++) {        for(mb_x=0; mb_x < s->mb_width; mb_x++) {            int xy= mb_y * s->mb_width + mb_x;            const int mot_stride = s->mb_width*2 + 2;            int mot_xy = (mb_y*2 + 1)*mot_stride + mb_x*2 + 1;            s->mb_x = mb_x;            s->mb_y = mb_y;            /* compute motion vector and macro block type (intra or non intra) */            motion_x = 0;            motion_y = 0;            if (s->pict_type == P_TYPE) {                s->mb_intra = estimate_motion(s, mb_x, mb_y,                                              &motion_x,                                              &motion_y);            } else {                s->mb_intra = 1;            }            /* Store MB type and MV */            s->mb_type[xy] = s->mb_intra;            s->mv_table[0][xy] = motion_x;            s->mv_table[1][xy] = motion_y;            s->motion_val[mot_xy  ][0]= motion_x;            s->motion_val[mot_xy  ][1]= motion_y;            s->motion_val[mot_xy+1][0]= motion_x;            s->motion_val[mot_xy+1][1]= motion_y;            mot_xy += mot_stride;            s->motion_val[mot_xy  ][0]= motion_x;            s->motion_val[mot_xy  ][1]= motion_y;            s->motion_val[mot_xy+1][0]= motion_x;            s->motion_val[mot_xy+1][1]= motion_y;        }    }    emms_c();    if(s->avg_mb_var < s->mc_mb_var && s->pict_type != B_TYPE){ //FIXME subtract MV bits        int i;        s->pict_type= I_TYPE;        s->picture_in_gop_number=0;        for(i=0; i<s->mb_num; i++){            s->mb_type[i] = 1;            s->mv_table[0][i] = 0;            s->mv_table[1][i] = 0;        }    }    /* find best f_code for ME which do unlimited searches */    if(s->pict_type==P_TYPE && s->full_search>3){        int mv_num[8];        int i;        int loose=0;        UINT8 * fcode_tab= s->fcode_tab;        for(i=0; i<8; i++) mv_num[i]=0;        for(i=0; i<s->mb_num; i++){            if(s->mb_type[i] == 0){                mv_num[ fcode_tab[s->mv_table[0][i] + MAX_MV] ]++;                mv_num[ fcode_tab[s->mv_table[1][i] + MAX_MV] ]++;//printf("%d %d %d\n", s->mv_table[0][i], fcode_tab[s->mv_table[0][i] + MAX_MV], i);            }//else printf("I");        }        for(i=MAX_FCODE; i>1; i--){            loose+= mv_num[i];            if(loose > 10) break; //FIXME this is pretty ineffective        }        s->f_code= i;/*        for(i=0; i<=MAX_FCODE; i++){            printf("%d ", mv_num[i]);        }        printf("\n");*/    }else{        s->f_code= 1;    }//printf("f_code %d ///\n", s->f_code);    /* convert MBs with too long MVs to I-Blocks */    if(s->pict_type==P_TYPE){        int i;        const int f_code= s->f_code;        UINT8 * fcode_tab= s->fcode_tab;        for(i=0; i<s->mb_num; i++){            if(s->mb_type[i] == 0){                if(   fcode_tab[s->mv_table[0][i] + MAX_MV] > f_code                   || fcode_tab[s->mv_table[0][i] + MAX_MV] == 0                   || fcode_tab[s->mv_table[1][i] + MAX_MV] > f_code                   || fcode_tab[s->mv_table[1][i] + MAX_MV] == 0 ){                    s->mb_type[i] = 1;                    s->mv_table[0][i] = 0;                    s->mv_table[1][i] = 0;                }            }        }    }//    printf("%d %d\n", s->avg_mb_var, s->mc_mb_var);    if (!s->fixed_qscale)         s->qscale = rate_estimate_qscale(s);    /* precompute matrix */    if (s->out_format == FMT_MJPEG) {        /* for mjpeg, we do include qscale in the matrix */        s->intra_matrix[0] = default_intra_matrix[0];        for(i=1;i<64;i++)            s->intra_matrix[i] = (default_intra_matrix[i] * s->qscale) >> 3;        convert_matrix(s->q_intra_matrix, s->q_intra_matrix16, s->intra_matrix, 8);    } else {        convert_matrix(s->q_intra_matrix, s->q_intra_matrix16, s->intra_matrix, s->qscale);        convert_matrix(s->q_non_intra_matrix, s->q_non_intra_matrix16, s->non_intra_matrix, s->qscale);    }    s->last_bits= get_bit_count(&s->pb);    switch(s->out_format) {    case FMT_MJPEG:        mjpeg_picture_header(s);        break;    case FMT_H263:        if (s->h263_msmpeg4)             msmpeg4_encode_picture_header(s, picture_number);        else if (s->h263_pred)            mpeg4_encode_picture_header(s, picture_number);        else if (s->h263_rv10)             rv10_encode_picture_header(s, picture_number);        else            h263_encode_picture_header(s, picture_number);        break;    case FMT_MPEG1:        mpeg1_encode_picture_header(s, picture_number);        break;    }    bits= get_bit_count(&s->pb);    s->header_bits= bits - s->last_bits;    s->last_bits= bits;    s->mv_bits=0;    s->misc_bits=0;    s->i_tex_bits=0;    s->p_tex_bits=0;    s->i_count=0;    s->p_count=0;    s->skip_count=0;    /* init last dc values */    /* note: quant matrix value (8) is implied here */    s->last_dc[0] = 128;    s->last_dc[1] = 128;    s->last_dc[2] = 128;    s->mb_incr = 1;    s->last_mv[0][0][0] = 0;    s->last_mv[0][0][1] = 0;    s->mv_type = MV_TYPE_16X16;    s->mv_dir = MV_DIR_FORWARD;    /* Get the GOB height based on picture height */    if (s->out_format == FMT_H263 && !s->h263_pred && !s->h263_msmpeg4) {        if (s->height <= 400)            s->gob_index = 1;        else if (s->height <= 800)            s->gob_index = 2;        else            s->gob_index = 4;    }            s->avg_mb_var = s->avg_mb_var / s->mb_num;                s->block_wrap[0]=    s->block_wrap[1]=    s->block_wrap[2]=    s->block_wrap[3]= s->mb_width*2 + 2;    s->block_wrap[4]=    s->block_wrap[5]= s->mb_width + 2;    for(mb_y=0; mb_y < s->mb_height; mb_y++) {        /* Put GOB header based on RTP MTU */        /* TODO: Put all this stuff in a separate generic function */        if (s->rtp_mode) {            if (!mb_y) {                s->ptr_lastgob = s->pb.buf;                s->ptr_last_mb_line = s->pb.buf;            } else if (s->out_format == FMT_H263 && !s->h263_pred && !s->h263_msmpeg4 && !(mb_y % s->gob_index)) {                last_gob = h263_encode_gob_header(s, mb_y);                if (last_gob) {                    s->first_gob_line = 1;                }            }        }                s->block_index[0]= s->block_wrap[0]*(mb_y*2 + 1) - 1;        s->block_index[1]= s->block_wrap[0]*(mb_y*2 + 1);        s->block_index[2]= s->block_wrap[0]*(mb_y*2 + 2) - 1;        s->block_index[3]= s->block_wrap[0]*(mb_y*2 + 2);        s->block_index[4]= s->block_wrap[4]*(mb_y + 1)                    + s->block_wrap[0]*(s->mb_height*2 + 2);        s->block_index[5]= s->block_wrap[4]*(mb_y + 1 + s->mb_height + 2) + s->block_wrap[0]*(s->mb_height*2 + 2);        for(mb_x=0; mb_x < s->mb_width; mb_x++) {            s->mb_x = mb_x;            s->mb_y = mb_y;            s->block_index[0]+=2;            s->block_index[1]+=2;            s->block_index[2]+=2;            s->block_index[3]+=2;            s->block_index[4]++;            s->block_index[5]++;#if 0            /* compute motion vector and macro block type (intra or non intra) */            motion_x = 0;            motion_y = 0;            if (s->pict_type == P_TYPE) {                s->mb_intra = estimate_motion(s, mb_x, mb_y,                                              &motion_x,                                              &motion_y);            } else {                s->mb_intra = 1;            }#endif            s->mb_intra = s->mb_type[mb_y * s->mb_width + mb_x];            motion_x = s->mv_table[0][mb_y * s->mb_width + mb_x];            motion_y = s->mv_table[1][mb_y * s->mb_width + mb_x];                        /* get the pixels */            wrap = s->linesize;            ptr = s->new_picture[0] + (mb_y * 16 * wrap) + mb_x * 16;            get_pixels(s->block[0], ptr, wrap);            get_pixels(s->block[1], ptr + 8, wrap);            get_pixels(s->block[2], ptr + 8 * wrap, wrap);            get_pixels(s->block[3], ptr + 8 * wrap + 8, wrap);            wrap = s->linesize >> 1;            ptr = s->new_picture[1] + (mb_y * 8 * wrap) + mb_x * 8;            get_pixels(s->block[4], ptr, wrap);            wrap = s->linesize >> 1;            ptr = s->new_picture[2] + (mb_y * 8 * wrap) + mb_x * 8;            get_pixels(s->block[5], ptr, wrap);            /* subtract previous frame if non intra */            if (!s->mb_intra) {                int dxy, offset, mx, my;                dxy = ((motion_y & 1) << 1) | (motion_x & 1);                ptr = s->last_picture[0] +                     ((mb_y * 16 + (motion_y >> 1)) * s->linesize) +                     (mb_x * 16 + (motion_x >> 1));                sub_pixels_2(s->block[0], ptr, s->linesize, dxy);                sub_pixels_2(s->block[1], ptr + 8, s->linesize, dxy);                sub_pixels_2(s->block[2], ptr + s->linesize * 8, s->linesize, dxy);                sub_pixels_2(s->block[3], ptr + 8 + s->linesize * 8, s->linesize ,dxy);                if (s->out_format == FMT_H263) {                    /* special rounding for h263 */                    dxy = 0;                    if ((motion_x & 3) != 0)                        dxy |= 1;                    if ((motion_y & 3) != 0)                        dxy |= 2;                    mx = motion_x >> 2;                    my = motion_y >> 2;                } else {                    mx = motion_x / 2;                    my = motion_y / 2;                    dxy = ((my & 1) << 1) | (mx & 1);                    mx >>= 1;                    my >>= 1;                }                offset = ((mb_y * 8 + my) * (s->linesize >> 1)) + (mb_x * 8 + mx);                ptr = s->last_picture[1] + offset;                sub_pixels_2(s->block[4], ptr, s->linesize >> 1, dxy);                ptr = s->last_picture[2] + offset;                sub_pixels_2(s->block[5], ptr, s->linesize >> 1, dxy);            }            emms_c();            #if 0            {                float adap_parm;                                adap_parm = ((s->avg_mb_var << 1) + s->mb_var[s->mb_width*mb_y+mb_x] + 1.0) /                            ((s->mb_var[s->mb_width*mb_y+mb_x] << 1) + s->avg_mb_var + 1.0);                            printf("\ntype=%c qscale=%2d adap=%0.2f dquant=%4.2f var=%4d avgvar=%4d",                         (s->mb_type[s->mb_width*mb_y+mb_x] > 0) ? 'I' : 'P',                         s->qscale, adap_parm, s->qscale*adap_parm,                        s->mb_var[s->mb_width*mb_y+mb_x], s->avg_mb_var);            }#endif            /* DCT & quantize */            if (s->h263_msmpeg4) {                msmpeg4_dc_scale(s);            } else if (s->h263_pred) {                h263_dc_scale(s);            } else {                /* default quantization values */                s->y_dc_scale = 8;                s->c_dc_scale = 8;            }            for(i=0;i<6;i++) {                s->block_last_index[i] = dct_quantize(s, s->block[i], i, s->qscale);            }            /* huffman encode */            switch(s->out_format) {            case FMT_MPEG1:                mpeg1_encode_mb(s, s->block, motion_x, motion_y);                break;            case FMT_H263:                if (s->h263_msmpeg4)                    msmpeg4_encode_mb(s, s->block, motion_x, motion_y);                else if(s->h263_pred)                    mpeg4_encode_mb(s, s->block, motion_x, motion_y);                else                    h263_encode_mb(s, s->block, motion_x, motion_y);                break;            case FMT_MJPEG:                mjpeg_encode_mb(s, s->block);                break;            }                        /* decompress blocks so that we keep the state of the decoder */            s->mv[0][0][0] = motion_x;            s->mv[0][0][1] = motion_y;            MPV_decode_mb(s, s->block);        }        /* Obtain average GOB size for RTP */        if (s->rtp_mode) {            if (!mb_y)                s->mb_line_avgsize = pbBufPtr(&s->pb) - s->ptr_last_mb_line;            else if (!(mb_y % s->gob_index)) {                    s->mb_line_avgsize = (s->mb_line_avgsize + pbBufPtr(&s->pb) - s->ptr_last_mb_line) >> 1;                s->ptr_last_mb_line = pbBufPtr(&s->pb);            }            //fprintf(stderr, "\nMB line: %d\tSize: %u\tAvg. Size: %u", s->mb_y,             //                    (s->pb.buf_ptr - s->ptr_last_mb_line), s->mb_line_avgsize);            s->first_gob_line = 0;        }    }    if (s->h263_msmpeg4 && s->pict_type == I_TYPE)        msmpeg4_encode_ext_header(s);    //if (s->gob_number)    //    fprintf(stderr,"\nNumber of GOB: %d", s->gob_number);        /* Send the last GOB if RTP */        if (s->rtp_mode) {        flush_put_bits(&s->pb);        pdif = pbBufPtr(&s->pb) - s->ptr_lastgob;        /* Call the RTP callback to send the last GOB */        if (s->rtp_callback)            s->rtp_callback(s->ptr_lastgob, pdif, s->gob_number);        s->ptr_lastgob = pbBufPtr(&s->pb);        //fprintf(stderr,"\nGOB: %2d size: %d (last)", s->gob_number, pdif);    }}