#include "../rfxswf.h"
#include "h263tables.c"
+/* TODO:
+ - get rid of _vxy, _i endings
+ - use prepare* / write* in encode_blockI
+*/
+
+
#ifdef MAIN
U16 totalframes = 0;
#endif
};
static double cc[8];
-int ccquant = -1;
+static int ccquant = -1;
static void preparequant(int quant)
{
}
}
}
+
static void copyregion(VIDEOSTREAM*s, YUV*dest, YUV*src, int bx, int by)
{
YUV*p1 = &src[by*s->linex*16+bx*16];
}
}
-static int compareregions(VIDEOSTREAM*s, int bx, int by)
+static int compare_pic_oldpic(VIDEOSTREAM*s, int bx, int by)
{
int linex = s->width;
YUV*p1 = &s->current[by*linex*16+bx*16];
YUV*p2 = &s->oldpic[by*linex*16+bx*16];
- int diff = 0;
+ int diffy=0, diffuv = 0;
int x,y;
for(y=0;y<16;y++) {
for(x=0;x<16;x++) {
int y = m->y - n->y;
int u = m->u - n->u;
int v = m->v - n->v;
- diff += y*y+(u*u+v*v)/4;
+ diffy += abs(y);
+ diffuv += abs(u)+abs(v);
}
p1+=linex;
p2+=linex;
}
- return diff/256;
+ return diffy + diffuv/4;
+}
+
+static int compare_pic_block(VIDEOSTREAM*s, block_t* b, int bx, int by)
+{
+ int linex = s->width;
+ YUV*y1 = &s->current[(by*2)*linex*8+bx*16];
+ YUV*y2 = &s->current[(by*2)*linex*8+bx*16+8];
+ YUV*y3 = &s->current[(by*2+1)*linex*8+bx*16];
+ YUV*y4 = &s->current[(by*2+1)*linex*8+bx*16+8];
+ YUV*uv = y1;
+ int diffy=0, diffuv = 0;
+ int x,y;
+ for(y=0;y<8;y++) {
+ for(x=0;x<8;x++) {
+ int yy,u,v;
+ int y8x = y*8+x;
+ yy = y1[x].y - b->y1[y8x];
+ diffy += abs(yy);
+ yy = y2[x].y - b->y2[y8x];
+ diffy += abs(yy);
+ yy = y3[x].y - b->y3[y8x];
+ diffy += abs(yy);
+ yy = y4[x].y - b->y4[y8x];
+ diffy += abs(yy);
+ u = uv[x*2].u - b->u[y8x];
+ v = uv[x*2].v - b->v[y8x];
+ diffuv += (abs(u)+abs(v))*4;
+ }
+ y1+=linex;
+ y2+=linex;
+ y3+=linex;
+ y4+=linex;
+ uv+=linex*2;
+ }
+ return diffy + diffuv/4;
}
static inline int valtodc(int val)
return bits;
}
-static void encode8x8(TAG*tag, int*bb, int has_dc, int has_tcoef)
+static int encode8x8(TAG*tag, int*bb, int has_dc, int has_tcoef)
{
int t;
int pos=0;
if(has_dc) {
swf_SetBits(tag, bb[0], 8);
+ bits += 8;
pos++;
}
if(rle_params[t].run == run &&
rle_params[t].level == level &&
rle_params[t].last == islast) {
- codehuffman(tag, rle, t);
+ bits += codehuffman(tag, rle, t);
swf_SetBits(tag, sign, 1);
+ bits += 1;
break;
}
}
if(t==RLE_ESCAPE) {
- codehuffman(tag, rle, RLE_ESCAPE);
+ bits += codehuffman(tag, rle, RLE_ESCAPE);
level=bb[pos];
/* table 14/h.263 */
assert(level);
swf_SetBits(tag, islast, 1);
swf_SetBits(tag, run, 6);
swf_SetBits(tag, level, 8); //FIXME: fixme??
+ bits += 1 + 6 + 8;
}
if(islast)
pos++;
}
}
+ return bits;
}
static void quantize(block_t*fb, block_t*b, int has_dc, int quant)
*dquant = 0;
}
-static void encode_blockI(TAG*tag, VIDEOSTREAM*s, int bx, int by, int*quant)
-{
- block_t fb;
- block_t b;
- int dquant=0;
- int cbpcbits = 0, cbpybits=0;
-
- getregion(&fb, s->current, bx, by, s->width);
-
- change_quant(*quant, &dquant);
- *quant+=dquant;
-
- dodctandquant(&fb, &b, 1, *quant);
- //quantize(&fb, &b, 1, *quant);
-
- //decode_blockI(s, &b, bx, by);
-
- getblockpatterns(&b, &cbpybits, &cbpcbits, 1);
-
- if(dquant) {
- codehuffman(tag, mcbpc_intra, 4+cbpcbits);
- } else {
- codehuffman(tag, mcbpc_intra, 0+cbpcbits);
- }
-
- codehuffman(tag, cbpy, cbpybits);
-
- if(dquant) {
- setQuant(tag, dquant);
- }
-
- /* luminance */
- encode8x8(tag, b.y1, 1, cbpybits&8);
- encode8x8(tag, b.y2, 1, cbpybits&4);
- encode8x8(tag, b.y3, 1, cbpybits&2);
- encode8x8(tag, b.y4, 1, cbpybits&1);
-
- /* chrominance */
- encode8x8(tag, b.u, 1, cbpcbits&2);
- encode8x8(tag, b.v, 1, cbpcbits&1);
-
- /* reconstruct */
- dequantize(&b, 1, *quant);
- doidct(&b);
- truncateblock(&b);
- copyblock(s, s->current, &b, bx, by);
-}
-
static void yuvdiff(block_t*a, block_t*b)
{
int t;
return x;
}
-static int encode_blockP(TAG*tag, VIDEOSTREAM*s, int bx, int by, int*quant)
+typedef struct _iblockdata_t
{
- block_t fb;
+ block_t b_i; //transformed quantized coefficients
+ block_t reconstruction;
+ int bits;
+ int bx,by;
+} iblockdata_t;
+
+typedef struct _mvdblockdata_t
+{
+ block_t b_vxy;
+ block_t fbold_vxy;
+ block_t reconstruction;
+ int predictmvdx;
+ int predictmvdy;
+ int x_vxy;
+ int y_vxy;
+ int bits;
+ int bx,by;
+} mvdblockdata_t;
+
+void prepareIBlock(VIDEOSTREAM*s, iblockdata_t*data, int bx, int by, block_t* fb, int*bits)
+{
+ /* consider I-block */
+ block_t fb_i;
block_t b;
- int dquant=0;
- int has_mvd=0;
- int has_mvd24=0;
+ int y,c;
+ data->bx = bx;
+ data->by = by;
+
+ memcpy(&fb_i, fb, sizeof(block_t));
+ dodctandquant(&fb_i, &data->b_i, 1, s->quant);
+ getblockpatterns(&data->b_i, &y, &c, 1);
+ *bits = 1; //cod
+ *bits += mcbpc_inter[3*4+c].len;
+ *bits += cbpy[y].len;
+ *bits += coefbits8x8(data->b_i.y1, 1);
+ *bits += coefbits8x8(data->b_i.y2, 1);
+ *bits += coefbits8x8(data->b_i.y3, 1);
+ *bits += coefbits8x8(data->b_i.y4, 1);
+ *bits += coefbits8x8(data->b_i.u, 1);
+ *bits += coefbits8x8(data->b_i.v, 1);
+ data->bits = *bits;
+
+ /* -- reconstruction -- */
+ memcpy(&data->reconstruction,&data->b_i,sizeof(block_t));
+ dequantize(&data->reconstruction, 1, s->quant);
+ doidct(&data->reconstruction);
+ truncateblock(&data->reconstruction);
+}
+
+int writeIBlock(VIDEOSTREAM*s, TAG*tag, iblockdata_t*data)
+{
+ int cbpcbits = 0, cbpybits=0;
+ int mode = 3; /* i block (mode=3) */
int has_dc=1;
+ 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
int mode = 0;
- int cbpcbits = 0, cbpybits=0;
- int diff;
- int predictmvdx;
- int predictmvdy;
+ int bx = data->bx;
+ int by = data->by;
+ int bits = 0;
+
+ getblockpatterns(&data->b_vxy, &y, &c, has_dc);
+ swf_SetBits(tag,0,1); bits += 1; // COD
+ bits += codehuffman(tag, mcbpc_inter, mode*4+c);
+ bits += codehuffman(tag, cbpy, y^15);
+
+ /* vector */
+ bits += codehuffman(tag, mvd, mvd2index(data->predictmvdx, data->predictmvdy, data->x_vxy, data->y_vxy, 0));
+ bits += codehuffman(tag, mvd, mvd2index(data->predictmvdx, data->predictmvdy, data->x_vxy, data->y_vxy, 1));
+ s->mvdx[by*s->bbx+bx] = data->x_vxy;
+ s->mvdy[by*s->bbx+bx] = data->y_vxy;
- block_t b_i;
+ /* luminance */
+ bits += encode8x8(tag, data->b_vxy.y1, has_dc, y&8);
+ bits += encode8x8(tag, data->b_vxy.y2, has_dc, y&4);
+ bits += encode8x8(tag, data->b_vxy.y3, has_dc, y&2);
+ bits += encode8x8(tag, data->b_vxy.y4, has_dc, y&1);
+
+ /* chrominance */
+ bits += encode8x8(tag, data->b_vxy.u, has_dc, c&2);
+ bits += encode8x8(tag, data->b_vxy.v, has_dc, c&1);
+
+ copyblock(s, s->current, &data->reconstruction, data->bx, data->by);
+ assert(data->bits == bits);
+ return bits;
+}
+
+
+/* should be called encode_PFrameBlock */
+static int encode_blockP(TAG*tag, VIDEOSTREAM*s, int bx, int by)
+{
+ block_t fb;
+ int diff1,diff2;
int bits_i;
+ int bits_vxy;
- block_t fbold_v00;
- block_t b_v00;
- int bits_v00 = 65535;
- int x_v00=0;
- int y_v00=0;
+ iblockdata_t iblock;
+ mvdblockdata_t mvdblock;
+
+ getregion(&fb, s->current, bx, by, s->width);
+ prepareIBlock(s, &iblock, bx, by, &fb, &bits_i);
- diff = compareregions(s, bx, by);
+ /* encoded last frame <=> original current block: */
+ diff1 = compare_pic_oldpic(s, bx, by);
+ /* encoded current frame <=> original current block: */
+ diff2 = compare_pic_block(s, &iblock.reconstruction, bx, by);
- if(diff < *quant) {
- /* TODO: measure the error an I-block encoding would do, and base the decision
- on that */
+ if(diff1 <= diff2) {
swf_SetBits(tag, 1,1); /* cod=1, block skipped */
/* copy the region from the last frame so that we have a complete reconstruction */
copyregion(s, s->current, s->oldpic, bx, by);
return 1;
}
+ prepareMVDBlock(s, &mvdblock, bx, by, &fb, &bits_vxy);
- predictmvd(s,bx,by,&predictmvdx,&predictmvdy);
- getregion(&fb, s->current, bx, by, s->width);
-
- { /* consider I-block */
- block_t fb_i;
- int y,c;
- memcpy(&fb_i, &fb, sizeof(block_t));
- dodctandquant(&fb_i, &b_i, 1, *quant);
- //quantize(&fb_i, &b_i, 1, *quant);
- getblockpatterns(&b_i, &y, &c, 1);
- bits_i = 1; //cod
- bits_i += mcbpc_inter[3*4+c].len;
- bits_i += cbpy[y].len;
- bits_i += coefbits8x8(b_i.y1, 1);
- bits_i += coefbits8x8(b_i.y2, 1);
- bits_i += coefbits8x8(b_i.y3, 1);
- bits_i += coefbits8x8(b_i.y4, 1);
- bits_i += coefbits8x8(b_i.u, 1);
- bits_i += coefbits8x8(b_i.v, 1);
+ if(bits_i > bits_vxy) {
+ return writeMVDBlock(s, tag, &mvdblock);
+ } else {
+ return writeIBlock(s, tag, &iblock);
}
+}
- { /* consider mvd(x,y)-block */
- block_t fbdiff;
- int y,c;
+/* should be called encode_IFrameBlock */
+static void encode_blockI(TAG*tag, VIDEOSTREAM*s, int bx, int by)
+{
+ block_t fb;
+ block_t b;
+ int dquant=0;
+ int c = 0, y=0;
- x_v00=0;
- y_v00=0;
+ getregion(&fb, s->current, bx, by, s->width);
- if(s->do_motion) {
- int hx,hy;
- int bestx=0,besty=0,bestbits=65536;
- int startx=-32,endx=31;
- int starty=-32,endy=31;
+ change_quant(s->quant, &dquant);
+ s->quant+=dquant;
- if(!bx) startx=0;
- if(!by) starty=0;
- if(bx==s->bbx-1) endx=0;
- if(by==s->bby-1) endy=0;
+ dodctandquant(&fb, &b, 1, s->quant);
- 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, *quant);
- //quantize(&fbdiff, &b, 0, *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;
- }
- }
- x_v00 = bestx;
- y_v00 = besty;
- }
+ getblockpatterns(&b, &y, &c, 1);
- memcpy(&fbdiff, &fb, sizeof(block_t));
- getmvdregion(&fbold_v00, s->oldpic, bx, by, x_v00, y_v00, s->linex);
- yuvdiff(&fbdiff, &fbold_v00);
- dodctandquant(&fbdiff, &b_v00, 0, *quant);
- //quantize(&fbdiff, &b_v00, 0, *quant);
- getblockpatterns(&b_v00, &y, &c, 0);
-
- bits_v00 = 1; //cod
- bits_v00 += mcbpc_inter[0*4+c].len;
- bits_v00 += cbpy[y^15].len;
- bits_v00 += mvd[mvd2index(predictmvdx, predictmvdy, x_v00, y_v00, 0)].len; // (0,0)
- bits_v00 += mvd[mvd2index(predictmvdx, predictmvdy, x_v00, y_v00, 1)].len;
- bits_v00 += coefbits8x8(b_v00.y1, 0);
- bits_v00 += coefbits8x8(b_v00.y2, 0);
- bits_v00 += coefbits8x8(b_v00.y3, 0);
- bits_v00 += coefbits8x8(b_v00.y4, 0);
- bits_v00 += coefbits8x8(b_v00.u, 0);
- bits_v00 += coefbits8x8(b_v00.v, 0);
+ if(dquant) {
+ codehuffman(tag, mcbpc_intra, 4+c);
+ } else {
+ codehuffman(tag, mcbpc_intra, 0+c);
}
- if(bits_i > bits_v00)
- {
- /* mvd (0,0) block (mode=0) */
- int t;
- mode = 0; // mvd w/o mvd24
- has_dc = 0;
- memcpy(&b, &b_v00, sizeof(block_t));
-
- getblockpatterns(&b, &cbpybits, &cbpcbits, has_dc);
- swf_SetBits(tag,0,1); // COD
- codehuffman(tag, mcbpc_inter, mode*4+cbpcbits);
- codehuffman(tag, cbpy, cbpybits^15);
-
- /* vector */
- codehuffman(tag, mvd, mvd2index(predictmvdx, predictmvdy, x_v00, y_v00, 0));
- codehuffman(tag, mvd, mvd2index(predictmvdx, predictmvdy, x_v00, y_v00, 1));
- s->mvdx[by*s->bbx+bx] = x_v00;
- s->mvdy[by*s->bbx+bx] = y_v00;
-
- /* luminance */
- encode8x8(tag, b.y1, has_dc, cbpybits&8);
- encode8x8(tag, b.y2, has_dc, cbpybits&4);
- encode8x8(tag, b.y3, has_dc, cbpybits&2);
- encode8x8(tag, b.y4, has_dc, cbpybits&1);
-
- /* chrominance */
- encode8x8(tag, b.u, has_dc, cbpcbits&2);
- encode8x8(tag, b.v, has_dc, cbpcbits&1);
-
- /* -- reconstruction -- */
- dequantize(&b, 0, *quant);
- doidct(&b);
- for(t=0;t<64;t++) {
- b.y1[t] = truncate256(b.y1[t] + (int)fbold_v00.y1[t]);
- b.y2[t] = truncate256(b.y2[t] + (int)fbold_v00.y2[t]);
- b.y3[t] = truncate256(b.y3[t] + (int)fbold_v00.y3[t]);
- b.y4[t] = truncate256(b.y4[t] + (int)fbold_v00.y4[t]);
- b.u[t] = truncate256(b.u[t] + (int)fbold_v00.u[t]);
- b.v[t] = truncate256(b.v[t] + (int)fbold_v00.v[t]);
- }
- copyblock(s, s->current, &b, bx, by);
- return bits_v00;
- } else {
- /* i block (mode=3) */
- mode = 3;
- has_dc = 1;
- memcpy(&b, &b_i, sizeof(block_t));
- getblockpatterns(&b, &cbpybits, &cbpcbits, has_dc);
- swf_SetBits(tag,0,1); // COD
- codehuffman(tag, mcbpc_inter, mode*4+cbpcbits);
- codehuffman(tag, cbpy, cbpybits);
-
- /* luminance */
- encode8x8(tag, b.y1, has_dc, cbpybits&8);
- encode8x8(tag, b.y2, has_dc, cbpybits&4);
- encode8x8(tag, b.y3, has_dc, cbpybits&2);
- encode8x8(tag, b.y4, has_dc, cbpybits&1);
-
- /* chrominance */
- encode8x8(tag, b.u, has_dc, cbpcbits&2);
- encode8x8(tag, b.v, has_dc, cbpcbits&1);
-
- /* -- reconstruction -- */
- dequantize(&b, 1, *quant);
- doidct(&b);
- truncateblock(&b);
- copyblock(s, s->current, &b, bx, by);
- return bits_i;
+ codehuffman(tag, cbpy, y);
+
+ if(dquant) {
+ setQuant(tag, dquant);
}
- exit(1);
-#if 0
- dodct(&fb);
- quantize(&fb, &b, has_dc, *quant);
- getblockpatterns(&b, &cbpybits, &cbpcbits, has_dc);
+ /* luminance */
+ encode8x8(tag, b.y1, 1, y&8);
+ encode8x8(tag, b.y2, 1, y&4);
+ encode8x8(tag, b.y3, 1, y&2);
+ encode8x8(tag, b.y4, 1, y&1);
- if(!dquant && has_mvd && !has_mvd24 && !has_dc) mode = 0;
- else if(dquant && has_mvd && !has_mvd24 && !has_dc) mode = 1;
- else if(!dquant && has_mvd && has_mvd24 && !has_dc) mode = 2;
- else if(!dquant && !has_mvd && !has_mvd24 && has_dc) mode = 3;
- else if(dquant && !has_mvd && !has_mvd24 && has_dc) mode = 4;
- else exit(1);
+ /* chrominance */
+ encode8x8(tag, b.u, 1, c&2);
+ encode8x8(tag, b.v, 1, c&1);
- swf_SetBits(tag,0,1); /* cod - 1 if we're not going to code this block*/
+ /* reconstruct */
+ dequantize(&b, 1, s->quant);
+ doidct(&b);
+ truncateblock(&b);
+ copyblock(s, s->current, &b, bx, by);
+}
+
+/*static void encode_blockI(TAG*tag, VIDEOSTREAM*s, int bx, int by)
+{
+ block_t fb;
+ block_t b;
+ iblockdata_t data;
+ int bits, quality;
+ int dquant = 0;
+ int cbpcbits = 0, cbpybits = 0;
- codehuffman(tag, mcbpc_inter, mode*4+cbpcbits);
- codehuffman(tag, cbpy, (mode==3 || mode==4)?cbpybits:cbpybits^15);
+ getregion(&fb, s->current, bx, by, s->width);
+ prepareIBlock(s, &data, bx, by, &fb, &bits, &quality);
+
+ getblockpatterns(&data.b_i, &cbpybits, &cbpcbits, has_dc);
if(dquant) {
- setQuant(tag, dquant);
+ codehuffman(tag, mcbpc_intra, 4+cbpcbits);
+ } else {
+ codehuffman(tag, mcbpc_intra, 0+cbpcbits);
}
- if(has_mvd) {
- /* 0,0 */
- codehuffman(tag, mvd, 32);
- codehuffman(tag, mvd, 32);
- }
- if(has_mvd24) {
+ codehuffman(tag, cbpy, cbpybits);
+
+ if(dquant) {
+ setQuant(tag, dquant);
}
- /* luminance */
- encode8x8(tag, b.y1, has_dc, cbpybits&8);
- encode8x8(tag, b.y2, has_dc, cbpybits&4);
- encode8x8(tag, b.y3, has_dc, cbpybits&2);
- encode8x8(tag, b.y4, has_dc, cbpybits&1);
+ // luminance
+ encode8x8(tag, b.y1, 1, cbpybits&8);
+ encode8x8(tag, b.y2, 1, cbpybits&4);
+ encode8x8(tag, b.y3, 1, cbpybits&2);
+ encode8x8(tag, b.y4, 1, cbpybits&1);
- /* chrominance */
- encode8x8(tag, b.u, has_dc, cbpcbits&2);
- encode8x8(tag, b.v, has_dc, cbpcbits&1);
-#endif
-}
+ // chrominance
+ encode8x8(tag, b.u, 1, cbpcbits&2);
+ encode8x8(tag, b.v, 1, cbpcbits&1);
+
+ copyblock(s, s->current, &data->reconstruction, data->bx, data->by);
+}*/
static int bmid = 0;
void setdbgpic(TAG*tag, RGBA*pic, int width, int height)
if(quant<1) quant=1;
if(quant>31) quant=31;
+ s->quant = quant;
writeHeader(tag, s->width, s->height, s->frame, quant, TYPE_IFRAME);
{
for(bx=0;bx<s->bbx;bx++)
{
- encode_blockI(tag, s, bx, by, &quant);
+ encode_blockI(tag, s, bx, by);
}
}
s->frame++;
if(quant<1) quant=1;
if(quant>31) quant=31;
+ s->quant = quant;
writeHeader(tag, s->width, s->height, s->frame, quant, TYPE_PFRAME);
{
for(bx=0;bx<s->bbx;bx++)
{
- encode_blockP(tag, s, bx, by, &quant);
+ encode_blockP(tag, s, bx, by);
}
}
s->frame++;
tag = swf_InsertTag(tag, ST_DEFINEVIDEOSTREAM);
swf_SetU16(tag, 33);
swf_SetVideoStreamDefine(tag, &stream, frames, width, height);
- stream.do_motion = 1;
+ stream.do_motion = 0;
for(t=0;t<frames;t++)
{
}
close(fi);
swf_FreeTags(&swf);
+ return 0;
}
#undef MAIN
#endif