+ int bits = 0;
+ block_t b;
+
+ getblockpatterns(&data->b_i, &cbpybits, &cbpcbits, has_dc);
+ swf_SetBits(tag,0,1); bits += 1; // COD
+ bits += codehuffman(tag, mcbpc_inter, mode*4+cbpcbits);
+ bits += codehuffman(tag, cbpy, cbpybits);
+
+ /* luminance */
+ bits += encode8x8(tag, data->b_i.y1, has_dc, cbpybits&8);
+ bits += encode8x8(tag, data->b_i.y2, has_dc, cbpybits&4);
+ bits += encode8x8(tag, data->b_i.y3, has_dc, cbpybits&2);
+ bits += encode8x8(tag, data->b_i.y4, has_dc, cbpybits&1);
+
+ /* chrominance */
+ bits += encode8x8(tag, data->b_i.u, has_dc, cbpcbits&2);
+ bits += encode8x8(tag, data->b_i.v, has_dc, cbpcbits&1);
+
+ copyblock(s, s->current, &data->reconstruction, data->bx, data->by);
+ assert(data->bits == bits);
+ return bits;
+}
+
+void prepareMVDBlock(VIDEOSTREAM*s, mvdblockdata_t*data, int bx, int by, block_t* fb, int*bits)
+{ /* consider mvd(x,y)-block */
+
+ int t;
+ int y,c;
+ block_t fbdiff;
+
+ data->bx = bx;
+ data->by = by;
+ predictmvd(s,bx,by,&data->predictmvdx,&data->predictmvdy);
+
+ data->bits = 65535;
+ data->x_vxy=0;
+ data->y_vxy=0;
+
+
+ if(s->do_motion) {
+ int hx,hy;
+ int bestx=0,besty=0,bestbits=65536;
+ int startx=-32,endx=31;
+ int starty=-32,endy=31;
+
+ if(!bx) startx=0;
+ if(!by) starty=0;
+ if(bx==s->bbx-1) endx=0;
+ if(by==s->bby-1) endy=0;
+
+ for(hx=startx;hx<=endx;hx+=1)
+ for(hy=starty;hy<=endy;hy+=1)
+ {
+ block_t b;
+ block_t fbold;
+ int bits = 0;
+ memcpy(&fbdiff, fb, sizeof(block_t));
+ getmvdregion(&fbold, s->oldpic, bx, by, hx, hy, s->linex);
+ yuvdiff(&fbdiff, &fbold);
+ dodctandquant(&fbdiff, &b, 0, s->quant);
+ bits += coefbits8x8(b.y1, 0);
+ bits += coefbits8x8(b.y2, 0);
+ bits += coefbits8x8(b.y3, 0);
+ bits += coefbits8x8(b.y4, 0);
+ bits += coefbits8x8(b.u, 0);
+ bits += coefbits8x8(b.v, 0);
+ if(bits<bestbits) {
+ bestbits = bits;
+ bestx = hx;
+ besty = hy;
+ }
+ }
+ data->x_vxy = bestx;
+ data->y_vxy = besty;
+ }
+
+ memcpy(&fbdiff, fb, sizeof(block_t));
+ getmvdregion(&data->fbold_vxy, s->oldpic, bx, by, data->x_vxy, data->y_vxy, s->linex);
+ yuvdiff(&fbdiff, &data->fbold_vxy);
+ dodctandquant(&fbdiff, &data->b_vxy, 0, s->quant);
+ getblockpatterns(&data->b_vxy, &y, &c, 0);
+
+ *bits = 1; //cod
+ *bits += mcbpc_inter[0*4+c].len;
+ *bits += cbpy[y^15].len;
+ *bits += mvd[mvd2index(data->predictmvdx, data->predictmvdy, data->x_vxy, data->y_vxy, 0)].len; // (0,0)
+ *bits += mvd[mvd2index(data->predictmvdx, data->predictmvdy, data->x_vxy, data->y_vxy, 1)].len;
+ *bits += coefbits8x8(data->b_vxy.y1, 0);
+ *bits += coefbits8x8(data->b_vxy.y2, 0);
+ *bits += coefbits8x8(data->b_vxy.y3, 0);
+ *bits += coefbits8x8(data->b_vxy.y4, 0);
+ *bits += coefbits8x8(data->b_vxy.u, 0);
+ *bits += coefbits8x8(data->b_vxy.v, 0);
+ data->bits = *bits;
+
+ /* -- reconstruction -- */
+ memcpy(&data->reconstruction, &data->b_vxy, sizeof(block_t));
+ dequantize(&data->reconstruction, 0, s->quant);
+ doidct(&data->reconstruction);
+ for(t=0;t<64;t++) {
+ data->reconstruction.y1[t] = truncate256(data->reconstruction.y1[t] + (int)data->fbold_vxy.y1[t]);
+ data->reconstruction.y2[t] = truncate256(data->reconstruction.y2[t] + (int)data->fbold_vxy.y2[t]);
+ data->reconstruction.y3[t] = truncate256(data->reconstruction.y3[t] + (int)data->fbold_vxy.y3[t]);
+ data->reconstruction.y4[t] = truncate256(data->reconstruction.y4[t] + (int)data->fbold_vxy.y4[t]);
+ data->reconstruction.u[t] = truncate256(data->reconstruction.u[t] + (int)data->fbold_vxy.u[t]);
+ data->reconstruction.v[t] = truncate256(data->reconstruction.v[t] + (int)data->fbold_vxy.v[t]);
+ }
+}
+
+int writeMVDBlock(VIDEOSTREAM*s, TAG*tag, mvdblockdata_t*data)
+{
+ int c = 0, y = 0;
+ /* mvd (0,0) block (mode=0) */
+ int t;
+ int has_dc=0; // mvd w/o mvd24