me_mode_decn.cpp

00001 /* ***** BEGIN LICENSE BLOCK *****
00002 *
00003 * $Id: me_mode_decn.cpp,v 1.2 2005/01/30 05:11:42 gabest Exp $ $Name:  $
00004 *
00005 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00006 *
00007 * The contents of this file are subject to the Mozilla Public License
00008 * Version 1.1 (the "License"); you may not use this file except in compliance
00009 * with the License. You may obtain a copy of the License at
00010 * http://www.mozilla.org/MPL/
00011 *
00012 * Software distributed under the License is distributed on an "AS IS" basis,
00013 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
00014 * the specific language governing rights and limitations under the License.
00015 *
00016 * The Original Code is BBC Research and Development code.
00017 *
00018 * The Initial Developer of the Original Code is the British Broadcasting
00019 * Corporation.
00020 * Portions created by the Initial Developer are Copyright (C) 2004.
00021 * All Rights Reserved.
00022 *
00023 * Contributor(s): Thomas Davies (Original Author)
00024 *
00025 * Alternatively, the contents of this file may be used under the terms of
00026 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
00027 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
00028 * the GPL or the LGPL are applicable instead of those above. If you wish to
00029 * allow use of your version of this file only under the terms of the either
00030 * the GPL or LGPL and not to allow others to use your version of this file
00031 * under the MPL, indicate your decision by deleting the provisions above
00032 * and replace them with the notice and other provisions required by the GPL
00033 * or LGPL. If you do not delete the provisions above, a recipient may use
00034 * your version of this file under the terms of any one of the MPL, the GPL
00035 * or the LGPL.
00036 * ***** END LICENSE BLOCK ***** */
00037 
00038 #include <libdirac_motionest/me_mode_decn.h>
00039 #include <libdirac_common/frame_buffer.h>
00040 using namespace dirac;
00041 
00042 #include <algorithm>
00043 
00044 using std::vector;
00045 
00046 ModeDecider::ModeDecider( const EncoderParams& encp):
00047     m_encparams( encp ),
00048     m_level_factor(3),
00049     m_mode_factor(3),
00050     m_me_data_set(3)
00051 {
00052 
00053     // The following factors normalise costs for sub-MBs and MBs to those of 
00054     // blocks, so that the overlap is take into account (e.g. a sub-MB has
00055     // length XBLEN+XBSEP and YBLEN+YBSEP). The MB costs for a 1x1 
00056     // decomposition are not directly comprable to those for other decompositions
00057     // because of the block overlaps. These factors remove these effects, so that
00058     // all SAD costs are normalised to the area corresponding to non-overlapping
00059     // 16 blocks of size XBLEN*YBLEN.    
00060 
00061    m_level_factor[0] = float( 16 * m_encparams.LumaBParams(2).Xblen() * m_encparams.LumaBParams(2).Yblen() )/
00062        float( m_encparams.LumaBParams(0).Xblen() * m_encparams.LumaBParams(0).Yblen() );
00063 
00064    m_level_factor[1] = float( 4 * m_encparams.LumaBParams(2).Xblen() * m_encparams.LumaBParams(2).Yblen() )/
00065        float( m_encparams.LumaBParams(1).Xblen() * m_encparams.LumaBParams(1).Yblen() );
00066 
00067    m_level_factor[2] = 1.0f;
00068 
00069     for (int i=0 ; i<=2 ; ++i)
00070         m_mode_factor[i] = 160.0*std::pow(0.8 , 2-i);
00071 }
00072 
00073 
00074 ModeDecider::~ModeDecider()
00075 {
00076     if (fsort != I_frame)
00077     {
00078         delete m_me_data_set[0];
00079         delete m_me_data_set[1];
00080     }
00081 }
00082 
00083 void ModeDecider::DoModeDecn(const FrameBuffer& my_buffer, int frame_num, MEData& me_data)
00084 {
00085 
00086      // We've got 'raw' block motion vectors for up to two reference frames. Now we want
00087      // to make a decision as to mode. In this initial implementation, this is bottom-up
00088     // i.e. find mvs for MBs and sub-MBs and see whether it's worthwhile merging.    
00089 
00090     int ref1,ref2;
00091 
00092     // Initialise // 
00094 
00095     fsort = my_buffer.GetFrame(frame_num).GetFparams().FSort();
00096     if (fsort != I_frame)
00097     {
00098         // Extract the references
00099         const vector<int>& refs = my_buffer.GetFrame(frame_num).GetFparams().Refs();
00100         num_refs = refs.size();
00101         ref1 = refs[0];
00102 
00103         // The picture we're doing estimation from
00104         m_pic_data = &(my_buffer.GetComponent( frame_num , Y_COMP));
00105 
00106         // Set up the hierarchy of motion vector data objects
00107         m_me_data_set[0] = new MEData( m_encparams.XNumMB() , m_encparams.YNumMB() , 
00108                                        m_encparams.XNumBlocks()/4 , m_encparams.YNumBlocks()/4 );
00109         m_me_data_set[1] = new MEData( m_encparams.XNumMB() , m_encparams.YNumMB() , 
00110                                        m_encparams.XNumBlocks()/2 , m_encparams.YNumBlocks()/2 );
00111 
00112         m_me_data_set[2] = &me_data;
00113 
00114         // Set up the lambdas to use per block
00115         m_me_data_set[0]->SetLambdaMap( 0 , me_data.LambdaMap() , 1.0/m_level_factor[0] );
00116         m_me_data_set[1]->SetLambdaMap( 1 , me_data.LambdaMap() , 1.0/m_level_factor[1] );
00117 
00118         // Set up the reference pictures
00119         m_ref1_updata = &(my_buffer.GetUpComponent( ref1 , Y_COMP));
00120 
00121         if (num_refs>1)
00122         {
00123             ref2 = refs[1];
00124             m_ref2_updata = &(my_buffer.GetUpComponent( ref2 , Y_COMP));
00125             // Create an object for computing bi-directional prediction calculations            
00126             m_bicheckdiff = new BiBChkBlockDiffUp( *m_ref1_updata ,
00127                                                  *m_ref2_updata ,
00128                                                  *m_pic_data );
00129         }
00130         else
00131         {    
00132             ref2 = ref1;
00133         }
00134 
00135 
00136         // Create an object for doing intra calculations
00137         m_intradiff = new IntraBlockDiff( *m_pic_data );
00138 
00139         // Loop over all the macroblocks, doing the work //
00141 
00142         for (m_ymb_loc=0 ; m_ymb_loc<m_encparams.YNumMB() ; ++m_ymb_loc )
00143         {
00144             for (m_xmb_loc=0 ; m_xmb_loc<m_encparams.XNumMB(); ++m_xmb_loc )
00145             {
00146                 DoMBDecn();
00147             }//m_xmb_loc        
00148         }//m_ymb_loc
00149 
00150         delete m_intradiff;
00151         if (num_refs>1)
00152             delete m_bicheckdiff;
00153     }
00154 }
00155 
00156 void ModeDecider::DoMBDecn()
00157 {
00158       // Does the mode decision for the given MB, in three stages
00159 
00160     // Start with 4x4 modes
00161     DoLevelDecn(2);
00162     float old_best_MB_cost = m_me_data_set[2]->MBCosts()[m_ymb_loc][m_xmb_loc];
00163 
00164     // Next do 2x2 modes
00165     DoLevelDecn(1);
00166 
00167     // Do 1x1 mode if merging worked before
00168     if ( m_me_data_set[2]->MBCosts()[m_ymb_loc][m_xmb_loc] <= old_best_MB_cost)
00169     {
00170         old_best_MB_cost = m_me_data_set[2]->MBCosts()[m_ymb_loc][m_xmb_loc];        
00171         DoLevelDecn(0);
00172     }
00173 
00174 }
00175 
00176 void ModeDecider::DoLevelDecn( int level )
00177 {
00178     // Computes the best costs if we were to
00179     // stick to a decomposition at this level
00180 
00181     // Looks at two cases: the prediction mode is
00182     // constant across the MB; and the pred mode
00183     // for each constituent is different.
00184 
00185     // The limits of the prediction units
00186     const int xstart = m_xmb_loc <<level;
00187     const int ystart = m_ymb_loc <<level;
00188 
00189     const int xend = xstart + (1<<level);
00190     const int yend = ystart + (1<<level);
00191 
00192     //    Case 1: prediction modes are all different
00193 
00194     float MB_cost = 0.0;    
00195     for ( int j=ystart ; j<yend ; ++j)
00196     {
00197         for (int i=xstart ; i<xend ; ++i)
00198        {
00199            if ( level<2 )
00200                DoME( i , j , level);
00201             MB_cost += DoUnitDecn( i , j ,level );
00202 
00203         }// i
00204     }// j
00205 
00206     // if we've improved on the best cost, we should propagate data in 
00207     // the base level motion vector set
00208     if (level == 2)
00209     {
00210         m_me_data_set[2]->MBSplit()[m_ymb_loc][m_xmb_loc] = 2;
00211         m_me_data_set[2]->MBCommonMode()[m_ymb_loc][m_xmb_loc] = false;
00212         m_me_data_set[2]->MBCosts()[m_ymb_loc][m_xmb_loc] = MB_cost;
00213     }
00214 
00215     if ( level<2 && MB_cost <= m_me_data_set[2]->MBCosts()[m_ymb_loc][m_xmb_loc] )
00216     {
00217         m_me_data_set[2]->MBCosts()[m_ymb_loc][m_xmb_loc] = MB_cost;
00218         m_me_data_set[2]->MBSplit()[m_ymb_loc][m_xmb_loc] = level;
00219         m_me_data_set[2]->MBCommonMode()[m_ymb_loc][m_xmb_loc] = false;
00220 
00221         // Parameters of the base-level blocks corresponding to each
00222         // prediction unit
00223         int xblock_start;
00224         int yblock_start;
00225         int xblock_end;
00226         int yblock_end;
00227 
00228         for ( int j=ystart ; j<yend ; ++j )
00229         {
00230             yblock_start = j<<(2-level);
00231             yblock_end = (j+1)<<(2-level);
00232             for ( int i=xstart ; i<xend ; ++i )
00233             {
00234                 xblock_start = i<<(2-level);
00235                 xblock_end = (i+1)<<(2-level);
00236 
00237                 for ( int v=yblock_start ; v<yblock_end ; ++v )
00238                 {
00239                     for ( int u=xblock_start ; u<xblock_end ; ++u )
00240                     {
00241                         m_me_data_set[2]->Mode()[v][u] = m_me_data_set[level]->Mode()[j][i];
00242                         m_me_data_set[2]->DC( Y_COMP )[v][u] = m_me_data_set[level]->DC( Y_COMP )[j][i];
00243                         m_me_data_set[2]->Vectors(1)[v][u] = m_me_data_set[level]->Vectors(1)[j][i];
00244                         if ( num_refs>1 )
00245                             m_me_data_set[2]->Vectors(2)[v][u] = m_me_data_set[level]->Vectors(2)[j][i];
00246 
00247                     }// u
00248                 }// v
00249 
00250             }// i
00251         }// j
00252 
00253     }
00254 
00255     //     Case 2: prediction modes are all the same
00256 
00257     PredMode predmode;
00258 
00259     MB_cost = DoCommonMode( predmode , level );
00260 
00261     if ( MB_cost <= m_me_data_set[2]->MBCosts()[m_ymb_loc][m_xmb_loc] )
00262     {
00263         m_me_data_set[2]->MBCosts()[m_ymb_loc][m_xmb_loc] = MB_cost;
00264         m_me_data_set[2]->MBSplit()[m_ymb_loc][m_xmb_loc] = level;
00265         m_me_data_set[2]->MBCommonMode()[m_ymb_loc][m_xmb_loc] = true;
00266         // Parameters of the base-level blocks corresponding to each
00267         // prediction unit
00268         int xblock_start;
00269         int yblock_start;
00270         int xblock_end;
00271         int yblock_end;
00272 
00273         for ( int j=ystart ; j<yend ; ++j )
00274         {
00275             yblock_start = j<<(2-level);
00276             yblock_end = (j+1)<<(2-level);
00277             for ( int i=xstart ; i<xend ; ++i )
00278             {
00279                 xblock_start = i<<(2-level);
00280                 xblock_end = (i+1)<<(2-level);
00281                 for ( int v=yblock_start ; v<yblock_end ; ++v )
00282                 {
00283                     for ( int u=xblock_start ; u<xblock_end ; ++u )
00284                     {
00285                         m_me_data_set[2]->Vectors(1)[v][u] = m_me_data_set[level]->Vectors(1)[j][i];
00286                         m_me_data_set[2]->Mode()[v][u] = predmode;
00287                         m_me_data_set[2]->DC( Y_COMP )[v][u] = m_me_data_set[level]->DC( Y_COMP )[j][i];
00288                         if ( num_refs>1 )
00289                             m_me_data_set[2]->Vectors(2)[v][u] = m_me_data_set[level]->Vectors(2)[j][i];
00290 
00291                     }// u
00292                 }// v
00293  
00294             }// i
00295         }// j
00296       }
00297 
00298 }
00299 
00300 
00301 void ModeDecider::DoME(const int xpos , const int ypos , const int level)
00302 {
00303     // Do motion estimation for a prediction unit using the 
00304     // four vectors derived from the next level as a guide
00305 
00306     MEData& me_data = *(m_me_data_set[level]);
00307     const MEData& guide_data = *(m_me_data_set[level+1]);
00308 
00309     // The corresponding location of the guide data
00310     const int guide_xpos = xpos<<1; 
00311     const int guide_ypos = ypos<<1;
00312 
00313     // The location of the lowest level vectors
00314     const int xblock = xpos << ( 2 - level); 
00315     const int yblock = ypos << ( 2 - level);
00316 
00317     // The list of potential candidate vectors
00318     CandidateList cand_list;
00319 
00320     // The lambda to use for motion estimation
00321     const float lambda = me_data.LambdaMap()[ypos][xpos];
00322 
00323     // The predicting motion vector
00324     MVector mv_pred;
00325 
00326     for ( int j=0 ; j<2 ; ++j )
00327         for (int i=0 ; i<2 ; ++i )
00328             AddNewVlist( cand_list , guide_data.Vectors(1)[guide_ypos+j][guide_xpos+i] , 1 , 1 );
00329 
00330     if (xblock>0 && yblock>0)
00331         mv_pred = MvMedian( m_me_data_set[2]->Vectors(1)[yblock][xblock-1] ,
00332                             m_me_data_set[2]->Vectors(1)[yblock-1][xblock-1],
00333                               m_me_data_set[2]->Vectors(1)[yblock-1][xblock]);
00334     else if (xblock==0 && yblock>0)
00335         mv_pred = MvMean( m_me_data_set[2]->Vectors(1)[yblock-1][xblock],
00336                           m_me_data_set[2]->Vectors(1)[yblock-1][xblock+1]);
00337     else if (xblock>0 && yblock==0)
00338         mv_pred = MvMean( m_me_data_set[2]->Vectors(1)[yblock][xblock-1],
00339                           m_me_data_set[2]->Vectors(1)[yblock+1][xblock-1]);
00340     else{
00341         mv_pred.x = 0;
00342         mv_pred.y = 0;
00343     }
00344 
00345     BlockMatcher my_bmatch1( *m_pic_data , *m_ref1_updata , m_encparams.LumaBParams(level) ,
00346                                                      me_data.Vectors(1) , me_data.PredCosts(1) );
00347     me_data.PredCosts(1)[ypos][xpos].total = 100000000.0f;
00348     my_bmatch1.FindBestMatchSubp( xpos , ypos , cand_list, mv_pred, lambda );
00349 
00350     if (num_refs>1)
00351     {//do the same for the other reference
00352 
00353         cand_list.clear();                
00354 
00355         for ( int j=0 ; j<2 ; ++j )
00356         {
00357             for (int i=0 ; i<2 ; ++i )
00358             {
00359                 AddNewVlist( cand_list , guide_data.Vectors(2)[guide_ypos+j][guide_xpos+i] , 1 , 1 );
00360             }// i
00361         }// j
00362 
00363         if (xblock>0 && yblock>0)
00364             mv_pred = MvMedian( m_me_data_set[2]->Vectors(2)[yblock][xblock-1] ,
00365                                              m_me_data_set[2]->Vectors(2)[yblock-1][xblock-1],
00366                                                m_me_data_set[2]->Vectors(2)[yblock-1][xblock]);
00367         else if (xblock==0 && yblock>0)
00368             mv_pred = MvMean( m_me_data_set[2]->Vectors(2)[yblock-1][xblock],
00369                                            m_me_data_set[2]->Vectors(2)[yblock-1][xblock+1]);
00370         else if (xblock>0 && yblock==0)
00371             mv_pred = MvMean( m_me_data_set[2]->Vectors(2)[yblock][xblock-1],
00372                                            m_me_data_set[2]->Vectors(2)[yblock+1][xblock-1]);
00373         else{
00374              mv_pred.x = 0;
00375              mv_pred.y = 0;
00376         }
00377 
00378         BlockMatcher my_bmatch2( *m_pic_data , *m_ref2_updata , m_encparams.LumaBParams(level) ,
00379                                                      me_data.Vectors(2) , me_data.PredCosts(2) );
00380         me_data.PredCosts(2)[ypos][xpos].total = 100000000.0f;
00381         my_bmatch2.FindBestMatchSubp( xpos , ypos , cand_list, mv_pred, lambda );
00382 
00383      }
00384 }
00385 
00386 
00387 
00388 float ModeDecider::DoUnitDecn(const int xpos , const int ypos , const int level )
00389 {
00390     // For a given prediction unit (MB, subMB or block) find the best
00391     // mode, given that the REF1 and REF2 motion estimation has
00392     // already been done.
00393 
00394     MEData& me_data = *( m_me_data_set[level] );
00395 
00396     // Coords of the top-leftmost block belonging to this unit
00397     const int xblock = xpos<<(2-level);
00398     const int yblock = ypos<<(2-level);
00399 
00400     const float loc_lambda = me_data.LambdaMap()[ypos][xpos];
00401 
00402     float unit_cost;
00403     float mode_cost;
00404     float min_unit_cost;
00405  
00406     BlockDiffParams dparams;
00407 
00408     dparams.SetBlockLimits( m_encparams.LumaBParams( level ) , *m_pic_data, xpos , ypos);
00409 
00410      // First check REF1 costs //
00411     /**************************/
00412 
00413     mode_cost = ModeCost( xblock , yblock , REF1_ONLY)*m_mode_factor[level];
00414     me_data.Mode()[ypos][xpos] = REF1_ONLY;
00415     me_data.PredCosts(1)[ypos][xpos].total *= m_level_factor[level];
00416     min_unit_cost = me_data.PredCosts(1)[ypos][xpos].total + mode_cost;
00417 
00418     // Calculate the cost if we were to code the block as intra //
00419     /************************************************************/
00420 
00421     mode_cost = ModeCost( xblock , yblock , INTRA) * m_mode_factor[level];
00422     me_data.IntraCosts()[ypos][xpos] = m_intradiff->Diff( dparams , me_data.DC( Y_COMP )[ypos][xpos] );
00423     me_data.IntraCosts()[ypos][xpos] += loc_lambda * 
00424                                        GetDCVar( me_data.DC( Y_COMP )[ypos][xpos] , GetDCPred( xblock , yblock ) );
00425     me_data.IntraCosts()[ypos][xpos] *= m_level_factor[level];
00426     unit_cost = me_data.IntraCosts()[ypos][xpos] +  mode_cost;
00427 
00428     if ( unit_cost<min_unit_cost )
00429     {
00430         me_data.Mode()[ypos][xpos] = INTRA;
00431         min_unit_cost = unit_cost;
00432     }
00433 
00434     if (num_refs>1)
00435     {
00436        // Next check REF2 costs //
00437        /*************************/
00438 
00439         mode_cost = ModeCost( xblock , yblock , REF2_ONLY)*m_mode_factor[level];
00440         me_data.PredCosts(2)[ypos][xpos].total *= m_level_factor[level];
00441         unit_cost = me_data.PredCosts(2)[ypos][xpos].total + mode_cost;
00442         if ( unit_cost<min_unit_cost )
00443         {
00444             me_data.Mode()[ypos][xpos] = REF2_ONLY;
00445             min_unit_cost = unit_cost;
00446         }
00447 
00448         // Finally, calculate the cost if we were to use bi-predictions //
00449         /****************************************************************/
00450 /*
00451         mode_cost = ModeCost( xpos , ypos , REF1AND2 )*m_mode_factor[level];
00452 
00453         me_data.BiPredCosts()[ypos][xpos].mvcost =
00454                                        me_data.PredCosts(1)[ypos][xpos].mvcost+
00455                                        me_data.PredCosts(2)[ypos][xpos].mvcost;
00456         
00457         me_data.BiPredCosts()[ypos][xpos].SAD = m_bicheckdiff->Diff(dparams , 
00458                                                   me_data.Vectors(1)[ypos][xpos] , 
00459                                                   me_data.Vectors(2)[ypos][xpos] );
00460 
00461         me_data.BiPredCosts()[ypos][xpos].SetTotal( loc_lambda );
00462 
00463         me_data.BiPredCosts()[ypos][xpos].total *= m_level_factor[level];
00464         unit_cost = me_data.BiPredCosts()[ypos][xpos].total + mode_cost;
00465 
00466         if ( unit_cost<min_unit_cost )
00467         {
00468             me_data.Mode()[ypos][xpos] = REF1AND2;
00469             min_unit_cost = unit_cost;
00470         }
00471 */
00472     }
00473 
00474     return min_unit_cost;
00475 }
00476 
00477 float ModeDecider::DoCommonMode( PredMode& predmode , const int level)
00478 {
00479     // For a given level, examine the costs in the constituent
00480     // prediction units of the MB at that level and decide 
00481     // whether there should be a common prediction mode or not.
00482 
00483     const MEData& me_data = *( m_me_data_set[level] );
00484 
00485     // The total cost for the MB for each possible prediction mode
00486     OneDArray<float> MB_cost(4);
00487     for ( int i=0 ; i<4 ; ++i)
00488         MB_cost[i] = ModeCost( m_xmb_loc<<2 , m_ymb_loc , PredMode(i) )*m_mode_factor[0];
00489 
00490     // The limits of the prediction units
00491     const int xstart = m_xmb_loc <<level;
00492     const int ystart = m_ymb_loc <<level;
00493 
00494     const int xend = xstart + (1<<level);
00495     const int yend = ystart + (1<<level);
00496 
00497     for (int j=ystart ; j<yend ; ++j)
00498     {
00499         for (int i=xstart ; i<xend ; ++i)
00500         {
00501             MB_cost[INTRA] += me_data.IntraCosts()[j][i];
00502             MB_cost[REF1_ONLY] += me_data.PredCosts(1)[j][i].total;
00503             if ( num_refs>1 )
00504             {
00505                 MB_cost[REF2_ONLY] += me_data.PredCosts(2)[j][i].total;
00506 //                MB_cost[REF1AND2] += me_data.BiPredCosts()[j][i].total;
00507             }
00508         }// i
00509     }// i
00510 
00511 
00512     // Find the minimum
00513     predmode = INTRA;
00514     if ( MB_cost[REF1_ONLY]<MB_cost[predmode] )
00515         predmode = REF1_ONLY;
00516 
00517     if ( num_refs>1)
00518     {
00519         if ( MB_cost[REF2_ONLY]<MB_cost[predmode] )
00520             predmode = REF2_ONLY;
00521 //         if ( MB_cost[REF1AND2]<MB_cost[predmode] )
00522 //             predmode = REF1AND2;
00523     }
00524  
00525     return MB_cost[predmode];
00526 }
00527 
00528 ValueType ModeDecider::GetDCPred( int xblock , int yblock )
00529 {
00530     ValueType dc_pred = 128;
00531 
00532     if ( xblock>0 && m_me_data_set[2]->Mode()[yblock][xblock-1] == INTRA )
00533     {
00534         dc_pred = m_me_data_set[2]->DC( Y_COMP )[yblock][xblock-1];
00535         if ( yblock>0 && m_me_data_set[2]->Mode()[yblock-1][xblock] == INTRA )
00536         {
00537             dc_pred += m_me_data_set[2]->DC( Y_COMP )[yblock-1][xblock];
00538             dc_pred >>= 1;
00539         }
00540     }
00541      
00542     return dc_pred;
00543 }
00544 
00545 float ModeDecider::ModeCost(const int xindex , const int yindex , 
00546                  const PredMode predmode )
00547 {
00548     // Computes the variation of the given mode, predmode, from its immediate neighbours
00549     // Currently, includes branches to cope with blocks on the edge of the picture.
00550     int i ,j;
00551     float diff;
00552     float var = 0.0;
00553 
00554     i = xindex-1;
00555     j = yindex;
00556     if ( i>=0)
00557     {
00558         diff = static_cast<float>( m_me_data_set[2]->Mode()[j][i] - predmode );
00559         var = std::abs( diff );
00560     }
00561 
00562     i = xindex-1;
00563     j = yindex-1;
00564     if ( i>=0 && j>=0)
00565     {
00566         diff = static_cast<float>( m_me_data_set[2]->Mode()[j][i] - predmode);
00567         var += std::abs( diff );
00568     }
00569 
00570     i = xindex;
00571     j = yindex-1;
00572     if ( j>=0 )
00573     {
00574         diff = static_cast<float>( m_me_data_set[2]->Mode()[j][i] - predmode );
00575         var += std::abs( diff );
00576     }
00577 
00578     return var*m_me_data_set[2]->LambdaMap()[yindex][xindex];
00579 }
00580 
00581 float ModeDecider::GetDCVar( const ValueType dc_val , const ValueType dc_pred)
00582 {
00583     return 8.0*std::abs( static_cast<float>( dc_val - dc_pred ) );
00584 }

Generated on Tue Dec 13 14:47:17 2005 for guliverkli by  doxygen 1.4.5