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

📄 macroblock.c

📁 avs-s最新代码,包括编码器和解码器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
*****************************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2003, Advanced Audio Video Coding Standard, Part II
*
* DISCLAIMER OF WARRANTY
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations under
* the License.
*                     
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY.
* The AVS Working Group doesn't represent or warrant that the programs
* furnished here under 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 for standardization procedure is available at 
* AVS Web site http://www.avs.org.cn. Patent Licensing is outside
* of AVS Working Group.
*
* The Original Code is Reference Software for China National Standard 
* GB/T 20090.2-2006 (short for AVS-P2 or AVS Video) at version RM52J.
*
* The Initial Developer of the Original Code is Video subgroup of AVS
* Workinggroup (Audio and Video coding Standard Working Group of China).
* Contributors:   Guoping Li,    Siwei Ma,    Jian Lou,    Qiang Wang , 
*   Jianwen Chen,Haiwu Zhao,  Xiaozhen Zheng, Junhao Zheng, Zhiming Wang
* 
******************************************************************************
*/



/*
*************************************************************************************
* File name: macroblock.c
* Function: Process one macroblock
*
*************************************************************************************
*/


#include "contributors.h"

#include <math.h>
#include <stdlib.h>
#include <assert.h>

#include "macroblock.h"
#include "refbuf.h"
#include "vlc.h"
#include "block.h"
#include "header.h"
#include "golomb.h"
#include "ratectl.h"

extern const byte QP_SCALE_CR[64];
extern const int NCBP[64][2];
extern const int NCBP_400[16][2];//4:0:0 WANGJP

int chroma_trans8x8(int tmp_block[2][8][8],int tmp_mpr[2][8][8],int *cbpc);/*lgp*/

//Rate control
int predict_error,dq;
extern int DELTA_QP,DELTA_QP2;
extern int QP,QP2;


//cjw 20060321 for MV limit
#define MAX_V_SEARCH_RANGE 1024
#define MAX_V_SEARCH_RANGE_FIELD 512
#define MAX_H_SEARCH_RANGE 8192


/*
*************************************************************************
* Function:Update the coordinates for the next macroblock to be processed
* Input:mb: MB address in scan order
* Output:
* Return: 
* Attention:
*************************************************************************
*/

void set_MB_parameters (int mb)
{
	const int number_mb_per_row = img->width / MB_BLOCK_SIZE ;  //add by wuzhongmou 0610

	img->current_mb_nr = mb;
	img->mb_x = mb % number_mb_per_row;
	img->mb_y = mb / number_mb_per_row;

	// Define vertical positions
	img->block8_y= img->mb_y * BLOCK_SIZE/2;/*lgp*/
	img->block_y = img->mb_y * BLOCK_SIZE;      // vertical luma block position
	img->pix_y   = img->mb_y * MB_BLOCK_SIZE;   // vertical luma macroblock position
	img->pix_c_y = img->mb_y * MB_BLOCK_SIZE/2; // vertical chroma macroblock position

	// Define horizontal positions
	img->block8_x= img->mb_x * BLOCK_SIZE/2;/*lgp*/
	img->block_x = img->mb_x * BLOCK_SIZE;        // luma block
	img->pix_x   = img->mb_x * MB_BLOCK_SIZE;     // luma pixel
	img->block_c_x = img->mb_x * BLOCK_SIZE/2;    // chroma block
	img->pix_c_x   = img->mb_x * MB_BLOCK_SIZE/2; // chroma pixel  
}

/*
*************************************************************************
* Function:Update the coordinates and statistics parameter for the
next macroblock
* Input:
* Output:
* Return: 
* Attention:
*************************************************************************
*/

void proceed2nextMacroblock()
{
	Macroblock *currMB = &img->mb_data[img->current_mb_nr];
	int*        bitCount = currMB->bitcounter;

#if TRACE
	int i;
	if (p_trace)
	{
		fprintf(p_trace, "\n*********** Pic: %i (I/P) MB: %i Slice: %i **********\n\n", frame_no, img->current_mb_nr, img->current_slice_nr);
		// Write out the tracestring for each symbol
		for (i=0; i<currMB->currSEnr; i++)
			trace2out(&(img->MB_SyntaxElements[i]));
	}
#endif

	// Update the statistics
	stat->bit_use_mb_type[img->type]      += bitCount[BITS_MB_MODE];
	stat->bit_use_coeffY[img->type]       += bitCount[BITS_COEFF_Y_MB] ;
	stat->tmp_bit_use_cbp[img->type]      += bitCount[BITS_CBP_MB];
	stat->bit_use_coeffC[img->type]       += bitCount[BITS_COEFF_UV_MB];
	stat->bit_use_delta_quant[img->type]  += bitCount[BITS_DELTA_QUANT_MB];

	if (img->type==INTRA_IMG)
		++stat->mode_use_intra[currMB->mb_type];
	else
		if (img->type != B_IMG)
		{
			++stat->mode_use_inter[0][currMB->mb_type];
			stat->bit_use_mode_inter[0][currMB->mb_type]+= bitCount[BITS_INTER_MB];

		}
		else
		{
			stat->bit_use_mode_inter[1][currMB->mb_type]+= bitCount[BITS_INTER_MB];
			++stat->mode_use_inter[1][currMB->mb_type];
		}

		// Statistics
		if ((img->type == INTER_IMG) )
		{
			++stat->quant0;
			stat->quant1 += img->qp;      // to find average quant for inter frames
		}

}

/*
*************************************************************************
* Function:initializes the current macroblock
* Input:
* Output:
* Return: 
* Attention:
*************************************************************************
*/

void start_macroblock()
{
	int i,j,k,l;
	Macroblock *currMB = &img->mb_data[img->current_mb_nr];

	// Save the slice number of this macroblock. When the macroblock below
	// is coded it will use this to decide if prediction for above is possible
	img->current_slice_nr = img->mb_data[img->current_mb_nr].slice_nr;     // jlzheng 6.30
	currMB->slice_nr = img->current_slice_nr;

	// Rate control
	if(input->RCEnable)
	{
		/*frame layer rate control*/
		if(input->basicunit==img->Frame_Total_Number_MB)
		{
			currMB->delta_qp = 0;
			currMB->qp       = img->qp;
		}
		/*basic unit layer rate control*/
		else
		{
			/*each I or B frame has only one QP*/
			if((img->type==INTRA_IMG)||(img->type==B_IMG))
			{
				currMB->delta_qp = 0;
				currMB->qp       = img->qp;
			}
			else if(img->type==INTER_IMG)
			{
				if (img->current_mb_nr == 0) //first macroblock
				{
					// Initialize delta qp change from last macroblock. Feature may be used for future rate control
					currMB->delta_qp = 0;
					currMB->qp       = img->qp;
					DELTA_QP = DELTA_QP2 = currMB->delta_qp;
					QP = QP2 = currMB->qp;
				}
				else
				{
					if (img->mb_data[img->current_mb_nr-1].prev_cbp == 1)
					{
						currMB->delta_qp = 0;
						currMB->qp       = img->qp;
					}
					else
					{
						currMB->qp = img->mb_data[img->current_mb_nr-1].prev_qp;
						currMB->delta_qp = currMB->qp - img->mb_data[img->current_mb_nr-1].qp;
						img->qp = currMB->qp;
					}
					DELTA_QP = DELTA_QP2 = currMB->delta_qp;
					QP = QP2 = currMB->qp;
				}

				/*compute the quantization parameter for each basic unit of P frame*/
				if((img->NumberofCodedMacroBlocks>0)\
					&&(img->NumberofCodedMacroBlocks%img->BasicUnit==0))
				{

					/*frame coding*/
					if(input->InterlaceCodingOption==0)
					{
						updateRCModel();
						img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
					}
					/*adaptive field/frame coding*/
					//Commented by qihuafei, 20070925
					/*	 else if((input->InterlaceCodingOption==2)&&(img->IFLAG==0))
					{
					updateRCModel();
					img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
					}
					*/
					/*field coding*/
					else if((input->InterlaceCodingOption==1)&&(img->IFLAG==0))
					{
						updateRCModel();
						img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
					}
				}


				if(img->current_mb_nr==0)
					img->BasicUnitQP=img->qp;

				currMB->predict_qp=img->BasicUnitQP;

				if(currMB->predict_qp>currMB->qp+25)
					currMB->predict_qp=currMB->qp+25;
				else if(currMB->predict_qp<currMB->qp-26)
					currMB->predict_qp=currMB->qp-26; 

				currMB->prev_qp = currMB->predict_qp;

				dq = currMB->delta_qp + currMB->predict_qp-currMB->qp;
				if(dq < -26) 
				{
					dq = -26;
					predict_error = dq-currMB->delta_qp;
					img->qp = img->qp+predict_error;
					currMB->delta_qp = -26;
				}
				else if(dq > 25)
				{
					dq = 25;
					predict_error = dq - currMB->delta_qp;
					img->qp = img->qp + predict_error;
					currMB->delta_qp = 25;
				}
				else
				{
					currMB->delta_qp = dq;
					predict_error=currMB->predict_qp-currMB->qp;
					img->qp = currMB->predict_qp;
				}
				currMB->qp =  img->qp;
				currMB->predict_error=predict_error;
			} 
		}
	}
	else
	{
		currMB->delta_qp = 0;
		currMB->qp       = img->qp;       // needed in loop filter (even if constant QP is used)
	}

	// Initialize counter for MB symbols
	currMB->currSEnr=0;

	// If MB is next to a slice boundary, mark neighboring blocks unavailable for prediction
	CheckAvailabilityOfNeighbors(img);

	currMB->mb_type   = 0;

	// Reset vectors before doing motion search in motion_search().
	if (img->type != B_IMG)  
	{
		for (k=0; k < 2; k++)
		{
			for (j=0; j < BLOCK_MULTIPLE; j++)
				for (i=0; i < BLOCK_MULTIPLE; i++)
					tmp_mv[k][img->block_y+j][img->block_x+i+4]=0;
		}
	}

	// Reset syntax element entries in MB struct
	currMB->mb_type   = 0;
	currMB->cbp_blk   = 0;
	currMB->cbp       = 0;
	currMB->mb_field  = 0;

	for (l=0; l < 2; l++)
		for (j=0; j < BLOCK_MULTIPLE; j++)
			for (i=0; i < BLOCK_MULTIPLE; i++)
				for (k=0; k < 2; k++)
					currMB->mvd[l][j][i][k] = 0;

	currMB->cbp_bits   = 0;
	currMB->c_ipred_mode = DC_PRED_8; //GB

	for (i=0; i < (BLOCK_MULTIPLE*BLOCK_MULTIPLE); i++)
		currMB->intra_pred_modes[i] = DC_PRED;
	//	currMB->intra_pred_modes[i] = -1;

	// store filtering parameters for this MB; For now, we are using the
	// same offset throughout the sequence
	currMB->lf_disable = input->loop_filter_disable;
	currMB->lf_alpha_c0_offset = input->alpha_c_offset;
	currMB->lf_beta_offset = input->beta_offset;

	// Initialize bitcounters for this macroblock
	if(img->current_mb_nr == 0) // No slice header to account for
	{
		currMB->bitcounter[BITS_HEADER] = 0;
	}
	else if (currMB->slice_nr == img->mb_data[img->current_mb_nr-1].slice_nr) // current MB belongs to the
		// same slice as the last MB
	{
		currMB->bitcounter[BITS_HEADER] = 0;
	}

	currMB->bitcounter[BITS_MB_MODE] = 0;
	currMB->bitcounter[BITS_COEFF_Y_MB] = 0;
	currMB->bitcounter[BITS_INTER_MB] = 0;
	currMB->bitcounter[BITS_CBP_MB] = 0;
	currMB->bitcounter[BITS_DELTA_QUANT_MB] = 0;
	currMB->bitcounter[BITS_COEFF_UV_MB] = 0;

}

