📄 macroblock.c
字号:
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;
img->coded_mb_nr= 0;
}
if(*end_of_picture == TRUE && img->cod_counter)
{
currSE->value1 = img->cod_counter;
currSE->mapping = ue_linfo;
currSE->type = SE_MBTYPE;
writeSyntaxElement_UVLC( currSE, currBitStream);
rlc_bits=currSE->len;
currMB->bitcounter[BITS_MB_MODE]+=rlc_bits;
img->cod_counter = 0;
}
}
/*
*************************************************************************
* Function: 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.
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
void CheckAvailabilityOfNeighbors()
{
int i,j;
//const int mb_width = input->img_width/MB_BLOCK_SIZE;
const int mb_width = img->width/MB_BLOCK_SIZE; //add by wuzhongmou 0610
const int mb_nr = img->current_mb_nr;
Macroblock *currMB = &img->mb_data[mb_nr];
int pix_x = img->pix_x;
int tmp_x = img->block_x;
int tmp_y = img->block_y;
int block_x = img->block_x/2;
int pix_y = img->pix_y;
int block_y = img->block_y/2;
int remove_prediction;
img->block_x = block_x;
img->block_y = block_y;
// 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(pix_x >= MB_BLOCK_SIZE)
{
remove_prediction = currMB->slice_nr != img->mb_data[mb_nr-1].slice_nr;
// upper blocks
if (remove_prediction)
{
img->ipredmode[img->block_x][img->block_y+1] = -1;
img->ipredmode[img->block_x][img->block_y+2] = -1;
}
// lower blocks
if (remove_prediction)
{
img->ipredmode[img->block_x][img->block_y+3] = -1;
img->ipredmode[img->block_x][img->block_y+4] = -1;
}
if (!remove_prediction)
{
currMB->mb_available[1][0]=&(img->mb_data[mb_nr-1]);
}
}
// Check MB above
if(pix_y >= MB_BLOCK_SIZE)
{
remove_prediction = currMB->slice_nr != img->mb_data[mb_nr-mb_width].slice_nr;
// upper blocks
if (remove_prediction)
{
img->ipredmode[img->block_x+1][img->block_y] = -1;
img->ipredmode[img->block_x+2][img->block_y] = -1;
}
if (!remove_prediction)
{
currMB->mb_available[0][1]=&(img->mb_data[mb_nr-mb_width]);
}
}
// Check MB left above
if(pix_x >= MB_BLOCK_SIZE && pix_y >= MB_BLOCK_SIZE )
{
remove_prediction = currMB->slice_nr != img->mb_data[mb_nr-mb_width-1].slice_nr;
if (remove_prediction)
{
img->ipredmode[img->block_x][img->block_y] = -1;
}
if (!remove_prediction)
{
currMB->mb_available[0][0]=&(img->mb_data[mb_nr-mb_width-1]);
}
}
// Check MB right above
if(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][2]=&(img->mb_data[mb_nr-mb_width+1]);
}
img->block_x = tmp_x;
img->block_y = tmp_y;
}
/*
*************************************************************************
* Function:Predict one component of a 4x4 Luma block
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
void
OneComponentLumaPrediction4x4 (int* mpred, // --> array of prediction values (row by row)
int pic_pix_x, // <-- absolute horizontal coordinate of 4x4 block
int pic_pix_y, // <-- absolute vertical coordinate of 4x4 block
int* mv, // <-- motion vector
int ref) // <-- reference frame (0.. / -1:backward)
{
int incr=0;/*lgp*13*/
pel_t** ref_pic;
int pix_add = 4;
int j0 = (pic_pix_y << 2) + mv[1], j1=j0+pix_add, j2=j1+pix_add, j3=j2+pix_add;
int i0 = (pic_pix_x << 2) + mv[0], i1=i0+pix_add, i2=i1+pix_add, i3=i2+pix_add;
int i,j;
pel_t (*get_pel) (pel_t**, int, int) = UMVPelY_14;
//////cjw 20060321 for MV limit////////////////////////
//MAX_V_SEARCH_RANGE [-256, +255.75]
//MAX_V_SEARCH_RANGE_FIELD [-128, +127.75]
//MAX_H_SEARCH_RANGE [-2048, +2047.75]
// MaxMVHRange= MAX_H_SEARCH_RANGE;
// MaxMVVRange= MAX_V_SEARCH_RANGE;
// if(!img->picture_structure) //field coding
// {
// MaxMVVRange=MAX_V_SEARCH_RANGE_FIELD;
// }
//
// if ( mv[0] < -MaxMVHRange || mv[0] > MaxMVHRange-1
// || mv[1] < -MaxMVVRange || mv[1] > MaxMVVRange-1 )
// {
// mv_out_of_range = 1;
// }
//////////end cjw //////////////////////////////////////
incr = 1;
if(!img->picture_structure) //field coding
{
incr =2;
}
ref_pic = img->type==B_IMG? mref [ref+incr] : mref [ref];
for(j=0;j<4;j++)
{
for(i=0;i<4;i++)
{
*mpred++ = get_pel (ref_pic, j0+pix_add*j, i0+pix_add*i);
}
}
}
/*
*************************************************************************
* Function:Predict one 4x4 Luma block
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
void
LumaPrediction4x4 (int block_x, // <-- relative horizontal block coordinate of 4x4 block
int block_y, // <-- relative vertical block coordinate of 4x4 block
int fw_mode, // <-- forward prediction mode (1-7, 0=DIRECT if bw_mode=0)
int bw_mode, // <-- backward prediction mode (1-7, 0=DIRECT if fw_mode=0)
int fw_ref, // <-- reference frame for forward prediction (-1: Intra4x4 pred. with fw_mode)
int bw_ref )
{
static int fw_pred[16];
static int bw_pred[16];
int i, j;
int block_x4 = block_x+4;
int block_y4 = block_y+4;
int pic_pix_x = img->pix_x + block_x;
int pic_pix_y = img->pix_y + block_y;
int bx = block_x >> 3;
int by = block_y >> 3;
int* fpred = fw_pred;
int* bpred = bw_pred;
int direct = (fw_mode == 0 && bw_mode == 0 && (img->type==B_IMG));
int skipped = (fw_mode == 0 && bw_mode == 0 && (img->type!=B_IMG));
//int *****fmv_array = img->all_mv; // For MB level frame/field coding
int scale_frame;
int *****fmv_array = (fw_mode && bw_mode)?img->all_omv:img->all_mv; // For MB level frame/field coding
int *****bmv_array = img->all_bmv; // For MB level frame/field coding
//cjw 20060112 for weighted prediction
int fw_lum_scale , fw_lum_shift ;
int bw_lum_scale , bw_lum_shift ;
int bw_ref_num ;
int fw_ref_num ;
//cjw weighted prediction parameter map 20060112
/*///frame coding/////////
P img->lum_scale[0] fw[0]
img->lum_scale[1] fw[1]
B img->lum_scale[0] fw[0]
img->lum_scale[1] bw[0]
///field coding////////
P img->lum_scale[0] fw[0] ; img->lum_scale[1] fw[1]
img->lum_scale[2] fw[2] ; img->lum_scale[3] fw[3]
B img->lum_scale[0] fw[0] ; img->lum_scale[1] bw[0]
img->lum_scale[2] fw[1] ; img->lum_scale[3] bw[1]
*/
if (direct)
{
fw_ref= 0;//max(refFrArr[ipdirect_y][ipdirect_x],0);
bw_ref= 0;//min(refFrArr[ipdirect_y][ipdirect_x],0);
if(!img->picture_structure) //field coding
{
scale_frame = refFrArr[img->block8_y + by][img->block8_x+bx];
bw_ref = 0;//-1; xyji 11.25
if (img->current_mb_nr_fld < img->total_number_mb) //top field
{
fw_ref = scale_frame >= 1 ? 1 : 0;
bw_ref = scale_frame >= 0 ?1 :0;
}
else
{
fw_ref =(scale_frame == 1 || scale_frame < 0)? 0 : 1;
bw_ref = 0;
}
if(scale_frame < 0)
bw_ref = 1;
}
}
direct_mode = direct;
if (fw_mode ||(direct && (fw_ref !=-1) )|| skipped)
{
if(!img->picture_structure) // !! field shenyanfei
OneComponentLumaPrediction4x4 (fw_pred, pic_pix_x, pic_pix_y, fmv_array [bx][by][fw_ref][fw_mode], fw_ref);
else // !! frame shenyanfei
OneComponentLumaPrediction4x4 (fw_pred, pic_pix_x, pic_pix_y, fmv_array [bx][by][fw_ref][fw_mode], (direct ?0:fw_ref));
}
if (bw_mode || (direct && (bw_ref !=-1) ) ||(direct && !img->picture_structure && (bw_ref ==-1) ) )
{
int delta_P,TRp,DistanceIndexFw,DistanceIndexBw,refframe,delta_PB;
int mv[2];
refframe = fw_ref;
delta_P = 2*(img->imgtr_next_P_frm - img->imgtr_last_P_frm);
if(img->picture_structure)
TRp = (refframe+1)*delta_P; //the lates backward reference
else
{
TRp = delta_P;//refframe == 0 ? delta_P-1 : delta_P+1;
}
delta_PB = 2*(picture_distance - img->imgtr_last_P_frm); // Tsinghua 200701
if(!img->picture_structure)
{
if(img->current_mb_nr_fld < img->total_number_mb) //top field
DistanceIndexFw = refframe == 0 ? delta_PB-1:delta_PB;
else
DistanceIndexFw = refframe == 0 ? delta_PB:delta_PB+1;
}
else
DistanceIndexFw = delta_PB;
//DistanceIndexBw = TRp - DistanceIndexFw;
DistanceIndexBw = (TRp - DistanceIndexFw+512)%512; // Added by Zhijie Yang, 20070419, Broadcom
mv[0] = - ((fmv_array[bx][by][fw_ref][fw_mode][0]*DistanceIndexBw*(512/DistanceIndexFw)+256)>>9);
mv[1] = - ((fmv_array[bx][by][fw_ref][fw_mode][1]*DistanceIndexBw*(512/DistanceIndexFw)+256)>>9);
if(fw_mode && bw_mode)
OneComponentLumaPrediction4x4 (bw_pred, pic_pix_x, pic_pix_y, mv,
(!img->picture_structure) ? (-2+bw_ref) : (-1-bw_ref));
else
OneComponentLumaPrediction4x4 (bw_pred, pic_pix_x, pic_pix_y, bmv_array[bx][by][bw_ref][bw_mode],
(!img->picture_structure) ? (-2+bw_ref) : (-1-bw_ref));
}
// !! start shenyanfei
if (direct || (fw_mode && bw_mode))
{
if(!img->picture_structure)
bw_ref=1-bw_ref; //cjw used for bw reference buffer address changing 20060112 bw
fw_ref_num=(img->picture_structure)?(fw_ref):(2*fw_ref); //cjw 20060112 fw
bw_ref_num=(img->picture_structure)?(bw_ref+1):(2*bw_ref+1); //cjw 20060112 bw
fw_lum_scale = img->lum_scale[fw_ref_num];
fw_lum_shift = img->lum_shift[fw_ref_num];
bw_lum_scale = img->lum_scale[bw_ref_num];
bw_lum_shift = img->lum_shift[bw_ref_num];
for(j=block_y; j<block_y4; j++)
for (i=block_x; i<block_x4; i++){
img->mpr[i][j] = (*fpred + *bpred + 1) / 2;
if(img->LumVarFlag == 1)
img->mpr_weight[i][j] = (Clip1((((*fpred)*fw_lum_scale + 16)>>5) + fw_lum_shift)+
Clip1((((*bpred)*bw_lum_scale + 16)>>5) + bw_lum_shift) + 1)/2;
fpred++;
bpred++;
}
}
else if (fw_mode || skipped) //P fw and B one direction fw
{
if(img->type==B_IMG){
fw_ref_num=(img->picture_structure)?(fw_ref):(2*fw_ref); //cjw 20060112 fw
fw_lum_scale = img->lum_scale[fw_ref_num]; //cjw 20060112
fw_lum_shift = img->lum_shift[fw_ref_num];
}
else{
fw_lum_scale = img->lum_scale[fw_ref];
fw_lum_shift = img->lum_shift[fw_ref];
}
for(j=block_y; j<block_y4; j++)
for (i=block_x; i<block_x4; i++){
img->mpr[i][j] = *fpred;
if((!skipped) && (img->LumVarFlag == 1)){
img->mpr_weight[i][j] = Clip1(((((*fpred)*fw_lum_scale + 16)>>5) + fw_lum_shift));
}
fpred++;
}
}
else //B one direction bw
{
if(!img->picture_structure)//cjw used for bw reference buffer address changing 20060112 bw
bw_ref=1-bw_ref;
bw_ref_num=(img->picture_structure)?(bw_ref+1):(2*bw_ref+1); //cjw 20060112 bw
bw_lum_scale = img->lum_scale[bw_ref_num];
bw_lum_shift = img->lum_shift[bw_ref_num];
for(j=block_y; j<block_y4; j++)
for (i=block_x; i<block_x4; i++){
img->mpr[i][j] = *bpred;
if(img->LumVarFlag == 1){
img->mpr_weight[i][j] = Clip1(((((*bpred)*bw_lum_scale + 16)>>5) + bw_lum_shift));
}
bpred++;
}
}
// !! end shenyanfei
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -