📄 getpic.c
字号:
#include <stdio.h>
#include <string.h>
#include "config.h"
#include "global.h"
#include "indices.h"
#include "sactbls.h"
#ifdef DEBUG_DENG
extern FILE* myfperr; //DENG
#endif
/* private prototypes*/
static void getMBs _ANSI_ARGS_((int framenum));
static void clearblock _ANSI_ARGS_((int comp));
static int motion_decode _ANSI_ARGS_((int vec,int pmv));
static int find_pmv _ANSI_ARGS_((int x, int y, int block, int comp));
static void addblock _ANSI_ARGS_((int comp, int bx, int by,int addflag));
static void reconblock_b _ANSI_ARGS_((int comp,int bx,int by,int mode,int bdx, int bdy));
static void find_bidir_limits _ANSI_ARGS_((int vec, int *start, int*stop, int nhv));
static void find_bidir_chroma_limits _ANSI_ARGS_((int vec, int *start, int*stop));
static void make_edge_image _ANSI_ARGS_ ((unsigned char *src, unsigned char *dst, int width, int height, int edge));
void interpolate_image _ANSI_ARGS_((unsigned char *in, unsigned char *out, int width, int height));
void startcode(); //DENG
/* decode one frame or field picture */
void getpicture(framenum)
int *framenum;
{
int i;
unsigned char *tmp;
for (i=0; i<3; i++) {
tmp = oldrefframe[i];
oldrefframe[i] = refframe[i];
refframe[i] = tmp;
newframe[i] = refframe[i];
}
if (mv_outside_frame && *framenum > 0) {
make_edge_image(oldrefframe[0],edgeframe[0],coded_picture_width,
coded_picture_height,32);
make_edge_image(oldrefframe[1],edgeframe[1],chrom_width, chrom_height,16);
make_edge_image(oldrefframe[2],edgeframe[2],chrom_width, chrom_height,16);
}
getMBs(*framenum);
if (pb_frame) {
if (expand && outtype == T_X11) {
interpolate_image(bframe[0], exnewframe[0],
coded_picture_width, coded_picture_height);
interpolate_image(bframe[1], exnewframe[1], chrom_width, chrom_height);
interpolate_image(bframe[2], exnewframe[2], chrom_width, chrom_height);
storeframe(exnewframe, *framenum);
}
else
storeframe(bframe,*framenum);
*framenum += pb_frame;
#ifdef USE_TIME
if (framerate > 0)
doframerate();
#endif
}
if (expand && outtype == T_X11) {
interpolate_image(newframe[0], exnewframe[0],
coded_picture_width, coded_picture_height);
interpolate_image(newframe[1], exnewframe[1], chrom_width, chrom_height);
interpolate_image(newframe[2], exnewframe[2], chrom_width, chrom_height);
storeframe(exnewframe, *framenum);
}
else
storeframe(newframe,*framenum);
}
/* decode all macroblocks of the current picture */
static void getMBs(framenum)
int framenum;
{
#ifdef DEBUG_DENG
int mytmp_01,mytmp_02; // deng
#endif
int comp;
int MBA, MBAmax;
int bx, by;
// int count=0 ; deng
int COD=0,MCBPC, CBPY, CBP=0, CBPB=0, MODB=0, Mode=0, DQUANT;
int COD_index, CBPY_index, MODB_index, DQUANT_index, MCBPC_index;
int INTRADC_index, YCBPB_index, UVCBPB_index, mvdbx_index, mvdby_index;
int mvx, mvy, mvy_index, mvx_index, pmv0, pmv1, xpos, ypos, gob, i,k;
int mvdbx=0, mvdby=0, pmvdbx, pmvdby, gfid, YCBPB, UVCBPB, gobheader_read;
int startmv,stopmv,offset,bsize,last_done=0,pCBP=0,pCBPB=0,pCOD=0;
int DQ_tab[4] = {-1,-2,1,2};
short *bp;
/* number of macroblocks per picture */
MBAmax = mb_width*mb_height;
MBA = 0; /* macroblock address */
newgob = 0;
/* mark MV's above the picture */
for (i = 1; i < dMBC+1; i++) {
for (k = 0; k < 5; k++) {
dMV[0][k][0][i] = NO_VEC;
dMV[1][k][0][i] = NO_VEC;
}
modemap[0][i] = MODE_INTRA;
}
/* zero MV's on the sides of the picture */
for (i = 0; i < dMBR+1; i++) {
for (k = 0; k < 5; k++) {
dMV[0][k][i][0] = 0;
dMV[1][k][i][0] = 0;
dMV[0][k][i][dMBC+1] = 0;
dMV[1][k][i][dMBC+1] = 0;
}
modemap[i][0] = MODE_INTRA;
modemap[i][dMBC+1] = MODE_INTRA;
}
fault = 0;
gobheader_read = 0;
for (;;) {
resync:
/* This version of the decoder does not resync on every possible
error, and it does not do all possible error checks. It is not
difficult to make it much more error robust, but I do not think
it is necessary to include this in the freely available
version. */
if (fault) {
// error occurs
#ifdef DEBUG_DENG
printf(" \n ********** error occurs: at MBA=%d \n ",MBA);
#endif
startcode(); /* sync on new startcode */
fault = 0;
}
if (!(showbits(22)>>6)) { /* startcode */
startcode(); // deng , uncomment it !!!!!!!!!!!!!!!!!
/* in case of byte aligned start code, ie. PSTUF, GSTUF or ESTUF
is used */
if (showbits(22) == (32|SEC)) { /* end of sequence */
if (!(syntax_arith_coding && MBA < MBAmax)) {
return;
}
}
else if ((showbits(22) == PSC<<5) ) { /* new picture */
if (!(syntax_arith_coding && MBA < MBAmax)) {
return;
}
}
else {
if (!(syntax_arith_coding && MBA%dMBC)) {
if (syntax_arith_coding) { /* SAC hack to finish GOBs which */
gob = (showbits(22) & 31); /* end with MBs coded with no bits */
if (gob * mb_width != MBA)
goto finish_gob;
}
gob = getheader() - 1;
if (gob > dMBR) {
// probably I can set gob = dMBR ;
return;
}
/* GFID is not allowed to change unless PTYPE in picture header
changes */
gfid = getbits(2);
/* NB: in error-prone environments the decoder can use this
value to determine whether a picture header where the PTYPE
has changed, has been lost */
quant = getbits(5);
xpos = 0;
ypos = gob;
MBA = ypos * mb_width;
newgob = 1;
gobheader_read = 1;
if (syntax_arith_coding)
decoder_reset(); /* init. arithmetic decoder buffer after gob */
}
}
}
finish_gob: /* SAC specific label */
if (!gobheader_read) {
xpos = MBA%mb_width;
ypos = MBA/mb_width;
if (xpos == 0 && ypos > 0)
newgob = 0;
}
else
gobheader_read = 0;
if (MBA>=MBAmax)
return; /* all macroblocks decoded */
read_cod:
if (syntax_arith_coding) {
if (pict_type == PCT_INTER) {
COD_index = decode_a_symbol(cumf_COD);
if(COD_index < 0 )COD_index=0;
if(COD_index > 1 )COD_index=1;
COD = codtab[COD_index];
}
else
COD = 0; /* COD not used in I-pictures, set to zero */
}
else {
if (pict_type == PCT_INTER) {
COD = showbits(1);
}
else
COD = 0; /* Intra picture -> not skipped */
}
if (!COD) { /* COD == 0 --> not skipped */
if (syntax_arith_coding) {
if (pict_type == PCT_INTER) {
MCBPC_index = decode_a_symbol(cumf_MCBPC);
if(MCBPC_index<0)MCBPC_index=0;
if(MCBPC_index>=21)MCBPC_index=20;
MCBPC = mcbpctab[MCBPC_index];
}
else {
MCBPC_index = decode_a_symbol(cumf_MCBPC_intra);
if(MCBPC_index<0)MCBPC_index=0;
if(MCBPC_index>=9)MCBPC_index=8;
MCBPC = mcbpc_intratab[MCBPC_index];
}
}
else {
if (pict_type == PCT_INTER)
flushbits(1); /* flush COD bit */
if (pict_type == PCT_INTRA)
MCBPC = getMCBPCintra();
else
MCBPC = getMCBPC();
}
if (fault) goto resync;
if (MCBPC == -1) { /* stuffing */
goto read_cod; /* read next COD without advancing MB count */
}
else { /* normal MB data */
Mode = MCBPC & 7;
/* MODB and CBPB */
if (pb_frame) {
CBPB = 0;
if (syntax_arith_coding) {
MODB_index = decode_a_symbol(cumf_MODB);
if(MODB_index<0)MODB_index=0;
if(MODB_index>=3)MODB_index=2;
MODB = modb_tab[MODB_index];
}
else
MODB = getMODB();
if (MODB == PBMODE_CBPB_MVDB) {
if (syntax_arith_coding) {
for(i=0; i<4; i++) {
YCBPB_index = decode_a_symbol(cumf_YCBPB);
if(YCBPB_index<0)YCBPB_index=0;
if(YCBPB_index>1)YCBPB_index=1;
YCBPB = ycbpb_tab[YCBPB_index];
CBPB |= (YCBPB << (6-1-i));
}
for(i=4; i<6; i++) {
UVCBPB_index = decode_a_symbol(cumf_UVCBPB);
if(UVCBPB_index<0)UVCBPB_index=0;
if(UVCBPB_index>1)UVCBPB_index=1;
UVCBPB = uvcbpb_tab[UVCBPB_index];
CBPB |= (UVCBPB << (6-1-i));
}
}
else
CBPB = getbits(6);
}
}
if (syntax_arith_coding) {
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) { /* Intra */
CBPY_index = decode_a_symbol(cumf_CBPY_intra);
if(CBPY_index<0)CBPY_index=0;
if(CBPY_index>=16)CBPY_index=15;
CBPY = cbpy_intratab[CBPY_index];
}
else {
CBPY_index = decode_a_symbol(cumf_CBPY);
if(CBPY_index<0)CBPY_index=0;
if(CBPY_index>=16)CBPY_index=15;
CBPY = cbpytab[CBPY_index];
}
}
else
CBPY = getCBPY();
/* Decode Mode and CBP */
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
{/* Intra */
if (!syntax_arith_coding)
CBPY = CBPY^15; /* needed in huffman coding only */
}
CBP = (CBPY << 2) | (MCBPC >> 4);
}
if (Mode == MODE_INTER4V && !adv_pred_mode)
{ fault = 1 ;
/* Could set fault-flag and resync */
}
if (Mode == MODE_INTER_Q || Mode == MODE_INTRA_Q) {
/* Read DQUANT if necessary */
if (syntax_arith_coding) {
DQUANT_index = decode_a_symbol(cumf_DQUANT);
if(DQUANT_index<0)DQUANT_index=0;
if(DQUANT_index>=4)DQUANT_index=3;
DQUANT = dquanttab[DQUANT_index] - 2;
quant +=DQUANT;
}
else {
DQUANT = getbits(2);
if(DQUANT<0)DQUANT=0;
if(DQUANT>=4)DQUANT=3;
quant += DQ_tab[DQUANT];
}
if (quant > 31 || quant < 1) {
quant = mmax(1,mmin(31,quant));
/* could set fault-flag and resync here */
}
}
/* motion vectors */
if (Mode == MODE_INTER || Mode == MODE_INTER_Q ||
Mode == MODE_INTER4V || pb_frame) {
if (Mode == MODE_INTER4V) { startmv = 1; stopmv = 4;}
else { startmv = 0; stopmv = 0;}
for (k = startmv; k <= stopmv; k++) {
if (syntax_arith_coding) {
mvx_index = decode_a_symbol(cumf_MVD);
if(mvx_index<0)mvx_index=0;
if(mvx_index>=64)mvx_index=63;
mvx = mvdtab[mvx_index];
if(mvy_index<0)mvy_index=0;
if(mvy_index>=64)mvy_index=63;
mvy_index = decode_a_symbol(cumf_MVD);
mvy = mvdtab[mvy_index];
}
else {
mvx = getTMNMV();
mvy = getTMNMV();
}
#ifdef DEBUG_DENG
mytmp_01 = mvx; mytmp_02 = mvy; //deng
#endif
pmv0 = find_pmv(xpos,ypos,k,0);
pmv1 = find_pmv(xpos,ypos,k,1);
mvx = motion_decode(mvx, pmv0);
mvy = motion_decode(mvy, pmv1);
#ifdef DEBUG_DENG
fprintf(myfperr,"\n MB%3d: movevect(%4d,%4d ), (mvx,mvy)=(%4d, %4d ) ",MBA,mytmp_01,mytmp_02,mvx,mvy); //deng
fprintf(stderr, "\n MB%3d: movevect(%4d,%4d ), (mvx,mvy)=(%4d, %4d ) ",MBA,mytmp_01,mytmp_02,mvx,mvy); //deng
#endif
/* Check mv's to prevent seg.faults when error rate is high */
if (!mv_outside_frame) {
bsize = k ? 8 : 16;
offset = k ? (((k-1)&1)<<3) : 0;
/* checking only integer component */
if ((xpos<<4) + (mvx/2) + offset < 0 ||
(xpos<<4) + (mvx/2) + offset > (mb_width<<4) - bsize) {
fault = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -