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

📄 mpeg2dec.cpp

📁 mpeg2编码解码源程序代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		       pMPG2->cur_position=_telli64(ld->Infile);
		       break;
			  
		   }
	   }
	   else //连续解码
	   {
		   if(CurFrame<=frameno+framenum)
		   {
			   
			    char str[100];
				sprintf( str, "CurFrame=%d", CurFrame);

	//		    ::MessageBox(NULL,str,"okMPG2GetHeader",MB_OK);
				Decode_Picture(frameno,frameno,Framedst1);

			   //转换并存储

				SaveFrame(Framedst1,dst,Mode,&offset,stride);
			  //存储帧累加
				decode_Framenum++;
				pMPG2->frameno++;


				pMPG2->hour=hour;
				pMPG2->minute=minute;
				pMPG2->sec=sec;
				pMPG2->frame=frame;
				pMPG2->lframe=lframe;
				pMPG2->cur_bitno=frameno;
				if(pMPG2->mode==0)
					pMPG2->cur_position=_telli64(pMPG2->infile);

				break;
		   }
	   }
	}		
	///////////////////////////////
	//若首帧序号超过实际帧数,则存储帧数为0	
    //释放缓存
	for(i=0;i<3;i++)
	{
		pMPG2->backward_reference_frame[i]=backward_reference_frame[i];
		pMPG2->forward_reference_frame[i]=forward_reference_frame[i];
		pMPG2->auxframe[i]=auxframe[i];
    }
	memcpy(pMPG2->ld,&base,sizeof(layer_data));
    remain=base.length;
    free(Framedst1);
    GlobalUnlock(hMPG2);
 
   return remain; //返回实际解码帧数

}

HANDLE okMPG2BeginDecodeEx(LPSTR infile,LPBYTE lpData,LPARAM lpParam)
{
//   ::MessageBox(NULL,NULL,"okMPG2BeginDecodeEx",MB_OK);
   HANDLE hMPG2;
   environment_data *pMPG2;
 
   hMPG2=GlobalAlloc(GHND,sizeof(environment_data));
   if(!hMPG2)
	 Error("alloc hDecode mem fail");
   pMPG2=(environment_data *)GlobalLock(hMPG2);
   pMPG2->hFilesize=sizeof(environment_data);
 
 //  pMPG2->ld=(layer_data*)malloc(sizeof(layer_data));
   pMPG2->ld=(layer_data*)GlobalAlloc(GPTR,sizeof(layer_data));
   ld=&base;

   if(infile)
   {
	   pMPG2->mode=0;
	   pMPG2->ld->Infile=_open(infile,O_RDONLY|O_BINARY);
	   pMPG2->ld->mode=0;
	    pMPG2->frameno=1;
   }
   else
   {
	   pMPG2->mode=1;
	   pMPG2->ld->mode=1;
	   pMPG2->frameno=1;

   }
   init_dither_tab();
   Initialize_Decoder();



   	long total;
	char temp[16];

	mpg2_header_info *head;
	head=(mpg2_header_info*)lpParam;

	total=head->totalframe;

	pMPG2=(environment_data *)GlobalLock(hMPG2);

 	memcpy(&base,pMPG2->ld,sizeof(layer_data));


	hour=pMPG2->hour;
    minute=pMPG2->minute;
	sec=pMPG2->sec;
	frame=pMPG2->frame;
	
	thour=pMPG2->thour;
	tminute=pMPG2->tminute;
	tsec=pMPG2->tsec;
	tframe=pMPG2->tframe;

	check_stream(pMPG2,lpData);
	GetParam(pMPG2,lpData);
	if(pMPG2->mode==0)
    {
		GetTotalFrame(hMPG2,&total);
	}

	TotalFrame=total;
	head->headsize=sizeof(header_data);
	head->totalframe=total;
	head->bit_rate=bit_rate;
	head->frame_rate=frame_rate;
	head->color=24;
	pMPG2->width=horizontal_size;
    pMPG2->height=vertical_size;
	pMPG2->OK_ID=OK_ID;
	if(fabs(factor-1.000)>0.001)
	    head->horizontal_size=WIDTHBYTES((int)((double)horizontal_size*factor))*8;
	else
		head->horizontal_size=horizontal_size;
	head->vertical_size=vertical_size;
	pMPG2->factor=factor;

	pMPG2->mb_height=mb_height;
	pMPG2->mb_width=mb_width;
	pMPG2->Chroma_Width	=Chroma_Width ;
    pMPG2->Chroma_Height=Chroma_Height ;
    pMPG2->block_count=block_count;
	pMPG2->FileSize=FileSize;
	pMPG2->frame_rate=frame_rate;


	for (int cc=0; cc<3; cc++)
	{
		long size=0;
		if (cc==0)
          size = Coded_Picture_Width*Coded_Picture_Height;
        else
          size = Chroma_Width*Chroma_Height;
		pMPG2->backward_reference_frame[cc] = (unsigned char *)malloc(size);
   
        pMPG2->forward_reference_frame[cc] = (unsigned char *)malloc(size);
 
        pMPG2->auxframe[cc] = (unsigned char *)malloc(size);
  	}
	


	
	if(pMPG2->mode==0)
	    pMPG2->total=total;
	else
		pMPG2->total=100;

	memcpy(pMPG2->ld,&base,sizeof(layer_data));

   GlobalUnlock(hMPG2);
   return hMPG2;
}


void  okMPG2EndDecodeEx(HANDLE hMPG2)
{
//    ::MessageBox(NULL,NULL,"okMPG2EndDecodeEx",MB_OK);
    environment_data *pMPG2;
   	pMPG2=(environment_data *)GlobalLock(hMPG2);
	memcpy(&base,pMPG2->ld,sizeof(layer_data));

	
	for(int i=0;i<3;i++)
	{
		backward_reference_frame[i]=pMPG2->backward_reference_frame[i];
		forward_reference_frame[i]=pMPG2->forward_reference_frame[i];
		auxframe[i]=pMPG2->auxframe[i];
   }


	AUDIO=false;
	SEQEND=false;

	ClearGlobal();

	Initialize_Buffer(); 
	

	Deinitialize_Sequence();
	
	if(pMPG2->mode==0)
		_close(pMPG2->ld->Infile);


   //free(pMPG2->ld);
    GlobalFree(pMPG2->ld);
   GlobalUnlock(hMPG2);
   GlobalFree(hMPG2);
 
}

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

	long frameno;
	long framenum=1;
	long Mode=2;
	long TotalFrame;
	long remain=0;
	long tlframe=0;
	long b,e;
	mpg2_frame_info *info;
	info=(mpg2_frame_info *)lpParam;
	long skip;
	if(info)
		skip=info->skip;
	else
		skip=0;


    pMPG2=(environment_data *)GlobalLock(hMPG2);  //分配环境变量
   	if(pMPG2->mode==0)
		frameno=lParam+1;
	else
        frameno=pMPG2->frameno;
	for(int i=0;i<3;i++)
	{
		backward_reference_frame[i]=pMPG2->backward_reference_frame[i];
		forward_reference_frame[i]=pMPG2->forward_reference_frame[i];
		auxframe[i]=pMPG2->auxframe[i];
	}

	b=tell(pMPG2->ld->Infile);
	horizontal_size=pMPG2->width;
	vertical_size=pMPG2->height;

	memcpy(&base,pMPG2->ld,sizeof(layer_data));

	mb_height=pMPG2->mb_height;
	mb_width=pMPG2->mb_width;
	System_Stream_Flag=pMPG2->System_Stream_Flag;
	factor=pMPG2->factor;
	


	TotalFrame=pMPG2->total;
	Coded_Picture_Height=pMPG2->height;
    Coded_Picture_Width=pMPG2->width;
	Chroma_Width = pMPG2->Chroma_Width;
    Chroma_Height = pMPG2->Chroma_Height;
	block_count=pMPG2->block_count;
	OK_ID=pMPG2->OK_ID;
	FileSize=pMPG2->FileSize;
	TotalFrame=pMPG2->total;
	frame_rate=pMPG2->frame_rate;



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

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

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

	
		



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


    if(frameno==pMPG2->cur_bitno+1)
	{
		if(pMPG2->mode==0)
		{
		//连续解码
		SKIP=false;
		//初始化播放时间
	
	
		base.length=0;
	    //指向当前帧位置
		_lseeki64(ld->Infile,pMPG2->cur_position,SEEK_SET);
		}
		else
		{
				//连续解码
			if(frameno==1)
		       base.lpData=lpBuf;
		base.length=0;
		base.size=lParam;
		SKIP=false;
	
	
		//初始化播放时间
		}
		hour=pMPG2->hour;
        minute=pMPG2->minute;
        sec=pMPG2->sec;
        lframe=pMPG2->lframe;
	    frame=pMPG2->frame;

		thour=pMPG2->thour;
        tminute=pMPG2->tminute;
        tsec=pMPG2->tsec;
        tlframe=pMPG2->tlframe;
	    tframe=pMPG2->tframe;
	
	}
	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);
		 }
		 	thour=pMPG2->thour;
        tminute=pMPG2->tminute;
        tsec=pMPG2->tsec;
        tlframe=pMPG2->tlframe;
	    tframe=pMPG2->tframe;
	
	
		//跳跃解码
		//计算粗略文件位置
		filecur=FileSize*(_int64)(frameno-interval)/(_int64)(TotalFrame);
		filecur=filecur/2048*2048;
	    if(filecur>=0)
	        _lseeki64(ld->Infile,filecur,SEEK_SET);
		else
		     lseek(ld->Infile,0l,SEEK_SET);
		Initialize_Buffer();
		
		//精确定位
        if(frameno>4*cal)
		{

			BACK=false;
			_int64 Ioffset;
	        while(1)
			{

				Ioffset=_telli64(ld->Infile);
			
		        if(!Headers())
				{
                    lseek(ld->Infile,0l,SEEK_SET);
					SEQEND=false;
					break;
				}
	            if(picture_coding_type==I_TYPE)
				{
		   	         CurFrame=((hour-thour)*3600+(minute-tminute)*60+(sec-tsec))*(int)(frame_rate+0.5)+(frame-tframe+1);
                     //粗略位置超过实际位置
					 if(CurFrame>frameno-cal)
					 {
					
						 BACK=true;
						 //跨度增加一个间隔
		                 interval+=4*(N+M+1);
		                 filecur=FileSize*(_int64)(frameno-interval)/(_int64)(TotalFrame);
		                 filecur=filecur/2048*2048;
						 if(filecur>=0)
	                        _lseeki64(ld->Infile,filecur,SEEK_SET);
		                 else
		                    lseek(ld->Infile,0l,SEEK_SET);
					 }
					 else if(!BACK&&frameno-cal-CurFrame>4*(N+M+1))
					 {
						 //粗略位置小于实际位置超过一个跨度
						 //减少一个跨度
						 interval-=4*(N+M+1); 
						 filecur=FileSize*(_int64)(frameno-interval)/(_int64)(TotalFrame);
		                 filecur=filecur/2048*2048;
						 if(filecur>=0)
	                        _lseeki64(ld->Infile,filecur,SEEK_SET);
		                 else
		                    lseek(ld->Infile,0l,SEEK_SET);

					 }
					 else
					 {
						 lseek(ld->Infile,Ioffset,SEEK_SET);
						 break;
					 }
		         

				}

			 }		
			 Initialize_Buffer();
		} 
	}
	//开始解码

	SEQEND=false;          //文件末尾标记
	while(1)
	{
		if(!Headers())
		{
			
			 pMPG2->hour=hour;
		     pMPG2->minute=minute;
		     pMPG2->sec=sec;
		     pMPG2->frame=frame;
		     pMPG2->lframe=lframe;
		     pMPG2->cur_bitno=frameno;
		     pMPG2->cur_position=_telli64(ld->Infile);
			 	//读文件尾

            if(frameno==TotalFrame)
			{
		         //存储最后一帧
                 Output_Last_Frame_of_Sequence(CurFrame,Framedst1);
	             SaveFrame(Framedst1,dst,Mode,&offset,stride);
	             decode_Framenum++;
			}
			break;
		}
	   if(picture_coding_type==I_TYPE)
	   {
		   //寻找图像组首位置
		   FirstI=true;
		   lframe=0;   //组内序号归零
	   }
	   else
	   {
		   //若不是图像组首且为非连续解码,则继续寻找。
		   if(!FirstI&&SKIP)
			 continue;
		    lframe++;   //组内序号加1
	   }
	   //计算当前帧号
		   CurFrame=((hour-thour)*3600+(minute-tminute)*60+(sec-tsec))*(int)(frame_rate+0.5)+(frame-tframe+1+lframe);
	  //若当前帧号大于解码帧号,则结束循环

	   if(CurFrame>frameno+framenum)
	   {	
            memset(Framedst1,0,Coded_Picture_Height*Coded_Picture_Width*3);
		    SaveFrame(Framedst1,dst,Mode,&offset,stride); 
		    break;
	   }
	
		 

       //跳跃解码	
	   if(SKIP)
	   {

		   if(FirstI)
		   {
			   Decode_Picture(CurFrame, CurFrame,Framedst1);
			 
			   //若等于解码帧号转换并存储
	        
			 
		       SaveFrame(Framedst1,dst,Mode,&offset,stride); 
			      //存储帧累加
		       decode_Framenum++;	
			   pMPG2->hour=hour;
		       pMPG2->minute=minute;
		       pMPG2->sec=sec;
		       pMPG2->frame=frame;
		       pMPG2->lframe=lframe;
		       pMPG2->cur_bitno=frameno;
			
		       pMPG2->cur_position=_telli64(ld->Infile);
		       break;
			  
		   }
/*		   //若当前帧号大于等于解码间隔
	      if(CurFrame>=frameno-cal&&CurFrame<=frameno+framenum)
		  { 
			  //解码
			  if(!skip)
		          Decode_Picture(CurFrame, CurFrame,Framedst1);
			 if(CurFrame==frameno)
			 {
				 if(info)
			      info->frame_type=picture_coding_type;
			 }
			   
			   //若等于解码帧号转换并存储
	          if(CurFrame==frameno+1)
			  {
		         SaveFrame(Framedst1,dst,Mode,&offset,stride); 
			   //存储帧累加
		         decode_Framenum++;	
			  }
		  }
		   //若等于解码帧号,结束循环,并存储相关信息
	      if(CurFrame==frameno+framenum)
		  { 
			 pMPG2->hour=hour;
		     pMPG2->minute=minute;
		     pMPG2->sec=sec;
		     pMPG2->frame=frame;
		     pMPG2->lframe=lframe;
		     pMPG2->cur_bitno=frameno;
			
		     pMPG2->cur_position=_telli64(ld->Infile);
		     break;
		  }*/
	   }
	   else //连续解码
	   {
		   if(CurFrame<=frameno+framenum)
		   {
			   if(!skip)
		         Decode_Picture(CurFrame,CurFrame,Framedst1);
			   if(CurFrame==frameno)
			   {
				   if(info)
			       info->frame_type=picture_coding_type;
			   }
			 
	        
			   //转换并存储
		   if(CurFrame==frameno+1)
		   {
		       SaveFra

⌨️ 快捷键说明

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