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

📄 p64.c

📁 h261协议的h261编码码,lib_261.h里面提供了详细的接口和说明.
💻 C
📖 第 1 页 / 共 3 页
字号:
/*************************************************************
Copyright (C) 1990, 1991, 1993 Andy C. Hung, all rights reserved.
PUBLIC DOMAIN LICENSE: Stanford University Portable Video Research
Group. If you use this software, you agree to the following: This
program package is purely experimental, and is licensed "as is".
Permission is granted to use, modify, and distribute this program
without charge for any purpose, provided this license/ disclaimer
notice appears in the copies.  No warranty or maintenance is given,
either expressed or implied.  In no event shall the author(s) be
liable to you or a third party for any special, incidental,
consequential, or other damages, arising out of the use or inability
to use the program for any purpose (or the loss of data), even if we
have been advised of such possibilities.  Any public reference or
advertisement of this source code should refer to it as the Portable
Video Research Group (PVRG) code, and not by any author(s) (or
Stanford University) name.
*************************************************************/
/*
************************************************************
p64.c

This is the file that has the "main" routine and all of the associated
high-level routines.  This has been kludged from the JPEG encoder, so
there is more extensibility than is really necessary.

************************************************************
*/

/*LABEL p64.c */

#include <stdio.h>
#include "globals.h"
#include "p64.h"
#include <string.h>
#include <stdlib.h>

/*PUBLIC*/

//int main();
int p64_main();
//extern void h261Decoder(unsigned char * _data, unsigned char * _yuv);
//extern void h261Encoder(unsigned char * _yuv, unsigned char * _data);

extern void p64EncodeSequence_en();
extern void p64EncodeFrame_en();
extern void p64EncodeGOB_en();
//extern void p64DecodeSequence();
//extern int p64DecodeGOB();
//extern void PrintImage();
//extern void PrintFrame();
extern void MakeImage_en();
extern void MakeFrame_en();
extern void MakeFstore_en();
extern void MakeStat_en();
extern void MakeRate_en();
extern void SetCCITT_en();
//extern void Help();
extern void MakeFileNames_en();
extern void VerifyFiles_en();

static void ExecuteQuantization_en();
//static void CallOracle();
static void p64EncodeMDU_en();
static void ReadCompressMDU_en();
static void WriteMDU_en();
static void DecodeSaveMDU_en();
//static int DecompressMDU();

/*PRIVATE*/

#define SwapFS_en(fs1,fs2) {FSTORE *ftemp;ftemp = fs1;fs1 = fs2;fs2 = ftemp;}

IMAGE *CImage=NULL;
FRAME *CFrame=NULL;
FSTORE *CFS=NULL;
FSTORE *OFS=NULL;
STAT *CStat=NULL;
STAT *RStat=NULL;
RATE *RCStore=NULL;

int BlockJ[] = {0,0,0,0,1,2};
int BlockV[] = {0,0,1,1,0,0};
int BlockH[] = {0,1,0,1,0,0};

char *DefaultSuffix[]={".Y",".U",".V"};

/* CCITT p*64 Marker information */

int TemporalReference=1;
int TemporalOffset=0;
int PType=0x0;
int Type2=0x0;
int MType=0x0;
int GQuant=8;
int MQuant=8;
int MVDH=0;
int MVDV=0;
int VAR=0;
int VAROR=0;
int MWOR=0;
int LastMVDV=0;
int LastMVDH=0;
int CBP=0x3f;
int ParityEnable=0;
int PSpareEnable=0;
int GSpareEnable=0;
int Parity=0;
int PSpare=0;
int GSpare=0;
int GRead=0;
int MBA=0;
int LastMBA=0;

int LastMType=0; /* Last MType */

/* System Definitions */

//int ImageType=IT_NTSC;
int ImageType=IT_QCIF;

//int ImageType=IT_QCIF;

int NumberMDU=0;
int CurrentMDU=0;
int NumberGOB=0;
int CurrentGOB=0;

int CurrentFrame=0;
int StartFrame=0;
int LastFrame=0;
int PreviousFrame=0;
int NumberFrames=0;
int TransmittedFrames=0;
int FrameRate=30;

int FrameSkip=1;

/* Stuff for RateControl */

int FileSizeBits=0;
int Rate=0;
int BufferOffset=0;  /*Number of bits assumed for initial buffer. */
int QDFact=1;
int QOffs=1;
int QUpdateFrequency=11;
int QUse=0;
int QSum=0;

/* Some internal parameters for rate control */

#define DEFAULT_QUANTIZATION 8

int InitialQuant=0;

/* DCT Coefficient Thresholds for coding blocks */

int CBPThreshold=1;  /* abs threshold before we use CBP */

/* MC Threshold for coding blocks through filter*/

#define D_FILTERTHRESHOLD 6

/* Intra forced every so many blocks */

#define SEQUENCE_INTRA_THRESHOLD 131

/* Parser stuff */

extern double Memory[];

/* Stuff for encoding (temporary integer storage) */

static int inputbuf[10][64];
static int output[64];

/* Stuff for Motion Compensation */

extern int SearchLimit;
extern int bit_set_mask[];
extern int MeX[];
extern int MeY[];
extern int MeVal[];
extern int MeOVal[];
extern int MeVAR[1024];
extern int MeVAROR[1024];
extern int MeMWOR[1024];

/* Book-keeping stuff */

int ErrorValue=0;
int Loud=MUTE;
//int Trace=NULL;
int Trace = 0;
int Verbose=0;
int ForceCIF=0; /* Forces CIF format - superset will hold any other format */

int Oracle=0;
int MQuantEnable;
int UseQuant;
int OracleGQuant,OracleMQuant;
int OracleMQuantEnable,OracleMType;

/* Statistics_en */

int NumberNZ=0;
int FirstFrameBits=0;
int NumberOvfl=0;
extern int MotionVectorBits;
extern int MacroAttributeBits;
extern int CodedBlockBits;
int YCoefBits=0;
int UCoefBits=0;
int VCoefBits=0;
extern int EOBBits;
int TotalBits,LastBits;
int MacroTypeFrequency[10];
int YTypeFrequency[10];
int UVTypeFrequency[10];

unsigned char **LastIntra;  /* Used for intra forcing (once per 132 frames) */

/* Coding control */

int QuantMType[] =    {0,1,0,1,0,0,1,0,0,1}; /* Quantization used */
int CBPMType[] =      {0,0,1,1,0,1,1,0,1,1}; /* CBP used in coding */
int IntraMType[] =    {1,1,0,0,0,0,0,0,0,0}; /* Intra coded macroblock */
int MFMType[] =       {0,0,0,0,1,1,1,1,1,1}; /* Motion forward vector used */
int FilterMType[] =   {0,0,0,0,0,0,0,1,1,1}; /* Filter flags */
int TCoeffMType[] =   {1,1,1,1,0,1,1,0,1,1}; /* Transform coeff. coded */

/* DCT Stuff */
/* Functional Declarations */

vFunc *UseDct = ChenDct_en;
vFunc *UseIDct = ChenIDct_en;

#define DefaultDct_en (*UseDct)
#define DefaultIDct_en (*UseIDct)

#define BufferContents_en() (mwtell_en() + BufferOffset -\
			  (((CurrentGOB*NumberMDU)+CurrentMDU)\
			   *Rate*FrameSkip\
			  /(NumberGOB*NumberMDU*FrameRate)))
#define BufferSize_en() (Rate/4) /*In bits */


//bengin
unsigned char	*yuv=NULL;
unsigned char	*data;
unsigned int	count=0;
////end


/*START*/
/*BFUNC

main() is the first routine called by program activation. It parses
the input command line and sets parameters accordingly.

EFUNC*/

//int p64_main(int argc,char **argv)
//{
//  BEGIN("main");//static char RoutineName[]= "main"
//  int i,p,s;
//
//  char str[]="h:\\short.p64";
//
//  MakeImage_en();   /* Initialize storage */
//  MakeFrame_en();
//  MakeFstore_en();
//  inithuff_en();    /* Put Huffman tables on */
//  initmc_en();      /* Put Motion Comp stuff on */		
//  
//  //fp=fopen("h:\\log.txt","w");
//  //if(fp==NULL) printf("Error\n");
//
//  if (argc==2)
//  {//解码
//		//beginmy
//		CImage->p64Mode |= P_DECODER;//-d
//		CImage->StreamFileName = str;//-s
//		strcpy(CFrame->ComponentFilePrefix[0],"short");
//		//ImageType = IT_QCIF;
//		//PType=0x00;
//		//endmy
//		//Help();
//		//exit(-1);
//  }
//  else if(argc == 1)
//  {//编码
//	  CurrentFrame = 0;
//	  StartFrame = CurrentFrame;
//	  LastFrame = 6;
//	  strcpy(CFrame->ComponentFilePrefix[0],"short");
//	  CImage->StreamFileName = "qjz.p64";
//	  //ImageType = IT_QCIF;
//	  //PType=0x00;
//
//  }
//  else
//  {
//	    for(s=0,p=0,i=1;i<argc;i++)
//		{
//			if (!strcmp("-NTSC",argv[i]))
//			{
//				ImageType = IT_NTSC;
//			}
//			else if (!strcmp("-CIF",argv[i]))
//			{
//				ImageType = IT_CIF;
//			}
//			else if (!strcmp("-QCIF",argv[i]))
//			{
//				ImageType = IT_QCIF;
//			}
//			else if (*(argv[i]) == '-')
//			{
//				switch(*(++argv[i]))
//				{
//				case 'a':
//					CurrentFrame = atoi(argv[++i]);
//					StartFrame=CurrentFrame;
//					break;
//				case 'b':
//					LastFrame = atoi(argv[++i]);
//					break;
//				case 'c': 
//					ForceCIF=1;
//					break; 
//				case 'd': 
//					CImage->p64Mode |= P_DECODER;
//					break; 
//				case 'f':
//					FrameRate = atoi(argv[++i]);
//					break;
//				case 'i':
//					SearchLimit = atoi(argv[++i]);
//					BoundValue(SearchLimit,1,31,"SearchLimit");
//					break;
//				case 'k':
//					FrameSkip = atoi(argv[++i]);
//					break;
//				case 'l':
//					Loud = atoi(argv[++i]);
//					break;
//				case 'o':
//					Oracle=1;
//					break;
//				case 'p':
//					ParityEnable=1;
//					break;
//				case 'q':
//					InitialQuant=atoi(argv[++i]);
//					BoundValue(InitialQuant,1,31,"InitialQuant");
//					break;
//				case 'r':
//					Rate = (atoi(argv[++i]));
//					break;
//				case 's':
//					CImage->StreamFileName = argv[++i];
//					break;
//				case 'v':
//					Verbose=1;
//					break;
//				case 'x':
//					FileSizeBits = (atoi(argv[++i]));
//					break;
//				case 'y':
//					UseDct = ReferenceDct;
//					UseIDct = ReferenceIDct;
//					break;
//				case 'z':
//					strcpy(CFrame->ComponentFileSuffix[s++],argv[++i]);
//					break;
//				default:
//					WHEREAMI();
//					printf("Illegal Option %c\n",*argv[i]);
//					exit(ERROR_BOUNDS);
//					break;
//				}
//			}
//			else
//			{
//				strcpy(CFrame->ComponentFilePrefix[p++],argv[i]);
//			}
//		}//end of for
//
//  }
//
//
//  
//
//	if (!CImage->StreamFileName)
//	{
//		if (!(CImage->StreamFileName =(char *) calloc(strlen(CFrame->ComponentFilePrefix[0])+6,	sizeof(char))))
//		{
//			WHEREAMI();
//			printf("Cannot allocate string for StreamFileName.\n");
//			exit(ERROR_MEMORY);
//		}
//		sprintf(CImage->StreamFileName,"%s.p64",CFrame->ComponentFilePrefix[0]);
//	}
//	if (Oracle)
//	{
//		initparser();
//		parser();
//	}
//	switch(ImageType)
//	{
//	case IT_NTSC:
//		PType=0x04;
//		PSpareEnable=1;
//		PSpare=0x8c;
//		break;
//	case IT_CIF:
//		PType=0x04;
//		break;
//	case IT_QCIF:
//		PType=0x00;//ImageType = IT_QCIF;
//		break;
//	default:
//		WHEREAMI();
//		printf("Image Type not supported: %d\n",ImageType);
//		break;
//	}
//	if(!(GetFlag(CImage->p64Mode,P_DECODER)))
//	{//编码
//		SetCCITT_en();
//		if (CurrentFrame>LastFrame)
//		{
//			WHEREAMI();
//			printf("Need positive number of frames.\n");
//			exit(ERROR_BOUNDS);
//		}
//		NumberFrames = LastFrame-CurrentFrame+1;
//		p64EncodeSequence_en();
//	}
//	else
//	{//解码
//		p64DecodeSequence();
//	}
//	exit(ErrorValue);
//}

/*BFUNC

ExecuteQuantization_en() is used to find the appropriate quantization for
the current sequence.  It calls the oracle if the flag is set.

EFUNC*/

static void ExecuteQuantization_en()
{
  BEGIN("ExecuteQuantization_en");
  int CurrentSize;

  CurrentSize=BufferContents_en();
  OracleGQuant = (CurrentSize/QDFact) + QOffs;
  OracleMQuant=OracleGQuant;
  if (Verbose)
    {
      printf("BufferContents_en: %d  New Q1: %d\n",
	     CurrentSize,GQuant);
    }
  //if (Oracle)  /* If oracle, then consult oracle */
  //  {
  //    CallOracle(1);
  //    OracleGQuant = (int)  Memory[L_GQUANT];
  //    OracleMQuant = (int)  Memory[L_MQUANT];
  //  }
  if (OracleGQuant<1) OracleGQuant=1;
  if (OracleGQuant>31) OracleGQuant=31;
  if (OracleMQuant<1) OracleMQuant=1;
  if (OracleMQuant>31) OracleMQuant=31;
}

/*BFUNC

CallOracle() calls the program interpreter by setting all the relevant
parameters and executing the program designated by value.

EFUNC*/

//static void CallOracle(int value)
//{
//  BEGIN("CallOracle");
//
//  Memory[L_GQUANT] = (double) GQuant;
//  Memory[L_MQUANT] = (double) MQuant;
//  Memory[L_MQUANTENABLE] = (double) MQuantEnable;
//  Memory[L_MTYPE] = (double) MType; /* Suggested MType */
//  Memory[L_BD] = (double) MeOVal[Bpos_en(CurrentGOB,
//				      CurrentMDU,0,0)];
//  Memory[L_DBD] = (double) MeVal[Bpos_en(CurrentGOB,
//				      CurrentMDU,0,0)];
//  Memory[L_VAROR] = (double) MeVAROR[Bpos_en(CurrentGOB,
//					  CurrentMDU,0,0)];
//  Memory[L_VAR] = (double) MeVAR[Bpos_en(CurrentGOB,
//				      CurrentMDU,0,0)];
//  Memory[L_MWOR] = (double) MeMWOR[Bpos_en(CurrentGOB,
//					CurrentMDU,0,0)];
//  Memory[L_RATE] = (double) Rate;
//  Memory[L_BUFFERSIZE] = (double) BufferSize_en();
//  Memory[L_BUFFERCONTENTS] = (double) BufferContents_en();
//  Memory[L_QDFACT] = (double) QDFact;
//  Memory[L_QOFFS] = (double) QOffs;
//  Execute(value);
//}

/*BFUNC

p64EncodeSequence_en() encodes the sequence defined by the CImage and
CFrame structures.

EFUNC*/

void p64EncodeSequence_en()
{
	BEGIN("p64EncodeSequence_en");

	MakeStat_en();
	MakeRate_en();
	MakeIob_en(READ_IOB);
	InitFS_en(CFS);
	ClearFS_en(CFS);
	InitFS_en(OFS);
	ClearFS_en(OFS);
	//swopen_en(CImage->StreamFileName);
	swopen_en(" ");
	//if (Loud > MUTE)
	//{
	//	PrintImage();
	//	PrintFrame();
	//}
	if (FileSizeBits)  /* Rate is determined by bits/second. */
		Rate=(FileSizeBits*FrameRate)/(FrameSkip*(LastFrame-CurrentFrame+1));
	if (Rate)
	{
		QDFact = (Rate/320);
		QOffs = 1;
		if (!InitialQuant)
		{
			InitialQuant = 10000000/Rate;
			if (InitialQuant>31) InitialQuant=31;
			else if (InitialQuant<1) InitialQuant=1;
			printf("Rate: %d   QDFact: %d  QOffs: %d\n",Rate,QDFact,QOffs);
			printf("Starting Quantization: %d\n",InitialQuant);
		}
	}
	if (!InitialQuant)
		InitialQuant=DEFAULT_QUANTIZATION;
	GQuant=MQuant=InitialQuant;
	BufferOffset=0;
	TotalBits=0;
	NumberOvfl=0;
	FirstFrameBits=0;
	printf("START>SEQUENCE\n");
	TransmittedFrames=0;
	while(CurrentFrame <= LastFrame)
	{
		p64EncodeFrame_en();
	}
	/*limit file growth*/
	if (CurrentFrame>LastFrame+1) 
	{
		CurrentFrame=LastFrame+1;
	}
	TemporalReference = CurrentFrame % 32;
	WritePictureHeader_en();
	swclose_en();
	/*
	SaveMem(CFS->fs[0]->mem,"XX");
	SaveMem(OFS->fs[0]->mem,"YY");
	*/
	printf("END>SEQUENCE\n");
	printf("Bits for first frame: %d   Number of buffer overflows: %d\n",FirstFrameBits,NumberOvfl);
}


/*BFUNC

p64EncodeFrame_en() encodes a single image frame.

EFUNC*/

void p64EncodeFrame_en()
{
  BEGIN("p64EncodeFrame_en");
  int x;
  
  printf("START>Frame: %d\n",CurrentFrame);
  MakeFileNames_en();
  VerifyFiles_en();
  ReadIob_en();
  InstallFS_en(0,CFS);
  if (CurrentFrame!=StartFrame)
    GlobalMC_en();
  TemporalReference = CurrentFrame % 32;
  WritePictureHeader_en();

  for(x=0;x<10;x++) /* Initialize Statistics_en */
    {
      MacroTypeFrequency[x]=0;
      YTypeFrequency[x]=0;
      UVTypeFrequency[x]=0;
    }
  MotionVectorBits=MacroAttributeBits=0;
  YCoefBits=UCoefBits=VCoefBits=EOBBits=0;
  QUse=QSum=0;
  NumberNZ=0;

  for(CurrentGOB=0;CurrentGOB<NumberGOB;CurrentMDU=0,CurrentGOB++)
    p64EncodeGOB_en();

  RCStore[CurrentFrame-StartFrame].position=TotalBits;
  RCStore[CurrentFrame-StartFrame].baseq = GQuant;
  x = mwtell_en();
  LastBits = x - TotalBits;
  TotalBits = x;
  printf("Total No of Bits: %8d  Bits for Frame: %8d\n",
	 TotalBits,LastBits);
  if (Rate)

⌨️ 快捷键说明

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