- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# bit_manager.cpp

    00001 /* ***** BEGIN LICENSE BLOCK *****
    00002 *
    00003 * $Id: bit_manager.cpp,v 1.2 2005/01/30 05:11:40 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 *                 Robert Scott Ladd,
    00025 *                 Tim Borer
    00026 *                 Anuradha Suraparaju
    00027 *
    00028 * Alternatively, the contents of this file may be used under the terms of
    00029 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
    00030 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
    00031 * the GPL or the LGPL are applicable instead of those above. If you wish to
    00032 * allow use of your version of this file only under the terms of the either
    00033 * the GPL or LGPL and not to allow others to use your version of this file
    00034 * under the MPL, indicate your decision by deleting the provisions above
    00035 * and replace them with the notice and other provisions required by the GPL
    00036 * or LGPL. If you do not delete the provisions above, a recipient may use
    00037 * your version of this file under the terms of any one of the MPL, the GPL
    00038 * or the LGPL.
    00039 * ***** END LICENSE BLOCK ***** */
    00040
    00041 #include <libdirac_common/bit_manager.h>
    00042 #include <libdirac_common/common.h>
    00043 using namespace dirac;
    00044
    00045 using std::vector;
    00046
    00048 //Output stuff//
    00050
    00051 //Constructor
    00052 BasicOutputManager::BasicOutputManager(std::ostream* out_data ):
    00053     m_num_out_bytes(0),
    00054     m_op_ptr(out_data)
    00055 {
    00056     InitOutputStream();
    00057 }
    00058
    00059 void BasicOutputManager::InitOutputStream()
    00060 {
    00061     // Set byte pointer to start of buffer
    00062     m_current_byte = 0;
    00063     // Set output mask to MSB of byte
    00064     m_output_mask = 0x80;
    00065     // Reset the output buffer
    00066     m_buffer.clear();
    00067 }
    00068
    00069 void BasicOutputManager::OutputSkipInterpretStartPrefixByte()
    00070 {
    00071     size_t buf_size = m_buffer.size();
    00072     if (buf_size >=4 &&
    00073         m_buffer[buf_size-1] == (char)START_CODE_PREFIX_BYTE3 &&
    00074         m_buffer[buf_size-2] == (char)START_CODE_PREFIX_BYTE2 &&
    00075         m_buffer[buf_size-3] == (char)START_CODE_PREFIX_BYTE1 &&
    00076         m_buffer[buf_size-4] == (char)START_CODE_PREFIX_BYTE0)
    00077     {
    00078         m_buffer.push_back((char)NOT_START_CODE);
    00079         std::cerr << "Wrote ignore code " << std::endl;
    00080     }
    00081 }
    00082
    00083 void BasicOutputManager::OutputBit(const bool& bit )
    00084 {
    00085     m_current_byte |= (bit ? (m_output_mask):0);
    00086
    00087     // Shift mask to next bit in the output byte
    00088     m_output_mask >>= 1;
    00089
    00090     if ( m_output_mask == 0 )
    00091     {
    00092         // If a whole byte has been written, write out
    00093         m_output_mask = 0x80;
    00094         m_buffer.push_back(m_current_byte);
    00095         OutputSkipInterpretStartPrefixByte();
    00096         m_current_byte = 0;
    00097     }
    00098 }
    00099
    00100 void BasicOutputManager::OutputBit(const bool& bit, int& count)
    00101 {
    00102     OutputBit(bit);
    00103     count++;
    00104 }
    00105
    00106 void BasicOutputManager::OutputByte(const char& byte)
    00107 {
    00108     FlushOutput();
    00109     m_buffer.push_back( byte );
    00110     OutputSkipInterpretStartPrefixByte();
    00111 }
    00112
    00113 void BasicOutputManager::OutputBytes( char* str_array )
    00114 {
    00115     FlushOutput();
    00116     while ( *str_array != 0 )
    00117     {
    00118         m_buffer.push_back( *str_array );
    00119         str_array++;
    00120     }
    00121 }
    00122
    00123 void BasicOutputManager::OutputBytes(char* str_array,int num)
    00124 {
    00125     FlushOutput();
    00126     for ( int i=0 ; i<num ; ++i )
    00127         m_buffer.push_back( str_array[i] );
    00128 }
    00129
    00130
    00131 void BasicOutputManager::WriteToFile()
    00132 {
    00133     FlushOutput();
    00134     for ( vector<char>::iterator it=m_buffer.begin() ; it!=m_buffer.end() ; ++it )
    00135     {
    00136         m_op_ptr->write( &( *it ) , 1 );
    00137     }
    00138     m_num_out_bytes = m_buffer.size();
    00139     InitOutputStream();
    00140 }
    00141
    00142 void BasicOutputManager::FlushOutput()
    00143 {
    00144     // Flush the current byte to output buffer and reset
    00145     if ( m_output_mask != 0x80 )
    00146     {
    00147         m_buffer.push_back( m_current_byte );
    00148         m_current_byte = 0;
    00149         m_output_mask = 0x80;
    00150     }
    00151 }
    00152
    00153 // Unit output - a subband or the MV data, for example //
    00154
    00155 UnitOutputManager::UnitOutputManager(std::ostream* out_data ):
    00156     m_header(out_data),
    00157     m_data(out_data),
    00158     m_unit_bytes(0),
    00159     m_unit_data_bytes(0),
    00160     m_unit_head_bytes(0)
    00161     {}
    00162
    00163 void UnitOutputManager::WriteToFile()
    00164 {
    00165     m_header.WriteToFile();
    00166     m_data.WriteToFile();
    00167
    00168     // after writing to file, get the number of unit bytes written
    00169     m_unit_data_bytes = m_data.GetNumBytes();
    00170     m_unit_head_bytes = m_header.GetNumBytes();
    00171     m_unit_bytes = m_unit_data_bytes + m_unit_head_bytes;
    00172
    00173 }
    00174
    00175 FrameOutputManager::FrameOutputManager( std::ostream* out_data , int num_bands ) :
    00176     m_data_array( 3 , num_bands ),
    00177     m_comp_bytes( 3 ),
    00178     m_comp_hdr_bytes( 3 ),
    00179     m_out_stream( out_data )
    00180 {
    00181     Init( num_bands );
    00182 }
    00183
    00184 FrameOutputManager::~FrameOutputManager()
    00185 {
    00186     DeleteAll();
    00187 }
    00188
    00189 void FrameOutputManager::WriteToFile()
    00190 {
    00191
    00192     // Write out the frame header
    00193     m_frame_header->WriteToFile();
    00194     m_total_bytes = m_frame_header->GetNumBytes();
    00195     m_header_bytes = m_frame_header->GetNumBytes();
    00196
    00197     // Write out the motion vector data
    00198     m_mv_data->WriteToFile();
    00199
    00200     // after writing to file, get the number of bytes written
    00201     m_mv_hdr_bytes = m_mv_data->GetUnitHeaderBytes();
    00202     m_mv_bytes = m_mv_data->GetUnitBytes();
    00203
    00204     m_total_bytes += m_mv_bytes;
    00205     m_header_bytes += m_mv_hdr_bytes;
    00206
    00207     // Write out the component data
    00208     for ( int c=0 ; c<3 ; ++c)
    00209     {
    00210
    00211         m_comp_hdr_bytes[c] = 0;
    00212         m_comp_bytes[c] = 0;
    00213
    00214         for ( int b=m_data_array.LastX() ; b>=0 ; --b)
    00215         {
    00216             m_data_array[c][b]->WriteToFile();
    00217             // after writing to file, get the number of bytes written
    00218             m_comp_hdr_bytes[c] += m_data_array[c][b]->GetUnitHeaderBytes();
    00219             m_comp_bytes[c] += m_data_array[c][b]->GetUnitBytes();
    00220         }// b
    00221
    00222     }// c
    00223
    00224     for ( int c=0 ; c<m_data_array.LengthY() ; ++c)
    00225     {
    00226         m_total_bytes += m_comp_bytes[c];
    00227         m_header_bytes += m_comp_hdr_bytes[c];
    00228     }
    00229 }
    00230
    00231 UnitOutputManager& FrameOutputManager::BandOutput( const int csort , const int band_num)
    00232 {
    00233     return *( m_data_array[csort][band_num-1] );
    00234 }
    00235
    00236 const UnitOutputManager& FrameOutputManager::BandOutput( const int csort , const int band_num) const
    00237 {
    00238     return *( m_data_array[csort][band_num-1] );
    00239 }
    00240
    00241 // Frame stuff
    00242
    00243
    00244 void FrameOutputManager::Init( int num_bands )
    00245 {
    00246     // Initialise output for the frame header
    00247     m_frame_header = new BasicOutputManager( m_out_stream );
    00248
    00249     // Initialise output for the MV data
    00250     m_mv_data = new UnitOutputManager( m_out_stream );
    00251
    00252     // Initialise subband outputs
    00253     for ( int c=0 ; c<3 ; ++c)
    00254         for ( int b=0 ; b<num_bands ; ++b)
    00255             m_data_array[c][b] = new UnitOutputManager( m_out_stream );
    00256 }
    00257
    00258 void FrameOutputManager::Reset()
    00259 {
    00260     const int num_bands = m_data_array.LengthX();
    00261     DeleteAll();
    00262     Init( num_bands );
    00263 }
    00264
    00265 void FrameOutputManager::DeleteAll()
    00266 {
    00267     // Delete subband outputs
    00268     for ( int c=0 ; c<3 ; ++c)
    00269         for ( int b=0 ; b<m_data_array.LengthX() ; ++b )
    00270             delete m_data_array[c][b];
    00271
    00272     // Delete MV data op
    00273     delete m_mv_data;
    00274
    00275     // Delete frame header op
    00276     delete m_frame_header;
    00277 }
    00278
    00279
    00280 // Sequence stuff //
    00281
    00282 SequenceOutputManager::SequenceOutputManager( std::ostream* out_data ):
    00283     m_frame_op_mgr( out_data ),
    00284     m_seq_header( out_data ),
    00285     m_seq_end( out_data ),
    00286     m_comp_bytes( 3 ),
    00287     m_comp_hdr_bytes( 3 ),
    00288     m_mv_hdr_bytes(0),
    00289     m_mv_bytes(0),
    00290     m_total_bytes(0),
    00291     m_header_bytes(0),
    00292     m_trailer_bytes(0)
    00293
    00294 {
    00295     for (int c=0 ; c<3 ; ++c )
    00296     {
    00297         m_comp_hdr_bytes[c] = 0;
    00298         m_comp_bytes[c] = 0;
    00299     }
    00300 }
    00301
    00302 void SequenceOutputManager::WriteFrameData()
    00303 {
    00304     m_frame_op_mgr.WriteToFile();
    00305
    00306     // Keep up with count of component bytes
    00307     for (int c=0 ; c<m_comp_hdr_bytes.Length(); ++c)
    00308     {
    00309         m_comp_hdr_bytes[c] += m_frame_op_mgr.ComponentHeadBytes( c );
    00310         m_comp_bytes[c] += m_frame_op_mgr.ComponentBytes( c );
    00311     }// c
    00312
    00313     // Keep up with count of MV bytes
    00314     m_mv_hdr_bytes += m_frame_op_mgr.MVHeadBytes();
    00315     m_mv_bytes += m_frame_op_mgr.MVBytes();
    00316
    00317     // Keep up with overall totals
    00318     m_header_bytes += m_frame_op_mgr.FrameHeadBytes();
    00319     m_total_bytes += m_frame_op_mgr.FrameBytes();
    00320
    00321 }
    00322
    00323 void SequenceOutputManager::WriteSeqHeaderToFile()
    00324 {
    00325     m_seq_header.WriteToFile();
    00326     m_header_bytes += m_seq_header.GetNumBytes();
    00327     m_total_bytes += m_seq_header.GetNumBytes();
    00328 }
    00329
    00330 void SequenceOutputManager::WriteSeqTrailerToFile()
    00331 {
    00332     m_seq_end.WriteToFile();
    00333     m_trailer_bytes += m_seq_end.GetNumBytes();
    00334     m_total_bytes += m_seq_end.GetNumBytes();
    00335 }
    00336
    00338 //Input stuff//
    00340
    00341 //Constructor
    00342 BitInputManager::BitInputManager(std::istream* in_data ):
    00343     m_ip_ptr(in_data)
    00344 {
    00345     InitInputStream();
    00346 }
    00347
    00348
    00349 void BitInputManager::InitInputStream()
    00350 {
    00351     m_shift = 0xffffffff;
    00352     m_input_bits_left = 0;
    00353 }
    00354
    00355 bool BitInputManager::InputBit()
    00356 {
    00357     //assumes mode errors will be caught by iostream class
    00358
    00359     if (m_input_bits_left == 0)
    00360     {
    00361         m_ip_ptr->read(&m_current_byte,1);
    00362         m_input_bits_left = 8;
    00363         if (m_shift == START_CODE_PREFIX && (unsigned char)m_current_byte == NOT_START_CODE)
    00364         {
    00365             std::cerr << "Ignoring byte " << std::endl;
    00366             m_ip_ptr->read(&m_current_byte,1);
    00367             m_shift = 0xffffffff;
    00368         }
    00369         m_shift = (m_shift << 8) | m_current_byte;
    00370     }
    00371
    00372     m_input_bits_left--;
    00373
    00374     return bool( ( m_current_byte >> m_input_bits_left ) & 1 );
    00375
    00376 }
    00377
    00378 bool BitInputManager::InputBit(int& count)
    00379 {
    00380     count++;
    00381     return InputBit();
    00382 }
    00383
    00384 bool BitInputManager::InputBit(int& count, const int max_count)
    00385 {
    00386     if ( count<max_count )
    00387     {
    00388         count++;
    00389         return InputBit();
    00390     }
    00391     else
    00392         return false;
    00393 }
    00394
    00395 char BitInputManager::InputByte()
    00396 {
    00397     // Forget about what's in the current byte
    00398     FlushInput();
    00399
    00400     char byte;
    00401     m_ip_ptr->read(&byte,1);
    00402
    00403     return byte;
    00404 }
    00405
    00406 void BitInputManager::InputBytes(char* cptr, int num)
    00407 {
    00408     // Forget about what's in the current byte
    00409     FlushInput();
    00410
    00411     m_ip_ptr->read(cptr,num);
    00412 }
    00413
    00414 void BitInputManager::FlushInput()
    00415 {
    00416     m_input_bits_left = 0;
    00417 }
    00418
    00419 bool BitInputManager::End() const
    00420 {
    00421     return m_ip_ptr->eof();
    00422 }