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

📄 getpic.cpp

📁 这是一个基于H.263的视频压缩编码和解码的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
////////////////////////////////////////////////////////////////////////////
//
//
//    Project     : VideoNet version 1.1.
//    Description : Peer to Peer Video Conferencing over the LAN.
//	  Author      :	Nagareshwar Y Talekar ( nsry2002@yahoo.co.in)
//    Date        : 15-6-2004.
//
//    This is the modified version of tmndecode (H.263 decoder) 
//    written by Karl & Robert.It was in ANSI C. I have converted into C++
//    so that it can be integrated into any windows application. I have 
//    removed some of the files which had display and file storing 
//    functions.I have removed the unnecessary code and also added some
//    new files..
//	  Original library dealt with files. Input & Output , both were files.
//    I have done some major changes so that it can be used for real time 
//    decoding process. Now one can use this library for decoding H263 frames. 
//
//
//    File description : 
//    Name    : GetPic.cpp
//
/////////////////////////////////////////////////////////////////////////////



/************************************************************************
 *
 *  getpic.c, picture decoding for tmndecode (H.263 decoder)
 *  Copyright (C) 1996  Telenor R&D, Norway
 *        Karl Olav Lillevold <Karl.Lillevold@nta.no>
 *
 *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Karl Olav Lillevold               <Karl.Lillevold@nta.no>
 *  Telenor Research and Development
 *  P.O.Box 83                        tel.:   +47 63 84 84 00
 *  N-2007 Kjeller, Norway            fax.:   +47 63 81 00 76
 *
 *  Robert Danielsen                  e-mail: Robert.Danielsen@nta.no
 *  Telenor Research and Development  www:    http://www.nta.no/brukere/DVC/
 *  P.O.Box 83                        tel.:   +47 63 84 84 00
 *  N-2007 Kjeller, Norway            fax.:   +47 63 81 00 76
 *  
 ************************************************************************/

/*
 * modified by Wayne Ellis BT Labs to run Annex E Arithmetic Decoding
 *           <ellis_w_wayne@bt-web.bt.co.uk>
 *
 * based on mpeg2decode, (C) 1994, MPEG Software Simulation Group
 * and mpeg2play, (C) 1994 Stefan Eckart
 *                         <stefan@lis.e-technik.tu-muenchen.de>
 */




#include "GetPic.h"

/* decode one frame or field picture */

void getpicture(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;

  }

  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);


}


/**
*   Store the pointer to Y, U , V frames...
*  
*/
void storeframe(unsigned char *src[],int frame)
{
  
  yp=src[0];		// Y component
  up=src[1];        // U component
  vp=src[2];        // V component

}


/* decode all macroblocks of the current picture */

static void getMBs(int framenum)
{
  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",framenum,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) {
        if(trace)
		fputs("Warning: A Fault Condition Has Occurred - Resyncing \n",dlog);
      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)
              fputs("GN out of range\n",dlog);
            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) {
          fputs("Arithmetic Decoding Debug \n",dlog);
          //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) 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)	

⌨️ 快捷键说明

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