📄 rdopt.c
字号:
#endif
//===== SET VALID MODES =====
valid[I4MB] = 1;
valid[I16MB] = 0;//Lou
valid[0] = (!intra );
valid[1] = (!intra && input->InterSearch16x16);
valid[2] = (!intra && input->InterSearch16x8);
valid[3] = (!intra && input->InterSearch8x16);
valid[4] = (!intra && input->InterSearch8x8);
valid[5] = 0;
valid[6] = 0;
valid[7] = 0;
valid[P8x8] = (valid[4] || valid[5] || valid[6] || valid[7]);
//===== SET LAGRANGE PARAMETERS =====
if (input->rdopt)
{
qp = (double)img->qp - SHIFT_QP;
if (input->successive_Bframe>0)
//Lou 1014 lambda_mode = 0.68 * pow (2, qp/3.0) * (img->type==B_IMG? max(2.00,min(4.00,(qp / 6.0))):1.0);
lambda_mode = 0.68 * pow (2, qp/4.0) * (img->type==B_IMG? max(2.00,min(4.00,(qp / 8.0))):1.0);
else
//Lou 1014 lambda_mode = 0.85 * pow (2, qp/3.0) * (img->type==B_IMG? 4.0:1.0);
lambda_mode = 0.85 * pow (2, qp/4.0) * (img->type==B_IMG? 4.0:1.0);
lambda_motion = sqrt (lambda_mode);
}
else
{
lambda_mode = lambda_motion = QP2QUANT[max(0,img->qp-SHIFT_QP)];
}
lambda_motion_factor = LAMBDA_FACTOR (lambda_motion);
// reset chroma intra predictor to default
currMB->c_ipred_mode = DC_PRED_8;
if (!intra)
{
//===== set direct motion vectors =====
if (bframe)
{
Get_IP_direct();
}
#ifdef FastME
cost8x8 = 1<<20;
//===== MOTION ESTIMATION FOR 16x16, 16x8, 8x16 BLOCKS =====
for (min_cost=cost8x8, best_mode=P8x8, mode=1; mode<4; mode++)
{
if (valid[mode])
{
for (cost=0, block=stage_block8x8_pos/2; block<(mode==1?1:2); block++)
//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 ---
if(img->type==INTER_IMG)/*lgp*/
{
for (fw_mcost=max_mcost, ref=0; ref<max_ref-adjust_ref; ref++)
{
//if (!checkref || ref==0)/*lgp*13*/
{
mcost = (input->rdopt ? write_ref ? REF_COST_FWD (lambda_motion_factor, ref) : 0 : (int)(2*lambda_motion*min(ref,1)));
mcost += motion_cost[mode][ref+/*1*/1/*lgp*13*/][block];
if (mcost < fw_mcost)
{
fw_mcost = mcost;
best_fw_ref = ref;
}
}
}
best_bw_ref = 0;//xyji
}
else
{
for (fw_mcost=max_mcost, ref=0; ref<max_ref-adjust_ref; ref++)
{
//if (!checkref || ref==0)/*lgp*13*/
{
//mcost = (input->rdopt ? write_ref ? REF_COST_FWD (lambda_motion_factor, ref) : 0 : (int)(2*lambda_motion*min(ref,1)));
mcost = motion_cost[mode][img->picture_structure ? ref+1 : ref+2][block];
if (mcost < fw_mcost)
{
fw_mcost = mcost;
best_fw_ref = ref;
}
}
}
best_bw_ref = 0;
}
if (bframe)
{
//--- get cost for bidirectional prediction ---
PartitionMotionSearch_bid (mode, block, lambda_motion);
best_bw_ref = 0;
bw_mcost = motion_cost[mode][0][block];
for (bw_mcost=max_mcost, ref=0; ref<max_ref-adjust_ref; ref++)
{
//if (!checkref || ref==0)/*lgp*13*/
{
//mcost = (input->rdopt ? write_ref ? REF_COST_FWD (lambda_motion_factor, ref) : 0 : (int)(2*lambda_motion*min(ref,1)));
mcost = motion_cost[mode][ref][block];
if (mcost < bw_mcost)
{
bw_mcost = mcost;
best_bw_ref = ref;
}
}
}
for (bid_mcost=max_mcost, ref=0; ref<max_ref-adjust_ref; ref++)
{
//if (!checkref || ref==0)/*lgp*13*/
{
//mcost = (input->rdopt ? write_ref ? REF_COST_FWD (lambda_motion_factor, ref) : 0 : (int)(2*lambda_motion*min(ref,1)));
mcost = motion_cost_bid[mode][img->picture_structure ? ref+1 : ref+2][block];
if (mcost < bid_mcost)
{
bid_mcost = mcost;
bid_best_fw_ref = ref;
bid_best_bw_ref = ref;
}
}
}
//--- get prediction direction ----
if (fw_mcost<=bw_mcost && fw_mcost<=bid_mcost)
{
best_pdir = 0;
best_bw_ref = 0;
cost += fw_mcost;
}
else if (bw_mcost<=fw_mcost && bw_mcost<=bid_mcost)
{
best_pdir = 1;
cost += bw_mcost;
best_fw_ref = 0;/*lgp*13*/
}
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;
best8x8bwref [3][block] = best8x8bwref [3][block+2] = best_bw_ref;
best8x8symref [3][block][0] = best8x8symref [3][block+2][0] = bid_best_fw_ref;
best8x8symref [3][block][1] = best8x8symref [3][block+2][1] = bid_best_bw_ref;
}
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;
best8x8bwref [2][2*block] = best8x8bwref [2][2*block+1] = best_bw_ref;
best8x8symref [2][2*block][0] = best8x8symref [2][2*block+1][0] = bid_best_fw_ref;
best8x8symref [2][2*block][1] = best8x8symref [2][2*block+1][1] = bid_best_bw_ref;
}
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;
best8x8bwref [1][0] = best8x8bwref [1][1] = best8x8bwref [1][2] = best8x8bwref [1][3] = best_bw_ref;
best8x8symref [1][0][0] = best8x8symref [1][1][0] = best8x8symref [1][2][0] = best8x8symref [1][3][0] = bid_best_fw_ref;
best8x8symref [1][0][1] = best8x8symref [1][1][1] = best8x8symref [1][2][1] = best8x8symref [1][3][1] = bid_best_bw_ref;
}
//--- set reference frames and motion vectors ---
if (mode>1 && block==0)
SetRefAndMotionVectors (block, mode, best_pdir==2?bid_best_fw_ref:best_fw_ref,
best_pdir==2?bid_best_bw_ref:best_bw_ref, best_pdir);
}
if (cost < min_cost)
{
best_mode = mode;
min_cost = cost;
}
} // if (valid[mode])
} // for (mode=3; mode>0; mode--)*/
#endif
if (valid[P8x8])
{
cost8x8 = 0;
//===== store coding state of macroblock =====
store_coding_state (cs_mb);
//===== LOOP OVER 8x8 SUB-PARTITIONS (Motion Estimation & Mode Decision) =====
for (cbp8x8=cbp_blk8x8=cnt_nonz_8x8=0, block=stage_block8x8_pos; block<4; block++)
{
//--- set coordinates ---
j0 = ((block/2)<<3); j1 = (j0>>2);
i0 = ((block%2)<<3); i1 = (i0>>2);
//===== LOOP OVER POSSIBLE CODING MODES FOR 8x8 SUB-PARTITION =====
for (min_cost_8x8=(1<<20), min_rdcost=1e30, index=(bframe?0:1); index<2; index++)
{
if (valid[mode=b8_mode_table[index]])
{
// if(mode==0 && img->type==B_IMG && img->VEC_FLAG==1 && input->vec_ext==3)// M1956 by Grandview 2006.12.12
// continue;
curr_cbp_blk = 0;
if (mode==0)
{
//--- Direct Mode ---
if (!input->rdopt)
{
cost_direct += (cost = Get_Direct_Cost8x8 ( block, lambda_mode ));
have_direct ++;
}
//for B frame
if(!img->picture_structure)
{
scale_refframe = refFrArr[img->block8_y+block/2][img->block8_x+block%2];
if (img->current_mb_nr_fld < img->total_number_mb) //top field
{
scale_refframe = scale_refframe == 0 ? 0 : 1;
}
else
{
scale_refframe = scale_refframe == 1 ? 0 : 1; //?????xyji
}
bid_best_fw_ref = scale_refframe;
if(img->current_mb_nr_fld < img->total_number_mb)
{
bid_best_bw_ref = 1;
}
else
bid_best_bw_ref = 0;
best8x8symref[0][block][0] = scale_refframe;
best8x8symref[0][block][1] = bid_best_bw_ref;
if(refFrArr[img->block8_y+block/2][img->block8_x+block%2] < 0)
{
best8x8symref[0][block][0] = 0;
best8x8symref[0][block][1] = 1;
bid_best_bw_ref = 1;
bid_best_fw_ref = 0;
}
}
best_fw_ref = -1;
best_pdir = 2;
} // if (mode==0)
else
{
//--- motion estimation for all reference frames ---
PartitionMotionSearch (mode, block, lambda_motion);
//--- get cost and reference frame for forward prediction ---
//--- get cost and reference frame for forward prediction ---
if(img->type == INTER_IMG)/*lgp*/
{
for (fw_mcost=max_mcost, ref=0; ref<max_ref-adjust_ref; ref++) // Tian Dong. PLUS1. -adjust_ref. June 06, 2002
{ /*lgp*13*/
{
mcost = (input->rdopt ? write_ref ? REF_COST_FWD (lambda_motion_factor, ref) : 0 : (int)(2*lambda_motion*min(ref,1)));
mcost += motion_cost[mode][ref+/*1*/1/*lgp*13*/][block];
if (mcost < fw_mcost)
{
fw_mcost = mcost;
best_fw_ref = ref;
}
}
}
}
else
{
//xyji
for (fw_mcost=max_mcost, ref=0; ref<max_ref-adjust_ref; ref++)
{
//if (!checkref || ref==0)/*lgp*13*/
{
//mcost = (input->rdopt ? write_ref ? REF_COST_FWD (lambda_motion_factor, ref) : 0 : (int)(2*lambda_motion*min(ref,1)));
mcost = motion_cost[mode][img->picture_structure ? ref+1 : ref+2][block];
if (mcost < fw_mcost)
{
fw_mcost = mcost;
best_fw_ref = ref;
}
}
}
best_bw_ref = 0;
}
if (bframe)
{
PartitionMotionSearch_bid (mode, block, lambda_motion);
best_bw_ref = 0;
bw_mcost = motion_cost[mode][0][block];
//xyji 11.26
for (bw_mcost=max_mcost, ref=0; ref<max_ref-adjust_ref; ref++)
{
{
//mcost = (input->rdopt ? write_ref ? REF_COST_FWD (lambda_motion_factor, ref) : 0 : (int)(2*lambda_motion*min(ref,1)));
mcost = motion_cost[mode][ref][block];
if (mcost < bw_mcost)
{
bw_mcost = mcost;
best_bw_ref = ref;
}
}
}
for (bid_mcost=max_mcost, ref=0; ref<max_ref-adjust_ref; ref++)
{
//if (!checkref || ref==0)/*lgp*13*/
{
//mcost = (input->rdopt ? write_ref ? REF_COST_FWD (lambda_motion_factor, ref) : 0 : (int)(2*lambda_motion*min(ref,1)));
mcost = motion_cost_bid[mode][img->picture_structure ? ref+1 : ref+2][block];
if (mcost < bid_mcost)
{
bid_mcost = mcost;
bid_best_fw_ref = ref;
bid_best_bw_ref = ref;
}
}
}
//--- get prediction direction ----
if(fw_mcost<=bw_mcost && fw_mcost<=bid_mcost)
{
best_pdir = 0;
cost = fw_mcost;
best_bw_ref = 0;
}
else if (bw_mcost<=fw_mcost && bw_mcost<=bid_mcost)
{
best_pdir = 1;
cost = bw_mcost;
best_fw_ref = 0;/*lgp*13*/
}
else
{
best_pdir = 2;
cost = bid_mcost;
}
}
else // if (bframe)
{
best_pdir = 0;
cost = fw_mcost;
}
} // if (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_pdir==2?bid_best_fw_ref:best_fw_ref,best_pdir==2?bid_best_bw_ref:best_bw_ref);/*lgp*13*/
}
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_8x8 ) )
{
min_cost_8x8 = cost;
min_rdcost = rdcost;
best8x8mode [block] = mode;
best8x8pdir [P8x8][block] = best_pdir;
best8x8ref [P8x8][block] = best_fw_ref;
best8x8bwref [P8x8][block] = best_bw_ref;
best8x8symref[P8x8][block][0] = bid_best_fw_ref;
best8x8symref[P8x8][block][1] = bid_best_bw_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 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_8x8;
if (!input->rdopt)
{
mode = best8x8mode[block];
pdir = best8x8pdir[P8x8][block];
curr_cbp_blk =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -