X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fh.263%2Fvideo.c;h=cc86371503ba14aec6d87f9fa2126fa9711123bd;hb=9004a9942603308ba84dbe9c8c87d742025ea67b;hp=cd7d2c493547fa3e37c9422f7862e96244807ff3;hpb=526f096a692b0ee2bd9668f59ae854b858e202d5;p=swftools.git diff --git a/lib/h.263/video.c b/lib/h.263/video.c index cd7d2c4..cc86371 100644 --- a/lib/h.263/video.c +++ b/lib/h.263/video.c @@ -3,16 +3,31 @@ Part of the swftools package. - Copyright (c) 2003 Matthias Kramm */ - -#include "../config.h" + Copyright (c) 2003 Matthias Kramm + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include "../../config.h" #include #include #include #include -#include "../lib/rfxswf.h" -#include "../lib/args.h" -#include "h263tables.c" +#include +#include "../rfxswf.h" +#include "../args.h" +#include "h263tables.h" static char * filename = 0; static char * indent = " "; @@ -129,6 +144,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 +248,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 +287,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 +328,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}; @@ -277,7 +365,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; @@ -287,7 +375,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; @@ -308,7 +396,7 @@ void decode_block(TAG*tag, int pictype) /* read cbpy */ - cbpy_index = gethuffvalue(tag, cbpy); + cbpy_index = gethuffvalue2(tag, cbpy, cbpy_tree); cbpy_value = cbpy_index; if(!intrablock) cbpy_value ^= 15; @@ -332,8 +420,11 @@ void decode_block(TAG*tag, int pictype) } 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 */ @@ -400,7 +491,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; @@ -493,6 +584,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");