mv_codec.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:28k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. *
  3. * $Id: mv_codec.cpp,v 1.2 2005/01/30 05:11:40 gabest Exp $ $Name:  $
  4. *
  5. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  6. *
  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/
  11. *
  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.
  15. *
  16. * The Original Code is BBC Research and Development code.
  17. *
  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.
  22. *
  23. * Contributor(s): Thomas Davies (Original Author), Scott R Ladd
  24. *
  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 ***** */
  37. #include <libdirac_common/mv_codec.h>
  38. using namespace dirac;
  39. //public functions//
  40. ////////////////////
  41. // Constructor for encoding
  42. MvDataCodec::MvDataCodec(BasicOutputManager* bits_out,
  43.                          size_t number_of_contexts,
  44.                          const ChromaFormat& cf)
  45.   : ArithCodec <MvData> (bits_out,number_of_contexts),
  46.     m_cformat(cf)
  47. {
  48.     // nada
  49. }        
  50. // Constructor for decoding
  51. MvDataCodec::MvDataCodec(BitInputManager* bits_in,
  52.                          size_t number_of_contexts,
  53.                          const ChromaFormat& cf)
  54.   : ArithCodec <MvData> (bits_in,number_of_contexts),
  55.     m_cformat(cf)
  56. {
  57.     // nada
  58. }    
  59. void MvDataCodec::InitContexts() 
  60. {
  61.     for (size_t i = 0;  i < m_context_list.size();  ++i)
  62.         m_context_list[i].SetCounts(1,1);     
  63. }
  64.     
  65. //protected functions//
  66. ///////////////////////
  67. inline void MvDataCodec::Resize(const int context_num)
  68. {
  69.     m_context_list[context_num].HalveCounts();     
  70. }
  71. inline void MvDataCodec::Update( const bool symbol , const int context_num )
  72. {    
  73.     m_context_list[context_num].IncrCount( symbol , 1 ); 
  74.     
  75.     if ( m_context_list[context_num].Weight()  >= 1024 )
  76.         Resize( context_num ); 
  77. }
  78. inline void MvDataCodec::ResetAll() {}
  79. //coding functions//
  80. ////////////////////
  81. //prediction functions
  82. //basic context functions
  83. inline int MvDataCodec::ChooseContext(const MvData& data, const int BinNumber) const
  84. {
  85.     return 0;
  86. }
  87. inline int MvDataCodec::ChooseContext(const MvData& data) const
  88. {
  89.     return 0;
  90. }
  91. inline int MvDataCodec::ChooseSignContext(const MvData& data) const
  92. {
  93.     return 0;
  94. }
  95. //proper context functions
  96. inline int MvDataCodec::ChooseMBSContext(const MvData& data, const int BinNumber) const
  97. {
  98.     if (BinNumber == 1)
  99.         return MB_SPLIT_BIN1_CTX; 
  100.     else
  101.         return MB_SPLIT_BIN2_CTX; 
  102. }
  103. inline int MvDataCodec::ChooseMBCContext(const MvData& data) const
  104. {
  105.     return MB_CMODE_CTX; 
  106. }
  107. inline int MvDataCodec::ChoosePredContext(const MvData& data, const int BinNumber) const
  108. {
  109.     if (BinNumber == 1)
  110.         return PMODE_BIN1_CTX; 
  111.     else if (BinNumber == 2)
  112.         return PMODE_BIN2_CTX; 
  113.     else
  114.         return PMODE_BIN3_CTX; 
  115. }
  116. inline int MvDataCodec::ChooseREF1xContext(const MvData& data, const int BinNumber) const
  117. {
  118.     if (BinNumber == 1)
  119.         return REF1x_BIN1_CTX; 
  120.     else if (BinNumber == 2)
  121.         return REF1x_BIN2_CTX; 
  122.     else if (BinNumber == 3)
  123.         return REF1x_BIN3_CTX; 
  124.     else if (BinNumber == 4)
  125.         return REF1x_BIN4_CTX; 
  126.     else
  127.         return REF1x_BIN5plus_CTX; 
  128. }
  129. inline int MvDataCodec::ChooseREF1xSignContext(const MvData& data) const
  130. {
  131.     return REF1x_SIGN0_CTX;
  132. }
  133. inline int MvDataCodec::ChooseREF1yContext(const MvData& data, const int BinNumber) const
  134. {
  135.     if (BinNumber == 1)
  136.         return REF1y_BIN1_CTX; 
  137.     else if (BinNumber == 2)
  138.         return REF1y_BIN2_CTX; 
  139.     else if (BinNumber == 3)
  140.         return REF1y_BIN3_CTX; 
  141.     else if (BinNumber == 4)
  142.         return REF1y_BIN4_CTX; 
  143.     else
  144.         return REF1y_BIN5plus_CTX; 
  145. }
  146. inline int MvDataCodec::ChooseREF1ySignContext(const MvData& data) const
  147. {
  148.     return REF1y_SIGN0_CTX;
  149. }
  150. inline int MvDataCodec::ChooseREF2xContext(const MvData& data, const int BinNumber) const
  151. {
  152.     if (BinNumber == 1)
  153.         return REF2x_BIN1_CTX; 
  154.     else if (BinNumber == 2)
  155.         return REF2x_BIN2_CTX; 
  156.     else if (BinNumber == 3)
  157.         return REF2x_BIN3_CTX; 
  158.     else if (BinNumber == 4)
  159.         return REF2x_BIN4_CTX; 
  160.     else
  161.         return REF2x_BIN5plus_CTX; 
  162. }
  163. inline int MvDataCodec::ChooseREF2xSignContext(const MvData& data) const
  164. {
  165.     return REF2x_SIGN0_CTX; 
  166. }
  167. inline int MvDataCodec::ChooseREF2yContext(const MvData& data, const int BinNumber) const
  168. {
  169.     if (BinNumber == 1)
  170.         return REF2y_BIN1_CTX; 
  171.     else if (BinNumber == 2)
  172.         return REF2y_BIN2_CTX; 
  173.     else if (BinNumber == 3)
  174.         return REF2y_BIN3_CTX; 
  175.     else if (BinNumber == 4)
  176.         return REF2y_BIN4_CTX; 
  177.     else
  178.         return REF2y_BIN5plus_CTX; 
  179. }
  180. inline int MvDataCodec::ChooseREF2ySignContext(const MvData& data) const
  181. {
  182.     return REF2y_SIGN0_CTX; 
  183. }
  184. inline int MvDataCodec::ChooseYDCContext(const MvData& data, const int BinNumber) const
  185. {
  186.     if (BinNumber == 1)
  187.         return YDC_BIN1_CTX; 
  188.     else
  189.         return YDC_BIN2plus_CTX; 
  190. }
  191. inline int MvDataCodec::ChooseUDCContext(const MvData& data, const int BinNumber) const
  192. {
  193.     if (BinNumber == 1)
  194.         return UDC_BIN1_CTX; 
  195.     else
  196.         return UDC_BIN2plus_CTX; 
  197. }
  198. inline int MvDataCodec::ChooseVDCContext(const MvData& data, const int BinNumber) const
  199. {
  200.     if (BinNumber == 1)
  201.         return VDC_BIN1_CTX; 
  202.     else
  203.         return VDC_BIN2plus_CTX; 
  204. }
  205. inline int MvDataCodec::ChooseYDCSignContext(const MvData& data) const
  206. {
  207.     return YDC_SIGN0_CTX; 
  208. }
  209. inline int MvDataCodec::ChooseUDCSignContext(const MvData& data) const
  210. {
  211.     return UDC_SIGN0_CTX; 
  212. }
  213. inline int MvDataCodec::ChooseVDCSignContext(const MvData& data) const
  214. {
  215.     return VDC_SIGN0_CTX; 
  216. }
  217. inline unsigned int MvDataCodec::MBSplitPrediction(const TwoDArray<int> & split_data ) const
  218. {    
  219.     int result = 0;
  220.     
  221.     std::vector < unsigned int >  nbrs;
  222.     
  223.     if (mb_xp > 0 && mb_yp > 0)
  224.     {
  225.         nbrs.push_back( split_data[mb_yp-1][mb_xp] ); 
  226.         nbrs.push_back( split_data[mb_yp-1][mb_xp-1] ); 
  227.         nbrs.push_back( split_data[mb_yp][mb_xp-1] ); 
  228.         result = GetMean(nbrs);     
  229.     }
  230.     else if (mb_xp > 0 && mb_yp == 0)
  231.         result = split_data[mb_yp][mb_xp-1]; 
  232.     else if (mb_xp == 0 && mb_yp > 0)
  233.         result =  split_data[mb_yp-1][mb_xp]; 
  234.     return result; 
  235. }
  236. inline bool MvDataCodec::MBCBModePrediction(const TwoDArray <bool> & cbm_data) const
  237. {
  238.     bool result = true;
  239.     std::vector < unsigned int >  nbrs; 
  240.     
  241.     if (mb_xp > 0 && mb_yp > 0)
  242.     {
  243.         nbrs.push_back( (unsigned int)( cbm_data[mb_yp-1][mb_xp] ) ); 
  244.         nbrs.push_back( (unsigned int)( cbm_data[mb_yp-1][mb_xp-1] ) ); 
  245.         nbrs.push_back( (unsigned int)( cbm_data[mb_yp][mb_xp-1] ) ); 
  246.         result = bool(GetMean(nbrs));     
  247.     }
  248.     else if (mb_xp > 0 && mb_yp == 0)
  249.         result = cbm_data[mb_yp][mb_xp-1]; 
  250.     else if (mb_xp == 0 && mb_yp > 0)
  251.         result = cbm_data[mb_yp-1][mb_xp]; 
  252.     
  253.     return result; 
  254. }
  255. inline unsigned int MvDataCodec::BlockModePrediction(const TwoDArray < PredMode > & preddata) const
  256. {
  257.     unsigned int result = (unsigned int)(REF1_ONLY);
  258.     std::vector <unsigned int> nbrs; 
  259.     
  260.     if (b_xp > 0 && b_yp > 0)
  261.     {
  262.         nbrs.push_back( (unsigned int)( preddata[b_yp-1][b_xp] ) ); 
  263.         nbrs.push_back( (unsigned int)( preddata[b_yp-1][b_xp-1] ) ); 
  264.         nbrs.push_back( (unsigned int)( preddata[b_yp][b_xp-1] ) ); 
  265.         result = GetMean(nbrs);
  266.     }
  267.     else if (b_xp > 0 && b_yp == 0)
  268.         result = preddata[b_yp][b_xp-1]; 
  269.     else if (b_xp == 0 && b_yp > 0)
  270.         result = preddata[b_yp-1][b_xp]; 
  271.     return result; 
  272. }
  273. inline MVector MvDataCodec::Mv1Prediction(const MvArray& mvarray,
  274.                                           const TwoDArray < PredMode > & preddata) const
  275. {
  276.     std::vector <MVector>  nbrs; 
  277.     PredMode pmode;     
  278.     MVector result; 
  279.     
  280.     if (b_xp > 0 && b_yp > 0)
  281.     {
  282.         pmode = preddata[b_yp-1][b_xp]; 
  283.         if (pmode == REF1_ONLY || pmode == REF1AND2) 
  284.             nbrs.push_back(mvarray[b_yp-1][b_xp]); 
  285.         
  286.         pmode = preddata[b_yp-1][b_xp-1]; 
  287.         if (pmode == REF1_ONLY || pmode == REF1AND2)
  288.             nbrs.push_back(mvarray[b_yp-1][b_xp-1]); 
  289.         
  290.         pmode = preddata[b_yp][b_xp-1]; 
  291.         if (pmode == REF1_ONLY || pmode == REF1AND2)        
  292.             nbrs.push_back(mvarray[b_yp][b_xp-1]); 
  293.         
  294.         if (nbrs.size() > 0)
  295.             result = MvMedian(nbrs); 
  296.     }
  297.     else if (b_xp > 0 && b_yp == 0)
  298.     {
  299.         pmode = preddata[0][b_xp-1]; 
  300.         if (pmode == REF1_ONLY || pmode == REF1AND2)
  301.             result = mvarray[0][b_xp-1]; 
  302.     }
  303.     else if (b_xp == 0 && b_yp > 0)
  304.     {
  305.         pmode = preddata[b_yp-1][0]; 
  306.         if (pmode == REF1_ONLY || pmode == REF1AND2)
  307.             result = mvarray[b_yp-1][0]; 
  308.     }
  309.     return result; 
  310. }
  311. inline MVector MvDataCodec::Mv2Prediction(const MvArray & mvarray,
  312.                                           const TwoDArray < PredMode >  & preddata) const
  313. {
  314.     std::vector <MVector>  nbrs; 
  315.     PredMode pmode; 
  316.     MVector result; 
  317.     
  318.     if (b_xp > 0 && b_yp > 0)
  319.     {
  320.         pmode = preddata[b_yp-1][b_xp]; 
  321.         if (pmode == REF2_ONLY || pmode == REF1AND2)
  322.             nbrs.push_back(mvarray[b_yp-1][b_xp]); 
  323.         
  324.         pmode = preddata[b_yp-1][b_xp-1]; 
  325.         if (pmode == REF2_ONLY || pmode == REF1AND2)
  326.             nbrs.push_back(mvarray[b_yp-1][b_xp-1]); 
  327.         
  328.         pmode = preddata[b_yp][b_xp-1]; 
  329.         if (pmode == REF2_ONLY || pmode == REF1AND2)
  330.             nbrs.push_back(mvarray[b_yp][b_xp-1]); 
  331.         
  332.         if (nbrs.size() > 0)
  333.             result = MvMedian(nbrs); 
  334.     }
  335.     else if (b_xp > 0 && b_yp == 0)
  336.     {
  337.         pmode = preddata[0][b_xp-1]; 
  338.         if(pmode == REF2_ONLY || pmode == REF1AND2)
  339.             result = mvarray[0][b_xp-1]; 
  340.     }
  341.     else if (b_xp == 0 && b_yp > 0)
  342.     {
  343.         pmode = preddata[b_yp-1][0]; 
  344.         if(pmode == REF2_ONLY || pmode == REF1AND2)
  345.             result = mvarray[b_yp-1][0]; 
  346.     }
  347.     return result; 
  348. }
  349. inline ValueType MvDataCodec::DCPrediction(const TwoDArray < ValueType > & dcdata,
  350.                                            const TwoDArray < PredMode > & preddata) const
  351. {
  352.     std::vector < int >  nbrs; 
  353.     PredMode pmode;
  354.     ValueType result = 128; 
  355.     
  356.     if (b_xp > 0 && b_yp > 0)
  357.     {
  358.         pmode = preddata[b_yp-1][b_xp]; 
  359.         if (pmode == INTRA) 
  360.             nbrs.push_back(int(dcdata[b_yp-1][b_xp])); 
  361.         
  362.         pmode = preddata[b_yp-1][b_xp-1]; 
  363.         if (pmode == INTRA)
  364.             nbrs.push_back(int(dcdata[b_yp-1][b_xp-1])); 
  365.         
  366.         pmode = preddata[b_yp][b_xp-1]; 
  367.         if (pmode == INTRA)        
  368.             nbrs.push_back(int(dcdata[b_yp][b_xp-1])); 
  369.         
  370.         if (nbrs.size() > 0)
  371.             result = ValueType(GetMean(nbrs));     
  372.     }
  373.     else if (b_xp > 0 && b_yp == 0)
  374.     {
  375.         pmode = preddata[0][b_xp-1]; 
  376.         if (pmode == INTRA)
  377.             result = dcdata[0][b_xp-1]; 
  378.     }
  379.     else if (b_xp == 0 && b_yp > 0)
  380.     {
  381.         pmode = preddata[b_yp-1][0]; 
  382.         if (pmode == INTRA)
  383.             result = dcdata[b_yp-1][0]; 
  384.     }
  385.     return result;
  386. }
  387. void MvDataCodec::DoWorkCode( MvData& in_data )
  388. {
  389.     int step,max; 
  390.     int pstep,pmax; 
  391.     int split_depth; 
  392.     bool common_ref; 
  393.     MB_count = 0; 
  394.     
  395.     for (mb_yp = 0, mb_tlb_y = 0;  mb_yp < in_data.MBSplit().LengthY();  ++mb_yp, mb_tlb_y += 4)
  396.     {
  397.         for (mb_xp = 0,mb_tlb_x = 0; mb_xp < in_data.MBSplit().LengthX(); ++mb_xp,mb_tlb_x += 4)
  398.         {
  399.              //start with split mode
  400.             CodeMBSplit(in_data); 
  401.             split_depth = in_data.MBSplit()[mb_yp][mb_xp]; 
  402.             step = 4  >>  (split_depth); 
  403.             max = (1 << split_depth); 
  404.             //next do common_ref
  405.             if(split_depth != 0)
  406.             {
  407.                 CodeMBCom(in_data); 
  408.                 pstep = step; 
  409.                 pmax = max; 
  410.             }
  411.             else
  412.             {
  413.                 pstep = 4; 
  414.                 pmax = 1; 
  415.             }
  416.             common_ref = in_data.MBCommonMode()[mb_yp][mb_xp]; 
  417.             //do prediction modes            
  418.             for (b_yp = mb_tlb_y; b_yp < mb_tlb_y+4; b_yp += pstep)
  419.                 for (b_xp = mb_tlb_x; b_xp < mb_tlb_x+4; b_xp += pstep)
  420.                     CodePredmode(in_data); 
  421.             
  422.             step = 4 >> (split_depth);             
  423.             
  424.                //now do all the block mvs in the mb            
  425.             for (b_yp = mb_tlb_y; b_yp < mb_tlb_y+4; b_yp += step)
  426.             {
  427.                 for (b_xp = mb_tlb_x; b_xp < mb_tlb_x+4; b_xp += step)
  428.                 {
  429.                     if (in_data.Mode()[b_yp][b_xp] == REF1_ONLY || in_data.Mode()[b_yp][b_xp] == REF1AND2 )
  430.                         CodeMv1(in_data); 
  431.                     
  432.                     if (in_data.Mode()[b_yp][b_xp] == REF2_ONLY || in_data.Mode()[b_yp][b_xp] == REF1AND2 )
  433.                         CodeMv2(in_data); 
  434.                     
  435.                     if(in_data.Mode()[b_yp][b_xp] == INTRA)
  436.                         CodeDC(in_data);                     
  437.                 }//b_xp
  438.             }//b_yp    
  439.             
  440.             //TODO: Update all contexts here?
  441.             
  442.         }//mb_xp
  443.     }//mb_yp
  444. }
  445. void MvDataCodec::CodeMBSplit(const MvData& in_data)
  446. {
  447.     int val = in_data.MBSplit()[mb_yp][mb_xp] - MBSplitPrediction( in_data.MBSplit() ); 
  448.     
  449.     if (val < 0)
  450.         val += 3; //produce prediction mod 3    
  451.     
  452.     int ctx; 
  453.     
  454.     for (int bin = 1; bin <= val; ++bin)
  455.     {
  456.         ctx = ChooseMBSContext(in_data,bin); 
  457.         EncodeSymbol(0,ctx); 
  458.     }
  459.     
  460.     if (val != 2)//if we've had two zeroes, know we must have value 2
  461.         EncodeSymbol(1,ChooseMBSContext(in_data,val+1)); 
  462. }
  463. void MvDataCodec::CodeMBCom(const MvData& in_data)
  464. {
  465.     bool val = in_data.MBCommonMode()[mb_yp][mb_xp]; 
  466.     
  467.     if (val != MBCBModePrediction( in_data.MBCommonMode() ))
  468.         EncodeSymbol( 1 , ChooseMBCContext( in_data ) ); 
  469.     else
  470.         EncodeSymbol( 0 , ChooseMBCContext( in_data ) ); 
  471. }
  472. void MvDataCodec::CodePredmode(const MvData& in_data)
  473. {
  474.     int val = in_data.Mode()[b_yp][b_xp] - BlockModePrediction( in_data.Mode() ); 
  475.     
  476.     if (val < 0)
  477.         val += 4;  //produce value mod 4    
  478.     
  479.     for (int bin = 1;  bin<= val;  ++bin)
  480.         EncodeSymbol( 0 , ChoosePredContext( in_data , bin ) ); 
  481.                  
  482.     if (val  !=  3) //if we've had three zeroes, know we must have value 3
  483.         EncodeSymbol( 1 , ChoosePredContext( in_data , val + 1 ) ); 
  484. }
  485. void MvDataCodec::CodeMv1(const MvData& in_data )
  486. {
  487.     const MvArray& mv_array = in_data.Vectors(1);
  488.     const MVector pred = Mv1Prediction( mv_array , in_data.Mode() ); 
  489.     const int valx = mv_array[b_yp][b_xp].x - pred.x; 
  490.     const int abs_valx = std::abs(valx); 
  491.     
  492.     for (int bin = 1;  bin  <= abs_valx;  ++bin)
  493.         EncodeSymbol( 0 , ChooseREF1xContext( in_data , bin ) ); 
  494.     EncodeSymbol( 1 , ChooseREF1xContext( in_data , abs_valx + 1 ) ); 
  495.     
  496.     if (valx != 0)
  497.         EncodeSymbol( ( (valx > 0)? 1 : 0) , ChooseREF1xSignContext( in_data ) ); 
  498.     const int valy = mv_array[b_yp][b_xp].y - pred.y;         
  499.     const int abs_valy = std::abs( valy );     
  500.     
  501.     for (int bin = 1; bin<=abs_valy ; ++bin )
  502.         EncodeSymbol( 0 , ChooseREF1yContext( in_data , bin ) );         
  503.     
  504.     EncodeSymbol( 1 , ChooseREF1yContext( in_data , abs_valy + 1 ) ); 
  505.     
  506.     if (valy != 0)
  507.         EncodeSymbol( ( (valy > 0)? 1 : 0) , ChooseREF1ySignContext( in_data ) );  
  508. }
  509. void MvDataCodec::CodeMv2(const MvData& in_data)
  510. {
  511.     const MvArray& mv_array = in_data.Vectors(2);
  512.     const MVector pred = Mv2Prediction( mv_array , in_data.Mode() );     
  513.     const int valx = mv_array[b_yp][b_xp].x - pred.x; 
  514.     const int abs_valx = abs(valx); 
  515.     
  516.     for (int bin = 1; bin <= abs_valx; ++bin)
  517.         EncodeSymbol( 0 , ChooseREF2xContext( in_data , bin ) ); 
  518.     EncodeSymbol( 1 , ChooseREF2xContext( in_data , abs_valx + 1 ) ); 
  519.     
  520.     if (valx != 0)
  521.         EncodeSymbol( ( (valx > 0)? 1 : 0) , ChooseREF2xSignContext( in_data ) ); 
  522.     const int valy = mv_array[b_yp][b_xp].y-pred.y; 
  523.     const int abs_valy = std::abs(valy);     
  524.     
  525.     for (int bin = 1; bin<=abs_valy; ++bin )
  526.         EncodeSymbol( 0 , ChooseREF2yContext( in_data , bin ) ); 
  527.     
  528.     EncodeSymbol( 1 , ChooseREF2yContext( in_data , abs_valy + 1 ) ); 
  529.     
  530.     if (valy != 0)
  531.         EncodeSymbol( ( (valy > 0)? 1 : 0) , ChooseREF2ySignContext( in_data ) ); 
  532. }
  533. void MvDataCodec::CodeDC(const MvData& in_data)
  534. {    
  535.     //begin with Y DC value    
  536.     const ValueType valY = in_data.DC( Y_COMP )[b_yp][b_xp]
  537.                            - DCPrediction( in_data.DC(Y_COMP) , in_data.Mode() ); 
  538.     const ValueType abs_valY = std::abs( valY ); 
  539.     for (ValueType bin = 1; bin <= abs_valY; ++bin)
  540.         EncodeSymbol( 0 , ChooseYDCContext( in_data , bin ) ); 
  541.     EncodeSymbol( 1 , ChooseYDCContext (in_data , abs_valY + 1 ) ); 
  542.     
  543.     if (valY != 0)
  544.         EncodeSymbol( ( (valY > 0)? 1 : 0) , ChooseYDCSignContext( in_data ) ); 
  545.     //now do U and V if necessary
  546.     if (m_cformat != Yonly)
  547.     {
  548.         //continue with U and V DC values
  549.         const int valU =  in_data.DC(U_COMP)[b_yp][b_xp]
  550.                           - DCPrediction(in_data.DC( U_COMP ) , in_data.Mode()); 
  551.         const int abs_valU = std::abs( valU ); 
  552.         for (ValueType bin = 1;  bin<=abs_valU ; ++bin)
  553.             EncodeSymbol( 0 , ChooseUDCContext( in_data , bin ) ); 
  554.         
  555.         EncodeSymbol( 1 , ChooseUDCContext( in_data , abs_valU + 1 ) ); 
  556.         
  557.         if (valU != 0)
  558.             EncodeSymbol( ( (valU > 0) ? 1 : 0) , ChooseUDCSignContext( in_data ) ); 
  559.         
  560.         const int valV = in_data.DC( V_COMP )[b_yp][b_xp] 
  561.                          - DCPrediction( in_data.DC( V_COMP ) , in_data.Mode() ); 
  562.         const int abs_valV = std::abs( valV ); 
  563.         for (ValueType bin = 1; bin<=abs_valV ; ++bin)
  564.             EncodeSymbol( 0 , ChooseVDCContext( in_data , bin ) ); 
  565.         EncodeSymbol( 1 , ChooseVDCContext( in_data , abs_valV + 1 ) ); 
  566.         
  567.         if (valV != 0)
  568.             EncodeSymbol( ( (valV > 0)? 1 : 0) , ChooseVDCSignContext( in_data ) ); 
  569.     }
  570. }
  571. //decoding functions//
  572. //////////////////////
  573. void MvDataCodec::DoWorkDecode( MvData& out_data, int num_bits)
  574. {
  575.     int step,max; 
  576.     int pstep,pmax;     
  577.     int split_depth; 
  578.     bool common_ref; 
  579.     int xstart,ystart;     
  580.     for (mb_yp = 0,mb_tlb_y = 0; mb_yp < out_data.MBSplit().LengthY(); ++mb_yp,mb_tlb_y += 4)
  581.     {
  582.         for (mb_xp = 0,mb_tlb_x = 0; mb_xp < out_data.MBSplit().LengthX(); ++mb_xp,mb_tlb_x += 4)
  583.         {
  584.              //start with split mode
  585.             DecodeMBSplit( out_data ); 
  586.             split_depth = out_data.MBSplit()[mb_yp][mb_xp]; 
  587.             step =  4  >>  (split_depth); 
  588.             max  = (1 << split_depth); 
  589.             //next do common_ref
  590.             if(split_depth  !=  0)
  591.             {
  592.                 DecodeMBCom( out_data ); 
  593.                 pstep = step; 
  594.                 pmax = max; 
  595.             }
  596.             else
  597.             {
  598.                 out_data.MBCommonMode()[mb_yp][mb_xp] = true; 
  599.                 pstep = 4; 
  600.                 pmax = 1; 
  601.             }
  602.             
  603.             common_ref = out_data.MBCommonMode()[mb_yp][mb_xp]; 
  604.             // do prediction modes
  605.             for (b_yp = mb_tlb_y;  b_yp < mb_tlb_y + 4;  b_yp += pstep)
  606.             {                
  607.                 for (b_xp = mb_tlb_x; b_xp < mb_tlb_x + 4;  b_xp += pstep)
  608.                 {
  609.                     DecodePredmode(out_data); 
  610.                     
  611.                     // propagate throughout MB                
  612.                     for (int y = b_yp;  y < b_yp + pstep;  y++)
  613.                         for (int x = b_xp;  x < b_xp + pstep;  x++)
  614.                             out_data.Mode()[y][x] = out_data.Mode()[b_yp][b_xp];                                                         
  615.                 }
  616.             }
  617.                //now do all the block mvs in the mb
  618.             for (int j = 0; j < max; ++j)
  619.             {                
  620.                 for (int i = 0; i < max; ++i)
  621.                 {
  622.                     xstart = b_xp = mb_tlb_x + i * step; 
  623.                     ystart = b_yp = mb_tlb_y + j * step;                                             
  624.                     
  625.                     if (out_data.Mode()[b_yp][b_xp] == REF1_ONLY || out_data.Mode()[b_yp][b_xp] == REF1AND2 )
  626.                         DecodeMv1( out_data ); 
  627.                     
  628.                     if (out_data.Mode()[b_yp][b_xp] == REF2_ONLY || out_data.Mode()[b_yp][b_xp] == REF1AND2 )
  629.                         DecodeMv2( out_data ); 
  630.                     
  631.                     if(out_data.Mode()[b_yp][b_xp] == INTRA)
  632.                         DecodeDC( out_data ); 
  633.                     
  634.                       //propagate throughout MB    
  635.                     for (b_yp = ystart; b_yp < ystart+step; b_yp++)
  636.                     {
  637.                         for (b_xp = xstart; b_xp < xstart+step; b_xp++)
  638.                         {                    
  639.                             out_data.Vectors(1)[b_yp][b_xp].x = out_data.Vectors(1)[ystart][xstart].x; 
  640.                             out_data.Vectors(1)[b_yp][b_xp].y = out_data.Vectors(1)[ystart][xstart].y; 
  641.                             out_data.Vectors(2)[b_yp][b_xp].x = out_data.Vectors(2)[ystart][xstart].x; 
  642.                             out_data.Vectors(2)[b_yp][b_xp].y = out_data.Vectors(2)[ystart][xstart].y; 
  643.                             out_data.DC( Y_COMP )[b_yp][b_xp] = out_data.DC( Y_COMP )[ystart][xstart]; 
  644.                             out_data.DC( U_COMP )[b_yp][b_xp] = out_data.DC( U_COMP )[ystart][xstart]; 
  645.                             out_data.DC( V_COMP )[b_yp][b_xp] = out_data.DC( V_COMP )[ystart][xstart]; 
  646.                         }//b_xp
  647.                     }//b_yp
  648.                 }//i                    
  649.             }//j
  650.         }//mb_xp
  651.     }//mb_yp
  652. }
  653. void MvDataCodec::DecodeMBSplit(MvData& out_data)
  654. {
  655.     int val = 0; 
  656.     int bin = 1; 
  657.     bool bit; 
  658.     do
  659.     {
  660.         DecodeSymbol( bit , ChooseMBSContext( out_data , bin ) ); 
  661.         
  662.         if (!bit)
  663.             val++; 
  664.         
  665.         bin++; 
  666.     }
  667.     while (!bit && val != 2);  
  668.     
  669.     out_data.MBSplit()[mb_yp][mb_xp] = ( val + MBSplitPrediction( out_data.MBSplit() ) ) % 3;     
  670. }
  671. void MvDataCodec::DecodeMBCom( MvData& out_data )
  672. {
  673.     bool bit; 
  674.     DecodeSymbol( bit , ChooseMBCContext( out_data ) ); 
  675.     
  676.     if ( bit )
  677.         out_data.MBCommonMode()[mb_yp][mb_xp] = !MBCBModePrediction( out_data.MBCommonMode() ); 
  678.     else
  679.         out_data.MBCommonMode()[mb_yp][mb_xp] = MBCBModePrediction( out_data.MBCommonMode() ); 
  680. }
  681. void MvDataCodec::DecodePredmode( MvData& out_data )
  682. {
  683.     int val = 0; 
  684.     int bin = 1; 
  685.     bool bit; 
  686.     
  687.     do
  688.     {
  689.         DecodeSymbol( bit , ChoosePredContext( out_data , bin ) ); 
  690.         
  691.         if (!bit)
  692.             val++; 
  693.         
  694.         bin++; 
  695.     }
  696.     while (!bit && val != 3);  
  697.     
  698.     out_data.Mode()[b_yp][b_xp] = PredMode( ( val + BlockModePrediction (out_data.Mode() ) ) %4); 
  699. }
  700. void MvDataCodec::DecodeMv1( MvData& out_data )
  701. {
  702.     MVector pred = Mv1Prediction( out_data.Vectors(1) , out_data.Mode() );     
  703.     int val = 0;
  704.     int bin = 1; 
  705.     bool bit; 
  706.     
  707.     do
  708.     {
  709.         DecodeSymbol( bit , ChooseREF1xContext( out_data , bin ) ); 
  710.         
  711.         if ( !bit )
  712.             val++; 
  713.         
  714.         bin++; 
  715.     }
  716.     while ( !bit ); 
  717.     
  718.     if (val != 0)
  719.     {
  720.         DecodeSymbol( bit , ChooseREF1xSignContext( out_data ) ); 
  721.         
  722.         if (!bit)
  723.             val = -val; 
  724.     }
  725.     
  726.     out_data.Vectors(1)[b_yp][b_xp].x = val + pred.x; 
  727.     val = 0; 
  728.     bin = 1; 
  729.     
  730.     do
  731.     {
  732.         DecodeSymbol( bit , ChooseREF1yContext( out_data , bin ) ); 
  733.         
  734.         if ( !bit )
  735.             val++; 
  736.         
  737.         bin++; 
  738.     }
  739.     while ( !bit ); 
  740.     
  741.     if (val != 0)
  742.     {
  743.         DecodeSymbol( bit , ChooseREF1ySignContext( out_data ) ); 
  744.         
  745.         if (!bit)
  746.             val = -val; 
  747.     }
  748.     
  749.     out_data.Vectors(1)[b_yp][b_xp].y = val + pred.y; 
  750. }
  751. void MvDataCodec::DecodeMv2( MvData& out_data )
  752. {
  753.     MVector pred = Mv2Prediction( out_data.Vectors(2) , out_data.Mode() ); 
  754.     int val = 0; 
  755.     int bin = 1; 
  756.     bool bit; 
  757.     
  758.     do
  759.     {
  760.         DecodeSymbol( bit , ChooseREF2xContext( out_data , bin ) ); 
  761.         
  762.         if ( !bit )
  763.             val++; 
  764.         
  765.         bin++; 
  766.     }
  767.     while ( !bit ); 
  768.     
  769.     if (val != 0)
  770.     {
  771.         DecodeSymbol( bit , ChooseREF2xSignContext( out_data ) ); 
  772.         
  773.         if (!bit)
  774.             val = -val; 
  775.     }
  776.     
  777.     out_data.Vectors(2)[b_yp][b_xp].x = val + pred.x; 
  778.     val = 0; 
  779.     bin = 1; 
  780.     
  781.     do
  782.     {
  783.         DecodeSymbol( bit , ChooseREF2yContext( out_data , bin ) ); 
  784.         
  785.         if ( !bit )
  786.             val++; 
  787.         
  788.         bin++; 
  789.     }
  790.     while ( !bit ); 
  791.     
  792.     if (val != 0)
  793.     {
  794.         DecodeSymbol( bit , ChooseREF2ySignContext( out_data ) ); 
  795.         
  796.         if ( !bit )
  797.             val = -val; 
  798.     }
  799.     
  800.     out_data.Vectors(2)[b_yp][b_xp].y = val + pred.y; 
  801. }
  802. void MvDataCodec::DecodeDC( MvData& out_data )
  803. {
  804.     //begin with Y DC value    
  805.     ValueType val = 0; 
  806.     int bin = 1; 
  807.     bool bit; 
  808.     
  809.     do
  810.     {
  811.         DecodeSymbol( bit , ChooseYDCContext( out_data , bin ) ); 
  812.         
  813.         if ( !bit )
  814.             val++; 
  815.         
  816.         bin++; 
  817.     }
  818.     while ( !bit ); 
  819.     
  820.     if (val != 0)
  821.     {
  822.         DecodeSymbol( bit , ChooseYDCSignContext( out_data ) ); 
  823.         
  824.         if (!bit)
  825.             val = -val; 
  826.     }
  827.     
  828.     out_data.DC( Y_COMP )[b_yp][b_xp] = val + DCPrediction( out_data.DC( Y_COMP ) , out_data.Mode()); 
  829.     if (m_cformat != Yonly)
  830.     {
  831.         //move onto U and V DC values
  832.         val = 0; 
  833.         bin = 1; 
  834.         
  835.         do
  836.         {
  837.             DecodeSymbol( bit , ChooseUDCContext( out_data , bin ) ); 
  838.             
  839.             if (!bit)
  840.                 val++; 
  841.             
  842.             bin++; 
  843.         }
  844.         while (!bit); 
  845.         
  846.         if (val != 0)
  847.         {
  848.             DecodeSymbol( bit , ChooseUDCSignContext ( out_data ) ); 
  849.             
  850.             if (!bit)
  851.                 val = -val; 
  852.         }
  853.         
  854.         out_data.DC( U_COMP )[b_yp][b_xp] = val + DCPrediction( out_data.DC( U_COMP ) , out_data.Mode()); 
  855.         val = 0; 
  856.         bin = 1; 
  857.         
  858.         do
  859.         {
  860.             DecodeSymbol( bit , ChooseVDCContext( out_data , bin ) ); 
  861.             
  862.             if ( !bit )
  863.                 val++; 
  864.             
  865.             bin++; 
  866.         }
  867.         while ( !bit ); 
  868.         
  869.         if (val != 0)
  870.         {
  871.             DecodeSymbol( bit , ChooseVDCSignContext( out_data ) ); 
  872.             
  873.             if ( !bit )
  874.                 val = -val; 
  875.         }
  876.         
  877.         out_data.DC( V_COMP )[b_yp][b_xp] = val + DCPrediction( out_data.DC( V_COMP ) , out_data.Mode() ); 
  878.     }
  879. }