?? macroblock.c
字號(hào):
/*!
*************************************************************************************
* \file macroblock.c
*
* \brief
* Process one macroblock
*
* \author
* 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>
* - Detlev Marpe <marpe@hhi.de>
* - Thomas Wedi <wedi@tnt.uni-hannover.de>
* - Ragip Kurceren <ragip.kurceren@nokia.com>
*************************************************************************************
*/
#include "contributors.h"
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "elements.h"
#include "macroblock.h"
#include "refbuf.h"
#include "fmo.h"
#include "vlc.h"
#include "image.h"
#include "mb_access.h"
#include "ratectl.h" // head file for rate control
#include "cabac.h"
//Rate control
int predict_error,dq;
extern int DELTA_QP,DELTA_QP2;
extern int QP,QP2;
/*!
************************************************************************
* \brief
* updates the coordinates for the next macroblock to be processed
*
* \param mb_addr
* MB address in scan order
************************************************************************
*/
void set_MB_parameters (int mb_addr)
{
img->current_mb_nr = mb_addr;
get_mb_block_pos(mb_addr, &img->mb_x, &img->mb_y);
img->block_x = img->mb_x << 2;
img->block_y = img->mb_y << 2;
img->pix_x = img->block_x << 2;
img->pix_y = img->block_y << 2;
img->opix_x = img->pix_x;
if (img->MbaffFrameFlag)
{
if (img->mb_data[mb_addr].mb_field)
{
imgY_org = (mb_addr % 2) ? imgY_org_bot : imgY_org_top;
imgUV_org = (mb_addr % 2) ? imgUV_org_bot : imgUV_org_top;
img->opix_y = (img->mb_y >> 1 ) << 4;
}
else
{
imgY_org = imgY_org_frm;
imgUV_org = imgUV_org_frm;
img->opix_y = img->block_y << 2;
}
}
else
{
img->opix_y = img->block_y << 2;
}
img->pix_c_x = img->pix_x >> 1;
img->pix_c_y = img->pix_y >> 1;
img->opix_c_x = img->opix_x >> 1;
img->opix_c_y = img->opix_y >> 1;
// printf ("set_MB_parameters: mb %d, mb_x %d, mb_y %d\n", mb_addr, img->mb_x, img->mb_y);
}
int clip1a(int a)
{
return ((a)>255?255:((a)<0?0:(a)));
}
/*!
************************************************************************
* \brief
* updates the coordinates and statistics parameter for the
* next macroblock
************************************************************************
*/
void proceed2nextMacroblock()
{
#if TRACE
int i;
int use_bitstream_backing = (input->slice_mode == FIXED_RATE || input->slice_mode == CALLBACK);
#endif
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
int* bitCount = currMB->bitcounter;
#if TRACE
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);
if(use_bitstream_backing)
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];
++stat->mode_use[img->type][currMB->mb_type];
stat->bit_use_mode[img->type][currMB->mb_type]+= bitCount[BITS_INTER_MB];
// Statistics
if ((img->type == P_SLICE)||(img->type==SP_SLICE) )
{
++stat->quant0;
stat->quant1 += currMB->qp; // to find average quant for inter frames
}
}
/*!
************************************************************************
* \brief
* initializes the current macroblock
************************************************************************
*/
void start_macroblock(int mb_addr, int mb_field)
{
int i,j,k,l;
int use_bitstream_backing = (input->slice_mode == FIXED_RATE || input->slice_mode == CALLBACK);
Macroblock *currMB = &img->mb_data[mb_addr];
Slice *curr_slice = img->currentSlice;
DataPartition *dataPart;
Bitstream *currStream;
EncodingEnvironmentPtr eep;
currMB->mb_field = mb_field;
enc_picture->mb_field[mb_addr] = mb_field;
set_MB_parameters (mb_addr);
if(use_bitstream_backing)
{
// Keep the current state of the bitstreams
if(!img->cod_counter)
for (i=0; i<curr_slice->max_part_nr; i++)
{
dataPart = &(curr_slice->partArr[i]);
currStream = dataPart->bitstream;
currStream->stored_bits_to_go = currStream->bits_to_go;
currStream->stored_byte_pos = currStream->byte_pos;
currStream->stored_byte_buf = currStream->byte_buf;
if (input->symbol_mode ==CABAC)
{
eep = &(dataPart->ee_cabac);
eep->ElowS = eep->Elow;
eep->ErangeS = eep->Erange;
eep->EbufferS = eep->Ebuffer;
eep->Ebits_to_goS = eep->Ebits_to_go;
eep->Ebits_to_followS = eep->Ebits_to_follow;
eep->EcodestrmS = eep->Ecodestrm;
eep->Ecodestrm_lenS = eep->Ecodestrm_len;
eep->CS = eep->C;
eep->BS = eep->B;
eep->ES = eep->E;
}
}
}
// 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
currMB->slice_nr = img->current_slice_nr;
// Initialize delta qp change from last macroblock. Feature may be used for future rate control
// Rate control
currMB->qpsp = img->qpsp;
if(input->RCEnable)
{
if (img->current_mb_nr==0)
{
currMB->prev_qp = img->qp;
currMB->prev_delta_qp = 0;
}
else
{
currMB->prev_qp = img->mb_data[img->current_mb_nr-1].qp;
currMB->prev_delta_qp = img->mb_data[img->current_mb_nr-1].delta_qp;
}
/*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==I_SLICE)||(img->type==B_SLICE))
{
currMB->delta_qp = 0;
currMB->qp = img->qp;
}
else if(img->type==P_SLICE)
{
if (!img->write_macroblock) //write macroblock
{
if (!currMB->mb_field) //frame macroblock
{
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 (!((input->MbInterlace) && img->bot_MB)) //top macroblock
{
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;
}
else //bottom macroblock
{
// Initialize delta qp change from last macroblock. Feature may be used for future rate control
currMB->delta_qp = 0;
currMB->qp = img->qp; // needed in loop filter (even if constant QP is used)
}
}
}
else //field macroblock
{
if (!img->bot_MB) //top macroblock
{
currMB->delta_qp = DELTA_QP2;
currMB->qp = img->qp = QP2;
}
else//bottom macroblock
{
currMB->qp = img->qp;
currMB->delta_qp = 0;
}
}
}
else
{
if (!img->bot_MB) //write top macroblock
{
if (img->write_macroblock_frame)
{
currMB->delta_qp = DELTA_QP;
img->qp = currMB->qp = QP;
}
else
{
currMB->delta_qp = DELTA_QP2;
img->qp = currMB->qp = QP2;
}
}
else //write bottom macroblock
{
currMB->delta_qp = 0;
currMB->qp = img->qp;
}
}
/*compute the quantization parameter for each basic unit of P frame*/
if(!((input->MbInterlace)&&img->bot_MB))
{
if(!currMB->mb_field)
{
if((img->NumberofCodedMacroBlocks>0)\
&&(img->NumberofCodedMacroBlocks%img->BasicUnit==0))
{
/*frame coding*/
if(active_sps->frame_mbs_only_flag)
{
updateRCModel();
img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
}
/*adaptive field/frame coding*/
else if((input->PicInterlace==ADAPTIVE_CODING)&&(!input->MbInterlace)&&(img->IFLAG==0))
{
updateRCModel();
img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
}
/*field coding*/
else if((input->PicInterlace==FIELD_CODING)&&(!input->MbInterlace)&&(img->IFLAG==0))
{
updateRCModel();
img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
}
/*mb adaptive f/f coding, field coding*/
else if((input->MbInterlace)&&(img->IFLAG==0)&&(img->FieldControl==1))
{
updateRCModel();
img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
}
/*mb adaptive f/f coding, frame coding*/
else if((input->MbInterlace)&&(img->IFLAG==0)&&(img->FieldControl==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;
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -