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

📄 mpeg2dec.cpp

📁 mpeg2编码解码源程序代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
   SEQEND=false;
   base.Infile=pMPG2->ld->Infile;
   GlobalUnlock(hMPG2);
}
void GetParam(environment_data *pMPG2,LPBYTE lpBuf)
{
	short N=0;
	short M=0;
	BOOL FirstP=false;
	BOOL FirstFrame=false;

	if(pMPG2->mode==0)
	{
		SEQEND=false; 
		
		//记录M,N  
		lseek(ld->Infile, 0l, 0);
		if(ld->Infile!=0)
		{
			lseek(ld->Infile, 0l, 0);
		}
	
		Initialize_Buffer(); 
		
		while(Headers())
		{
			//得到开始时间
			if(picture_coding_type==I_TYPE&&!FirstFrame)
			{
				pMPG2->tframe=frame;
				pMPG2->tsec=sec;
				pMPG2->tminute=minute;
				pMPG2->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_Sequence1();

		pMPG2->cur_position=0l;
		pMPG2->M=M;
		pMPG2->N=N;
		pMPG2->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;
		}
		if(frame_rate==0)
			frame_rate=25;
		MaxFrame=bit_rate/(frame_rate*8);  //估计帧大小
		FileSize=_filelengthi64(ld->Infile); //得到文件长度
		if(OK_ID)
		initscale();                       //初始化缩放
	}
	else
	{
		SEQEND=false; 
	    base.lpData=lpBuf;
		base.size=80000;
		base.length=0;
	

		
       
		//记录M,N  
		Initialize_Buffer(); 

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

		SEQEND=false;
		Initialize_Sequence1();

		pMPG2->cur_position=0l;
	

		
		//确定缩放比例系数
		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;
		}
		if(OK_ID)
		initscale();    
	}
}

HANDLE okMPG2BeginDecode(LPSTR infile)
{
   HANDLE hMPG2;
   environment_data *pMPG2;
		
   hMPG2=GlobalAlloc(GHND,sizeof(environment_data));

   if(!hMPG2)
	 return NULL;

//	 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));
   memset(pMPG2->ld,0,sizeof(layer_data));

   ld=&base;
   memset(ld,0,sizeof(layer_data));

//	::MessageBox(NULL,infile,"okMPG2BeginDecode",MB_OK); 

   if(infile)
   {
//	   ::MessageBox(NULL,infile,"okMPG2BeginDecode",MB_OK); 
	   pMPG2->mode=0;
	   int temp=open(infile,O_RDONLY|O_BINARY);
	   pMPG2->ld->Infile=temp;
	   if(temp==-1)
	   {
		   return NULL;
	   }
	   pMPG2->ld->mode=0;
	   pMPG2->frameno=1;
   }
   else
   {
//	   ::MessageBox(NULL,"pMPG2->mode=1","okMPG2BeginDecode",MB_OK); 
	   pMPG2->mode=1;
	   pMPG2->ld->mode=1;
	   pMPG2->frameno=1;

   }
   init_dither_tab();
   Initialize_Decoder();

   GlobalUnlock(hMPG2);
   return hMPG2;
}
typedef struct     //数据头结构
{
   // 公用部分
  long headsize;          //数据头大小
  long totalframe;        //总帧数 (out)
  long horizontal_size;  //宽度,缺省768 (in,out)
  long vertical_size;     //高度,缺省576 (in,out)
  double frame_rate;       //帧速率,缺省25.0      (in,out)
 //用于MJPG的参数
  long quality;          /*jpeg质量因子,缺省75,(in) 若大于此值会增加编码时间,
						  在某些情况下无法达到实时采集*/
  long color;
 

  //用于MPEG4编码器,建议以下采用缺省值
  double bit_rate;       // 位速率,缺省值4000000(in)。码位率过低降低图像质量。

  long Encode_Mode;      /*编码模式 ,缺省值0(in),范围(0-1)整数。=0表示双通道;
                          =1表示固定码率,固定码率值为bit_rate*/

  long Interval;         /*关键帧间隔,缺省值100(in),范围(1--300)整数.
                           此值过高会降低反向播放的速度。过低会降低压缩比。*/

  long BNum;             /*B帧模式,缺省值0(in),范围(0-2)整数. =0时可以保证实时采集;
                          =1是与divx5.0兼容,=2可以大大提高压缩比,
                           但是会增加编码时间,在某些情况下无法达到实时采集。*/

  long Q;                /*mpeg4质量因子,缺省值0(in). 范围(0---6)之间整数,
                          值越高图像质量越好,但会增加编码时间,无法进行实时采集。*/
  long reserved1;        //保留
  long reserved2;        //保留
  long reserved3;        //保留
  long reserved4;        //保留

}video_param;
BOOL okMPG2GetHeader(HANDLE hMPG2, LPBYTE lpData,LPARAM head1)
{
	long total;
	char temp[16];

//	::MessageBox(NULL,NULL,"okMPG2GetHeader",MB_OK);

	video_param *head;
	head=(video_param*)head1;
    if(!head || !hMPG2)
		return false;
	total=head->totalframe;
	environment_data *pMPG2;
//	memset(head,1,sizeof(video_param));
	pMPG2=(environment_data *)GlobalLock(hMPG2);
	if(!pMPG2)
	{
//		::MessageBox(NULL,"pMPG2=NULL","okMPG2GetHeader",MB_OK);
		return false;
	}
 	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;

	if(check_stream(pMPG2,lpData)==0)
		return FALSE;
	GetParam(pMPG2,lpData);
	if(pMPG2->mode==0)
    {
		GetTotalFrame(hMPG2,&total);
	    char str[100];
		sprintf( str, "total=%d,SEQEND=%d", total,SEQEND);
//	    ::MessageBox(NULL,str,"okMPG2GetHeader",MB_OK);
	}

	if(frame_rate==0)
		frame_rate=25;
	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;
		if(!pMPG2->backward_reference_frame[cc])
			pMPG2->backward_reference_frame[cc] = (unsigned char *)malloc(size);
		if(!pMPG2->forward_reference_frame[cc])
			pMPG2->forward_reference_frame[cc] = (unsigned char *)malloc(size);
		if(!pMPG2->auxframe[cc])
			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 true;
	   
}

void  okMPG2EndDecode(HANDLE hMPG2)
{
    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(); 
	
//	::MessageBox(NULL,NULL,"okMPG2EndDecode",MB_OK);
	Deinitialize_Sequence();
	
	if(pMPG2->mode==0)
	{
	    char str[100];
		sprintf( str, "Infile=%d", pMPG2->ld->Infile,SEQEND);
		lseek(pMPG2->ld->Infile, 0l, 0);
//		::MessageBox(NULL,str,"okMPG2EndDecode",MB_OK);
		_close(pMPG2->ld->Infile);
	}
   //free(pMPG2->ld);
    GlobalFree(pMPG2->ld);
    GlobalUnlock(hMPG2);
    GlobalFree(hMPG2);
 
}

long  okMPG2ReadFrame(HANDLE hMPG2,LPBYTE lpBuf, long lParam, LPBYTE dst,long stride)
{

	//分配存储空间
	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 interval;            //文件位置跨度
	_int64 filecur;             //粗略文件位置
	BOOL BACK;                  //文件位置后向查找标记
	BOOL FirstI;                //图像组位置标记

	long frameno;
	long framenum=1;
	long Mode=2;
	long TotalFrame;
	long remain=0;
	long tlframe=0;

	long b,e;

//	::MessageBox(NULL,NULL,"okMPG2ReadFrame",MB_OK);

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

	
    //初始化
	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();

	}
	//开始解码

	SEQEND=false;          //文件末尾标记
	while(1)
	{
		if(!Headers() && SEQEND)
		{
			 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(picture_coding_type==I_TYPE)
	   {
		   //寻找图像组首位置
		   FirstI=true;
		   lframe=0;   //组内序号归零
	   }
	   else
	   {
		   //若不是图像组首且为非连续解码,则继续寻找。
		   if((frameno<2 && !FirstI) || SKIP )
		   {	
		      FirstI=TRUE;   //组内序号加1
			  continue;
		   }
	   }

	   if(SEQEND)
	   {	
		   ::MessageBox(NULL,NULL,"SEQEND",MB_OK);
            memset(Framedst1,0,Coded_Picture_Height*Coded_Picture_Width*3);
		    SaveFrame(Framedst1,dst,Mode,&offset,stride); 
		    break;
	   }
	
		 

       //跳跃解码	
	   if(SKIP)
	   {
		   if(FirstI)
		   {
			   Decode_Picture(-1, -1,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;
			

⌨️ 快捷键说明

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