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.30 2008/10/01 01:26:47 asuraparaju Exp $ $Name: Dirac_1_0_2 $
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     enum MvElement { HORIZONTAL , VERTICAL };
00055 
00057     template <class T>
00058     class MotionVector
00059     {
00060     public:
00061 
00063         MotionVector<T>(T a, T b) : x(a), y(b) {};
00065         MotionVector<T>() : x(0), y(0) {};
00067         MotionVector<T>(T a) : x(a), y(a) {};
00068 
00070         inline MotionVector<T> operator+(const MotionVector<T>& argument) const;
00071 
00073         inline MotionVector<T> operator-(const MotionVector<T>& argument) const;
00074 
00076         inline MotionVector<T> operator*(const float argument) const;
00077 
00079         inline MotionVector<T> operator*(const int argument) const;
00080 
00082         inline MotionVector<T> operator<<(const int argument) const;
00083 
00085         inline MotionVector<T> operator>>(const int argument) const;
00086         
00088         T& operator[](const int pos){return ( ( pos==0) ? x : y );}
00089 
00091         const T& operator[](const int pos) const {return ( ( pos==0) ? x : y );}
00092 
00093 
00095         T x,y;
00096 
00097     };
00098 
00099 
00100     template <class T>
00101     inline MotionVector<T> MotionVector<T>::operator+(const MotionVector<T>& argument) const 
00102     {
00103         MotionVector<T> temp;
00104         temp.x = x + argument.x;
00105         temp.y = y + argument.y;
00106 
00107         return temp;
00108     }
00109 
00110     template <class T>
00111     inline MotionVector<T>  MotionVector<T>::operator-(const MotionVector<T>& argument) const 
00112     {
00113         MotionVector<T> temp;
00114         temp.x = x-argument.x;
00115         temp.y = y-argument.y;
00116 
00117         return temp;
00118     }
00119 
00120     template <class T>
00121     inline MotionVector<T>  MotionVector<T>::operator*(const float argument) const 
00122     {
00123         MotionVector<T> temp;
00124         temp.x = x*argument;
00125         temp.y = y*argument;
00126 
00127         return temp;
00128     }
00129 
00130     template <class T>
00131     inline MotionVector<T>  MotionVector<T>::operator*(const int argument) const 
00132     {
00133         MotionVector<T> temp;
00134         temp.x = x*argument;
00135         temp.y = y*argument;
00136 
00137         return temp;
00138     }
00139 
00140     template <class T>
00141     inline MotionVector<T>  MotionVector<T>::operator<<(const int argument) const 
00142     {
00143         MotionVector<T> temp;
00144         temp.x = x<<argument;
00145         temp.y = y<<argument;
00146 
00147         return temp;
00148     }
00149 
00150     template <class T>
00151     inline MotionVector<T>  MotionVector<T>::operator>>(const int argument) const 
00152     {
00153         MotionVector<T> temp;
00154         temp.x = x>>argument;
00155         temp.y = y>>argument;
00156 
00157         return temp;
00158     }
00159 
00161     template <class T>
00162     std::ostream & operator<< (std::ostream & stream, MotionVector<T> & mv)
00163     {
00164         stream << mv.x << " " << mv.y;
00165 
00166         return stream;
00167     }
00168 
00170     template <class T>
00171     std::istream & operator>> (std::istream & stream, MotionVector<T> & mv)
00172     {
00173         stream >> mv.x;
00174         stream >> mv.y;
00175 
00176         return stream;
00177     }
00178 
00180     typedef MotionVector<int> MVector;
00181 
00183     typedef MotionVector<int> ImageCoords;
00184 
00186     typedef TwoDArray<MVector> MvArray;
00187 
00189     typedef TwoDArray< MotionVector<float> > MvFloatArray;
00190 
00192     class MvCostData
00193     {
00194     public:
00196         MvCostData():
00197         SAD(0.0),
00198         mvcost(0.0),
00199         total(0.0){}
00200 
00201         void SetTotal( const float lambda ){total = SAD + lambda*mvcost;}
00202 
00204         float SAD;
00205 
00207         float mvcost;
00208 
00210         float total;
00211     };
00212 
00213 
00215 
00219     class MvData
00220     {
00221     public:
00223 
00228         MvData( const PicturePredParams& predparams ,  const int num_refs);
00229 
00231         ~MvData();
00232 
00234         PicturePredParams& GetPicPredParams(){return m_predparams;}
00235 
00237         const PicturePredParams& GetPicPredParams() const{return m_predparams;}
00238 
00240         MvArray& Vectors(const int ref_id){return *( m_vectors[ref_id] );}
00241 
00243         const MvArray& Vectors(const int ref_id) const {return *( m_vectors[ref_id] );}
00244 
00246         MvArray& GlobalMotionVectors(const int ref_id){return *( m_gm_vectors[ref_id] );}
00247 
00249         const MvArray& GlobalMotionVectors(const int ref_id) const {return *( m_gm_vectors[ref_id] );} 
00250 
00252         TwoDArray<ValueType>& DC(CompSort cs){return *( m_dc[cs] );}
00253 
00255         const TwoDArray<ValueType>& DC(CompSort cs) const {return *( m_dc[cs] );}
00256 
00258         const OneDArray< TwoDArray<ValueType>* >& DC() const {return m_dc;}
00259 
00261         TwoDArray<PredMode>& Mode(){return m_modes;}
00262 
00264         const TwoDArray<PredMode>& Mode() const {return m_modes;}
00265 
00267         TwoDArray<int>& SBSplit(){return m_sb_split;}
00268 
00270         const TwoDArray<int>& SBSplit() const{return m_sb_split;}
00271 
00273         OneDArray<float>& GlobalMotionParameters(const int ref_id) { return *( m_gm_params[ref_id] ); }
00274 
00276         const OneDArray<float>& GlobalMotionParameters(const int ref_id) const { return *( m_gm_params[ref_id] ); }
00277 
00278     protected:
00279         // A local copy of the picture prediction parameters
00280     PicturePredParams m_predparams;
00281 
00282         // Initialises the arrays of data
00283         void InitMvData();
00284 
00285         // The motion vectors
00286         OneDArray<MvArray*> m_vectors;
00287 
00288         // The global motion vectors
00289         OneDArray<MvArray*> m_gm_vectors;
00290 
00291         // The block modes
00292         TwoDArray<PredMode> m_modes;
00293 
00294         // The DC values
00295         OneDArray< TwoDArray<ValueType>* > m_dc;
00296 
00297         // The SB split levels
00298         TwoDArray<int> m_sb_split;
00299 
00300         // Global motion model parameters
00301         OneDArray< OneDArray<float>* > m_gm_params;
00302 
00303 //        // Number of reference frames
00304 //        unsigned int m_num_refs;
00305     };
00306 
00308 
00313     class MEData: public MvData
00314     {
00315     public:
00316 
00318 
00323         MEData( const PicturePredParams& predparams , const int num_refs = 2);
00324 
00326         ~MEData();
00327     
00329     void DropRef( int ref_index );
00330 
00332         TwoDArray<MvCostData>& PredCosts(const int ref_id){ return *( m_pred_costs[ref_id] ); }
00333 
00335         const TwoDArray<MvCostData>& PredCosts(const int ref_id) const { return *( m_pred_costs[ref_id] ); }
00336 
00338         TwoDArray<float>& IntraCosts(){ return m_intra_costs; }
00339 
00341         const TwoDArray<float>& IntraCosts() const { return m_intra_costs; }
00342 
00344         TwoDArray<MvCostData>& BiPredCosts(){ return m_bipred_costs; }
00345 
00347         const TwoDArray<MvCostData>& BiPredCosts() const { return m_bipred_costs; }
00348 
00350         TwoDArray<float>& SBCosts(){ return m_SB_costs; }
00351 
00353         const TwoDArray<float>& SBCosts() const { return m_SB_costs; }
00354 
00356     float IntraBlockRatio() const {return m_intra_block_ratio; }
00357 
00359     void SetIntraBlockRatio(const float r){ m_intra_block_ratio = r; }
00360 
00362         void SetLambdaMap( const int num_refs , const float lambda );
00363 
00365         void SetLambdaMap( const int level , const TwoDArray<float>& l_map , const float wt );
00366 
00368         const TwoDArray<float>& LambdaMap() const { return m_lambda_map; }
00369 
00371         TwoDArray<int>& GlobalMotionInliers(const int ref_id){ return *( m_inliers[ref_id] ); }
00372 
00374         const TwoDArray<int>& GlobalMotionInliers(const int ref_id) const { return *( m_inliers[ref_id] ); }
00375 
00377         friend std::ostream &operator<< (std::ostream & stream, MEData & me_data);
00378 
00380         friend std::istream &operator>> (std::istream & stream, MEData & me_data);
00381 
00382     private:
00383         // Initialises the arrays of data
00384         void InitMEData();
00385 
00386         // Finds transitions in the motion vectors
00387         void FindTransitions( TwoDArray<bool>& trans_map , const int ref_num );
00388 
00389         // The costs of predicting each block, for each reference
00390         OneDArray< TwoDArray<MvCostData>* > m_pred_costs;
00391 
00392         // The costs of predicting each block by DC
00393         TwoDArray<float> m_intra_costs;
00394 
00395         // The costs of predicting each block bidirectionally
00396         TwoDArray<MvCostData> m_bipred_costs;
00397 
00398         // The costs for each macroblock as a whole
00399         TwoDArray<float> m_SB_costs;
00400 
00401         // A map of the lambda values to use
00402         TwoDArray<float> m_lambda_map;
00403 
00404         // Global motion inliers
00405         OneDArray< TwoDArray<int>* > m_inliers;
00406 
00407     // Intra block ratio
00408     float m_intra_block_ratio;
00409 
00410     };
00411 
00412     //motion estimation and coding stuff
00413     
00415     int Median( const int val1, const int val2, const int val3);
00416 
00418     MVector MvMedian(const MVector& mv1,const MVector& mv2,const MVector& mv3);
00419 
00420 
00422     int Median(const std::vector<int>& val_list);
00423 
00425     MVector MvMedian(const std::vector<MVector>& vect_list);
00426 
00428     MVector MvMean(const MVector& mv1, const MVector& mv2);
00429 
00431     inline int Norm2(const MVector& mv){//L^2 norm of a motion vector
00432         return mv.x*mv.x+mv.y*mv.y;
00433     }
00434 
00436     inline int Norm1(const MVector& mv){//L^1 norm of a motion vector
00437         return abs(mv.x)+abs(mv.y);
00438     }
00439     
00441     unsigned int GetUMean(std::vector<unsigned int>& values);
00442     
00444     int GetSMean(std::vector<int>& values);
00445 
00446 } // namespace dirac
00447 
00448 #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.