- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# 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 }