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

📄 p64.c

📁 h261协议的h261编码码,lib_261.h里面提供了详细的接口和说明.
💻 C
📖 第 1 页 / 共 3 页
字号:
    {
      printf("Buffer Contents: %8d  out of: %8d\n",
	     BufferContents_en(),
	     BufferSize_en());
    }
  printf("MB Attribute Bits: %6d  MV Bits: %6d   EOB Bits: %6d\n",
	 MacroAttributeBits,MotionVectorBits,EOBBits);
  printf("Y Bits: %7d  U Bits: %7d  V Bits: %7d  Total Bits: %7d\n",
	 YCoefBits,UCoefBits,VCoefBits,(YCoefBits+UCoefBits+VCoefBits));
  printf("MV StepSize: %f  MV NumberNonZero: %f  MV NumberZero: %f\n",
	 (double) ((double) QSum)/((double)(QUse)),
	 (double) ((double) NumberNZ)/
	 ((double)(NumberGOB*NumberMDU*6)),
	 (double) ((double) (NumberGOB*NumberMDU*6*64)- NumberNZ)/
	 ((double)(NumberGOB*NumberMDU*6)));
  RCStore[CurrentFrame-StartFrame].size = LastBits;
  printf("Code MType: ");
  for(x=0;x<10;x++) printf("%5d",x);
  printf("\n");
  printf("Macro Freq: ");
  for(x=0;x<10;x++) printf("%5d",MacroTypeFrequency[x]);
  printf("\n");
  printf("Y     Freq: ");
  for(x=0;x<10;x++) printf("%5d",YTypeFrequency[x]);
  printf("\n");
  printf("UV    Freq: ");
  for(x=0;x<10;x++) printf("%5d",UVTypeFrequency[x]);
  printf("\n");

  SwapFS_en(CFS,OFS);

  Statistics_en();
  printf("END>Frame: %d\n",CurrentFrame);
  if (Rate)
    {
      if (CurrentFrame==StartFrame)
	{/* Begin Buffer at 0.5 size */
	  FirstFrameBits = TotalBits;
	  BufferOffset = (BufferSize_en()/2) - BufferContents_en();
	  printf("First Frame Reset Buffer by delta bits: %d\n",
		 BufferOffset);
	}
      /* Take off standard deduction afterwards. */
      BufferOffset -= (Rate*FrameSkip/FrameRate);
    }
  else if (CurrentFrame==StartFrame)
    FirstFrameBits = TotalBits;
  CurrentGOB=0;TransmittedFrames++;
  CurrentFrame+=FrameSkip;    /* Change GOB & Frame at same time */
}


/*BFUNC

p64EncodeGOB_en() encodes a group of blocks within a frame.

EFUNC*/

void p64EncodeGOB_en()
{
  BEGIN("p64EncodeGOB_en");
  double xValue,yValue;

  MQuantEnable=0;                         /* Disable MQuant */
  if ((Rate)&&(CurrentFrame!=StartFrame)) /* Change Quantization */
    { 
      ExecuteQuantization_en();
      GQuant=OracleGQuant;
    }
  switch (ImageType)
    {
    case IT_NTSC:
    case IT_CIF:
      GRead=CurrentGOB;
      break;
    case IT_QCIF:
      GRead=(CurrentGOB<<1);
      break;
    default:
      WHEREAMI();
      printf("Unknown Image Type: %d\n",ImageType);
      break;
    }
  WriteGOBHeader_en();
  
  LastMBA = -1; MType=0;
  for(;CurrentMDU<NumberMDU;CurrentMDU++)
    { /* MAIN LOOP */
      LastMType=MType;
      if ((Rate)&&(CurrentMDU)&&!(CurrentMDU%QUpdateFrequency)&&
	  (CurrentFrame!=StartFrame))
	{  /* Begin Buffer control */
	  ExecuteQuantization_en();
	  if (OracleMQuant!= GQuant)
	    {
	      if (MQuantEnable=OracleMQuantEnable)
		MQuant=OracleMQuant;
	    }
	  else MQuantEnable=0;
	}
      xValue = (double) MeOVal[Bpos_en(CurrentGOB,CurrentMDU,0,0)];
      yValue = (double) MeVal[Bpos_en(CurrentGOB,CurrentMDU,0,0)];
      xValue = xValue/256;
      yValue = yValue/256;
      MVDH = MeX[Bpos_en(CurrentGOB,CurrentMDU,0,0)];
      MVDV = MeY[Bpos_en(CurrentGOB,CurrentMDU,0,0)];
      VAR  = MeVAR[Bpos_en(CurrentGOB,CurrentMDU,0,0)];
      VAROR = MeVAROR[Bpos_en(CurrentGOB,CurrentMDU,0,0)];
      MWOR = MeMWOR[Bpos_en(CurrentGOB,CurrentMDU,0,0)];
      if (CurrentFrame!=StartFrame)   /* Intra vs. Inter decision */
	  {
		  if ((VAR < 64) || (VAROR > VAR))
		  {                               /* (MC+Inter)mode */
			  if ((xValue < 1.0) ||  
				  ((xValue < 3.0) && (yValue > (xValue*0.5))) || 
				  ((yValue > (xValue/1.1))))
				  MType = 2;                   /* Inter mode */
			  else if (VAR < (double) D_FILTERTHRESHOLD) /* MC mode */
				  MType = 5;                    /* No Filter MC */
			  else
				  MType = 8;                    /* Filter MC */
		  }
		  else MType = 0; /*Intramode */
		  if (MQuantEnable)
		  {
			  MType++;
		  }
		  //if (Oracle)  /* If oracle, then consult oracle */
		  //{
			 // CallOracle(0);
			 // /* Maybe also look at Q? */
			 // /* MQuant = (int)  Memory[L_MQuant]; */
			 // /* MQuantEnable = (int)  Memory[L_Q2ENABLE]; */
			 // MType = (int) Memory[L_MTYPE];             /* Oracle's Type 3 */
		  //}
	  }
	  else
		  MType = 0; /* We always start with Intramode */
	  if (LastIntra[CurrentGOB][CurrentMDU]>SEQUENCE_INTRA_THRESHOLD)
		  MType=0;  /* Code intra every 132 blocks */

      /* printf("[State %d]",MType);*/
	  if ((Rate)&&(BufferContents_en()>BufferSize_en()))
	  {
		  MVDH=MVDV=0; /* Motion vectors 0 */
		  MType=4;     /* No coefficient transmission */
		  NumberOvfl++;
		  WHEREAMI();
		  printf("Buffer Overflow!\n");
	  }
	  p64EncodeMDU_en();
	}
}

/*BFUNC

p64EncodeMDU_en(MDU,)
     ) encodes the MDU by read/compressing the MDU; encodes the MDU by read/compressing the MDU, then
writing it, then decoding it and accumulating statistics.

EFUNC*/

static void p64EncodeMDU_en()
{
  BEGIN("p64EncodeMDU_en");

  ReadCompressMDU_en();
  WriteMDU_en();
  DecodeSaveMDU_en();

  QUse++;                  /* Accumulate statistics */
  QSum+=UseQuant;
  if (MType < 10)
    MacroTypeFrequency[MType]++;
  else
    {
      WHEREAMI();
      printf("Illegal MType: %d\n",MType);
    }
}

/*BFUNC

ReadCompressMDU_en(MDU,)
     ) reads in the MDU; reads in the MDU, and attempts to compress it.
If the chosen MType is invalid, it finds the closest match.

EFUNC*/

static void ReadCompressMDU_en()
{
  BEGIN("ReadCompressMDU_en");
  int c,j,h,v,x;
  int *input;
  int total,accum,pmask;

  while(1)                        /* READ AND COMPRESS */
  {
	  if (QuantMType[MType])
	  {
		  UseQuant=MQuant;
		  GQuant=MQuant; /* Future MB Quant is now MQuant */
	  }
	  else UseQuant=GQuant;
	  for(c=0;c<6;c++)
	  {
		  input = &inputbuf[c][0];
		  j = BlockJ[c];
		  v = BlockV[c];
		  h = BlockH[c];
		  if (TCoeffMType[MType])
		  {
			  InstallIob_en(j);
			  MoveTo_en(CurrentGOB,CurrentMDU,h,v);
			  ReadBlock_en(input);
			  if (!IntraMType[MType])
			  {
				  InstallFS_en(j,CFS);
				  MoveTo_en(CurrentGOB,CurrentMDU,h,v);
				  if (FilterMType[MType])
				  {
					  if (j)
						  HalfSubFCompensate_en(input);
					  else
						  SubFCompensate_en(input);
				  }
				  else if (MFMType[MType])
				  {
					  if (j)
						  HalfSubCompensate_en(input);
					  else
						  SubCompensate_en(input);
				  }
				  else
					  SubOverlay_en(input);
			  }
			  DefaultDct_en(input,output);
			  BoundDctMatrix_en(output);
			  if (IntraMType[MType])
			  {
				  CCITTFlatQuantize_en(output,8,UseQuant);
				  FlatBoundQuantizeMatrix_en(output);
			  }
			  else
			  {
				  CCITTQuantize_en(output,UseQuant,UseQuant);
				  BoundQuantizeMatrix_en(output);
			  }
			  ZigzagMatrix_en(output,input);
		  }
		  else
			  for(x=0;x<64;x++) 
				  input[x] = 0;
	  }
	  if (!CBPMType[MType]) CBP = 0x3f;  /* VERIFY MType CBP */
	  else
	  {
		  for(pmask=0,CBP=0,total=0,c=0;c<6;c++)
		  {
			  input = &inputbuf[c][0];
			  for(accum=0,x=0;x<64;x++) 
				  accum += abs(input[x]);
			  if ((accum)&&(pmask==0)) 
				  pmask|=bit_set_mask[5-c];
			  if (accum>CBPThreshold) 
				  CBP |= bit_set_mask[5-c];
			  total+= accum;
		  }
		  if (!CBP)
		  {
			  if (pmask) 
				  CBP=pmask;
			  else 
			  {
				  if (!FilterMType[MType])
				  {
					  CBP=0;
					  MType=4;
					  continue;
				  }
				  else 
				  {
					  CBP=0;
					  MType=7;
					  continue;
				  }
			  }
		  }
	  }
	  if (IntraMType[MType])
		  LastIntra[CurrentGOB][CurrentMDU]=0;
	  else 
		  LastIntra[CurrentGOB][CurrentMDU]++;
	  return;                              /* IF HERE, THEN EXIT LOOP */
  }                                     /* GOOD ENCODING TYPE */
}

/*BFUNC

WriteMDU_en() writes out the MDU to the stream. The input buffer and
MType must already be set once this function is called.

EFUNC*/

static void WriteMDU_en()
{
  BEGIN("WriteMDU_en");
  int c,j,x;
  int *input;

  MBA = (CurrentMDU-LastMBA);     /* WRITE */
  WriteMBHeader_en();
  LastMBA = CurrentMDU;
  for(c=0;c<6;c++)
    {
      j = BlockJ[c];
      input = &inputbuf[c][0];
      if ((CBP & bit_set_mask[5-c])&&(TCoeffMType[MType]))
	{
	  if(j) {UVTypeFrequency[MType]++;}
	  else {YTypeFrequency[MType]++;}
	  CodedBlockBits=0;
	  if (CBPMType[MType])
	    {
	      CBPEncodeAC_en(0,input);
	    }
	  else
	    {
	      EncodeDC_en(*input);
	      EncodeAC_en(1,input);
	    }
	  if(!j){YCoefBits+=CodedBlockBits;}
	  else if(j==1){UCoefBits+=CodedBlockBits;}
	  else{VCoefBits+=CodedBlockBits;}
	  IZigzagMatrix_en(input,output);
	  if (IntraMType[MType])
	    ICCITTFlatQuantize_en(output,8,UseQuant);
	  else
	    ICCITTQuantize_en(output,UseQuant,UseQuant);
	  DefaultIDct_en(output,input);
	}
      else for(x=0;x<64;x++) input[x]=0;
    }
}

/*BFUNC

DecodeSaveMDU_en() does a decode on the MDU that was just encoded/decoded
and left on the inputbuf array.  The device is OFS if encoding mode is
on, else it is the Iob if decoding mode is on.

EFUNC*/

static void DecodeSaveMDU_en()
{
	BEGIN("DecodeSaveMDU_en");
	int c,j,h,v;
	int *input;
    
	for(c=0;c<6;c++)
	{
		j = BlockJ[c];
		v = BlockV[c];
		h = BlockH[c];
		input = &inputbuf[c][0];
        
		if (!IntraMType[MType])     /* DECODE */
		{
			InstallFS_en(j,CFS);
			MoveTo_en(CurrentGOB,CurrentMDU,h,v);
			if (FilterMType[MType])
			{
				if (j)
					HalfAddFCompensate_en(input);
				else
					AddFCompensate_en(input);
			}
			else if (MFMType[MType])
			{
				if (j)
					HalfAddCompensate_en(input);
				else
					AddCompensate_en(input);
			}
			else
				AddOverlay_en(input);
		}
		BoundIDctMatrix_en(input);       /* SAVE */
		if (!(GetFlag(CImage->p64Mode,P_DECODER)))
			InstallFS_en(j,OFS);
		else
			InstallIob_en(j);
		MoveTo_en(CurrentGOB,CurrentMDU,h,v);
		WriteBlock_en(input);
	}
}


/*BFUNC

p64DecodeSequence() decodes the sequence defined in the CImage and
CFrame structures.

EFUNC*/

//void p64DecodeSequence()
//{
//	BEGIN("p64DecodeSequence");
//	int SelfParity;
//	int Active;
//	int EndFrame=0;
//    
//	//sropen(CImage->StreamFileName);
//	sropen(" ");
//	if (ReadHeaderHeader()) /* nonzero on error or eof */
//	{
//		srclose();
//		exit(ErrorValue);
//	}
//	Active=0;
//	while(1)
//    {
//		if (!EndFrame)
//			ReadHeaderTrailer();
//		if ((GRead < 0)||(EndFrame))  /* End Of Frame */
//		{
//			if (!EndFrame)
//				ReadPictureHeader();
//			else
//				TemporalReference++;
//			if (Active)
//			{
//				CopyIob2FS(CFS);
//				while(((CurrentFrame+TemporalOffset)%32) !=	TemporalReference)
//				{
//					printf("END> Frame: %d\n",CurrentFrame);
//					MakeFileNames_en();
//					WriteIob();
//					CurrentFrame++;
//				}
//				/* Might still be "Filler Frame" sent at the end of file */
//				if (ParityEnable)
//				{
//					SelfParity = ParityFS(CFS);
//					if (Parity != SelfParity)
//					{
//						printf("Bad Parity: Self: %x  Sent: %x\n",SelfParity,Parity);
//					}
//				}
//			}
//			else
//			{	      /* First Frame */
//				if (ForceCIF)
//					ImageType=IT_CIF;
//				else
//				{
//					if (PType&0x04)
//					{
//						if (PSpareEnable&&PSpare==0x8c) 
//							ImageType=IT_NTSC;
//						else ImageType=IT_CIF;
//					}
//					else ImageType=IT_QCIF;
//				}
//				SetCCITT_en();
//				if (Loud > MUTE)
//				{
//					PrintImage();
//					PrintFrame();
//				}
//				MakeIob_en(WRITE_IOB);
//				InitFS_en(CFS);
//				ClearFS_en(CFS);
//				TemporalOffset=(TemporalReference-CurrentFrame)%32;
//				Active=1;
//			}
//			if ((EndFrame)||(ReadHeaderHeader())) /* nonzero on error or eof */
//				break; /* Could be end of file */
//			printf("START>Frame: %d\n",CurrentFrame); /* Frame is for real */
//			continue;
//		}
//		EndFrame = p64DecodeGOB();                     /* Else decode the GOB */
//	}
//	srclose();
//}

/*BFUNC

p64DecodeGOB() decodes the GOB block of the current frame.

EFUNC*/

//int p64DecodeGOB()
//{
//	BEGIN("p64DecodeGOB");
//    
//	ReadGOBHeader();             /* Read the group of blocks header  */
//	switch(ImageType)
//	{
//	case IT_NTSC:
//	case IT_CIF:
//		CurrentGOB = GRead;
//		break;
//	case IT_QCIF:
//		CurrentGOB = (GRead>>1);
//		break;
//	default:
//		WHEREAMI();
//		printf("Unknown Image Type: %d.\n",ImageType);
//		break;
//	}
//	if (CurrentGOB > NumberGOB)
//	{
//		WHEREAMI();
//		printf("Buffer Overflow: Current:%d  Number:%d\n",CurrentGOB, NumberGOB);
//		return 0;
//		//return;
//	}
//	LastMBA = -1;               /* Reset the MBA and the other predictors  */
//	LastMVDH = 0;
//	LastMVDV = 0;
//	
//	while(ReadMBHeader()==0)
//	{
//		if (DecompressMDU())
//			return(1);
//		DecodeSaveMDU_en();
//	}
//	return(0);
//}

/*BFUNC

DecompressMDU() decompresses the current MDU of which the header has
already been read off of the stream.  It leaves the decoded result in
the inputbuf array.  It returns a 1 if an end of file has occurred.

EFUNC*/

//static int DecompressMDU()
//{
//	BEGIN("DecompressMDU");
//	int c,j,x;
//	int *input;
//
//	LastMBA = LastMBA + MBA;
//	CurrentMDU = LastMBA;
//	if (CurrentMDU >= NumberMDU)
//	{
//		if ((CurrentGOB == NumberGOB-1)&&(seof()))
//			return(1);
//
//		WHEREAMI();
//		printf("Apparent MDU out of range: %d > %d.\n",CurrentMDU,NumberMDU);
//		printf("CurrentGOB: %d LastMBA %d, MBA: %d\n",CurrentGOB,LastMBA,MBA);
//		printf("at bit position %d in stream\n",mrtell());
//		CurrentMDU=0;
//		LastMBA=0;
//		return(0);
//	}
//	if (!CBPMType[MType]) CBP = 0x3f;
//	if (QuantMType[MType])
//	{
//		UseQuant=MQuant;
//		GQuant=MQuant;
//	}
//	else UseQuant=GQuant;
//	for(c=0;c<6;c++)
//	{
//		j=BlockJ[c];
//		input = &inputbuf[c][0];
//		if ((CBP & bit_set_mask[5-c])&&(TCoeffMType[MType]))
//		{
//			if (CBPMType[MType])
//				CBPDecodeAC(0,input);		      
//			else
//			{
//				*input = DecodeDC();
//				DecodeAC(1,input);
//			}
//			if (Loud > TALK)
//			{
//				printf("Cooked Input\n");
//				PrintMatrix(input);
//			}			
//			IZigzagMatrix_en(input,output);
//			if (IntraMType[MType])
//				ICCITTFlatQuantize_en(output,8,UseQuant);
//			else
//				ICCITTQuantize_en(output,UseQuant,UseQuant);
//			DefaultIDct_en(output,input);
//		}
//		else  
//			for(x=0;x<64;x++) 
//				input[x]=0; 
//	}
//	return(0);
//}

/*BFUNC

PrintImage() prints the image structure to stdout.

EFUNC*/

//void PrintImage()
//{
//  BEGIN("PrintImage");
//
//  printf("*** Image ID: %x ***\n",CImage);
//  if (CImage)
//    {
//      if (CImage->StreamFileName)
//	{
//	  printf("StreamFileName %s\n",CImage->StreamFileName);
//	}
//      printf("InternalMode: %d   Height: %d   Width: %d\n",
//	     CImage->p64Mode,CImage->Height,CImage->Width);
//    }
//}

/*BFUNC

⌨️ 快捷键说明

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