- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

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