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

📄 macroblock.c

📁 avs源代码
💻 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];

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*/
          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_row_nr && (img->coded_mb_nr != img->total_number_mb))
  {

⌨️ 快捷键说明

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