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

多媒体编程

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. *
  3. * $Id: frame_decompress.cpp,v 1.3 2005/01/30 05:11:41 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), 
  24. *                 Scott R Ladd
  25. *                 Anuradha Suraparaju
  26. *
  27. * Alternatively, the contents of this file may be used under the terms of
  28. * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
  29. * Public License Version 2.1 (the "LGPL"), in which case the provisions of
  30. * the GPL or the LGPL are applicable instead of those above. If you wish to
  31. * allow use of your version of this file only under the terms of the either
  32. * the GPL or LGPL and not to allow others to use your version of this file
  33. * under the MPL, indicate your decision by deleting the provisions above
  34. * and replace them with the notice and other provisions required by the GPL
  35. * or LGPL. If you do not delete the provisions above, a recipient may use
  36. * your version of this file under the terms of any one of the MPL, the GPL
  37. * or the LGPL.
  38. * ***** END LICENSE BLOCK ***** */
  39. //Decompression of frames
  40. /////////////////////////
  41. #include <libdirac_common/dirac_assertions.h>
  42. #include <libdirac_common/bit_manager.h>
  43. #include <libdirac_decoder/frame_decompress.h>
  44. #include <libdirac_decoder/comp_decompress.h>
  45. #include <libdirac_common/mot_comp.h>
  46. #include <libdirac_common/mv_codec.h>
  47. #include <libdirac_common/golomb.h>
  48. using namespace dirac;
  49. #include <iostream>
  50. using std::vector;
  51. FrameDecompressor::FrameDecompressor(DecoderParams& decp, ChromaFormat cf)
  52. m_decparams(decp),
  53. m_cformat(cf)
  54. {}
  55. FrameDecompressor::~FrameDecompressor()
  56. {
  57. }
  58. bool FrameDecompressor::ReadFrameHeader(const FrameBuffer& my_buffer)
  59. {
  60.     FrameParams my_fparams (m_cformat , my_buffer.GetFParams().Xl(), my_buffer.GetFParams().Yl());
  61.      //Get the frame header (which includes the frame number)
  62.     m_fparams = my_fparams; 
  63.     m_read_header = ReadFrameHeader(m_fparams);
  64.     return m_read_header;
  65. }
  66. bool FrameDecompressor::Decompress(FrameBuffer& my_buffer)
  67. {
  68.     if ( !(m_decparams.BitsIn().End())&& m_read_header )
  69.     {//if we've not finished the data, can proceed
  70.         TEST (my_buffer.GetFParams().Xl() == m_fparams.Xl());
  71.         TEST (my_buffer.GetFParams().Yl() == m_fparams.Yl());
  72.         if ( !m_skipped )
  73.         {//if we're not m_skipped then we can decode the rest of the frame
  74.             if ( m_decparams.Verbose() )
  75.                 std::cerr<<std::endl<<"Decoding frame "<<m_fparams.FrameNum()<<" in display order";        
  76.              //Add a frame into the buffer ready to receive the data        
  77.             my_buffer.PushFrame(m_fparams);
  78.             Frame& my_frame = my_buffer.GetFrame(m_fparams.FrameNum());//Reference to the frame being decoded
  79.             FrameSort fsort = m_fparams.FSort();
  80.             MvData* mv_data;
  81.             unsigned int num_mv_bits;
  82.             if ( fsort != I_frame )
  83.             {//do all the MV stuff        
  84.                 mv_data = new MvData( m_decparams.XNumMB() , m_decparams.YNumMB() );
  85.                  //decode mv data
  86.                 if (m_decparams.Verbose())
  87.                     std::cerr<<std::endl<<"Decoding motion data ...";        
  88.                 MvDataCodec my_mv_decoder( &m_decparams.BitsIn(), 50 , m_cformat );
  89.                 my_mv_decoder.InitContexts();//may not be necessary
  90.                 num_mv_bits = UnsignedGolombDecode( m_decparams.BitsIn() );
  91.                  //Flush to the end of the header for the MV bits            
  92.                 m_decparams.BitsIn().FlushInput();
  93.                  //Decompress the MV bits
  94.                 my_mv_decoder.Decompress( *mv_data , num_mv_bits );                
  95.             }
  96.                //decode components
  97.             CompDecompress( my_buffer,m_fparams.FrameNum() , Y_COMP );
  98.             if ( m_fparams.CFormat() != Yonly )
  99.             {
  100.                 CompDecompress( my_buffer , m_fparams.FrameNum() , U_COMP );        
  101.                 CompDecompress( my_buffer , m_fparams.FrameNum() , V_COMP );
  102.             }
  103.             if ( fsort != I_frame )
  104.             {//motion compensate to add the data back in if we don't have an I frame
  105.                 MotionCompensator mycomp(m_decparams , ADD );
  106.                 mycomp.CompensateFrame(my_buffer , m_fparams.FrameNum() , *mv_data);        
  107.                 delete mv_data;    
  108.             }
  109.             my_frame.Clip();
  110.             if (m_decparams.Verbose())
  111.                 std::cerr<<std::endl;        
  112.         }//?m_skipped,!End()
  113.         else if (m_skipped){
  114.          //TBD: decide what to return if we're m_skipped. Nearest frame in temporal order??    
  115.         }
  116.         m_read_header = false;
  117.          //exit success
  118.         return true;
  119.     }
  120.      //exit failure
  121.     return false;
  122. }
  123. void FrameDecompressor::CompDecompress(FrameBuffer& my_buffer, int fnum,CompSort cs)
  124. {
  125.     if ( m_decparams.Verbose() )
  126.         std::cerr<<std::endl<<"Decoding component data ...";
  127.     CompDecompressor my_compdecoder( m_decparams , my_buffer.GetFrame(fnum).GetFparams() );    
  128.     PicArray& comp_data=my_buffer.GetComponent( fnum , cs );
  129.     my_compdecoder.Decompress( comp_data );
  130. }
  131. bool FrameDecompressor::ReadFrameHeader( FrameParams& fparams )
  132. {
  133.     if ( !m_decparams.BitsIn().End() )
  134.     {
  135.         char frame_start[5];
  136.         for (int i=0;i<5;++i)
  137.         {
  138.             frame_start[i]=m_decparams.BitsIn().InputByte();    
  139.         }
  140.          //read the frame number
  141.         int temp_int;
  142.         temp_int = (int)UnsignedGolombDecode( m_decparams.BitsIn() );
  143.         fparams.SetFrameNum(temp_int);
  144.          //read whether the frame is m_skipped or not
  145.         m_skipped=m_decparams.BitsIn().InputBit();
  146.         if (!m_skipped)
  147.         {
  148.              //read the expiry time relative to the frame number
  149.             fparams.SetExpiryTime( int( UnsignedGolombDecode( m_decparams.BitsIn() ) ) );
  150.              //read the frame sort
  151.             fparams.SetFSort( FrameSort( UnsignedGolombDecode( m_decparams.BitsIn() ) ) );
  152.             if ( fparams.FSort() != I_frame ){
  153.                  //if not an I-frame, read how many references there are
  154.                 fparams.Refs().clear();
  155.                 fparams.Refs().resize( UnsignedGolombDecode( m_decparams.BitsIn() ) );
  156.                  //for each reference, read the reference numbers
  157.                 for ( size_t I = 0 ; I < fparams.Refs().size() ; ++I )
  158.                 {
  159.                     fparams.Refs()[I] = fparams.FrameNum() + GolombDecode( m_decparams.BitsIn() );
  160.                 }//I
  161.                  //determine whether or not there is global motion vector data
  162.                 m_use_global= m_decparams.BitsIn().InputBit();
  163.                  //determine whether or not there is block motion vector data
  164.                 m_use_block_mv= m_decparams.BitsIn().InputBit();
  165.                  //if there is global but no block motion vector data, determine the prediction mode to use
  166.                  //for the whole frame
  167.                 if ( m_use_global && !m_use_block_mv )
  168.                     m_global_pred_mode= PredMode(UnsignedGolombDecode( m_decparams.BitsIn() ));
  169.             }//?is not an I frame
  170.         }//?m_skipped
  171.          //flush the header
  172.         m_decparams.BitsIn().FlushInput();
  173.          //exit success
  174.         return true;
  175.     }//?m_decparams.BitsIn().End()
  176.     else
  177.     {
  178.          //exit failure    
  179.         return false;
  180.     }
  181. }