00001
00002
00003
00004
00005
00006 #include <e32base.h>
00007 #include <mmf/server/mmfdatabuffer.h>
00008 #include "ivorbiscodec.h"
00009 #include <oggutil.h>
00010 #include <vorbisinfo.h>
00011 #include "VorbisDecoder.h"
00012 #include "../OggVorbisUtil/OggUtilBody.h"
00013 #include <e32debug.h>
00014
00015 const TInt KMaxPcmOutFromPacket = 8000;
00016
00017 CVorbisDecoder* CVorbisDecoder::NewL()
00018 {
00019 CVorbisDecoder* self = new(ELeave)CVorbisDecoder;
00020 CleanupStack::PushL(self);
00021 self->ConstructL();
00022 CleanupStack::Pop(self);
00023 return self;
00024 }
00025
00026 CVorbisDecoder::CVorbisDecoder()
00027 {
00028 }
00029
00030 void CVorbisDecoder::ConstructL()
00031 {
00032 vorbis_info_init(&iInfo);
00033 vorbis_comment_init(&iComment);
00034
00035 iSyncState = ogg_sync_create();
00036
00037
00038
00039 iStreamState = ogg_stream_create(-1);
00040 }
00041
00042 CVorbisDecoder::~CVorbisDecoder()
00043 {
00044 if (iState==EReady)
00045 {
00046 vorbis_block_clear(&iBlock);
00047 vorbis_dsp_clear(&iDspState);
00048 }
00049 vorbis_comment_clear(&iComment);
00050 vorbis_info_clear(&iInfo);
00051 ogg_packet_release(&iPacket);
00052 ogg_page_release(&iPage);
00053 ogg_sync_destroy(iSyncState);
00054 ogg_stream_destroy(iStreamState);
00055 }
00056
00067 void CVorbisDecoder::PacketInL(ogg_packet aPacket)
00068 {
00069 if (iState == EBadStream)
00070 {
00071 User::Leave(KErrCorrupt);
00072 }
00073 else if (iState == ENotVorbis)
00074 {
00075 User::Leave(KErrNotSupported);
00076 }
00077 iPacket = aPacket;
00078 if (iState == EInitializing)
00079 {
00080 TInt res = vorbis_synthesis_headerin(&iInfo, &iComment, &iPacket);
00081 if (res < KErrNone)
00082 {
00083 if (res == OV_ENOTVORBIS)
00084 {
00085 iState = ENotVorbis;
00086 User::Leave(KErrNotSupported);
00087 }
00088 else
00089 {
00090 iState = EBadStream;
00091 User::Leave(KErrCorrupt);
00092 }
00093 }
00094 ++iPacketCount;
00095
00096 if (iPacketCount == 3)
00097 {
00098 vorbis_synthesis_init(&iDspState, &iInfo);
00099 vorbis_block_init(&iDspState, &iBlock);
00100 iState = EReady;
00101 }
00102 }
00103 else if (iState == EReady)
00104 {
00105 TInt res = vorbis_synthesis(&iBlock, &iPacket, 1);
00106 if (res == KErrNone)
00107 {
00108 vorbis_synthesis_blockin(&iDspState, &iBlock);
00109 }
00110 else
00111 {
00112 User::Leave(KErrCorrupt);
00113 }
00114 }
00115 else
00116 {
00117 User::Leave(KErrGeneral);
00118 }
00119 }
00120
00131 void CVorbisDecoder::PcmOutL(TDes8& aBuf)
00132 {
00133 if (iState == ENotVorbis)
00134 {
00135 User::Leave(KErrNotSupported);
00136 }
00137 else if (iState == EBadStream)
00138 {
00139 User::Leave(KErrCorrupt);
00140 }
00141 else if (iState == EInitializing)
00142 {
00143 aBuf.SetLength(0);
00144 }
00145 else if (iState == EReady)
00146 {
00147 TInt** pcm;
00148 TInt samples = vorbis_synthesis_pcmout(&iDspState, &pcm);
00149 while ( samples > 0)
00150 {
00151 TInt bytesPerSample = 2*iInfo.channels;
00152 if (bytesPerSample == 0)
00153 {
00154 User::Leave(KErrCorrupt);
00155 }
00156 TInt data = aBuf.Length();
00157 TInt newLength = 0;
00158 if ( data == 0)
00159 {
00160 newLength = aBuf.MaxLength();
00161 }
00162 else
00163 {
00164 newLength = aBuf.MaxLength() - data;
00165 }
00166 TInt bufSamples = newLength/bytesPerSample;
00167 TInt toConv = (samples>bufSamples) ? bufSamples : samples;
00168 TInt length = data + (toConv*bytesPerSample);
00169 if(length <= aBuf.MaxLength())
00170 {
00171 aBuf.SetLength(length);
00172 }
00173 else
00174 {
00175 User::Leave(KErrOverflow);
00176 }
00177 TInt16* bufptr = reinterpret_cast<TInt16*>(&aBuf[data + 0]);
00178
00179 for (TInt c=0; c<iInfo.channels; ++c)
00180 {
00181 TInt* mono = pcm[c];
00182 TInt16* dest = &bufptr[c];
00183 for (TInt i=0; i<toConv; i++)
00184 {
00185 TInt s = mono[i]>>9;
00186
00187
00188 if (s>KMaxTInt16)
00189 {
00190 s = KMaxTInt16;
00191 }
00192 else if (s<KMinTInt16)
00193 {
00194 s = KMinTInt16;
00195 }
00196 dest[i*iInfo.channels] = s;
00197 }
00198 }
00199 vorbis_synthesis_read(&iDspState, toConv);
00200 samples = vorbis_synthesis_pcmout(&iDspState, &pcm);
00201 }
00202 }
00203 else
00204 {
00205 User::Leave(KErrGeneral);
00206 }
00207 }
00208
00209 void CVorbisDecoder::Reset()
00210 {
00211 if (iState==EReady)
00212 {
00213 vorbis_block_clear(&iBlock);
00214 vorbis_dsp_clear(&iDspState);
00215 }
00216 vorbis_comment_clear(&iComment);
00217 vorbis_info_clear(&iInfo);
00218 vorbis_info_init(&iInfo);
00219 vorbis_comment_init(&iComment);
00220 iPacketCount = 0;
00221 iState = EInitializing;
00222 }
00234 void CVorbisDecoder::DecoderL(const CMMFDataBuffer& aBuf, TDes8& aDstBuf)
00235 {
00236 CMMFDataBuffer& srcBuf = const_cast<CMMFDataBuffer&>(aBuf);
00237 if(srcBuf.Status()!= EUnAvailable)
00238 {
00239 unsigned char* buf = ogg_sync_bufferin(iSyncState, aBuf.BufferSize());
00240 TPtr8 bufPtr(buf, 0, aBuf.BufferSize());
00241 bufPtr.Copy(aBuf.Data());
00242 ogg_sync_wrote(iSyncState, aBuf.BufferSize());
00243 }
00244 TInt res = 0;
00245 while(ETrue)
00246 {
00247 res = ogg_stream_packetout(iStreamState, &iPacket);
00248 if (res > 0)
00249 {
00250 PacketInL(iPacket);
00251 if(iState != EInitializing)
00252 {
00253 PcmOutL(aDstBuf);
00254
00255
00256 if (aDstBuf.MaxLength() - aDstBuf.Length() < KMaxPcmOutFromPacket)
00257 {
00258 break;
00259 }
00260 }
00261 }
00262 else if(res == 0)
00263 {
00264
00265 TInt length = ogg_sync_pageseek(iSyncState, &iPage);
00266 if ( length < 0 )
00267 {
00268 continue;
00269 }
00270 else if ( length > 0 )
00271 {
00272 if(iPageNumber == 0)
00273 {
00274 ogg_stream_reset_serialno(iStreamState, ogg_page_serialno(&iPage));
00275 }
00276 ++iPageNumber;
00277
00278 ogg_stream_pagein(iStreamState, &iPage);
00279 }
00280 else
00281 {
00282 break;
00283 }
00284 }
00285 }
00286 }
00287
00288
00289
00290
00291
00292 CVorbisDecoderProcessor* CVorbisDecoderProcessor::NewL()
00293 {
00294 CVorbisDecoderProcessor* self = new(ELeave)CVorbisDecoderProcessor;
00295 CleanupStack::PushL(self);
00296 self->ConstructL();
00297 CleanupStack::Pop(self);
00298 return self;
00299 }
00300
00301 CVorbisDecoderProcessor::CVorbisDecoderProcessor()
00302 {
00303 }
00304
00305 void CVorbisDecoderProcessor::ConstructL()
00306 {
00307 #ifdef SYMBIAN_SEP_HEAP
00308 User::LeaveIfError(iVorbisChunk.CreateLocal(KInitialChunkSize, KMaxChunkSize, EOwnerThread));
00309 iVorbisHeap = User::ChunkHeap(iVorbisChunk, KMinHeapLength);
00310 iDefaultHeap = &User::Heap();
00311 #endif
00312 VORBIS_TRAPD(leaveErr, iDecoder = CVorbisDecoder::NewL());
00313 User::LeaveIfError(leaveErr);
00314 }
00315
00316 CVorbisDecoderProcessor::~CVorbisDecoderProcessor()
00317 {
00318 #ifdef SYMBIAN_SEP_HEAP
00319 if(iVorbisHeap)
00320 {
00321 User::SwitchHeap(iVorbisHeap);
00322 }
00323 #endif
00324 delete iDecoder;
00325 #ifdef SYMBIAN_SEP_HEAP
00326 if(iVorbisHeap)
00327 {
00328 iVorbisChunk.Close();
00329 User::SwitchHeap(iDefaultHeap);
00330 }
00331 #endif
00332 }
00333
00351 void CVorbisDecoderProcessor::ProcessL(const CMMFBuffer& aSource,
00352 CMMFBuffer& aDst,
00353 TProcessResult& aRes,
00354 TUint& aSourceUsed,
00355 TUint& aDestWritten)
00356 {
00357
00358 if (!CMMFBuffer::IsSupportedDataBuffer(aSource.Type()))
00359 {
00360 User::Leave(KErrNotSupported);
00361 }
00362 if (!CMMFBuffer::IsSupportedDataBuffer(aDst.Type()))
00363 {
00364 User::Leave(KErrNotSupported);
00365 }
00366 const CMMFDataBuffer& src = static_cast<const CMMFDataBuffer&>(aSource);
00367 if((src.LastBuffer()) && (src.Data().Length() == 0 ))
00368 {
00369
00370 aDestWritten = 0;
00371 aSourceUsed = 0;
00372 aRes = EComplete;
00373 return;
00374 }
00375 CMMFDataBuffer& dstBuf = static_cast<CMMFDataBuffer&>(aDst);
00376 if ((aSource.FrameNumber()<2) && (aSource.FrameNumber()<iLastFrame))
00377 {
00378 #ifdef SYMBIAN_SEP_HEAP
00379 User::SwitchHeap(iVorbisHeap);
00380 #endif
00381 iDecoder->Reset();
00382 #ifdef SYMBIAN_SEP_HEAP
00383 iVorbisChunk.Close();
00384 #endif
00385 }
00386 dstBuf.Data().SetLength(0);
00387
00388 VORBIS_TRAPD(leaveErr, iDecoder->DecoderL(src,dstBuf.Data()));
00389 User::LeaveIfError(leaveErr);
00390 aDestWritten = dstBuf.Data().Length();
00391 dstBuf.Data().SetLength(dstBuf.Data().Length());
00392 aSourceUsed = src.Data().Length()-aSource.Position();
00393 aRes = ( aDestWritten==0) ? EDestNotFilled : EComplete ;
00394 iLastFrame = aSource.FrameNumber();
00395 }
00396