frame_decompress.cpp

00001 /* ***** BEGIN LICENSE BLOCK *****
00002 *
00003 * $Id: frame_decompress.cpp,v 1.3 2005/01/30 05:11:41 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), 
00024 *                 Scott R Ladd
00025 *                 Anuradha Suraparaju
00026 *
00027 * Alternatively, the contents of this file may be used under the terms of
00028 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
00029 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
00030 * the GPL or the LGPL are applicable instead of those above. If you wish to
00031 * allow use of your version of this file only under the terms of the either
00032 * the GPL or LGPL and not to allow others to use your version of this file
00033 * under the MPL, indicate your decision by deleting the provisions above
00034 * and replace them with the notice and other provisions required by the GPL
00035 * or LGPL. If you do not delete the provisions above, a recipient may use
00036 * your version of this file under the terms of any one of the MPL, the GPL
00037 * or the LGPL.
00038 * ***** END LICENSE BLOCK ***** */
00039 
00040 
00041 //Decompression of frames
00043 
00044 #include <libdirac_common/dirac_assertions.h>
00045 #include <libdirac_common/bit_manager.h>
00046 #include <libdirac_decoder/frame_decompress.h>
00047 #include <libdirac_decoder/comp_decompress.h>
00048 #include <libdirac_common/mot_comp.h>
00049 #include <libdirac_common/mv_codec.h>
00050 #include <libdirac_common/golomb.h>
00051 using namespace dirac;
00052 
00053 #include <iostream>
00054 
00055 using std::vector;
00056 
00057 FrameDecompressor::FrameDecompressor(DecoderParams& decp, ChromaFormat cf)
00058 : 
00059 m_decparams(decp),
00060 m_cformat(cf)
00061 {}
00062 
00063 FrameDecompressor::~FrameDecompressor()
00064 {
00065 }
00066 
00067 bool FrameDecompressor::ReadFrameHeader(const FrameBuffer& my_buffer)
00068 {
00069     FrameParams my_fparams (m_cformat , my_buffer.GetFParams().Xl(), my_buffer.GetFParams().Yl());
00070      //Get the frame header (which includes the frame number)
00071     m_fparams = my_fparams; 
00072     m_read_header = ReadFrameHeader(m_fparams);
00073     return m_read_header;
00074 }
00075 
00076 bool FrameDecompressor::Decompress(FrameBuffer& my_buffer)
00077 {
00078 
00079 
00080     if ( !(m_decparams.BitsIn().End())&& m_read_header )
00081     {//if we've not finished the data, can proceed
00082         TEST (my_buffer.GetFParams().Xl() == m_fparams.Xl());
00083         TEST (my_buffer.GetFParams().Yl() == m_fparams.Yl());
00084 
00085         if ( !m_skipped )
00086         {//if we're not m_skipped then we can decode the rest of the frame
00087 
00088             if ( m_decparams.Verbose() )
00089                 std::cerr<<std::endl<<"Decoding frame "<<m_fparams.FrameNum()<<" in display order";        
00090 
00091              //Add a frame into the buffer ready to receive the data        
00092             my_buffer.PushFrame(m_fparams);
00093             Frame& my_frame = my_buffer.GetFrame(m_fparams.FrameNum());//Reference to the frame being decoded
00094             FrameSort fsort = m_fparams.FSort();
00095             MvData* mv_data;
00096             unsigned int num_mv_bits;
00097 
00098             if ( fsort != I_frame )
00099             {//do all the MV stuff        
00100                 mv_data = new MvData( m_decparams.XNumMB() , m_decparams.YNumMB() );
00101 
00102                  //decode mv data
00103                 if (m_decparams.Verbose())
00104                     std::cerr<<std::endl<<"Decoding motion data ...";        
00105                 MvDataCodec my_mv_decoder( &m_decparams.BitsIn(), 50 , m_cformat );
00106                 my_mv_decoder.InitContexts();//may not be necessary
00107                 num_mv_bits = UnsignedGolombDecode( m_decparams.BitsIn() );
00108 
00109                  //Flush to the end of the header for the MV bits            
00110                 m_decparams.BitsIn().FlushInput();
00111 
00112                  //Decompress the MV bits
00113                 my_mv_decoder.Decompress( *mv_data , num_mv_bits );                
00114             }
00115 
00116                //decode components
00117             CompDecompress( my_buffer,m_fparams.FrameNum() , Y_COMP );
00118             if ( m_fparams.CFormat() != Yonly )
00119             {
00120                 CompDecompress( my_buffer , m_fparams.FrameNum() , U_COMP );        
00121                 CompDecompress( my_buffer , m_fparams.FrameNum() , V_COMP );
00122             }
00123 
00124             if ( fsort != I_frame )
00125             {//motion compensate to add the data back in if we don't have an I frame
00126                 MotionCompensator mycomp(m_decparams , ADD );
00127                 mycomp.CompensateFrame(my_buffer , m_fparams.FrameNum() , *mv_data);        
00128                 delete mv_data;    
00129             }
00130             my_frame.Clip();
00131 
00132             if (m_decparams.Verbose())
00133                 std::cerr<<std::endl;        
00134 
00135         }//?m_skipped,!End()
00136         else if (m_skipped){
00137          //TBD: decide what to return if we're m_skipped. Nearest frame in temporal order??    
00138 
00139         }
00140 
00141         m_read_header = false;
00142          //exit success
00143         return true;
00144     }
00145      //exit failure
00146     return false;
00147 }
00148 
00149 void FrameDecompressor::CompDecompress(FrameBuffer& my_buffer, int fnum,CompSort cs)
00150 {
00151     if ( m_decparams.Verbose() )
00152         std::cerr<<std::endl<<"Decoding component data ...";
00153     CompDecompressor my_compdecoder( m_decparams , my_buffer.GetFrame(fnum).GetFparams() );    
00154     PicArray& comp_data=my_buffer.GetComponent( fnum , cs );
00155     my_compdecoder.Decompress( comp_data );
00156 }
00157 
00158 bool FrameDecompressor::ReadFrameHeader( FrameParams& fparams )
00159 {
00160 
00161     if ( !m_decparams.BitsIn().End() )
00162     {
00163         char frame_start[5];
00164         for (int i=0;i<5;++i)
00165         {
00166             frame_start[i]=m_decparams.BitsIn().InputByte();    
00167         }
00168          //read the frame number
00169         int temp_int;
00170 
00171         temp_int = (int)UnsignedGolombDecode( m_decparams.BitsIn() );
00172         fparams.SetFrameNum(temp_int);
00173 
00174          //read whether the frame is m_skipped or not
00175         m_skipped=m_decparams.BitsIn().InputBit();
00176 
00177         if (!m_skipped)
00178         {
00179 
00180              //read the expiry time relative to the frame number
00181             fparams.SetExpiryTime( int( UnsignedGolombDecode( m_decparams.BitsIn() ) ) );
00182 
00183              //read the frame sort
00184             fparams.SetFSort( FrameSort( UnsignedGolombDecode( m_decparams.BitsIn() ) ) );
00185 
00186             if ( fparams.FSort() != I_frame ){
00187 
00188                  //if not an I-frame, read how many references there are
00189                 fparams.Refs().clear();
00190                 fparams.Refs().resize( UnsignedGolombDecode( m_decparams.BitsIn() ) );
00191 
00192                  //for each reference, read the reference numbers
00193                 for ( size_t I = 0 ; I < fparams.Refs().size() ; ++I )
00194                 {
00195                     fparams.Refs()[I] = fparams.FrameNum() + GolombDecode( m_decparams.BitsIn() );
00196                 }//I
00197 
00198                  //determine whether or not there is global motion vector data
00199                 m_use_global= m_decparams.BitsIn().InputBit();
00200 
00201                  //determine whether or not there is block motion vector data
00202                 m_use_block_mv= m_decparams.BitsIn().InputBit();
00203 
00204                  //if there is global but no block motion vector data, determine the prediction mode to use
00205                  //for the whole frame
00206                 if ( m_use_global && !m_use_block_mv )
00207                     m_global_pred_mode= PredMode(UnsignedGolombDecode( m_decparams.BitsIn() ));
00208 
00209             }//?is not an I frame
00210         }//?m_skipped
00211 
00212          //flush the header
00213         m_decparams.BitsIn().FlushInput();
00214 
00215          //exit success
00216         return true;
00217     }//?m_decparams.BitsIn().End()
00218     else
00219     {
00220          //exit failure    
00221         return false;
00222     }
00223 }

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