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

📄 getpic.cpp

📁 263yasuoyuv.rar是把yuv-411格式文件压缩为*.263可直看
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// Getpic.cpp: implementation of the CGetpic class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "视频编解码器.h"
#include "Getpic.h"

#include "indices.h" 
#include "sactbls.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define sign(a)         ((a) < 0 ? -1 : 1)
#define mmax(a, b)  	((a) > (b) ? (a) : (b))
#define mmin(a, b)  	((a) < (b) ? (a) : (b))

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
 int MV[2][5][MBR_MAX+1][MBC_MAX+2];
 int modemap[MBR_MAX+1][MBC_MAX+2];
extern int mv_outside_frame;
extern unsigned char *edgeframe[3], *edgeframeorig[3], *exnewframe[3],*bframe[3];
extern unsigned char *newframe[3],*oldrefframe[3],*refframe[3];
extern int horizontal_size,vertical_size,mb_width,mb_height;
extern int coded_picture_width, coded_picture_height,pb_frame;
extern int chrom_width,chrom_height,expand,outtype,newgob;
extern int MBC,MBR,syntax_arith_coding,quiet,quant,trace,fault,tr_framenum;
extern int trb,trd,blk_cnt,pict_type,adv_pred_mode,long_vectors;
extern unsigned char *clp;
extern ldecode *ld;


CGetpic::CGetpic()
{

}

CGetpic::~CGetpic()
{

}

void CGetpic::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)//扩张模式 得到图像时间上的分辨率
	{ //计算插值图像 Y U V
      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);
      //存储变换后的图像
      m_store.storeframe(exnewframe, *framenum);
    }
    else
      m_store.storeframe(bframe,*framenum);

   *framenum += pb_frame;

#ifdef USE_TIME
    if (framerate > 0)
      doframerate();
#endif
  }//end of(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);
     //存储变换后的图像文件
    m_store.storeframe(exnewframe, *framenum);
  }
  else
    m_store.storeframe(newframe,*framenum);

}

/*****************************************************************************/
void CGetpic::getMBs(int framenum)
{
  int comp;
  int MBA, MBAmax;
  int bx, by;
  CString outshow;

  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;

  // 每帧图象的宏块数
  MBAmax = mb_width*mb_height;
  MBA = 0; // 宏块标志 
  newgob = 0;
  //初始化图像边上的宏块的运动矢量
  // 1  标记图象上边沿MV 
  for (i = 1; i < MBC+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;
  }
  // 2 标记图象边沿的MV为0 
  for (i = 0; i < MBR+1; i++) 
  {
    for (k = 0; k < 5; k++) 
	{
      MV[0][k][i][0] = 0;
      MV[1][k][i][0] = 0;
      MV[0][k][i][MBC+1] = 0;
      MV[1][k][i][MBC+1] = 0;
    }
    modemap[i][0] = MODE_INTRA;
    modemap[i][MBC+1] = MODE_INTRA;
  }

  fault = 0;
  gobheader_read = 0;
  //开始解码:
  //1.先确定 COD
  //2.根据COD的值决定是否解码块头信息Mcbpc,Cbpy,Mode,MV
  //3.根据MV,Mode,CBPY,进行DCT变换恢复上一块的block数据(MBA-1)
  //4.根据Mode,CBPY 从Huffman系数中得到(Run level,last)恢复当前块的DCT系数

  for (;;) 
  {
    if (trace)
	{
		outshow.Format("frame %d, MB %d\n",tr_framenum,MBA);
        AfxMessageBox(outshow);
		outshow.Empty();
	}
  resync:
    if (fault) 
	{
      outshow.Format("Warning: A Fault Condition Has Occurred - Resyncing!");
      AfxMessageBox(outshow);
	  m_gethdr.startcode();  // sync on new startcode 
      fault = 0;
    }
    //确定是否是头信息
    if (!(m_getbits.showbits(22)>>6)) 
	{ // startcode 
      m_gethdr.startcode();  
      // 字节对齐,例如使用 PSTUF, GSTUF 或 ESTUF
      if (m_getbits.showbits(22) == (32|SEC)) 
	  { // EOS检测是否为序列结束标志 
	    if (!(syntax_arith_coding && MBA < MBAmax))
	        return;
      }
      else if ((m_getbits.showbits(22) == PSC<<5) ) //PSC=1
	  { // 新图像的开始
      	if (!(syntax_arith_coding && MBA < MBAmax)) 
	       return;
      }
      else 
	  {
	    if (!(syntax_arith_coding && MBA%MBC))
		{
	     if (syntax_arith_coding)
		 {   // SAC   
			 gob = (m_getbits.showbits(22) & 31); 
	         if (gob * mb_width != MBA) 
	           goto finish_gob;
		 }
    	 gob = m_gethdr.getheader() - 1;
	     if (gob > MBR) 
		 {
	       if (!quiet)
	         AfxMessageBox("GN out of range!");
	       return ;
		 } 
	     gfid = m_getbits.getbits(2);  //GFID 
 
	     quant = m_getbits.getbits(5);
	     if(trace)
		 {
	        outshow.Format("GQUANT: %d\n", quant);
			AfxMessageBox(outshow);
		 }
	     xpos = 0;
	     ypos = gob;
	     MBA = ypos * mb_width;
	  
	     newgob = 1;
	     gobheader_read = 1;
	     if (syntax_arith_coding) 
	        m_sacode.decoder_reset();// init SAD buffer
		} 
      } 
    }//end of(!(m_getbits.showbits(22)>>6)) 

  finish_gob:  
    //开始解MB
    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; /* 所有宏块解码完毕 */
 /*************************************************************/
	// 1.确定COD
 /*************************************************************/
  read_cod:
    if (syntax_arith_coding) //Sac code 
	{ 
      if (pict_type == PCT_INTER)
	  {
	     COD_index = m_sacode.decode_a_symbol(cumf_COD);
	     COD = codtab[COD_index];
      }
      else
	     COD = 0;// I帧不使用COD, COD=0
	}
    else  //比特编码
	{
      if(pict_type == PCT_INTER) 
	      COD = m_getbits.showbits(1);
      else
       	  COD = 0; // I_picture-> not skipped 
    } 
   /******************************************************/ 
	//2 根据COD确定是否要解码 其他块头信息(MCBPC CBPY MV)
   /*****************************************************/
    if(!COD) // COD == 0 --> not skipped
	{   
      if (syntax_arith_coding)
	  {
	    if (pict_type == PCT_INTER) 
		{
	        MCBPC_index = m_sacode.decode_a_symbol(cumf_MCBPC);
	        MCBPC = mcbpctab[MCBPC_index];
		}	 
	    else
		{
	        MCBPC_index = m_sacode.decode_a_symbol(cumf_MCBPC_intra);
	        MCBPC = mcbpc_intratab[MCBPC_index];
		} 
	    if (trace) 
		{
			outshow.Format("MCBPC Index: %d MCBPC: %d ",MCBPC_index, MCBPC);
			AfxMessageBox(outshow);
		}

	  }
      else //DCT_Huff
	  {   
	     if (pict_type == PCT_INTER)
	        m_getbits.flushbits(1); //flush COD bit 
      	 if (pict_type == PCT_INTRA) 
	        MCBPC = m_getvlc.getMCBPCintra();
      	 else
	        MCBPC = m_getvlc.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;
	   //To Get MODB and CBPB 
	    if (pb_frame) 
		{ 
	        CBPB = 0;
 	        if (syntax_arith_coding) 
			{ 
	            MODB_index = m_sacode.decode_a_symbol(cumf_MODB);
	            MODB = modb_tab[MODB_index];
			} 
	        else 
	            MODB = m_getvlc.getMODB();
	        if (MODB == PBMODE_CBPB_MVDB) 
			{
	          if (syntax_arith_coding) 
			  { 
	             for(i=0; i<4; i++)
				 { 
	      	        YCBPB_index = m_sacode.decode_a_symbol(cumf_YCBPB);
		            YCBPB = ycbpb_tab[YCBPB_index];
		            CBPB |= (YCBPB << (6-1-i));
				 } 
 
	             for(i=4; i<6; i++)
				 { 
		             UVCBPB_index = m_sacode.decode_a_symbol(cumf_UVCBPB);
		             UVCBPB = uvcbpb_tab[UVCBPB_index];
		             CBPB |= (UVCBPB << (6-1-i));
				 } 
			  } 
	          else
	             CBPB = m_getbits.getbits(6);
			  if (trace)
			  {
	              outshow.Format("CBPB = %d\n",CBPB);
		          AfxMessageBox(outshow);
			  } 
			}  
		}//end of(pb_frame)  
        //解码 CBPY
	    if (syntax_arith_coding)
		{ 

	      if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
		  { // Intra 
	         CBPY_index = m_sacode.decode_a_symbol(cumf_CBPY_intra);
	         CBPY = cbpy_intratab[CBPY_index];
		  } 
	      else
		  {
	         CBPY_index = m_sacode.decode_a_symbol(cumf_CBPY);
	         CBPY = cbpytab[CBPY_index];
		  } 
	      if (trace)
		  {
			  outshow.Format("CBPY Index: %d CBPY %d ",CBPY_index, CBPY);
              AfxMessageBox(outshow);
		  }
		} 
	    else 
	       CBPY = m_getvlc.getCBPY();
	    if (trace)
		{
	      outshow.Format("CBPY = %d",CBPY);
		  AfxMessageBox(outshow);
		}
 	    // 解码 Mode and CBP 
		if(Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
	         if (!syntax_arith_coding)	// Intra 
	           CBPY = CBPY^15;	 
    	CBP = (CBPY << 2) | (MCBPC >> 4);
      }
      //
      if(Mode == MODE_INTER4V && !adv_pred_mode) 
     	if(!quiet)
			AfxMessageBox("8x8 vectors not allowed in normal prediction mode\n");
          
      //确定是否要解码DQUANT
	  if(Mode == MODE_INTER_Q || Mode == MODE_INTRA_Q)

⌨️ 快捷键说明

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