X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fh.263%2Fswfvideo.c;h=1b075ffda1e50c56c36853bcb5f9534ab15d4f17;hb=6c3ab5574d31504d24710c2756899d49275c1a37;hp=c928a3fa44b0570ef6687e0fc92c49b009e8e42a;hpb=d71ba2887f2fd86de49a1b456fd91febcb145786;p=swftools.git diff --git a/lib/h.263/swfvideo.c b/lib/h.263/swfvideo.c index c928a3f..1b075ff 100644 --- a/lib/h.263/swfvideo.c +++ b/lib/h.263/swfvideo.c @@ -37,13 +37,6 @@ U16 totalframes = 0; #endif void swf_SetVideoStreamDefine(TAG*tag, VIDEOSTREAM*stream, U16 frames, U16 width, U16 height) { - swf_SetU16(tag, frames); - swf_SetU16(tag, width); - swf_SetU16(tag, height); - //swf_SetU8(tag, 1); /* smoothing on */ - swf_SetU8(tag, 0); /* smoothing off */ - swf_SetU8(tag, 2); /* codec = h.263 sorenson spark */ - #ifdef MAIN totalframes = frames; #endif @@ -58,26 +51,31 @@ void swf_SetVideoStreamDefine(TAG*tag, VIDEOSTREAM*stream, U16 frames, U16 width stream->height = height; stream->bbx = width/16; stream->bby = height/16; - stream->current = (YUV*)malloc(width*height*sizeof(YUV)); - stream->oldpic = (YUV*)malloc(width*height*sizeof(YUV)); - stream->mvdx = (int*)malloc(stream->bbx*stream->bby*sizeof(int)); - stream->mvdy = (int*)malloc(stream->bbx*stream->bby*sizeof(int)); + stream->current = (YUV*)rfx_calloc(width*height*sizeof(YUV)); + stream->oldpic = (YUV*)rfx_calloc(width*height*sizeof(YUV)); + stream->mvdx = (int*)rfx_alloc(stream->bbx*stream->bby*sizeof(int)); + stream->mvdy = (int*)rfx_alloc(stream->bbx*stream->bby*sizeof(int)); stream->do_motion = 0; - memset(stream->oldpic, 0, width*height*sizeof(YUV)); - memset(stream->current, 0, width*height*sizeof(YUV)); - assert((stream->width&15) == 0); assert((stream->height&15) == 0); assert((stream->bbx*16) == stream->width); assert((stream->bby*16) == stream->height); + + swf_SetU16(tag, frames); + swf_SetU16(tag, width); + swf_SetU16(tag, height); + //swf_SetU8(tag, 1); /* smoothing on */ + swf_SetU8(tag, 0); /* smoothing off */ + swf_SetU8(tag, 2); /* codec = h.263 sorenson spark */ + } void swf_VideoStreamClear(VIDEOSTREAM*stream) { - free(stream->oldpic);stream->oldpic = 0; - free(stream->current);stream->current = 0; - free(stream->mvdx);stream->mvdx=0; - free(stream->mvdy);stream->mvdy=0; + rfx_free(stream->oldpic);stream->oldpic = 0; + rfx_free(stream->current);stream->current = 0; + rfx_free(stream->mvdx);stream->mvdx=0; + rfx_free(stream->mvdy);stream->mvdy=0; } typedef struct _block_t @@ -255,6 +253,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 +596,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); @@ -1232,6 +1237,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; + int x,y; + s->quant = quant; + + writeHeader(tag, s->width, s->height, s->frame, quant, TYPE_IFRAME); + + 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) { @@ -1268,9 +1305,10 @@ 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, void**picture, 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; @@ -1288,6 +1326,7 @@ void swf_SetVideoStreamMover(TAG*tag, VIDEOSTREAM*s, signed char* movex, signed 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; @@ -1305,13 +1344,16 @@ void swf_SetVideoStreamMover(TAG*tag, VIDEOSTREAM*s, signed char* movex, signed swf_SetBits(tag,0,1); // COD - if(mvx==0 && mvy==0) { // only picture + if(mvx==0 && mvy==0 && picture) { // only picture mode = 3; has_dc = 1; } if(picture) { - /* todo: store picture in b */ + 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 { @@ -1319,7 +1361,7 @@ void swf_SetVideoStreamMover(TAG*tag, VIDEOSTREAM*s, signed char* movex, signed } codehuffman(tag, mcbpc_inter, mode*4+c); - codehuffman(tag, cbpy, y^15); + codehuffman(tag, cbpy, mode==3?y:y^15); if(mode < 3) { /* has motion vector */ @@ -1330,7 +1372,7 @@ void swf_SetVideoStreamMover(TAG*tag, VIDEOSTREAM*s, signed char* movex, signed s->mvdy[by*s->bbx+bx] = mvy; } - if(picture) { + 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); @@ -1351,7 +1393,7 @@ void test_copy_diff() VIDEOSTREAM stream; VIDEOSTREAM* s = &stream; TAG*tag; - RGBA*pic = malloc(256*256*sizeof(RGBA)); + RGBA*pic = (RGBA*)rfx_alloc(256*256*sizeof(RGBA)); block_t fb; int x,y; int bx,by; @@ -1406,8 +1448,7 @@ void mkblack() RGBA* pic = 0; VIDEOSTREAM stream; - pic = malloc(width*height*4); - memset(pic, 0, width*height*4); + pic = rfx_calloc(width*height*4); memset(&swf,0,sizeof(SWF)); memset(&obj,0,sizeof(obj)); @@ -1492,10 +1533,10 @@ int main(int argn, char*argv[]) memset(&stream, 0, sizeof(stream)); getPNG(fname, &width, &height, &data); - pic = (RGBA*)malloc(width*height*sizeof(RGBA)); - pic2 = (RGBA*)malloc(width*height*sizeof(RGBA)); + pic = (RGBA*)rfx_alloc(width*height*sizeof(RGBA)); + pic2 = (RGBA*)rfx_alloc(width*height*sizeof(RGBA)); memcpy(pic, data, width*height*sizeof(RGBA)); - free(data); + rfx_free(data); printf("Compressing %s, size %dx%d\n", fname, width, height);