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

📄 mpeg2dec.cpp

📁 mpeg2编码解码源程序代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
      *total=temp;
   }
   
  
   lseek(pDecode->infile, 0l, 0);
   if(pDecode->infile!=0)
   {
     lseek(pDecode->infile, 0l, 0);
   }
   Initialize_Buffer(); 
   SEQEND=false;
   base.Infile=pDecode->infile;
   GlobalUnlock(hDecode);
}

int scale[768];
int scaleB[768];
int scaleT[1024][1024];
//初始化缩放表
void initscale()
{
   long  sw=horizontal_size;
   long  dw=WIDTHBYTES((int)((double)sw*factor))*8;
   if(fabs(factor-1.0000)<0.0001)
	   dw=sw;

   for ( int j = 0; j < dw; j++ )
   {

        scale[j] = j * sw / dw;
        scaleB[j] = dw-j * sw % dw;
	}
   
    for ( j = -256; j < 256; j++ )
	 for ( int i = 0; i <dw; i++ )
    {

        scaleT[256+j][i]=j*i/dw;
	}

}
void GetHeader1(HANDLE hDecode)
{
   short N=0;
   short M=0;
   BOOL FirstP=false;
   BOOL FirstFrame=false;
   environment_data *pDecode;


   pDecode=(environment_data *)GlobalLock(hDecode);
   base.Infile=pDecode->infile;
   SEQEND=false; 
  
   //记录M,N  
   lseek(pDecode->infile, 0l, 0);
   if(pDecode->infile!=0)
   {
     lseek(pDecode->infile, 0l, 0);
   }
   Initialize_Buffer(); 

   while(Headers())
   {
	   //得到开始时间
	    if(picture_coding_type==I_TYPE&&!FirstFrame)
		{
			tframe=frame;
			tsec=sec;
			tminute=minute;
			thour=hour;
			FirstFrame=true;
		}
	    if(picture_coding_type==P_TYPE&&N>1)
		{
			FirstP=true;
		}
		if(picture_coding_type==I_TYPE&&N>1)
		{
			break;
		}
		if(!FirstP)
			M++;
		N++;
   }
   SEQEND=false;
   Initialize_Sequence();
   pDecode->cur_position=0l;
   pDecode->M=M;
	pDecode->N=N;
	pDecode->infile=base.Infile;

 
	//确定缩放比例系数
	if(OK_ID)
	{
	   if(vertical_size==576||vertical_size==384||vertical_size==288)
	       factor=768.0/720.0;
       else if(vertical_size==480||vertical_size==320||vertical_size==240)
		   factor=640.0/720.0;
	   else
	   {
		   factor=1.000;
	   }
	}
	else
	{
		factor=1.000;
	}

    MaxFrame=bit_rate/(frame_rate*8);  //估计帧大小
	FileSize=_filelengthi64(pDecode->infile); //得到文件长度

	initscale();                       //初始化缩放表
    GlobalUnlock(hDecode);
}

int  Stretch_Linear(unsigned char *src,unsigned char *dst2,long width,long height,long stride, double factor, int nPixelSize)
{

    long sw = width , sh = height, dw = WIDTHBYTES((int)((double)sw*factor))*8, dh = sh;
	long B; 
	long x;
    unsigned char * pLinePrev;
    unsigned char * pA, *pB;
	if(fabs(factor-1.000)<0.001)
	{	
		dw=sw;
	}
	long Width=dw*nPixelSize;
    long sWidth=sw*nPixelSize;
    long dw14=dw/4;
    long dw34=dw*3/4;
	long off;

	if(stride<0)
	  off=abs(stride+Width);
	else
	   off=stride-Width;

    for (int  i = 0; i <dh; i++ )
    {
        pLinePrev=src;
        for ( int j = 0; j < dw; j++ )
        {

            x = scale[j]*nPixelSize;
            B = scaleB[j];
            pA = pLinePrev + x;
            pB = pA + nPixelSize;

            if (dw-B<=dw14)   //目标点在原始点左1/4
            {
				*dst2++=*pA++;
				if(nPixelSize>1)
				{
				   *dst2++=*pA++;
				   *dst2++=*pA++;
				}
			
            }
			else if(dw-B>=dw34)  //在右3/4
			{
				
				*dst2++=*pB++;
				if(nPixelSize>1)
				{
				   *dst2++=*pB++;
				   *dst2++=*pB++;
				}

			}
			else               //在中间1/2
			{	
				
				//线性差值
				*dst2++=scaleT[(*pA-*pB)+256][B]+*pB;
				if(nPixelSize>1)
				{
				   *dst2++=scaleT[(*(pA+1)-*(pB+1))+256][B]+*(pB+1);
			       *dst2++=scaleT[(*(pA+2)-*(pB+2))+256][B]+*(pB+2);
				}
			}
        }
		src+=sWidth;
		dst2+=off;
		if(stride<0)
		{
			dst2+=stride;
		    dst2+=stride;
		}
    }

    return 0;

}

void YUVtoRGB24(unsigned char *src,unsigned char *buf1,long width,long height,long stride)
{
   short Y,U,V,B,G,R;
   long Ysize=width*height;
   long Usize=Ysize+Chroma_Width*Chroma_Height;
   long off;
   long Yi,Vi;
   long woff=width/2;
   long i,j;
   unsigned char *dsts;   //解码缓存指针

    Yi=0;
    Vi=0;
	if(OK_ID)
	{
		if(!(dsts=(unsigned char*)GlobalAlloc(GMEM_FIXED,width*height*3*sizeof(unsigned char))))
			Error("alloc frame mem fail");
	for (j=0;j<height;j++) 
	{
		 for (i=0;i<width;i++) 
		{	
			
			Y=*(src+Yi);
			Yi++;

			U=*(src+Vi+Ysize);
			V=*(src+Vi+Usize);
			if(chroma_format==CHROMA420)
			{
			if(j%2!=0&&i==0)
			{
				Vi-=woff;
			}
			else
			{
				if(i%2!=0)
				Vi++;
			}
			}
			else if(chroma_format==CHROMA422)
			{
			   if(i%2!=0)
				Vi++;
			}
			else
			{
				Vi++;
			}
			B = Clip[(tab_76309[Y] + cbu_tab[U]) >> 16];
			G = Clip[(tab_76309[Y] - cgu_tab[U] - cgv_tab[V]) >> 16];
			R = Clip[(tab_76309[Y] + crv_tab[V]) >> 16];
			if(j<vertical_size&&i<horizontal_size)
			{
			*dsts=B;
			dsts++;
			*dsts=G;
			dsts++;
			*dsts=R;
			dsts++;
			}

		}
	   }
	   dsts-=vertical_size*horizontal_size*3;
	 //缩放
	  Stretch_Linear(dsts,buf1,horizontal_size,vertical_size,stride, factor,3);
	  	  GlobalFree(dsts);
	}
	else
	{
	long off;
	int	Width=3*width;
	if(stride<0)
	  off=abs(stride+Width);
	else
	   off=stride-Width;
	dsts=buf1;
	if(!dsts)
    {
		Error("alloc frame mem fail");
	}
	for (j=0;j<height;j++) 
	{
		 for (i=0;i<width;i++) 
		{	
			
			Y=*(src+Yi);
			Yi++;

			U=*(src+Vi+Ysize);
			V=*(src+Vi+Usize);
			if(chroma_format==CHROMA420)
			{
			if(j%2!=0&&i==0)
			{
				Vi-=woff;
			}
			else
			{
				if(i%2!=0)
				Vi++;
			}
			}
			else if(chroma_format==CHROMA422)
			{
			   if(i%2!=0)
				Vi++;
			}
			else
			{
				Vi++;
			}
			
			B = Clip[(tab_76309[Y] + cbu_tab[U]) >> 16];
			G = Clip[(tab_76309[Y] - cgu_tab[U] - cgv_tab[V]) >> 16];
			R = Clip[(tab_76309[Y] + crv_tab[V]) >> 16];

		
			if(j<vertical_size&&i<horizontal_size)
			{
			*dsts=B;
			dsts++;
			*dsts=G;
			dsts++;
			*dsts=R;
			dsts++;
			}

		}
		 dsts+=off;
	   	if(stride<0)
		{
			dsts+=stride;
		    dsts+=stride;
		}
	   }
	    

	}
}
void YUVtoGRAY8(unsigned char *src,unsigned char *buf1,long width,long height,long stride)
{
   short Y,U,V,B,G,R;
   long Width=horizontal_size*1;
   long Ysize=width*height;
   long Usize=Ysize+Chroma_Width*Chroma_Height;
   long off;
   long Yi,Vi;
   long woff=width/2;
   long i,j;
    unsigned char *dsts;   //解码缓存指针
   
   Yi=0;
   Vi=0;
  
	if(stride<0)
	  off=abs(stride+Width);
	else
		off=stride-Width;

	
 
	dsts=(unsigned char*)GlobalAlloc(GMEM_FIXED,width*height*3*sizeof(unsigned char));
    if(!dsts)
    {
		Error("alloc frame mem fail");
	}

	   for (j=0;j<height;j++) 
	   {
		 for (i=0;i<width;i++) 
		{	
			Y=*(src+Yi);
			Yi++;
			B = Y;
			if(j<vertical_size&&i<horizontal_size)
			{
			*dsts=B;
			dsts++;
			}
		}
		 
	   }
	  dsts-=vertical_size*horizontal_size;
	  Stretch_Linear(dsts,buf1,horizontal_size,vertical_size,stride, factor,1);
	  GlobalFree(dsts);
}

void YUVtoYUV422(unsigned char *src,unsigned char *buf1,long width,long height,long stride)
{

   short Y,U,V,B,G,R;
   long Width=horizontal_size*2;
   long Ysize=width*height;
   long Usize=Ysize+Chroma_Width*Chroma_Height;
   long off;
   long Yi,Vi;
   long woff=width/2;
   long i,j;
   
   Yi=0;
   Vi=0;
	if(stride<0)
	  off=abs(stride+Width);
	else
		off=stride-Width;

	
	

	   for (j=0;j<height;j++) 
	   {
		 for (i=0;i<width;i++) 
		{	
			Y=*(src+Yi);
			Yi++;

			U=*(src+Vi+Ysize);
			V=*(src+Vi+Usize);
			if(chroma_format==CHROMA420)
			{
			if(j%2!=0&&i==0)
			{
				Vi-=woff;
				if(i%2!=0)
				Vi++;
			}
			else
			{
				if(i%2!=0)
				Vi++;
			}
			}
			else if(chroma_format==CHROMA422)
			{
			   if(i%2!=0)
				Vi++;
			}
			else
			{
				Vi++;
			}
			if(j<vertical_size&&i<horizontal_size){
			if(i%2==0)
			   *buf1=U;
			else
			   *buf1=V;
			buf1++;
			*buf1=Y;
			buf1++;}

		}
			buf1+=off;
			if(stride<0)
			{
				buf1+=stride;
			    buf1+=stride;
			}
	   }

}

void SaveFrame(unsigned char* Framedst1,unsigned char* dst,short Mode,long* offset,long stride)
{

	switch(Mode)
	{
			case GRAY8:
			    YUVtoGRAY8(Framedst1,dst+*offset, Coded_Picture_Width,Coded_Picture_Height,stride);
			   (*offset)+=vertical_size*stride;
				break;
			case RGB24:	
              	YUVtoRGB24(Framedst1,dst+*offset, Coded_Picture_Width,Coded_Picture_Height,stride);			    
				(*offset)+=vertical_size*stride;
				break;
			case YUV422:
			    YUVtoYUV422(Framedst1,dst+*offset, Coded_Picture_Width,Coded_Picture_Height,stride);
			    (*offset)+=vertical_size*stride;
			    break;
			case YUV420:
                memcpy(dst+*offset,Framedst1,Coded_Picture_Height*abs(stride));
                (*offset)+=vertical_size*stride;
				break;
			default:
				break;
	}

}



short DecodeMpeg2(HANDLE hDecode, unsigned char *dst, long framenum,long frameno, short Mode,long stride)
{
	//分配存储空间
	long offset=0;             //存储偏移量
	unsigned char *Framedst1;   //解码缓存指针
	environment_data *pDecode;   //文件指针
	short decode_Framenum;    //实际解码帧数
	short N,M;                  //N,M变量
	short cal;                  //跳跃解码间隔
	long CurFrame=0;            //当前帧号
	long lframe=0;             //图像组内序号
	BOOL SKIP;                  //跳跃解码标记
	_int64 interval;            //文件位置跨度
	_int64 filecur;             //粗略文件位置
	BOOL BACK;                  //文件位置后向查找标记
	BOOL FirstI;                //图像组位置标记

			  
	if(frameno-1>=TotalFrame)    //若帧号大于总帧数则返回0    
	{

		memset(Framedst1,0,Coded_Picture_Height*Coded_Picture_Width*3);
		SaveFrame(Framedst1,dst,Mode,&offset,stride); 
		return 0;
	}
	
		


	//分配存储空间
	Framedst1=(unsigned char*)malloc(Coded_Picture_Height*Coded_Picture_Width*3);
	if(!Framedst1)
		Error("alloc frame mem fail");

    pDecode=(environment_data *)GlobalLock(hDecode);  //分配环境变量
	base.Infile=pDecode->infile;                      

    //初始化
	N=pDecode->N;                                    
	M=pDecode->M;
	decode_Framenum=0; 
	cal=N+M+1;
	interval=4*(N+M+1);		
	AUDIO=false;
    SEQEND=false;
	FirstI=false;
	SKIP=true;
		


    if(frameno==pDecode->cur_bitno+1)
	{
		//连续解码
		SKIP=false;
		//初始化播放时间
		hour=pDecode->hour;
        minute=pDecode->minute;
        sec=pDecode->sec;
        lframe=pDecode->lframe;
	    frame=pDecode->frame;
	    //指向当前帧位置
		_lseeki64(pDecode->infile,pDecode->cur_position,SEEK_SET);
	}
	else
	{
		 for (int cc=0; cc<3; cc++)
		 {
			 long size;
             if (cc==0)
                 size = Coded_Picture_Width*Coded_Picture_Height;
             else
                 size = Chroma_Width*Chroma_Height;
             memset(backward_reference_frame[cc],0,size);
	         memset(forward_reference_frame[cc],0,size);
	         memset(auxframe[cc],0,size);
		 }
	
		//跳跃解码
		//计算粗略文件位置
		filecur=FileSize*(_int64)(frameno-interval)/(_int64)(TotalFrame);
		filecur=filecur/2048*2048;
	    if(filecur>=0)
	        _lseeki64(pDecode->infile,filecur,SEEK_SET);
		else

⌨️ 快捷键说明

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