/*
*************************************************************************
* Function:Terminate processing of the current macroblock depending
on the chosen slice mode
* Input:
* Output:
* Return: 
* Attention:
*************************************************************************
*/

void terminate_macroblock(Boolean *end_of_picture)
{
	Macroblock    *currMB    = &img->mb_data[img->current_mb_nr];
	SyntaxElement *currSE    = &img->MB_SyntaxElements[currMB->currSEnr];


	int rlc_bits=0;
	static int skip = FALSE;
	int mb_width = img->width/16;
	int slice_mb = input->slice_row_nr*mb_width;


	img->coded_mb_nr++;

	if(!input->slice_set_enable)   //added by mz, 2008.04
	{
		if(input->slice_row_nr && (img->coded_mb_nr != img->total_number_mb))
		{
			if(img->coded_mb_nr%slice_mb == 0 )
			{
				img->mb_data[img->current_mb_nr+1].slice_nr = img->mb_data[img->current_mb_nr].slice_nr+1;  // last MB of slice, begin next slice   by jlzheng  6.30
				img->mb_no_currSliceLastMB =  min(img->mb_no_currSliceLastMB + slice_mb, img->total_number_mb) ;  // Yulj 2004.07.15		 
			}
			else
				img->mb_data[img->current_mb_nr+1].slice_nr = img->mb_data[img->current_mb_nr].slice_nr;
		}
	}  

	if (img->coded_mb_nr == img->total_number_mb) // maximum number of MBs reached
	{
		*end_of_picture = TRUE;

⌨️ 快捷键说明

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