📄 macroblock.c
字号:
/*
*****************************************************************************
* 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 + -