diff -r 000000000000 -r 71ca22bcf22a mmfenh/advancedaudiocontroller/audiocontrollerpluginsvariant/AdvancedAudioController/Src/AdvancedAudioDecoder.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmfenh/advancedaudiocontroller/audiocontrollerpluginsvariant/AdvancedAudioController/Src/AdvancedAudioDecoder.cpp Tue Feb 02 01:08:46 2010 +0200 @@ -0,0 +1,802 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: The functions in this module implements the common behavior +* for the audio decoder base class. +* +*/ + + +// INCLUDE FILES +#include "AdvancedAudioDecoder.h" +#include "DebugMacros.h" +#include + + +// CONSTANTS + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +EXPORT_C CAdvancedAudioDecoder::CAdvancedAudioDecoder( + TInt aPriority) + : CActive(aPriority), + iState(EIdle), + iSharedBuffers(NULL), + iMMFDevSound(NULL), + iObserver(NULL) + { + DP0(_L("CAdvancedAudioDecoder::CAdvancedAudioDecoder()")); + + iDecoderUtilityObserver = NULL; + iFrameTable = NULL; + } + +// Destructor +EXPORT_C CAdvancedAudioDecoder::~CAdvancedAudioDecoder() + { + DP0(_L("CAdvancedAudioDecoder::~CAdvancedAudioDecoder()")); + iRenderEnableConfig.Close(); + iRenderDisableConfig.Close(); + iMarkPlayEndConfig.Close(); + iUnMarkPlayEndConfig.Close(); + iEnableConfig.Close(); + iDisableConfig.Close(); + delete iConvertBuffer; + delete iChannelAndSampleRateConverterFactory; + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::SetDevSound +// Sets the DevSound instance. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAdvancedAudioDecoder::SetDevSound( + CMMFDevSound& aDevSound) + { + iMMFDevSound = &aDevSound; + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::SetObserver +// Sets the observer instance. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAdvancedAudioDecoder::SetObserver( + MAdvancedAudioDecoderObserver& aObserver) + { + iObserver = &aObserver; + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::SetDecoderUtilityObserver +// Sets the observer instance. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAdvancedAudioDecoder::SetDecoderUtilityObserver(MAdvancedAudioDecoderUtilityObserver& aDecoderUtilityObserver) + { + iDecoderUtilityObserver = &aDecoderUtilityObserver; + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::SetSourceBuffers +// Sets the source buffer for conversion operations. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAdvancedAudioDecoder::SetSourceBuffers( + RPointerArray* aBuffers) + { + iSharedBuffers = aBuffers; + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::SetConfigL +// Sets audio decoder settings and attributes +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAdvancedAudioDecoder::SetConfigL( + TUint aSourceSampleRate, + TUint aSourceChannels, + TUint aSWConvertSampleRate, + TUint aSWConvertChannels, + const RArray& aCodecConfigData, + TInt aIndex) + { + DP0(_L("CAdvancedAudioDecoder::SetConfigL")); + + CodecConfig(const_cast&>(aCodecConfigData)); + + QueueThisBuffer(aIndex); // will set iNextBuffer (current buffer) and update iSharedBufferIndex (to next buffer) + + if(aSourceSampleRate != aSWConvertSampleRate) // Sampling Rate Conversion is needed + { + if (!iChannelAndSampleRateConverterFactory) + { + iChannelAndSampleRateConverterFactory = new(ELeave) CMMFChannelAndSampleRateConverterFactory; + iChannelAndSampleRateConverter = iChannelAndSampleRateConverterFactory->CreateConverterL(aSourceSampleRate, aSourceChannels, + aSWConvertSampleRate, aSWConvertChannels); + } + iNeedsSWConversion = ETrue; + } + + Enable(); + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::FillBuffer +// Request to fill the specified buffer with converted data. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAdvancedAudioDecoder::FillBufferL( + CMMFBuffer* aBuffer) + { + DP0(_L("CAdvancedAudioDecoder::FillBufferL")); + iBufferToFill = aBuffer; + iState = EDecoding; + iStatus = KRequestPending; // service request would be made here and pending set by service provider + SetActive(); + Ready(KErrNone); + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::Stop +// Stops decoding process. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAdvancedAudioDecoder::Stop() + { + DP0(_L("CAdvancedAudioDecoder::Stop")); + + iState = EIdle; + Disable(); + RenderEnable(); + iEventPos = 0; + + // cancel any outstanding FrameTable Seeking event callback + if (iFrameTable) + { + TInt err = iFrameTable->UnRegisterForEvent(CFrameTable::EPosReached, this); + // Fix for the error ou1cimx1#137567 - SXUU-7S9SLD + //TInt err1 = iFrameTable->UnRegisterForEvent(CFrameTable::EPlayWindowEndPosReached, this); + //if (err|err1 != KErrNone) + if (err != KErrNone) + { + //DP2(_L("CAdvancedAudioDecoder::Stop, UnRegisterForEvent errs[%d][%d]"), err, err1); + DP1(_L("CAdvancedAudioDecoder::Stop, UnRegisterForEvent err[%d]"), err); + } + } + } + +EXPORT_C TInt CAdvancedAudioDecoder::SetSourceReference(TUint aTimeMs, TUint aPos) + { + if (!iFrameTable) + return KErrNotSupported; + + return iFrameTable->SetSourceReference(aTimeMs, aPos); + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::FindFramePosFromTime +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CAdvancedAudioDecoder::FindFramePosFromTime(TUint& aTimeMs, TUint& aPos) + { + if (!iFrameTable) + return KErrNotSupported; + + return iFrameTable->FindFramePosFromTime(aTimeMs, aPos); + } + +EXPORT_C TInt CAdvancedAudioDecoder::FindFrameTimeFromPos(TUint& aTime, TUint& aPos) + { + if (!iFrameTable) + return KErrNotSupported; + + return iFrameTable->FindFrameTimeFromPos(aTime, aPos); + } + + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::LastFramePos +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CAdvancedAudioDecoder::LastFramePos(TUint& aPos) + { + if (!iFrameTable) + return KErrNotSupported; + + return iFrameTable->LastFramePos(aPos); + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::LastFrameTime +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CAdvancedAudioDecoder::LastFrameTime(TUint& aTimeMs) + { + if (!iFrameTable) + return KErrNotSupported; + + return iFrameTable->LastFrameTime(aTimeMs); + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::ResetTable +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CAdvancedAudioDecoder::ResetTable() + { + if (!iFrameTable) + return KErrNotSupported; + + iFrameTable->ResetTable(); + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::SeekToTimeMs +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CAdvancedAudioDecoder::SeekToTimeMs(TUint aTimeMs) + { + if (!iFrameTable) + return KErrNotSupported; + if (aTimeMs == KMaxTUint) + { + // Only other place that we unregister is when we stop the decoder. + // Here we need to unregister explicitly such as when there is an outstanding + // seek and we seek again, but if we are not playing yet, we won't stop the output + // and unregister outstanding events by stopping the output. + DP0(_L("CAdvancedAudioDecoder::SeekToTimeMs unregistering events")); + TInt status1 = iFrameTable->UnRegisterForEvent(CFrameTable::EPosReached, this); + return status1; + } + + RenderDisable(); + iSeekToTimeMs = aTimeMs; + return iFrameTable->RegisterForEvent(CFrameTable::EPosReached, this, aTimeMs); + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::SetPlayEndTimeMs +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CAdvancedAudioDecoder::SetPlayWindowEndTimeMs(TUint aTimeMs) + { + TInt status = KErrNotSupported; + if (iFrameTable) + { + if (aTimeMs == 0) + { + status = iFrameTable->UnRegisterForEvent(CFrameTable::EPlayWindowEndPosReached, this); + } + else + { + status = iFrameTable->RegisterForEvent(CFrameTable::EPlayWindowEndPosReached, this, aTimeMs); + } + } + return status; + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::BitRate +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CAdvancedAudioDecoder::BitRate() + { + if (!iFrameTable) + return KErrNotSupported; + + return iFrameTable->Bitrate(); + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::EnableDecodeIntervalEvent +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CAdvancedAudioDecoder::EnableDecodeIntervalEvent(TBool aEnable, TUint aTimeMs) + { + if (!iFrameTable) + return KErrNotSupported; + else + { + if (aEnable) + return iFrameTable->RegisterForEvent(CFrameTable::EDecodeInterval, this, aTimeMs); + else + return iFrameTable->UnRegisterForEvent(CFrameTable::EDecodeInterval, this); + } + } + + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::HandleFrameTableEvent +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CAdvancedAudioDecoder::HandleFrameTableEvent(CFrameTable::TFrameTableEvent aEvent) + { + TInt status = KErrNone; + switch (aEvent) + { + case CFrameTable::EPlayWindowEndPosReached: + case CFrameTable::EPosReached: + RenderEnable(); + if (iDecoderUtilityObserver) + { + if (aEvent == CFrameTable::EPosReached) + { + DP0(_L("CAdvancedAudioDecoder::HandleFrameTableEvent, EPosReached")); + // to allow the iTimePositionInMicroSecs to be updated to seek time in controller + TInt offsets; + TUint pos; + status = iDecoderUtilityObserver->GetOffsets(offsets); + status = iFrameTable->GetLastPosEvent(pos); + DP2(_L("CAdvancedAudioDecoder::HandleFrameTableEvent, pos = %U, offsets = %U"),pos,offsets); + iEventPos = pos + offsets; + iDecoderUtilityObserver->SeekPositionReached(iSeekToTimeMs); + } + else + { // play window end + DP0(_L("CAdvancedAudioDecoder::HandleFrameTableEvent play window end reached")); + iDecoderUtilityObserver->PlayWindowEndPositionReached(); + MarkPlayEnd(); + } + } + break; + + case CFrameTable::EDecodeInterval: + DP0(_L("CAdvancedAudioDecoder::HandleFrameTableEvent, EDecodeInterval")); + + if (iDecoderUtilityObserver) + { + iDecoderUtilityObserver->DecodeIntervalEvent(); + } + + break; + + default: + User::Panic(_L("CAdvancedAudioDecoder::HandleFrameTableEvent, Unexpected event"), KErrArgument); + break; + } + + return status; + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::Ready +// Utility function to post a request complete +// ----------------------------------------------------------------------------- +// +void CAdvancedAudioDecoder::Ready( + const TInt aStatus) + { + TRequestStatus* stat = &iStatus; + User::RequestComplete(stat, aStatus); + } + + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::QueueThisBuffer +// gets buffer at aBufferIndex ready for decoding +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAdvancedAudioDecoder::QueueThisBuffer(TUint aBufferIndex) + { + iNextBuffer = (*iSharedBuffers)[aBufferIndex]; + + DP4(_L("CAdvancedAudioDecoder::QueueThisBuffer, Index[%d] [%x] last[%d] pos[%d]"), + aBufferIndex, static_cast(iNextBuffer)->Data().Ptr(), iNextBuffer->LastBuffer(), iNextBuffer->Position()); + + iSharedBufferIndex = aBufferIndex + 1; + + if (iSharedBufferIndex == iSharedBuffers->Count()) + { + iSharedBufferIndex = 0; + } + + iFrameTable->ShrinkTable(); + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::NextSharedBufferL +// Determine the next available shared buffer from the pool of shared buffers +// iNextBuffer is actually the current buffer in use +// iSharedBufferIndex points to the next buffer to be used +// ----------------------------------------------------------------------------- +// +void CAdvancedAudioDecoder::NextSharedBufferL() + { + CMMFBuffer* refillBuffer = NULL; + // index is the next buffer, index-1 is current buffer, check 2 buffers back from the one being selected + TInt checkBufIndex = iSharedBufferIndex-2; + + if (checkBufIndex < 0) + { + checkBufIndex = checkBufIndex+iSharedBuffers->Count(); + } + + if ((*iSharedBuffers)[checkBufIndex]->Status() == EBeingEmptied) + { + if (iSharedBuffers->Count() <= 2) + { + DP1(_L("CAdvancedAudioDecoder::NextSharedBufferL leave, EBeingEmptied is used on Count[%d]"), iSharedBuffers->Count()); + User::Leave(KErrAbort); + } + DP2(_L("CAdvancedAudioDecoder::NextSharedBufferL, index[%d] [%x] is EBeingEmptied"), + checkBufIndex, static_cast((*iSharedBuffers)[checkBufIndex])->Data().Ptr() ); + refillBuffer = (*iSharedBuffers)[checkBufIndex]; + } + if (refillBuffer) + { + iObserver->RefillBuffer(refillBuffer); + } + if ((*iSharedBuffers)[iSharedBufferIndex]->Status() == EFull) + { + QueueThisBuffer(iSharedBufferIndex); + DP1(_L("CAdvancedAudioDecoder::NextSharedBufferL, After Increment, index[%d]"), iSharedBufferIndex); + } + else + { + DP2(_L("CAdvancedAudioDecoder::NextSharedBufferL - not ready, Index[%d] [%x]"), + iSharedBufferIndex, static_cast((*iSharedBuffers)[iSharedBufferIndex])->Data().Ptr() ); + QueueThisBuffer(iSharedBufferIndex); // we should still have the buffer ready to be used when it is filled + User::Leave(KErrBufferNotReady); + } + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::RunL +// Invoke by the active scheduler when a request completes +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAdvancedAudioDecoder::RunL() + { + DP0(_L("CAdvancedAudioDecoder::RunL")); + if (iState == EDecoding) + { + TRAPD(err,HandleFillBufferL()); + if (err) // if error is encountered, an event is generated and the playback is paused. + { + iObserver->SendEvent(TMMFEvent(KMMFEventCategoryPlaybackComplete, err)); + } + } + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::HandleFillBufferL +// Handle the request to fill the specified buffer with converted data. +// Fill next buffer with audio data. If soft codec, data must first be decoded. +// If source buffer is depleted, a request to the controller is sent to refill +// the buffer with more data and the next source buffer is used. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAdvancedAudioDecoder::HandleFillBufferL() + { + DP3(_L("CAdvancedAudioDecoder::HandleFillBufferL ptr[%x] iRenderEnabled[%d] Position[%d]"), static_cast(iNextBuffer)->Data().Ptr(), iRenderEnabled, iNextBuffer->Position()); + DP3(_L("CAdvancedAudioDecoder::HandleFillBufferL frm#[%d] d0[%x] dp[%x]"), static_cast(iNextBuffer)->FrameNumber(), static_cast(iNextBuffer)->Data().Ptr()[0], + static_cast(iNextBuffer)->Data().Ptr()[iNextBuffer->Position()]); + + iBufferToFill->SetPosition(0); + static_cast(iBufferToFill)->Data().SetLength(0); + iBufferToFill->SetLastBuffer(EFalse); + + TCodecProcessResult result; + TBool moreProcessing = ETrue; + + while (moreProcessing) + { + TRAPD(err, result = ProcessL(*iNextBuffer, *iBufferToFill)); + DP4(_L ("CAdvancedAudioDecoder::HandleFillBufferL - ProcessL stat[%d] result[%d] iEnabled[%d] iMarkPlayEnd[%d]"), + err, result, iEnabled, iMarkPlayEnd); + if (!iEnabled) + { // output buffers are invalid when stopped - don't use them + DP0(_L ("CAdvancedAudioDecoder::HandleFillBufferL - disabled - returning")); + return; + } + + if (err != 0) + { + if (err == KErrCorrupt) + { // go ahead and use corrupt if the codec determines the data is corrupt. + User::Leave(KErrCorrupt); + } + else + { // don't use KErrDied or controller will pause + User::Leave(KErrGeneral); + } + } + + if (iMarkPlayEnd) + { + DP0(_L ("CAdvancedAudioDecoder::HandleFillBufferL marking play end")); + iNextBuffer->SetLastBuffer(ETrue); + iMarkPlayEnd = EFalse; + result.iStatus = TCodecProcessResult::EEndOfData; + } +// DP5(_L ("CAdvancedAudioDecoder::HandleFillBufferL after decode istatus[%d] iSrcBytesProcessed[%d] iDstBytesAdded[%d] srcPosition[%d] dstPosition[%d]"), +// result.iStatus, result.iSrcBytesProcessed, result.iDstBytesAdded, iNextBuffer->Position(), iBufferToFill->Position()); + + TInt bytesInDstBuf = iBufferToFill->Position()+result.iDstBytesAdded; + TInt bytesUsedFromSrcBuf = iNextBuffer->Position()+result.iSrcBytesProcessed; + DP3(_L("CAdvancedAudioDecoder::HandleFillBufferL bytesUsedFromSrcBuf[%d] Position[%d] iSrcBytesProcessed[%d]"), + bytesUsedFromSrcBuf, iNextBuffer->Position(), result.iSrcBytesProcessed); + + if ((result.iStatus == TCodecProcessResult::EProcessComplete || + result.iStatus == TCodecProcessResult::EEndOfData || + result.iStatus == TCodecProcessResult::EDstNotFilled) && iNextBuffer->LastBuffer()) + { + iBufferToFill->SetPosition(bytesInDstBuf); + iNextBuffer->SetPosition(bytesUsedFromSrcBuf); + DP2(_L("CAdvancedAudioDecoder::HandleFillBufferL set pos[%d] in src buf[0x%x]"), + bytesUsedFromSrcBuf, static_cast(iNextBuffer)->Data().Ptr()); + + DP0(_L ("CAdvancedAudioDecoder::HandleFillBufferL setting output buffer as last buffer")); + iBufferToFill->SetLastBuffer(ETrue); + moreProcessing = EFalse; + } + else + { + switch (result.iStatus) + { + case TCodecProcessResult::EProcessComplete: + // finished processing input buffer, all data in output buffer + case TCodecProcessResult::EDstNotFilled: + // the output buffer is not full + case TCodecProcessResult::EProcessIncomplete: + // the output buffer was filled before all the input buffer was processed + { + iBufferToFill->SetPosition(bytesInDstBuf); + iNextBuffer->SetPosition(bytesUsedFromSrcBuf); + DP2(_L("CAdvancedAudioDecoder::HandleFillBufferL set pos[%d] in src buf[0x%x]"), + bytesUsedFromSrcBuf, static_cast(iNextBuffer)->Data().Ptr()); + + + TInt srclength = static_cast(iNextBuffer)->Data().Length(); + TInt dstlength = static_cast(iBufferToFill)->Data().Length(); + TInt dstmaxlength = static_cast(iBufferToFill)->Data().MaxLength(); + + // bytesUsedFromSrcBuf should always be <= iNextBuffer's length + if (bytesUsedFromSrcBuf == srclength) + { + // all input buffer used + if (iNextBuffer->LastBuffer()) + { + DP0(_L ("CAdvancedAudioDecoder::HandleFillBufferL all src used - setting output last buffer")); + iBufferToFill->SetLastBuffer(ETrue); + moreProcessing = EFalse; + } + else + { + // for streaming model keep this used buffer until we start decoding from the next buffer + // so we can be sure to have entries in the seek table for the next buffer for pause resume cases + // for which we have non-seekable sources. + // if we did send it to be refilled, we might pause before we start decoding into the next buffer + // we could be decoding from the temp holding buffer in the codec. + // setting buffer status to EBeingEmptied indicates we are done with the buffer. + // it will be sent for refill later by NextSharedBufferL(). + static_cast(iNextBuffer)->SetStatus(EBeingEmptied); + NextSharedBufferL(); + // length can only be <= maxlength + if (dstlength == dstmaxlength) + { + moreProcessing = EFalse; + } + } + } + else + { + // length can only be <= maxlength + if (dstlength == dstmaxlength) + moreProcessing = EFalse; + } + + break; + } + + case TCodecProcessResult::EEndOfData: + { + DP0(_L("CAdvancedAudioDecoder::HandleFillBufferL, EEndOfData")); + iBufferToFill->SetLastBuffer(ETrue); + moreProcessing = EFalse; + break; + } + + default: + { + DP0(_L("CAdvancedAudioDecoder::HandleFillBufferL, leave on unexpected Result")); + User::Leave(KErrGeneral); + break; + } + } + } + + // break the loop during seeking, in case desired position is already reach during ProcessL + if (!iRenderEnabled) + { + moreProcessing = EFalse; + } + } + + if (iNeedsSWConversion && iRenderEnabled) + { + iBufferToEmpty = iBufferToFill; + CMMFDataBuffer* audio; + + if (iConvertBuffer) + { + delete iConvertBuffer; + iConvertBuffer = NULL; + } + + iConvertBuffer = CMMFDataBuffer::NewL(static_cast(iBufferToFill)->Data().Length()); + iChannelAndSampleRateConverter->Convert(*(static_cast(iBufferToFill)), *iConvertBuffer); + audio = iConvertBuffer; + + //copy our converted data back into the real buffer to return to DevSound Output + TDes8& dest = static_cast(iBufferToFill)->Data(); + dest.SetLength(0); + dest.Copy(audio->Data()); + } + + if (iRenderEnabled) + { + DP1(_L("CAdvancedAudioDecoder::HandleFillBufferL, iObserver->BufferFilled[%x]"), + static_cast(iBufferToFill)->Data().Ptr()); + iObserver->BufferFilled(iBufferToFill); // send output buffer to devsound + } + else + { + if (iBufferToFill->LastBuffer()) + { + DP1(_L("CAdvancedAudioDecoder::HandleFillBufferL, iObserver->BufferFilled[%x] is last buffer"), + static_cast(iBufferToFill)->Data().Ptr()); + iObserver->BufferFilled(iBufferToFill); // be sure to send a last buffer to DS + } + else + { + if (iState == EDecoding) + { + FillBufferL(iBufferToFill); + } + } + } + + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::DoCancel +// Cancels the current and any on going requests/tasks. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CAdvancedAudioDecoder::DoCancel() + { + } + +EXPORT_C void CAdvancedAudioDecoder::RenderDisable() + { + DP0(_L("CAdvancedAudioDecoder::RenderDisable")); + iRenderEnabled = EFalse; + CodecCmd(ERenderDisable); + } + +EXPORT_C void CAdvancedAudioDecoder::RenderEnable() + { + DP0(_L("CAdvancedAudioDecoder::RenderEnable")); + iRenderEnabled = ETrue; + CodecCmd(ERenderEnable); + } + +EXPORT_C void CAdvancedAudioDecoder::Disable() + { + DP0(_L("CAdvancedAudioDecoder::Disable")); + iEnabled = EFalse; + CodecCmd(EDisable); + } + +EXPORT_C void CAdvancedAudioDecoder::Enable() + { + DP0(_L("CAdvancedAudioDecoder::Enable")); + iEnabled = ETrue; + CodecCmd(EEnable); + } + +EXPORT_C void CAdvancedAudioDecoder::MarkPlayEnd() + { + DP0(_L("CAdvancedAudioDecoder::MarkPlayEnd")); + iMarkPlayEnd = ETrue; + CodecCmd(EMarkPlayEnd); + } + +EXPORT_C void CAdvancedAudioDecoder::UnMarkPlayEnd() + { + DP0(_L("CAdvancedAudioDecoder::UnMarkPlayEnd")); + iMarkPlayEnd = EFalse; + CodecCmd(EUnMarkPlayEnd); + } + +EXPORT_C TInt CAdvancedAudioDecoder::CodecConfig(RArray& /*aConfig*/) + { + DP0(_L("CAdvancedAudioDecoder::CodecConfig not supported")); + return KErrNotSupported; + } + +//EXPORT_C TInt CAdvancedAudioDecoder::IsSeeking(TBool& aIsSeeking) +// { +// if (!iFrameTable) +// return KErrNotSupported; +// return iFrameTable->IsSeeking(aIsSeeking); +// } + +EXPORT_C void CAdvancedAudioDecoder::ResetL() + { + DP0(_L("CAdvancedAudioDecoder::ResetL")); + iSoftCodec->ResetL(); + // Enable the decoder for processing, to resume playback + Enable(); + } + +EXPORT_C TBool CAdvancedAudioDecoder::IsHwAccelerated() + { + DP0(_L ("CAdvancedAudioDecoder::IsHwAccelerated false")); + return EFalse; + } + +EXPORT_C TCodecProcessResult CAdvancedAudioDecoder::ProcessL(CMMFBuffer& aSrc, CMMFBuffer& aDst) + { + DP0(_L ("CAdvancedAudioDecoder::ProcessL")); + TCodecProcessResult result; + result = iSoftCodec->ProcessL(aSrc, aDst); + return result; + } + +EXPORT_C TInt CAdvancedAudioDecoder::CodecCmd(TCodecCmd aCmd) + { + DP0(_L ("CAdvancedAudioDecoder::CodecCmd")); + TInt stat = KErrNone; + switch (aCmd) + { + case ERenderDisable: + DP0(_L("CAdvancedAudioDecoder::CodecCmd RenderDisable")); + TRAP(stat, iSoftCodec->ConfigureL(KUidConfig, reinterpret_cast(iRenderDisableConfig))); + break; + case ERenderEnable: + DP0(_L("CAdvancedAudioDecoder::CodecCmd RenderEnable")); + TRAP(stat, iSoftCodec->ConfigureL(KUidConfig, reinterpret_cast(iRenderEnableConfig))); + break; + case EDisable: + DP0(_L("CAdvancedAudioDecoder::CodecCmd Disable")); + TRAP(stat, iSoftCodec->ConfigureL(KUidConfig, reinterpret_cast(iDisableConfig))); + break; + case EEnable: + DP0(_L("CAdvancedAudioDecoder::CodecCmd Enable")); + TRAP(stat, iSoftCodec->ConfigureL(KUidConfig, reinterpret_cast(iEnableConfig))); + break; + case EMarkPlayEnd: + DP0(_L("CAdvancedAudioDecoder::CodecCmd MarkPlayEnd")); + TRAP(stat, iSoftCodec->ConfigureL(KUidConfig, reinterpret_cast(iMarkPlayEndConfig))); + break; + case EUnMarkPlayEnd: + DP0(_L("CAdvancedAudioDecoder::CodecCmd UnMarkPlayEnd")); + TRAP(stat, iSoftCodec->ConfigureL(KUidConfig, reinterpret_cast(iUnMarkPlayEndConfig))); + break; + default: + break; + } + return stat; + } + + +// End of file