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

📄 image.c

📁 Mobile IP VCEG的信道模拟程序
💻 C
📖 第 1 页 / 共 3 页
字号:
// *************************************************************************************
// *************************************************************************************
// Image.c   Code one image/slice
//
// Main contributors (see contributors.h for copyright, address and affiliation details)
//
// Inge Lille-Lang鴜               <inge.lille-langoy@telenor.com>
// Rickard Sjoberg                 <rickard.sjoberg@era.ericsson.se>
// Jani Lainema                    <jani.lainema@nokia.com>
// Sebastian Purreiter             <sebastian.purreiter@mch.siemens.de>
// Byeong-Moon Jeon                <jeonbm@lge.com>
// Yoon-Seong Soh                  <yunsung@lge.com>
// Thomas Stockhammer              <stockhammer@ei.tum.de>
// Detlev Marpe                    <marpe@hhi.de>
// Guido Heising                   <heising@hhi.de> 
// Thomas Wedi                     <wedi@tnt.uni-hannover.de>
// *************************************************************************************
// *************************************************************************************
#include "contributors.h"

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <sys/timeb.h>
#include <string.h>
#include <memory.h>
#include <assert.h>

#include "global.h"
//#include "elements.h"
#include "image.h"
#include "refbuf.h"

#ifdef _ADAPT_LAST_GROUP_
int *last_P_no;
#endif

static void UnifiedOneForthPix (pel_t **imgY, pel_t** imgU, pel_t **imgV,
				pel_t **out4Y, pel_t **outU, pel_t **outV, pel_t *ref11);

/************************************************************************
*
*  Name :       encode_one_frame()
*
*  Description: Encodes one frame
*
************************************************************************/
int encode_one_frame()
{
	Boolean end_of_frame = FALSE;
	SyntaxElement sym;

	time_t ltime1;   // for time measurement 
	time_t ltime2;

#ifdef WIN32
	struct _timeb tstruct1;
	struct _timeb tstruct2;
#else
	//struct tm *l_time;
	//char string[20];
	struct timeb tstruct1;
	struct timeb tstruct2;
	//time_t now;
#endif

	int tmp_time;

#ifdef WIN32
	_ftime( &tstruct1 );    // start time ms 
#else 
	ftime(&tstruct1);
#endif
	time( &ltime1 );        // start time s  
  
	
	/* Initialize frame with all stat and img variables */
	img->total_number_mb = (img->width * img->height)/(MB_BLOCK_SIZE*MB_BLOCK_SIZE);
	init_frame();

	/* Initialize loopfilter */
	init_loop_filter();

// StW: The following used to set imgTypeSymbol's len and info fields to a value according
// to img->no_multpred and img->type.  Those two were set elsewhere (in lencod.c to be
// precise.
// The function was moved to header.c, function PictureHeader().
//
//	/* Select picture type: write coding to symbol */
//	select_picture_type(&imgTypeSymbol);


	/* Read one new frame */
	read_one_new_frame();

	if (img->type == B_IMG)		
		Bframe_ctr++;

	while (end_of_frame == FALSE)	/* loop over slices */
	{
		/* Encode the current slice */
		encode_one_slice(&sym);

		/* Proceed to next slice */
		img->current_slice_nr++;
		stat->bit_slice = 0;
		if (img->current_mb_nr == img->total_number_mb) /* end of frame reached? */
			end_of_frame = TRUE;
	}

 	loopfilter(img); // reconstructed imgY, imgUV -> loop-filtered imgY, imgUV

	// in future only one call of oneforthpix() for all frame tyoes will be necessary, because
	// mref buffer will be increased by one frame to store also the next P-frame. Then mref_P
	// will not be used any more
	if (img->type != B_IMG) /*all I- and P-frames*/
	{
		if (input->successive_Bframe == 0 || img->number == 0)
			interpolate_frame(); // I- and P-frames:loop-filtered imgY, imgUV -> mref[][][], mcef[][][][]
		else
			interpolate_frame_2();    // I- and P-frames prior a B-frame:loop-filtered imgY, imgUV -> mref_P[][][], mcef_P[][][][]
    	                           // I- and P-frames prior a B-frame:loop-filtered imgY, imgUV -> mref_P[][][], mcef_P[][][][]
	}
	else 
		if (img->b_frame_to_code == input->successive_Bframe) 
			copy2mref(img);		       // last successive B-frame: mref_P[][][], mcef_P[][][][] (loop-filtered imgY, imgUV)-> mref[][][], mcef[][][][]	

	find_snr(snr,img);     
    
	time(&ltime2);       // 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();
	if(img->number == 0)
	{
		printf("%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); 
		stat->bitr0=stat->bitr;           
		stat->bit_ctr_0=stat->bit_ctr;   
		stat->bit_ctr=0;                  
	}
	else
	{
		if (img->type != B_IMG)
		{
			stat->bit_ctr_P += stat->bit_ctr-stat->bit_ctr_n;  
			printf("%3d(P) %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); 
		}
		else
		{
			stat->bit_ctr_B += stat->bit_ctr-stat->bit_ctr_n;  		
			printf("%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); 	
		}
	}
	stat->bit_ctr_n=stat->bit_ctr; 	
	

	if(img->number == 0) 
		return 0; 	
	else
		return 1;
}


/************************************************************************
*
*  Name :       encode_one_slice()
*
*  Description: Encodes one slice
*
************************************************************************/
void encode_one_slice(SyntaxElement *sym)
{
	Boolean end_of_slice = FALSE;
	Boolean recode_macroblock;
	int len;

	/* Initializes the parameters of the current slice */
	init_slice();

	/* Write slice or picture header */
	len = start_slice(sym);

	/* Update statistics */
	if (img->current_mb_nr > 0)	
	{
 		img->mb_data[img->current_mb_nr].bitcounter[BITS_HEADER_MB] = len;
	}
	else															/* first slice includes picture header */
	{
		if (input->symbol_mode == UVLC)
		{
			stat->bit_ctr += len;
			stat->bit_slice += len;
		}
		stat->bit_use_head_mode[img->type] += len;
	}

	while (end_of_slice == FALSE)	/* loop over macroblocks */
	{

		/* recode_macroblock is used in slice mode two and three where */
		/* backing of one macroblock in the bitstream is possible      */
		recode_macroblock = FALSE;

		/* Initializes the current macroblock */
		start_macroblock();

		/* Encode one macroblock */
		encode_one_macroblock();

		/* Pass the generated syntax elements to the NAL */
		write_one_macroblock();

		/* Terminate processing of the current macroblock */
		terminate_macroblock(&end_of_slice, &recode_macroblock);

		if (recode_macroblock == FALSE)					/* The final processing of the macroblock has been done */
			proceed2nextMacroblock(); /* Go to next macroblock */
			
	}

	terminate_slice();
}


/************************************************************************
*
*  Name :       init_frame()
*
*  Description: Initializes the parameters for a new frame
*               
************************************************************************/
void init_frame()
{
	int i,j,k;
	int prevP_no, nextP_no;

	img->current_mb_nr=0;
	img->current_slice_nr=0;
	stat->bit_slice = 0;

#ifdef UMV
	img->mhor  = img->width *4-1;
	img->mvert = img->height*4-1;
#endif

	img->mb_y = img->mb_x = 0;
	img->block_y = img->pix_y = img->pix_c_y = 0; 	/* define vertical positions */
	img->block_x = img->pix_x = img->block_c_x = img->pix_c_x = 0; /* define horizontal positions */

	if (input->intra_upd > 0 && img->mb_y <= img->mb_y_intra)
		img->height_err=(img->mb_y_intra*16)+15;     /* for extra intra MB */
	else
		img->height_err=img->height-1;

	if(img->type != B_IMG)
	{
		img->tr=img->number*(input->jumpd+1);
	
#ifdef _ADAPT_LAST_GROUP_
		if (input->last_frame && img->number+1 == input->no_frames)
		  img->tr=input->last_frame;
#endif
		if(img->number!=0 && input->successive_Bframe != 0) 	/* B pictures to encode */
			nextP_tr=img->tr;

		if (img->type == INTRA_IMG)            
			img->qp = input->qp0;					/* set quant. parameter for I-frame */
		else															
		  {
#ifdef _CHANGE_QP_
		    if (input->qp2start > 0 && img->tr >= input->qp2start)
		      img->qp = input->qpN2;
		    else
#endif
		      img->qp = input->qpN;
		  }

		img->mb_y_intra=img->mb_y_upd;   /*  img->mb_y_intra indicates which GOB to intra code for this frame */

		if (input->intra_upd > 0)          /* if error robustness, find next GOB to update */
		{
			img->mb_y_upd=(img->number/input->intra_upd) % (img->width/MB_BLOCK_SIZE);
		}
	}
	else
	{
		img->p_interval = input->jumpd+1;
		prevP_no = (img->number-1)*img->p_interval;
		nextP_no = img->number*img->p_interval;
#ifdef _ADAPT_LAST_GROUP_
		last_P_no[0] = prevP_no; for (i=1; i<img->buf_cycle; i++) last_P_no[i] = last_P_no[i-1]-img->p_interval;

		if (input->last_frame && img->number+1 == input->no_frames)
		  {
		    nextP_no        =input->last_frame;
		    img->p_interval =nextP_no - prevP_no;
		  }
#endif


		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; /* ????? */

#ifdef _CHANGE_QP_
		if (input->qp2start > 0 && img->tr >= input->qp2start)
		  img->qp = input->qpB2;
		else
#endif
		  img->qp = input->qpB;
     
		// initialize arrays
		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;
			}		
			
	}
}

/************************************************************************
*
*  Name :       init_slice()
*
*  Description: Initializes the parameters for a new slice
*               
************************************************************************/
void init_slice()
{

	int i;
	Slice *curr_slice = img->currentSlice;
	DataPartition *dataPart;
	Bitstream *currStream;

	curr_slice->picture_id = img->tr%256;
	curr_slice->slice_nr = img->current_slice_nr;
	curr_slice->qp = img->qp;
	curr_slice->start_mb_nr = img->current_mb_nr;
	curr_slice->dp_mode = input->partition_mode;
	curr_slice->slice_too_big = dummy_slice_too_big;

	for (i=0; i<curr_slice->max_part_nr; i++)
	{
		dataPart = &(curr_slice->partArr[i]);

		/* in priciple it is possible to assign to each partition */
		/* a different entropy coding method */ 
		if (input->symbol_mode == UVLC)
			dataPart->writeSyntaxElement = writeSyntaxElement_UVLC; 
		else
			dataPart->writeSyntaxElement = writeSyntaxElement_CABAC;

		// A little hack until CABAC can handle non-byte aligned start positions   StW!
		// For UVLC, the stored_ positions in the bit buffer are necessary.  For CABAC,
		// the buffer is initialized to start at zero.

		if (input->symbol_mode == UVLC) {
			currStream = dataPart->bitstream;
			currStream->bits_to_go	= currStream->stored_bits_to_go;
			currStream->byte_pos		= currStream->stored_byte_pos;
			currStream->byte_buf		= currStream->stored_byte_buf;
		} else {		// CABAC
			currStream = dataPart->bitstream;
			currStream->bits_to_go	= 8;
			currStream->byte_pos		= 0;
			currStream->byte_buf		= 0;
		}
	}
}
	

/************************************************************************
*
*  Name :       init_loop_filter()
*
*  Description: initializes loop filter
*               
************************************************************************/
void init_loop_filter()
{
	int i, j;

	for (i=0;i<img->width/4+2;i++)
		for (j=0;j<img->height/4+2;j++)
			loopb[i+1][j+1]=0;

	for (i=0;i<img->width_cr/4+2;i++)
		for (j=0;j<img->height_cr/4+2;j++)
			loopc[i+1][j+1]=0;
}


/************************************************************************
*
*  Name :       read_one_new frame()
*
*  Description: Reads new frame from file and sets frame_no
*               
************************************************************************/
void read_one_new_frame()
{
	int i, j, uv;
	int status; //frame_no;
	int frame_size = img->height*img->width*3/2;

	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);
#ifdef _ADAPT_LAST_GROUP_
	    if (input->last_frame && img->number+1 == input->no_frames)
	      frame_no=input->last_frame;
#endif

⌨️ 快捷键说明

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