Dirac - A Video Codec

Created by the British Broadcasting Corporation.


motion.h

Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002 *
00003 * $Id: motion.h,v 1.20 2006/10/30 13:42:42 tjdwave 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 *                 Chris Bowley,
00025 *                 Tim Borer
00026 *
00027 * Alternatively, the contents of this file may be used under the terms of
00028 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
00029 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
00030 * the GPL or the LGPL are applicable instead of those above. If you wish to
00031 * allow use of your version of this file only under the terms of the either
00032 * the GPL or LGPL and not to allow others to use your version of this file
00033 * under the MPL, indicate your decision by deleting the provisions above
00034 * and replace them with the notice and other provisions required by the GPL
00035 * or LGPL. If you do not delete the provisions above, a recipient may use
00036 * your version of this file under the terms of any one of the MPL, the GPL
00037 * or the LGPL.
00038 * ***** END LICENSE BLOCK ***** */
00039 
00040 #include <libdirac_common/common.h>
00041 #include <algorithm>
00042 #ifndef _MOTION_H
00043 #define _MOTION_H
00044 
00045 namespace dirac
00046 {
00048     //classes and functions for motion estimation and compensation//
00050 
00051     //classes
00052 
00054     template <class T>
00055     class MotionVector
00056     {
00057     public:
00058 
00060         MotionVector<T>(T a, T b) : x(a), y(b) {};
00062         MotionVector<T>() : x(0), y(0) {};
00064         MotionVector<T>(T a) : x(a), y(a) {};
00065 
00067         inline MotionVector<T> operator+(const MotionVector<T>& argument) const;
00068 
00070         inline MotionVector<T> operator-(const MotionVector<T>& argument) const;
00071 
00073         inline MotionVector<T> operator*(const float argument) const;
00074 
00076         inline MotionVector<T> operator*(const int argument) const;
00077 
00079         inline MotionVector<T> operator<<(const int argument) const;
00080 
00082         inline MotionVector<T> operator>>(const int argument) const;
00083 
00084 
00086         T x,y;
00087 
00088     };
00089 
00090 
00091     template <class T>
00092     inline MotionVector<T> MotionVector<T>::operator+(const MotionVector<T>& argument) const 
00093     {
00094         MotionVector<T> temp;
00095         temp.x = x + argument.x;
00096         temp.y = y + argument.y;
00097 
00098         return temp;
00099     }
00100 
00101     template <class T>
00102     inline MotionVector<T>  MotionVector<T>::operator-(const MotionVector<T>& argument) const 
00103     {
00104         MotionVector<T> temp;
00105         temp.x = x-argument.x;
00106         temp.y = y-argument.y;
00107 
00108         return temp;
00109     }
00110 
00111     template <class T>
00112     inline MotionVector<T>  MotionVector<T>::operator*(const float argument) const 
00113     {
00114         MotionVector<T> temp;
00115         temp.x = x*argument;
00116         temp.y = y*argument;
00117 
00118         return temp;
00119     }
00120 
00121     template <class T>
00122     inline MotionVector<T>  MotionVector<T>::operator*(const int argument) const 
00123     {
00124         MotionVector<T> temp;
00125         temp.x = x*argument;
00126         temp.y = y*argument;
00127 
00128         return temp;
00129     }
00130 
00131     template <class T>
00132     inline MotionVector<T>  MotionVector<T>::operator<<(const int argument) const 
00133     {
00134         MotionVector<T> temp;
00135         temp.x = x<<argument;
00136         temp.y = y<<argument;
00137 
00138         return temp;
00139     }
00140 
00141     template <class T>
00142     inline MotionVector<T>  MotionVector<T>::operator>>(const int argument) const 
00143     {
00144         MotionVector<T> temp;
00145         temp.x = x>>argument;
00146         temp.y = y>>argument;
00147 
00148         return temp;
00149     }
00150 
00152     template <class T>
00153     std::ostream & operator<< (std::ostream & stream, MotionVector<T> & mv)
00154     {
00155         stream << mv.x << " " << mv.y;
00156 
00157         return stream;
00158     }
00159 
00161     template <class T>
00162     std::istream & operator>> (std::istream & stream, MotionVector<T> & mv)
00163     {
00164         stream >> mv.x;
00165         stream >> mv.y;
00166 
00167         return stream;
00168     }
00169 
00171     typedef MotionVector<int> MVector;
00172 
00174     typedef MotionVector<int> ImageCoords;
00175 
00177     typedef TwoDArray<MVector> MvArray;
00178 
00180     typedef TwoDArray< MotionVector<float> > MvFloatArray;
00181 
00183     class MvCostData
00184     {
00185     public:
00187         MvCostData():
00188         SAD(0.0),
00189         mvcost(0.0),
00190         total(0.0){}
00191 
00192         void SetTotal( const float lambda ){total = SAD + lambda*mvcost;}
00193 
00195         float SAD;
00196 
00198         float mvcost;
00199 
00201         float total;
00202     };
00203 
00204 
00206 
00210     class MvData
00211     {
00212     public:
00214 
00222         MvData( const int xnumMB, const int ynumMB , 
00223                 const int xnumblocks, const int ynumblocks ,  const int num_refs);
00224 
00226 
00232         MvData( const int xnumMB, const int ynumMB ,  const int num_refs);
00233 
00235         ~MvData();
00236 
00238         MvArray& Vectors(const int ref_id){return *( m_vectors[ref_id] );}
00239 
00241         const MvArray& Vectors(const int ref_id) const {return *( m_vectors[ref_id] );}
00242 
00244         MvArray& GlobalMotionVectors(const int ref_id){return *( m_gm_vectors[ref_id] );}
00245 
00247         const MvArray& GlobalMotionVectors(const int ref_id) const {return *( m_gm_vectors[ref_id] );} 
00248 
00250         TwoDArray<ValueType>& DC(CompSort cs){return *( m_dc[cs] );}
00251 
00253         const TwoDArray<ValueType>& DC(CompSort cs) const {return *( m_dc[cs] );}
00254 
00256         const OneDArray< TwoDArray<ValueType>* >& DC() const {return m_dc;}
00257 
00259         TwoDArray<PredMode>& Mode(){return m_modes;}
00260 
00262         const TwoDArray<PredMode>& Mode() const {return m_modes;}
00263      
00265         TwoDArray<int>& MBSplit(){return m_mb_split;}
00266 
00268         const TwoDArray<int>& MBSplit() const{return m_mb_split;}
00269 
00271         OneDArray<float>& GlobalMotionParameters(const int ref_id) { return *( m_gm_params[ref_id] ); }
00272 
00274         const OneDArray<float>& GlobalMotionParameters(const int ref_id) const { return *( m_gm_params[ref_id] ); }
00275 
00277         const unsigned int NumRefs()const {return m_num_refs;}
00278 
00279     private:
00280         // Initialises the arrays of data
00281         void InitMvData();
00282 
00283         // The motion vectors
00284         OneDArray<MvArray*> m_vectors;
00285 
00286         // The global motion vectors
00287         OneDArray<MvArray*> m_gm_vectors;
00288 
00289         // The block modes
00290         TwoDArray<PredMode> m_modes;
00291 
00292         // The DC values
00293         OneDArray< TwoDArray<ValueType>* > m_dc;
00294 
00295         // The MB split levels
00296         TwoDArray<int> m_mb_split;
00297 
00298         // Global motion model parameters
00299         OneDArray< OneDArray<float>* > m_gm_params;
00300 
00301         // Number of reference frames
00302         const unsigned int m_num_refs;
00303     };
00304 
00306 
00311     class MEData: public MvData
00312     {
00313     public:
00314 
00316 
00324         MEData( const int xnumMB, const int ynumMB , 
00325                 const int xnumblocks, const int ynumblocks , const int num_refs = 2);
00326 
00328 
00334         MEData( const int xnumMB, const int ynumMB , const int num_refs = 2);
00335 
00337         ~MEData();
00338 
00340         TwoDArray<MvCostData>& PredCosts(const int ref_id){ return *( m_pred_costs[ref_id] ); }
00341 
00343         const TwoDArray<MvCostData>& PredCosts(const int ref_id) const { return *( m_pred_costs[ref_id] ); }
00344 
00346         TwoDArray<float>& IntraCosts(){ return m_intra_costs; }
00347 
00349         const TwoDArray<float>& IntraCosts() const { return m_intra_costs; }
00350 
00352         TwoDArray<MvCostData>& BiPredCosts(){ return m_bipred_costs; }
00353 
00355         const TwoDArray<MvCostData>& BiPredCosts() const { return m_bipred_costs; }
00356 
00358         TwoDArray<float>& MBCosts(){ return m_MB_costs; }
00359 
00361         const TwoDArray<float>& MBCosts() const { return m_MB_costs; }
00362 
00364         void SetLambdaMap( const int num_refs , const float lambda );
00365 
00367         void SetLambdaMap( const int level , const TwoDArray<float>& l_map , const float wt );
00368 
00370         const TwoDArray<float>& LambdaMap() const { return m_lambda_map; }
00371 
00373         TwoDArray<int>& GlobalMotionInliers(const int ref_id){ return *( m_inliers[ref_id] ); }
00374 
00376         const TwoDArray<int>& GlobalMotionInliers(const int ref_id) const { return *( m_inliers[ref_id] ); }
00377 
00379         friend std::ostream &operator<< (std::ostream & stream, MEData & me_data);
00380 
00382         friend std::istream &operator>> (std::istream & stream, MEData & me_data);
00383 
00384     private:
00385         // Initialises the arrays of data
00386         void InitMEData();
00387 
00388         // Finds transitions in the motion vectors
00389         void FindTransitions( TwoDArray<bool>& trans_map , const int ref_num );
00390 
00391         // The costs of predicting each block, for each reference
00392         OneDArray< TwoDArray<MvCostData>* > m_pred_costs;
00393 
00394         // The costs of predicting each block by DC
00395         TwoDArray<float> m_intra_costs;
00396 
00397         // The costs of predicting each block bidirectionally
00398         TwoDArray<MvCostData> m_bipred_costs;
00399 
00400         // The costs for each macroblock as a whole
00401         TwoDArray<float> m_MB_costs;
00402 
00403         // A map of the lambda values to use
00404         TwoDArray<float> m_lambda_map;
00405 
00406         // Global motion inliers
00407         OneDArray< TwoDArray<int>* > m_inliers;
00408 
00409     };
00410 
00411     //motion estimation and coding stuff
00412 
00414     MVector MvMedian(const MVector& mv1,const MVector& mv2,const MVector& mv3);
00415 
00417     MVector MvMedian(const std::vector<MVector>& vect_list);
00418 
00420     MVector MvMean(const MVector& mv1, const MVector& mv2);
00421 
00423     inline int Norm2(const MVector& mv){//L^2 norm of a motion vector
00424         return mv.x*mv.x+mv.y*mv.y;
00425     }
00426 
00428     inline int Norm1(const MVector& mv){//L^1 norm of a motion vector
00429         return abs(mv.x)+abs(mv.y);
00430     }
00431 
00433     unsigned int GetUMean(std::vector<unsigned int>& values);
00434     
00436     int GetSMean(std::vector<int>& values);
00437 
00438 } // namespace dirac
00439 
00440 #endif

© 2004 British Broadcasting Corporation. Dirac code licensed under the Mozilla Public License (MPL) Version 1.1.
HTML documentation generated by Dimitri van Heesch's excellent Doxygen tool.