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

多媒体编程

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. *
  3. * $Id: seq_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. *                 Anuradha Suraparaju
  25. *
  26. * Alternatively, the contents of this file may be used under the terms of
  27. * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
  28. * Public License Version 2.1 (the "LGPL"), in which case the provisions of
  29. * the GPL or the LGPL are applicable instead of those above. If you wish to
  30. * allow use of your version of this file only under the terms of the either
  31. * the GPL or LGPL and not to allow others to use your version of this file
  32. * under the MPL, indicate your decision by deleting the provisions above
  33. * and replace them with the notice and other provisions required by the GPL
  34. * or LGPL. If you do not delete the provisions above, a recipient may use
  35. * your version of this file under the terms of any one of the MPL, the GPL
  36. * or the LGPL.
  37. * ***** END LICENSE BLOCK ***** */
  38. ///////////////////////////////////////////
  39. //---------------------------------------//
  40. //Class to manage decompressing sequences//
  41. //---------------------------------------//
  42. ///////////////////////////////////////////
  43. #include <libdirac_common/dirac_assertions.h>
  44. #include <libdirac_decoder/seq_decompress.h>
  45. #include <libdirac_common/common.h>
  46. #include <libdirac_common/golomb.h>
  47. #include <libdirac_common/frame_buffer.h>
  48. #include <libdirac_decoder/frame_decompress.h>
  49. using namespace dirac;
  50. SequenceDecompressor::SequenceDecompressor(std::istream* ip,bool verbosity)
  51. m_all_done(false),
  52. m_infile(ip),
  53. m_current_code_fnum(0),
  54. m_delay(1),
  55. m_last_frame_read(-1),
  56. m_show_fnum(-1)
  57. {
  58.     m_decparams.SetBitsIn( new BitInputManager(m_infile) );
  59.     m_decparams.SetVerbose( verbosity );
  60.     ReadStreamHeader();
  61.     //Amount of horizontal padding for Y,U and V components
  62.     int xpad_luma,xpad_chroma;
  63.     //Amount of vertical padding for Y,U and V components
  64.     int ypad_luma,ypad_chroma;
  65.     //scaling factors for chroma based on chroma format
  66.     int x_chroma_fac,y_chroma_fac;
  67.     //First, we need to have sufficient padding to take account of the blocksizes.
  68.     //It's sufficient to check for chroma
  69.     if ( m_sparams.CFormat() == format411 )
  70.     {
  71.         x_chroma_fac = 4; 
  72.         y_chroma_fac = 1;
  73.     }
  74.     else if ( m_sparams.CFormat() == format420 )
  75.     {
  76.         x_chroma_fac = 2; 
  77.         y_chroma_fac = 2;
  78.     }
  79.     else if ( m_sparams.CFormat() == format422 )
  80.     {
  81.         x_chroma_fac = 2; 
  82.         y_chroma_fac = 1;
  83.     }
  84.     else
  85.     {
  86.         x_chroma_fac = 1; 
  87.         y_chroma_fac = 1;
  88.     }
  89.     int xl_chroma=m_sparams.Xl() / x_chroma_fac;
  90.     int yl_chroma=m_sparams.Yl() / y_chroma_fac;
  91.     //make sure we have enough macroblocks to cover the pictures 
  92.     m_decparams.SetXNumMB( m_sparams.Xl() / m_decparams.LumaBParams(0).Xbsep() );
  93.     m_decparams.SetYNumMB( m_sparams.Yl() / m_decparams.LumaBParams(0).Ybsep() );
  94.     if ( m_decparams.XNumMB() * m_decparams.ChromaBParams(0).Xbsep() < xl_chroma )
  95.     {
  96.         m_decparams.SetXNumMB( m_decparams.XNumMB() + 1 );
  97.         xpad_chroma = m_decparams.XNumMB() * m_decparams.ChromaBParams(0).Xbsep() - xl_chroma;
  98.     }
  99.     else
  100.         xpad_chroma=0;
  101.     if (m_decparams.YNumMB()*m_decparams.ChromaBParams(0).Ybsep()<yl_chroma)
  102.     {
  103.         m_decparams.SetYNumMB( m_decparams.YNumMB() + 1 );
  104.         ypad_chroma=m_decparams.YNumMB()*m_decparams.ChromaBParams(0).Ybsep()-yl_chroma;
  105.     }
  106.     else
  107.         ypad_chroma=0;    
  108.     //Now we have an integral number of macroblocks in a picture and we set the number of blocks
  109.     m_decparams.SetXNumBlocks( 4*m_decparams.XNumMB() );
  110.     m_decparams.SetYNumBlocks( 4*m_decparams.YNumMB() );
  111.     //Next we work out the additional padding due to the wavelet transform
  112.     //For the moment, we'll fix the transform depth to be 4, so we need divisibility by 16.
  113.     //In the future we'll want arbitrary transform depths. It's sufficient to check for
  114.     //chroma only
  115.     int xpad_len = xl_chroma+xpad_chroma;
  116.     int ypad_len = yl_chroma+ypad_chroma;
  117.     if ( xpad_len%16 != 0 )
  118.         xpad_chroma=( ( xpad_len/16 ) + 1 )*16 - xl_chroma;
  119.     if ( ypad_len%16 != 0)
  120.         ypad_chroma = ( ( ypad_len/16 ) + 1 )*16 - yl_chroma;    
  121.     xpad_luma = xpad_chroma*x_chroma_fac;
  122.     ypad_luma = ypad_chroma*y_chroma_fac;
  123.     //set up padded picture sizes, based on original picture sizes, the block parameters and the wavelet transform depth
  124.     m_fbuffer= new FrameBuffer( m_sparams.CFormat() , m_sparams.Xl() + xpad_luma , m_sparams.Yl() + ypad_luma );
  125.     m_fdecoder = new FrameDecompressor (m_decparams , m_sparams.CFormat() );
  126. }
  127. SequenceDecompressor::~SequenceDecompressor()
  128. {
  129.     delete m_fbuffer;
  130.     delete m_fdecoder;
  131.     delete &m_decparams.BitsIn();
  132. }
  133. bool SequenceDecompressor::ReadNextFrameHeader()
  134. {
  135.     return m_fdecoder->ReadFrameHeader(*m_fbuffer);
  136. }
  137. const FrameParams& SequenceDecompressor::GetNextFrameParams() const
  138. {
  139.     return m_fdecoder->GetFrameParams();
  140. }
  141. Frame& SequenceDecompressor::DecompressNextFrame(bool skip /* = false */)
  142. {
  143.     //this function decodes the next frame in coding order and returns the next frame in display order
  144.     //In general these will differ, and because of re-ordering there is a m_delay which needs to be imposed.
  145.     //This creates problems at the start and at the end of the sequence which must be dealt with.
  146.     //At the start we just keep outputting frame 0. At the end you will need to loop for longer to get all
  147.     //the frames out. It's up to the calling function to do something with the decoded frames as they
  148.     //come out - write them to screen or to file, as required.
  149.     TEST (m_fdecoder != NULL);
  150.     if (m_current_code_fnum!=0){
  151.         //if we're not at the beginning, clean the buffer of frames that can be discarded
  152.         m_fbuffer->Clean(m_show_fnum);
  153.     }
  154.     bool new_frame_to_display=false;
  155.        
  156.     if (!skip)
  157.        new_frame_to_display = m_fdecoder->Decompress(*m_fbuffer);
  158.     //if we've exited with success, there's a new frame to display, so increment
  159.     //the counters. Otherwise, freeze on the last frame shown
  160.     m_show_fnum=std::max(m_current_code_fnum-m_delay,0);
  161.     if (new_frame_to_display || skip)
  162.     {
  163.         m_current_code_fnum++;
  164.     }
  165.     return m_fbuffer->GetFrame(m_show_fnum);
  166. }
  167. Frame& SequenceDecompressor::GetNextFrame()
  168. {
  169.     return m_fbuffer->GetFrame(m_show_fnum);
  170. }
  171. void SequenceDecompressor::ReadStreamHeader()
  172. {    //called from constructor
  173.     //read the stream header parameters
  174.     //begin with the identifying string
  175.     OLBParams bparams;
  176.     //char kwname[9];
  177.     //for (int i=0; i<8; ++i)
  178.     //{
  179.     //    kwname[i]=m_decparams.BitsIn().InputByte();    
  180.     //}    
  181.     //kwname[8]='';
  182.     char seq_start[5];
  183.     for (int i=0;i<5;++i)
  184.     {
  185.         seq_start[i]=m_decparams.BitsIn().InputByte();    
  186.     }    
  187.     //TBC: test that kwname="KW-DIRAC"    
  188.     //bit stream version
  189.     m_sparams.SetBitstreamVersion( m_decparams.BitsIn().InputByte() );
  190.     // TODO: test if this bit stream version is supported. Report an error
  191.     // otherwise
  192.     TESTM (m_sparams.BitstreamVersion() == BITSTREAM_VERSION, "Bitstream version match");
  193.     //picture dimensions
  194.     m_sparams.SetXl( int(UnsignedGolombDecode( m_decparams.BitsIn() )) );
  195.     m_sparams.SetYl( int(UnsignedGolombDecode( m_decparams.BitsIn() )) );    
  196.     //picture rate
  197.     m_sparams.SetFrameRate( int(UnsignedGolombDecode( m_decparams.BitsIn() )) );
  198.      //block parameters
  199.     bparams.SetXblen( int(UnsignedGolombDecode( m_decparams.BitsIn() )) );
  200.     bparams.SetYblen( int(UnsignedGolombDecode( m_decparams.BitsIn() )) );    
  201.     bparams.SetXbsep( int(UnsignedGolombDecode( m_decparams.BitsIn() )) );
  202.     bparams.SetYbsep( int(UnsignedGolombDecode( m_decparams.BitsIn() )) );
  203.     //dimensions of block arrays (remember there may need to be padding for some block and picture sizes)
  204.     m_decparams.SetXNumBlocks( int(UnsignedGolombDecode( m_decparams.BitsIn())) );
  205.     m_decparams.SetYNumBlocks( int(UnsignedGolombDecode( m_decparams.BitsIn())) );
  206.     m_decparams.SetXNumMB( m_decparams.XNumBlocks()/4 );
  207.     m_decparams.SetYNumMB( m_decparams.YNumBlocks()/4 );
  208.     //chroma format
  209.     m_sparams.SetCFormat( ChromaFormat(UnsignedGolombDecode( m_decparams.BitsIn())) );        
  210.     m_decparams.SetBlockSizes( bparams , m_sparams.CFormat() );
  211.      //interlace marker
  212.     m_decparams.SetInterlace( m_decparams.BitsIn().InputBit() );
  213.     m_sparams.SetInterlace( m_decparams.Interlace() );
  214.     //Flush the input to the end of the header
  215.     m_decparams.BitsIn().FlushInput();    
  216. }