diff options
Diffstat (limited to 'Src/f263/Decoder.cpp')
-rw-r--r-- | Src/f263/Decoder.cpp | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/Src/f263/Decoder.cpp b/Src/f263/Decoder.cpp new file mode 100644 index 00000000..b9a35f54 --- /dev/null +++ b/Src/f263/Decoder.cpp @@ -0,0 +1,133 @@ +#include "Decoder.h" + + +bool Decoder::initted; +unsigned char *Decoder::clp; +unsigned char Decoder::clp_table[1024]; + +int Decoder::DecodeFrame(YV12_PLANES *yv12, int *width, int *height, int *keyframe) +{ + if (getheader()) + { + if (firstFrame) + { + if (init()) + return 1; + } + + Frame frame; + getpicture(frame); + yv12->y.baseAddr = frame[0]; + yv12->y.rowBytes = coded_picture_width; + yv12->u.baseAddr = frame[1]; + yv12->u.rowBytes = chrom_width; + yv12->v.baseAddr = frame[2]; + yv12->v.rowBytes = chrom_width; + + *width = horizontal_size; + *height = vertical_size; + *keyframe = (pict_type == PCT_INTRA)?1:0; + + return 0; + } + return 1; +} + +Decoder::Decoder() +{ + for (int cc=0; cc<3; cc++) + { + refframe[cc]=0; + newframe[cc]=0; + oldrefframe[cc]=0; + edgeframe[cc]=0; + edgeframeorig[cc]=0; + } + + horizontal_size=0; + vertical_size=0; + mb_width=0; + mb_height=0; + coded_picture_width=0; + coded_picture_height=0; + chrom_width=0; + chrom_height=0; + pict_type=0; + fault=0; + refidct=0; + quant=0; + escapemode=0; + + firstFrame=true; + if (!initted) + { + /* clip table */ + clp=&clp_table[384]; + + for (int i=-384; i<640; i++) + clp[i] = (i<0) ? 0 : ((i>255) ? 255 : i); + + initted=true; + } + idct.init(); +} + +Decoder::~Decoder() +{ + for (int cc=0; cc<3; cc++) + { + free(refframe[cc]); + free(oldrefframe[cc]); + free(edgeframeorig[cc]); + } +} + +#define ROUNDUP16(size) (((size)+15) & ~15) + +int Decoder::init() +{ + int cc; + unsigned int size; + + mb_width = (horizontal_size+15)/16; + mb_height = (vertical_size +15)/16; + coded_picture_width = ROUNDUP16(horizontal_size); + coded_picture_height = ROUNDUP16(vertical_size); + chrom_width = coded_picture_width>>1; + chrom_height = coded_picture_height>>1; + + if (coded_picture_width >= (65536 - 64) + || coded_picture_height >= (65536 - 64)) + return 1; + + for (cc=0; cc<3; cc++) + { + if (cc==0) + size = coded_picture_width*coded_picture_height; + else + size = chrom_width*chrom_height; + + refframe[cc] = (unsigned char *)malloc(size); + oldrefframe[cc] = (unsigned char *)malloc(size); + } + + for (cc=0; cc<3; cc++) + { + if (cc==0) + { + size = (coded_picture_width+64)*(coded_picture_height+64); + edgeframeorig[cc] = (unsigned char *)malloc(size); + + edgeframe[cc] = edgeframeorig[cc] + (coded_picture_width+64) * 32 + 32; + } + else + { + size = (chrom_width+32)*(chrom_height+32); + edgeframeorig[cc] = (unsigned char *)malloc(size); + + edgeframe[cc] = edgeframeorig[cc] + (chrom_width+32) * 16 + 16; + } + } + + return 0; +} |