?? macroblock.c
字號:
readCBPandCoeffsFromNAL(img,inp);
return (((img->type==B_IMG_1) || (img->type==B_IMG_MULT)) ? DECODE_MB_BFRAME : DECODE_MB);
}
/************************************************************************
*
* Name : readMotionInfoFromNAL_Pframe()
*
* Description: Get for a given MB of a P picture the reference frame
* parameter and the motion vectors from the NAL
*
************************************************************************/
void readMotionInfoFromNAL_Pframe(struct img_par *img,struct inp_par *inp)
{
int i,j,k,l,m;
int step_h,step_v;
int curr_mvd;
int mb_nr = img->current_mb_nr;
Macroblock *currMB = &img->mb_data[mb_nr];
SyntaxElement currSE;
Slice *currSlice = img->currentSlice;
DataPartition *dP;
int *partMap = assignSE2partition[inp->partition_mode];
int ref_frame = currMB->ref_frame;
int predframe_no = currMB->predframe_no;
/* keep track of neighbouring macroblocks available for prediction */
int mb_width = img->width/16;
int mb_available_up = (img->mb_y == 0) ? 0 : (img->slice_numbers[mb_nr] == img->slice_numbers[mb_nr-mb_width]);
int mb_available_left = (img->mb_x == 0) ? 0 : (img->slice_numbers[mb_nr] == img->slice_numbers[mb_nr-1]);
int mb_available_upleft = (img->mb_x == 0 || img->mb_y == 0) ? 0 : (img->slice_numbers[mb_nr] == img->slice_numbers[mb_nr-mb_width-1]);
int mb_available_upright = (img->mb_x >= mb_width-1 || img->mb_y == 0) ? 0 : (img->slice_numbers[mb_nr] == img->slice_numbers[mb_nr-mb_width+1]);
/* keep track of neighbouring blocks available for motion vector prediction */
int block_available_up, block_available_left, block_available_upright, block_available_upleft;
int mv_a, mv_b, mv_c, mv_d;
int mvPredType, rFrameL, rFrameU, rFrameUR;
int ie, j4, i4, ii,jj;
int pred_vec=0, vec;
/* If multiple ref. frames, read reference frame for the MB **********************************/
if(img->type==INTER_IMG_MULT)
{
#if TRACE
strcpy(currSE.tracestring, "Reference frame no ");
#endif
currSE.type = SE_REFFRAME;
dP = &(currSlice->partArr[partMap[currSE.type]]);
if (inp->symbol_mode == UVLC)
currSE.mapping = linfo;
else
currSE.reading = readRefFrameFromBuffer_CABAC;
dP->readSyntaxElement(&currSE,img,inp,dP);
predframe_no = currMB->predframe_no = currSE.value1;
ref_frame = currMB->ref_frame = (img->frame_cycle +img->buf_cycle- predframe_no) % img->buf_cycle;
/*!
* \note
* if frame lost occurs within img->buf_cycle frames and buffer of previous
* decoded pictures is still empty, set ref_frame to last decoded
* picture to avoid prediction from unexistent frames.
*/
if (ref_frame > img->number) ref_frame = 0;
/* Update the reference frame information for motion vector prediction */
for (j = 0;j < BLOCK_SIZE;j++)
for (i = 0;i < BLOCK_SIZE;i++)
refFrArr[img->block_y+j][img->block_x+i] = predframe_no;
}
/* read motion vectors ***********************************************************************/
currSE.type = SE_MVD;
dP = &(currSlice->partArr[partMap[currSE.type]]);
if (inp->symbol_mode == UVLC)
currSE.mapping = linfo_mvd;
else
currSE.reading = readMVDFromBuffer_CABAC;
step_h=BLOCK_STEP[img->mb_mode][0]; /* horizontal stepsize */
step_v=BLOCK_STEP[img->mb_mode][1]; /* vertical stepsize */
ie=4-BLOCK_STEP[img->mb_mode][0];
for (j=0; j < BLOCK_SIZE; j += step_v)
{
block_available_up = mb_available_up || (j > 0);
j4=img->block_y+j;
for (i=0;i < BLOCK_SIZE; i += step_h)
{
i4=img->block_x+i;
/* first make mv-prediction */
/* D B C */
/* A X */
/* 1 A, B, D are set to 0 if unavailable */
/* 2 If C is not available it is replaced by D */
block_available_left = mb_available_left || (i > 0);
if (j > 0)
block_available_upright = i != ie ? 1 : 0;
else if (i != ie)
block_available_upright = block_available_up;
else
block_available_upright = mb_available_upright;
if (i > 0)
block_available_upleft = j > 0 ? 1 : block_available_up;
else if (j > 0)
block_available_upleft = block_available_left;
else
block_available_upleft = mb_available_upleft;
mvPredType = MVPRED_MEDIAN;
rFrameL = block_available_left ? refFrArr[j4][i4-1] : -1;
rFrameU = block_available_up ? refFrArr[j4-1][i4] : -1;
rFrameUR = block_available_upright ? refFrArr[j4-1][i4+BLOCK_STEP[img->mb_mode][0]] :
block_available_upleft ? refFrArr[j4-1][i4-1] : -1;
/* Prediction if only one of the neighbors uses the selected reference frame */
if(rFrameL == predframe_no && rFrameU != predframe_no && rFrameUR != predframe_no)
mvPredType = MVPRED_L;
else if(rFrameL != predframe_no && rFrameU == predframe_no && rFrameUR != predframe_no)
mvPredType = MVPRED_U;
else if(rFrameL != predframe_no && rFrameU != predframe_no && rFrameUR == predframe_no)
mvPredType = MVPRED_UR;
/* Directional predictions */
else if(img->mb_mode == 3)
{
if(i == 0)
{
if(rFrameL == predframe_no)
mvPredType = MVPRED_L;
}
else
{
if(rFrameUR == predframe_no)
mvPredType = MVPRED_UR;
}
}
else if(img->mb_mode == 2)
{
if(j == 0)
{
if(rFrameU == predframe_no)
mvPredType = MVPRED_U;
}
else
{
if(rFrameL == predframe_no)
mvPredType = MVPRED_L;
}
}
else if(img->mb_mode == 5 && i == 2)
mvPredType = MVPRED_L;
else if(img->mb_mode == 6 && j == 2)
mvPredType = MVPRED_U;
for (k=0; k < 2; k++)
{
mv_a = block_available_left ? img->mv[i4-1+BLOCK_SIZE][j4][k] : 0;
mv_b = block_available_up ? img->mv[i4+BLOCK_SIZE][j4-1][k] : 0;
mv_d = block_available_upleft ? img->mv[i4-1+BLOCK_SIZE][j4-1][k] : 0;
mv_c = block_available_upright ? img->mv[i4+BLOCK_STEP[img->mb_mode][0]+BLOCK_SIZE][j4-1][k] : mv_d;
switch (mvPredType)
{
case MVPRED_MEDIAN:
if(!(block_available_upleft || block_available_up || block_available_upright))
pred_vec = mv_a;
else
pred_vec =mv_a+mv_b+mv_c-min(mv_a,min(mv_b,mv_c))-max(mv_a,max(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;
}
#if TRACE
sprintf(currSE.tracestring, " MVD");
#endif
img->subblock_x = i; // position used for context determination
img->subblock_y = j; // position used for context determination
currSE.value2 = k; // identifies the component; only used for context determination
dP->readSyntaxElement(&currSE,img,inp,dP);
curr_mvd = currSE.value1;
vec=curr_mvd+pred_vec; /* find motion vector */
for(ii=0;ii<BLOCK_STEP[img->mb_mode][0];ii++)
for(jj=0;jj<BLOCK_STEP[img->mb_mode][1];jj++)
img->mv[i4+ii+BLOCK_SIZE][j4+jj][k]=vec;
/* store (oversampled) mvd */
for (l=0; l < step_v; l++)
for (m=0; m < step_h; m++)
currMB->mvd[0][j+l][i+m][k] = curr_mvd;
}
}
}
}
/************************************************************************
*
* Name : readCBPandCoeffs2NAL()
*
* Description: Get coded block pattern and coefficients (run/level)
* from the NAL
*
************************************************************************/
void readCBPandCoeffsFromNAL(struct img_par *img,struct inp_par *inp)
{
int i,j,k;
int level, run;
int mb_nr = img->current_mb_nr;
int ii,jj;
int i1,j1, m2,jg2;
Macroblock *currMB = &img->mb_data[mb_nr];
int cbp;
SyntaxElement currSE;
Slice *currSlice = img->currentSlice;
DataPartition *dP;
int *partMap = assignSE2partition[inp->partition_mode];
int iii,jjj;
int coef_ctr, len, i0,j0;
int ll;
int scan_loop_ctr;
int block_x,block_y;
int scan_mode, start_scan;
/* read CBP if not new intra mode */
if (img->imod != INTRA_MB_NEW)
{
if (img->imod == INTRA_MB_OLD)
{
if (inp->symbol_mode == UVLC)
currSE.mapping = linfo_cbp_intra;
currSE.type = SE_CBP_INTRA;
}
else
{
if (inp->symbol_mode == UVLC)
currSE.mapping = linfo_cbp_inter;
currSE.type = SE_CBP_INTER;
}
if (inp->symbol_mode == CABAC)
currSE.reading = readCBPFromBuffer_CABAC;
#if TRACE
sprintf(currSE.tracestring, " CBP ");
#endif
dP = &(currSlice->partArr[partMap[currSE.type]]);
dP->readSyntaxElement(&currSE,img,inp,dP);
currMB->cbp = cbp = currSE.value1;
}
else
cbp = currMB->cbp;
for (i=0;i<BLOCK_SIZE;i++)
for (j=0;j<BLOCK_SIZE;j++)
for(iii=0;iii<BLOCK_SIZE;iii++)
for(jjj=0;jjj<BLOCK_SIZE;jjj++)
img->cof[i][j][iii][jjj]=0;/* reset luma coeffs */
if(img->imod==INTRA_MB_NEW) /* read DC coeffs for new intra modes */
{
for (i=0;i<BLOCK_SIZE;i++)
for (j=0;j<BLOCK_SIZE;j++)
img->ipredmode[img->block_x+i+1][img->block_y+j+1]=0;
////////
currSE.type = SE_LUM_DC_INTRA;
dP = &(currSlice->partArr[partMap[currSE.type]]);
if (inp->symbol_mode == UVLC)
currSE.mapping = linfo_levrun_inter;
else
{
currSE.reading = readRunLevelFromBuffer_CABAC;
currSE.context = 3; // for choosing context model
}
//////////////
coef_ctr=-1;
//len = 0; /* just to get inside the loop */
level = 1; /* just to get inside the loop */
//for(k=0;(k<17) && (len!=1);k++)
for(k=0;(k<17) && (level!=0);k++)
{
#if TRACE
sprintf(currSE.tracestring, "DC luma 16x16 ");
#endif
dP->readSyntaxElement(&currSE,img,inp,dP);
level = currSE.value1;
run = currSE.value2;
len = currSE.len;
//if (len != 1) /* leave if len=1 */
if (level != 0) /* leave if len=1 */
{
coef_ctr=coef_ctr+run+1;
i0=SNGL_SCAN[coef_ctr][0];
j0=SNGL_SCAN[coef_ctr][1];
img->cof[i0][j0][0][0]=level;/* add new intra DC coeff */
}
}
itrans_2(img);/* transform new intra DC */
}
if (img->imod == INTRA_MB_OLD && img->qp < 24)
scan_mode=DOUBLE_SCAN;
else
scan_mode=SINGLE_SCAN;
/* luma coefficients */
for (block_y=0; block_y < 4; block_y += 2) /* all modes */
{
for (block_x=0; block_x < 4; block_x += 2)
{
for (j=block_y; j < block_y+2; j++)
{
jj=j/2;
for (i=block_x; i < block_x+2; i++)
{
ii=i/2;
if (img->imod == INTRA_MB_NEW)
start_scan = 1; /* skip DC coeff */
else
start_scan = 0; /* take all coeffs */
if((cbp & (int)pow(2,(ii+2*jj))) != 0) /* are there any coeff in current block at all */
{
if (scan_mode==SINGLE_SCAN)
{
coef_ctr=start_scan-1;
//len = 0; /* just to get inside the loop */
level = 1;
//for(k=start_scan;(k<17) && (len!=1);k++)
for(k=start_scan;(k<17) && (level!=0);k++)
{
if (inp->symbol_mode == UVLC)
currSE.mapping = linfo_levrun_inter;
else
currSE.reading = readRunLevelFromBuffer_CABAC;
/*
* make distinction between INTRA and INTER coded
* luminance coefficients
*/
if (k == 0)
{
if (img->imod == INTRA_MB_OLD || img->imod == INTRA_MB_NEW)
{
currSE.context = 2; // for choosing context model
currSE.type = SE_LUM_DC_INTRA;
}
else
{
currSE.context = 1; // for choosing context model
currSE.type = SE_LUM_DC_INTER;
}
}
else
{
if (img->imod == INTRA_MB_OLD /*|| img->imod == INTRA_MB_NEW*/)
{
currSE.context = 2; // for choosing context model
currSE.type = SE_LUM_AC_INTRA;
}
else if ( img->imod == INTRA_MB_NEW )
{
currSE.context = 4; // for choosing context model
currSE.type = SE_LUM_AC_INTRA;
}
else
{
currSE.context = 1; // for choosing context model
currSE.type = SE_LUM_AC_INTER;
}
}
#if TRACE
sprintf(currSE.tracestring, " Luma sng ");
#endif
dP = &(currSlice->partArr[partMap[currSE.type]]);
dP->readSyntaxElement(&currSE,img,inp,dP);
level = currSE.value1;
run = currSE.value2;
len = currSE.len;
//if (len != 1) /* leave if len=1 */
if (level != 0) /* leave if len=1 */
{
coef_ctr += run+1;
i0=SNGL_SCAN[coef_ctr][0];
j0=SNGL_SCAN[coef_ctr][1];
img->cof[i][j][i0][j0]=level*JQ1[img->qp];
if (level!=0)
{
loopb[img->block_x+i+1][img->block_y+j+1]=max(loopb[img->block_x+i+1][img->block_y+j+1],2);
loopb[img->block_x+i ][img->block_y+j+1]=max(loopb[img->block_x+i ][img->block_y+j+1],1);
loopb[img->block_x+i+1][img->block_y+j ]=max(loopb[img->block_x+i+1][img->block_y+j ],1);
loopb[img->block_x+i+2][img->block_y+j+1]=max(loopb[img->block_x+i+2][img->block_y+j+1],1);
loopb[img->block_x+i+1][img->block_y+j+2]=max(loopb[img->block_x+i+1][img->block_y+j+2],1);
}
}
}
}
else /* double scan (old intra with QP<24*/
{
for(scan_loop_ctr=0;scan_loop_ctr<2;scan_loop_ctr++)
{
coef_ctr=start_scan-1;
//len=0; /* just to get inside the loop */
level=1; /* just to get inside the loop */
//for(k=0; k<9 && len!=1;k++)
for(k=0; k<9 && level!=0;k++)
{
if (inp->symbol_mode == UVLC)
currSE.mapping = linfo_levrun_intra;
else
{
currSE.context = 0; // for choosing context model
currSE.reading = readRunLevelFromBuffer_CABAC;
}
if (k == 0)
currSE.type = SE_LUM_DC_INTRA; /* element is of type DC */
else
currSE.type = SE_LUM_AC_INTRA; /* element is of type AC */
#if TRACE
//sprintf(currSE.tracestring, " Luma dbl ");
sprintf(currSE.tracestring, "Luma dbl(%2d,%2d) ",scan_loop_ctr,k);
#endif
dP = &(currSlice->partArr[partMap[currSE.type]]);
dP->readSyntaxElement(&currSE,img,inp,dP);
level = currSE.value1;
run = currSE.value2;
len = currSE.len;
//if (len != 1) /* leave if len=1 */
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -