00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <libdirac_common/frame_buffer.h>
00040 #include <libdirac_motionest/motion_estimate.h>
00041 #include <libdirac_motionest/pixel_match.h>
00042 #include <libdirac_motionest/me_subpel.h>
00043 #include <libdirac_motionest/me_mode_decn.h>
00044 using namespace dirac;
00045
00046 #include <cmath>
00047 #include <vector>
00048
00049 MotionEstimator::MotionEstimator( const EncoderParams& encp ):
00050 m_encparams( encp )
00051 {}
00052
00053 bool MotionEstimator::DoME(const FrameBuffer& my_buffer, int frame_num, MEData& me_data)
00054 {
00055
00056 const FrameParams& fparams = my_buffer.GetFrame(frame_num).GetFparams();
00057
00058
00059
00060
00061 PixelMatcher pix_match( m_encparams );
00062 pix_match.DoSearch( my_buffer , frame_num , me_data);
00063
00064
00065
00066
00067 SubpelRefine pelrefine( m_encparams );
00068 pelrefine.DoSubpel( my_buffer , frame_num , me_data );
00069
00070
00071
00072
00073
00074
00075 ModeDecider my_mode_dec( m_encparams );
00076 my_mode_dec.DoModeDecn( my_buffer , frame_num , me_data );
00077
00078
00079
00080
00081
00082 if (fparams.CFormat() != Yonly)
00083 SetChromaDC( my_buffer , frame_num , me_data );
00084
00085 return IsACut( me_data );
00086
00087 }
00088
00089 ValueType MotionEstimator::GetChromaBlockDC(const PicArray& pic_data,
00090 int xunit , int yunit , int split)
00091 {
00092 BlockDiffParams dparams;
00093 dparams.SetBlockLimits( m_encparams.ChromaBParams( split ) ,
00094 pic_data, xunit , yunit);
00095
00096 ValueType dc;
00097
00098 IntraBlockDiff intradiff( pic_data );
00099
00100 intradiff.Diff( dparams , dc );
00101
00102 return dc;
00103 }
00104
00105 void MotionEstimator::SetChromaDC( const PicArray& pic_data , MvData& mv_data , CompSort csort )
00106 {
00107
00108
00109 int xtl,ytl;
00110
00111 int xbr,ybr;
00112
00113
00114 int xsubMBtl,ysubMBtl;
00115 int xsubMBbr,ysubMBbr;
00116
00117 TwoDArray<ValueType>& dcarray = mv_data.DC( csort );
00118
00119 ValueType dc = 0;
00120
00121
00122 int xunit, yunit;
00123
00124
00125 int xstart, ystart;
00126 int xend, yend;
00127
00128 int level;
00129
00130 for ( int ymb=0 ; ymb<mv_data.MBSplit().LengthY() ; ++ymb )
00131 {
00132 for ( int xmb=0 ; xmb<mv_data.MBSplit().LengthX() ; ++xmb )
00133 {
00134
00135 level = mv_data.MBSplit()[ymb][xmb];
00136
00137 xtl = xmb<<2;
00138 ytl = ymb<<2;
00139 xbr = xtl+4;
00140 ybr = ytl+4;
00141
00142 xsubMBtl = xmb<<1;
00143 ysubMBtl = ymb<<1;
00144 xsubMBbr = xsubMBtl+2;
00145 ysubMBbr = ysubMBtl+2;
00146
00147
00148 for (int j = 0 ; j<(1<<level) ;++j)
00149 {
00150 for (int i = 0 ; i<(1<<level) ;++i)
00151 {
00152 xunit = ( xmb<<level ) + i;
00153 yunit = ( ymb<<level ) + j;
00154
00155 xstart = xunit<<( 2-level );
00156 ystart = yunit<<( 2-level );
00157
00158 xend = xstart + ( 1<<( 2-level ) );
00159 yend = ystart + ( 1<<( 2-level ) );
00160
00161 if ( mv_data.Mode()[ystart][xstart] == INTRA )
00162
00163 dc = GetChromaBlockDC( pic_data , xunit , yunit , level );
00164
00165
00166 for ( int q=ystart ; q< yend ; ++q )
00167 for ( int p=xstart ; p< xend ; ++p )
00168 dcarray[q][p] = dc;
00169
00170 }
00171 }
00172
00173 }
00174 }
00175 }
00176
00177 void MotionEstimator::SetChromaDC( const FrameBuffer& my_buffer , int frame_num , MvData& mv_data)
00178 {
00179
00180 SetChromaDC( my_buffer.GetComponent( frame_num , U_COMP) , mv_data , U_COMP );
00181 SetChromaDC( my_buffer.GetComponent( frame_num , V_COMP) , mv_data , V_COMP );
00182
00183 }
00184
00185 bool MotionEstimator::IsACut( const MEData& me_data ) const
00186 {
00187
00188 const TwoDArray<PredMode>& modes = me_data.Mode();
00189
00190 int count_intra = 0;
00191 for ( int j=0 ; j<modes.LengthY() ; ++j )
00192 {
00193 for ( int i=0 ; i<modes.LengthX() ; ++i )
00194 {
00195 if ( modes[j][i] == INTRA )
00196 count_intra++;
00197 }
00198 }
00199
00200 double intra_percent = 100.0*static_cast<double>( count_intra ) /
00201 static_cast<double>( modes.LengthX() * modes.LengthY() );
00202
00203 if ( m_encparams.Verbose() )
00204 std::cerr<<std::endl<<intra_percent<<"% of blocks are intra ";
00205
00206
00207 const TwoDArray<MvCostData>& pcosts = me_data.PredCosts( 1 );
00208
00209
00210 long double sad_average = 0.0;
00211
00212 long double block_average;
00213
00214 const OLBParams& bparams = m_encparams.LumaBParams( 2 );
00215
00216 int block_count = 0;
00217
00218 for ( int j=0 ; j<pcosts.LengthY() ; ++j )
00219 {
00220 for ( int i=0 ; i<pcosts.LengthX() ; ++i )
00221 {
00222
00223 if ( modes[j][i] == REF1_ONLY || modes[j][i] == REF1AND2 )
00224 {
00225 block_average = pcosts[j][i].SAD /
00226 static_cast<long double>( bparams.Xblen() * bparams.Yblen() * 4 );
00227 sad_average += block_average;
00228 block_count++;
00229 }
00230
00231 }
00232 }
00233
00234 if ( block_count != 0)
00235 sad_average /= static_cast<long double>( block_count );
00236
00237 if ( (sad_average > 30.0) || (intra_percent > 50.0) )
00238 return true;
00239 else
00240 return false;
00241
00242 }