X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fh.263%2Fvideo.c;h=c130b543e821f7ce5b5ae17892fa7ab42f854382;hb=41569c18e30f72307d3774c0423130cdcafe31f1;hp=2376017530a1b9f28439f45a1cf5fbccce8f768d;hpb=c66d70eb818cbc80ddae1dd5f35352d048ce5a5c;p=swftools.git diff --git a/lib/h.263/video.c b/lib/h.263/video.c index 2376017..c130b54 100644 --- a/lib/h.263/video.c +++ b/lib/h.263/video.c @@ -5,13 +5,14 @@ Copyright (c) 2003 Matthias Kramm */ -#include "../config.h" +#include "../../config.h" #include #include #include #include -#include "../lib/rfxswf.h" -#include "../lib/args.h" +#include +#include "../rfxswf.h" +#include "../args.h" #include "h263tables.c" static char * filename = 0; @@ -129,6 +130,62 @@ int checkhufftable(struct huffcode*code, char*name) } } + +struct hufftree +{ + struct hufftree*left;//0 + struct hufftree*right;//1 + int index; +}; + +struct hufftree * rle_tree; +struct hufftree * mcbpc_intra_tree; +struct hufftree * mcbpc_inter_tree; +struct hufftree * cbpy_tree; +struct hufftree * mvd_tree; + +static void insert(struct hufftree*tree, char*code, int index) +{ + if(!*code) { + assert(!tree->left); //shannon conditional + assert(!tree->right); + tree->left = 0; + tree->right = 0; + tree->index = index; + return; + } + if(code[0] == '0') { + if(!tree->left) { + tree->left = (struct hufftree*)malloc(sizeof(struct hufftree)); + memset(tree->left, 0, sizeof(struct hufftree)); + tree->left->index = -1; + } + insert(tree->left, code+1, index); + return; + } else { + assert(code[0] == '1'); + if(!tree->right) { + tree->right = (struct hufftree*)malloc(sizeof(struct hufftree)); + memset(tree->right, 0, sizeof(struct hufftree)); + tree->right->index = -1; + } + insert(tree->right, code+1, index); + return; + } +} + +struct hufftree* huffcode2tree(struct huffcode*code) +{ + struct hufftree* t = malloc(sizeof(struct hufftree)); + memset(t, 0, sizeof(struct hufftree)); + t->index = -1; + while(code->code) { + insert(t, code->code, code->index); + code++; + } + return t; +} + int gethuffvalue(TAG*tag, struct huffcode*code) { int len = 0; @@ -177,6 +234,22 @@ int gethuffvalue(TAG*tag, struct huffcode*code) }*/ } +int gethuffvalue2(TAG*tag, struct huffcode*code, struct hufftree*tree) +{ + while(1) { + if(tree->index>=0) { + return tree->index; + } + if(!swf_GetBits(tag, 1)) { + assert(tree->left); + tree=tree->left; + } else { + assert(tree->right); + tree=tree->right; + } + } +} + void get_DC_TCOEF(TAG*tag, int t, int has_dc, int has_tcoef) { int dc; @@ -200,7 +273,7 @@ void get_DC_TCOEF(TAG*tag, int t, int has_dc, int has_tcoef) int last; int run; int level; - index = gethuffvalue(tag, rle); + index = gethuffvalue2(tag, rle, rle_tree); last = rle_params[index].last; run = rle_params[index].run; level = rle_params[index].level; @@ -241,10 +314,11 @@ void get_DC_TCOEF(TAG*tag, int t, int has_dc, int has_tcoef) } } -void readMVD(TAG*tag) +int readMVD(TAG*tag) { - int index = gethuffvalue(tag, mvd); + int index = gethuffvalue2(tag, mvd, mvd_tree); DEBUG printf("mvd index:%d\n", index); + return index; } char has_quant[] = {0,1,0,0,1}; @@ -259,12 +333,11 @@ void decode_block(TAG*tag, int pictype) { int t; int mb_type = -1, cbpc = -1; - int dbquant; + int dquant; int cbpy_index, cbpy_value; int intrablock = 0; int type; if(pictype == TYPE_INTER) /* non-intra pictures have a cod flag */ - /* TODO: according to the flash spec, this field is always present */ { int cod = swf_GetBits(tag, 1); DEBUG printf("cod=%d\n",cod); @@ -278,7 +351,7 @@ void decode_block(TAG*tag, int pictype) /* read mcbpc */ if(pictype == TYPE_INTRA) { /* I-frame */ - type = gethuffvalue(tag, mcbpc_intra); + type = gethuffvalue2(tag, mcbpc_intra, mcbpc_intra_tree); DEBUG printf("mcbpc=%d\n",type); mb_type = mcbpc_intra_params[type].mb_type; cbpc = mcbpc_intra_params[type].cbpc; @@ -288,7 +361,7 @@ void decode_block(TAG*tag, int pictype) } } else if(pictype == 1) { /* P-frame */ - type = gethuffvalue(tag, mcbpc_inter); + type = gethuffvalue2(tag, mcbpc_inter, mcbpc_inter_tree); DEBUG printf("mcbpc=%d\n",type); mb_type = mcbpc_inter_params[type].mb_type; cbpc = mcbpc_inter_params[type].cbpc; @@ -302,14 +375,14 @@ void decode_block(TAG*tag, int pictype) { intrablock = 1; } - - printf("%d", intrablock); + + printf("%c", "vqVii"[mb_type]); DEBUG printf("mcbpc type: %d mb_type:%d cbpc:%d\n", type, mb_type, cbpc); /* read cbpy */ - cbpy_index = gethuffvalue(tag, cbpy); + cbpy_index = gethuffvalue2(tag, cbpy, cbpy_tree); cbpy_value = cbpy_index; if(!intrablock) cbpy_value ^= 15; @@ -324,13 +397,20 @@ void decode_block(TAG*tag, int pictype) /* quantizer */ if(has_quant[mb_type]) { - dbquant = swf_GetBits(tag, 2); - DEBUG printf("quantizer: %d\n", dbquant); + dquant = swf_GetBits(tag, 2); + if(dquant == 0) dquant = -1; + else if(dquant == 1) dquant = -2; + else if(dquant == 2) dquant = +1; + else if(dquant == 3) dquant = +2; + DEBUG printf("dquant: %d\n", dquant); } if(has_mvd[mb_type]&1) { - readMVD(tag); //horizontal - readMVD(tag); //vertical + int x,y; + x = readMVD(tag); //horizontal + y = readMVD(tag); //vertical + if(x==32 && y==32) + printf("0"); } if(has_mvd[mb_type]&2) { /* only in advanced prediction mode */ @@ -397,7 +477,7 @@ void handleVideoFrame(TAG*tag, char*prefix) sizeflags = swf_GetBits(tag, 3); switch(sizeflags) { - case 0: width = swf_GetU8(tag); height = swf_GetU8(tag); break; + case 0: width = swf_GetBits(tag,8); height = swf_GetBits(tag,8); break; case 1: width = swf_GetBits(tag, 16); height = swf_GetBits(tag, 16); break; case 2: width = 352; height = 288; break; case 3: width = 176; height = 144; break; @@ -441,8 +521,8 @@ void handleVideoFrame(TAG*tag, char*prefix) /*if(pictype == TYPE_INTER) return;*/ - if(pictype == TYPE_INTRA) - return; + /*if(pictype == TYPE_INTRA) + return;*/ /*tagnr++; if(tagnr!=2) @@ -490,6 +570,12 @@ int main (int argc,char ** argv) checkhufftable(cbpy, "cbpy"); checkhufftable(mvd, "mvd"); + rle_tree = huffcode2tree(rle); + mcbpc_intra_tree = huffcode2tree(mcbpc_intra); + mcbpc_inter_tree = huffcode2tree(mcbpc_inter); + cbpy_tree = huffcode2tree(cbpy); + mvd_tree = huffcode2tree(mvd); + processargs(argc, argv); if(!filename) { fprintf(stderr, "You must supply a filename.\n");