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 #include <libdirac_motionest/me_subpel.h>
00039 #include <libdirac_common/frame_buffer.h>
00040 using namespace dirac;
00041
00042 #include <iostream>
00043
00044 using std::vector;
00045
00046 SubpelRefine::SubpelRefine(const EncoderParams& encp):
00047 m_encparams(encp),
00048 m_nshift(4)
00049 {
00050
00051 m_nshift[0].x = -1;
00052 m_nshift[0].y = 0;
00053
00054 m_nshift[1].x = -1;
00055 m_nshift[1].y = -1;
00056
00057 m_nshift[2].x = 0;
00058 m_nshift[2].y = -1;
00059
00060 m_nshift[3].x = 1;
00061 m_nshift[3].y = -1;
00062
00063 }
00064
00065 void SubpelRefine::DoSubpel(const FrameBuffer& my_buffer,int frame_num, MEData& me_data)
00066 {
00067
00068 int ref1,ref2;
00069
00070 const FrameSort fsort = my_buffer.GetFrame(frame_num).GetFparams().FSort();
00071
00072 if (fsort != I_frame)
00073 {
00074 float lambda;
00075
00076 if ( fsort == L1_frame )
00077 lambda = m_encparams.L1MELambda();
00078 else
00079 lambda = m_encparams.L2MELambda();
00080
00081
00082 const vector<int>& refs = my_buffer.GetFrame(frame_num).GetFparams().Refs();
00083
00084 int num_refs = refs.size();
00085 ref1 = refs[0];
00086 if (num_refs>1)
00087 ref2 = refs[1];
00088 else
00089 ref2 = ref1;
00090
00091
00092 me_data.SetLambdaMap( num_refs , lambda );
00093
00094 const PicArray& pic_data = my_buffer.GetComponent(frame_num , Y_COMP);
00095 const PicArray& refup1_data = my_buffer.GetUpComponent( ref1 , Y_COMP);
00096 const PicArray& refup2_data = my_buffer.GetUpComponent( ref2 , Y_COMP);
00097
00098
00099 MatchPic( pic_data , refup1_data , me_data ,1 );
00100
00101 if (ref1 != ref2 )
00102 MatchPic( pic_data , refup2_data , me_data ,2 );
00103
00104 }
00105 }
00106
00107 void SubpelRefine::MatchPic(const PicArray& pic_data , const PicArray& refup_data , MEData& me_data ,
00108 int ref_id)
00109 {
00110
00111
00112
00113
00115
00116
00117 MvArray& mv_array = me_data.Vectors( ref_id );
00118 TwoDArray<MvCostData>& pred_costs = me_data.PredCosts( ref_id );
00119
00120
00121 BlockMatcher my_bmatch( pic_data , refup_data , m_encparams.LumaBParams(2) ,
00122 mv_array , pred_costs );
00123
00124
00126
00127
00128
00129 for (int yblock=0 ; yblock<m_encparams.YNumBlocks() ; ++yblock)
00130 {
00131 for (int xblock=0 ; xblock<m_encparams.XNumBlocks() ; ++xblock)
00132 {
00133 DoBlock(xblock , yblock , my_bmatch , me_data , ref_id );
00134 }
00135 }
00136 }
00137
00138
00139 void SubpelRefine::DoBlock(const int xblock , const int yblock ,
00140 BlockMatcher& my_bmatch, MEData& me_data , const int ref_id )
00141 {
00142
00143
00144
00145 MvArray& mv_array = me_data.Vectors( ref_id );
00146 TwoDArray<MvCostData>& pred_costs = me_data.PredCosts( ref_id );
00147
00148
00149 CandidateList cand_list;
00150
00151 const float loc_lambda = me_data.LambdaMap()[yblock][xblock];
00152
00153
00154 const MVector mv_pred = GetPred( xblock , yblock , mv_array );
00155
00156
00157
00158 mv_array[yblock][xblock] = mv_array[yblock][xblock]<<3;
00159
00160
00161 pred_costs[yblock][xblock].mvcost = GetVar(mv_pred , mv_array[yblock][xblock]);
00162 pred_costs[yblock][xblock].SetTotal( loc_lambda );
00163
00164 AddNewVlist( cand_list , mv_array[yblock][xblock] , 0 , 0 , 1 );
00165
00166
00167 AddNewVlist(cand_list , mv_array[yblock][xblock] , 1 , 1 , 4);
00168 cand_list.erase( cand_list.begin() );
00169 my_bmatch.FindBestMatchSubp( xblock , yblock , cand_list, mv_pred, loc_lambda );
00170
00171
00172 AddNewVlist(cand_list , mv_array[yblock][xblock] , 1 , 1 , 2);
00173 cand_list.erase( cand_list.begin() );
00174 my_bmatch.FindBestMatchSubp( xblock , yblock , cand_list, mv_pred, loc_lambda );
00175
00176
00177 AddNewVlist(cand_list , mv_array[yblock][xblock] , 1 , 1 , 1);
00178 cand_list.erase( cand_list.begin() );
00179 my_bmatch.FindBestMatchSubp( xblock , yblock , cand_list, mv_pred, loc_lambda );
00180
00181 }
00182
00183
00184 MVector SubpelRefine::GetPred(int xblock,int yblock,const MvArray& mvarray)
00185 {
00186 MVector mv_pred;
00187 ImageCoords n_coords;
00188 vector<MVector> neighbours;
00189
00190 if (xblock>0 && yblock>0 && xblock<mvarray.LastX())
00191 {
00192
00193 for (int i=0 ; i<m_nshift.Length() ; ++i)
00194 {
00195 n_coords.x = xblock+m_nshift[i].x;
00196 n_coords.y = yblock+m_nshift[i].y;
00197 neighbours.push_back(mvarray[n_coords.y][n_coords.x]);
00198
00199 }
00200 }
00201 else
00202 {
00203 for (int i=0 ; i<m_nshift.Length(); ++i )
00204 {
00205 n_coords.x = xblock+m_nshift[i].x;
00206 n_coords.y = yblock+m_nshift[i].y;
00207 if (n_coords.x>=0 && n_coords.y>=0 && n_coords.x<mvarray.LengthX() && n_coords.y<mvarray.LengthY())
00208 neighbours.push_back(mvarray[n_coords.y][n_coords.x]);
00209 }
00210 }
00211
00212 mv_pred = MvMedian(neighbours);
00213
00214 return mv_pred;
00215 }