X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fh.263%2Fswfvideo.c;h=4c5983d1fb3e6de071f0535abe31468c0bf2bc41;hb=ea7b8b50792baaff58933612b4632e61731ddf87;hp=6e2149429d9c88dcd181dda5918e1ab732421d53;hpb=675cc23f423cc699b0ad29e61adf185fdfbfc25f;p=swftools.git diff --git a/lib/h.263/swfvideo.c b/lib/h.263/swfvideo.c index 6e21494..4c5983d 100644 --- a/lib/h.263/swfvideo.c +++ b/lib/h.263/swfvideo.c @@ -255,6 +255,7 @@ static void rgb2yuv(YUV*dest, RGBA*src, int dlinex, int slinex, int width, int h dest[y*dlinex+x].v = (r*0.500 + g*-0.419 + b*-0.0813 + 128.0);*/ //dest[y*dlinex+x].y = 128;//(r*((int)( 0.299*256)) + g*((int)( 0.587*256)) + b*((int)( 0.114 *256)))>>8; + dest[y*dlinex+x].y = (r*((int)( 0.299*256)) + g*((int)( 0.587*256)) + b*((int)( 0.114 *256)))>>8; dest[y*dlinex+x].u = (r*((int)(-0.169*256)) + g*((int)(-0.332*256)) + b*((int)( 0.500 *256))+ 128*256)>>8; dest[y*dlinex+x].v = (r*((int)( 0.500*256)) + g*((int)(-0.419*256)) + b*((int)(-0.0813*256))+ 128*256)>>8; @@ -597,9 +598,15 @@ static int encode8x8(TAG*tag, int*bb, int has_dc, int has_tcoef) bits += codehuffman(tag, rle, RLE_ESCAPE); level=bb[pos]; /* table 14/h.263 */ + if(!level || level<-127 || level>127) { + fprintf(stderr, "Warning: Overflow- Level %d at pos %d\n", level, pos); + if(level<-127) level=-127; + if(level>127) level=127; + } + assert(level); assert(level>=-127); - assert(level<=127); + assert(level<=127); //TODO: known to fail for pos=0 (with custom frames?) swf_SetBits(tag, islast, 1); swf_SetBits(tag, run, 6); @@ -816,6 +823,9 @@ static void predictmvd(VIDEOSTREAM*s, int bx, int by, int*px, int*py) static inline int mvd2index(int px, int py, int x, int y, int xy) { + + if((x<-32 && x>31) || (y<-32 && y>31)) + fprintf(stderr, "(%d,%d)\n", x,y); assert((x>=-32 && x<=31) && (y>=-32 && y<=31)); //assert((x&1)==0 && (y&1)==0);//for now //assert((x&2)==0 && (y&2)==0);//for now(2) @@ -1055,9 +1065,9 @@ void prepareMVDBlock(VIDEOSTREAM*s, mvdblockdata_t*data, int bx, int by, block_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 + /* mvd (0,0) block (mode=0) */ int mode = 0; int bx = data->bx; int by = data->by; @@ -1229,6 +1239,38 @@ void swf_SetVideoStreamIFrame(TAG*tag, VIDEOSTREAM*s, RGBA*pic, int quant) s->frame++; memcpy(s->oldpic, s->current, s->width*s->height*sizeof(YUV)); } +void swf_SetVideoStreamBlackFrame(TAG*tag, VIDEOSTREAM*s) +{ + int bx, by; + int quant = 31; + s->quant = quant; + + writeHeader(tag, s->width, s->height, s->frame, quant, TYPE_IFRAME); + + int x,y; + for(y=0;yheight;y++) + for(x=0;xwidth;x++) { + s->current[y*s->width+x].y = 0; + s->current[y*s->width+x].u = 128; + s->current[y*s->width+x].v = 128; + } + for(x=0;x<16;x++) + for(y=0;y<16;y++) { + s->current[y*s->width+x].y = 64; + s->current[y*s->width+x].u = 128; + s->current[y*s->width+x].v = 128; + } + + for(by=0;bybby;by++) + { + for(bx=0;bxbbx;bx++) + { + encode_IFrame_block(tag, s, bx, by); + } + } + s->frame++; + memcpy(s->oldpic, s->current, s->width*s->height*sizeof(YUV)); +} void swf_SetVideoStreamPFrame(TAG*tag, VIDEOSTREAM*s, RGBA*pic, int quant) { @@ -1265,12 +1307,14 @@ void swf_SetVideoStreamPFrame(TAG*tag, VIDEOSTREAM*s, RGBA*pic, int quant) #endif } -void swf_SetVideoStreamMover(TAG*tag, VIDEOSTREAM*s, signed char* movex, signed char* movey, int quant) +void swf_SetVideoStreamMover(TAG*tag, VIDEOSTREAM*s, signed char* movex, signed char* movey, void**pictures, int quant) { int bx, by; + YUV pic[16*16]; if(quant<1) quant=1; if(quant>31) quant=31; + s->quant = quant; writeHeader(tag, s->width, s->height, s->frame, quant, TYPE_PFRAME); @@ -1281,29 +1325,67 @@ void swf_SetVideoStreamMover(TAG*tag, VIDEOSTREAM*s, signed char* movex, signed { for(bx=0;bxbbx;bx++) { - if(!(by==31)) { - /* mvd (0,0) block (mode=0) */ - int t; - int mode = 0; - int has_dc = 0; - int cbpybits=0,cbpcbits=0; - int predictmvdx, predictmvdy; - int mvx=movex[by*s->bbx+bx]; - int mvy=movey[by*s->bbx+bx]; + int predictmvdx=0, predictmvdy=0; + int mvx=movex[by*s->bbx+bx]; + int mvy=movey[by*s->bbx+bx]; + void*picture = pictures?pictures[by*s->bbx+bx]:0; + + if(mvx<-32) mvx=-32; + if(mvx>31) mvx=31; + if(mvy<-32) mvy=-32; + if(mvy>31) mvy=31; + if(mvx == 0 && mvy == 0 && picture == 0) { + swf_SetBits(tag,1,1); // COD skip + } else { + int mode = 0; + int has_dc=0; + int y=0,c=0; + block_t b; + block_t b2; + swf_SetBits(tag,0,1); // COD - codehuffman(tag, mcbpc_inter, mode*4+cbpcbits); - codehuffman(tag, cbpy, cbpybits^15); - - /* vector */ - predictmvd(s,bx,by,&predictmvdx,&predictmvdy); - codehuffman(tag, mvd, mvd2index(predictmvdx, predictmvdy, mvx, mvy, 0)); - codehuffman(tag, mvd, mvd2index(predictmvdx, predictmvdy, mvx, mvy, 1)); - s->mvdx[by*s->bbx+bx] = mvx; - s->mvdy[by*s->bbx+bx] = mvy; + + if(mvx==0 && mvy==0 && picture) { // only picture + mode = 3; + has_dc = 1; + } + + if(picture) { + RGBA* picblock = (RGBA*)picture; + rgb2yuv(pic, picblock,16,16,16,16); + /* TODO: if has_dc!=1, subtract 128 from rgb values */ + getregion(&b, pic, 0,0,16); + dodctandquant(&b, &b2, 1, s->quant); + getblockpatterns(&b2, &y, &c, 1); + } else { + y=0;c=0; + } + + codehuffman(tag, mcbpc_inter, mode*4+c); + codehuffman(tag, cbpy, mode==3?y:y^15); + + if(mode < 3) { + /* has motion vector */ + predictmvd(s,bx,by,&predictmvdx,&predictmvdy); + codehuffman(tag, mvd, mvd2index(predictmvdx, predictmvdy, mvx, mvy, 0)); + codehuffman(tag, mvd, mvd2index(predictmvdx, predictmvdy, mvx, mvy, 1)); + s->mvdx[by*s->bbx+bx] = mvx; + s->mvdy[by*s->bbx+bx] = mvy; + } + + if(has_dc||y||c) { + encode8x8(tag, b2.y1, has_dc, y&8); + encode8x8(tag, b2.y2, has_dc, y&4); + encode8x8(tag, b2.y3, has_dc, y&2); + encode8x8(tag, b2.y4, has_dc, y&1); + encode8x8(tag, b2.u, has_dc, c&2); + encode8x8(tag, b2.v, has_dc, c&1); + } } } } + s->frame++; } #define TESTS @@ -1352,6 +1434,81 @@ void test_copy_diff() #ifdef MAIN #include "png.h" + +int compileSWFActionCode(const char *script, int version, void**data, int*len) {return 0;} + +void mkblack() +{ + SWF swf; + SWFPLACEOBJECT obj; + int frames = 88; + int width = 160; + int height = 112; + int x,y; + TAG*tag = 0; + RGBA rgb; + RGBA* pic = 0; + VIDEOSTREAM stream; + + pic = malloc(width*height*4); + memset(pic, 0, width*height*4); + + memset(&swf,0,sizeof(SWF)); + memset(&obj,0,sizeof(obj)); + + swf.fileVersion = 6; + swf.frameRate = 15*256; + swf.movieSize.xmax = 20*width; + swf.movieSize.ymax = 20*height; + + swf.firstTag = swf_InsertTag(NULL,ST_SETBACKGROUNDCOLOR); + tag = swf.firstTag; + rgb.r = 0x00;rgb.g = 0x30;rgb.b = 0xff; + swf_SetRGB(tag,&rgb); + + tag = swf_InsertTag(tag, ST_DEFINEVIDEOSTREAM); + swf_SetU16(tag, 1); + swf_SetVideoStreamDefine(tag, &stream, frames, width, height); + stream.do_motion = 0; + + for(y=0;y