Updating Contact email
[BrunelResearch-dirac.git] / libdirac_motionest / motion_estimate.cpp
blobe1c128e46769a0020f4ec991b5b7f94fc52f18af
1 /* ***** BEGIN LICENSE BLOCK *****
3 * $Id$ $Name$
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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.
16 * The Original Code is BBC Research and Development code.
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.
23 * Contributor(s): Thomas Davies (Original Author)
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 ***** */
39 #include <libdirac_encoder/enc_queue.h>
40 #include <libdirac_motionest/motion_estimate.h>
41 #include <libdirac_motionest/pixel_match.h>
42 #include <libdirac_motionest/me_subpel.h>
43 #include <libdirac_motionest/me_mode_decn.h>
44 using namespace dirac;
46 #include <cmath>
47 #include <vector>
49 MotionEstimator::MotionEstimator( const EncoderParams& encp ):
50 m_encparams( encp )
53 void MotionEstimator::DoME( EncQueue& my_buffer, int pic_num )
55 MEData& me_data = my_buffer.GetPicture( pic_num ).GetMEData();
57 const PictureParams& pparams = my_buffer.GetPicture(pic_num).GetPparams();
59 // Step 1.
60 //Initial search gives vectors for each reference accurate to 1 pixel
62 PixelMatcher pix_match( m_encparams );
63 pix_match.DoSearch( my_buffer , pic_num );
65 float lambda;
66 // Get the references
67 const std::vector<int>& refs = my_buffer.GetPicture(pic_num).GetPparams().Refs();
69 const int num_refs = refs.size();
70 if ( pparams.IsBPicture())
71 lambda = m_encparams.L2MELambda();
72 else
73 lambda = m_encparams.L1MELambda();
75 // Set up the lambda to be used
76 me_data.SetLambdaMap( num_refs , lambda );
78 MVPrecisionType orig_prec = m_encparams.MVPrecision();
80 // Step 2.
81 // Pixel accurate vectors are then refined to sub-pixel accuracy
83 if (orig_prec != MV_PRECISION_PIXEL)
85 SubpelRefine pelrefine( m_encparams );
86 pelrefine.DoSubpel( my_buffer , pic_num );
88 else
90 // FIXME: HACK HACK
91 // Mutiplying the motion vectors by 2 and setting MV precision to
92 // HALF_PIXEL to implement pixel accurate motion estimate
93 MvArray &mv_arr1 = me_data.Vectors(1);
94 for (int j = 0; j < mv_arr1.LengthY(); ++j)
96 for (int i = 0; i < mv_arr1.LengthX(); ++i)
97 mv_arr1[j][i] = mv_arr1[j][i] << 1;
99 if (num_refs > 1)
101 MvArray &mv_arr2 = me_data.Vectors(2);
102 for (int j = 0; j < mv_arr2.LengthY(); ++j)
104 for (int i = 0; i < mv_arr2.LengthX(); ++i)
105 mv_arr2[j][i] = mv_arr2[j][i] << 1;
108 m_encparams.SetMVPrecision(MV_PRECISION_HALF_PIXEL);
111 // Step3.
112 // We now have to decide how each superblock should be split
113 // and which references should be used, and so on.
115 ModeDecider my_mode_dec( m_encparams );
116 my_mode_dec.DoModeDecn( my_buffer , pic_num );
118 if (orig_prec == MV_PRECISION_PIXEL)
120 // FIXME: HACK HACK
121 // Divide the motion vectors by 2 to convert back to pixel
122 // accurate motion vectors and reset MV precision to
123 // PIXEL accuracy
124 MvArray &mv_arr1 = me_data.Vectors(1);
125 for (int j = 0; j < mv_arr1.LengthY(); ++j)
127 for (int i = 0; i < mv_arr1.LengthX(); ++i)
128 mv_arr1[j][i] = mv_arr1[j][i] >> 1;
130 if (num_refs > 1)
132 MvArray &mv_arr2 = me_data.Vectors(2);
133 for (int j = 0; j < mv_arr2.LengthY(); ++j)
135 for (int i = 0; i < mv_arr2.LengthX(); ++i)
136 mv_arr2[j][i] = mv_arr2[j][i]>>1;
139 m_encparams.SetMVPrecision(MV_PRECISION_PIXEL);
142 // Finally, although not strictly part of motion estimation,
143 // we have to assign DC values for chroma components for
144 // blocks we're decided are intra.
146 SetChromaDC( my_buffer , pic_num );
148 //return false;
151 ValueType MotionEstimator::GetChromaBlockDC(const PicArray& pic_data,
152 int xunit , int yunit , int split)
154 BlockDiffParams dparams;
155 dparams.SetBlockLimits( m_encparams.ChromaBParams( split ) ,
156 pic_data, xunit , yunit);
158 ValueType dc;
160 IntraBlockDiff intradiff( pic_data );
162 intradiff.Diff( dparams , dc );
164 return dc;
167 void MotionEstimator::SetChromaDC( const PicArray& pic_data , MEData& me_data , CompSort csort )
170 // Lower limit of block coords in SB
171 int xtl,ytl;
172 // Upper limit of block coords in SB
173 int xbr,ybr;
175 // Ditto, for subSBs
176 int xsubSBtl,ysubSBtl;
177 int xsubSBbr,ysubSBbr;
179 TwoDArray<ValueType>& dcarray = me_data.DC( csort );
181 ValueType dc = 0;
183 // Coords of the prediction units (at appropriate level)
184 int xunit, yunit;
186 // The delimiters of the blocks contained in the prediction unit
187 int xstart, ystart;
188 int xend, yend;
190 int level;
192 for ( int ysb=0 ; ysb<me_data.SBSplit().LengthY() ; ++ysb )
194 for ( int xsb=0 ; xsb<me_data.SBSplit().LengthX() ; ++xsb )
197 level = me_data.SBSplit()[ysb][xsb];
199 xtl = xsb<<2;
200 ytl = ysb<<2;
201 xbr = xtl+4;
202 ybr = ytl+4;
204 xsubSBtl = xsb<<1;
205 ysubSBtl = ysb<<1;
206 xsubSBbr = xsubSBtl+2;
207 ysubSBbr = ysubSBtl+2;
210 for (int j = 0 ; j<(1<<level) ;++j)
212 for (int i = 0 ; i<(1<<level) ;++i)
214 xunit = ( xsb<<level ) + i;
215 yunit = ( ysb<<level ) + j;
217 xstart = xunit<<( 2-level );
218 ystart = yunit<<( 2-level );
220 xend = xstart + ( 1<<( 2-level ) );
221 yend = ystart + ( 1<<( 2-level ) );
223 if ( me_data.Mode()[ystart][xstart] == INTRA )
224 // Get the DC value for the unit
225 dc = GetChromaBlockDC( pic_data , xunit , yunit , level );
227 // Copy it into the corresponding blocks
228 for ( int q=ystart ; q< yend ; ++q )
229 for ( int p=xstart ; p< xend ; ++p )
230 dcarray[q][p] = dc;
232 }// i
233 }// j
235 }// xsb
236 }// ysb
239 void MotionEstimator::SetChromaDC( EncQueue& my_buffer , int pic_num )
241 MEData& me_data = my_buffer.GetPicture(pic_num).GetMEData();
242 SetChromaDC( my_buffer.GetPicture( pic_num ).OrigData(U_COMP) , me_data , U_COMP );
243 SetChromaDC( my_buffer.GetPicture( pic_num ).OrigData(V_COMP) , me_data , V_COMP );