00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
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
00054
00055
00056
00057
00058
00059
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
00087
00088
00089
00090 int ref1,ref2;
00091
00092
00094
00095 fsort = my_buffer.GetFrame(frame_num).GetFparams().FSort();
00096 if (fsort != I_frame)
00097 {
00098
00099 const vector<int>& refs = my_buffer.GetFrame(frame_num).GetFparams().Refs();
00100 num_refs = refs.size();
00101 ref1 = refs[0];
00102
00103
00104 m_pic_data = &(my_buffer.GetComponent( frame_num , Y_COMP));
00105
00106
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
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
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
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
00137 m_intradiff = new IntraBlockDiff( *m_pic_data );
00138
00139
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 }
00148 }
00149
00150 delete m_intradiff;
00151 if (num_refs>1)
00152 delete m_bicheckdiff;
00153 }
00154 }
00155
00156 void ModeDecider::DoMBDecn()
00157 {
00158
00159
00160
00161 DoLevelDecn(2);
00162 float old_best_MB_cost = m_me_data_set[2]->MBCosts()[m_ymb_loc][m_xmb_loc];
00163
00164
00165 DoLevelDecn(1);
00166
00167
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
00179
00180
00181
00182
00183
00184
00185
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
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 }
00204 }
00205
00206
00207
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
00222
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 }
00248 }
00249
00250 }
00251 }
00252
00253 }
00254
00255
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
00267
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 }
00292 }
00293
00294 }
00295 }
00296 }
00297
00298 }
00299
00300
00301 void ModeDecider::DoME(const int xpos , const int ypos , const int level)
00302 {
00303
00304
00305
00306 MEData& me_data = *(m_me_data_set[level]);
00307 const MEData& guide_data = *(m_me_data_set[level+1]);
00308
00309
00310 const int guide_xpos = xpos<<1;
00311 const int guide_ypos = ypos<<1;
00312
00313
00314 const int xblock = xpos << ( 2 - level);
00315 const int yblock = ypos << ( 2 - level);
00316
00317
00318 CandidateList cand_list;
00319
00320
00321 const float lambda = me_data.LambdaMap()[ypos][xpos];
00322
00323
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 {
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 }
00361 }
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
00391
00392
00393
00394 MEData& me_data = *( m_me_data_set[level] );
00395
00396
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
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
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
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
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472 }
00473
00474 return min_unit_cost;
00475 }
00476
00477 float ModeDecider::DoCommonMode( PredMode& predmode , const int level)
00478 {
00479
00480
00481
00482
00483 const MEData& me_data = *( m_me_data_set[level] );
00484
00485
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
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
00507 }
00508 }
00509 }
00510
00511
00512
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
00522
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
00549
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 }