www.pudn.com > lencod.rar > image.c


/* 
*********************************************************************** 
* COPYRIGHT AND WARRANTY INFORMATION 
* 
* Copyright 2003, Advanced Audio Video Coding Standard, Part II 
* 
* DISCLAIMER OF WARRANTY 
* 
* These software programs are available to the users without any 
* license fee or royalty on an "as is" basis. The AVS disclaims 
* any and all warranties, whether express, implied, or statutory, 
* including any implied warranties of merchantability or of fitness 
* for a particular purpose. In no event shall the contributors or  
* the AVS be liable for any incidental, punitive, or consequential 
* damages of any kind whatsoever arising from the use of this program. 
* 
* This disclaimer of warranty extends to the user of this program 
* and user's customers, employees, agents, transferees, successors, 
* and assigns. 
* 
* The AVS does not represent or warrant that the program furnished 
* hereunder are free of infringement of any third-party patents. 
* Commercial implementations of AVS, including shareware, may be 
* subject to royalty fees to patent holders. Information regarding 
* the AVS patent policy is available from the AVS Web site at 
* http://www.avs.org.cn 
* 
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY. 
************************************************************************ 
*/ 
 
/* 
************************************************************************************* 
* File name:  
* Function:  
* 
************************************************************************************* 
*/ 
#include "contributors.h" 
 
#include  
#include  
#include  
#include  
#include  
#include  
#include  
 
#include "global.h" 
#include "image.h" 
#include "refbuf.h" 
#include "mbuffer.h" 
#include "header.h" 
#include "memalloc.h" 
#include "bitstream.h" 
#include "ratectl.h" 
#include "vlc.h" 
 
#define TO_SAVE 4711 
#define FROM_SAVE 4712 
#define Clip(min,max,val) (((val)<(min))?(min):(((val)>(max))?(max):(val))) 
 
static void code_a_picture(Picture *frame); 
static void ReadOneFrame (int FrameNoInFile, int HeaderSize, int xs, int ys); 
static void write_reconstructed_image(); 
static int  writeout_picture(); 
static int  writeout_slice(); 
static void find_snr(); 
static void frame_mode_buffer (int bit_frame, float snr_frame_y, float snr_frame_u, float snr_frame_v); 
static void init_frame(); 
void init_field (); 
 
void top_field(Picture *pic); 
void bot_field(Picture *pic); 
 
void combine_field(); 
int terminate_picture(); 
 
 
void put_buffer_frame(); 
void put_buffer_top(); 
void put_buffer_bot(); 
void interpolate_frame_to_fb(); 
 
static void CopyFrameToOldImgOrgVariables (); 
static void UnifiedOneForthPix (pel_t ** imgY, pel_t ** imgU, pel_t ** imgV, 
                                pel_t ** out4Y); 
static void ReportFirstframe(int tmp_time); 
static void ReportIntra(int tmp_time); 
static void ReportP(int tmp_time); 
static void ReportB(int tmp_time); 
 
static int CalculateFrameNumber();  // Calculates the next frame number 
static int FrameNumberInFile;       // The current frame number in the input file 
 
// !! weighting prediction 
// The two fuctions below can be rewritten by other algorithms 
// Determine the parameters of weighting prediction 
void estimate_weighting_factor(); 
   //cjw 20051219 weighting prediction  for field  
void estimate_weighting_factor_field(); 
 
#define  IClip( Min, Max, Val) (((Val)<(Min))? (Min):(((Val)>(Max))? (Max):(Val))) 
 
//Rate control 
int    QP; 
 
