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

多媒体编程

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. *
  3. * $Id: me_utils.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), Peter Meerwald (pmeerw@users.sourceforge.net)
  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. ///////////////////////////////////
  38. //-------------------------------//
  39. //utilities for motion estimation//
  40. //-------------------------------//
  41. ///////////////////////////////////
  42. #include <libdirac_motionest/me_utils.h>
  43. #include <libdirac_common/common.h>
  44. using namespace dirac;
  45. #include <algorithm>
  46. void BlockDiffParams::SetBlockLimits( const OLBParams& bparams ,
  47.                                       const PicArray& pic_data , 
  48.                                       const int xbpos , const int ybpos)
  49. {
  50.     const int loc_xp = xbpos * bparams.Xbsep() - bparams.Xoffset();
  51.     const int loc_yp = ybpos * bparams.Ybsep() - bparams.Yoffset();
  52.     m_xp=std::max( loc_xp , 0 );
  53.     m_yp=std::max( loc_yp , 0 );
  54.     m_xl = bparams.Xblen() - m_xp + loc_xp;
  55.     m_yl = bparams.Yblen() - m_yp + loc_yp;
  56.      //constrain block lengths to fall within the picture
  57.     m_xl = ( ( m_xp + m_xl - 1) > pic_data.LastX() ) ? ( pic_data.LastX() + 1 - m_xp ): m_xl;
  58.     m_yl = ( ( m_yp + m_yl - 1) > pic_data.LastY() ) ? ( pic_data.LastY() + 1 - m_yp ) : m_yl;
  59. }
  60. // Block difference class functions
  61. // Constructors ...
  62. BlockDiff::BlockDiff(const PicArray& ref,const PicArray& pic) :
  63.     pic_data( pic ),
  64.     ref_data( ref )
  65. {}
  66. SimpleBlockDiff::SimpleBlockDiff( const PicArray& ref , const PicArray& pic ) :
  67.     BlockDiff( ref , pic )
  68. {}
  69. BChkBlockDiff::BChkBlockDiff( const PicArray& ref , const PicArray& pic ) :
  70.     BlockDiff( ref , pic )
  71. {}    
  72. IntraBlockDiff::IntraBlockDiff( const PicArray& pic ) :
  73.     pic_data( pic )
  74. {}
  75. BiBlockDiff::BiBlockDiff( const PicArray& ref1 , const PicArray& ref2 ,
  76.                           const PicArray& pic) :
  77.     pic_data( pic ),
  78.     ref_data1( ref1 ),
  79.     ref_data2( ref2 )
  80. {}
  81. BiSimpleBlockDiff::BiSimpleBlockDiff( const PicArray& ref1 , const PicArray& ref2 ,
  82.                                       const PicArray& pic) :
  83.     BiBlockDiff(ref1 , ref2 , pic)
  84. {}
  85. BiBChkBlockDiff::BiBChkBlockDiff( const PicArray& ref1 , const PicArray& ref2 ,
  86.                                   const PicArray& pic ) :
  87.     BiBlockDiff(ref1 , ref2 , pic)
  88. {}
  89. BlockDiffUp::BlockDiffUp( const PicArray& ref , const PicArray& pic):
  90.     BlockDiff( ref , pic )
  91. {}
  92. SimpleBlockDiffUp::SimpleBlockDiffUp( const PicArray& ref , const PicArray& pic ) :
  93.     BlockDiffUp( ref , pic )
  94. {}
  95. BChkBlockDiffUp::BChkBlockDiffUp(const PicArray& ref,const PicArray& pic) :
  96.     BlockDiffUp( ref , pic )
  97. {}
  98. BiBlockDiffUp::BiBlockDiffUp( const PicArray& ref1 , const PicArray& ref2 , 
  99.                               const PicArray& pic) :
  100.     BiBlockDiff( ref1 , ref2 , pic )
  101. {}
  102. BiSimpleBlockDiffUp::BiSimpleBlockDiffUp( const PicArray& ref1 , const PicArray& ref2 ,
  103.                                           const PicArray& pic ):
  104.     BiBlockDiffUp( ref1 , ref2 , pic)
  105. {}
  106. BiBChkBlockDiffUp::BiBChkBlockDiffUp( const PicArray& ref1 , const PicArray& ref2 , 
  107.                                       const PicArray& pic ) :
  108.     BiBlockDiffUp( ref1 , ref2 , pic)
  109. {}
  110. // Difference functions ...
  111. float SimpleBlockDiff::Diff( const BlockDiffParams& dparams, const MVector& mv )
  112. {
  113.     ValueType diff;    
  114.     CalcValueType sum( 0 );
  115.     for (int j=dparams.Yp() ; j != dparams.Yp()+dparams.Yl() ; ++j )
  116.     {
  117.         for(int i=dparams.Xp() ; i!= dparams.Xp()+dparams.Xl() ; ++i )
  118.         {
  119.             diff = pic_data[j][i]-ref_data[j+mv.y][i+mv.x];
  120.             sum += std::abs( diff );
  121.         }// i, k
  122.     }// j, l
  123.     return static_cast<float>( sum );
  124. }
  125. float BChkBlockDiff::Diff( const BlockDiffParams& dparams, const MVector& mv )
  126. {
  127.     const int xmax = ref_data.LengthX();
  128.     const int ymax = ref_data.LengthY();
  129.     ValueType diff;
  130.     CalcValueType sum( 0 );
  131.     for ( int j=dparams.Yp() ; j!=dparams.Yp()+dparams.Yl() ; ++j )
  132.     {
  133.         for( int i=dparams.Xp() ; i!=dparams.Xp()+dparams.Xl() ; ++i )
  134.         {
  135.             diff = pic_data[j][i] - ref_data[BChk(j+mv.y , ymax)][BChk(i+mv.x , xmax)];
  136.             sum += std::abs( diff );
  137.         }// i
  138.     }// j
  139.     
  140.     return static_cast<float>( sum );
  141. }
  142. float IntraBlockDiff::Diff( const BlockDiffParams& dparams , ValueType& dc_val )
  143. {
  144.      //computes the cost if block is predicted by its dc component
  145.     CalcValueType int_dc( 0 );
  146.     for ( int j=dparams.Yp() ; j!=dparams.Yp()+dparams.Yl() ; ++j)
  147.         for(int i=dparams.Xp(); i!=dparams.Xp()+dparams.Xl() ; ++i )
  148.             int_dc += static_cast<int>( pic_data[j][i] );
  149.     int_dc /= ( dparams.Xl() * dparams.Yl() );
  150.     // Just give dc to 8-bit accuracy
  151.     dc_val = static_cast<ValueType>( (int_dc+2)>>2 );
  152.     // Now compute the resulting SAD
  153.     ValueType dc( dc_val<<2 );
  154.     CalcValueType intra_cost( 0 );
  155.     for (int j=dparams.Yp(); j!=dparams.Yp()+dparams.Yl() ; ++j)
  156.         for( int i=dparams.Xp() ; i!=dparams.Xp()+dparams.Xl() ;++i )
  157.             intra_cost += std::abs( pic_data[j][i] - dc );
  158.     
  159.     return static_cast<float>( intra_cost );
  160. }
  161. float BiSimpleBlockDiff::Diff( const BlockDiffParams& dparams, const MVector& mv1,const MVector& mv2){
  162.     CalcValueType sum( 0 );
  163.     ValueType diff;
  164.     for ( int j=dparams.Yp(); j!=dparams.Yp()+dparams.Yl(); ++j )
  165.     {
  166.         for( int i=dparams.Xp() ; i!=dparams.Xp()+dparams.Xl() ; ++i )
  167.         {
  168.             diff = pic_data[j][i]-( ( ref_data1[j+mv1.y][i+mv1.x] + 1 )>>1 );
  169.             diff -= ( ( ref_data2[j+mv2.y][i+mv2.x] + 1 )>>1 );
  170.             sum += std::abs( diff );
  171.         }// i
  172.     }// j
  173.     return static_cast<float>( sum );
  174. }
  175. float BiBChkBlockDiff::Diff( const BlockDiffParams& dparams, const MVector& mv1,const MVector& mv2){
  176.     ValueType diff;
  177.     const int xmax1 = ref_data1.LengthX();
  178.     const int ymax1 = ref_data1.LengthY();
  179.     const int xmax2 = ref_data2.LengthX();
  180.     const int ymax2 = ref_data2.LengthY();
  181.     CalcValueType sum( 0 );
  182.     for ( int j=dparams.Yp() ; j!=dparams.Yp() + dparams.Yl() ; ++j )
  183.     {
  184.         for( int i=dparams.Xp() ; i!=dparams.Xp() + dparams.Xl() ; ++i )
  185.         {
  186.             diff = pic_data[j][i]-( ( ref_data1[BChk(j+mv1.y , ymax1)][BChk(i+mv1.x , xmax1)] + 1 )>>1 );
  187.             diff -= ( ( ref_data2[BChk(j+mv2.y , ymax2)][BChk(i+mv2.x , xmax2)] + 1 )>>1 );
  188.             sum += std::abs( diff );       
  189.         }// i
  190.     }// j
  191.     return static_cast<float>( sum );
  192. }
  193. float SimpleBlockDiffUp::Diff( const BlockDiffParams& dparams, const MVector& mv )
  194. {
  195.     //Coordinates in the image being written to
  196.     const ImageCoords StartPos(dparams.Xp(),dparams.Yp());
  197.     const ImageCoords EndPos(StartPos.x+dparams.Xl(),StartPos.y+dparams.Yl());
  198.     //the rounded motion vectors, accurate to 1/2 pel
  199.     //NB: bitshift rounds negative numbers DOWN, as required    
  200.     const MVector roundvec(mv.x>>2,mv.y>>2);
  201.     //remainder, giving 1/8 pel accuracy, needed for linear interp
  202.     const MVector rmdr(mv.x-(roundvec.x<<2),mv.y-(roundvec.y<<2));
  203.     //Set up the start point in the reference image.    
  204.     const ImageCoords RefStart((StartPos.x<<1) + roundvec.x,(StartPos.y<<1) + roundvec.y);
  205.     //weights for doing linear interpolation, calculated from the remainder values
  206.     const ValueType TLweight((4-rmdr.x)*(4-rmdr.y));
  207.     const ValueType TRweight(rmdr.x*(4-rmdr.y));
  208.     const ValueType BLweight((4-rmdr.x)*rmdr.y);
  209.     const ValueType BRweight(rmdr.x*rmdr.y);    
  210.     CalcValueType sum( 0 );
  211.     ValueType temp;    
  212.     for(int c = StartPos.y, uY = RefStart.y; c < EndPos.y; ++c, uY += 2){
  213.         for(int l = StartPos.x, uX = RefStart.x; l < EndPos.x; ++l, uX += 2){
  214.             temp = (
  215.                     TLweight * ref_data[uY][uX] +
  216.                     TRweight * ref_data[uY][uX+1] +
  217.                     BLweight * ref_data[uY+1][uX] +
  218.                     BRweight * ref_data[uY+1][uX+1] +
  219.                     8
  220.                     )>>4;
  221.             sum += std::abs( pic_data[c][l] - temp );
  222.         }//l
  223.     }//c
  224.     return static_cast<float>( sum );    
  225. }
  226. float BChkBlockDiffUp::Diff(  const BlockDiffParams& dparams, const MVector& mv )
  227. {
  228.     //the picture sizes
  229.     const int DoubleXdim=ref_data.LengthX();
  230.     const int DoubleYdim=ref_data.LengthY();
  231.     //Coordinates in the image being written to
  232.     const ImageCoords StartPos(dparams.Xp(),dparams.Yp());
  233.     const ImageCoords EndPos(StartPos.x+dparams.Xl(),StartPos.y+dparams.Yl());
  234.     //the rounded motion vectors, accurate to 1/2 pel
  235.     //NB: bitshift rounds negative numbers DOWN, as required    
  236.     const MVector roundvec(mv.x>>2,mv.y>>2);
  237.     //remainder, giving 1/8 pel accuracy, needed for linear interp
  238.     const MVector rmdr(mv.x-(roundvec.x<<2),mv.y-(roundvec.y<<2));
  239.     //Set up the start point in the reference image.    
  240.     const ImageCoords RefStart((StartPos.x<<1) + roundvec.x,(StartPos.y<<1) + roundvec.y);
  241.     //weights for doing linear interpolation, calculated from the remainder values
  242.     const ValueType    TLweight((4-rmdr.x)*(4-rmdr.y));
  243.     const ValueType    TRweight(rmdr.x*(4-rmdr.y));
  244.     const ValueType    BLweight((4-rmdr.x)*rmdr.y);
  245.     const ValueType    BRweight(rmdr.x*rmdr.y);    
  246.     CalcValueType sum( 0 );
  247.     ValueType temp;
  248.     for(int c = StartPos.y, uY = RefStart.y; c < EndPos.y; ++c, uY += 2)
  249.     {
  250.         for(int l = StartPos.x, uX = RefStart.x; l < EndPos.x; ++l, uX += 2)
  251.         {
  252.             temp = (
  253.                     TLweight * ref_data[BChk(uY,DoubleYdim)][BChk(uX,DoubleXdim)] +
  254.                     TRweight * ref_data[BChk(uY,DoubleYdim)][BChk(uX+1,DoubleXdim)] +
  255.                     BLweight * ref_data[BChk(uY+1,DoubleYdim)][BChk(uX,DoubleXdim)] +
  256.                     BRweight * ref_data[BChk(uY+1,DoubleYdim)][BChk(uX+1,DoubleXdim)] +
  257.                     8
  258.                     )>>4;
  259.             sum += ( std::abs( pic_data[c][l] - temp ) );
  260.         }//l
  261.     }//c    
  262.     return static_cast<float>( sum );
  263. }
  264. float BiSimpleBlockDiffUp::Diff( const BlockDiffParams& dparams, const MVector& mv1, const MVector& mv2){
  265.     //the start and end points in the current frame
  266.     const ImageCoords StartPos(dparams.Xp(),dparams.Yp());//Coordinates in the current image
  267.     const ImageCoords EndPos(StartPos.x+dparams.Xl(),StartPos.y+dparams.Yl());    
  268.     //the motion vectors rounded to 1/2 pel accuracy
  269.     const MVector roundvec1(mv1.x>>2,mv1.y>>2);
  270.     const MVector roundvec2(mv2.x>>2,mv2.y>>2);
  271.     //the remainders giving 1/8 pel accuracy    
  272.     const MVector rmdr1(mv1.x-(roundvec1.x<<2),mv1.y-(roundvec1.y<<2));
  273.     const MVector rmdr2(mv2.x-(roundvec2.x<<2),mv2.y-(roundvec2.y<<2));
  274.     //the starting points of the reference blocks in the reference images, to 1/2 pel accuracy
  275.     const ImageCoords RefStart1((StartPos.x<<1) + roundvec1.x,(StartPos.y<<1) + roundvec1.y);
  276.     const ImageCoords RefStart2((StartPos.x<<1) + roundvec2.x,(StartPos.y<<1) + roundvec2.y);
  277.     //weights for doing linear interpolation, calculated from the remainder values
  278.     const ValueType    TLweight1((4-rmdr1.x)*(4-rmdr1.y));
  279.     const ValueType    TRweight1(rmdr1.x*(4-rmdr1.y));
  280.     const ValueType    BLweight1((4-rmdr1.x)*rmdr1.y);
  281.     const ValueType    BRweight1(rmdr1.x*rmdr1.y);        
  282.     const ValueType    TLweight2((4-rmdr2.x)*(4-rmdr2.y));
  283.     const ValueType    TRweight2(rmdr2.x*(4-rmdr2.y));
  284.     const ValueType    BLweight2((4-rmdr2.x)*rmdr2.y);
  285.     const ValueType    BRweight2(rmdr2.x*rmdr2.y);        
  286.     CalcValueType temp;
  287.     CalcValueType sum( 0 );
  288.     for(int c = StartPos.y, uY1 = RefStart1.y,uY2=RefStart2.y; c < EndPos.y; ++c, uY1 += 2,uY2 += 2){
  289.         for(int l = StartPos.x, uX1 = RefStart1.x,uX2=RefStart2.x; l < EndPos.x; ++l, uX1 += 2, uX2 += 2){
  290.             temp = (
  291.                     TLweight1 * ref_data1[uY1][uX1] +
  292.                     TRweight1 * ref_data1[uY1][uX1+1] +
  293.                     BLweight1 * ref_data1[uY1+1][uX1] +
  294.                     BRweight1 * ref_data1[uY1+1][uX1+1] +
  295.                     16
  296.                     )>>5;
  297.             temp += (
  298.                     TLweight2 * ref_data2[uY2][uX2] +
  299.                     TRweight2 * ref_data2[uY2][uX2+1] +
  300.                     BLweight2 * ref_data2[uY2+1][uX2] +
  301.                     BRweight2 * ref_data2[uY2+1][uX2+1] +
  302.                     16
  303.                     )>>5;
  304.             sum += std::abs( pic_data[c][l] - temp );
  305.         }//l
  306.     }//c    
  307.     return static_cast<float>( sum );   
  308. }
  309. float BiBChkBlockDiffUp::Diff( const BlockDiffParams& dparams, const MVector& mv1, const MVector& mv2)
  310. {
  311.     //as above, but with bounds checking
  312.     const int xmax1 = ref_data1.LengthX(); 
  313.     const int ymax1 = ref_data1.LengthY();
  314.     const int xmax2 = ref_data2.LengthX(); 
  315.     const int ymax2 = ref_data2.LengthY();    
  316.     //the start and end points in the current frame
  317.     const ImageCoords StartPos(dparams.Xp(),dparams.Yp());//Coordinates in the current image
  318.     const ImageCoords EndPos(StartPos.x+dparams.Xl(),StartPos.y+dparams.Yl());    
  319.     //the motion vectors rounded to 1/2 pel accuracy
  320.     const MVector roundvec1(mv1.x>>2,mv1.y>>2);
  321.     const MVector roundvec2(mv2.x>>2,mv2.y>>2);
  322.     //the remainders giving 1/8 pel accuracy    
  323.     const MVector rmdr1(mv1.x-(roundvec1.x<<2),mv1.y-(roundvec1.y<<2));
  324.     const MVector rmdr2(mv2.x-(roundvec2.x<<2),mv2.y-(roundvec2.y<<2));
  325.     //the starting points of the reference blocks in the reference images, to 1/2 pel accuracy
  326.     const ImageCoords RefStart1((StartPos.x<<1) + roundvec1.x,(StartPos.y<<1) + roundvec1.y);
  327.     const ImageCoords RefStart2((StartPos.x<<1) + roundvec2.x,(StartPos.y<<1) + roundvec2.y);
  328.     //weights for doing linear interpolation, calculated from the remainder values
  329.     const ValueType TLweight1((4-rmdr1.x)*(4-rmdr1.y));
  330.     const ValueType TRweight1(rmdr1.x*(4-rmdr1.y));
  331.     const ValueType BLweight1((4-rmdr1.x)*rmdr1.y);
  332.     const ValueType BRweight1(rmdr1.x*rmdr1.y);        
  333.     const ValueType TLweight2((4-rmdr2.x)*(4-rmdr2.y));
  334.     const ValueType TRweight2(rmdr2.x*(4-rmdr2.y));
  335.     const ValueType BLweight2((4-rmdr2.x)*rmdr2.y);
  336.     const ValueType BRweight2(rmdr2.x*rmdr2.y);        
  337.     CalcValueType temp;
  338.     CalcValueType sum( 0 );
  339.     for(int c = StartPos.y, uY1 = RefStart1.y,uY2=RefStart2.y; c < EndPos.y; ++c, uY1 += 2,uY2 += 2)
  340.     {
  341.         for(int l = StartPos.x, uX1 = RefStart1.x,uX2=RefStart2.x; l < EndPos.x; ++l, uX1 += 2, uX2 += 2)
  342.         {
  343.             temp = (
  344.                     TLweight1 * ref_data1[BChk(uY1,ymax1)][BChk(uX1,xmax1)] +
  345.                     TRweight1 * ref_data1[BChk(uY1,ymax1)][BChk(uX1+1,xmax1)] +
  346.                     BLweight1 * ref_data1[BChk(uY1+1,ymax1)][BChk(uX1,xmax1)] +
  347.                     BRweight1 * ref_data1[BChk(uY1+1,ymax1)][BChk(uX1+1,xmax1)] +
  348.                     16)>>5;
  349.             temp += (
  350.                     TLweight2 * ref_data2[BChk(uY2,ymax2)][BChk(uX2,xmax2)] +
  351.                     TRweight2 * ref_data2[BChk(uY2,ymax2)][BChk(uX2+1,xmax2)] +
  352.                     BLweight2 * ref_data2[BChk(uY2+1,ymax2)][BChk(uX2,xmax2)] +
  353.                     BRweight2 * ref_data2[BChk(uY2+1,ymax2)][BChk(uX2+1,xmax2)]+
  354.                     16)>>5;
  355.             sum += std::abs( pic_data[c][l] - temp );
  356.         }//l
  357.     }//c    
  358.     return static_cast<float>( sum );
  359. }