/* ***** BEGIN LICENSE BLOCK ***** * * $Id: me_utils.h,v 1.12 2006/04/20 10:41:58 asuraparaju Exp $ $Name: Dirac_0_7_0 $ * * Version: MPL 1.1/GPL 2.0/LGPL 2.1- * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. * * The Original Code is BBC Research and Development code. * * The Initial Developer of the Original Code is the British Broadcasting * Corporation. * Portions created by the Initial Developer are Copyright (C) 2004. * All Rights Reserved. * * Contributor(s): Thomas Davies (Original Author) * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser * Public License Version 2.1 (the "LGPL"), in which case the provisions of * the GPL or the LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the either * the GPL or LGPL and not to allow others to use your version of this file * under the MPL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by the GPL * or LGPL. If you do not delete the provisions above, a recipient may use * your version of this file under the terms of any one of the MPL, the GPL * or the LGPL. * ***** END LICENSE BLOCK ***** */ #ifndef _ME_UTILS_H_ #define _ME_UTILS_H_ #include #include #include namespace dirac { /////////////////////////////////// //Utilities for motion estimation// //-------------------------------// /////////////////////////////////// //! A class encapsulating parameters for calculating a block difference value (a single instance of matching) class BlockDiffParams { public: //! Constructor BlockDiffParams(){} //! Constructor BlockDiffParams( const int x_p , const int y_p , const int x_l , const int y_l): m_xp(x_p), m_yp(y_p), m_xl(x_l), m_yl(y_l), m_xend(x_l+x_p), m_yend(y_l+y_p) {} //////////////////////////////////////////////////////////////////// //NB: Assume default copy constructor, assignment = and destructor// //////////////////////////////////////////////////////////////////// // Sets ... //! Set the limits of the block to fit in a picture void SetBlockLimits( const OLBParams& bparams , const PicArray& pic_data , const int xbpos , const int ybpos); // ... and gets //! Return the x-position of the top-left block corner const int Xp() const {return m_xp;} //! Return the y-position of the top-left block corner const int Yp() const {return m_yp;} //! Return the block width const int Xl() const {return m_xl;} //! Return the block height const int Yl() const {return m_yl;} //! Return the block horizontal endpoint const int Xend() const {return m_xend;} //! Return the block vertical endpoint const int Yend() const {return m_yend;} private: int m_xp; int m_yp; int m_xl; int m_yl; int m_xend; int m_yend; }; ////////////////////////////////////////////////// //----Different difference classes, so that-----// //bounds-checking need only be done as necessary// ////////////////////////////////////////////////// //! An abstract class for doing block difference calculations class BlockDiff { public: //! Constructor, initialising the reference and picture data /* Constructor, initialising the reference and picture data \param ref the reference picture \param pic the picture being matched */ BlockDiff( const PicArray& ref , const PicArray& pic ); //! Destructor virtual ~BlockDiff(){} //! Do the difference, returning SAD /*! Do the difference, returning SAD \param dparams block parameters \param mv the motion vector being used */ virtual float Diff( const BlockDiffParams& dparams , const MVector& mv )=0; protected: const PicArray& m_pic_data; const PicArray& m_ref_data; private: //! Private, bodyless copy-constructor: class should not be copied BlockDiff( const BlockDiff& cpy ); //! Private, bodyless assignment=: class should not be assigned BlockDiff& operator=( const BlockDiff& rhs ); }; //! A class for doing block differences to pixel accuracy, inherited from BlockDiff class PelBlockDiff: public BlockDiff { public: //! Constructor, initialising the reference and picture data /* Constructor, initialising the reference and picture data \param ref the reference picture \param pic the picture being matched */ PelBlockDiff( const PicArray& ref , const PicArray& pic ); //! Do the difference, returning SAD /*! Do the difference, returning SAD \param dparams block parameters \param mv the motion vector being used */ float Diff( const BlockDiffParams& dparams , const MVector& mv ); //! Do the difference, overwriting the best MV so far if appropriate /*! Do the difference, overwriting the best MV so far if appropriate, and bailing out if we do worse \param dparams block parameters \param mv the motion vector being used \param best_sum the best SAD value obtain yet \param best_mv the MV giving the best SAD value so far */ void Diff( const BlockDiffParams& dparams , const MVector& mv , float& best_sum , MVector& best_mv ); private: //! Private, bodyless copy-constructor: class should not be copied PelBlockDiff(const PelBlockDiff& cpy); //! Private, bodyless assignment=: class should not be assigned PelBlockDiff& operator=(const PelBlockDiff& rhs); }; //! A class for calculating the difference between a block and its DC value (average) class IntraBlockDiff { public: //! Constructor, initialising the picture data /* Constructor, initialising the picture data \param pic the picture being matched */ IntraBlockDiff( const PicArray& pic ); //! Do the difference, returning SAD /*! Do the difference, returning SAD \param dparams block parameters \param dc_val DC value */ float Diff( const BlockDiffParams& dparams , ValueType& dc_val ); private: //! Private, bodyless copy-constructor: class should not be copied IntraBlockDiff(const IntraBlockDiff& cpy); //! Private, bodyless assignment=: class should not be assigned IntraBlockDiff& operator=(const IntraBlockDiff& rhs); const PicArray& m_pic_data; }; //! A virtual class for bi-directional differences class BiBlockDiff { public: //! Constructor, initialising the references and picture data /* Constructor, initialising the references and picture data \param ref1 the first reference picture \param ref2 the second reference picture \param pic the picture being matched */ BiBlockDiff( const PicArray& ref1 , const PicArray& ref2 , const PicArray& pic); //! Virtual destructor virtual ~BiBlockDiff( ) {} //! Do the difference, returning SAD /*! Do the difference, returning SAD \param dparams block parameters \param mv1 the motion vector being used for reference 1 \param mv2 the motion vector being used for reference 2 */ virtual float Diff( const BlockDiffParams& dparams , const MVector& mv1 , const MVector& mv2 )=0; protected: const PicArray& m_pic_data; const PicArray& m_ref_data1; const PicArray& m_ref_data2; private: //! Private, bodyless copy-constructor: class should not be copied BiBlockDiff(const BiBlockDiff& cpy); //! Private, bodyless assignment=: class should not be assigned BiBlockDiff& operator=(const BiBlockDiff& rhs); }; // Classes where the reference is upconverted // //////////////////////////////////////////////// //! A virtual class for doing differences with sub-pixel vectors class BlockDiffUp: public BlockDiff { public: //! Constructor, initialising the reference and picture data /* Constructor, initialising the reference and picture data \param ref the reference picture \param pic the picture being matched */ BlockDiffUp( const PicArray& ref , const PicArray& pic ); //! Destructor virtual ~BlockDiffUp(){} //! Do the difference, returning SAD /*! Do the difference, returning SAD \param dparams block parameters \param mv the motion vector being used */ virtual float Diff( const BlockDiffParams& dparams , const MVector& mv )=0; //! Do the actual difference, overwriting the best MV so far if appropriate /*! Do the actual difference, overwriting the best MV so far if appropriate, and bailing out if we do worse \param dparams block parameters \param mv the motion vector being used \param mvcost the (prediction) cost of the motion vector mv \param lambda the weighting to be given to mvcost \param best_costs the best Lagrangian costs obtained yet \param best_mv the MV giving the best Lagrangian costs so far */ virtual void Diff( const BlockDiffParams& dparams, const MVector& mv , const float mvcost, const float lambda, MvCostData& best_costs , MVector& best_mv)=0; private: //! Private, bodyless copy-constructor: class should not be copied BlockDiffUp(const BlockDiffUp& cpy); //! Private, bodyless assignment=: class should not be assigned BlockDiffUp& operator=(const BlockDiffUp& rhs); }; //! A class for doing differences with half-pixel accurate vectors class BlockDiffHalfPel: public BlockDiffUp { public: //! Constructor, initialising the reference and picture data /* Constructor, initialising the reference and picture data \param ref the reference picture \param pic the picture being matched */ BlockDiffHalfPel( const PicArray& ref , const PicArray& pic ); //! Destructor ~BlockDiffHalfPel(){} //! Do the difference, returning SAD /*! Do the difference, returning SAD \param dparams block parameters \param mv the motion vector being used */ float Diff( const BlockDiffParams& dparams , const MVector& mv ); //! Do the actual difference, overwriting the best MV so far if appropriate /*! Do the actual difference, overwriting the best MV so far if appropriate, and bailing out if we do worse \param dparams block parameters \param mv the motion vector being used \param mvcost the (prediction) cost of the motion vector mv \param lambda the weighting to be given to mvcost \param best_costs the best Lagrangian costs obtained yet \param best_mv the MV giving the best Lagrangian costs so far */ void Diff( const BlockDiffParams& dparams, const MVector& mv , const float mvcost, const float lambda, MvCostData& best_costs , MVector& best_mv); private: //! Private, bodyless copy-constructor: class should not be copied BlockDiffHalfPel(const BlockDiffHalfPel& cpy); //! Private, bodyless assignment=: class should not be assigned BlockDiffHalfPel& operator=(const BlockDiffHalfPel& rhs); }; //! A class for doing differences with quarter-pixel accurate vectors class BlockDiffQuarterPel: public BlockDiffUp { public: //! Constructor, initialising the reference and picture data /* Constructor, initialising the reference and picture data \param ref the reference picture \param pic the picture being matched */ BlockDiffQuarterPel( const PicArray& ref , const PicArray& pic ); //! Destructor ~BlockDiffQuarterPel(){} //! Do the difference, returning SAD /*! Do the difference, returning SAD \param dparams block parameters \param mv the motion vector being used */ float Diff( const BlockDiffParams& dparams , const MVector& mv ); //! Do the actual difference, overwriting the best MV so far if appropriate /*! Do the actual difference, overwriting the best MV so far if appropriate, and bailing out if we do worse \param dparams block parameters \param mv the motion vector being used \param mvcost the (prediction) cost of the motion vector mv \param lambda the weighting to be given to mvcost \param best_costs the best Lagrangian costs obtained yet \param best_mv the MV giving the best Lagrangian costs so far */ void Diff( const BlockDiffParams& dparams, const MVector& mv , const float mvcost, const float lambda, MvCostData& best_costs , MVector& best_mv); private: //! Private, bodyless copy-constructor: class should not be copied BlockDiffQuarterPel(const BlockDiffQuarterPel& cpy); //! Private, bodyless assignment=: class should not be assigned BlockDiffQuarterPel& operator=(const BlockDiffQuarterPel& rhs); }; //! A class for doing differences with eighth-pixel accurate vectors class BlockDiffEighthPel: public BlockDiffUp { public: //! Constructor, initialising the reference and picture data /* Constructor, initialising the reference and picture data \param ref the reference picture \param pic the picture being matched */ BlockDiffEighthPel( const PicArray& ref , const PicArray& pic ); //! Destructor ~BlockDiffEighthPel(){} //! Do the difference, returning SAD /*! Do the difference, returning SAD \param dparams block parameters \param mv the motion vector being used */ float Diff( const BlockDiffParams& dparams , const MVector& mv ); //! Do the actual difference, overwriting the best MV so far if appropriate /*! Do the actual difference, overwriting the best MV so far if appropriate, and bailing out if we do worse \param dparams block parameters \param mv the motion vector being used \param mvcost the (prediction) cost of the motion vector mv \param lambda the weighting to be given to mvcost \param best_costs the best Lagrangian costs obtained yet \param best_mv the MV giving the best Lagrangian costs so far */ void Diff( const BlockDiffParams& dparams, const MVector& mv , const float mvcost, const float lambda, MvCostData& best_costs , MVector& best_mv); private: //! Private, bodyless copy-constructor: class should not be copied BlockDiffEighthPel(const BlockDiffEighthPel& cpy); //! Private, bodyless assignment=: class should not be assigned BlockDiffEighthPel& operator=(const BlockDiffEighthPel& rhs); }; //! A class for computing a bidirection difference for half-pel vectors class BiBlockHalfPel: public BiBlockDiff { public: //! Constructor, initialising the references and picture data /* Constructor, initialising the reference and picture data \param ref1 the first reference picture \param ref2 the second reference picture \param pic the picture being matched */ BiBlockHalfPel( const PicArray& ref1 , const PicArray& ref2 , const PicArray& pic ); //! Do the difference, returning SAD /*! Do the difference, returning SAD \param dparams block parameters \param mv1 the motion vector being used for reference 1 \param mv2 the motion vector being used for reference 2 */ float Diff( const BlockDiffParams& dparams , const MVector& mv1 , const MVector& mv2 ); private: //! Private, bodyless copy-constructor: class should not be copied BiBlockHalfPel(const BiBlockHalfPel& cpy); //! Private, bodyless assignment=: class should not be assigned BiBlockHalfPel& operator=(const BiBlockHalfPel& rhs); }; //! A class for computing a bidirection difference for quarter-pel vectors class BiBlockQuarterPel: public BiBlockDiff { public: //! Constructor, initialising the references and picture data /* Constructor, initialising the reference and picture data \param ref1 the first reference picture \param ref2 the second reference picture \param pic the picture being matched */ BiBlockQuarterPel( const PicArray& ref1 , const PicArray& ref2 , const PicArray& pic ); //! Do the difference, returning SAD /*! Do the difference, returning SAD \param dparams block parameters \param mv1 the motion vector being used for reference 1 \param mv2 the motion vector being used for reference 2 */ float Diff( const BlockDiffParams& dparams , const MVector& mv1 , const MVector& mv2 ); private: //! Private, bodyless copy-constructor: class should not be copied BiBlockQuarterPel(const BiBlockQuarterPel& cpy); //! Private, bodyless assignment=: class should not be assigned BiBlockQuarterPel& operator=(const BiBlockQuarterPel& rhs); }; //! A class for computing a bidirection difference for eighth-pel vectors class BiBlockEighthPel: public BiBlockDiff { public: //! Constructor, initialising the references and picture data /* Constructor, initialising the reference and picture data \param ref1 the first reference picture \param ref2 the second reference picture \param pic the picture being matched */ BiBlockEighthPel( const PicArray& ref1 , const PicArray& ref2 , const PicArray& pic ); //! Do the difference, returning SAD /*! Do the difference, returning SAD \param dparams block parameters \param mv1 the motion vector being used for reference 1 \param mv2 the motion vector being used for reference 2 */ float Diff( const BlockDiffParams& dparams , const MVector& mv1 , const MVector& mv2 ); private: //! Private, bodyless copy-constructor: class should not be copied BiBlockEighthPel(const BiBlockEighthPel& cpy); //! Private, bodyless assignment=: class should not be assigned BiBlockEighthPel& operator=(const BiBlockEighthPel& rhs); }; } // namespace dirac #endif