+ const int motion_x= s->mv[0][0][0];
+ const int motion_y= s->mv[0][0][1];
+ int i;
+
+ /* 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;
+
+ if(s->mv_type==MV_TYPE_16X16){
+ 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);
+ }else{
+ int src_x, src_y;
+
+ for(i=0;i<4;i++) {
+ int motion_x = s->mv[0][i][0];
+ int motion_y = s->mv[0][i][1];
+
+ dxy = ((motion_y & 1) << 1) | (motion_x & 1);
+ src_x = mb_x * 16 + (motion_x >> 1) + (i & 1) * 8;
+ src_y = mb_y * 16 + (motion_y >> 1) + (i >>1) * 8;
+
+ ptr = s->last_picture[0] + (src_y * s->linesize) + (src_x);
+ sub_pixels_2(s->block[i], ptr, s->linesize, dxy);
+ }
+ /* In case of 8X8, we construct a single chroma motion vector
+ with a special rounding */
+ mx = 0;
+ my = 0;
+ for(i=0;i<4;i++) {
+ mx += s->mv[0][i][0];
+ my += s->mv[0][i][1];
+ }
+ if (mx >= 0)
+ mx = (h263_chroma_roundtab[mx & 0xf] + ((mx >> 3) & ~1));
+ else {
+ mx = -mx;
+ mx = -(h263_chroma_roundtab[mx & 0xf] + ((mx >> 3) & ~1));
+ }
+ if (my >= 0)
+ my = (h263_chroma_roundtab[my & 0xf] + ((my >> 3) & ~1));
+ else {
+ my = -my;
+ my = -(h263_chroma_roundtab[my & 0xf] + ((my >> 3) & ~1));
+ }
+ dxy = ((my & 1) << 1) | (mx & 1);
+ mx >>= 1;
+ my >>= 1;
+
+ src_x = mb_x * 8 + mx;
+ src_y = mb_y * 8 + my;
+ src_x = clip(src_x, -8, s->width/2);
+ if (src_x == s->width/2)
+ dxy &= ~1;
+ src_y = clip(src_y, -8, s->height/2);
+ if (src_y == s->height/2)
+ dxy &= ~2;
+
+ offset = (src_y * (s->linesize >> 1)) + src_x;
+ 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);
+ }
+ }
+
+#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;
+ }
+}
+
+static void copy_bits(PutBitContext *pb, UINT8 *src, int length)
+{
+ int bytes= length>>3;
+ int bits= length&7;
+ int i;
+
+ for(i=0; i<bytes; i++) put_bits(pb, 8, src[i]);
+ put_bits(pb, bits, src[i]>>(8-bits));
+}
+
+static void encode_picture(MpegEncContext *s, int picture_number)
+{
+ int mb_x, mb_y, last_gob, pdif = 0;
+ int i;
+ int bits;
+ MpegEncContext best_s;
+ UINT8 bit_buf[4][3000]; //FIXME check that this is ALLWAYS large enogh for a MB