/* 
************************************************************************* 
* Function: 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
void stuffing_byte(int n) 
{ 
	int i; 
    Bitstream *currStream; 
     
	currStream = currBitStream; 
	 
	for(i=0; istreamBuffer[currStream->byte_pos++] = 0x80; 
		currStream->bits_to_go = 8; 
		currStream->byte_buf = 0; 
	} 
} 
 
/* 
************************************************************************* 
* Function: 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
static void picture_header() 
{ 
  int len=0; 
   
  Bitstream *bitstream = currBitStream; 
  img->cod_counter = 0; 
   
  if(img->type==INTRA_IMG) 
  {    
	  if((input->InterlaceCodingOption == FRAME_CODING)||(input->InterlaceCodingOption == FIELD_CODING))   //add by wuzhongmou  
	  {  
	      if(input->vec_period) //add by wuzhongmou 
		  {    
	        if(img->count%input->vec_period ==0) 
			{ 
	         len = u_v(32, "video_edit_code",0x1B7,bitstream); //add by wuzhongmou 
             img->VEC_FLAG=1; 
	         img->count_PAFF=0;    //add by wuzhongmou  
			} 
		  } 
 
		  if(input->vec_period==0) 
		  { 
			if(img->count==0) 
			{ 
			len = u_v(32, "video_edit_code",0x1B7,bitstream); //add by cjw only first 
             img->VEC_FLAG=1; 
	         img->count_PAFF=0;    //add by cjw  only first 
			} 
		  } 
	  } 
	   if((input->InterlaceCodingOption == PAFF_CODING)) 
	   {  
	      if(input->vec_period) //add by wuzhongmou 
		  {    
	        if(((img->count-1)%input->vec_period ==0)||(img->count%input->vec_period ==0)) 
			{ 
	         len = u_v(32, "video_edit_code",0x1B7,bitstream); //add by wuzhongmou 
             img->VEC_FLAG=1; 
	         img->count_PAFF=0;    //add by wuzhongmou  
			} 
		  } 
 
		  if(input->vec_period==0) 
		  { 
			if(img->count==0) 
			{ 
			len = u_v(32, "video_edit_code",0x1B7,bitstream); //add by cjw only first 
             img->VEC_FLAG=1; 
	         img->count_PAFF=0;    //add by cjw  only first 
			} 
		  } 
	   } 
 
	  len =len+IPictureHeader(img->number); 
	  if((input->InterlaceCodingOption == FRAME_CODING)||(input->InterlaceCodingOption == FIELD_CODING))   //add by wuzhongmou 
	  img->count=img->count+2;        //add by wuzhongmou 
	  if((input->InterlaceCodingOption == PAFF_CODING)) 
      img->count=img->count+1;       //add by wuzhongmou 
     
  } 
  else 
    len = len+PBPictureHeader(); 
    
  // Rate control 
  img->NumberofHeaderBits +=len; 
  if(img->BasicUnitFrame_Total_Number_MB) 
	  img->NumberofBasicUnitHeaderBits +=len; 
 
 
  // Update statistics 
  stat->bit_slice += len; 
  stat->bit_use_header[img->type] += len; 
   
  img->ptype =img->type; 
  WriteFrameFieldMBInHeader = 0; 
} 
 
/* 
************************************************************************* 
* Function:Encodes one frame 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
int encode_one_frame () 
{ 
	static int prev_frame_no = 0; // POC200301 
	static int consecutive_non_reference_pictures = 0; // POC200301 
	int    i; 
	 
	time_t ltime1; 
	time_t ltime2; 
	 
#ifdef WIN32 
	struct _timeb tstruct1; 
	struct _timeb tstruct2; 
#else 
	struct timeb tstruct1; 
	struct timeb tstruct2; 
#endif 
	 
	int tmp_time; 
	int bits_frm = 0, bits_fld = 0; 
	float dis_frm = 0, dis_frm_y = 0, dis_frm_u = 0, dis_frm_v = 0; 
	float dis_fld = 0, dis_fld_y = 0, dis_fld_u = 0, dis_fld_v = 0; 
	int framesize; 
 
	//Rate control 
	int pic_type, bits = 0;  
 
	//cjw  
	second_IField=0; 
	 
	 
#ifdef WIN32 
	_ftime (&tstruct1);           // start time ms 
#else 
	ftime (&tstruct1); 
#endif 
	time (<ime1);               // start time s 
	 
	init_frame ();           // initial frame variables 
		 
	FrameNumberInFile = CalculateFrameNumber(); 
		 
	ReadOneFrame (FrameNumberInFile, input->infile_header, img->width, img->height); 
		 
	CopyFrameToOldImgOrgVariables(); 
 
	current_slice_bytepos=0;  //qhg 20060327 for de-emulation 
	  
  img->types = img->type; 
 
  //Rate control 
  img->FieldControl=0;  
  if(input->RCEnable) 
  {  
  /*update the number of MBs in the basic unit for MB adaptive  
      f/f coding*/ 
	  img->BasicUnit=input->basicunit; 
       
    rc_init_pict(1,0,1);  
    img->qp  = updateQuantizationParameter(0);  
           
    pic_type = img->type; 
    QP =0; 
  } 
 
	 
  if (input->InterlaceCodingOption != FIELD_CODING)  // !! frame coding 
	{ 
		 
		put_buffer_frame ();     //initialize frame buffer 
 
		//frame picture 
		img->progressive_frame = 1; 
		img->picture_structure = 1; 
		 
 
		if (img->type == B_IMG) 
			Bframe_ctr++;         // Bframe_ctr only used for statistics, should go to stat-> 
		 
		singlefactor =(float) ((Bframe_ctr & 0x01) ? 2 : 0.5); 
		// !!  [1/5/2004] 
		// !!  calculate the weighting parameter 
		//cjw 20051219 
		img->LumVarFlag = 0 ;  // !! default : no weighting prediction 
		img->mb_weighting_flag = 1 ;  
		//cjw 20051219 
		if(img->type != INTRA_IMG && input->slice_weighting_flag == 1){ 
			estimate_weighting_factor(); 
		} 
		// !!  [1/5/2004] 
		code_a_picture (frame_pic); 
		 
		if (img->type!=B_IMG) 
			Update_Picture_Buffers(); 
		 
		stat->bit_ctr_emulationprevention += stat->em_prev_bits_frm; 
		 
		frame_mode_buffer (bits_frm, dis_frm_y, dis_frm_u, dis_frm_v); 
	} 
	 
	if (input->InterlaceCodingOption != FRAME_CODING)  // !! field coding 
	{ 
		int i; 
 
		//Rate control 
		int old_pic_type;              // picture type of top field used for rate control     
		int TopFieldBits; 
		 
		//Rate control 
		old_pic_type = img->type; 
		img->FieldControl=1; 
          
		if(input->InterlaceCodingOption==FIELD_CODING) 
		  img->FieldFrame = 1; 
		 
		if(input->RCEnable) 
		{ 
			img->BasicUnit=input->basicunit; 
			 
			if(input->InterlaceCodingOption==1) 
				rc_init_pict(0,1,1);  
			else 
				rc_init_pict(0,1,0); 
			 
			img->qp  = updateQuantizationParameter(1);  
		} 
 
		singlefactor = 1; 
		//non frame picture 
		img->progressive_frame = 0; 
		img->picture_structure = 0; 
		//resize picture size, reference number for field 
		img->height >>= 1; 
		img->height_cr >>= 1; 
	 
		img->nb_references = img->nb_references*2; // coded available reference number 
				 
		if (input->InterlaceCodingOption == FIELD_CODING) 
		{ 
			AllocateBitstream();   //start bit stream for field coding 
			if (img->type == B_IMG) 
				Bframe_ctr++;         // Bframe_ctr only used for statistics, should go to stat-> 
		} 
		else 
		{ 
			// save coded bitstream from frame coding 
			pic_buf = (byte *) calloc(img->width*img->height*4,1); 
			memcpy(pic_buf,currBitStream->streamBuffer,currBitStream->byte_pos); 
			framesize = currBitStream->byte_pos; 
			memset(currBitStream,0,sizeof(currBitStream)); 
			currBitStream->bits_to_go = 8; 
		} 
 
		//coded picture header 
		picture_header(); 
	    img->buf_cycle <<=1;   // restrict maximum reference numuber 
		img->old_type = img->type; 
		//initialize buffer 
		put_buffer_top(); 
 
		// !! start [12/28/2005] shenyanfei cjw 
		//cjw 20051219 
		img->LumVarFlag = 0 ;  // !! default : no weighting prediction 
		img->mb_weighting_flag = 1 ;  
		//cjw 20051219 
		if(img->type != INTRA_IMG && input->slice_weighting_flag == 1){ 
			estimate_weighting_factor_field(); 
		} 
		// !! end [12/28/2005] shenyanfei cjw 
		 
 
		init_field(); 
		top_field(top_pic); 
 
		//Rate control 
		TopFieldBits=top_pic->bits_per_picture; 
 
		if (img->type != B_IMG) 
		{ 
			Update_Picture_Buffers_top_field(); 
	    //all I- and P-frames 
			interpolate_frame_to_fb (); 
 
		} 
		else 
		{  // !! B frame shenyanfei  
			//current_field = ref_fld[4]; 
			for (i=0; iheight; i++) 
			{ 
				memcpy(imgY_com[i*2], imgY_top[i], img->width);     // top field 
			} 
			 
			for (i=0; iheight_cr; i++) 
			{ 
				memcpy(imgUV_com[0][i*2], imgUV_top[0][i], img->width_cr); 
				memcpy(imgUV_com[1][i*2], imgUV_top[1][i], img->width_cr); 
			} 
		} 
 
		if(img->type==INTRA_IMG){ 
			img->type = INTER_IMG;           // delete by jlzheng 7.21 
			img->buf_cycle /= 2;			 // cjw 20051230 I bot field reference number  
			second_IField=1; 
		} 
		 
		img->nb_references++; 
 
		//Rate control 
		if(input->RCEnable)   
			setbitscount(TopFieldBits); 
		if(input->RCEnable) 
		{ 
			rc_init_pict(0,0,0);  
			img->qp  = updateQuantizationParameter(0);  
		} 
 
		//initialize buffer 
		put_buffer_bot(); 
	 
		// !! start [12/28/2005] shenyanfei cjw 
		//cjw 20051219 
		img->LumVarFlag = 0 ;  // !! default : no weighting prediction 
		img->mb_weighting_flag = 1 ;  
		//cjw 20051219 
		if(img->type != INTRA_IMG && input->slice_weighting_flag == 1){ 
			estimate_weighting_factor_field(); 
		} 
		// !! end [12/28/2005] shenyanfei cjw 
 
		init_field(); 
		bot_field(bot_pic); 
		terminate_picture();          //delete by jlzheng  6.30 
 
		if (img->type != B_IMG)       //all I- and P-frames 
		{ 
			Update_Picture_Buffers_bot_field(); 
			interpolate_frame_to_fb (); 
		}else  // !! B frame shenyanfei  
		{ 
			for (i=0; iheight; i++) 
			{ 
				memcpy(imgY_com[i*2 + 1], imgY_bot[i], img->width); // bottom field 
			} 
			 
			for (i=0; iheight_cr; i++) 
			{ 
				memcpy(imgUV_com[0][i*2 + 1], imgUV_bot[0][i], img->width_cr); 
				memcpy(imgUV_com[1][i*2 + 1], imgUV_bot[1][i], img->width_cr); 
			} 
		} 
		 
		if(img->type!=B_IMG) 
			combine_field(); 
 
		imgY = imgY_com; 
		imgUV = imgUV_com; 
		imgY_org  = imgY_org_frm; 
		imgUV_org = imgUV_org_frm;  
 
		img->height <<= 1; 
		img->height_cr <<= 1; 
		 
		if (second_IField!=1) 
		{ 
			img->buf_cycle >>= 1; 
		} 
		 
		img->nb_references = (img->nb_references-1)/2; 
 
		if (input->InterlaceCodingOption != FIELD_CODING) 
		{ 
			find_distortion (snr, img);   // find snr from original frame picture 
			 
			bot_pic->distortion_y = snr->snr_y; 
			bot_pic->distortion_u = snr->snr_u; 
			bot_pic->distortion_v = snr->snr_v; 
		} 
		// restore reference number and image size 
	} 
 
	if(input->InterlaceCodingOption == PAFF_CODING)  // !! picture adaptive frame  field coding 
	{ 
		if (!picture_structure_decision(frame_pic,top_pic,bot_pic))		 
		{			 
			//split frame to field 
			img->height >>= 1; 
			img->height_cr >>= 1; 
			if (img->type != B_IMG) 
			{ 
				split_field_top(); 
				split_field_bot(); 
			} 
			img->height <<= 1 ; 
		  img->height_cr <<= 1; 
			 
			//restore buffer 
			img->picture_structure = 1; 
			currBitStream->byte_pos = framesize; 
			memcpy(currBitStream->streamBuffer, pic_buf,framesize); 
 
			writeout_picture (); 
			 
			imgY = imgY_frm; 
			imgUV = imgUV_frm; 
		}else 
		{//field 
			//update refernce frame buffer 
		 
			if (img->type != B_IMG) 
			{ 
				//integer pixel buffer 
				for (i=0; iheight; i++) 
				{ 
					memcpy(imgY_frm[i],imgY_com[i], img->width);     // top field 
				} 
				 
				for (i=0; iheight_cr; i++) 
				{ 
					memcpy(imgUV_frm[0][i], imgUV_com[0][i], img->width_cr); 
					memcpy(imgUV_frm[1][i], imgUV_com[1][i], img->width_cr); 
				} 
				//update 1/4 pixel reference buffer 
				imgY = imgY_frm; 
				imgUV = imgUV_frm; 
				mref[0] = mref_frm[0]; 
				interpolate_frame_to_fb(); 
			} 
 
			writeout_picture (); 
		} 
 
    //Rate control 
	 
		if(img->picture_structure==0) 
			img->FieldFrame=1; 
		/*the current choice is field coding*/ 
		else 
			img->FieldFrame=0; 
	} 
	else 
	{    
 
		writeout_picture (); 
	} 
	 
	if (input->InterlaceCodingOption != FRAME_CODING) 
	{ 
		store_field_MV (IMG_NUMBER);      // assume that img->number = frame_number 
	} 
 
	FreeBitstream();   
	find_snr (); 
	free(pic_buf); 
	 
	time (<ime2);               // end time sec 
#ifdef WIN32 
	_ftime (&tstruct2);           // end time ms 
#else 
	ftime (&tstruct2);            // end time ms 
