📄 rdopt.c
字号:
//--- get cost for backward prediction ---
bw_mcost = motion_cost[mode][0][block];
//--- get cost for bidirectional prediction ---
bid_mcost = (input->rdopt ? write_ref ? REF_COST (lambda_motion_factor, best_fw_ref) : 0 : (int)(2*lambda_motion*min(best_fw_ref,1)));
bid_mcost += BIDPartitionCost (mode, block, best_fw_ref, lambda_motion_factor);
//--- get prediction direction ----
if (fw_mcost<=bw_mcost && fw_mcost<=bid_mcost) {best_pdir = 0; cost = fw_mcost; }
else if (bw_mcost<=fw_mcost && bw_mcost<=bid_mcost) {best_pdir = 1; cost = bw_mcost; }
else {best_pdir = 2; cost = bid_mcost;}
} // if (bframe)
else
{
best_pdir = 0;
cost = fw_mcost;
}
} // if (mode!=IBLOCK && mode!=0)
//--- store coding state before coding with current mode ---
store_coding_state (cs_cm);
if (input->rdopt)
{
//--- get and check rate-distortion cost ---
rdcost = RDCost_for_8x8blocks (&cnt_nonz, &curr_cbp_blk, lambda_mode,
block, mode, best_pdir, best_fw_ref);
}
else
{
cost += (REF_COST (lambda_motion_factor, B8Mode2Value (mode, best_pdir)) - 1);
}
//--- set variables if best mode has changed ---
if (( input->rdopt && rdcost < min_rdcost) ||
(!input->rdopt && cost < min_cost ) )
{
min_cost = cost;
min_rdcost = rdcost;
best8x8mode [block] = mode;
best8x8pdir[P8x8][block] = best_pdir;
best8x8ref [P8x8][block] = best_fw_ref;
//--- store number of nonzero coefficients ---
best_cnt_nonz = cnt_nonz;
if (input->rdopt)
{
//--- store block cbp ---
cbp_blk8x8 &= (~(0x33 << (((block>>1)<<3)+((block%2)<<1)))); // delete bits for block
cbp_blk8x8 |= curr_cbp_blk;
//--- store coefficients ---
for (k=0; k< 4; k++)
for (j=0; j< 2; j++)
for (i=0; i<18; i++) cofAC8x8[block][k][j][i] = img->cofAC[block][k][j][i];
//--- store reconstruction and prediction ---
for (j=j0; j<j0+8; j++)
for (i=i0; i<i0+8; i++)
{
rec_mbY8x8[j][i] = imgY[img->pix_y+j][img->pix_x+i];
mpr8x8 [j][i] = img->mpr[i][j];
}
}
//--- store coding state ---
store_coding_state (cs_b8);
} // if (rdcost <= min_rdcost)
//--- re-set coding state as it was before coding with current mode was performed ---
reset_coding_state (cs_cm);
} // if (valid[mode=b8_mode_table[index]])
} // for (min_rdcost=1e30, index=(bframe?0:1); index<6; index++)
cost8x8 += min_cost;
if (!input->rdopt)
{
mode = best8x8mode[block];
pdir = best8x8pdir[P8x8][block];
if (mode!=IBLOCK)
{
curr_cbp_blk = 0;
best_cnt_nonz = LumaResidualCoding8x8 (&dummy, &curr_cbp_blk, block,
(pdir==0||pdir==2?mode:0),
(pdir==1||pdir==2?mode:0),
(mode!=0?best8x8ref[P8x8][block]:max(0,refFrArr[img->block_y+j1][img->block_x+i1])));
cbp_blk8x8 &= (~(0x33 << (((block>>1)<<3)+((block%2)<<1)))); // delete bits for block
cbp_blk8x8 |= curr_cbp_blk;
}
//--- store coefficients ---
for (k=0; k< 4; k++)
for (j=0; j< 2; j++)
for (i=0; i<18; i++) cofAC8x8[block][k][j][i] = img->cofAC[block][k][j][i];
//--- store reconstruction and prediction ---
for (j=j0; j<j0+8; j++)
for (i=i0; i<i0+8; i++)
{
rec_mbY8x8[j][i] = imgY[img->pix_y+j][img->pix_x+i];
mpr8x8 [j][i] = img->mpr[i][j];
}
}
//----- set cbp and count of nonzero coefficients ---
if (best_cnt_nonz)
{
cbp8x8 |= (1<<block);
cnt_nonz_8x8 += (best8x8mode[block]==IBLOCK ? MAX_VALUE : best_cnt_nonz);
}
else if (best8x8mode[block]==IBLOCK && cnt_nonz_8x8)
{
// coefficients cannot be discarded if a following INTRA4x4 blocks needs they for prediction
cnt_nonz_8x8 += MAX_VALUE;
}
if ((mode=best8x8mode[block])!=IBLOCK)
{
//===== reset intra prediction modes (needed for prediction, must be stored after 8x8 mode dec.) =====
j0 = img->block_y+1+2*(block/2);
i0 = img->block_x+1+2*(block%2);
for (j=j0; j<j0+2; j++)
for (i=i0; i<i0+2; i++) img->ipredmode[i][j] = 0;
i0 = 4*block;
for (i=i0; i<i0+4; i++) currMB->intra_pred_modes[i] = 0;
}
if (block<3)
{
//===== set motion vectors and reference frames (prediction) =====
SetRefAndMotionVectors (block, mode, best8x8ref[P8x8][block], best8x8pdir[P8x8][block]);
//===== re-set reconstructed block =====
j0 = 8*(block/2);
i0 = 8*(block%2);
for (j=j0; j<j0+8; j++)
for (i=i0; i<i0+8; i++) imgY[img->pix_y+j][img->pix_x+i] = rec_mbY8x8[j][i];
} // if (block<3)
//===== set the coding state after current block =====
reset_coding_state (cs_b8);
} // for (cbp8x8=cbp_blk8x8=cnt_nonz_8x8=0, block=0; block<4; block++)
//===== store intra prediction modes for 8x8+ macroblock mode =====
for (k=0, j=img->block_y+1; j<img->block_y+5; j++)
for ( i=img->block_x+1; i<img->block_x+5; i++, k++)
{
b8_ipredmode [k] = img ->ipredmode [i][j];
b8_intra_pred_modes[k] = currMB->intra_pred_modes[k];
}
//--- re-set coding state (as it was before 8x8 block coding) ---
reset_coding_state (cs_mb);
}
else // if (valid[P8x8])
{
cost8x8 = (1<<20);
}
//===== MOTION ESTIMATION FOR 16x16, 16x8, 8x16 BLOCKS =====
for (min_cost=cost8x8, best_mode=P8x8, mode=3; mode>0; mode--)
{
if (valid[mode])
{
for (cost=0, block=0; block<(mode==1?1:2); block++)
{
PartitionMotionSearch (mode, block, lambda_motion);
//--- set 4x4 block indizes (for getting MV) ---
j = (block==1 && mode==2 ? 2 : 0);
i = (block==1 && mode==3 ? 2 : 0);
//--- get cost and reference frame for forward prediction ---
for (fw_mcost=max_mcost, ref=0; ref<max_ref; ref++)
{
if (!checkref || ref==0 || CheckReliabilityOfRef (block, ref, mode))
{
mcost = (input->rdopt ? write_ref ? REF_COST (lambda_motion_factor, ref) : 0 : (int)(2*lambda_motion*min(ref,1)));
mcost += motion_cost[mode][ref+1][block];
if (mcost < fw_mcost)
{
fw_mcost = mcost;
best_fw_ref = ref;
}
}
}
if (bframe)
{
//--- get cost for backward prediction ---
bw_mcost = motion_cost[mode][0][block];
//--- get cost for bidirectional prediction ---
bid_mcost = (input->rdopt ? write_ref ? REF_COST (lambda_motion_factor, best_fw_ref) : 0 : (int)(2*lambda_motion*min(best_fw_ref,1)));
bid_mcost += BIDPartitionCost (mode, block, best_fw_ref, lambda_motion_factor);
//--- get prediction direction ----
if (fw_mcost<=bw_mcost && fw_mcost<=bid_mcost) {best_pdir = 0; cost += fw_mcost; }
else if (bw_mcost<=fw_mcost && bw_mcost<=bid_mcost) {best_pdir = 1; cost += bw_mcost; }
else {best_pdir = 2; cost += bid_mcost;}
}
else // if (bframe)
{
best_pdir = 0;
cost += fw_mcost;
}
//----- set reference frame and direction parameters -----
if (mode==3)
{
best8x8ref [3][ block] = best8x8ref [3][ block+2] = best_fw_ref;
best8x8pdir[3][ block] = best8x8pdir[3][ block+2] = best_pdir;
}
else if (mode==2)
{
best8x8ref [2][2*block] = best8x8ref [2][2*block+1] = best_fw_ref;
best8x8pdir[2][2*block] = best8x8pdir[2][2*block+1] = best_pdir;
}
else
{
best8x8ref [1][0] = best8x8ref [1][1] = best8x8ref [1][2] = best8x8ref [1][3] = best_fw_ref;
best8x8pdir[1][0] = best8x8pdir[1][1] = best8x8pdir[1][2] = best8x8pdir[1][3] = best_pdir;
}
//--- set reference frames and motion vectors ---
if (mode>1 && block==0) SetRefAndMotionVectors (block, mode, best_fw_ref, best_pdir);
} // for (block=0; block<(mode==1?1:2); block++)
if (cost < min_cost)
{
best_mode = mode;
min_cost = cost;
}
} // if (valid[mode])
} // for (mode=3; mode>0; mode--)
}
else // if (img->type!=INTRA_IMG)
{
min_cost = (1<<20);
}
if (input->rdopt)
{
//===== GET BEST MACROBLOCK MODE =====
for (ctr16x16=0, min_rdcost=max_rdcost, index=0; index<7; index++)
{
mode = mb_mode_table[index];
//--- for INTER16x16 check all prediction directions ---
if (mode==1 && bframe)
{
best8x8pdir[1][0] = best8x8pdir[1][1] = best8x8pdir[1][2] = best8x8pdir[1][3] = ctr16x16;
if (ctr16x16 < 2) index--;
ctr16x16++;
}
if (valid[mode])
{
if (RDCost_for_macroblocks (lambda_mode, mode, &min_rdcost))
{
store_macroblock_parameters (mode);
}
}
}
}
else
{
if (valid[0] && bframe) // check DIRECT MODE
{
cost = (have_direct?cost_direct:Get_Direct_CostMB (lambda_mode));
cost -= (int)floor(16*lambda_motion+0.4999);
if (cost <= min_cost)
{
min_cost = cost;
best_mode = 0;
}
}
if (valid[I4MB]) // check INTRA4x4
{
currMB->cbp = Mode_Decision_for_Intra4x4Macroblock (lambda_mode, &cost);
if (cost <= min_cost)
{
min_cost = cost;
best_mode = I4MB;
}
}
if (valid[I16MB]) // check INTRA16x16
{
intrapred_luma_2 ();
cost = find_sad2 (&i16mode);
if (cost < min_cost)
{
best_mode = I16MB;
currMB->cbp = dct_luma2 (i16mode);
}
}
}
if (rerun==0)
{
intra1[0] = (currMB->mb_type==I16MB || currMB->b8mode[0]==IBLOCK ? 1 : 0);
intra1[1] = (currMB->mb_type==I16MB || currMB->b8mode[1]==IBLOCK ? 1 : 0);
intra1[2] = (currMB->mb_type==I16MB || currMB->b8mode[2]==IBLOCK ? 1 : 0);
intra1[3] = (currMB->mb_type==I16MB || currMB->b8mode[3]==IBLOCK ? 1 : 0);
}
} // for (rerun=0; rerun<runs; rerun++)
if (input->rdopt)
{
set_stored_macroblock_parameters ();
}
else
{
//===== set parameters for chosen mode =====
SetModesAndRefframeForBlocks (best_mode);
if (best_mode==P8x8)
{
SetCoeffAndReconstruction8x8 (currMB);
}
else
{
if (best_mode!=I4MB)
{
for (k=0, j=img->block_y+1; j<img->block_y+5; j++)
for ( i=img->block_x+1; i<img->block_x+5; i++, k++)
{
img ->ipredmode [i][j] = 0;
currMB->intra_pred_modes[k] = 0;
}
if (best_mode!=I16MB)
{
LumaResidualCoding ();
}
}
}
ChromaResidualCoding (&dummy);
if (best_mode==I16MB)
{
img->i16offset = I16Offset (currMB->cbp, i16mode);
}
SetMotionVectorsMB (currMB, bframe);
//===== check for COPY mode =====
if (img->type==INTER_IMG && best_mode==1 && currMB->cbp==0 &&
refFrArr [img->block_y][img->block_x ]==0 &&
tmp_mv[0][img->block_y][img->block_x+4]==0 &&
tmp_mv[1][img->block_y][img->block_x+4]==0 )
{
currMB->mb_type=currMB->b8mode[0]=currMB->b8mode[1]=currMB->b8mode[2]=currMB->b8mode[3]=0;
}
}
/*
if (input->rdopt==2 && !bframe)
{
for (j=0 ;j<input->NoOfDecoders; j++) DeblockMb(img, decs->decY_best[j], NULL);
}
*/
//===== init and update number of intra macroblocks =====
if (img->current_mb_nr==0) intras=0;
if (img->type==INTER_IMG && IS_INTRA(currMB)) intras++;
//===== Decide if this MB will restrict the reference frames =====
if (input->RestrictRef==1)
{
if (input->rdopt==1)
{
refresh_map[2*img->mb_y ][2*img->mb_x ] = (intra ? 1 : 0);
refresh_map[2*img->mb_y ][2*img->mb_x+1] = (intra ? 1 : 0);
refresh_map[2*img->mb_y+1][2*img->mb_x ] = (intra ? 1 : 0);
refresh_map[2*img->mb_y+1][2*img->mb_x+1] = (intra ? 1 : 0);
}
else if (input->rdopt==2)
{
refresh_map[2*img->mb_y ][2*img->mb_x ] = (intra1[0]==0 && (currMB->mb_type==I16MB || currMB->b8mode[0]==IBLOCK) ? 1 : 0);
refresh_map[2*img->mb_y ][2*img->mb_x+1] = (intra1[1]==0 && (currMB->mb_type==I16MB || currMB->b8mode[1]==IBLOCK) ? 1 : 0);
refresh_map[2*img->mb_y+1][2*img->mb_x ] = (intra1[2]==0 && (currMB->mb_type==I16MB || currMB->b8mode[2]==IBLOCK) ? 1 : 0);
refresh_map[2*img->mb_y+1][2*img->mb_x+1] = (intra1[3]==0 && (currMB->mb_type==I16MB || currMB->b8mode[3]==IBLOCK) ? 1 : 0);
}
}
else if (input->RestrictRef==2)
{
refresh_map[2*img->mb_y ][2*img->mb_x ] = (currMB->mb_type==I16MB || currMB->b8mode[0]==IBLOCK ? 1 : 0);
refresh_map[2*img->mb_y ][2*img->mb_x+1] = (currMB->mb_type==I16MB || currMB->b8mode[1]==IBLOCK ? 1 : 0);
refresh_map[2*img->mb_y+1][2*img->mb_x ] = (currMB->mb_type==I16MB || currMB->b8mode[2]==IBLOCK ? 1 : 0);
refresh_map[2*img->mb_y+1][2*img->mb_x+1] = (currMB->mb_type==I16MB || currMB->b8mode[3]==IBLOCK ? 1 : 0);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -