📄 rdopt.c
字号:
}
else
{
for (y = y_pos ; y < y_pos + BLOCK_SIZE ; y++)
{
for (x = x_pos ; x < x_pos + BLOCK_SIZE ; x++)
{
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 (int* nonzero,
int b8,
int b4,
int ipmode,
double lambda,
double min_rdcost,
int mostProbableMode)
{
double rdcost;
int dummy, x, y, rate;
int64 distortion = 0;
int block_x = 8*(b8 & 0x01)+4*(b4 & 0x01);
int block_y = 8*(b8 >> 1)+4*(b4 >> 1);
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;
imgpel **imgY = enc_picture->imgY;
Slice *currSlice = img->currentSlice;
SyntaxElement se;
const int *partMap = assignSE2partition[input->partition_mode];
DataPartition *dataPart;
//===== perform DCT, Q, IQ, IDCT, Reconstruction =====
dummy = 0;
if(img->type!=SP_SLICE)
*nonzero = dct_luma (block_x, block_y, &dummy, 1);
else if(!si_frame_indicator && !sp2_frame_indicator)
{
*nonzero = dct_luma_sp(block_x, block_y, &dummy);
}
else
{
*nonzero = dct_luma_sp2(block_x, block_y, &dummy);
}
//===== get distortion (SSD) of 4x4 block =====
for (y=0; y<4; y++)
{
for (x=pic_pix_x; x<pic_pix_x+4; x++)
{
distortion += iabs2( imgY_org[pic_opix_y+y][x] - imgY[pic_pix_y+y][x] );
}
}
//===== RATE for INTRA PREDICTION MODE (SYMBOL MODE MUST BE SET TO UVLC) =====
se.value1 = (mostProbableMode == ipmode) ? -1 : ipmode < mostProbableMode ? ipmode : ipmode-1;
//--- set position and type ---
se.context = 4*b8 + 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 (input->symbol_mode == UVLC)
{
rate += writeCoeff4x4_CAVLC (LUMA, b8, b4, 0);
}
else
{
rate += writeLumaCoeff4x4_CABAC (b8, b4, 1);
}
//reset_coding_state (cs_cm);
rdcost = (double)distortion + lambda*(double)rate;
return rdcost;
}
/*!
*************************************************************************************
* \brief
* Mode Decision for an 4x4 Intra block
*************************************************************************************
*/
int Mode_Decision_for_4x4IntraBlocks (int b8, int b4, double lambda, int* min_cost)
{
int ipmode, best_ipmode = 0, i, j, k, y, cost, dummy;
int c_nz, nonzero = 0;
imgpel rec4x4[4][4];
double rdcost;
int block_x = 8 * (b8 & 0x01) + 4 * (b4 & 0x01);
int block_y = 8 * (b8 >> 1) + 4 * (b4 >> 1);
int pic_pix_x = img->pix_x + block_x;
int pic_pix_y = img->pix_y + block_y;
int pic_opix_x = img->opix_x + block_x;
int pic_opix_y = img->opix_y + block_y;
int pic_block_x = pic_pix_x >> 2;
int pic_block_y = pic_pix_y >> 2;
double min_rdcost = 1e30;
int left_available, up_available, all_available;
char upMode;
char leftMode;
int mostProbableMode;
PixelPos left_block;
PixelPos top_block;
int lrec4x4[4][4];
int fixedcost = (int) floor(4 * lambda );
#ifdef BEST_NZ_COEFF
int best_nz_coeff = 0;
int best_coded_block_flag = 0;
int bit_pos = 1 + ((((b8>>1)<<1)+(b4>>1))<<2) + (((b8&1)<<1)+(b4&1));
static int64 cbp_bits;
if (b8==0 && b4==0)
cbp_bits = 0;
#endif
getLuma4x4Neighbour(img->current_mb_nr, block_x - 1, block_y, &left_block);
getLuma4x4Neighbour(img->current_mb_nr, block_x, block_y-1, &top_block);
// constrained intra pred
if (input->UseConstrainedIntraPred)
{
left_block.available = left_block.available ? img->intra_block[left_block.mb_addr] : 0;
top_block.available = top_block.available ? img->intra_block[top_block.mb_addr] : 0;
}
upMode = top_block.available ? img->ipredmode[top_block.pos_y ][top_block.pos_x ] : -1;
leftMode = left_block.available ? img->ipredmode[left_block.pos_y][left_block.pos_x] : -1;
mostProbableMode = (upMode < 0 || leftMode < 0) ? DC_PRED : upMode < leftMode ? upMode : leftMode;
*min_cost = INT_MAX;
//===== INTRA PREDICTION FOR 4x4 BLOCK =====
intrapred_luma (pic_pix_x, pic_pix_y, &left_available, &up_available, &all_available);
//===== LOOP OVER ALL 4x4 INTRA PREDICTION MODES =====
for (ipmode=0; ipmode<NO_INTRA_PMODE; ipmode++)
{
int available_mode = (ipmode==DC_PRED) ||
((ipmode==VERT_PRED||ipmode==VERT_LEFT_PRED||ipmode==DIAG_DOWN_LEFT_PRED) && up_available ) ||
((ipmode==HOR_PRED||ipmode==HOR_UP_PRED) && left_available ) ||(all_available);
if (input->IntraDisableInterOnly==0 || img->type != I_SLICE)
{
if (input->Intra4x4ParDisable && (ipmode==VERT_PRED||ipmode==HOR_PRED))
continue;
if (input->Intra4x4DiagDisable && (ipmode==DIAG_DOWN_LEFT_PRED||ipmode==DIAG_DOWN_RIGHT_PRED))
continue;
if (input->Intra4x4DirDisable && ipmode>=VERT_RIGHT_PRED)
continue;
}
if( available_mode)
{
if (!input->rdopt)
{
for (k=j=0; j<4; j++)
{
int jj = pic_opix_y+j;
for (i=0; i<4; i++, k++)
{
diff[k] = imgY_org[jj][pic_opix_x+i] - img->mprr[ipmode][j][i];
}
}
cost = (ipmode == mostProbableMode) ? 0 : fixedcost;
cost += distortion4x4 (diff);
if (cost < *min_cost)
{
best_ipmode = ipmode;
*min_cost = cost;
}
}
else
{
// get prediction and prediction error
for (j=0; j<4; j++)
{
memcpy(&img->mpr[block_y+j][block_x], img->mprr[ipmode][j], BLOCK_SIZE * sizeof(imgpel));
for (i=0; i<4; i++)
{
img->m7[j][i] = (int) (imgY_org[pic_opix_y+j][pic_opix_x+i] - img->mprr[ipmode][j][i]);
}
}
//===== store the coding state =====
//store_coding_state (cs_cm);
// get and check rate-distortion cost
#ifdef BEST_NZ_COEFF
img->mb_data[img->current_mb_nr].cbp_bits = cbp_bits;
#endif
if ((rdcost = RDCost_for_4x4IntraBlocks (&c_nz, b8, b4, ipmode, lambda, min_rdcost, mostProbableMode)) < min_rdcost)
{
//--- set coefficients ---
memcpy(cofAC4x4[0],img->cofAC[b8][b4][0], 18 * sizeof(int));
memcpy(cofAC4x4[1],img->cofAC[b8][b4][1], 18 * sizeof(int));
//--- set reconstruction ---
for (y=0; y<4; y++)
{
memcpy(rec4x4[y],&enc_picture->imgY[pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(imgpel));
if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator))
memcpy(lrec4x4[y],&lrec[pic_pix_y+y][pic_pix_x], BLOCK_SIZE * sizeof(int));// stores the mode coefficients
}
//--- flag if dct-coefficients must be coded ---
nonzero = c_nz;
//--- set best mode update minimum cost ---
min_rdcost = rdcost;
best_ipmode = ipmode;
#ifdef BEST_NZ_COEFF
best_nz_coeff = img->nz_coeff [img->current_mb_nr][block_x4][block_y4];
best_coded_block_flag = (int)((img->mb_data[img->current_mb_nr].cbp_bits>>bit_pos)&(int64)(1));
#endif
//store_coding_state (cs_ib4);
if (img->AdaptiveRounding)
{
for (j=0; j<4; j++)
memcpy(&fadjust4x4[block_y+j][block_x],&img->fadjust4x4[1][block_y+j][block_x], BLOCK_SIZE * sizeof(int));
}
}
#ifndef RESET_STATE
reset_coding_state (cs_cm);
#endif
}
}
}
#ifdef BEST_NZ_COEFF
img->nz_coeff [img->current_mb_nr][block_x4][block_y4] = best_nz_coeff;
cbp_bits &= (~(int64)(1<<bit_pos));
cbp_bits |= (int64)(best_coded_block_flag<<bit_pos);
#endif
//===== set intra mode prediction =====
img->ipredmode[pic_block_y][pic_block_x] = (char) best_ipmode;
img->mb_data[img->current_mb_nr].intra_pred_modes[4*b8+b4] =
(char) (mostProbableMode == best_ipmode ? -1 : (best_ipmode < mostProbableMode ? best_ipmode : best_ipmode-1));
if (!input->rdopt)
{
// get prediction and prediction error
for (j=0; j<4; j++)
{
int jj = pic_opix_y+j;
for (i=0; i<4; i++)
{
img->mpr[block_y+j][block_x+i] = img->mprr[best_ipmode][j][i];
img->m7[j][i] = imgY_org[jj][pic_opix_x+i] - img->mprr[best_ipmode][j][i];
}
}
nonzero = dct_luma (block_x, block_y, &dummy, 1);
}
else
{
//===== restore coefficients =====
for (j=0; j<2; j++)
{
memcpy (img->cofAC[b8][b4][j],cofAC4x4[j], 18 * sizeof(int));
}
//===== restore reconstruction and prediction (needed if single coeffs are removed) =====
for (y=0; y<BLOCK_SIZE; y++)
{
memcpy (&enc_picture->imgY[pic_pix_y+y][pic_pix_x],rec4x4[y], BLOCK_SIZE * sizeof(imgpel));
memcpy (&img->mpr[block_y+y][block_x],img->mprr[best_ipmode][y], BLOCK_SIZE * sizeof(imgpel));
if(img->type==SP_SLICE &&(!si_frame_indicator && !sp2_frame_indicator))
memcpy (&lrec[pic_pix_y+y][pic_pix_x],lrec4x4[y], BLOCK_SIZE * sizeof(int));//restore coefficients when encoding primary SP frame
}
if (img->AdaptiveRounding)
{
for (j=0; j<BLOCK_SIZE; j++)
memcpy (&img->fadjust4x4[1][block_y+j][block_x],&fadjust4x4[block_y+j][block_x], BLOCK_SIZE * sizeof(int));
}
}
return nonzero;
}
/*!
*************************************************************************************
* \brief
* Mode Decision for an 8x8 Intra block
*************************************************************************************
*/
int Mode_Decision_for_8x8IntraBlocks(int b8,double lambda,int *cost)
{
int nonzero=0, b4;
int cost4x4;
*cost = (int)floor(6.0 * lambda + 0.4999);
for (b4=0; b4<4; b4++)
{
if (Mode_Decision_for_4x4IntraBlocks (b8, b4, lambda, &cost4x4))
{
nonzero = 1;
}
*cost += cost4x4;
}
#ifdef RESET_STATE
//reset_coding_state (cs_cm);
#endif
return nonzero;
}
/*!
*************************************************************************************
* \brief
* 4x4 Intra mode decision for an macroblock
*************************************************************************************
*/
int Mode_Decision_for_Intra4x4Macroblock (double lambda, int* cost)
{
int cbp=0, b8, cost8x8;
for (*cost=0, b8=0; b8<4; b8++)
{
if (Mode_Decision_for_8x8IntraBlocks (b8, lambda, &cost8x8))
{
cbp |= (1<<b8);
}
*cost += cost8x8;
}
return cbp;
}
/*!
*************************************************************************************
* \brief
* R-D Cost for an 8x8 Partition
*************************************************************************************
*/
double RDCost_for_8x8blocks (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
{
int i, j, 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);
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -