mv_codec.cpp

00001 /* ***** BEGIN LICENSE BLOCK *****
00002 *
00003 * $Id: mv_codec.cpp,v 1.2 2005/01/30 05:11:40 gabest 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), Scott R Ladd
00024 *
00025 * Alternatively, the contents of this file may be used under the terms of
00026 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
00027 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
00028 * the GPL or the LGPL are applicable instead of those above. If you wish to
00029 * allow use of your version of this file only under the terms of the either
00030 * the GPL or LGPL and not to allow others to use your version of this file
00031 * under the MPL, indicate your decision by deleting the provisions above
00032 * and replace them with the notice and other provisions required by the GPL
00033 * or LGPL. If you do not delete the provisions above, a recipient may use
00034 * your version of this file under the terms of any one of the MPL, the GPL
00035 * or the LGPL.
00036 * ***** END LICENSE BLOCK ***** */
00037 
00038 #include <libdirac_common/mv_codec.h>
00039 using namespace dirac;
00040 
00041 //public functions//
00043 // Constructor for encoding
00044 MvDataCodec::MvDataCodec(BasicOutputManager* bits_out,
00045                          size_t number_of_contexts,
00046                          const ChromaFormat& cf)
00047   : ArithCodec <MvData> (bits_out,number_of_contexts),
00048     m_cformat(cf)
00049 {
00050     // nada
00051 }        
00052 
00053 // Constructor for decoding
00054 MvDataCodec::MvDataCodec(BitInputManager* bits_in,
00055                          size_t number_of_contexts,
00056                          const ChromaFormat& cf)
00057   : ArithCodec <MvData> (bits_in,number_of_contexts),
00058     m_cformat(cf)
00059 {
00060     // nada
00061 }    
00062 
00063 void MvDataCodec::InitContexts() 
00064 {
00065     for (size_t i = 0;  i < m_context_list.size();  ++i)
00066         m_context_list[i].SetCounts(1,1);     
00067 }
00068 
00069     
00070 
00071 //protected functions//
00073 
00074 inline void MvDataCodec::Resize(const int context_num)
00075 {
00076     m_context_list[context_num].HalveCounts();     
00077 }
00078 
00079 
00080 inline void MvDataCodec::Update( const bool symbol , const int context_num )
00081 {    
00082     m_context_list[context_num].IncrCount( symbol , 1 ); 
00083     
00084     if ( m_context_list[context_num].Weight()  >= 1024 )
00085         Resize( context_num ); 
00086 }
00087 inline void MvDataCodec::ResetAll() {}
00088 
00089 //coding functions//
00091 
00092 //prediction functions
00093 
00094 //basic context functions
00095 
00096 inline int MvDataCodec::ChooseContext(const MvData& data, const int BinNumber) const
00097 {
00098     return 0;
00099 }
00100 
00101 inline int MvDataCodec::ChooseContext(const MvData& data) const
00102 {
00103     return 0;
00104 }
00105 
00106 inline int MvDataCodec::ChooseSignContext(const MvData& data) const
00107 {
00108     return 0;
00109 }
00110 
00111 //proper context functions
00112 
00113 inline int MvDataCodec::ChooseMBSContext(const MvData& data, const int BinNumber) const
00114 {
00115     if (BinNumber == 1)
00116         return MB_SPLIT_BIN1_CTX; 
00117     else
00118         return MB_SPLIT_BIN2_CTX; 
00119 }
00120 
00121 inline int MvDataCodec::ChooseMBCContext(const MvData& data) const
00122 {
00123     return MB_CMODE_CTX; 
00124 }
00125 
00126 inline int MvDataCodec::ChoosePredContext(const MvData& data, const int BinNumber) const
00127 {
00128     if (BinNumber == 1)
00129         return PMODE_BIN1_CTX; 
00130     else if (BinNumber == 2)
00131         return PMODE_BIN2_CTX; 
00132     else
00133         return PMODE_BIN3_CTX; 
00134 }
00135 
00136 inline int MvDataCodec::ChooseREF1xContext(const MvData& data, const int BinNumber) const
00137 {
00138     if (BinNumber == 1)
00139         return REF1x_BIN1_CTX; 
00140     else if (BinNumber == 2)
00141         return REF1x_BIN2_CTX; 
00142     else if (BinNumber == 3)
00143         return REF1x_BIN3_CTX; 
00144     else if (BinNumber == 4)
00145         return REF1x_BIN4_CTX; 
00146     else
00147         return REF1x_BIN5plus_CTX; 
00148 }
00149 
00150 inline int MvDataCodec::ChooseREF1xSignContext(const MvData& data) const
00151 {
00152     return REF1x_SIGN0_CTX;
00153 }
00154 
00155 inline int MvDataCodec::ChooseREF1yContext(const MvData& data, const int BinNumber) const
00156 {
00157     if (BinNumber == 1)
00158         return REF1y_BIN1_CTX; 
00159     else if (BinNumber == 2)
00160         return REF1y_BIN2_CTX; 
00161     else if (BinNumber == 3)
00162         return REF1y_BIN3_CTX; 
00163     else if (BinNumber == 4)
00164         return REF1y_BIN4_CTX; 
00165     else
00166         return REF1y_BIN5plus_CTX; 
00167 }
00168 
00169 inline int MvDataCodec::ChooseREF1ySignContext(const MvData& data) const
00170 {
00171     return REF1y_SIGN0_CTX;
00172 }
00173 
00174 inline int MvDataCodec::ChooseREF2xContext(const MvData& data, const int BinNumber) const
00175 {
00176     if (BinNumber == 1)
00177         return REF2x_BIN1_CTX; 
00178     else if (BinNumber == 2)
00179         return REF2x_BIN2_CTX; 
00180     else if (BinNumber == 3)
00181         return REF2x_BIN3_CTX; 
00182     else if (BinNumber == 4)
00183         return REF2x_BIN4_CTX; 
00184     else
00185         return REF2x_BIN5plus_CTX; 
00186 }
00187 
00188 inline int MvDataCodec::ChooseREF2xSignContext(const MvData& data) const
00189 {
00190     return REF2x_SIGN0_CTX; 
00191 }
00192 
00193 inline int MvDataCodec::ChooseREF2yContext(const MvData& data, const int BinNumber) const
00194 {
00195     if (BinNumber == 1)
00196         return REF2y_BIN1_CTX; 
00197     else if (BinNumber == 2)
00198         return REF2y_BIN2_CTX; 
00199     else if (BinNumber == 3)
00200         return REF2y_BIN3_CTX; 
00201     else if (BinNumber == 4)
00202         return REF2y_BIN4_CTX; 
00203     else
00204         return REF2y_BIN5plus_CTX; 
00205 }
00206 
00207 inline int MvDataCodec::ChooseREF2ySignContext(const MvData& data) const
00208 {
00209     return REF2y_SIGN0_CTX; 
00210 }
00211 
00212 inline int MvDataCodec::ChooseYDCContext(const MvData& data, const int BinNumber) const
00213 {
00214     if (BinNumber == 1)
00215         return YDC_BIN1_CTX; 
00216     else
00217         return YDC_BIN2plus_CTX; 
00218 }
00219 
00220 inline int MvDataCodec::ChooseUDCContext(const MvData& data, const int BinNumber) const
00221 {
00222     if (BinNumber == 1)
00223         return UDC_BIN1_CTX; 
00224     else
00225         return UDC_BIN2plus_CTX; 
00226 }
00227 
00228 inline int MvDataCodec::ChooseVDCContext(const MvData& data, const int BinNumber) const
00229 {
00230     if (BinNumber == 1)
00231         return VDC_BIN1_CTX; 
00232     else
00233         return VDC_BIN2plus_CTX; 
00234 }
00235 
00236 inline int MvDataCodec::ChooseYDCSignContext(const MvData& data) const
00237 {
00238     return YDC_SIGN0_CTX; 
00239 }
00240 
00241 inline int MvDataCodec::ChooseUDCSignContext(const MvData& data) const
00242 {
00243     return UDC_SIGN0_CTX; 
00244 }
00245 
00246 inline int MvDataCodec::ChooseVDCSignContext(const MvData& data) const
00247 {
00248     return VDC_SIGN0_CTX; 
00249 }
00250 
00251 inline unsigned int MvDataCodec::MBSplitPrediction(const TwoDArray<int> & split_data ) const
00252 {    
00253     int result = 0;
00254     
00255     std::vector < unsigned int >  nbrs;
00256     
00257     if (mb_xp > 0 && mb_yp > 0)
00258     {
00259         nbrs.push_back( split_data[mb_yp-1][mb_xp] ); 
00260         nbrs.push_back( split_data[mb_yp-1][mb_xp-1] ); 
00261         nbrs.push_back( split_data[mb_yp][mb_xp-1] ); 
00262 
00263         result = GetMean(nbrs);     
00264     }
00265     else if (mb_xp > 0 && mb_yp == 0)
00266         result = split_data[mb_yp][mb_xp-1]; 
00267     else if (mb_xp == 0 && mb_yp > 0)
00268         result =  split_data[mb_yp-1][mb_xp]; 
00269 
00270     return result; 
00271 }
00272 
00273 inline bool MvDataCodec::MBCBModePrediction(const TwoDArray <bool> & cbm_data) const
00274 {
00275     bool result = true;
00276     std::vector < unsigned int >  nbrs; 
00277     
00278     if (mb_xp > 0 && mb_yp > 0)
00279     {
00280         nbrs.push_back( (unsigned int)( cbm_data[mb_yp-1][mb_xp] ) ); 
00281         nbrs.push_back( (unsigned int)( cbm_data[mb_yp-1][mb_xp-1] ) ); 
00282         nbrs.push_back( (unsigned int)( cbm_data[mb_yp][mb_xp-1] ) ); 
00283 
00284         result = bool(GetMean(nbrs));     
00285     }
00286     else if (mb_xp > 0 && mb_yp == 0)
00287         result = cbm_data[mb_yp][mb_xp-1]; 
00288     else if (mb_xp == 0 && mb_yp > 0)
00289         result = cbm_data[mb_yp-1][mb_xp]; 
00290     
00291     return result; 
00292 }
00293 
00294 inline unsigned int MvDataCodec::BlockModePrediction(const TwoDArray < PredMode > & preddata) const
00295 {
00296     unsigned int result = (unsigned int)(REF1_ONLY);
00297     std::vector <unsigned int> nbrs; 
00298     
00299     if (b_xp > 0 && b_yp > 0)
00300     {
00301         nbrs.push_back( (unsigned int)( preddata[b_yp-1][b_xp] ) ); 
00302         nbrs.push_back( (unsigned int)( preddata[b_yp-1][b_xp-1] ) ); 
00303         nbrs.push_back( (unsigned int)( preddata[b_yp][b_xp-1] ) ); 
00304 
00305         result = GetMean(nbrs);
00306     }
00307     else if (b_xp > 0 && b_yp == 0)
00308         result = preddata[b_yp][b_xp-1]; 
00309     else if (b_xp == 0 && b_yp > 0)
00310         result = preddata[b_yp-1][b_xp]; 
00311 
00312     return result; 
00313 }
00314 
00315 inline MVector MvDataCodec::Mv1Prediction(const MvArray& mvarray,
00316                                           const TwoDArray < PredMode > & preddata) const
00317 {
00318     std::vector <MVector>  nbrs; 
00319     PredMode pmode;     
00320     MVector result; 
00321     
00322     if (b_xp > 0 && b_yp > 0)
00323     {
00324         pmode = preddata[b_yp-1][b_xp]; 
00325         if (pmode == REF1_ONLY || pmode == REF1AND2) 
00326             nbrs.push_back(mvarray[b_yp-1][b_xp]); 
00327         
00328         pmode = preddata[b_yp-1][b_xp-1]; 
00329         if (pmode == REF1_ONLY || pmode == REF1AND2)
00330             nbrs.push_back(mvarray[b_yp-1][b_xp-1]); 
00331         
00332         pmode = preddata[b_yp][b_xp-1]; 
00333         if (pmode == REF1_ONLY || pmode == REF1AND2)        
00334             nbrs.push_back(mvarray[b_yp][b_xp-1]); 
00335         
00336         if (nbrs.size() > 0)
00337             result = MvMedian(nbrs); 
00338     }
00339     else if (b_xp > 0 && b_yp == 0)
00340     {
00341         pmode = preddata[0][b_xp-1]; 
00342         if (pmode == REF1_ONLY || pmode == REF1AND2)
00343             result = mvarray[0][b_xp-1]; 
00344     }
00345     else if (b_xp == 0 && b_yp > 0)
00346     {
00347         pmode = preddata[b_yp-1][0]; 
00348         if (pmode == REF1_ONLY || pmode == REF1AND2)
00349             result = mvarray[b_yp-1][0]; 
00350     }
00351 
00352     return result; 
00353 }
00354 
00355 inline MVector MvDataCodec::Mv2Prediction(const MvArray & mvarray,
00356                                           const TwoDArray < PredMode >  & preddata) const
00357 {
00358     std::vector <MVector>  nbrs; 
00359     PredMode pmode; 
00360     MVector result; 
00361     
00362     if (b_xp > 0 && b_yp > 0)
00363     {
00364         pmode = preddata[b_yp-1][b_xp]; 
00365         if (pmode == REF2_ONLY || pmode == REF1AND2)
00366             nbrs.push_back(mvarray[b_yp-1][b_xp]); 
00367         
00368         pmode = preddata[b_yp-1][b_xp-1]; 
00369         if (pmode == REF2_ONLY || pmode == REF1AND2)
00370             nbrs.push_back(mvarray[b_yp-1][b_xp-1]); 
00371         
00372         pmode = preddata[b_yp][b_xp-1]; 
00373         if (pmode == REF2_ONLY || pmode == REF1AND2)
00374             nbrs.push_back(mvarray[b_yp][b_xp-1]); 
00375         
00376         if (nbrs.size() > 0)
00377             result = MvMedian(nbrs); 
00378     }
00379     else if (b_xp > 0 && b_yp == 0)
00380     {
00381         pmode = preddata[0][b_xp-1]; 
00382         if(pmode == REF2_ONLY || pmode == REF1AND2)
00383             result = mvarray[0][b_xp-1]; 
00384     }
00385     else if (b_xp == 0 && b_yp > 0)
00386     {
00387         pmode = preddata[b_yp-1][0]; 
00388         if(pmode == REF2_ONLY || pmode == REF1AND2)
00389             result = mvarray[b_yp-1][0]; 
00390     }
00391 
00392     return result; 
00393 }
00394 
00395 inline ValueType MvDataCodec::DCPrediction(const TwoDArray < ValueType > & dcdata,
00396                                            const TwoDArray < PredMode > & preddata) const
00397 {
00398     std::vector < int >  nbrs; 
00399     PredMode pmode;
00400     ValueType result = 128; 
00401     
00402     if (b_xp > 0 && b_yp > 0)
00403     {
00404         pmode = preddata[b_yp-1][b_xp]; 
00405         if (pmode == INTRA) 
00406             nbrs.push_back(int(dcdata[b_yp-1][b_xp])); 
00407         
00408         pmode = preddata[b_yp-1][b_xp-1]; 
00409         if (pmode == INTRA)
00410             nbrs.push_back(int(dcdata[b_yp-1][b_xp-1])); 
00411         
00412         pmode = preddata[b_yp][b_xp-1]; 
00413         if (pmode == INTRA)        
00414             nbrs.push_back(int(dcdata[b_yp][b_xp-1])); 
00415         
00416         if (nbrs.size() > 0)
00417             result = ValueType(GetMean(nbrs));     
00418     }
00419     else if (b_xp > 0 && b_yp == 0)
00420     {
00421         pmode = preddata[0][b_xp-1]; 
00422         if (pmode == INTRA)
00423             result = dcdata[0][b_xp-1]; 
00424     }
00425     else if (b_xp == 0 && b_yp > 0)
00426     {
00427         pmode = preddata[b_yp-1][0]; 
00428         if (pmode == INTRA)
00429             result = dcdata[b_yp-1][0]; 
00430     }
00431 
00432     return result;
00433 }
00434 
00435 
00436 void MvDataCodec::DoWorkCode( MvData& in_data )
00437 {
00438     int step,max; 
00439     int pstep,pmax; 
00440     int split_depth; 
00441     bool common_ref; 
00442 
00443     MB_count = 0; 
00444     
00445     for (mb_yp = 0, mb_tlb_y = 0;  mb_yp < in_data.MBSplit().LengthY();  ++mb_yp, mb_tlb_y += 4)
00446     {
00447         for (mb_xp = 0,mb_tlb_x = 0; mb_xp < in_data.MBSplit().LengthX(); ++mb_xp,mb_tlb_x += 4)
00448         {
00449              //start with split mode
00450             CodeMBSplit(in_data); 
00451             split_depth = in_data.MBSplit()[mb_yp][mb_xp]; 
00452 
00453             step = 4  >>  (split_depth); 
00454             max = (1 << split_depth); 
00455 
00456             //next do common_ref
00457             if(split_depth != 0)
00458             {
00459                 CodeMBCom(in_data); 
00460                 pstep = step; 
00461                 pmax = max; 
00462             }
00463             else
00464             {
00465                 pstep = 4; 
00466                 pmax = 1; 
00467             }
00468             common_ref = in_data.MBCommonMode()[mb_yp][mb_xp]; 
00469 
00470 
00471             //do prediction modes            
00472             for (b_yp = mb_tlb_y; b_yp < mb_tlb_y+4; b_yp += pstep)
00473                 for (b_xp = mb_tlb_x; b_xp < mb_tlb_x+4; b_xp += pstep)
00474                     CodePredmode(in_data); 
00475             
00476             step = 4 >> (split_depth);             
00477             
00478                //now do all the block mvs in the mb            
00479             for (b_yp = mb_tlb_y; b_yp < mb_tlb_y+4; b_yp += step)
00480             {
00481                 for (b_xp = mb_tlb_x; b_xp < mb_tlb_x+4; b_xp += step)
00482                 {
00483                     if (in_data.Mode()[b_yp][b_xp] == REF1_ONLY || in_data.Mode()[b_yp][b_xp] == REF1AND2 )
00484                         CodeMv1(in_data); 
00485                     
00486                     if (in_data.Mode()[b_yp][b_xp] == REF2_ONLY || in_data.Mode()[b_yp][b_xp] == REF1AND2 )
00487                         CodeMv2(in_data); 
00488                     
00489                     if(in_data.Mode()[b_yp][b_xp] == INTRA)
00490                         CodeDC(in_data);                     
00491                 }//b_xp
00492             }//b_yp    
00493             
00494             //TODO: Update all contexts here?
00495             
00496         }//mb_xp
00497     }//mb_yp
00498 
00499 }
00500 
00501 
00502 void MvDataCodec::CodeMBSplit(const MvData& in_data)
00503 {
00504     int val = in_data.MBSplit()[mb_yp][mb_xp] - MBSplitPrediction( in_data.MBSplit() ); 
00505     
00506     if (val < 0)
00507         val += 3; //produce prediction mod 3    
00508     
00509     int ctx; 
00510     
00511     for (int bin = 1; bin <= val; ++bin)
00512     {
00513         ctx = ChooseMBSContext(in_data,bin); 
00514         EncodeSymbol(0,ctx); 
00515     }
00516     
00517     if (val != 2)//if we've had two zeroes, know we must have value 2
00518         EncodeSymbol(1,ChooseMBSContext(in_data,val+1)); 
00519 }
00520 
00521 void MvDataCodec::CodeMBCom(const MvData& in_data)
00522 {
00523     bool val = in_data.MBCommonMode()[mb_yp][mb_xp]; 
00524     
00525     if (val != MBCBModePrediction( in_data.MBCommonMode() ))
00526         EncodeSymbol( 1 , ChooseMBCContext( in_data ) ); 
00527     else
00528         EncodeSymbol( 0 , ChooseMBCContext( in_data ) ); 
00529 }
00530 
00531 void MvDataCodec::CodePredmode(const MvData& in_data)
00532 {
00533     int val = in_data.Mode()[b_yp][b_xp] - BlockModePrediction( in_data.Mode() ); 
00534     
00535     if (val < 0)
00536         val += 4;  //produce value mod 4    
00537     
00538     for (int bin = 1;  bin<= val;  ++bin)
00539         EncodeSymbol( 0 , ChoosePredContext( in_data , bin ) ); 
00540                  
00541     if (val  !=  3) //if we've had three zeroes, know we must have value 3
00542         EncodeSymbol( 1 , ChoosePredContext( in_data , val + 1 ) ); 
00543 }
00544 
00545 void MvDataCodec::CodeMv1(const MvData& in_data )
00546 {
00547     const MvArray& mv_array = in_data.Vectors(1);
00548     const MVector pred = Mv1Prediction( mv_array , in_data.Mode() ); 
00549 
00550     const int valx = mv_array[b_yp][b_xp].x - pred.x; 
00551     const int abs_valx = std::abs(valx); 
00552     
00553     for (int bin = 1;  bin  <= abs_valx;  ++bin)
00554         EncodeSymbol( 0 , ChooseREF1xContext( in_data , bin ) ); 
00555 
00556     EncodeSymbol( 1 , ChooseREF1xContext( in_data , abs_valx + 1 ) ); 
00557     
00558     if (valx != 0)
00559         EncodeSymbol( ( (valx > 0)? 1 : 0) , ChooseREF1xSignContext( in_data ) ); 
00560 
00561     const int valy = mv_array[b_yp][b_xp].y - pred.y;         
00562     const int abs_valy = std::abs( valy );     
00563     
00564     for (int bin = 1; bin<=abs_valy ; ++bin )
00565         EncodeSymbol( 0 , ChooseREF1yContext( in_data , bin ) );         
00566     
00567     EncodeSymbol( 1 , ChooseREF1yContext( in_data , abs_valy + 1 ) ); 
00568     
00569     if (valy != 0)
00570         EncodeSymbol( ( (valy > 0)? 1 : 0) , ChooseREF1ySignContext( in_data ) );  
00571 }
00572 
00573 void MvDataCodec::CodeMv2(const MvData& in_data)
00574 {
00575     const MvArray& mv_array = in_data.Vectors(2);
00576     const MVector pred = Mv2Prediction( mv_array , in_data.Mode() );     
00577 
00578     const int valx = mv_array[b_yp][b_xp].x - pred.x; 
00579     const int abs_valx = abs(valx); 
00580     
00581     for (int bin = 1; bin <= abs_valx; ++bin)
00582         EncodeSymbol( 0 , ChooseREF2xContext( in_data , bin ) ); 
00583 
00584     EncodeSymbol( 1 , ChooseREF2xContext( in_data , abs_valx + 1 ) ); 
00585     
00586     if (valx != 0)
00587         EncodeSymbol( ( (valx > 0)? 1 : 0) , ChooseREF2xSignContext( in_data ) ); 
00588 
00589     const int valy = mv_array[b_yp][b_xp].y-pred.y; 
00590     const int abs_valy = std::abs(valy);     
00591     
00592     for (int bin = 1; bin<=abs_valy; ++bin )
00593         EncodeSymbol( 0 , ChooseREF2yContext( in_data , bin ) ); 
00594     
00595     EncodeSymbol( 1 , ChooseREF2yContext( in_data , abs_valy + 1 ) ); 
00596     
00597     if (valy != 0)
00598         EncodeSymbol( ( (valy > 0)? 1 : 0) , ChooseREF2ySignContext( in_data ) ); 
00599 }
00600 
00601 void MvDataCodec::CodeDC(const MvData& in_data)
00602 {    
00603     //begin with Y DC value    
00604     const ValueType valY = in_data.DC( Y_COMP )[b_yp][b_xp]
00605                            - DCPrediction( in_data.DC(Y_COMP) , in_data.Mode() ); 
00606     const ValueType abs_valY = std::abs( valY ); 
00607 
00608     for (ValueType bin = 1; bin <= abs_valY; ++bin)
00609         EncodeSymbol( 0 , ChooseYDCContext( in_data , bin ) ); 
00610 
00611     EncodeSymbol( 1 , ChooseYDCContext (in_data , abs_valY + 1 ) ); 
00612     
00613     if (valY != 0)
00614         EncodeSymbol( ( (valY > 0)? 1 : 0) , ChooseYDCSignContext( in_data ) ); 
00615 
00616     //now do U and V if necessary
00617     if (m_cformat != Yonly)
00618     {
00619         //continue with U and V DC values
00620         const int valU =  in_data.DC(U_COMP)[b_yp][b_xp]
00621                           - DCPrediction(in_data.DC( U_COMP ) , in_data.Mode()); 
00622         const int abs_valU = std::abs( valU ); 
00623 
00624         for (ValueType bin = 1;  bin<=abs_valU ; ++bin)
00625             EncodeSymbol( 0 , ChooseUDCContext( in_data , bin ) ); 
00626         
00627         EncodeSymbol( 1 , ChooseUDCContext( in_data , abs_valU + 1 ) ); 
00628         
00629         if (valU != 0)
00630             EncodeSymbol( ( (valU > 0) ? 1 : 0) , ChooseUDCSignContext( in_data ) ); 
00631         
00632         const int valV = in_data.DC( V_COMP )[b_yp][b_xp] 
00633                          - DCPrediction( in_data.DC( V_COMP ) , in_data.Mode() ); 
00634         const int abs_valV = std::abs( valV ); 
00635 
00636         for (ValueType bin = 1; bin<=abs_valV ; ++bin)
00637             EncodeSymbol( 0 , ChooseVDCContext( in_data , bin ) ); 
00638 
00639         EncodeSymbol( 1 , ChooseVDCContext( in_data , abs_valV + 1 ) ); 
00640         
00641         if (valV != 0)
00642             EncodeSymbol( ( (valV > 0)? 1 : 0) , ChooseVDCSignContext( in_data ) ); 
00643     }
00644 }
00645 
00646 //decoding functions//
00648 
00649 void MvDataCodec::DoWorkDecode( MvData& out_data, int num_bits)
00650 {
00651     int step,max; 
00652     int pstep,pmax;     
00653     int split_depth; 
00654     bool common_ref; 
00655     int xstart,ystart;     
00656 
00657     for (mb_yp = 0,mb_tlb_y = 0; mb_yp < out_data.MBSplit().LengthY(); ++mb_yp,mb_tlb_y += 4)
00658     {
00659         for (mb_xp = 0,mb_tlb_x = 0; mb_xp < out_data.MBSplit().LengthX(); ++mb_xp,mb_tlb_x += 4)
00660         {
00661              //start with split mode
00662             DecodeMBSplit( out_data ); 
00663             split_depth = out_data.MBSplit()[mb_yp][mb_xp]; 
00664             step =  4  >>  (split_depth); 
00665             max  = (1 << split_depth); 
00666 
00667             //next do common_ref
00668             if(split_depth  !=  0)
00669             {
00670                 DecodeMBCom( out_data ); 
00671                 pstep = step; 
00672                 pmax = max; 
00673             }
00674             else
00675             {
00676                 out_data.MBCommonMode()[mb_yp][mb_xp] = true; 
00677                 pstep = 4; 
00678                 pmax = 1; 
00679             }
00680             
00681             common_ref = out_data.MBCommonMode()[mb_yp][mb_xp]; 
00682 
00683             // do prediction modes
00684             for (b_yp = mb_tlb_y;  b_yp < mb_tlb_y + 4;  b_yp += pstep)
00685             {                
00686                 for (b_xp = mb_tlb_x; b_xp < mb_tlb_x + 4;  b_xp += pstep)
00687                 {
00688                     DecodePredmode(out_data); 
00689                     
00690                     // propagate throughout MB                
00691                     for (int y = b_yp;  y < b_yp + pstep;  y++)
00692                         for (int x = b_xp;  x < b_xp + pstep;  x++)
00693                             out_data.Mode()[y][x] = out_data.Mode()[b_yp][b_xp];                                                         
00694                 }
00695             }
00696 
00697                //now do all the block mvs in the mb
00698             for (int j = 0; j < max; ++j)
00699             {                
00700                 for (int i = 0; i < max; ++i)
00701                 {
00702                     xstart = b_xp = mb_tlb_x + i * step; 
00703                     ystart = b_yp = mb_tlb_y + j * step;                                             
00704                     
00705                     if (out_data.Mode()[b_yp][b_xp] == REF1_ONLY || out_data.Mode()[b_yp][b_xp] == REF1AND2 )
00706                         DecodeMv1( out_data ); 
00707                     
00708                     if (out_data.Mode()[b_yp][b_xp] == REF2_ONLY || out_data.Mode()[b_yp][b_xp] == REF1AND2 )
00709                         DecodeMv2( out_data ); 
00710                     
00711                     if(out_data.Mode()[b_yp][b_xp] == INTRA)
00712                         DecodeDC( out_data ); 
00713                     
00714                       //propagate throughout MB    
00715                     for (b_yp = ystart; b_yp < ystart+step; b_yp++)
00716                     {
00717                         for (b_xp = xstart; b_xp < xstart+step; b_xp++)
00718                         {                    
00719                             out_data.Vectors(1)[b_yp][b_xp].x = out_data.Vectors(1)[ystart][xstart].x; 
00720                             out_data.Vectors(1)[b_yp][b_xp].y = out_data.Vectors(1)[ystart][xstart].y; 
00721                             out_data.Vectors(2)[b_yp][b_xp].x = out_data.Vectors(2)[ystart][xstart].x; 
00722                             out_data.Vectors(2)[b_yp][b_xp].y = out_data.Vectors(2)[ystart][xstart].y; 
00723                             out_data.DC( Y_COMP )[b_yp][b_xp] = out_data.DC( Y_COMP )[ystart][xstart]; 
00724                             out_data.DC( U_COMP )[b_yp][b_xp] = out_data.DC( U_COMP )[ystart][xstart]; 
00725                             out_data.DC( V_COMP )[b_yp][b_xp] = out_data.DC( V_COMP )[ystart][xstart]; 
00726                         }//b_xp
00727                     }//b_yp
00728                 }//i                    
00729             }//j
00730 
00731         }//mb_xp
00732     }//mb_yp
00733 
00734 }
00735 
00736 void MvDataCodec::DecodeMBSplit(MvData& out_data)
00737 {
00738     int val = 0; 
00739     int bin = 1; 
00740     bool bit; 
00741 
00742     do
00743     {
00744         DecodeSymbol( bit , ChooseMBSContext( out_data , bin ) ); 
00745         
00746         if (!bit)
00747             val++; 
00748         
00749         bin++; 
00750     }
00751     while (!bit && val != 2);  
00752     
00753     out_data.MBSplit()[mb_yp][mb_xp] = ( val + MBSplitPrediction( out_data.MBSplit() ) ) % 3;     
00754 }
00755 
00756 void MvDataCodec::DecodeMBCom( MvData& out_data )
00757 {
00758     bool bit; 
00759     DecodeSymbol( bit , ChooseMBCContext( out_data ) ); 
00760     
00761     if ( bit )
00762         out_data.MBCommonMode()[mb_yp][mb_xp] = !MBCBModePrediction( out_data.MBCommonMode() ); 
00763     else
00764         out_data.MBCommonMode()[mb_yp][mb_xp] = MBCBModePrediction( out_data.MBCommonMode() ); 
00765 }
00766 
00767 void MvDataCodec::DecodePredmode( MvData& out_data )
00768 {
00769     int val = 0; 
00770     int bin = 1; 
00771     bool bit; 
00772     
00773     do
00774     {
00775         DecodeSymbol( bit , ChoosePredContext( out_data , bin ) ); 
00776         
00777         if (!bit)
00778             val++; 
00779         
00780         bin++; 
00781     }
00782     while (!bit && val != 3);  
00783     
00784     out_data.Mode()[b_yp][b_xp] = PredMode( ( val + BlockModePrediction (out_data.Mode() ) ) %4); 
00785 }
00786 
00787 void MvDataCodec::DecodeMv1( MvData& out_data )
00788 {
00789     MVector pred = Mv1Prediction( out_data.Vectors(1) , out_data.Mode() );     
00790     int val = 0;
00791     int bin = 1; 
00792     bool bit; 
00793     
00794     do
00795     {
00796         DecodeSymbol( bit , ChooseREF1xContext( out_data , bin ) ); 
00797         
00798         if ( !bit )
00799             val++; 
00800         
00801         bin++; 
00802     }
00803     while ( !bit ); 
00804     
00805     if (val != 0)
00806     {
00807         DecodeSymbol( bit , ChooseREF1xSignContext( out_data ) ); 
00808         
00809         if (!bit)
00810             val = -val; 
00811     }
00812     
00813     out_data.Vectors(1)[b_yp][b_xp].x = val + pred.x; 
00814 
00815     val = 0; 
00816     bin = 1; 
00817     
00818     do
00819     {
00820         DecodeSymbol( bit , ChooseREF1yContext( out_data , bin ) ); 
00821         
00822         if ( !bit )
00823             val++; 
00824         
00825         bin++; 
00826     }
00827     while ( !bit ); 
00828     
00829     if (val != 0)
00830     {
00831         DecodeSymbol( bit , ChooseREF1ySignContext( out_data ) ); 
00832         
00833         if (!bit)
00834             val = -val; 
00835     }
00836     
00837     out_data.Vectors(1)[b_yp][b_xp].y = val + pred.y; 
00838 }
00839 
00840 void MvDataCodec::DecodeMv2( MvData& out_data )
00841 {
00842     MVector pred = Mv2Prediction( out_data.Vectors(2) , out_data.Mode() ); 
00843     int val = 0; 
00844     int bin = 1; 
00845     bool bit; 
00846     
00847     do
00848     {
00849         DecodeSymbol( bit , ChooseREF2xContext( out_data , bin ) ); 
00850         
00851         if ( !bit )
00852             val++; 
00853         
00854         bin++; 
00855     }
00856     while ( !bit ); 
00857     
00858     if (val != 0)
00859     {
00860         DecodeSymbol( bit , ChooseREF2xSignContext( out_data ) ); 
00861         
00862         if (!bit)
00863             val = -val; 
00864     }
00865     
00866     out_data.Vectors(2)[b_yp][b_xp].x = val + pred.x; 
00867 
00868     val = 0; 
00869     bin = 1; 
00870     
00871     do
00872     {
00873         DecodeSymbol( bit , ChooseREF2yContext( out_data , bin ) ); 
00874         
00875         if ( !bit )
00876             val++; 
00877         
00878         bin++; 
00879     }
00880     while ( !bit ); 
00881     
00882     if (val != 0)
00883     {
00884         DecodeSymbol( bit , ChooseREF2ySignContext( out_data ) ); 
00885         
00886         if ( !bit )
00887             val = -val; 
00888     }
00889     
00890     out_data.Vectors(2)[b_yp][b_xp].y = val + pred.y; 
00891 }
00892 
00893 void MvDataCodec::DecodeDC( MvData& out_data )
00894 {
00895     //begin with Y DC value    
00896     ValueType val = 0; 
00897     int bin = 1; 
00898     bool bit; 
00899     
00900     do
00901     {
00902         DecodeSymbol( bit , ChooseYDCContext( out_data , bin ) ); 
00903         
00904         if ( !bit )
00905             val++; 
00906         
00907         bin++; 
00908     }
00909     while ( !bit ); 
00910     
00911     if (val != 0)
00912     {
00913         DecodeSymbol( bit , ChooseYDCSignContext( out_data ) ); 
00914         
00915         if (!bit)
00916             val = -val; 
00917     }
00918     
00919     out_data.DC( Y_COMP )[b_yp][b_xp] = val + DCPrediction( out_data.DC( Y_COMP ) , out_data.Mode()); 
00920 
00921     if (m_cformat != Yonly)
00922     {
00923         //move onto U and V DC values
00924         val = 0; 
00925         bin = 1; 
00926         
00927         do
00928         {
00929             DecodeSymbol( bit , ChooseUDCContext( out_data , bin ) ); 
00930             
00931             if (!bit)
00932                 val++; 
00933             
00934             bin++; 
00935         }
00936         while (!bit); 
00937         
00938         if (val != 0)
00939         {
00940             DecodeSymbol( bit , ChooseUDCSignContext ( out_data ) ); 
00941             
00942             if (!bit)
00943                 val = -val; 
00944         }
00945         
00946         out_data.DC( U_COMP )[b_yp][b_xp] = val + DCPrediction( out_data.DC( U_COMP ) , out_data.Mode()); 
00947 
00948         val = 0; 
00949         bin = 1; 
00950         
00951         do
00952         {
00953             DecodeSymbol( bit , ChooseVDCContext( out_data , bin ) ); 
00954             
00955             if ( !bit )
00956                 val++; 
00957             
00958             bin++; 
00959         }
00960         while ( !bit ); 
00961         
00962         if (val != 0)
00963         {
00964             DecodeSymbol( bit , ChooseVDCSignContext( out_data ) ); 
00965             
00966             if ( !bit )
00967                 val = -val; 
00968         }
00969         
00970         out_data.DC( V_COMP )[b_yp][b_xp] = val + DCPrediction( out_data.DC( V_COMP ) , out_data.Mode() ); 
00971     }
00972 }

Generated on Tue Dec 13 14:47:14 2005 for guliverkli by  doxygen 1.4.5