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

📄 mpeg2dec.cpp

📁 mpeg2编码解码源程序代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		     lseek(pDecode->infile,0l,SEEK_SET);
		Initialize_Buffer();
		
		//精确定位
        if(frameno>4*cal)
		{

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

				Ioffset=_telli64(pDecode->infile);
			
		        if(!Headers())
				{
                    lseek(pDecode->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(pDecode->infile,filecur,SEEK_SET);
		                 else
		                    lseek(pDecode->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(pDecode->infile,filecur,SEEK_SET);
		                 else
		                    lseek(pDecode->infile,0l,SEEK_SET);

					 }
					 else
					 {
						 lseek(pDecode->infile,Ioffset,SEEK_SET);
						 break;
					 }
		         

				}

			 }		
			 Initialize_Buffer();
		} 
	}

	//开始解码
	ld->Infile=pDecode->infile;

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

            if(frameno==TotalFrame)
			{
		         //存储最后一帧
//				::MessageBox(NULL,NULL,"frameno==TotalFrame",MB_OK); 
                 Output_Last_Frame_of_Sequence(CurFrame,Framedst1);
	             pDecode->infile=base.Infile;
	             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)
	   {	
//		   	::MessageBox(NULL,NULL,"CurFrame>frameno+framenum",MB_OK); 
            memset(Framedst1,0,Coded_Picture_Height*Coded_Picture_Width*3);
		    SaveFrame(Framedst1,dst,Mode,&offset,stride); 
		    break;
	   }
	
		 

       //跳跃解码	
	   if(SKIP)
	   {
		   //若当前帧号大于等于解码间隔
	      if(CurFrame>=frameno-cal&&CurFrame<=frameno+framenum)
		  { 
			  //解码
		      Decode_Picture(CurFrame, CurFrame,Framedst1);
			 
	          pDecode->infile=ld->Infile;
			   //若等于解码帧号转换并存储
	          if(CurFrame==frameno+1)
			  {
		         SaveFrame(Framedst1,dst,Mode,&offset,stride); 
			      //存储帧累加
		         decode_Framenum++;	
			  }
		  }
		   //若等于解码帧号,结束循环,并存储相关信息
	      if(CurFrame==frameno+framenum)
		  { 
			  pDecode->hour=hour;
		      pDecode->minute=minute;
		      pDecode->sec=sec;
		      pDecode->frame=frame;
		      pDecode->lframe=lframe;
		      pDecode->cur_bitno=frameno;
		      pDecode->cur_position=_telli64(pDecode->infile);
		      break;
		  }
	  }
	  else //连续解码
	  {
		  if(CurFrame<=frameno+framenum)
		  {
			  Decode_Picture(CurFrame,CurFrame,Framedst1);
	          pDecode->infile=ld->Infile;
		     
			   //转换并存储
			  if(CurFrame==frameno+1)
			  {
				  SaveFrame(Framedst1,dst,Mode,&offset,stride);
			  //存储帧累加
				  decode_Framenum++;	
			  }
			  if(CurFrame==frameno+framenum)
			  {
				  pDecode->hour=hour;
				  pDecode->minute=minute;
				  pDecode->sec=sec;
				  pDecode->frame=frame;
		          pDecode->lframe=lframe;
		          pDecode->cur_bitno=frameno;
		          pDecode->cur_position=_telli64(pDecode->infile);
		          break;
			  }
		   }
	   }
	}		
	///////////////////////////////
	//若首帧序号超过实际帧数,则存储帧数为0	
    base.Infile=pDecode->infile; 
    //释放缓存
    free(Framedst1);
    GlobalUnlock(hDecode);


  return decode_Framenum; //返回实际解码帧数

}

void ClearGlobal()
{
	
 Coded_Picture_Width=0;
 Coded_Picture_Height=0;
 Chroma_Width=0;
 Chroma_Height=0;
 
block_count=0;
 Second_Field=0;
 profile=0;
 level=0;

 horizontal_size=0;
 vertical_size=0;
 mb_width=0;
 mb_height=0;
 bit_rate=0;
 frame_rate=0; 



 aspect_ratio_information=0;
 frame_rate_code=0; 
 bit_rate_value=0; 
 vbv_buffer_size=0;
 constrained_parameters_flag=0;


 profile_and_level_indication=0;
 progressive_sequence=0;
 chroma_format=0;
 low_delay=0;
 frame_rate_extension_n=0;
 frame_rate_extension_d=0;


 video_format=0;  
 color_description=0;
 color_primaries=0;
 transfer_characteristics=0;
 matrix_coefficients=0;
 display_horizontal_size=0;
 display_vertical_size=0;


 
 temporal_reference=0;
 picture_coding_type=0;
 vbv_delay=0;
 full_pel_forward_vector=0;
 forward_f_code=0;
 full_pel_backward_vector=0;
 backward_f_code=0;



// f_code[2][2]=0;
 memset(f_code,0,4);
 intra_dc_precision=0;
 picture_structure=0;
 top_field_first=0;
 frame_pred_frame_dct=0;
 concealment_motion_vectors=0;

 intra_vlc_format=0;

 repeat_first_field=0;

 chroma_420_type=0;
 progressive_frame=0;
 composite_display_flag=0;
 v_axis=0;
 field_sequence=0;
 sub_carrier=0;
 burst_amplitude=0;
 sub_carrier_phase=0;




// frame_center_horizontal_offset[3]=0;
// frame_center_vertical_offset[3]=0;
 memset(frame_center_horizontal_offset,0,3);
 memset(frame_center_vertical_offset,0,3);
 memset(ld,0,sizeof(layer_data));




 layer_id=0;
 lower_layer_prediction_horizontal_size=0;
 lower_layer_prediction_vertical_size=0;
 horizontal_subsampling_factor_m=0;
 horizontal_subsampling_factor_n=0;
 vertical_subsampling_factor_m=0;
 vertical_subsampling_factor_n=0;



 lower_layer_temporal_reference=0;
 lower_layer_horizontal_offset=0;
 lower_layer_vertical_offset=0;
 spatial_temporal_weight_code_table_index=0;
 lower_layer_progressive_frame=0;
 lower_layer_deinterlaced_field_select=0;


 copyright_flag=0;
 copyright_identifier=0;
 original_or_copy=0;
 copyright_number_1=0;
 copyright_number_2=0;
 copyright_number_3=0;


 drop_flag=0;
 hour=0;
 minute=0;
 sec=0;
 frame=0;
 closed_gop=0;
 broken_link=0;
 tframe=0;
 tsec=0;
 tminute=0;
 thour=0;
 
		

}
void CloseMpeg2(HANDLE hDecode)
{
    environment_data *pDecode;
   	pDecode=(environment_data *)GlobalLock(hDecode);
	base.Infile=pDecode->infile;


	AUDIO=false;
	SEQEND=false;

	ClearGlobal();

	Deinitialize_Sequence();
   _close(pDecode->infile);

   if (Two_Streams)
       close(enhan.Infile);

   GlobalUnlock(hDecode);
   GlobalFree(pDecode);
 
}

BOOL check_stream(environment_data *pMPG2,LPBYTE lpBuf)
{
	long i=0;
	long code;
	char temp[16];
	char str[200];

	if(pMPG2->mode==0)
	{
		sprintf( str,"Infile=%d",ld->Infile);
//		::MessageBox(NULL,str,"check_stream",MB_OK);

		pMPG2->mode=0;
		System_Stream_Flag = 0;
		Clear_Options();
		lseek(ld->Infile, 0l, 0);

		Initialize_Buffer(); 
		if(SHOW_BITS(8)==0x47)
		{
//			::MessageBox(NULL,"非法退出1!!!","check_stream",MB_OK);
			return 0;
		}
	
		int pos_file;
		int continue_loop=1;
		_int64 FileSize=_filelengthi64(ld->Infile); //得到文件长度
		for (;;)
		{
		 /* look for next_start_code */
			next_start_code();
			code = Get_Bits32();
	
			pos_file=_tell(base.Infile);

			if(pos_file>20480 || pos_file>FileSize/2)
				break;
			switch (code)
			{
				case PACK_START_CODE:
					continue_loop=0;
					System_Stream_Flag = 1;
					break;
				case VIDEO_ELEMENTARY_STREAM:
					continue_loop=0;
					System_Stream_Flag = 1;
					break;
				default:
				break;
			}
			if(!continue_loop)
				 break;
		}

		lseek(base.Infile, 0l, 0);
		Initialize_Buffer(); 

		pMPG2->System_Stream_Flag=System_Stream_Flag;
		
		_lseek(pMPG2->ld->Infile, 0l, 0);
		Initialize_Buffer();
		
		OK_ID=true;
/*		
		memset(temp,0,16);
		_lseek(pMPG2->ld->Infile, 0l, 0);
		read(pMPG2->ld->Infile,temp,16);
		if(strcmp(temp,"00ok00ok00ok00ok")==0)
			OK_ID=true;
		else
			OK_ID=false;
*/

		_lseek(pMPG2->ld->Infile, 0l, 0);
		Initialize_Buffer();
	}
	else
	{
		SEQEND=false; 
	    base.lpData=lpBuf;
		base.size=80000;
		base.length=0;
	
		System_Stream_Flag = 0;
		Initialize_Buffer(); 
		if(SHOW_BITS(8)==0x47)
		{
//			::MessageBox(NULL,"非法退出1!!!","check_stream",MB_OK);
			return 0;
		}
		while(1)
		{
			i+=32;
			next_start_code();
			code = Get_Bits32();//Show_Bits(32);
			
			switch(code)
			{
			case SEQUENCE_HEADER_CODE:
				break;
			case PACK_START_CODE:
				System_Stream_Flag = 1;
				break;
			case VIDEO_ELEMENTARY_STREAM:
				System_Stream_Flag = 1;
				break;
			}
			if(code==SEQUENCE_HEADER_CODE||System_Stream_Flag )
				break;
			if(i>2048)
			{
//				::MessageBox(NULL,"非法退出1!!!","check_stream",MB_OK);
				return 0;
			}
		}
		//Initialize_Buffer();
	}
	return 1;	
}
void GetTotalFrame(HANDLE hMPG2,long* total)
{
//   ::MessageBox(NULL,NULL,"GetTotalFrame",MB_OK);  
   long temp=0;
   long lframe=0;
   environment_data *pMPG2;
   
   pMPG2=(environment_data *)GlobalLock(hMPG2);
   SEQEND=false;

   //计算总帧数
   //定位于文件尾后一定范围内

   _lseeki64(pMPG2->ld->Infile,-1*MaxFrame*(pMPG2->N*10),SEEK_END);
   BOOL FirstI=false;
/* 
   while(Headers())
   {
	   
	   if(picture_coding_type==I_TYPE)
	   {
		   FirstI=true;
		   lframe=0;   //组内序号归零
	   }
	   else if(picture_coding_type==P_TYPE||picture_coding_type==B_TYPE)
	   {
		   //若不是图像组首且为非连续解码,则继续寻找。
		   if(!FirstI)
			 continue;
		   lframe++;
	   }
	   if(SEQEND)
		 break;
   }
*/
   int hour_ok=hour, minute_ok=minute, sec_ok=sec;

   while(Headers())
   {
	   if(hour > hour_ok)
	   {
			hour_ok=hour;minute_ok=minute; sec_ok=sec;
	   }
	   else if(minute > minute_ok)
	   {
			minute_ok=minute; sec_ok=sec;
	   }
	   else if(sec > sec_ok)
	   {
			sec_ok=sec;
	   }

	   if(picture_coding_type==I_TYPE)
	   {
		   FirstI=true;
		   lframe=0;   //组内序号归零
	   }
	   else if(picture_coding_type==P_TYPE||picture_coding_type==B_TYPE)
	   {
		   //若不是图像组首且为非连续解码,则继续寻找。
		   if(!FirstI)
			 continue;
		   lframe++;
	   }
	   if(SEQEND)
		 break;
   }
   SEQEND=false;
 
   if(lframe>pMPG2->N)
   lframe=pMPG2->N;

    *total=((hour_ok-pMPG2->thour)*3600+(minute_ok-pMPG2->tminute)*60+(sec_ok-pMPG2->tsec))*(int)(frame_rate+0.5)+(frame-pMPG2->tframe+1+lframe);

   //若在范围内无播放时间信息,则遍历整个文件得到的总帧数
   
   if(*total<=0)
   {
	  SEQEND=false;
      lseek(pMPG2->ld->Infile, 0l, 0);
      if(pMPG2->ld->Infile!=0)
	  {
         lseek(pMPG2->ld->Infile, 0l, 0);
	  }
	  Initialize_Buffer();
      while(1)
	  {  
	     int code;
	     next_start_code();
         code = Get_Bits32();
	     pMPG2->ld->Infile=base.Infile;
	     if(code==PICTURE_START_CODE)
		 {
		    temp++;
		 }
	     if(SEQEND)
		    break;	
	  }
      *total=temp;
   }
   
  
   lseek(pMPG2->ld->Infile, 0l, 0);
   if(pMPG2->ld->Infile!=0)
   {
     lseek(pMPG2->ld->Infile, 0l, 0);
   }
   Initialize_Buffer(); 

⌨️ 快捷键说明

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