📄 rdopt.c
字号:
int Mode_Decision_for_8x8IntraBlocks(int b8,double lambda,int *cost)
{
int nonzero=0;
int cost4x4;
int loc_cost0,loc_cost,best_AVS_cost;
int cbp_blk_part,cbp_blk_mask;
int best_nonzero;
int b8_x,b8_y;
*cost = (int)floor(6.0 * lambda + 0.4999);
loc_cost0 = *cost;
cbp_blk_mask=0x0033;
if(b8&1)cbp_blk_mask<<=2;
if(b8&2)cbp_blk_mask<<=8;
b8_x=(b8&1)<<3;
b8_y=(b8&2)<<2;
best_AVS_cost=0x7FFFFFFFL; //max int value
cbp_blk_part=0;
best_nonzero=0;
nonzero=0;
loc_cost=loc_cost0;
//only one 8x8 mode
if(Mode_Decision_for_AVS_IntraBlocks(b8,lambda,&cost4x4))
nonzero=1;
loc_cost+=cost4x4;
if(loc_cost<best_AVS_cost)
{
//is better than last (or ist first try).
best_AVS_cost=loc_cost;
best_nonzero=nonzero;
}
loc_cost=best_AVS_cost;
nonzero=best_nonzero;
*cost = best_AVS_cost;
return nonzero;
}
/*
*************************************************************************
* Function:4x4 Intra mode decision for an macroblock
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
int Mode_Decision_for_Intra4x4Macroblock (double lambda, int* cost)
{
int cbp=0, b8, cost8x8;
int stage_block8x8_pos=0;/*lgp*/
for (*cost=0, b8=stage_block8x8_pos; b8<4; b8++)
{
if (Mode_Decision_for_8x8IntraBlocks (b8, lambda, &cost8x8))
{
cbp |= (1<<b8);
}
*cost += cost8x8;
}
return cbp;
}
/*
*************************************************************************
* Function:R-D Cost for an 8x8 Partition
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
double RDCost_for_8x8blocks (int* cnt_nonz, // --> number of nonzero coefficients
int* cbp_blk, // --> cbp blk
double lambda, // <-- lagrange multiplier
int block, // <-- 8x8 block number
int mode, // <-- partitioning mode
int pdir, // <-- prediction direction
int ref, // <-- reference frame
int bwd_ref) // <-- abp type
{
int i, j;
int rate=0, distortion=0;
int dummy, mrate;
int fw_mode, bw_mode;
int cbp = 0;
int pax = 8*(block%2);
int pay = 8*(block/2);
int i0 = pax/8;
int j0 = pay/8;
int bframe = (img->type==B_IMG);
int direct = (bframe && mode==0);
int b8value = B8Mode2Value (mode, pdir);
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
SyntaxElement *currSE = &img->MB_SyntaxElements[currMB->currSEnr];
int **frefarr = refFrArr; // For MB level field/frame
int block_y = img->block_y;
int block_x = img->block_x;
int pix_y = img->pix_y;
int pix_x = img->pix_x;
byte **imgY_original = imgY_org;
int incr_y=1,off_y=0;/*lgp*/
//===== GET COEFFICIENTS, RECONSTRUCTIONS, CBP
if (direct)
{
*cnt_nonz = LumaResidualCoding8x8 (&cbp, cbp_blk, block, 0, 0,
max(0,frefarr[block_y+j0][block_x+i0]), 0);
}
else
{
fw_mode = (pdir==0||pdir==2 ? mode : 0);
bw_mode = (pdir==1||pdir==2 ? mode : 0);
*cnt_nonz = LumaResidualCoding8x8 (&cbp, cbp_blk, block, fw_mode, bw_mode, ref, bwd_ref);
}
for (j=0; j<8; j++)/*lgp*/
for (i=pax; i<pax+8; i++)
{
distortion += img->quad [imgY_original[pix_y+pay+/*j*/incr_y*j+off_y/*lgp*/][pix_x+i] - imgY[img->pix_y+pay+/*j*/incr_y*j+off_y/*lgp*/][img->pix_x+i]];
}
//===== GET RATE
//----- block 8x8 mode -----
ue_linfo (b8value, dummy, &mrate, &dummy);
rate += mrate;
//----- motion information -----
if (!direct)
{
if (pdir==0 || pdir==2)
{
rate += writeMotionVector8x8 (i0, j0, i0+1, j0+1, ref, 0, 1, mode);
}
if (pdir==1 || pdir==2)
{
rate += writeMotionVector8x8 (i0, j0, i0+1, j0+1, bwd_ref, 0, 0, mode);
}
}
//----- luminance coefficients -----
if (*cnt_nonz)
{
currMB->cbp = cbp;
rate += writeLumaCoeff8x8 (block, 0);
}
return (double)distortion + lambda * (double)rate;
}
/*
*************************************************************************
* Function:Sets modes and reference frames for an macroblock
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
void SetModesAndRefframeForBlocks (int mode)
{
int i,j,k;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
int bframe = (img->type==B_IMG);
int **fwrefarr = fw_refFrArr;
int **bwrefarr = bw_refFrArr;
int **frefarr = refFrArr;
int block_y = img->block_y;
int block_x = img->block_x;
int stage_block8x8_pos=0;/*lgp*/
//--- macroblock type ---
currMB->mb_type = mode;
//--- block 8x8 mode and prediction direction ---
switch (mode)
{
case 0:
for(i=stage_block8x8_pos/*lgp*/;i<4;i++)
{
currMB->b8mode[i] = 0;
currMB->b8pdir[i] = (bframe?2:0);
}
break;
case 1:
case 2:
case 3:
for(i=stage_block8x8_pos/*lgp*/;i<4;i++)
{
currMB->b8mode[i] = mode;
currMB->b8pdir[i] = best8x8pdir[mode][i];
}
break;
//case 4:
case P8x8:
for(i=stage_block8x8_pos/*lgp*/;i<4;i++)
{
currMB->b8mode[i] = best8x8mode[i];
currMB->b8pdir[i] = best8x8pdir[mode][i];
}
break;
case I4MB:
for(i=stage_block8x8_pos/*lgp*/;i<4;i++)
{
currMB->b8mode[i] = IBLOCK;
currMB->b8pdir[i] = -1;
}
break;
default:
printf ("Unsupported mode in SetModesAndRefframeForBlocks!\n");
exit (1);
}
//--- reference frame arrays ---
if (mode==0 || mode==I4MB)
{
if (bframe)
{
for (j=stage_block8x8_pos/2/*lgp*/;j<2;j++)
for (i=0;i<2;i++)
{
k = 2*j+i;
if(!mode)
{
if(!img->picture_structure)
{
fwrefarr[(block_y>>1)+j][(block_x>>1)+i] = best8x8symref[mode][k][0];
bwrefarr[(block_y>>1)+j][(block_x>>1)+i] = best8x8symref[mode][k][1];
}
else
{
fwrefarr[(block_y>>1)+j][(block_x>>1)+i] = 0;
//sw 11.23
if(img->picture_structure)
bwrefarr[(block_y>>1)+j][(block_x>>1)+i] = 0;// min(frefarr[ipdirect_y][ipdirect_x],0);
else
bwrefarr[(block_y>>1)+j][(block_x>>1)+i] = 0;
}
}
else
{
fwrefarr[(block_y>>1)+j][(block_x>>1)+i] = -1;
bwrefarr[(block_y>>1)+j][(block_x>>1)+i] = -1;
}
}
}
else
{
for (j=stage_block8x8_pos/2;j<2;j++)
for (i=0;i<2;i++)
{
frefarr [(block_y>>1)+j][(block_x>>1)+i] = (mode==0?0:-1);
}
}
}
else
{
if (bframe)
{
for (j=stage_block8x8_pos/2;j<2;j++)
for (i=0;i<2;i++)
{
k = 2*j+i;
if((mode==P8x8) && (best8x8mode[k]==0))
{
if(!img->picture_structure)
{
fwrefarr[(block_y>>1)+j][(block_x>>1)+i] = best8x8symref[0][k][0];
bwrefarr[(block_y>>1)+j][(block_x>>1)+i] = best8x8symref[0][k][1];
}
else
{
fwrefarr[(block_y>>1)+j][(block_x>>1)+i] = 0;
bwrefarr[(block_y>>1)+j][(block_x>>1)+i] = 0;
}
}
else
{
if(IS_FW&&IS_BW)
{
fwrefarr[(block_y>>1)+j][(block_x>>1)+i] = best8x8symref[mode][k][0];
bwrefarr[(block_y>>1)+j][(block_x>>1)+i] = best8x8symref[mode][k][1];
}
else
{
fwrefarr[(block_y>>1)+j][(block_x>>1)+i] = (IS_FW ? best8x8ref[mode][k] : -1);
bwrefarr[(block_y>>1)+j][(block_x>>1)+i] = (IS_BW ? best8x8bwref[mode][k] : -1);
}
}
}
}
else
{
for (j=stage_block8x8_pos/2/*lgp*/;j<2;j++)
for (i=0;i<2;i++)
{
k = 2*j+i;
frefarr [(block_y>>1)+j][(block_x>>1)+i] = (IS_FW ? best8x8ref[mode][k] : -1);
#ifdef BACKGROUND
//for scaling
if(img->type == INTER_IMG && img->typeb == BP_IMG)
frefarr [(block_y>>1)+j][(block_x>>1)+i] = 0;
#endif
}
}
}
}
/*
*************************************************************************
* Function:Sets Coefficients and reconstruction for an 8x8 block
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
void SetCoeffAndReconstruction8x8 (Macroblock* currMB)
{
int block, k, j, i;
int block_x = img->block_x;
int block_y = img->block_y;
int **ipredmodes = img->ipredmode;
int stage_block8x8_pos=0; /*lgp*/
int incr_y=1,off_y=0;/*lgp*/
//--- restore coefficients ---
for (block=0; block<6; block++)
for (k=0; k<4; k++)
for (j=0; j<2; j++)
for (i=0; i<65; i++)
img->cofAC[block][k][j][i] = cofAC8x8[block][k][j][i];
if (cnt_nonz_8x8<=5)/*lgp*/
{
currMB->cbp = 0;
currMB->cbp_blk = 0;
for (j=0; j<16; j++)
for (i=0; i<16; i++)
imgY[img->pix_y+j][img->pix_x+i] = mpr8x8[j][i];
}
else
{
currMB->cbp = cbp8x8;
currMB->cbp_blk = cbp_blk8x8;
for(k=stage_block8x8_pos/2;k<2;k++)
{
for (j=0; j<8; j++)
for (i=0; i<16; i++)
imgY[img->pix_y+k*8+incr_y*j+off_y][img->pix_x+i] = rec_mbY8x8[k*8+incr_y*j+off_y][i];
}
}
//===== restore intra prediction modes for 8x8+ macroblock mode =====
for (j=img->block8_y+1+stage_block8x8_pos/2; j<img->block8_y+3; j++)
for ( i=img->block8_x+1; i<img->block8_x+3; i++)
{
k = (j-img->block8_y-1)*2 + i -img->block8_x -1;
ipredmodes [i][j] = b8_ipredmode [k];
currMB->intra_pred_modes[k] = b8_intra_pred_modes[k];
}
}
/*
*************************************************************************
* Function:Sets motion vectors for an macroblock
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
void SetMotionVectorsMB (Macroblock* currMB, int bframe)
{
int i, j, k, mode8, pdir8, ref, by, bx, bxr, dref;
int ***mv = tmp_mv;
int *****all_mv = img->all_mv;
int *****all_bmv = img->all_bmv;
int ***fwMV = tmp_fwMV;
int ***bwMV = tmp_bwMV;
int *****imgmv = img->mv;
int *****p_fwMV = img->p_fwMV;
int *****p_bwMV = img->p_bwMV;
int **refar = refFrArr;
int **frefar = fw_refFrArr;
int block_y = img->block_y>>1;
int block_x = img->block_x>>1;
int **brefar = bw_refFrArr;
int bw_ref;
int stage_block8x8_pos=0;/*lgp*/
for (j=stage_block8x8_pos/2/*lgp*/;j<2;j++)
for (i=0; i<2; i++)
{
mode8 = currMB->b8mode[k=2*j+i];
pdir8 = currMB->b8pdir[k];
if(pdir8 == 2 && mode8 != 0) //mode8 != 0 added by xyji 07.11
{
//sw 10.1
all_mv = img->all_omv;
p_fwMV = img->omv;
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -