📄 macroblock.c
字号:
// !! KS: not sure if the following is still correct...
ts = ls = 0; // Check to see if the neighboring block is SI
if (currMB->mb_type == I4MB && img->type == SI_SLICE) // need support for MBINTLC1
{
if (left_block.available)
if (img->siblock [left_block.pos_y][left_block.pos_x])
ls=1;
if (top_block.available)
if (img->siblock [top_block.pos_y][top_block.pos_x])
ts=1;
}
upIntraPredMode = (top_block.available &&(ts == 0)) ? img->ipredmode[top_block.pos_y ][top_block.pos_x ] : -1;
leftIntraPredMode = (left_block.available &&(ls == 0)) ? img->ipredmode[left_block.pos_y][left_block.pos_x] : -1;
mostProbableIntraPredMode = (upIntraPredMode < 0 || leftIntraPredMode < 0) ? DC_PRED : upIntraPredMode < leftIntraPredMode ? upIntraPredMode : leftIntraPredMode;
dec = (currSE.value1 == -1) ? mostProbableIntraPredMode : currSE.value1 + (currSE.value1 >= mostProbableIntraPredMode);
//set
for(jj = 0; jj < (bs_y >> 2); jj++) //loop 4x4s in the subblock for 8x8 prediction setting
{
memset(&(img->ipredmode[bj + jj][bi]), dec, (bs_x>>2) * sizeof(char));
}
}
}
}
}
if (IntraChromaPredModeFlag && (dec_picture->chroma_format_idc != YUV400) && (dec_picture->chroma_format_idc != YUV444))
{
currSE.type = SE_INTRAPREDMODE;
TRACE_STRING("intra_chroma_pred_mode");
dP = &(currSlice->partArr[partMap[currSE.type]]);
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
currSE.mapping = linfo_ue;
else
currSE.reading = readCIPredMode_CABAC;
dP->readSyntaxElement(&currSE,img,dP);
currMB->c_ipred_mode = currSE.value1;
if (currMB->c_ipred_mode < DC_PRED_8 || currMB->c_ipred_mode > PLANE_8)
{
error("illegal chroma intra pred mode!\n", 600);
}
}
}
/*!
************************************************************************
* \brief
* Get current block spatial neighbors
************************************************************************
*/
void get_neighbors(Macroblock *currMB, // <-- current Macroblock
PixelPos *block_a, // <--> left block
PixelPos *block_b, // <--> top block
PixelPos *block_c, // <--> top-right block | top-left block
PixelPos *block_d, // <--> top-left block. Can be removed.
int mb_x, // <-- block x position
int mb_y, // <-- block y position
int blockshape_x // <-- block width
)
{
int *mb_size = img->mb_size[IS_LUMA];
get4x4Neighbour(currMB, mb_x - 1, mb_y , mb_size, block_a);
get4x4Neighbour(currMB, mb_x, mb_y - 1, mb_size, block_b);
get4x4Neighbour(currMB, mb_x + blockshape_x, mb_y - 1, mb_size, block_c);
get4x4Neighbour(currMB, mb_x - 1, mb_y - 1, mb_size, block_d);
if (mb_y > 0)
{
if (mb_x < 8) // first column of 8x8 blocks
{
if (mb_y == 8 )
{
if (blockshape_x == MB_BLOCK_SIZE)
block_c->available = 0;
}
else if (mb_x+blockshape_x == 8)
{
block_c->available = 0;
}
}
else if (mb_x + blockshape_x == MB_BLOCK_SIZE)
{
block_c->available = 0;
}
}
if (!block_c->available)
{
*block_c = *block_d;
}
}
/*!
************************************************************************
* \brief
* Get motion vector predictor
************************************************************************
*/
void GetMotionVectorPredictor (Macroblock *currMB,
PixelPos *block_a, // <--> left block
PixelPos *block_b, // <--> top block
PixelPos *block_c, // <--> top-right block
short pmv[2],
char ref_frame,
char **refPic,
short ***tmp_mv,
int mb_x,
int mb_y,
int blockshape_x,
int blockshape_y)
{
int mv_a, mv_b, mv_c, pred_vec=0;
int mvPredType, rFrameL, rFrameU, rFrameUR;
int hv;
mvPredType = MVPRED_MEDIAN;
if (!img->MbaffFrameFlag)
{
rFrameL = block_a->available ? refPic[block_a->pos_y][block_a->pos_x] : -1;
rFrameU = block_b->available ? refPic[block_b->pos_y][block_b->pos_x] : -1;
rFrameUR = block_c->available ? refPic[block_c->pos_y][block_c->pos_x] : -1;
}
else
{
if (currMB->mb_field)
{
rFrameL = block_a->available
? (img->mb_data[block_a->mb_addr].mb_field
? refPic[block_a->pos_y][block_a->pos_x]
: refPic[block_a->pos_y][block_a->pos_x] * 2) : -1;
rFrameU = block_b->available
? (img->mb_data[block_b->mb_addr].mb_field
? refPic[block_b->pos_y][block_b->pos_x]
: refPic[block_b->pos_y][block_b->pos_x] * 2) : -1;
rFrameUR = block_c->available
? (img->mb_data[block_c->mb_addr].mb_field
? refPic[block_c->pos_y][block_c->pos_x]
: refPic[block_c->pos_y][block_c->pos_x] * 2) : -1;
}
else
{
rFrameL = block_a->available
? (img->mb_data[block_a->mb_addr].mb_field
? refPic[block_a->pos_y][block_a->pos_x] >>1
: refPic[block_a->pos_y][block_a->pos_x]) : -1;
rFrameU = block_b->available
? (img->mb_data[block_b->mb_addr].mb_field
? refPic[block_b->pos_y][block_b->pos_x] >>1
: refPic[block_b->pos_y][block_b->pos_x]) : -1;
rFrameUR = block_c->available
? (img->mb_data[block_c->mb_addr].mb_field
? refPic[block_c->pos_y][block_c->pos_x] >>1
: refPic[block_c->pos_y][block_c->pos_x]) : -1;
}
}
/* Prediction if only one of the neighbors uses the reference frame
* we are checking
*/
if (rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame)
mvPredType = MVPRED_L;
else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame)
mvPredType = MVPRED_U;
else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame)
mvPredType = MVPRED_UR;
// Directional predictions
if(blockshape_x == 8 && blockshape_y == 16)
{
if(mb_x == 0)
{
if(rFrameL == ref_frame)
mvPredType = MVPRED_L;
}
else
{
if( rFrameUR == ref_frame)
mvPredType = MVPRED_UR;
}
}
else if(blockshape_x == 16 && blockshape_y == 8)
{
if(mb_y == 0)
{
if(rFrameU == ref_frame)
mvPredType = MVPRED_U;
}
else
{
if(rFrameL == ref_frame)
mvPredType = MVPRED_L;
}
}
for (hv=0; hv < 2; hv++)
{
if (!img->MbaffFrameFlag || hv == 0)
{
mv_a = block_a->available ? tmp_mv[block_a->pos_y][block_a->pos_x][hv] : 0;
mv_b = block_b->available ? tmp_mv[block_b->pos_y][block_b->pos_x][hv] : 0;
mv_c = block_c->available ? tmp_mv[block_c->pos_y][block_c->pos_x][hv] : 0;
}
else
{
if (currMB->mb_field)
{
mv_a = block_a->available ? img->mb_data[block_a->mb_addr].mb_field
? tmp_mv[block_a->pos_y][block_a->pos_x][hv]
: tmp_mv[block_a->pos_y][block_a->pos_x][hv] / 2
: 0;
mv_b = block_b->available ? img->mb_data[block_b->mb_addr].mb_field
? tmp_mv[block_b->pos_y][block_b->pos_x][hv]
: tmp_mv[block_b->pos_y][block_b->pos_x][hv] / 2
: 0;
mv_c = block_c->available ? img->mb_data[block_c->mb_addr].mb_field
? tmp_mv[block_c->pos_y][block_c->pos_x][hv]
: tmp_mv[block_c->pos_y][block_c->pos_x][hv] / 2
: 0;
}
else
{
mv_a = block_a->available ? img->mb_data[block_a->mb_addr].mb_field
? tmp_mv[block_a->pos_y][block_a->pos_x][hv] * 2
: tmp_mv[block_a->pos_y][block_a->pos_x][hv]
: 0;
mv_b = block_b->available ? img->mb_data[block_b->mb_addr].mb_field
? tmp_mv[block_b->pos_y][block_b->pos_x][hv] * 2
: tmp_mv[block_b->pos_y][block_b->pos_x][hv]
: 0;
mv_c = block_c->available ? img->mb_data[block_c->mb_addr].mb_field
? tmp_mv[block_c->pos_y][block_c->pos_x][hv] * 2
: tmp_mv[block_c->pos_y][block_c->pos_x][hv]
: 0;
}
}
switch (mvPredType)
{
case MVPRED_MEDIAN:
if(!(block_b->available || block_c->available))
{
pred_vec = mv_a;
}
else
{
pred_vec = mv_a + mv_b + mv_c - imin(mv_a, imin(mv_b, mv_c)) - imax(mv_a, imax(mv_b, mv_c));
}
break;
case MVPRED_L:
pred_vec = mv_a;
break;
case MVPRED_U:
pred_vec = mv_b;
break;
case MVPRED_UR:
pred_vec = mv_c;
break;
default:
break;
}
pmv[hv] = (short) pred_vec;
}
}
/*!
************************************************************************
* \brief
* Read motion info
************************************************************************
*/
static void readMotionInfoFromNAL (ImageParameters *img, Slice *currSlice, Macroblock *currMB)
{
int i,j,k;
int mb_nr = img->current_mb_nr;
SyntaxElement currSE;
DataPartition *dP = NULL;
byte *partMap = assignSE2partition[currSlice->dp_mode];
int bslice = (img->type==B_SLICE);
int partmode = ((currMB->mb_type == P8x8) ? 4 : currMB->mb_type);
int step_h0 = BLOCK_STEP [partmode][0];
int step_v0 = BLOCK_STEP [partmode][1];
int i0, j0, j6;
int j4, i4, ii;
PicMotionParams *motion = &dec_picture->motion;
MotionParams *colocated;
int mv_scale = 0;
int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (mb_nr&0x01) ? 4 : 2 : 0;
if (bslice)
{
if ((img->MbaffFrameFlag) && (currMB->mb_field))
{
if(mb_nr&0x01)
{
colocated = &Co_located->bottom;
}
else
{
colocated = &Co_located->top;
}
}
else
{
colocated = &Co_located->frame;
}
if (currMB->mb_type == P8x8)
{
if (img->direct_spatial_mv_pred_flag)
{
char l0_rFrame, l1_rFrame;
short pmvl0[2]={0,0}, pmvl1[2]={0,0};
prepare_direct_params(currMB, dec_picture, img, pmvl0, pmvl1, &l0_rFrame, &l1_rFrame);
for (k = 0; k < 4; k++)
{
if (currMB->b8mode[k] == 0)
{
i = img->block_x + 2 * (k & 0x01);
for(j = 2 * (k >> 1); j < 2 * (k >> 1)+2;j++)
{
j6 = img->block_y_aff + j;
j4 = img->block_y + j;
for(i4 = i; i4 < i + 2; i4++)
{
if (l0_rFrame >= 0)
{
if (!l0_rFrame && ((!colocated->moving_block[j6][i4]) && (!listX[LIST_1 + list_offset][0]->is_long_term)))
{
motion->mv [LIST_0][j4][i4][0] = 0;
motion->mv [LIST_0][j4][i4][1] = 0;
motion->ref_idx[LIST_0][j4][i4] = 0;
}
else
{
motion->mv [LIST_0][j4][i4][0] = pmvl0[0];
motion->mv [LIST_0][j4][i4][1] = pmvl0[1];
motion->ref_idx[LIST_0][j4][i4] = l0_rFrame;
}
}
else
{
motion->mv [LIST_0][j4][i4][0] = 0;
motion->mv [LIST_0][j4][i4][1] = 0;
motion->ref_idx[LIST_0][j4][i4] = -1;
}
if (l1_rFrame >= 0)
{
if (l1_rFrame==0 && ((!colocated->moving_block[j6][i4])&& (!listX[LIST_1 + list_offset][0]->is_long_term)))
{
motion->mv [LIST_1][j4][i4][0] = 0;
motion->mv [LIST_1][j4][i4][1] = 0;
motion->ref_idx[LIST_1][j4][i4] = 0;
}
else
{
motion->mv [LIST_1][j4][i4][0] = pmvl1[0];
motion->mv [LIST_1][j4][i4][1] = pmvl1[1];
motion->ref_idx[LIST_1][j4][i4] = l1_rFrame;
}
}
else
{
motion->mv [LIST_1][j4][i4][0] = 0;
motion->mv [LIST_1][j4][i4][1] = 0;
motion->ref_idx[LIST_1][j4][i4] = -1;
}
if (l0_rFrame <0 && l1_rFrame <0)
{
motion->ref_idx[LIST_0][j4][i4] = 0;
motion->ref_idx[LIST_1][j4][i4] = 0;
}
}
}
}
}
}
else
{
for (k = 0; k < 4; k++) // Scan all blocks
{
if (currMB->b8mode[k] == 0)
{
for(j0 = 2 * (k >> 1); j0 < 2 * (k >> 1) + 2; j0 += step_v0)
{
for(i0 = img->block_x + 2*(k & 0x01); i0 < img->block_x + 2 * (k & 0x01)+2; i0 += step_h0)
{
int refList = colocated->ref_idx[LIST_0 ][img->block_y_aff + j0][i0]== -1 ? LIST_1 : LIST_0;
int ref_idx = colocated->ref_idx[refList][img->block_y_aff + j0][i0];
int mapped_idx = -1, iref;
if (ref_idx == -1)
{
for (j4 = img->block_y + j0; j4 < img->block_y + j0 + step_v0; j4++)
{
memset(&motion->ref_idx [LIST_0][j4]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -