void BlockMatcher::FindBestMatchSubp( const int xpos, const int ypos, const CandidateList& cand_list, const MVector& mv_prediction, const float lambda) { BlockDiffParams dparams; dparams.SetBlockLimits( m_bparams , m_pic_data , xpos , ypos); //now test against the offsets in the MV list to get the lowest cost// ////////////////////////////////////////////////////////////////////// // Numbers of the lists to do more searching in vector<int> list_nums; // Costs of the initial vectors in each list OneDArray<float> list_costs( cand_list.size() ); // First test the first in each of the lists to choose which lists to pursue MvCostData best_costs( m_cost_array[ypos][xpos] ); best_costs.total = 100000000.0f; MVector best_mv( m_mv_array[ypos][xpos] ); MvCostData cand_costs; MVector cand_mv; for (size_t list_num=0 ; list_num<cand_list.size() ; ++list_num ) { for (size_t i=0 ; i<cand_list[list_num].size() ; ++i ) { cand_mv = cand_list[list_num][i]; cand_costs.mvcost = GetVarUp( mv_prediction , cand_mv ); m_subpeldiff[m_precision-1]->Diff( dparams, cand_mv , cand_costs.mvcost, lambda, best_costs , best_mv); }// }// list_num // Write the results in the arrays // ///////////////////////////////////// m_mv_array[ypos][xpos] = best_mv; m_cost_array[ypos][xpos] = best_costs; }
void BlockMatcher::FindBestMatchPel(const int xpos , const int ypos , const CandidateList& cand_list, const MVector& mv_prediction, const int list_start) { BlockDiffParams dparams; dparams.SetBlockLimits( m_bparams , m_pic_data , xpos , ypos); //now test against the offsets in the MV list to get the lowest cost// ////////////////////////////////////////////////////////////////////// // First test the first in each of the lists to choose which lists to pursue float best_cost = m_cost_array[ypos][xpos].total; MVector best_mv = m_mv_array[ypos][xpos]; for ( size_t lnum=list_start ; lnum<cand_list.size() ; ++lnum) { for (size_t i=0 ; i<cand_list[lnum].size() ; ++i) { m_peldiff.Diff( dparams , cand_list[lnum][i] , best_cost , best_mv); }// i }// num // Write the results in the arrays // ///////////////////////////////////// m_mv_array[ypos][xpos] = best_mv; m_cost_array[ypos][xpos].SAD = best_cost; m_cost_array[ypos][xpos].mvcost = GetVar( mv_prediction , best_mv); m_cost_array[ypos][xpos].SetTotal( 0.0 ); }
float ModeDecider::DoUnitDecn(const int xpos , const int ypos , const int level ) { // For a given prediction unit (MB, subMB or block) find the best // mode, given that the REF1 and REF2 motion estimation has // already been done. MEData& me_data = *( m_me_data_set[level] ); // Coords of the top-leftmost block belonging to this unit // const int xblock = xpos<<(2-level); // const int yblock = ypos<<(2-level); const float loc_lambda = me_data.LambdaMap()[ypos][xpos]; float unit_cost; float mode_cost(0.0); float min_unit_cost; float best_SAD_value; BlockDiffParams dparams; dparams.SetBlockLimits( m_predparams.LumaBParams( level ) , *m_pic_data, xpos , ypos); // First check REF1 costs // /**************************/ // mode_cost = ModeCost( xblock , yblock )*m_mode_factor[level]; me_data.Mode()[ypos][xpos] = REF1_ONLY; me_data.PredCosts(1)[ypos][xpos].total *= m_level_factor[level]; min_unit_cost = me_data.PredCosts(1)[ypos][xpos].total + mode_cost; best_SAD_value = me_data.PredCosts(1)[ypos][xpos].SAD; if (num_refs>1) { // Next check REF2 costs // /*************************/ // mode_cost = ModeCost( xblock , yblock )*m_mode_factor[level]; me_data.PredCosts(2)[ypos][xpos].total *= m_level_factor[level]; unit_cost = me_data.PredCosts(2)[ypos][xpos].total + mode_cost; if ( unit_cost<min_unit_cost ) { me_data.Mode()[ypos][xpos] = REF2_ONLY; min_unit_cost = unit_cost; best_SAD_value = me_data.PredCosts(2)[ypos][xpos].SAD; } // Calculate the cost if we were to use bi-predictions // /****************************************************************/ // mode_cost = ModeCost( xpos , ypos )*m_mode_factor[level]; me_data.BiPredCosts()[ypos][xpos].mvcost = me_data.PredCosts(1)[ypos][xpos].mvcost+ me_data.PredCosts(2)[ypos][xpos].mvcost; me_data.BiPredCosts()[ypos][xpos].SAD = m_bicheckdiff->Diff(dparams , me_data.Vectors(1)[ypos][xpos] , me_data.Vectors(2)[ypos][xpos] ); me_data.BiPredCosts()[ypos][xpos].SetTotal( loc_lambda ); me_data.BiPredCosts()[ypos][xpos].total *= m_level_factor[level]; unit_cost = me_data.BiPredCosts()[ypos][xpos].total + mode_cost; if ( unit_cost<min_unit_cost ) { me_data.Mode()[ypos][xpos] = REF1AND2; min_unit_cost = unit_cost; best_SAD_value = me_data.BiPredCosts()[ypos][xpos].SAD; } } // Calculate the cost if we were to code the block as intra // /************************************************************/ if (best_SAD_value> 4.0*m_predparams.LumaBParams( level ).Xblen()*m_predparams.LumaBParams( level ).Yblen() ) { // mode_cost = ModeCost( xblock , yblock ) * m_mode_factor[level]; me_data.IntraCosts()[ypos][xpos] = m_intradiff->Diff( dparams , me_data.DC( Y_COMP )[ypos][xpos] ); // me_data.IntraCosts()[ypos][xpos] += loc_lambda * // GetDCVar( me_data.DC( Y_COMP )[ypos][xpos] , GetDCPred( xblock , yblock ) ); me_data.IntraCosts()[ypos][xpos] *= m_level_factor[level]; unit_cost = me_data.IntraCosts()[ypos][xpos] + mode_cost; if ( unit_cost<min_unit_cost && me_data.IntraCosts()[ypos][xpos]<1.2*best_SAD_value) { me_data.Mode()[ypos][xpos] = INTRA; min_unit_cost = unit_cost; } } return min_unit_cost; }
void BlockMatcher::RefineMatchSubp(const int xpos, const int ypos, const MVector& mv_prediction, const float lambda) { BlockDiffParams dparams; dparams.SetBlockLimits( m_bparams , m_pic_data , xpos , ypos); m_cost_array[ypos][xpos].mvcost = GetVarUp( mv_prediction, m_mv_array[ypos][xpos]<<m_precision ); m_cost_array[ypos][xpos].SetTotal( lambda ); // Initialise to the best pixel value MvCostData best_costs( m_cost_array[ypos][xpos] ); MVector pel_mv( m_mv_array[ypos][xpos] ); MVector best_mv( pel_mv ); // If the integer value is good enough, bail out if ( best_costs.SAD < 2*dparams.Xl()*dparams.Yl() ) { m_mv_array[ypos][xpos] = m_mv_array[ypos][xpos]<<m_precision; return; } // Next, test the predictor. If that's good enough, bail out MvCostData pred_costs; pred_costs.mvcost = 0; pred_costs.SAD = m_subpeldiff[m_precision-1]->Diff( dparams, mv_prediction); pred_costs.total = pred_costs.SAD; if (pred_costs.SAD<2*dparams.Xl()*dparams.Yl() ) { m_mv_array[ypos][xpos] = mv_prediction; m_cost_array[ypos][xpos] = pred_costs; return; } // Now, let's see if we can do better than this MvCostData cand_costs; MVector cand_mv, old_best_mv; for (int i=1; i<=m_precision; ++i ) { best_mv = best_mv<<1; MVector temp_best_mv = best_mv; // Do a neighbourhood of best_mv // Stage 1 - look at the 4 nearest points cand_mv.x = best_mv.x - 1; cand_mv.y = best_mv.y; m_subpeldiff[i-1]->Diff( dparams, cand_mv , GetVarUp( mv_prediction, cand_mv<<(m_precision-i) ) , lambda , best_costs , temp_best_mv); cand_mv.x = best_mv.x + 1; cand_mv.y = best_mv.y; m_subpeldiff[i-1]->Diff( dparams, cand_mv , GetVarUp( mv_prediction, cand_mv<<(m_precision-i) ) , lambda , best_costs , temp_best_mv); cand_mv.x = best_mv.x; cand_mv.y = best_mv.y - 1; m_subpeldiff[i-1]->Diff( dparams, cand_mv , GetVarUp( mv_prediction, cand_mv<<(m_precision-i) ) , lambda , best_costs , temp_best_mv); cand_mv.x = best_mv.x; cand_mv.y = best_mv.y + 1; m_subpeldiff[i-1]->Diff( dparams, cand_mv , GetVarUp( mv_prediction, cand_mv<<(m_precision-i) ) , lambda , best_costs , temp_best_mv); // Stage 2. If we've done better than the original value, // look at the other two neighbours if ( temp_best_mv.x != best_mv.x ) { MVector new_best_mv = temp_best_mv; cand_mv.x = new_best_mv.x; cand_mv.y = new_best_mv.y - 1; m_subpeldiff[i-1]->Diff( dparams, cand_mv , GetVarUp( mv_prediction, cand_mv<<(m_precision-i) ) , lambda , best_costs , temp_best_mv); cand_mv.x = new_best_mv.x; cand_mv.y = new_best_mv.y + 1; m_subpeldiff[i-1]->Diff( dparams, cand_mv , GetVarUp( mv_prediction, cand_mv<<(m_precision-i) ) , lambda , best_costs , temp_best_mv); } else if ( temp_best_mv.y != best_mv.y ) { MVector new_best_mv = temp_best_mv; cand_mv.x = new_best_mv.x - 1; cand_mv.y = new_best_mv.y; m_subpeldiff[i-1]->Diff( dparams, cand_mv , GetVarUp( mv_prediction, cand_mv<<(m_precision-i) ) , lambda , best_costs , temp_best_mv); cand_mv.x = new_best_mv.x + 1; cand_mv.y = new_best_mv.y; m_subpeldiff[i-1]->Diff( dparams, cand_mv , GetVarUp( mv_prediction, cand_mv<<(m_precision-i) ) , lambda , best_costs , temp_best_mv); } best_mv = temp_best_mv; // Bail out if we can't do better than 10% worse than the predictor at // each stage if ( best_costs.total>1.1*pred_costs.total ) { m_mv_array[ypos][xpos] = mv_prediction; m_cost_array[ypos][xpos] = pred_costs; return; } }//i // Write the results in the arrays // ///////////////////////////////////// m_mv_array[ypos][xpos] = best_mv; m_cost_array[ypos][xpos] = best_costs; }