⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 getpic.c

📁 音视频编解码的H.263协议-C语言编写
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include "config.h"#include "tmndec.h"#include "global.h"#include "indices.h" #include "sactbls.h"extern struct _VideoFrame {                                 unsigned char *Raw[2];                                 unsigned char *refframe[3];                                 unsigned char *oldrefframe[3];                                 unsigned char *bframe[3];                            }VideoFrameData[];extern int DstWindow;/* private prototypes*/static void getMBs();static void clearblock(int );static int motion_decode(int ,int );static int find_pmv(int , int , int , int );static void addblock(int , int , int ,int );static void reconblock_b(int ,int ,int ,int ,int , int );static void find_bidir_limits(int , int *, int*, int);static void find_bidir_chroma_limits(int , int *, int*);static void make_edge_image(unsigned char *,unsigned char *,int ,int ,int );void interpolate_image(unsigned char *, unsigned char *, int , int );/* decode one frame or field picture */void getpicture(int *framenum){  int i;  unsigned char *tmp;  for (i=0; i<3; i++)   {    tmp = VideoFrameData[DstWindow].oldrefframe[i];    VideoFrameData[DstWindow].oldrefframe[i] = 		VideoFrameData[DstWindow].refframe[i];    VideoFrameData[DstWindow].refframe[i] = tmp;    newframe[i] = VideoFrameData[DstWindow].refframe[i];  }  if (mv_outside_frame && *framenum > 0)   {    make_edge_image(VideoFrameData[DstWindow].oldrefframe[0],		edgeframe[0],coded_picture_width,            coded_picture_height,32);    make_edge_image(VideoFrameData[DstWindow].oldrefframe[1],		edgeframe[1],chrom_width, chrom_height,16);    make_edge_image(VideoFrameData[DstWindow].oldrefframe[2],		edgeframe[2],chrom_width, chrom_height,16);  }  getMBs();  if (pb_frame)   {	dither(VideoFrameData[DstWindow].bframe);  }  else  {  	dither(newframe);  }  *framenum += pb_frame;}/* decode all macroblocks of the current picture */static void getMBs(){  int comp;  int MBA, MBAmax;  int bx, by;  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 < mb_width+1; i++) {    for (k = 0; k < 5; k++) {      MV[0][k][0][i] = NO_VEC;      MV[1][k][0][i] = NO_VEC;    }    modemap[0][i] = MODE_INTRA;  }  /* zero MV's on the sides of the picture */  for (i = 0; i < mb_height+1; i++) {    for (k = 0; k < 5; k++) {      MV[0][k][i][0] = 0;      MV[1][k][i][0] = 0;      MV[0][k][i][mb_width+1] = 0;      MV[1][k][i][mb_width+1] = 0;    }    modemap[i][0] = MODE_INTRA;    modemap[i][mb_width+1] = MODE_INTRA;  }  fault = 0;  gobheader_read = 0;    for (;;) {	 if (trace)      printf("frame %d, MB %d\n",0,MBA);  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) {      printf("Warning: A Fault Condition Has Occurred - Resyncing \n");      startcode();  /* sync on new startcode */      fault = 0;    }    if (!(showbits(22)>>6))  /* startcode */    {      startcode();        /* in case of byte aligned start code, ie. PSTUF, GSTUF or ESTUF         is used */            if (showbits(22) == (32|SE_CODE))  /* 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%mb_width))         {          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 > mb_height) 	  {            if (!quiet)              printf("GN out of range\n");            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);          if (trace)            printf("GQUANT: %d\n", quant);          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);        COD = codtab[COD_index];        if (trace) {          printf("Arithmetic Decoding Debug \n");          printf("COD Index: %d COD: %d \n", COD_index, COD);        }      }      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);          MCBPC = mcbpctab[MCBPC_index];        }	        else {          MCBPC_index = decode_a_symbol(cumf_MCBPC_intra);          MCBPC = mcbpc_intratab[MCBPC_index];        }        if (trace)           printf("MCBPC Index: %d MCBPC: %d \n",MCBPC_index, MCBPC);      }      else {        if (pict_type == PCT_INTER)          flushbits(1); /* flush COD bit */        if (pict_type == PCT_INTRA)           MCBPC = getMCBPCintra();        else          MCBPC = getMCBPC();      }      	if (fault) 	{	if (trace)	printf("resync\n");	goto resync;	}            if (MCBPC == 255) { /* 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);            MODB = modb_tab[MODB_index];          }          else             MODB = getMODB();          if (trace)            printf("MODB: %d\n", MODB);          if (MODB == PBMODE_CBPB_MVDB) {            if (syntax_arith_coding)  {              for(i=0; i<4; i++) {        YCBPB_index = decode_a_symbol(cumf_YCBPB);        YCBPB = ycbpb_tab[YCBPB_index];        CBPB |= (YCBPB << (6-1-i));              }               for(i=4; i<6; i++) {        UVCBPB_index = decode_a_symbol(cumf_UVCBPB);        UVCBPB = uvcbpb_tab[UVCBPB_index];        CBPB |= (UVCBPB << (6-1-i));              }            }            else              CBPB = getbits(6);            if (trace)              printf("CBPB = %d\n",CBPB);          }        }        if (syntax_arith_coding) {          if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) { /* Intra */            CBPY_index = decode_a_symbol(cumf_CBPY_intra);            CBPY = cbpy_intratab[CBPY_index];          }          else {            CBPY_index = decode_a_symbol(cumf_CBPY);            CBPY = cbpytab[CBPY_index];                  }          if (trace)            printf("CBPY Index: %d CBPY %d \n",CBPY_index, CBPY);        }        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)         if (!quiet)          printf("8x8 vectors not allowed in normal prediction mode\n");          /* 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);          DQUANT = dquanttab[DQUANT_index] - 2;           quant +=DQUANT;          if (trace)            printf("DQUANT Index: %d DQUANT %d \n",DQUANT_index, DQUANT);        }        else {          DQUANT = getbits(2);          quant += DQ_tab[DQUANT];          if (trace) {            printf("DQUANT (");            printbits(DQUANT,2,2);            printf("): %d = %d\n",DQUANT,DQ_tab[DQUANT]);          }        }        if (quant > 31 || quant < 1) {          if (!quiet)            printf("Quantizer out of range: clipping\n");          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);            mvx = mvdtab[mvx_index];            mvy_index = decode_a_symbol(cumf_MVD);            mvy = mvdtab[mvy_index];            if (trace)              printf("mvx_index: %d mvy_index: %d \n", mvy_index, mvx_index);          }          else {            mvx = getTMNMV();            mvy = getTMNMV();          }          pmv0 = find_pmv(xpos,ypos,k,0);          pmv1 = find_pmv(xpos,ypos,k,1);          mvx = motion_decode(mvx, pmv0);          mvy = motion_decode(mvy, pmv1);          if (trace) {            printf("mvx: %d\n", mvx);            printf("mvy: %d\n", mvy);          }          /* 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) {              if (!quiet)        printf("mvx out of range: searching for sync\n");              fault = 1;            }            offset = k ? (((k-1)&2)<<2) : 0;            if ((ypos<<4) + (mvy/2) + offset < 0 ||        (ypos<<4) + (mvy/2) + offset > (mb_height<<4) - bsize) {              if (!quiet)        printf("mvy out of range: searching for sync\n");              fault = 1;            }          }          MV[0][k][ypos+1][xpos+1] = mvx;          MV[1][k][ypos+1][xpos+1] = mvy;        }        /* PB frame delta vectors */        if (pb_frame) {          if (MODB == PBMODE_MVDB || MODB == PBMODE_CBPB_MVDB) {            if (syntax_arith_coding) {              mvdbx_index = decode_a_symbol(cumf_MVD);              mvdbx = mvdtab[mvdbx_index];                            mvdby_index = decode_a_symbol(cumf_MVD);              mvdby = mvdtab[mvdby_index];            }            else {              mvdbx = getTMNMV();              mvdby = getTMNMV();            }            mvdbx = motion_decode(mvdbx, 0);            mvdby = motion_decode(mvdby, 0);            /* This will not work if the PB deltas are so large they               require the second colums of the motion vector VLC               table to be used.  To fix this it is necessary to               calculate the MV predictor for the PB delta: TRB*MV/TRD               here, and use this as the second parameter to               motion_decode(). The B vector itself will then be               returned from motion_decode(). This will have to be               changed to the PB delta again, since it is the PB delta               which is used later in this program. I don't think PB               deltas outside the range mentioned above is useful, but               you never know... */            if (trace) {              printf("MVDB x: %d\n", mvdbx);              printf("MVDB y: %d\n", mvdby);            }          }          else {            mvdbx = 0;             mvdby = 0;          }        }      }      	if (fault) 	{        if (trace)        printf("resync 1\n");	goto resync;	}    }    else { /* COD == 1 --> skipped MB */      if (MBA>=MBAmax)        return; /* all macroblocks decoded */      if (!syntax_arith_coding)        if (pict_type == PCT_INTER)          flushbits(1);      Mode = MODE_INTER;            /* Reset CBP */      CBP = CBPB = 0;      /* reset motion vectors */      MV[0][0][ypos+1][xpos+1] = 0;      MV[1][0][ypos+1][xpos+1] = 0;      mvdbx = 0;      mvdby = 0;    }    /* Store Mode*/    modemap[ypos+1][xpos+1] = Mode;    if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)       if (!pb_frame)        MV[0][0][ypos+1][xpos+1]=MV[1][0][ypos+1][xpos+1] = 0;  reconstruct_mb:    /* pixel coordinates of top left corner of current macroblock */    /* one delayed because of OBMC */    if (xpos > 0) {      bx = 16*(xpos-1);      by = 16*ypos;    }    else {      bx = coded_picture_width-16;      by = 16*(ypos-1);    }    if (MBA > 0) {      Mode = modemap[by/16+1][bx/16+1];      /* forward motion compensation for B-frame */      if (pb_frame)        reconstruct(bx,by,0,pmvdbx,pmvdby);            /* motion compensation for P-frame */      if (Mode == MODE_INTER || Mode == MODE_INTER_Q || Mode == MODE_INTER4V)        reconstruct(bx,by,1,0,0);      /* copy or add block data into P-picture */      for (comp=0; comp<blk_cnt; comp++) {        /* inverse DCT */        if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) {          if (refidct)            idctref(ld->block[comp]);          else            _idct_(ld->block[comp]);          addblock(comp,bx,by,0);        }        else if ( (pCBP & (1<<(blk_cnt-1-comp))) ) {          /* No need to to do this for blocks with no coeffs */          if (refidct)            idctref(ld->block[comp]);          else            _idct_(ld->block[comp]);          addblock(comp,bx,by,1);        }      }                  if (pb_frame) {        /* add block data into B-picture */        for (comp = 6; comp<blk_cnt+6; comp++) {          if (!pCOD || adv_pred_mode)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -