me_mode_decn.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:21k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. *
  3. * $Id: me_mode_decn.cpp,v 1.2 2005/01/30 05:11:42 gabest Exp $ $Name:  $
  4. *
  5. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  6. *
  7. * The contents of this file are subject to the Mozilla Public License
  8. * Version 1.1 (the "License"); you may not use this file except in compliance
  9. * with the License. You may obtain a copy of the License at
  10. * http://www.mozilla.org/MPL/
  11. *
  12. * Software distributed under the License is distributed on an "AS IS" basis,
  13. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
  14. * the specific language governing rights and limitations under the License.
  15. *
  16. * The Original Code is BBC Research and Development code.
  17. *
  18. * The Initial Developer of the Original Code is the British Broadcasting
  19. * Corporation.
  20. * Portions created by the Initial Developer are Copyright (C) 2004.
  21. * All Rights Reserved.
  22. *
  23. * Contributor(s): Thomas Davies (Original Author)
  24. *
  25. * Alternatively, the contents of this file may be used under the terms of
  26. * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
  27. * Public License Version 2.1 (the "LGPL"), in which case the provisions of
  28. * the GPL or the LGPL are applicable instead of those above. If you wish to
  29. * allow use of your version of this file only under the terms of the either
  30. * the GPL or LGPL and not to allow others to use your version of this file
  31. * under the MPL, indicate your decision by deleting the provisions above
  32. * and replace them with the notice and other provisions required by the GPL
  33. * or LGPL. If you do not delete the provisions above, a recipient may use
  34. * your version of this file under the terms of any one of the MPL, the GPL
  35. * or the LGPL.
  36. * ***** END LICENSE BLOCK ***** */
  37. #include <libdirac_motionest/me_mode_decn.h>
  38. #include <libdirac_common/frame_buffer.h>
  39. using namespace dirac;
  40. #include <algorithm>
  41. using std::vector;
  42. ModeDecider::ModeDecider( const EncoderParams& encp):
  43.     m_encparams( encp ),
  44.     m_level_factor(3),
  45.     m_mode_factor(3),
  46.     m_me_data_set(3)
  47. {
  48.     // The following factors normalise costs for sub-MBs and MBs to those of 
  49.     // blocks, so that the overlap is take into account (e.g. a sub-MB has
  50.     // length XBLEN+XBSEP and YBLEN+YBSEP). The MB costs for a 1x1 
  51.     // decomposition are not directly comprable to those for other decompositions
  52.     // because of the block overlaps. These factors remove these effects, so that
  53.     // all SAD costs are normalised to the area corresponding to non-overlapping
  54.     // 16 blocks of size XBLEN*YBLEN.    
  55.    m_level_factor[0] = float( 16 * m_encparams.LumaBParams(2).Xblen() * m_encparams.LumaBParams(2).Yblen() )/
  56.        float( m_encparams.LumaBParams(0).Xblen() * m_encparams.LumaBParams(0).Yblen() );
  57.    m_level_factor[1] = float( 4 * m_encparams.LumaBParams(2).Xblen() * m_encparams.LumaBParams(2).Yblen() )/
  58.        float( m_encparams.LumaBParams(1).Xblen() * m_encparams.LumaBParams(1).Yblen() );
  59.    m_level_factor[2] = 1.0f;
  60.     for (int i=0 ; i<=2 ; ++i)
  61.         m_mode_factor[i] = 160.0*std::pow(0.8 , 2-i);
  62. }
  63. ModeDecider::~ModeDecider()
  64. {
  65.     if (fsort != I_frame)
  66.     {
  67.         delete m_me_data_set[0];
  68.         delete m_me_data_set[1];
  69.     }
  70. }
  71. void ModeDecider::DoModeDecn(const FrameBuffer& my_buffer, int frame_num, MEData& me_data)
  72. {
  73.      // We've got 'raw' block motion vectors for up to two reference frames. Now we want
  74.      // to make a decision as to mode. In this initial implementation, this is bottom-up
  75.     // i.e. find mvs for MBs and sub-MBs and see whether it's worthwhile merging.    
  76.     int ref1,ref2;
  77.     // Initialise // 
  78.     ////////////////
  79.     fsort = my_buffer.GetFrame(frame_num).GetFparams().FSort();
  80.     if (fsort != I_frame)
  81.     {
  82.         // Extract the references
  83.         const vector<int>& refs = my_buffer.GetFrame(frame_num).GetFparams().Refs();
  84.         num_refs = refs.size();
  85.         ref1 = refs[0];
  86.         // The picture we're doing estimation from
  87.         m_pic_data = &(my_buffer.GetComponent( frame_num , Y_COMP));
  88.         // Set up the hierarchy of motion vector data objects
  89.         m_me_data_set[0] = new MEData( m_encparams.XNumMB() , m_encparams.YNumMB() , 
  90.                                        m_encparams.XNumBlocks()/4 , m_encparams.YNumBlocks()/4 );
  91.         m_me_data_set[1] = new MEData( m_encparams.XNumMB() , m_encparams.YNumMB() , 
  92.                                        m_encparams.XNumBlocks()/2 , m_encparams.YNumBlocks()/2 );
  93.         m_me_data_set[2] = &me_data;
  94.         // Set up the lambdas to use per block
  95.         m_me_data_set[0]->SetLambdaMap( 0 , me_data.LambdaMap() , 1.0/m_level_factor[0] );
  96.         m_me_data_set[1]->SetLambdaMap( 1 , me_data.LambdaMap() , 1.0/m_level_factor[1] );
  97.         // Set up the reference pictures
  98.         m_ref1_updata = &(my_buffer.GetUpComponent( ref1 , Y_COMP));
  99.         if (num_refs>1)
  100.         {
  101.             ref2 = refs[1];
  102.             m_ref2_updata = &(my_buffer.GetUpComponent( ref2 , Y_COMP));
  103.             // Create an object for computing bi-directional prediction calculations            
  104.             m_bicheckdiff = new BiBChkBlockDiffUp( *m_ref1_updata ,
  105.                                                  *m_ref2_updata ,
  106.                                                  *m_pic_data );
  107.         }
  108.         else
  109.         {    
  110.             ref2 = ref1;
  111.         }
  112.         // Create an object for doing intra calculations
  113.         m_intradiff = new IntraBlockDiff( *m_pic_data );
  114.         // Loop over all the macroblocks, doing the work //
  115.         ///////////////////////////////////////////////////
  116.         for (m_ymb_loc=0 ; m_ymb_loc<m_encparams.YNumMB() ; ++m_ymb_loc )
  117.         {
  118.             for (m_xmb_loc=0 ; m_xmb_loc<m_encparams.XNumMB(); ++m_xmb_loc )
  119.             {
  120.                 DoMBDecn();
  121.             }//m_xmb_loc        
  122.         }//m_ymb_loc
  123.         delete m_intradiff;
  124.         if (num_refs>1)
  125.             delete m_bicheckdiff;
  126.     }
  127. }
  128. void ModeDecider::DoMBDecn()
  129. {
  130.       // Does the mode decision for the given MB, in three stages
  131.     // Start with 4x4 modes
  132.     DoLevelDecn(2);
  133.     float old_best_MB_cost = m_me_data_set[2]->MBCosts()[m_ymb_loc][m_xmb_loc];
  134.     // Next do 2x2 modes
  135.     DoLevelDecn(1);
  136.     // Do 1x1 mode if merging worked before
  137.     if ( m_me_data_set[2]->MBCosts()[m_ymb_loc][m_xmb_loc] <= old_best_MB_cost)
  138.     {
  139.         old_best_MB_cost = m_me_data_set[2]->MBCosts()[m_ymb_loc][m_xmb_loc];        
  140.         DoLevelDecn(0);
  141.     }
  142. }
  143. void ModeDecider::DoLevelDecn( int level )
  144. {
  145.     // Computes the best costs if we were to
  146.     // stick to a decomposition at this level
  147.     // Looks at two cases: the prediction mode is
  148.     // constant across the MB; and the pred mode
  149.     // for each constituent is different.
  150.     // The limits of the prediction units
  151.     const int xstart = m_xmb_loc <<level;
  152.     const int ystart = m_ymb_loc <<level;
  153.     const int xend = xstart + (1<<level);
  154.     const int yend = ystart + (1<<level);
  155.     //    Case 1: prediction modes are all different
  156.     float MB_cost = 0.0;    
  157.     for ( int j=ystart ; j<yend ; ++j)
  158.     {
  159.         for (int i=xstart ; i<xend ; ++i)
  160.        {
  161.            if ( level<2 )
  162.                DoME( i , j , level);
  163.             MB_cost += DoUnitDecn( i , j ,level );
  164.         }// i
  165.     }// j
  166.     // if we've improved on the best cost, we should propagate data in 
  167.     // the base level motion vector set
  168.     if (level == 2)
  169.     {
  170.         m_me_data_set[2]->MBSplit()[m_ymb_loc][m_xmb_loc] = 2;
  171.         m_me_data_set[2]->MBCommonMode()[m_ymb_loc][m_xmb_loc] = false;
  172.         m_me_data_set[2]->MBCosts()[m_ymb_loc][m_xmb_loc] = MB_cost;
  173.     }
  174.     if ( level<2 && MB_cost <= m_me_data_set[2]->MBCosts()[m_ymb_loc][m_xmb_loc] )
  175.     {
  176.         m_me_data_set[2]->MBCosts()[m_ymb_loc][m_xmb_loc] = MB_cost;
  177.         m_me_data_set[2]->MBSplit()[m_ymb_loc][m_xmb_loc] = level;
  178.         m_me_data_set[2]->MBCommonMode()[m_ymb_loc][m_xmb_loc] = false;
  179.         // Parameters of the base-level blocks corresponding to each
  180.         // prediction unit
  181.         int xblock_start;
  182.         int yblock_start;
  183.         int xblock_end;
  184.         int yblock_end;
  185.         for ( int j=ystart ; j<yend ; ++j )
  186.         {
  187.             yblock_start = j<<(2-level);
  188.             yblock_end = (j+1)<<(2-level);
  189.             for ( int i=xstart ; i<xend ; ++i )
  190.             {
  191.                 xblock_start = i<<(2-level);
  192.                 xblock_end = (i+1)<<(2-level);
  193.                 for ( int v=yblock_start ; v<yblock_end ; ++v )
  194.                 {
  195.                     for ( int u=xblock_start ; u<xblock_end ; ++u )
  196.                     {
  197.                         m_me_data_set[2]->Mode()[v][u] = m_me_data_set[level]->Mode()[j][i];
  198.                         m_me_data_set[2]->DC( Y_COMP )[v][u] = m_me_data_set[level]->DC( Y_COMP )[j][i];
  199.                         m_me_data_set[2]->Vectors(1)[v][u] = m_me_data_set[level]->Vectors(1)[j][i];
  200.                         if ( num_refs>1 )
  201.                             m_me_data_set[2]->Vectors(2)[v][u] = m_me_data_set[level]->Vectors(2)[j][i];
  202.                     }// u
  203.                 }// v
  204.             }// i
  205.         }// j
  206.     }
  207.     //     Case 2: prediction modes are all the same
  208.     PredMode predmode;
  209.     MB_cost = DoCommonMode( predmode , level );
  210.     if ( MB_cost <= m_me_data_set[2]->MBCosts()[m_ymb_loc][m_xmb_loc] )
  211.     {
  212.         m_me_data_set[2]->MBCosts()[m_ymb_loc][m_xmb_loc] = MB_cost;
  213.         m_me_data_set[2]->MBSplit()[m_ymb_loc][m_xmb_loc] = level;
  214.         m_me_data_set[2]->MBCommonMode()[m_ymb_loc][m_xmb_loc] = true;
  215.         // Parameters of the base-level blocks corresponding to each
  216.         // prediction unit
  217.         int xblock_start;
  218.         int yblock_start;
  219.         int xblock_end;
  220.         int yblock_end;
  221.         for ( int j=ystart ; j<yend ; ++j )
  222.         {
  223.             yblock_start = j<<(2-level);
  224.             yblock_end = (j+1)<<(2-level);
  225.             for ( int i=xstart ; i<xend ; ++i )
  226.             {
  227.                 xblock_start = i<<(2-level);
  228.                 xblock_end = (i+1)<<(2-level);
  229.                 for ( int v=yblock_start ; v<yblock_end ; ++v )
  230.                 {
  231.                     for ( int u=xblock_start ; u<xblock_end ; ++u )
  232.                     {
  233.                         m_me_data_set[2]->Vectors(1)[v][u] = m_me_data_set[level]->Vectors(1)[j][i];
  234.                         m_me_data_set[2]->Mode()[v][u] = predmode;
  235.                         m_me_data_set[2]->DC( Y_COMP )[v][u] = m_me_data_set[level]->DC( Y_COMP )[j][i];
  236.                         if ( num_refs>1 )
  237.                             m_me_data_set[2]->Vectors(2)[v][u] = m_me_data_set[level]->Vectors(2)[j][i];
  238.                     }// u
  239.                 }// v
  240.  
  241.             }// i
  242.         }// j
  243.       }
  244. }
  245. void ModeDecider::DoME(const int xpos , const int ypos , const int level)
  246. {
  247.     // Do motion estimation for a prediction unit using the 
  248.     // four vectors derived from the next level as a guide
  249.     MEData& me_data = *(m_me_data_set[level]);
  250.     const MEData& guide_data = *(m_me_data_set[level+1]);
  251.     // The corresponding location of the guide data
  252.     const int guide_xpos = xpos<<1; 
  253.     const int guide_ypos = ypos<<1;
  254.     // The location of the lowest level vectors
  255.     const int xblock = xpos << ( 2 - level); 
  256.     const int yblock = ypos << ( 2 - level);
  257.     // The list of potential candidate vectors
  258.     CandidateList cand_list;
  259.     // The lambda to use for motion estimation
  260.     const float lambda = me_data.LambdaMap()[ypos][xpos];
  261.     // The predicting motion vector
  262.     MVector mv_pred;
  263.     for ( int j=0 ; j<2 ; ++j )
  264.         for (int i=0 ; i<2 ; ++i )
  265.             AddNewVlist( cand_list , guide_data.Vectors(1)[guide_ypos+j][guide_xpos+i] , 1 , 1 );
  266.     if (xblock>0 && yblock>0)
  267.         mv_pred = MvMedian( m_me_data_set[2]->Vectors(1)[yblock][xblock-1] ,
  268.                             m_me_data_set[2]->Vectors(1)[yblock-1][xblock-1],
  269.                               m_me_data_set[2]->Vectors(1)[yblock-1][xblock]);
  270.     else if (xblock==0 && yblock>0)
  271.         mv_pred = MvMean( m_me_data_set[2]->Vectors(1)[yblock-1][xblock],
  272.                           m_me_data_set[2]->Vectors(1)[yblock-1][xblock+1]);
  273.     else if (xblock>0 && yblock==0)
  274.         mv_pred = MvMean( m_me_data_set[2]->Vectors(1)[yblock][xblock-1],
  275.                           m_me_data_set[2]->Vectors(1)[yblock+1][xblock-1]);
  276.     else{
  277.         mv_pred.x = 0;
  278.         mv_pred.y = 0;
  279.     }
  280.     BlockMatcher my_bmatch1( *m_pic_data , *m_ref1_updata , m_encparams.LumaBParams(level) ,
  281.                                                      me_data.Vectors(1) , me_data.PredCosts(1) );
  282.     me_data.PredCosts(1)[ypos][xpos].total = 100000000.0f;
  283.     my_bmatch1.FindBestMatchSubp( xpos , ypos , cand_list, mv_pred, lambda );
  284.     if (num_refs>1)
  285.     {//do the same for the other reference
  286.         cand_list.clear();                
  287.         for ( int j=0 ; j<2 ; ++j )
  288.         {
  289.             for (int i=0 ; i<2 ; ++i )
  290.             {
  291.                 AddNewVlist( cand_list , guide_data.Vectors(2)[guide_ypos+j][guide_xpos+i] , 1 , 1 );
  292.             }// i
  293.         }// j
  294.         if (xblock>0 && yblock>0)
  295.             mv_pred = MvMedian( m_me_data_set[2]->Vectors(2)[yblock][xblock-1] ,
  296.                                              m_me_data_set[2]->Vectors(2)[yblock-1][xblock-1],
  297.                                                m_me_data_set[2]->Vectors(2)[yblock-1][xblock]);
  298.         else if (xblock==0 && yblock>0)
  299.             mv_pred = MvMean( m_me_data_set[2]->Vectors(2)[yblock-1][xblock],
  300.                                            m_me_data_set[2]->Vectors(2)[yblock-1][xblock+1]);
  301.         else if (xblock>0 && yblock==0)
  302.             mv_pred = MvMean( m_me_data_set[2]->Vectors(2)[yblock][xblock-1],
  303.                                            m_me_data_set[2]->Vectors(2)[yblock+1][xblock-1]);
  304.         else{
  305.              mv_pred.x = 0;
  306.              mv_pred.y = 0;
  307.         }
  308.         BlockMatcher my_bmatch2( *m_pic_data , *m_ref2_updata , m_encparams.LumaBParams(level) ,
  309.                                                      me_data.Vectors(2) , me_data.PredCosts(2) );
  310.         me_data.PredCosts(2)[ypos][xpos].total = 100000000.0f;
  311.         my_bmatch2.FindBestMatchSubp( xpos , ypos , cand_list, mv_pred, lambda );
  312.      }
  313. }
  314. float ModeDecider::DoUnitDecn(const int xpos , const int ypos , const int level )
  315. {
  316.     // For a given prediction unit (MB, subMB or block) find the best
  317.     // mode, given that the REF1 and REF2 motion estimation has
  318.     // already been done.
  319.     MEData& me_data = *( m_me_data_set[level] );
  320.     // Coords of the top-leftmost block belonging to this unit
  321.     const int xblock = xpos<<(2-level);
  322.     const int yblock = ypos<<(2-level);
  323.     const float loc_lambda = me_data.LambdaMap()[ypos][xpos];
  324.     float unit_cost;
  325.     float mode_cost;
  326.     float min_unit_cost;
  327.  
  328.     BlockDiffParams dparams;
  329.     dparams.SetBlockLimits( m_encparams.LumaBParams( level ) , *m_pic_data, xpos , ypos);
  330.      // First check REF1 costs //
  331.     /**************************/
  332.     mode_cost = ModeCost( xblock , yblock , REF1_ONLY)*m_mode_factor[level];
  333.     me_data.Mode()[ypos][xpos] = REF1_ONLY;
  334.     me_data.PredCosts(1)[ypos][xpos].total *= m_level_factor[level];
  335.     min_unit_cost = me_data.PredCosts(1)[ypos][xpos].total + mode_cost;
  336.     // Calculate the cost if we were to code the block as intra //
  337.     /************************************************************/
  338.     mode_cost = ModeCost( xblock , yblock , INTRA) * m_mode_factor[level];
  339.     me_data.IntraCosts()[ypos][xpos] = m_intradiff->Diff( dparams , me_data.DC( Y_COMP )[ypos][xpos] );
  340.     me_data.IntraCosts()[ypos][xpos] += loc_lambda * 
  341.                                        GetDCVar( me_data.DC( Y_COMP )[ypos][xpos] , GetDCPred( xblock , yblock ) );
  342.     me_data.IntraCosts()[ypos][xpos] *= m_level_factor[level];
  343.     unit_cost = me_data.IntraCosts()[ypos][xpos] +  mode_cost;
  344.     if ( unit_cost<min_unit_cost )
  345.     {
  346.         me_data.Mode()[ypos][xpos] = INTRA;
  347.         min_unit_cost = unit_cost;
  348.     }
  349.     if (num_refs>1)
  350.     {
  351.        // Next check REF2 costs //
  352.        /*************************/
  353.         mode_cost = ModeCost( xblock , yblock , REF2_ONLY)*m_mode_factor[level];
  354.         me_data.PredCosts(2)[ypos][xpos].total *= m_level_factor[level];
  355.         unit_cost = me_data.PredCosts(2)[ypos][xpos].total + mode_cost;
  356.         if ( unit_cost<min_unit_cost )
  357.         {
  358.             me_data.Mode()[ypos][xpos] = REF2_ONLY;
  359.             min_unit_cost = unit_cost;
  360.         }
  361.         // Finally, calculate the cost if we were to use bi-predictions //
  362.         /****************************************************************/
  363. /*
  364.         mode_cost = ModeCost( xpos , ypos , REF1AND2 )*m_mode_factor[level];
  365.         me_data.BiPredCosts()[ypos][xpos].mvcost =
  366.                                        me_data.PredCosts(1)[ypos][xpos].mvcost+
  367.                                        me_data.PredCosts(2)[ypos][xpos].mvcost;
  368.         
  369.         me_data.BiPredCosts()[ypos][xpos].SAD = m_bicheckdiff->Diff(dparams , 
  370.                                                   me_data.Vectors(1)[ypos][xpos] , 
  371.                                                   me_data.Vectors(2)[ypos][xpos] );
  372.         me_data.BiPredCosts()[ypos][xpos].SetTotal( loc_lambda );
  373.         me_data.BiPredCosts()[ypos][xpos].total *= m_level_factor[level];
  374.         unit_cost = me_data.BiPredCosts()[ypos][xpos].total + mode_cost;
  375.         if ( unit_cost<min_unit_cost )
  376.         {
  377.             me_data.Mode()[ypos][xpos] = REF1AND2;
  378.             min_unit_cost = unit_cost;
  379.         }
  380. */
  381.     }
  382.     return min_unit_cost;
  383. }
  384. float ModeDecider::DoCommonMode( PredMode& predmode , const int level)
  385. {
  386.     // For a given level, examine the costs in the constituent
  387.     // prediction units of the MB at that level and decide 
  388.     // whether there should be a common prediction mode or not.
  389.     const MEData& me_data = *( m_me_data_set[level] );
  390.     // The total cost for the MB for each possible prediction mode
  391.     OneDArray<float> MB_cost(4);
  392.     for ( int i=0 ; i<4 ; ++i)
  393.         MB_cost[i] = ModeCost( m_xmb_loc<<2 , m_ymb_loc , PredMode(i) )*m_mode_factor[0];
  394.     // The limits of the prediction units
  395.     const int xstart = m_xmb_loc <<level;
  396.     const int ystart = m_ymb_loc <<level;
  397.     const int xend = xstart + (1<<level);
  398.     const int yend = ystart + (1<<level);
  399.     for (int j=ystart ; j<yend ; ++j)
  400.     {
  401.         for (int i=xstart ; i<xend ; ++i)
  402.         {
  403.             MB_cost[INTRA] += me_data.IntraCosts()[j][i];
  404.             MB_cost[REF1_ONLY] += me_data.PredCosts(1)[j][i].total;
  405.             if ( num_refs>1 )
  406.             {
  407.                 MB_cost[REF2_ONLY] += me_data.PredCosts(2)[j][i].total;
  408. //                MB_cost[REF1AND2] += me_data.BiPredCosts()[j][i].total;
  409.             }
  410.         }// i
  411.     }// i
  412.     // Find the minimum
  413.     predmode = INTRA;
  414.     if ( MB_cost[REF1_ONLY]<MB_cost[predmode] )
  415.         predmode = REF1_ONLY;
  416.     if ( num_refs>1)
  417.     {
  418.         if ( MB_cost[REF2_ONLY]<MB_cost[predmode] )
  419.             predmode = REF2_ONLY;
  420. //         if ( MB_cost[REF1AND2]<MB_cost[predmode] )
  421. //             predmode = REF1AND2;
  422.     }
  423.  
  424.     return MB_cost[predmode];
  425. }
  426. ValueType ModeDecider::GetDCPred( int xblock , int yblock )
  427. {
  428.     ValueType dc_pred = 128;
  429.     if ( xblock>0 && m_me_data_set[2]->Mode()[yblock][xblock-1] == INTRA )
  430.     {
  431.         dc_pred = m_me_data_set[2]->DC( Y_COMP )[yblock][xblock-1];
  432.         if ( yblock>0 && m_me_data_set[2]->Mode()[yblock-1][xblock] == INTRA )
  433.         {
  434.             dc_pred += m_me_data_set[2]->DC( Y_COMP )[yblock-1][xblock];
  435.             dc_pred >>= 1;
  436.         }
  437.     }
  438.      
  439.     return dc_pred;
  440. }
  441. float ModeDecider::ModeCost(const int xindex , const int yindex , 
  442.                  const PredMode predmode )
  443. {
  444.     // Computes the variation of the given mode, predmode, from its immediate neighbours
  445.     // Currently, includes branches to cope with blocks on the edge of the picture.
  446.     int i ,j;
  447.     float diff;
  448.     float var = 0.0;
  449.     i = xindex-1;
  450.     j = yindex;
  451.     if ( i>=0)
  452.     {
  453.         diff = static_cast<float>( m_me_data_set[2]->Mode()[j][i] - predmode );
  454.         var = std::abs( diff );
  455.     }
  456.     i = xindex-1;
  457.     j = yindex-1;
  458.     if ( i>=0 && j>=0)
  459.     {
  460.         diff = static_cast<float>( m_me_data_set[2]->Mode()[j][i] - predmode);
  461.         var += std::abs( diff );
  462.     }
  463.     i = xindex;
  464.     j = yindex-1;
  465.     if ( j>=0 )
  466.     {
  467.         diff = static_cast<float>( m_me_data_set[2]->Mode()[j][i] - predmode );
  468.         var += std::abs( diff );
  469.     }
  470.     return var*m_me_data_set[2]->LambdaMap()[yindex][xindex];
  471. }
  472. float ModeDecider::GetDCVar( const ValueType dc_val , const ValueType dc_pred)
  473. {
  474.     return 8.0*std::abs( static_cast<float>( dc_val - dc_pred ) );
  475. }