#endif 
	 
	tmp_time = (ltime2 * 1000 + tstruct2.millitm) - (ltime1 * 1000 + tstruct1.millitm); 
	tot_time = tot_time + tmp_time; 
	 
 
 
	// Write reconstructed images 
	write_reconstructed_image (); 
	 
  	//Rate control 
	if(input->RCEnable) 
	{ 
		bits = stat->bit_ctr-stat->bit_ctr_n;//CABAC*/ 
		rc_update_pict_frame(bits); 
	} 
 
 
	if (IMG_NUMBER == 0) 
		ReportFirstframe(tmp_time); 
	else 
	{ 
    //Rate control 
		if(input->RCEnable) 
		{ 
			if(input->InterlaceCodingOption==0) 
				bits=stat->bit_ctr-stat->bit_ctr_n; 
			else 
			{ 
				bits = stat->bit_ctr -Pprev_bits; // used for rate control update */ 
				Pprev_bits = stat->bit_ctr; 
			} 
		} 
 
		switch (img->type) 
		{ 
		case INTRA_IMG: 
			stat->bit_ctr_P += stat->bit_ctr - stat->bit_ctr_n; 
			ReportIntra(tmp_time); 
			break; 
		case B_IMG: 
			stat->bit_ctr_B += stat->bit_ctr - stat->bit_ctr_n; 
			ReportB(tmp_time); 
			break; 
		default:      // P, P_MULTPRED? 
			stat->bit_ctr_P += stat->bit_ctr - stat->bit_ctr_n; 
			ReportP(tmp_time); 
		} 
	} 
	 
	stat->bit_ctr_n = stat->bit_ctr; 
		//Rate control 
	if(input->RCEnable)  
	{ 
		rc_update_pict(bits); 
		/*update the parameters of quadratic R-D model*/ 
		if((img->type==INTER_IMG)&&(input->InterlaceCodingOption==0)) 
			updateRCModel(); 
		else if((img->type==INTER_IMG)&&(input->InterlaceCodingOption!=0)\ 
			&&(img->IFLAG==0)) 
			updateRCModel(); 
	} 
	if (IMG_NUMBER == 0) 
		return 0; 
	else 
		return 1; 
} 
 
/* 
************************************************************************* 
* Function:This function write out a picture 
* Input: 
* Output: 
* Return: 0 if OK,                                                         \n 
        1 in case of error 
* Attention: 
************************************************************************* 
*/ 
 
static int writeout_picture() 
{ 
 
  assert (currBitStream->bits_to_go == 8);    //! should always be the case, the                                              //! byte alignment is done in terminate_slice 
  WriteBitstreamtoFile(); 
   
  return 0;    
} 
 
/* 
************************************************************************* 
* Function:Encodes a frame picture 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
static void code_a_picture (Picture *frame) 
{ 
  stat->em_prev_bits_frm = 0; 
  stat->em_prev_bits = &stat->em_prev_bits_frm; 
 
  AllocateBitstream(); 
 
  picture_header(); 
  picture_data(frame); 
 
  frame->bits_per_picture = 8 * (currBitStream->byte_pos);   
  if (input->InterlaceCodingOption != FRAME_CODING) 
  { 
		find_distortion (snr, img); 
		frame->distortion_y = snr->snr_y; 
		frame->distortion_u = snr->snr_u; 
		frame->distortion_v = snr->snr_v; 
  } 
} 
 
/* 
************************************************************************* 
* Function:Frame Mode Buffer 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
static void frame_mode_buffer (int bit_frame, float snr_frame_y, float snr_frame_u, float snr_frame_v) 
{    
  if (img->type != B_IMG)       //all I- and P-frames 
    interpolate_frame_to_fb (); 
} 
 
/* 
************************************************************************* 
* Function:Initializes the parameters for a new frame 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
static void init_frame () 
{ 
  int i, j, k; 
  int prevP_no, nextP_no; 
 
	img->top_bot = -1;    //Yulj 2004.07.20 
  img->current_mb_nr = 0; 
  img->current_slice_nr = 0; 
 
  //---Yulj 2004.07.15 
	{ 
		int widthMB, heightMB; 
		widthMB = img->width  / MB_BLOCK_SIZE; 
		heightMB = img->height / MB_BLOCK_SIZE; 
		img->mb_no_currSliceLastMB = ( input->slice_row_nr != 0 ) 
		                           ? min(input->slice_row_nr * widthMB - 1, widthMB * heightMB - 1) 
														   : widthMB * heightMB - 1 ; 
	} 
	//---end. 
 
  stat->bit_slice = 0; 
  img->coded_mb_nr = 0; 
   
  img->mb_y = img->mb_x = 0; 
  img->block_y = img->pix_y = img->pix_c_y = 0;  
  img->block_x = img->pix_x = img->block_c_x = img->pix_c_x = 0; 
 
	refFrArr    = refFrArr_frm; 
  fw_refFrArr = fw_refFrArr_frm; 
  bw_refFrArr = bw_refFrArr_frm; 
 
  if (img->type != B_IMG) 
  { 
	 
	  img->tr = IMG_NUMBER * (input->jumpd + 1); 
	  img->imgtr_last_prev_P_frm = img->imgtr_last_P_frm;//Lou 1016 
     
    img->imgtr_last_P_frm = img->imgtr_next_P_frm; 
    img->imgtr_next_P_frm = img->tr; 
     
    if (IMG_NUMBER != 0 && input->successive_Bframe != 0)     // B pictures to encode 
      nextP_tr_frm = img->tr; 
     
    //Rate control 
    if(!input->RCEnable) 
    { 
      if (img->type == INTRA_IMG) 
        img->qp = input->qp0;   // set quant. parameter for I-frame 
      else 
      { 
        img->qp = input->qpN; 
      } 
    } 
  } 
  else 
  { 
    img->p_interval = input->jumpd + 1; 
    prevP_no = (IMG_NUMBER - 1) * img->p_interval; 
    nextP_no = (IMG_NUMBER) * img->p_interval; 
     
    img->b_interval = 
      (int) ((float) (input->jumpd + 1) / (input->successive_Bframe + 1.0) + 
      0.49999); 
     
    img->tr = prevP_no + img->b_interval * img->b_frame_to_code;      // from prev_P 
     
    if (img->tr >= nextP_no) 
      img->tr = nextP_no - 1; 
     
    //Rate control 
    if(!input->RCEnable) 
      img->qp = input->qpB; 
     
    // initialize arrays 
 
		if(!img->picture_structure) //field coding 
		{ 
				for (k = 0; k < 2; k++) 
					for (i = 0; i < img->height / BLOCK_SIZE; i++) 
						for (j = 0; j < img->width / BLOCK_SIZE + 4; j++) 
						{ 
							tmp_fwMV[k][i][j] = 0; 
							tmp_bwMV[k][i][j] = 0; 
							dfMV[k][i][j] = 0; 
							dbMV[k][i][j] = 0; 
						} 
						 
						for (i = 0; i < img->height / B8_SIZE; i++) 
							for (j = 0; j < img->width / BLOCK_SIZE; j++) 
							{ 
								fw_refFrArr[i][j] = bw_refFrArr[i][j] = -1; 
							} 
		}else 
    { 
			for (k = 0; k < 2; k++) 
      for (i = 0; i < img->height / BLOCK_SIZE; i++) 
        for (j = 0; j < img->width / BLOCK_SIZE + 4; j++) 
        { 
          tmp_fwMV[k][i][j] = 0; 
          tmp_bwMV[k][i][j] = 0; 
          dfMV[k][i][j] = 0; 
          dbMV[k][i][j] = 0; 
        } 
 
    for (i = 0; i < img->height / BLOCK_SIZE; i++) 
      for (j = 0; j < img->width / BLOCK_SIZE; j++) 
      { 
        fw_refFrArr[i][j] = bw_refFrArr[i][j] = -1; 
      } 
		}     
  } 
   
  img->total_number_mb = (img->width * img->height) / (MB_BLOCK_SIZE * MB_BLOCK_SIZE);  
} 
 
 
void init_field () 
{ 
 
  img->current_mb_nr = 0; 
  img->current_slice_nr = 0; 
  stat->bit_slice = 0; 
  img->coded_mb_nr = 0; 
   
  img->mb_y = img->mb_x = 0; 
  img->block_y = img->pix_y = img->pix_c_y = 0;  
  img->block_x = img->pix_x = img->block_c_x = img->pix_c_x = 0; 
 
  //---Yulj 2004.07.15 
		{ 
		int widthMB, heightMB; 
		widthMB = img->width  / MB_BLOCK_SIZE; 
		heightMB = img->height / MB_BLOCK_SIZE; 
		img->mb_no_currSliceLastMB = ( input->slice_row_nr != 0 ) 
		                           ? min(input->slice_row_nr * widthMB - 1, widthMB * heightMB - 1) 
														   : widthMB * heightMB - 1 ; 
		} 
	//---end. 
	 
  img->total_number_mb = (img->width * img->height) / (MB_BLOCK_SIZE * MB_BLOCK_SIZE);   
} 
 
/* 
************************************************************************* 
* Function:Writes reconstructed image(s) to file 
           This can be done more elegant! 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
static void write_reconstructed_image () 
{ 
  int i, j, k; 
  int start = 0, inc = 1; 
   
  if (p_dec != NULL) 
  { 
    if (img->type != B_IMG) 
    { 
      // write reconstructed image (IPPP) 
      if (input->successive_Bframe == 0) 
      { 
        for (i = start; i < img->height; i += inc) 
          for (j = 0; j < img->width; j++) 
            fputc (imgY[i][j], p_dec); 
           
        for (k = 0; k < 2; ++k) 
          for (i = start; i < img->height / 2; i += inc) 
            for (j = 0; j < img->width / 2; j++) 
              fputc (imgUV[k][i][j], p_dec); 
      } 
      // write reconstructed image (IBPBP) : only intra written 
      else if (IMG_NUMBER == 0 && input->successive_Bframe != 0) 
      { 
        for (i = start; i < img->height; i += inc) 
          for (j = 0; j < img->width; j++) 
            fputc (imgY[i][j], p_dec); 
           
					 
        for (k = 0; k < 2; ++k) 
          for (i = start; i < img->height / 2; i += inc) 
            for (j = 0; j < img->width / 2; j++) 
            { 
							//imgUV[1][i][j]=0; 
						  fputc (imgUV[k][i][j], p_dec); 
						} 
      } 
       
      // next P picture. This is saved with recon B picture after B picture coding 
      if (IMG_NUMBER != 0 && input->successive_Bframe != 0) 
      { 
        for (i = start; i < img->height; i += inc) 
          for (j = 0; j < img->width; j++) 
            nextP_imgY[i][j] = imgY[i][j]; 
 
        for (k = 0; k < 2; ++k) 
          for (i = start; i < img->height / 2; i += inc) 
            for (j = 0; j < img->width / 2; j++) 
              nextP_imgUV[k][i][j] = imgUV[k][i][j]; 
      } 
    } 
    else 
    { 
      for (i = start; i < img->height; i += inc) 
        for (j = 0; j < img->width; j++) 
          fputc (imgY[i][j], p_dec); 
 
      for (k = 0; k < 2; ++k) 
        for (i = start; i < img->height / 2; i += inc) 
          for (j = 0; j < img->width / 2; j++) 
            fputc (imgUV[k][i][j], p_dec); 
             
      // If this is last B frame also store P frame 
      if (img->b_frame_to_code == input->successive_Bframe) 
      { 
        // save P picture 
        for (i = start; i < img->height; i += inc) 
          for (j = 0; j < img->width; j++) 
            fputc (nextP_imgY[i][j], p_dec); 
 
        for (k = 0; k < 2; ++k) 
          for (i = start; i < img->height / 2; i += inc) 
            for (j = 0; j < img->width / 2; j++) 
              fputc (nextP_imgUV[k][i][j], p_dec); 
      } 
    } 
  } 
} 
 
/* 
************************************************************************* 
* Function:Choose interpolation method depending on MV-resolution 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
void interpolate_frame_to_fb () 
{                             // write to mref[] 
  UnifiedOneForthPix (imgY, imgUV[0], imgUV[1], mref[0]); 
} 
 
/* 
************************************************************************* 
* Function:Upsample 4 times, store them in out4x.  Color is simply copied 
* Input:srcy, srcu, srcv, out4y, out4u, out4v 
* Output: 
* Return:  
* Attention:Side Effects_ 
     Uses (writes) img4Y_tmp.  This should be moved to a static variable 
     in this module 
************************************************************************* 
*/ 
#define  IClip( Min, Max, Val) (((Val)<(Min))? (Min):(((Val)>(Max))? (Max):(Val))) 
 
static void UnifiedOneForthPix (pel_t ** imgY, pel_t ** imgU, pel_t ** imgV, 
                                pel_t ** out4Y) 
{ 
    int is; 
    int i, j;// j4; 
    int ie2, je2, jj, maxy; 
 
    //horizonal 1/2 interpolation 
    for (j = -IMG_PAD_SIZE; j < img->height + IMG_PAD_SIZE; j++) 
        for (i = -IMG_PAD_SIZE; i < img->width + IMG_PAD_SIZE; i++) 
        { 
            jj = IClip (0, img->height - 1, j); 
            is = 5 * (imgY[jj][IClip (0, img->width - 1, i)] + imgY[jj][IClip (0, img->width - 1, i + 1)]) + 
                   - (imgY[jj][IClip (0, img->width - 1, i - 1)] + imgY[jj][IClip (0, img->width - 1, i + 2)]); 
            //store horizonal 1/2 pixel value 
            img4Y_tmp[(j + IMG_PAD_SIZE)*4][(i + IMG_PAD_SIZE) * 4 + 2] = is; 
            //store 1/1 pixel vaule 
            img4Y_tmp[(j + IMG_PAD_SIZE)*4][(i + IMG_PAD_SIZE) * 4] = imgY[IClip (0, img->height - 1, j)][IClip (0, img->width - 1, i)]*8; 
        } 
 
    //vertical 1/2 interpolation 
    for (i = 0; i < (img->width + 2 * IMG_PAD_SIZE) * 4; i+=2) 
    { 
        for (j = 0; j < (img->height + 2 * IMG_PAD_SIZE) * 4; j+=4) 
        { 
            maxy = (img->height + 2 * IMG_PAD_SIZE) * 4 - 4; 
            is = 5 * (img4Y_tmp[j][i] + img4Y_tmp[min (maxy, j + 4)][i]) 
                   - (img4Y_tmp[max (0, j - 4)][i] + img4Y_tmp[min (maxy, j + 8)][i]); 
            img4Y_tmp[j + 2][i] =is; 
        } 
        for (j = 0; j < (img->height + 2 * IMG_PAD_SIZE) * 4; j+=4) 
        { 
            img4Y_tmp[j][i] =img4Y_tmp[j][i]*8; 
        } 
    } 
        // 1/4 pix 
    ie2 = (img->width  + 2 * IMG_PAD_SIZE - 1) * 4; 
    je2 = (img->height + 2 * IMG_PAD_SIZE - 1) * 4; 
 
    //horizonal 1/4 interpolation 
    for (j = 0; j < (img->height  + 2 * IMG_PAD_SIZE)*4; j += 2) 
        for (i = 0; i < (img->width  + 2 * IMG_PAD_SIZE)*4; i += 2) 
        { 
            //  '-' 
            img4Y_tmp[j][i+1]=IClip (0,255, 
                                       (int) ((1* img4Y_tmp[j][IClip (0, (img->width + 2 * IMG_PAD_SIZE) * 4 - 2, i-2)] + 
                                               7* img4Y_tmp[j][IClip (0, (img->width + 2 * IMG_PAD_SIZE) * 4 - 2, i  )] + 
                                               7* img4Y_tmp[j][IClip (0, (img->width + 2 * IMG_PAD_SIZE) * 4 - 2, i+2)] + 
                                               1* img4Y_tmp[j][IClip (0, (img->width + 2 * IMG_PAD_SIZE) * 4 - 2, i+4)] + 512)/ 1024) 
                                    ); 
        } 
 
     //vertical 1/4 interpolation 
     for (i = 0; i < (img->width  + 2 * IMG_PAD_SIZE)*4; i++) 
     { 
            for (j = 0; j < (img->height  + 2 * IMG_PAD_SIZE)*4; j += 2) 
            { 
                // '|' 
                if (i % 2 == 0) 
                { 
                    img4Y_tmp[j+1][i]=IClip(0,255, 
                                            (int) ((1* img4Y_tmp[IClip (0, (img->height + 2 * IMG_PAD_SIZE) * 4 - 2, j-2)][i] + 
                                                    7* img4Y_tmp[IClip (0, (img->height + 2 * IMG_PAD_SIZE) * 4 - 2, j  )][i] + 
                                                    7* img4Y_tmp[IClip (0, (img->height + 2 * IMG_PAD_SIZE) * 4 - 2, j+2)][i] + 
                                                    1* img4Y_tmp[IClip (0, (img->height + 2 * IMG_PAD_SIZE) * 4 - 2, j+4)][i] + 512) / 1024) 
                                            ); 
                } 
 
                else if (j % 4 == 0 && i % 4 == 1) 
                { 
                    // '\' 
                    img4Y_tmp[j+1][i]=IClip(0, 255, 
                                            (int) ((img4Y_tmp[j+2][i+1] + img4Y_tmp[j][i-1] + 64) / 128) 
                                            ); 
                } 
                else if(j % 4 == 2 && i % 4 == 3){ 
                   img4Y_tmp[j+1][i]=IClip(0, 255, 
                                            (int) ((img4Y_tmp[j][i-1] 
                                                    + img4Y_tmp[min((img->height + 2 * IMG_PAD_SIZE - 1) * 4, j+2)][min((img->width + 2 * IMG_PAD_SIZE - 1) * 4, i+1)] + 64 )/ 128) 
                                                    ); 
 
                } 
                else if(j % 4 == 0 && i % 4 == 3) 
                { 
                    //  '/' 
                    img4Y_tmp[j+1][i]=IClip(0, 255, 
                                            (int) ((img4Y_tmp[j+2][i-1] 
                                            + img4Y_tmp[j][min((img->width + 2 * IMG_PAD_SIZE - 1) * 4, i+1)] + 64) / 128) 
                                            ); 
                } 
                else if(j % 4 == 2 && i % 4 == 1){ 
                    //  '/' 
                   img4Y_tmp[j+1][i]=IClip(0, 255, 
                                            (int) ((img4Y_tmp[j][i+1] 
                                            + img4Y_tmp[min((img->height + 2 * IMG_PAD_SIZE - 1) * 4, j+2)][i-1] + 64) / 128) 
                                            ); 
                } 
 
            } 
        } 
 
 
    for (j = 0; j < (img->height  + 2 * IMG_PAD_SIZE)*4; j += 2) 
               for (i = 0; i < (img->width  + 2 * IMG_PAD_SIZE)*4; i += 2) 
               { 
                  img4Y_tmp[j][i]=IClip(0, 255, (int) (img4Y_tmp[j][i] + 32) / 64); 
               } 
 
 
    for (j = 0; j < (img->height  + 2 * IMG_PAD_SIZE)*4; j ++) 
        for (i = 0; i < (img->width  + 2 * IMG_PAD_SIZE)*4; i ++) 
        { 
           PutPel_14 (out4Y, j - IMG_PAD_SIZE * 4, i - IMG_PAD_SIZE * 4, (pel_t) img4Y_tmp[j][i]); 
        } 
} 
 
static void UnifiedOneForthPix_old (pel_t ** imgY, pel_t ** imgU, pel_t ** imgV, 
                                pel_t ** out4Y) 
{ 
    int is; 
    int i, j;// j4; 
    int ie2, je2, jj, maxy; 
 
    //horizonal 1/2 interpolation 
    for (j = -IMG_PAD_SIZE; j < img->height + IMG_PAD_SIZE; j++) 
        for (i = -IMG_PAD_SIZE; i < img->width + IMG_PAD_SIZE; i++) 
        { 
            jj = IClip (0, img->height - 1, j); 
            is = 5 * (imgY[jj][IClip (0, img->width - 1, i)] + imgY[jj][IClip (0, img->width - 1, i + 1)]) + 
                   - (imgY[jj][IClip (0, img->width - 1, i - 1)] + imgY[jj][IClip (0, img->width - 1, i + 2)]); 
            //store horizonal 1/2 pixel value 
            img4Y_tmp[(j + IMG_PAD_SIZE)*4][(i + IMG_PAD_SIZE) * 4 + 2] = is; 
            //store 1/1 pixel vaule 
            img4Y_tmp[(j + IMG_PAD_SIZE)*4][(i + IMG_PAD_SIZE) * 4] = imgY[IClip (0, img->height - 1, j)][IClip (0, img->width - 1, i)]*8; 
        } 
 
    //vertical 1/2 interpolation 
    for (i = 0; i < (img->width + 2 * IMG_PAD_SIZE) * 4; i+=2) 
    { 
        for (j = 0; j < (img->height + 2 * IMG_PAD_SIZE) * 4; j+=4) 
        { 
            maxy = (img->height + 2 * IMG_PAD_SIZE) * 4 - 4; 
            is = 5 * (img4Y_tmp[j][i] + img4Y_tmp[min (maxy, j + 4)][i]) 
                   - (img4Y_tmp[max (0, j - 4)][i] + img4Y_tmp[min (maxy, j + 8)][i]); 
            img4Y_tmp[j + 2][i] =is; 
        } 
        for (j = 0; j < (img->height + 2 * IMG_PAD_SIZE) * 4; j+=4) 
        { 
            img4Y_tmp[j][i] =img4Y_tmp[j][i]*8; 
        } 
    } 
        // 1/4 pix 
    ie2 = (img->width  + 2 * IMG_PAD_SIZE - 1) * 4; 
    je2 = (img->height + 2 * IMG_PAD_SIZE - 1) * 4; 
 
    //horizonal 1/4 interpolation 
    for (j = 0; j < (img->height  + 2 * IMG_PAD_SIZE)*4; j += 2) 
        for (i = 0; i < (img->width  + 2 * IMG_PAD_SIZE)*4; i += 2) 
        { 
            //  '-' 
            img4Y_tmp[j][i+1]=IClip (0,255, 
                                       (int) ((1* img4Y_tmp[j][IClip (0, (img->width + 2 * IMG_PAD_SIZE) * 4 - 2, i-2)] + 
                                               7* img4Y_tmp[j][IClip (0, (img->width + 2 * IMG_PAD_SIZE) * 4 - 2, i  )] + 
                                               7* img4Y_tmp[j][IClip (0, (img->width + 2 * IMG_PAD_SIZE) * 4 - 2, i+2)] + 
                                               1* img4Y_tmp[j][IClip (0, (img->width + 2 * IMG_PAD_SIZE) * 4 - 2, i+4)] + 512)/ 1024) 
                                    ); 
        } 
 
     //vertical 1/4 interpolation 
     for (i = 0; i < (img->width  + 2 * IMG_PAD_SIZE)*4; i++) 
     { 
            for (j = 0; j < (img->height  + 2 * IMG_PAD_SIZE)*4; j += 2) 
            { 
                // '|' 
                if (i % 2 == 0) 
                { 
                    img4Y_tmp[j+1][i]=IClip(0,255, 
                                            (int) ((1* img4Y_tmp[IClip (0, (img->height + 2 * IMG_PAD_SIZE) * 4 - 2, j-2)][i] + 
                                                    7* img4Y_tmp[IClip (0, (img->height + 2 * IMG_PAD_SIZE) * 4 - 2, j  )][i] + 
                                                    7* img4Y_tmp[IClip (0, (img->height + 2 * IMG_PAD_SIZE) * 4 - 2, j+2)][i] + 
                                                    1* img4Y_tmp[IClip (0, (img->height + 2 * IMG_PAD_SIZE) * 4 - 2, j+4)][i] + 512) / 1024) 
                                            ); 
                } 
 
                else if (j % 4 == 0 && i % 4 == 1) 
                { 
                    // '\' 
                    img4Y_tmp[j+1][i]=IClip(0, 255, 
                                            (int) ((img4Y_tmp[j+2][i+1] + img4Y_tmp[j][i-1] + 64) / 128) 
                                            ); 
                } 
                else if(j % 4 == 2 && i % 4 == 3){ 
                   img4Y_tmp[j+1][i]=IClip(0, 255, 
                                            (int) ((img4Y_tmp[j][i-1] 
                                                    + img4Y_tmp[min((img->height + 2 * IMG_PAD_SIZE - 1) * 4, j+2)][min((img->width + 2 * IMG_PAD_SIZE - 1) * 4, i+1)] + 64 )/ 128) 
                                                    ); 
 
                } 
                else if(j % 4 == 0 && i % 4 == 3) 
                { 
                    //  '/' 
                    img4Y_tmp[j+1][i]=IClip(0, 255, 
                                            (int) ((img4Y_tmp[j+2][i-1] 
                                            + img4Y_tmp[j][min((img->width + 2 * IMG_PAD_SIZE - 1) * 4, i+1)] + 64) / 128) 
                                            ); 
                } 
                else if(j % 4 == 2 && i % 4 == 1){ 
                    //  '/' 
                   img4Y_tmp[j+1][i]=IClip(0, 255, 
                                            (int) ((img4Y_tmp[j][i+1] 
                                            + img4Y_tmp[min((img->height + 2 * IMG_PAD_SIZE - 1) * 4, j+2)][i-1] + 64) / 128) 
                                            ); 
                } 
 
            } 
        } 
 
 
    for (j = 0; j < (img->height  + 2 * IMG_PAD_SIZE)*4; j += 2) 
               for (i = 0; i < (img->width  + 2 * IMG_PAD_SIZE)*4; i += 2) 
               { 
                  img4Y_tmp[j][i]=IClip(0, 255, (int) (img4Y_tmp[j][i] + 32) / 64); 
               } 
 
 
    for (j = 0; j < (img->height  + 2 * IMG_PAD_SIZE)*4; j ++) 
        for (i = 0; i < (img->width  + 2 * IMG_PAD_SIZE)*4; i ++) 
        { 
           PutPel_14 (out4Y, j - IMG_PAD_SIZE * 4, i - IMG_PAD_SIZE * 4 ,img4Y_tmp[j][i]); 
        } 
} 
 
/* 
************************************************************************* 
* Function:Find SNR for all three components 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
static void find_snr () 
{ 
  int i, j; 
  int diff_y, diff_u, diff_v; 
  int impix; 
   
  //  Calculate  PSNR for Y, U and V. 
  //     Luma. 
  impix = img->height * img->width; 
   
  diff_y = 0; 
  for (i = 0; i < img->width; ++i) 
  { 
    for (j = 0; j < img->height; ++j) 
    { 
      diff_y += img->quad[imgY_org[j][i] - imgY[j][i]]; 
    } 
  } 
   
  //     Chroma. 
  diff_u = 0; 
  diff_v = 0; 
   
  for (i = 0; i < img->width_cr; i++) 
  { 
    for (j = 0; j < img->height_cr; j++) 
    { 
      diff_u += img->quad[imgUV_org[0][j][i] - imgUV[0][j][i]]; 
      diff_v += img->quad[imgUV_org[1][j][i] - imgUV[1][j][i]]; 
    } 
  } 
   
  //  Collecting SNR statistics 
  if (diff_y != 0) 
  { 
    snr->snr_y = (float) (10 * log10 (65025 * (float) impix / (float) diff_y));         // luma snr for current frame 
    snr->snr_u = (float) (10 * log10 (65025 * (float) impix / (float) (4 * diff_u)));   // u croma snr for current frame, 1/4 of luma samples 
    snr->snr_v = (float) (10 * log10 (65025 * (float) impix / (float) (4 * diff_v)));   // v croma snr for current frame, 1/4 of luma samples 
  } 
   
  if (img->number == 0) 
  { 
    snr->snr_y1 = (float) (10 * log10 (65025 * (float) impix / (float) diff_y));        // keep luma snr for first frame 
    snr->snr_u1 = (float) (10 * log10 (65025 * (float) impix / (float) (4 * diff_u)));  // keep croma u snr for first frame 
    snr->snr_v1 = (float) (10 * log10 (65025 * (float) impix / (float) (4 * diff_v)));  // keep croma v snr for first frame 
    snr->snr_ya = snr->snr_y1; 
    snr->snr_ua = snr->snr_u1; 
    snr->snr_va = snr->snr_v1; 
  } 
  // B pictures 
  else 
  { 
    snr->snr_ya = (float) (snr->snr_ya * (img->number + Bframe_ctr) + snr->snr_y) / (img->number + Bframe_ctr + 1); // average snr lume for all frames inc. first 
    snr->snr_ua = (float) (snr->snr_ua * (img->number + Bframe_ctr) + snr->snr_u) / (img->number + Bframe_ctr + 1); // average snr u croma for all frames inc. first 
    snr->snr_va = (float) (snr->snr_va * (img->number + Bframe_ctr) + snr->snr_v) / (img->number + Bframe_ctr + 1); // average snr v croma for all frames inc. first 
  } 
   
} 
 
/* 
************************************************************************* 
* Function:Find distortion for all three components 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
void find_distortion () 
{ 
  int i, j; 
  int diff_y, diff_u, diff_v; 
  int impix; 
   
  //  Calculate  PSNR for Y, U and V. 
  //     Luma. 
  impix = img->height * img->width; 
   
  diff_y = 0; 
  for (i = 0; i < img->width; ++i) 
  { 
    for (j = 0; j < img->height; ++j) 
    { 
      diff_y += img->quad[abs (imgY_org[j][i] - imgY[j][i])]; 
    } 
  } 
   
  //     Chroma. 
  diff_u = 0; 
  diff_v = 0; 
   
  for (i = 0; i < img->width_cr; i++) 
  { 
    for (j = 0; j < img->height_cr; j++) 
    { 
      diff_u += img->quad[abs (imgUV_org[0][j][i] - imgUV[0][j][i])]; 
      diff_v += img->quad[abs (imgUV_org[1][j][i] - imgUV[1][j][i])]; 
    } 
  } 
   
  // Calculate real PSNR at find_snr_avg() 
  snr->snr_y = (float) diff_y; 
  snr->snr_u = (float) diff_u; 
  snr->snr_v = (float) diff_v; 
 
} 
 
/*! 
 ************************************************************************ 
 * \brief 
 *    RD decision of frame and field coding  
 ************************************************************************ 
 */ 
int decide_fld_frame(float snr_frame_Y, float snr_field_Y, int bit_field, int bit_frame, double lambda_picture) 
{ 
  double cost_frame, cost_field; 
 
  cost_frame = bit_frame * lambda_picture + snr_frame_Y; 
  cost_field = bit_field * lambda_picture + snr_field_Y; 
 
  if (cost_field > cost_frame) 
    return (0); 
  else 
    return (1); 
} 
 
/* 
************************************************************************* 
* Function: 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
static void ReportFirstframe(int tmp_time) 
{ 
  int bits; 
 
  FILE *file = fopen("stat.dat","at"); 
   
  fprintf(file,"\n -------------------- DEBUG_INFO_START -------------------- \n"); 
   
  fprintf (file,"%3d(I)  %8d %4d %7.4f %7.4f %7.4f  %5d          %3d      %3s\n", 
    frame_no, stat->bit_ctr - stat->bit_ctr_n, 
    img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, 
    intras, img->picture_structure ? "FLD" : "FRM"); 
   
  fclose(file); 
   
  printf ("%3d(I)  %8d %4d %7.4f %7.4f %7.4f  %5d       %s \n", 
    frame_no, stat->bit_ctr - stat->bit_ctr_n, 
    img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, img->picture_structure ? "FRM":"FLD" ); 
   
    //Rate control 
  if(input->RCEnable) 
  { 
	  if(input->InterlaceCodingOption==0) 
		  bits = stat->bit_ctr-stat->bit_ctr_n; // used for rate control update  
	  else 
	  { 
		  bits = stat->bit_ctr - Iprev_bits; // used for rate control update  
		  Iprev_bits = stat->bit_ctr; 
	  } 
  } 
 
  stat->bitr0 = stat->bitr; 
  stat->bit_ctr_0 = stat->bit_ctr; 
  stat->bit_ctr = 0; 
 
} 
 
/* 
************************************************************************* 
* Function: 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
  
static void ReportIntra(int tmp_time) 
{ 
  FILE *file = fopen("stat.dat","at"); 
  fprintf (file,"%3d(I)  %8d %4d %7.4f %7.4f %7.4f  %5d      \n", 
    frame_no, stat->bit_ctr - stat->bit_ctr_n, 
    img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time ); 
   
  fclose(file); 
   
  printf ("%3d(I)  %8d %4d %7.4f %7.4f %7.4f  %5d %3s\n", 
    frame_no, stat->bit_ctr - stat->bit_ctr_n, 
    img->qp, snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, img->picture_structure ? "FRM":"FLD"); 
 
} 
   
/* 
************************************************************************* 
* Function: 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
static void ReportB(int tmp_time) 
{ 
  FILE *file = fopen("stat.dat","at"); 
  fprintf (file,"%3d(B)  %8d %4d %7.4f %7.4f %7.4f  %5d        \n", 
    frame_no, stat->bit_ctr - stat->bit_ctr_n, img->qp, 
    snr->snr_y, snr->snr_u, snr->snr_v, tmp_time); 
   
  fclose(file); 
   
  printf ("%3d(B)  %8d %4d %7.4f %7.4f %7.4f  %5d       %3s\n", 
    frame_no, stat->bit_ctr - stat->bit_ctr_n, img->qp, 
    snr->snr_y, snr->snr_u, snr->snr_v, tmp_time, img->picture_structure ? "FRM":"FLD"); 
 
} 
   
/* 
************************************************************************* 
* Function: 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
  
static void ReportP(int tmp_time) 
{             
   
  FILE *file = fopen("stat.dat","at"); 
  fprintf (file,"%3d(P)  %8d %4d %7.4f %7.4f %7.4f  %5d        %3d\n", 
    frame_no, stat->bit_ctr - stat->bit_ctr_n, img->qp, snr->snr_y, 
    snr->snr_u, snr->snr_v, tmp_time, 
    intras); 
   
  fclose(file); 
   
  printf ("%3d(P)  %8d %4d %7.4f %7.4f %7.4f  %5d       %3s     %3d    \n", 
    frame_no, stat->bit_ctr - stat->bit_ctr_n, img->qp, snr->snr_y, 
    snr->snr_u, snr->snr_v, tmp_time, 
     img->picture_structure ? "FRM":"FLD",intras); 
   
} 
   
/* 
************************************************************************* 
* Function:Copies contents of a Sourceframe structure into the old-style 
*    variables imgY_org_frm and imgUV_org_frm.  No other side effects 
* Input:  sf the source frame the frame is to be taken from 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
static void CopyFrameToOldImgOrgVariables () 
{ 
  int x, y; 
  byte *u_buffer,*v_buffer; 
  u_buffer=imgY_org_buffer+img->width*img->height; 
  v_buffer=imgY_org_buffer+img->width*img->height*5/4; 
   
  for (y=0; yheight; y++) 
    for (x=0; xwidth; x++) 
      imgY_org_frm [y][x] = imgY_org_buffer[y*img->width+x]; 
 
  for (y=0; yheight/2; y++) 
    for (x=0; xwidth/2; x++) 
    { 
      imgUV_org_frm[0][y][x] = u_buffer[y*img->width/2+x]; 
      imgUV_org_frm[1][y][x] = v_buffer[y*img->width/2+x]; 
    } 
 
	if(input->InterlaceCodingOption != FRAME_CODING) 
	{ 
		for (y=0; yheight; y += 2) 
			for (x=0; xwidth; x++) 
			{ 
				imgY_org_top [y/2][x] = imgY_org_buffer[y*img->width    +x]; // !! Lum component for top field  
				imgY_org_bot [y/2][x] = imgY_org_buffer[(y+1)*img->width+x]; // !! Lum component for bot field 
			} 
				 
		for (y=0; yheight/2; y += 2) 
			for (x=0; xwidth/2; x++) 
			{ 
				imgUV_org_top[0][y/2][x] = u_buffer[y*img->width/2+x];    // !! Cr and Cb component for top field 
				imgUV_org_top[1][y/2][x] = v_buffer[y*img->width/2+x]; 
				imgUV_org_bot[0][y/2][x] = u_buffer[(y+1)*img->width/2+x]; // !! Cr and Cb component for bot field 
				imgUV_org_bot[1][y/2][x] = v_buffer[(y+1)*img->width/2+x]; 
			} 
	} 
} 
   
/* 
************************************************************************* 
* Function: Calculates the absolute frame number in the source file out 
        of various variables in img-> and input-> 
* Input: 
* Output: 
* Return: frame number in the file to be read 
* Attention: \side effects 
    global variable frame_no updated -- dunno, for what this one is necessary 
************************************************************************* 
*/ 
 
 
static int CalculateFrameNumber() 
{ 
  if (img->type == B_IMG) 
    frame_no = (IMG_NUMBER - 1) * (input->jumpd + 1) + img->b_interval * img->b_frame_to_code; 
  else 
  { 
    frame_no = IMG_NUMBER * (input->jumpd + 1); 
  } 
 
  return frame_no; 
} 
   
/* 
************************************************************************* 
* Function:Reads one new frame from file 
* Input: FrameNoInFile: Frame number in the source file 
    HeaderSize: Number of bytes in the source file to be skipped 
    xs: horizontal size of frame in pixels, must be divisible by 16 
    ys: vertical size of frame in pixels, must be divisible by 16 or 
        32 in case of MB-adaptive frame/field coding 
    sf: Sourceframe structure to which the frame is written 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
static void ReadOneFrame (int FrameNoInFile, int HeaderSize, int xs, int ys) 
{ 
  const unsigned int bytes_y = input->img_width *input->stuff_height; 
  const unsigned int bytes_uv = bytes_y/4; 
  const int framesize_in_bytes = bytes_y + 2*bytes_uv; 
  int i, j; 
  int stuff_height_cr = (input->img_height-input->stuff_height)/2; 
  int off_y = input->img_width*input->img_height; 
  int off_uv = off_y/4; 
   
  assert (FrameNumberInFile == FrameNoInFile); 
   
  if (fseek (p_in, framesize_in_bytes*FrameNoInFile + HeaderSize, SEEK_SET) != 0) 
    error ("ReadOneFrame: cannot fseek to (Header size) in p_in", -1); 
   
  if (fread (imgY_org_buffer, 1, bytes_y, p_in) != (unsigned )bytes_y) 
  { 
    printf ("ReadOneFrame: cannot read %d bytes from input file, unexpected EOF?, exiting", bytes_y); 
    exit (-1); 
  } 
 
  if(input->img_height != input->stuff_height) 
  { 
		for(j = input->stuff_height; j < input->img_height; j++) 
    for(i = 0; i img_width; i++) 
		{ 
			imgY_org_buffer[j*input->img_width + i] = imgY_org_buffer[input->stuff_height*input->img_width - input->img_width +i]; 
		} 
  } 
 
 
  if (fread (imgY_org_buffer + off_y, 1, bytes_uv, p_in) != (unsigned )bytes_uv) 
  { 
    printf ("ReadOneFrame: cannot read %d bytes from input file, unexpected EOF?, exiting", bytes_y); 
    exit (-1); 
  } 
 
  if(input->img_height != input->stuff_height) 
  { 
		for(j = 0; j < stuff_height_cr; j++) 
    for(i = 0; i img_width/2; i++) 
		{ 
			imgY_org_buffer[off_y+ bytes_uv +j*input->img_width/2 + i] = imgY_org_buffer[off_y+ bytes_uv - input->img_width/2 +i]; 
		} 
  } 
 
  if (fread (imgY_org_buffer + input->img_height*input->img_width + input->img_height*input->img_width/4, 1, bytes_uv, p_in) != (unsigned )bytes_uv) 
  { 
    printf ("ReadOneFrame: cannot read %d bytes from input file, unexpected EOF?, exiting", bytes_y); 
    exit (-1); 
  } 
 
 
  if(input->img_height != input->stuff_height) 
  { 
		for(j = 0; j < stuff_height_cr; j++) 
    for(i = 0; i img_width/2; i++) 
		{ 
			imgY_org_buffer[off_y + off_uv + bytes_uv + j*input->img_width/2 + i] = imgY_org_buffer[off_y+off_uv+bytes_uv - input->img_width/2 +i]; 
		} 
  } 
} 
   
/* 
************************************************************************* 
* Function:point to frame coding variables  
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
void put_buffer_frame() 
{ 
	int i,j; 
 
  imgY_org  = imgY_org_frm; 
  imgUV_org = imgUV_org_frm;   
  tmp_mv    = tmp_mv_frm; 
 
	//initialize ref index 1/4 pixel 
	for(i=0;i<2;i++) 
	{ 
		mref[i] = mref_frm[i]; 
	} 
		 
	//integer pixel for chroma 
	for(i=0;i<2;i++) 
	for(j=0;j<2;j++) 
	{ 
		mcef[i][j]   = ref_frm[i][j+1];   
	} 
 
	//integer pixel for luma 
  for(i=0;i<2;i++) 
  	Refbuf11[i] = &ref_frm[i][0][0][0]; 
		 
	//current reconstructed image  
	 
	imgY = imgY_frm = current_frame[0]; 
	imgUV = imgUV_frm =  ¤t_frame[1]; 
 	 
  refFrArr    = refFrArr_frm; 
  fw_refFrArr = fw_refFrArr_frm; 
  bw_refFrArr = bw_refFrArr_frm; 
} 
 
/* 
************************************************************************* 
* Function:point to top field coding variables  
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
void put_buffer_top() 
{ 
	int i,j; 
	 
  img->fld_type = 0; 
	 
	 
  imgY_org  = imgY_org_top; 
  imgUV_org = imgUV_org_top; 
	  
	//intial ref index for field coding  
  for(i=0;i<4;i++)              // 3 2 1 0 
		ref[i] = ref_fld[i];  
	 
	//initialize ref index 1/4 pixel 
	for(i=0;i<4;i++) 
	{ 
		mref[i] = mref_fld[i]; 
	} 
	 
	//integer chroma pixel for interlace  
	for (j=0;j<4;j++)//ref_index = 0 
		for (i=0;i<2;i++) 
		{ 
			mcef[j][i] = ref_fld[j][i+1]; 
		} 
		 
		//integer luma pixel for interlace 
		for(i=0;i<4;i++) 
		{ 
			Refbuf11[i] = &ref[i][0][0][0]; 
		} 
		 
		imgY  = imgY_top   = current_field[0]; 
		imgUV = imgUV_top  = ¤t_field[1]; 
		 
		tmp_mv = tmp_mv_top; 
		refFrArr = refFrArr_top; 
		fw_refFrArr = fw_refFrArr_top; 
		bw_refFrArr = bw_refFrArr_top; 
} 
   
/* 
************************************************************************* 
* Function:point to bottom field coding variables  
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
void put_buffer_bot() 
{ 
	int i,j; 
 
  img->fld_type = 1;  
   
  imgY_org = imgY_org_bot; 
  imgUV_org = imgUV_org_bot; 
   
  tmp_mv = tmp_mv_bot; 
  refFrArr = refFrArr_bot; 
  fw_refFrArr = fw_refFrArr_bot; 
  bw_refFrArr = bw_refFrArr_bot; 
   
   //intial ref index for field coding  
  for(i=0;i<4;i++) 
  	ref[i] = ref_fld[i];  
 
	//initialize ref index 1/4 pixel 
	for(i=0;i<4;i++) 
	{ 
		mref[i] = mref_fld[i]; 
	} 
 
	//integer chroma pixel for interlace  
	for (j=0;j<4;j++)//ref_index = 0 
	for (i=0;i<2;i++) 
	{ 
		mcef[j][i] = ref_fld[j][i+1]; 
	} 
	 
	//integer luma pixel for interlace 
	for(i=0;i<4;i++) 
	{ 
		Refbuf11[i] = &ref[i][0][0][0]; 
	} 
	//imgY = imgY_bot; 
    //imgUV = imgUV_bot; 
	imgY_bot = current_field[0]; 
    imgUV_bot = ¤t_field[1]; 
	imgY = imgY_bot; 
    imgUV = imgUV_bot; 
} 
   
/* 
************************************************************************* 
* Function: 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
void split_field_top() 
{ 
  int i; 
 
  imgY = imgY_top; 
	imgUV = imgUV_top; 
   
	for (i=0; iheight; i++) 
  { 
    memcpy(imgY[i], imgY_frm[i*2], img->width);  
  } 
   
  for (i=0; iheight_cr; i++) 
  { 
    memcpy(imgUV[0][i], imgUV_frm[0][i*2], img->width_cr); 
    memcpy(imgUV[1][i], imgUV_frm[1][i*2], img->width_cr); 
  } 
 
	UnifiedOneForthPix (imgY, imgUV[0], imgUV[1], 
    mref[1]); 
} 
 
   
/* 
************************************************************************* 
* Function:extract bottom field from a frame  
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
void split_field_bot() 
{ 
  int i; 
 
	imgY = imgY_bot; 
	imgUV = imgUV_bot; 
     
  for (i=0; iheight; i++) 
  { 
    memcpy(imgY[i], imgY_frm[i*2 + 1], img->width); 
  } 
   
  for (i=0; iheight_cr; i++) 
  { 
    memcpy(imgUV[0][i], imgUV_frm[0][i*2 + 1], img->width_cr); 
    memcpy(imgUV[1][i], imgUV_frm[1][i*2 + 1], img->width_cr); 
  } 
   
		UnifiedOneForthPix (imgY, imgUV[0], imgUV[1], 
    mref[0]); 
} 
 
/* 
************************************************************************* 
* Function:update the decoder picture buffer 
* Input:frame number in the bitstream and the video sequence 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
 
void Update_Picture_Buffers() 
{  
	unsigned char ***tmp; 
	unsigned char **tmp_y; 
	int i; 
		 
	//update integer pixel reference buffer 
	tmp = ref_frm[1];       //ref_frm[ref_index][yuv][height][width] ref_index = 0,1  for P frame 
  ref_frm[1] = ref_frm[0];    // ref_index = 0, backward reference for B frame; 1: forward reference for B frame 
  ref_frm[0] = current_frame; // current_frame: current image under reconstruction 
  current_frame = tmp;	 
   
  //update luma 1/4 pixel reference buffer mref[ref_index][height][width] ref_index = 0,1 for P frame 
	tmp_y = mref_frm[1];              // ref_index = 0, forward refernce for B frame ; 1: backward refernce for B frame 
	mref_frm[1] = mref_frm[0]; 
	mref_frm[0] = tmp_y; 
	 
	//initial reference index, and for coming interpolation in mref[0] 
	for(i=0;i<2;i++) 
	{ 
		mref[i] = mref_frm[i]; 
	} 
} 
 
 
 
void Update_Picture_Buffers_top_field() 
{  
	unsigned char ***tmp; 
	unsigned char **tmp_y; 
	int i,j; 
		 
 
		//update integer pixel reference frame buffer  
		tmp = ref_fld[4]; 
		for (i=4; i>0; i--) 
			ref_fld[i] = ref_fld[i-1]; 
		ref_fld[0] = current_field; 
		current_field = tmp; 
		 
		//update  
		tmp_y = mref_fld[3]; 
		for (j=3;j>0;j--)//ref_index = 0 
		{ 
			mref_fld[j] = mref_fld[j-1]; 
		} 
    mref_fld[0] = tmp_y; 
		 
		//for interpolation 
		//for(i=0;i<3;i++) 
    for(i=0;i<4;i++) 
		{ 
			mref[i] = mref_fld[i]; 
		}  
} 
 
void Update_Picture_Buffers_bot_field() 
{  
	unsigned char ***tmp; 
	unsigned char **tmp_y; 
	int i,j; 
		 
	 
		//update integer pixel reference frame buffer  
		tmp = ref_fld[4]; 
		for (i=4; i>0; i--) 
			ref_fld[i] = ref_fld[i-1]; 
		ref_fld[0] = current_field; 
		current_field = tmp; 
		 
		//update 1/4 pixel reference for interpolation 
		tmp_y = mref_fld[3]; 
		for (j=3;j>0;j--)//ref_index = 0 
		{ 
			mref_fld[j] = mref_fld[j-1]; 
		} 
    mref_fld[0] = tmp_y; 
		 
		//for interpolation 
		//for(i=0;i<3;i++) 
    for(i=0;i<4;i++) 
		{ 
			mref[i] = mref_fld[i]; 
		}  
} 
 
int DetectLumVar() 
{ 
	int i , j ; 
	int Histogtam_Cur[256] ; 
	int Histogtam_Pre[256] ; 
	int temp = 0 ; 
 
	for( i = 0 ; i < 256 ; i++){ 
		Histogtam_Cur[i] = 0 ;  
		Histogtam_Pre[i] = 0 ; 
	} 
	 
	for(j = 0 ; j < img->height ; j++){ 
		for( i = 0 ; i < img->width ; i++){ 
			Histogtam_Cur[imgY_org[j][i]] += 1 ; 
			Histogtam_Pre[Refbuf11[0][j*img->width + i]] += 1 ; 
		} 
	} 
 
	for(i = 0 ; i < 256 ; i++){ 
		temp += abs(Histogtam_Pre[i] - Histogtam_Cur[i]); 
	} 
    
	// if(temp >= ((img->height*img->width)*2)){ 
	if(temp >= ((img->height*img->width)/4)){ 
		return 1; 
	} 
	else 
	{ 
		return 0; 
	} 
} 
 
void CalculateBrightnessPar(int currentblock[16][16] , int preblock[16][16] , float *c , float *d) 
{ 
	int N = 256 ; 
	int i , j ; 
	int m1,m2,m3,m4,m5,m6; 
	 
	m1 = m2 = m3 = m4 = m5 = m6 = 0 ; 
	for(j = 0 ; j < 16 ; j++){ 
		for(i = 0 ; i < 16 ; i++){ 
			m1 += preblock[j][i]*preblock[j][i] ; 
			m2 += preblock[j][i]; 
			m3 += preblock[j][i]; 
			m4 += 1; 
			m5 += preblock[j][i]*currentblock[j][i] ; 
			m6 += currentblock[j][i];  
		} 
	} 
	*c = ((float)(m4*m5 - m2*m6)) / ((float)(m1*m4 - m2*m3)); 
	*d = ((float)(m3*m5 - m6*m1)) / ((float)(m3*m2 - m1*m4)); 
	return ; 
} 
 
void CalculatePar(int refnum) 
{ 
	int mbx , mby ; 
	int currmb[16][16] ; 
	int refmb[16][16] ; 
	float alpha ; 
	float belta ; 
	int i , j ; 
	int Alpha_His[256]; 
	int Belta_His[256]; 
	int max_num = 0 ; 
	int max_index = -1 ; 
	int belta_sum = 0 ; 
 
	for( i = 0 ; i < 256 ; i++){ 
		Alpha_His[i] = 0 ; 
		Belta_His[i] = 0 ; 
	} 
 
	for(mby = 0 ; mby < img->height/16 ; mby++){ 
		for(mbx = 0 ; mbx < img->width/16 ; mbx++){ 
			for( j = 0 ; j < 16 ; j++){ 
				for( i = 0 ; i < 16 ; i++){ 
					currmb[j][i] = imgY_org[mby*16+j][mbx*16+i]; 
					refmb [j][i] = Refbuf11[refnum][(mby*16+j)*img->width + mbx*16+i] ; 
				} 
			} 
			CalculateBrightnessPar(currmb,refmb,&alpha,&belta); 
			allalpha_lum[mby*(img->width/16)+mbx] = (int)(alpha*32); 
			allbelta_lum[mby*(img->width/16)+mbx] = (int)(belta); 
		} 
	} 
 
	for(i = 0 ; i < ((img->height/16)*(img->width/16)) ; i++) 
	{ 
		// !!  [12/28/2005] cjw  shenyanfei  
		if((0 < allalpha_lum[i]) &&( allalpha_lum[i] < 256)&&(abs(allbelta_lum[i]) < 127)) 
		{ 
			Alpha_His[abs(allalpha_lum[i])]++; 
		} 
	} 
 
	for( i = 4 ; i < 256 ; i++) // !! 4-256 shenyanfei  
	{ 
		if(Alpha_His[i] > max_num) 
		{ 
			max_num = Alpha_His[i] ; 
			max_index = i ; 
		} 
	} 
 
	for( i = 0 ; i < ((img->height/16)*(img->width/16)) ; i++){ 
		if(allalpha_lum[i] == max_index){ 
			belta_sum += allbelta_lum[i] ; 
		} 
	} 
	img->lum_scale[refnum] = max_index ; 
		 
	if (max_num == 0) { 
				max_num = max_num ; 
		} 
	 
	img->lum_shift[refnum] = belta_sum/max_num ; 
 
	//cjw 20060327 for shift range limit  7.2.4 
	img->lum_shift[refnum]= Clip3(-128,127,img->lum_shift[refnum]); 
 
	if(max_num > ((img->height/16)*(img->width/16) / 2)) 
		img->mb_weighting_flag = 0 ; //all the NoIntra mbs are WP  
	else 
		img->mb_weighting_flag = 1 ;  
 
	img->chroma_scale[refnum] = img->lum_scale[refnum] ;  // cjw default chroma value same with luma 
	img->chroma_shift[refnum] = img->lum_shift[refnum]  ; // cjw default chroma value same with luma 
 
//	img->lum_scale[refnum] = 28;	 //cjw just for debug 
//	img->lum_shift[refnum] = 0;		 //cjw just for debug 
//	img->chroma_scale[refnum] = 29 ; // cjw just for debug 
//	img->chroma_shift[refnum] = 0  ; // cjw just for debug 
	return ; 
} 
 
void estimate_weighting_factor() 
{ 
	int   bframe    = (img->type==B_IMG); 
	int   max_ref   = img->nb_references; 
	int   ref_num ; 
 
	if(max_ref > img->buf_cycle) 
		max_ref = img->buf_cycle; 
 
	// !! detection luminance variation 
	img->LumVarFlag = DetectLumVar(); 
	img->LumVarFlag = 1; //cjw 20051230 just for debug 
 
	if(img->LumVarFlag == 1){ 
		for(ref_num = 0 ; ref_num < max_ref ; ref_num++){ 
			CalculatePar(ref_num); 
		} 
	} 
	return; 
} 
 
//then for field coding the parameters are achieved from frame coding function estimate_weighting_factor() 
void estimate_weighting_factor_field() 
{ 
	int   bframe    = (img->type==B_IMG); 
	int   max_ref   = img->nb_references; 
	int   ref_num ; 
 
	if(max_ref > img->buf_cycle) 
		max_ref = img->buf_cycle; 
 
	// !! detection luminance variation 
	img->LumVarFlag = DetectLumVar();   
	img->LumVarFlag = 1; //cjw 20051230 just for debug 
 
	if (img->LumVarFlag == 1) { 
		for(ref_num = 0 ; ref_num < max_ref ; ref_num++){ 
			CalculatePar(ref_num); 
		} 
	} 
	return; 
}