00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "MpegBitstream.hxx"
00023 #include "Assert.hxx"
00024 #include <cstring>
00025 #include <iostream>
00026
00027 namespace CLAM
00028 {
00029
00030 namespace AudioCodecs
00031 {
00032
00033
00034
00035
00036 const int MpegBitstream::mInputBufferSize = 5*8192;
00037
00038 MpegBitstream::MpegBitstream( FILE* bitstream )
00039 : mpFile( bitstream )
00040 {
00041 mInputBuffer = new unsigned char[mInputBufferSize];
00042 }
00043
00044 MpegBitstream::MpegBitstream()
00045 {
00046 mInputBuffer = new unsigned char[mInputBufferSize];
00047 }
00048
00049 MpegBitstream::~MpegBitstream()
00050 {
00051 if ( mInputBuffer )
00052 delete [] mInputBuffer;
00053 }
00054
00055 void MpegBitstream::Init( FILE* fp )
00056 {
00057 mpFile = fp;
00058 Init();
00059 }
00060
00061 void MpegBitstream::Init()
00062 {
00063 mad_stream_init( &mBitstream );
00064 mad_frame_init( &mCurrentFrame );
00065 mad_synth_init( &mMpegSynth );
00066 mad_timer_reset( &mStreamTimer );
00067 mFatalError = false;
00068 }
00069
00070 TTime MpegBitstream::Finish()
00071 {
00072 mad_synth_finish( &mMpegSynth );
00073 mad_frame_finish( &mCurrentFrame );
00074 mad_stream_finish( &mBitstream );
00075
00076 return (TTime)mad_timer_count( mStreamTimer, MAD_UNITS_MILLISECONDS );
00077 }
00078
00079 bool MpegBitstream::EOS()
00080 {
00081 if ( feof( mpFile ) )
00082 return true;
00083 return false;
00084
00085 }
00086
00087 bool MpegBitstream::NextFrame()
00088 {
00089 bool validFrameFound = false;
00090
00091 while( !validFrameFound && !FatalError() )
00092 {
00093
00094
00095
00096
00097
00098 if ( mBitstream.buffer == NULL
00099 || mBitstream.error == MAD_ERROR_BUFLEN )
00100 {
00101
00102 TSize readSize, remaining;
00103 unsigned char* readStart;
00104
00105 if ( mBitstream.next_frame != NULL )
00106 {
00107 remaining = mBitstream.bufend - mBitstream.next_frame;
00108 memmove( mInputBuffer, mBitstream.next_frame, remaining );
00109 readStart = mInputBuffer+remaining;
00110 readSize = mInputBufferSize - remaining;
00111 }
00112 else
00113 {
00114 readSize = mInputBufferSize;
00115 readStart = mInputBuffer;
00116 remaining = 0;
00117 }
00118
00119 TSize readbytes = fread( readStart, sizeof(unsigned char), readSize, mpFile );
00120
00121 if ( readbytes == 0 )
00122 return false;
00123 else if ( readbytes < readSize )
00124 {
00125 CLAM_DEBUG_ASSERT( readStart + readbytes + MAD_BUFFER_GUARD <=
00126 mInputBuffer + mInputBufferSize,
00127 "Whoops! no room left for buffer guard bytes" );
00128 unsigned char* startPadding = readStart + readbytes;
00129
00130 for ( int i = 0; i < MAD_BUFFER_GUARD; i++ )
00131 startPadding[i] = 0;
00132
00133 readSize = readbytes + MAD_BUFFER_GUARD;
00134 }
00135 else
00136 readSize = readbytes;
00137
00138
00139 mad_stream_buffer( &mBitstream, mInputBuffer, readSize+remaining );
00140 mBitstream.error = MAD_ERROR_NONE;
00141 }
00142
00143
00144 if (mad_frame_decode( &mCurrentFrame, &mBitstream )==-1 )
00145 {
00146
00147 if ( !MAD_RECOVERABLE( mBitstream.error ) )
00148 if ( mBitstream.error != MAD_ERROR_BUFLEN )
00149 mFatalError = true;
00150 }
00151 else
00152 {
00153
00154 validFrameFound = true;
00155
00156 mad_timer_add( &mStreamTimer, mCurrentFrame.header.duration );
00157 }
00158
00159
00160 }
00161
00162 return validFrameFound;
00163
00164 }
00165
00166 bool MpegBitstream::FatalError()
00167 {
00168 return mFatalError || ferror(mpFile)!=0;
00169 }
00170
00171 bool MpegBitstream::SynthesizeCurrent()
00172 {
00173 mad_synth_frame( &mMpegSynth, &mCurrentFrame );
00174
00175 return true;
00176 }
00177
00178 struct mad_frame& MpegBitstream::CurrentFrame()
00179 {
00180 return mCurrentFrame;
00181 }
00182
00183 struct mad_synth& MpegBitstream::CurrentSynthesis()
00184 {
00185 return mMpegSynth;
00186 }
00187
00188 }
00189
00190 }
00191