コード例 #1
0
ファイル: block_match.cpp プロジェクト: banduladh/meplayer
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;   

}
コード例 #2
0
ファイル: block_match.cpp プロジェクト: banduladh/meplayer
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 );
}
コード例 #3
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;
}
コード例 #4
0
ファイル: block_match.cpp プロジェクト: banduladh/meplayer
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;   

}
コード例 #5
0
ファイル: me_utils_mmx.cpp プロジェクト: Fluffiest/mpc-hc
    CalcValueType simple_intra_block_diff_mmx_4 ( 
            const BlockDiffParams& dparams, 
            const PicArray& pic_data, ValueType &dc_val)
    {
        __m64 tmp = _mm_set_pi16(0, 0, 0, 0);
        u_mmx_val u_sum;
        u_sum.i[0] = u_sum.i[1] = 0;

        ValueType *src = &(pic_data[dparams.Yp()][dparams.Xp()]);

        int height = dparams.Yl();
        int width = dparams.Xl();
        int stopX = (width>>2)<<2;
        int pic_next = (pic_data.LengthX() - width);
        CalcValueType mop_sum = 0;
        for (int j = 0; j < height; j++)
        {
            for (int i = 0; i < stopX; i+=4) 
            {
                __m64 pic = *(__m64 *)src;
                // sum += (pic)
                tmp = _mm_xor_si64(tmp, tmp);
                tmp = _mm_unpackhi_pi16(pic, tmp);
                tmp = _mm_slli_pi32 (tmp, 16);
                tmp = _mm_srai_pi32 (tmp, 16);
                pic = _mm_unpacklo_pi16(pic, pic);
                pic = _mm_srai_pi32 (pic, 16);
                pic = _mm_add_pi32 (pic, tmp);
                u_sum.m = _mm_add_pi32 (u_sum.m, pic);
                src += 4;
            }
            // Mop up
            for (int i = stopX; i < width; ++i)
            {
                mop_sum += *src;
                src++;
            }
            src += pic_next;
        }

        CalcValueType int_dc =  (u_sum.i[0] + u_sum.i[1] + mop_sum)/(width*height);

        dc_val = static_cast<ValueType>( int_dc );

        // Now compute the resulting SAD
        __m64 dc = _mm_set_pi16 ( dc_val, dc_val , dc_val , dc_val);
        u_sum.m = _mm_xor_si64(u_sum.m, u_sum.m); // initialise sum to 0
        mop_sum = 0;
        
        src = &(pic_data[dparams.Yp()][dparams.Xp()]);
        for (int j = 0; j < height; ++j)
        {
            for (int i = 0; i < stopX; i+=4)
            {
                __m64 pic = *(__m64 *)src;
                // pic - dc
                pic = _mm_sub_pi16 (pic, dc);
                // abs (pic - dc)
                tmp = _mm_srai_pi16(pic, 15);
                pic = _mm_xor_si64(pic, tmp);
                pic = _mm_sub_pi16 (pic, tmp);
                // sum += abs(pic -dc)
                tmp = _mm_xor_si64(tmp, tmp);
                tmp = _mm_unpackhi_pi16(pic, tmp);
                pic = _mm_unpacklo_pi16(pic, pic);
                pic = _mm_srai_pi32 (pic, 16);
                pic = _mm_add_pi32 (pic, tmp);
                u_sum.m = _mm_add_pi32 (u_sum.m, pic);
                src += 4;
            }
            // Mop up
            for (int i = stopX; i < width; ++i)
            {
                mop_sum += std::abs(*src - dc_val);
                src++;
            }
            src += pic_next;
        }
        CalcValueType intra_cost = u_sum.i[0] + u_sum.i[1] + mop_sum;
        _mm_empty();

        return intra_cost;

    }