📄 macroblock.c
字号:
}
}
// Restore image to avoid DeblockMB to operate twice
// Note that this can be simplified! The copy range!
for(y=0; y<img->height; y++)
for(x=0; x<img->width; x++)
imgY[y][x] = imgY_tmp[y][x];
for(i=0; i<2; i++)
for(y=0; y<img->height_cr; y++)
for(x=0; x<img->width_cr; x++)
imgUV[i][y][x] = imgUV_tmp[i][y][x];
}
if(*end_of_slice == TRUE && skip == TRUE) //! TO 4.11.2001 Skip MBs at the end of this slice
{
//! only for Slice Mode 2 or 3
// If we still have to write the skip, let's do it!
if(img->cod_counter && *recode_macroblock == TRUE) //! MB that did not fit in this slice
{
// If recoding is true and we have had skip,
// we have to reduce the counter in case of recoding
img->cod_counter--;
if(img->cod_counter)
{
dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);
currSE->value1 = img->cod_counter;
currSE->mapping = n_linfo2;
currSE->type = SE_MBTYPE;
dataPart->writeSyntaxElement( currSE, dataPart);
rlc_bits=currSE->len;
currMB->bitcounter[BITS_MB_MODE]+=rlc_bits;
img->cod_counter = 0;
}
}
else //! MB that did not fit in this slice anymore is not a Skip MB
{
for (i=0; i<currSlice->max_part_nr; i++)
{
dataPart = &(currSlice->partArr[i]);
currStream = dataPart->bitstream;
// update the bitstream
currStream->bits_to_go = currStream->bits_to_go_skip;
currStream->byte_pos = currStream->byte_pos_skip;
currStream->byte_buf = currStream->byte_buf_skip;
}
// update the statistics
img->cod_counter = 0;
skip = FALSE;
}
}
//! TO 4.11.2001 Skip MBs at the end of this slice for Slice Mode 0 or 1
if(*end_of_slice == TRUE && img->cod_counter && !use_bitstream_backing)
{
dataPart = &(currSlice->partArr[partMap[SE_MBTYPE]]);
currSE->value1 = img->cod_counter;
currSE->mapping = n_linfo2;
currSE->type = SE_MBTYPE;
dataPart->writeSyntaxElement( currSE, dataPart);
rlc_bits=currSE->len;
currMB->bitcounter[BITS_MB_MODE]+=rlc_bits;
img->cod_counter = 0;
}
}
/*!
*****************************************************************************
*
* \brief
* For Slice Mode 2: Checks if one partition of one slice exceeds the
* allowed size
*
* \return
* FALSE if all Partitions of this slice are smaller than the allowed size
* TRUE is at least one Partition exceeds the limit
*
* \para Parameters
*
*
*
* \para Side effects
* none
*
* \para Other Notes
*
*
*
* \date
* 4 November 2001
*
* \author
* Tobias Oelbaum drehvial@gmx.net
*****************************************************************************/
int slice_too_big(int rlc_bits)
{
Slice *currSlice = img->currentSlice;
DataPartition *dataPart;
Bitstream *currStream;
EncodingEnvironmentPtr eep;
int i;
int size_in_bytes;
//! UVLC
if (input->symbol_mode == UVLC)
{
for (i=0; i<currSlice->max_part_nr; i++)
{
dataPart = &(currSlice->partArr[i]);
currStream = dataPart->bitstream;
size_in_bytes = currStream->byte_pos;
if (currStream->bits_to_go < 8)
size_in_bytes++;
if (currStream->bits_to_go < rlc_bits)
size_in_bytes++;
if(size_in_bytes > input->slice_argument)
return TRUE;
}
}
//! CABAC
if (input->symbol_mode ==CABAC)
{
for (i=0; i<currSlice->max_part_nr; i++)
{
dataPart= &(currSlice->partArr[i]);
eep = &(dataPart->ee_cabac);
if(arienco_bits_written(eep) > (input->slice_argument*8))
return TRUE;
}
}
return FALSE;
}
/*!
************************************************************************
* \brief
* Checks the availability of neighboring macroblocks of
* the current macroblock for prediction and context determination;
* marks the unavailable MBs for intra prediction in the
* ipredmode-array by -1. Only neighboring MBs in the causal
* past of the current MB are checked.
************************************************************************
*/
void CheckAvailabilityOfNeighbors()
{
int i,j;
const int mb_width = img->width/MB_BLOCK_SIZE;
const int mb_nr = img->current_mb_nr;
Macroblock *currMB = &img->mb_data[mb_nr];
// mark all neighbors as unavailable
for (i=0; i<3; i++)
for (j=0; j<3; j++)
img->mb_data[mb_nr].mb_available[i][j]=NULL;
img->mb_data[mb_nr].mb_available[1][1]=currMB; // current MB
// Check MB to the left
if(img->pix_x >= MB_BLOCK_SIZE)
{
int remove_prediction = currMB->slice_nr != img->mb_data[mb_nr-1].slice_nr;
if(input->UseConstrainedIntraPred)
remove_prediction = (remove_prediction || img->intra_mb[mb_nr-1] ==0);
if(remove_prediction)
{
img->ipredmode[img->block_x][img->block_y+1] = -1;
img->ipredmode[img->block_x][img->block_y+2] = -1;
img->ipredmode[img->block_x][img->block_y+3] = -1;
img->ipredmode[img->block_x][img->block_y+4] = -1;
} else
currMB->mb_available[1][0]=&(img->mb_data[mb_nr-1]);
}
// Check MB above
if(img->pix_y >= MB_BLOCK_SIZE)
{
int remove_prediction = currMB->slice_nr != img->mb_data[mb_nr-mb_width].slice_nr;
if(input->UseConstrainedIntraPred)
remove_prediction = (remove_prediction || img->intra_mb[mb_nr-mb_width] ==0);
if(remove_prediction)
{
img->ipredmode[img->block_x+1][img->block_y] = -1;
img->ipredmode[img->block_x+2][img->block_y] = -1;
img->ipredmode[img->block_x+3][img->block_y] = -1;
img->ipredmode[img->block_x+4][img->block_y] = -1;
} else
currMB->mb_available[0][1]=&(img->mb_data[mb_nr-mb_width]);
}
// Check MB left above
if(img->pix_x >= MB_BLOCK_SIZE && img->pix_y >= MB_BLOCK_SIZE )
{
if(currMB->slice_nr == img->mb_data[mb_nr-mb_width-1].slice_nr)
img->mb_data[mb_nr].mb_available[0][0]=&(img->mb_data[mb_nr-mb_width-1]);
}
// Check MB right above
if(img->pix_y >= MB_BLOCK_SIZE && img->pix_x < (img->width-MB_BLOCK_SIZE ))
{
if(currMB->slice_nr == img->mb_data[mb_nr-mb_width+1].slice_nr)
// currMB->mb_available[0][1]=&(img->mb_data[mb_nr-mb_width+1]);
currMB->mb_available[0][2]=&(img->mb_data[mb_nr-mb_width+1]);
}
}
/*!
************************************************************************
* \brief
* Performs 4x4 and 16x16 intra prediction and transform coding
* of the prediction residue. The routine returns the best cost;
* current cbp (for LUMA only) and intra pred modes are affected
************************************************************************
*/
int MakeIntraPrediction(int *intra_pred_mode_2)
{
int i,j;
int block_x, block_y;
int best_ipmode=0;
int tot_intra_sad, tot_intra_sad2, best_intra_sad, current_intra_sad;
int coeff_cost; // not used
int pic_pix_y,pic_pix_x,pic_block_y,pic_block_x;
int last_ipred=0; // keeps last chosen intra prediction mode for 4x4 intra pred
int ipmode; // intra pred mode
int cbp_mask;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
// start making 4x4 intra prediction
currMB->cbp = 0;
currMB->intraOrInter = INTRA_MB_4x4;
tot_intra_sad=QP2QUANT[img->qp]*24;// sum of intra sad values, start with a 'handicap'
for(block_y = 0 ; block_y < MB_BLOCK_SIZE ; block_y += BLOCK_MULTIPLE)
{
pic_pix_y=img->pix_y+block_y;
pic_block_y=pic_pix_y/BLOCK_SIZE;
for(block_x = 0 ; block_x < MB_BLOCK_SIZE ; block_x += BLOCK_MULTIPLE)
{
cbp_mask=(1<<(2*(block_y/8)+block_x/8));
pic_pix_x=img->pix_x+block_x;
pic_block_x=pic_pix_x/BLOCK_SIZE;
/*
intrapred_luma() makes and returns 4x4 blocks with all 5 intra prediction modes.
Notice that some modes are not possible at frame edges.
*/
intrapred_luma(pic_pix_x,pic_pix_y);
best_intra_sad=MAX_VALUE; // initial value, will be modified below
img->imod = INTRA_MB_OLD; // for now mode set to intra, may be changed in motion_search()
// DM: has to be removed
for (ipmode=0; ipmode < NO_INTRA_PMODE; ipmode++) // all intra prediction modes
{
// Horizontal pred from Y neighbour pix , vertical use X pix, diagonal needs both
if (ipmode==DC_PRED||ipmode==HOR_PRED||img->ipredmode[pic_block_x+1][pic_block_y] >= 0)// DC or vert pred or hor edge
{
if (ipmode==DC_PRED||ipmode==VERT_PRED||img->ipredmode[pic_block_x][pic_block_y+1] >= 0)// DC or hor pred or vert edge
{
for (j=0; j < BLOCK_SIZE; j++)
{
for (i=0; i < BLOCK_SIZE; i++)
img->m7[i][j]=imgY_org[pic_pix_y+j][pic_pix_x+i]-img->mprr[ipmode][j][i]; // find diff
}
current_intra_sad=QP2QUANT[img->qp]*PRED_IPRED[img->ipredmode[pic_block_x+1][pic_block_y]+1][img->ipredmode[pic_block_x][pic_block_y+1]+1][ipmode]*2;
current_intra_sad += find_sad(input->hadamard, img->m7); // add the start 'handicap' and the computed SAD
if (current_intra_sad < best_intra_sad)
{
best_intra_sad=current_intra_sad;
best_ipmode=ipmode;
for (j=0; j < BLOCK_SIZE; j++)
for (i=0; i < BLOCK_SIZE; i++)
img->mpr[i+block_x][j+block_y]=img->mprr[ipmode][j][i]; // store the currently best intra prediction block
}
}
}
}
tot_intra_sad += best_intra_sad;
img->ipredmode[pic_block_x+1][pic_block_y+1]=best_ipmode;
if ((pic_block_x & 1) == 1) // just even blocks, two and two predmodes are sent together
{
currMB->intra_pred_modes[block_x/4+block_y]=PRED_IPRED[img->ipredmode[pic_block_x+1][pic_block_y]+1][img->ipredmode[pic_block_x][pic_block_y+1]+1][best_ipmode];
currMB->intra_pred_modes[block_x/4-1+block_y]=last_ipred;
}
last_ipred=PRED_IPRED[img->ipredmode[pic_block_x+1][pic_block_y]+1][img->ipredmode[pic_block_x][pic_block_y+1]+1][best_ipmode];
// Make difference from prediction to be transformed
for (j=0; j < BLOCK_SIZE; j++)
for (i=0; i < BLOCK_SIZE; i++)
img->m7[i][j] =imgY_org[img->pix_y+block_y+j][img->pix_x+block_x+i] - img->mpr[i+block_x][j+block_y];
if( dct_luma(block_x,block_y,&coeff_cost) ) // if non zero coefficients
currMB->cbp |= cbp_mask; // set coded block pattern if nonzero coeffs
}
}
// 16x16 intra prediction
intrapred_luma_2(img); // make intra pred for the new 4 modes
tot_intra_sad2 = find_sad2(intra_pred_mode_2); // find best SAD for new modes
if (tot_intra_sad2<tot_intra_sad)
{
currMB->cbp = 0; // cbp for 16x16 LUMA is signaled by the MB-mode
tot_intra_sad = tot_intra_sad2; // update best intra sad if necessary
img->imod = INTRA_MB_NEW; // one of the new modes is used
currMB->intraOrInter = INTRA_MB_16x16;
dct_luma2(*intra_pred_mode_2);
for (i=0;i<4;i++)
for (j=0;j<4;j++)
img->ipredmode[img->block_x+i+1][img->block_y+j+1]=0;
}
return tot_intra_sad;
}
/*!
************************************************************************
* \brief
* Performs DCT, R-D constrained quantization, run/level
* pre-coding and IDCT for the MC-compensated MB residue
* of P-frame; current cbp (for LUMA only) is affected
************************************************************************
*/
void LumaResidualCoding_P()
{
int i,j;
int block_x, block_y;
int pic_pix_y,pic_pix_x,pic_block_y,pic_block_x;
int ii4,i2,jj4,j2;
int sum_cnt_nonz;
int mb_x, mb_y;
int cbp_mask, cbp_blk_mask ;
int coeff_cost;
int nonzero;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
currMB->cbp = 0 ;
currMB->cbp_blk = 0 ;
sum_cnt_nonz = 0 ;
for (mb_y=0; mb_y < MB_BLOCK_SIZE; mb_y += BLOCK_SIZE*2)
{
for (mb_x=0; mb_x < MB_BLOCK_SIZE; mb_x += BLOCK_SIZE*2)
{
cbp_mask = (1<<(mb_x/8+mb_y/4));
coeff_cost = 0;
for (block_y=mb_y; block_y < mb_y+BLOCK_SIZE*2; block_y += BLOCK_SIZE)
{
pic_pix_y=img->pix_y+block_y;
pic_block_y=pic_pix_y/BLOCK_SIZE;
for (block_x=mb_x; block_x < mb_x+BLOCK_SIZE*2; block_x += BLOCK_SIZE)
{
pic_pix_x = img->pix_x+block_x;
pic_block_x = pic_pix_x/BLOCK_SIZE;
cbp_blk_mask = (block_x>>2)+ block_y ;
img->ipredmode[pic_block_x+1][pic_block_y+1]=0;
if(input->mv_res)
{
ii4=(img->pix_x+block_x)*8+tmp_mv[0][pic_block_y][pic_block_x+4];
jj4=(img->pix_y+block_y)*8+tmp_mv[1][pic_block_y][pic_block_x+4];
for (j=0;j<4;j++)
{
j2=j*8;
for (i=0;i<4;i++)
{
i2=i*8;
img->mpr[i+block_x][j+block_y]=UMVPelY_18 (mref[img->multframe_no], jj4+j2, ii4+i2);
}
}
}
else
{
ii4=(img->pix_x+block_x)*4+tmp_mv[0][pic_block_y][pic_block_x+4];
jj4=(img->pix_y+block_y)*4+tmp_mv[1][pic_block_y][pic_block_x+4];
for (j=0;j<4;j++)
{
j2 = jj4+j*4;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -