📄 rdopt.c
字号:
{
pres_y = dy == 1 ? y : y + 1;
pres_y = iClip3(0,maxold_y,pres_y);
for(xx=-2;xx<4;xx++)
{
pres_x = iClip3(0,maxold_x,xx + x);
if (pixel_map[pres_y][pres_x] < ref_frame)
return 0;
}
pres_x = dx == 1 ? x : x + 1;
pres_x = iClip3(0,maxold_x,pres_x);
for(yy=-2;yy<4;yy++)
{
pres_y = iClip3(0,maxold_y, yy + y);
if (pixel_map[pres_y][pres_x] < ref_frame)
return 0;
}
}
}
}
}
}
}
return 1;
}
/*!
*************************************************************************************
* \brief
* R-D Cost for an 4x4 Intra block
*************************************************************************************
*/
double RDCost_for_4x4IntraBlocks (Macroblock *currMB,
int* nonzero,
int b8,
int b4,
int ipmode,
double lambda,
int mostProbableMode,
int c_nzCbCr[3],
int is_cavlc)
{
double rdcost;
int dummy = 0, rate;
int64 distortion = 0;
int block_x = ((b8 & 0x01) << 3) + ((b4 & 0x01) << 2);
int block_y = ((b8 >> 1) << 3) + ((b4 >> 1) << 2);
int pic_pix_x = img->pix_x + block_x;
int pic_pix_y = img->pix_y + block_y;
int pic_opix_y = img->opix_y + block_y;
Slice *currSlice = img->currentSlice;
SyntaxElement se;
const int *partMap = assignSE2partition[params->partition_mode];
DataPartition *dataPart;
//===== perform DCT, Q, IQ, IDCT, Reconstruction =====
//select_dct(img, currMB);
*nonzero = pDCT_4x4 (currMB, PLANE_Y, block_x, block_y, &dummy, 1, is_cavlc);
//===== get distortion (SSD) of 4x4 block =====
distortion += compute_SSE(&pCurImg[pic_opix_y], &enc_picture->imgY[pic_pix_y], pic_pix_x, pic_pix_x, 4, 4);
if(img->P444_joined)
{
ColorPlane k;
for (k = PLANE_U; k <= PLANE_V; k++)
{
select_plane(k);
c_nzCbCr[k] = pDCT_4x4(currMB, k, block_x, block_y, &dummy, 1, is_cavlc);
distortion += compute_SSE(&pCurImg[pic_opix_y], &enc_picture->p_curr_img[pic_pix_y], pic_pix_x, pic_pix_x, 4, 4);
}
select_plane(PLANE_Y);
}
ipmode_DPCM=NO_INTRA_PMODE;
//===== RATE for INTRA PREDICTION MODE (SYMBOL MODE MUST BE SET TO CAVLC) =====
se.value1 = (mostProbableMode == ipmode) ? -1 : ipmode < mostProbableMode ? ipmode : ipmode - 1;
//--- set position and type ---
se.context = (b8 << 2) + b4;
se.type = SE_INTRAPREDMODE;
//--- choose data partition ---
dataPart = &(currSlice->partArr[partMap[SE_INTRAPREDMODE]]);
//--- encode and update rate ---
writeIntraPredMode (&se, dataPart);
rate = se.len;
//===== RATE for LUMINANCE COEFFICIENTS =====
if (is_cavlc)
{
rate += writeCoeff4x4_CAVLC (currMB, LUMA, b8, b4, 0);
if(img->P444_joined)
{
rate += writeCoeff4x4_CAVLC (currMB, CB, b8, b4, 0);
rate += writeCoeff4x4_CAVLC (currMB, CR, b8, b4, 0);
}
}
else
{
rate += writeCoeff4x4_CABAC (currMB, PLANE_Y, b8, b4, 1);
if(img->P444_joined)
{
rate += writeCoeff4x4_CABAC (currMB, PLANE_U, b8, b4, 1);
rate += writeCoeff4x4_CABAC (currMB, PLANE_V, b8, b4, 1);
}
}
//reset_coding_state (currMB, cs_cm);
rdcost = (double)distortion + lambda * (double) rate;
return rdcost;
}
/*!
*************************************************************************************
* \brief
* R-D Cost for an 8x8 Partition
*************************************************************************************
*/
double RDCost_for_8x8blocks (Macroblock *currMB, // --> Current macroblock to code
int* cnt_nonz, // --> number of nonzero coefficients
int64* cbp_blk, // --> cbp blk
double lambda, // <-- lagrange multiplier
int block, // <-- 8x8 block number
int mode, // <-- partitioning mode
short pdir, // <-- prediction direction
short l0_ref, // <-- L0 reference picture
short l1_ref, // <-- L1 reference picture
short bipred_me, // <-- bi prediction mode
int is_cavlc
)
{
int k;
int rate=0;
int64 distortion=0;
int dummy = 0, mrate;
int fw_mode, bw_mode;
int cbp = 0;
int pax = 8*(block & 0x01);
int pay = 8*(block >> 1);
int i0 = pax >> 2;
int j0 = pay >> 2;
int bframe = (img->type==B_SLICE);
int direct = (bframe && mode==0);
int b8value = B8Mode2Value (mode, pdir);
SyntaxElement se;
Slice *currSlice = img->currentSlice;
DataPartition *dataPart;
const int *partMap = assignSE2partition[params->partition_mode];
EncodingEnvironmentPtr eep_dp;
//=====
//===== GET COEFFICIENTS, RECONSTRUCTIONS, CBP
//=====
currMB->bipred_me[block] = bipred_me;
if (direct)
{
if (direct_pdir[img->block_y+j0][img->block_x+i0]<0) // mode not allowed
return (1e20);
else
*cnt_nonz = LumaResidualCoding8x8 (currMB, &cbp, cbp_blk, block, direct_pdir[img->block_y+j0][img->block_x+i0], 0, 0,
(short)imax(0,direct_ref_idx[LIST_0][img->block_y+j0][img->block_x+i0]),
direct_ref_idx[LIST_1][img->block_y+j0][img->block_x+i0], is_cavlc);
}
else
{
if (pdir == 2 && active_pps->weighted_bipred_idc == 1)
{
int weight_sum = (active_pps->weighted_bipred_idc == 1)? wbp_weight[0][l0_ref][l1_ref][0] + wbp_weight[1][l0_ref][l1_ref][0] : 0;
if (weight_sum < -128 || weight_sum > 127)
{
return (1e20);
}
}
fw_mode = (pdir==0||pdir==2 ? mode : 0);
bw_mode = (pdir==1||pdir==2 ? mode : 0);
*cnt_nonz = LumaResidualCoding8x8 (currMB, &cbp, cbp_blk, block, pdir, fw_mode, bw_mode, l0_ref, l1_ref, is_cavlc);
}
if(img->P444_joined)
{
*cnt_nonz += ( coeff_cost_cr[1] + coeff_cost_cr[2] );
}
// RDOPT with losses
if (params->rdopt==3 && img->type!=B_SLICE)
{
//===== get residue =====
// We need the reconstructed prediction residue for the simulated decoders.
//compute_residue_b8block (img, &enc_picture->p_img[0][img->pix_y], decs->res_img[0], block, -1);
compute_residue_block (img, &enc_picture->p_img[0][img->pix_y], decs->res_img[0], img->mb_pred[0], block, 8);
//=====
//===== GET DISTORTION
//=====
for (k=0; k<params->NoOfDecoders ;k++)
{
decode_one_b8block (img, enc_picture, k, P8x8, block, mode, l0_ref);
distortion += compute_SSE(&pCurImg[img->opix_y+pay], &enc_picture->p_dec_img[0][k][img->opix_y+pay], img->opix_x+pax, img->opix_x+pax, 8, 8);
}
distortion /= params->NoOfDecoders;
}
else
{
distortion += compute_SSE(&pCurImg[img->opix_y + pay], &enc_picture->imgY[img->pix_y + pay], img->opix_x + pax, img->pix_x + pax, 8, 8);
if (img->P444_joined)
{
distortion += compute_SSE(&pImgOrg[1][img->opix_y + pay], &enc_picture->imgUV[0][img->pix_y + pay], img->opix_x + pax, img->pix_x + pax, 8, 8);
distortion += compute_SSE(&pImgOrg[2][img->opix_y + pay], &enc_picture->imgUV[1][img->pix_y + pay], img->opix_x + pax, img->pix_x + pax, 8, 8);
}
}
if(img->P444_joined)
{
cbp |= cmp_cbp[1];
cbp |= cmp_cbp[2];
cmp_cbp[1] = cbp;
cmp_cbp[2] = cbp;
}
//=====
//===== GET RATE
//=====
//----- block 8x8 mode -----
if (is_cavlc)
{
ue_linfo (b8value, dummy, &mrate, &dummy);
rate += mrate;
}
else
{
se.value1 = b8value;
se.type = SE_MBTYPE;
dataPart = &(currSlice->partArr[partMap[se.type]]);
writeB8_typeInfo(&se, dataPart);
rate += se.len;
}
//----- motion information -----
if (!direct)
{
if ((img->num_ref_idx_l0_active > 1 ) && (pdir==0 || pdir==2))
rate += writeReferenceFrame (currMB, mode, i0, j0, 1, l0_ref);
if ((img->num_ref_idx_l1_active > 1 && img->type== B_SLICE ) && (pdir==1 || pdir==2))
{
rate += writeReferenceFrame (currMB, mode, i0, j0, 0, l1_ref);
}
if (pdir==0 || pdir==2)
{
rate += writeMotionVector8x8 (currMB, i0, j0, i0 + 2, j0 + 2, l0_ref, LIST_0, mode, currMB->bipred_me[block]);
}
if (pdir==1 || pdir==2)
{
rate += writeMotionVector8x8 (currMB, i0, j0, i0 + 2, j0 + 2, l1_ref, LIST_1, mode, currMB->bipred_me[block]);
}
}
//----- coded block pattern (for CABAC only) -----
if (!is_cavlc)
{
dataPart = &(currSlice->partArr[partMap[SE_CBP]]);
eep_dp = &(dataPart->ee_cabac);
mrate = arienco_bits_written (eep_dp);
writeCBP_BIT_CABAC (currMB, block, ((*cnt_nonz>0)?1:0), cbp8x8, 1, eep_dp, img->currentSlice->tex_ctx);
mrate = arienco_bits_written (eep_dp) - mrate;
rate += mrate;
}
//----- luminance coefficients -----
if (*cnt_nonz)
{
rate += writeCoeff8x8 (currMB, PLANE_Y, block, mode, currMB->luma_transform_size_8x8_flag);
}
if(img->P444_joined)
{
rate += writeCoeff8x8( currMB, PLANE_U, block, mode, currMB->luma_transform_size_8x8_flag );
rate += writeCoeff8x8( currMB, PLANE_V, block, mode, currMB->luma_transform_size_8x8_flag );
}
return (double)distortion + lambda * (double)rate;
}
/*!
*************************************************************************************
* \brief
* Gets mode offset for intra16x16 mode
*************************************************************************************
*/
int I16Offset (int cbp, int i16mode)
{
return (cbp&15?13:1) + i16mode + ((cbp&0x30)>>2);
}
/*!
*************************************************************************************
* \brief
* Sets modes and reference frames for a macroblock
*************************************************************************************
*/
void SetModesAndRefframeForBlocks (Macroblock *currMB, int mode)
{
int i,j,k,l;
int bframe = (img->type==B_SLICE);
int block_x, block_y, block8x8, block4x4;
int cur_ref;
int clist;
char cref[2], curref, bestref;
Block8x8Info *b8x8info = img->b8x8info;
//--- macroblock type ---
currMB->mb_type = mode;
for( i = 0; i < 4; i++)
{
currMB->bipred_me[i] = b8x8info->bipred8x8me[mode][i];
}
//--- block 8x8 mode and prediction direction ---
switch (mode)
{
case 0:
memset(currMB->b8mode, 0, 4 * sizeof(short));
if (bframe)
{
for(i=0;i<4;i++)
{
currMB->b8pdir[i] = direct_pdir[img->block_y + ((i >> 1)<<1)][img->block_x + ((i & 0x01)<<1)];
}
}
else
{
memset(currMB->b8pdir, 0, 4 * sizeof(short));
}
break;
case 1:
case 2:
case 3:
for(i=0;i<4;i++)
{
currMB->b8mode[i] = mode;
currMB->b8pdir[i] = b8x8info->best8x8pdir[mode][i];
}
break;
case P8x8:
memcpy(currMB->b8mode, b8x8info->best8x8mode, 4 * sizeof(short));
for(i=0;i<4;i++)
{
currMB->b8pdir[i] = b8x8info->best8x8pdir[mode][i];
}
break;
case I4MB:
for(i=0;i<4;i++)
{
currMB->b8mode[i] = IBLOCK;
currMB->b8pdir[i] = -1;
}
break;
case I16MB:
memset(currMB->b8mode, 0, 4 * sizeof(short));
for(i=0;i<4;i++)
{
currMB->b8pdir[i] = -1;
}
break;
case I8MB:
for(i=0;i<4;i++)
{
currMB->b8mode[i] = I8MB;
currMB->b8pdir[i] = -1;
}
//switch to 8x8 transform
currMB->luma_transform_size_8x8_flag = 1;
break;
case IPCM:
for(i=0;i<4;i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -