diff -r 000000000000 -r 71ca22bcf22a mmfenh/advancedaudiocontroller/audiocontrollerpluginsvariant/AdvancedAudioController/Src/AdvancedAudioDecoderHw.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmfenh/advancedaudiocontroller/audiocontrollerpluginsvariant/AdvancedAudioController/Src/AdvancedAudioDecoderHw.cpp Tue Feb 02 01:08:46 2010 +0200 @@ -0,0 +1,433 @@ +/* +* 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 +//#include + +EXPORT_C TCodecProcessResult CAdvancedAudioDecoder::ProcessHwL(CMMFBuffer& aSrc, CMMFBuffer& aDst) + { + DP0(_L ("CAdvancedAudioDecoder::ProcessAccelL ---start")); + + TMMFPtr8 codecSrc; + TMMFPtr8 codecDst; + + TCodecProcessResult result; + result.iStatus = TCodecProcessResult::EProcessIncomplete; + + //convert from generic CMMFBuffer to CMMFDataBuffer + iSrc = static_cast(&aSrc); + iDst = static_cast(&aDst); + + const TUint srcLen = iSrc->Data().Length(); + const TUint dstAvail = iDst->Data().MaxLength() - iDst->Position(); + + if (!dstAvail) + User::Leave(KErrArgument); + + TUint dstAdded = 0; + TUint srcUsed = 0; + + TInt srcPos = iSrc->Position(); + TInt dstPos = iDst->Position(); + +// DP4(_L ("CAdvancedAudioDecoder::ProcessAccelL: srcLen[%d], srcPos[%d] dstPos[%d], dstAvailLen[%d]"), srcLen, srcPos, dstPos, dstAvailLen); + + while ((dstAdded < dstAvail) && (srcPos + srcUsed < srcLen)) + { + codecSrc.Set(iSrc->Data()); + codecDst.Set(iDst->Data()); + codecDst.SetLength(codecDst.MaxLength()); + codecSrc.Shift(srcPos + srcUsed); + codecDst.Shift(dstPos + dstAdded); + +// DP2(_L ("CAdvancedAudioDecoder::ProcessAccelL: before ProcessDecodeL offsetting srcptr to srcPos[%d]+srcUsed[%d]"), srcPos, srcUsed); + + ProcessParseL(&codecSrc, &codecDst); + if (!iEnabled) + { // output buffer is invalid when stopped - don't use it + DP0(_L ("CAdvancedAudioDecoder::ProcessAccelL --- end - disabled - returning")); + result.iStatus = TCodecProcessResult::EProcessComplete; + return result; + } + + dstAdded += codecDst.Length(); + srcUsed += codecSrc.Length(); + + if (iMarkPlayEnd) + { // don't parse any more data + DP0(_L ("CAdvancedAudioDecoder::ProcessAccelL --- mark play end breaking")); + break; + } + } + + result.iSrcBytesProcessed = srcUsed; + result.iDstBytesAdded = dstAdded; + + if (result.iDstBytesAdded && (result.iSrcBytesProcessed + srcPos >= srcLen)) + result.iStatus = TCodecProcessResult::EProcessComplete; + else if (result.iDstBytesAdded < dstAvail) + result.iStatus = TCodecProcessResult::EDstNotFilled; + + iDst->Data().SetLength(iDst->Position()+result.iDstBytesAdded); + + DP0(_L ("CAdvancedAudioDecoder::ProcessAccelL ---end")); + return result; + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::ProcessParseL +// ProcessParseL method that shall be called from the ProcessL method to perform +// the parsing of the encoded data +// ----------------------------------------------------------------------------- +EXPORT_C void CAdvancedAudioDecoder::ProcessParseL(TMMFPtr8* aSrc, TMMFPtr8* aDst) + { + DP0(_L ("CAdvancedAudioDecoder::ProcessParseL ---start")); + TUint8* srcPtr = NULL; + TUint8* dstPtr = NULL; + TInt srcLen = aSrc->Length(); + TInt dstAvail= aDst->Length(); + TInt srcUsed = 0; + TInt dstUsed = 0; + + //************************************************** + //* Get Input Data: Only want to process more input + //* data if the output buffer is empty. + //************************************************** + + if(iOutBufferCount == 0) + { + srcPtr = (TUint8*) aSrc->Ptr(); + + //************************************************* + //* If the input buffer is empty, and there is + //* enough data in the input stream, then use the + //* data from the input stream. Else must append + //* available input data to the input buffer. + //************************************************* + + srcPtr = PrepareInFrame(srcPtr, srcLen, srcUsed); + + if (iInBufferCount > 0) + { + srcLen = iInBufferCount; + } + } + + //************************************************* + //* If there is enough input data, then determine + //* where the output should go (output stream or + //* output buffer if output stream doesn't have + //* enough room). Then parse the data. + //************************************************* + + if(srcPtr) + { + // Determine where to put output data + dstPtr = (TUint8*) aDst->Ptr(); + dstUsed = iOutFrameLength; + TInt inLen, outLen; + + outLen = dstAvail; + + if(dstAvail < iOutFrameLength) + { +// DP2(_L ("CAdvancedAudioDecoder::ProcessParseL: dstAvail[%d], iOutFrameLength[%d]"), dstAvail, iOutFrameLength); + + dstPtr = iOutBuffer; + outLen = iOutFrameLength; // Set the dst length to the new length + } + + // Parse one frame + inLen = srcLen; + + ParseL(srcPtr, inLen, dstPtr, outLen); + if (!iEnabled) + { // aDst and dstPtr invalid when stopped - don't use + DP0(_L ("CAdvancedAudioDecoder::ProcessParseL --- end - disabled - returning")); + return; + } + + // adjust in counters + if (iInBufferCount > 0) + { + // if parse from the temp buf, adjust indexes +// DP3(_L ("CAdvancedAudioDecoder::ProcessParseL adjusting tempbuf after parse count[%d] indx[%d] used[%d]"), +// iInBufferCount, iInBufferIndx, inLen); + iInBufferCount -= inLen; + iInBufferIndx += inLen; + } + else + { + srcUsed = inLen; + } + + if ((inLen == 0) && (iSrc->LastBuffer())) + { + srcUsed = srcLen; + dstUsed = 0; + } + + // adjust out counters + dstUsed = outLen; + + if (dstAvail < iOutFrameLength) + iOutBufferCount = outLen; + } + + //************************************************* + //* If any data is stored in the output buffer, + //* then output as much of it as well fit in the + //* output stream. + //************************************************* + + if(iOutBufferCount > 0) + { + dstUsed = Min (iOutBufferCount, dstAvail); + TPtrC8 outPtr (iOutBufferPtr, dstUsed); + + aDst->SetLength(0); + aDst->Append (outPtr); + + iOutBufferCount -= dstUsed; + iOutBufferPtr += dstUsed; + + if(iOutBufferCount == 0) + { + iOutBufferPtr = iOutBuffer; + } + } + + + //************************************************* + //* Modify the length attributes of the source and + //* destination data streams to inform the caller + //* of how much data was used in each buffer. + //************************************************* + + +// DP2(_L ("CAdvancedAudioDecoder::ProcessParseL maxlen[%d] used[%d]"), aSrc->MaxLength(), srcUsed); + aSrc->SetLength(srcUsed); + aDst->SetLength(dstUsed); + DP0(_L ("CAdvancedAudioDecoder::ProcessParseL ---end")); + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::PrepareInFrame +// ----------------------------------------------------------------------------- +EXPORT_C TUint8* CAdvancedAudioDecoder::PrepareInFrame(TUint8* aSrc, TInt aSrcLen, TInt& aSrcUsed) + { +// DP0(_L ("CAdvancedAudioDecoder::PrepareInFrame ---start")); + // note: aSrcUsed returns how much data is used from source buffer. + // when it reaches the value of aSrcLen, we will be provided the next input buffer. + // while we are decoding from the temp buf, we set it to 0 because we have not decoded any from + // the current src buffer. + TUint8* dataPtr = NULL; + aSrcUsed = 0; + + if (iInBufferCount == 0) + { + // decoding from src buffer +// DP2(_L("CAdvancedAudioDecoder::PrepareInFrame, aSrc[0x%x] aSrcLen[%d]"), aSrc, aSrcLen); + + iInBufferFilled = EFalse; + iInBufferIndx = 0; + + if (aSrcLen >= iMaxFrameSize) + { // if enough data in input buffer, just use input buffer +// DP2(_L ("CAdvancedAudioDecoder::PrepareInFrame using input buffer[0x%x][0x%x]"), aSrc, aSrc[0]); + dataPtr = aSrc; + } + else if (iSrc->LastBuffer()) + { // if input buffer is last buffer, then use it +// DP2(_L ("CAdvancedAudioDecoder::PrepareInFrame using last input buffer[0x%x][0x%x]"), aSrc, aSrc[0]); + dataPtr = aSrc; + } + else + { + // save input data + // When not enough data in input buffer, move it to temp buffer +// DP5(_L ("CAdvancedAudioDecoder::PrepareInFrame moving to temp buffer[0x%x] src[0x%x]d0[0x%x]srclen[%d]dend[0x%x]"), +// iInBuffer, aSrc, aSrc[0], aSrcLen, aSrc[aSrcLen-1]); + Mem::Copy(iInBuffer, aSrc, aSrcLen); + iInBufferCount = aSrcLen; + aSrcUsed = aSrcLen; // inform that we used input buffer so we will get a new input buffer + iInBufferIndx = 0; // index will move with amount of data decoded + dataPtr = NULL; // NULL prevents decoder from decoding. We need to fill rest of temp buffer + iUsedInBuffer = iInBufferCount; + iSavedBytesCopiedFromSrc = 0; + } + } + else + { + // decoding from temp buffer + dataPtr = iInBuffer+iInBufferIndx; // index is adjusted after decode and ptr is data to decode +// DP4(_L ("CAdvancedAudioDecoder::PrepareInFrame using temp buffer dataPtr[0x%x] iInBufferIndx[%d] iInBufferCount[%d] iInBufferFilled[%d]"), +// dataPtr, iInBufferIndx, iInBufferCount, iInBufferFilled); + + if (!iInBufferFilled) + { + // need to fill rest of temp buffer + TInt bytesToCopy = iSizeOfInBuffer-iUsedInBuffer; + TInt bytesAvailable = aSrcLen; + + if (bytesAvailable < bytesToCopy) + { + bytesToCopy = bytesAvailable; + } + + if (bytesToCopy) + { + // only do this once - partial input buffer means last buffer +// DP5(_L ("CAdvancedAudioDecoder::PrepareInFrame putting more to temp buffer dstptr[0x%x] srcptr[0x%x]d0[0x%x]cnt[%d]dend[0x%x]"), +// dataPtr+iUsedInBuffer, aSrc, aSrc[0], bytesToCopy, iInBuffer[KSizeOfInBuffer-1]); + Mem::Copy(dataPtr+iUsedInBuffer, aSrc, bytesToCopy); + iSavedBytesCopiedFromSrc = bytesToCopy; // save byte count used from this src buffer + iInBufferCount += bytesToCopy; + iUsedInBuffer += bytesToCopy; + iInBufferFilled = ETrue; + } + } + else + { + // temp buffer is filled and we are decoding from it + TInt decodeOffsetIntoInputBuf = iSavedBytesCopiedFromSrc - iInBufferCount; +// DP1(_L ("CAdvancedAudioDecoder::PrepareInFrame using temp buf aSrcUsed[%d]"), decodeOffsetIntoInputBuf); + + if (decodeOffsetIntoInputBuf >= 0) + { + // within the temp buffer, we have decoded all of the prior src buffer's data + // we are decoding into the data copied from the current input buffer + // so we can set the pointer to start using input buffer again + dataPtr = NULL; // NULL prevents decoder from decoding. Need to let src get updated by aSrcUsed + iInBufferCount = 0; + aSrcUsed = decodeOffsetIntoInputBuf; +// DP1(_L ("CAdvancedAudioDecoder::PrepareInFrame using inbuffer again, aSrcUsed[%d]"), aSrcUsed); + } + else + { + aSrcUsed = 0; // here references current src buffer that we are not decoding from yet. +// DP1(_L ("CAdvancedAudioDecoder::PrepareInFrame using inbuffer again, aSrcUsed[%d] b"), aSrcUsed); + } + } + } + + return dataPtr; + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::ParseL +// ----------------------------------------------------------------------------- +EXPORT_C void CAdvancedAudioDecoder::ParseL(TUint8* aSrc, TInt& aSrcUsed, TUint8* aDst, TInt& aDstLen) + { + DP1(_L ("CAdvancedAudioDecoder::ParseL [0x%x]"), aSrc[0]); + TInt savedLen = aSrcUsed; + TInt err = KErrNone; + TInt inLen = aSrcUsed; +// TAudioFrameInfo frameInfo; + TInt frameLen; + + // Parse one frame + + err = FrameLength(aSrc, inLen, frameLen); + aSrcUsed = frameLen; + if (aSrcUsed > savedLen) + { // in case util reports more bytes used than what is available at the end of the content + aSrcUsed = savedLen; + } + + if (!iRenderEnabled) + { // seeking + aDstLen = 0; + } + else + { + if (err == KErrNone) + { + Mem::Copy(aDst, aSrc, aSrcUsed); + aDstLen = aSrcUsed; + } + } + + if (err != KErrNone) + { + aSrcUsed = 0; + err = KErrCorrupt; + } + +// DP2(_L ("CAdvancedAudioDecoder::ParseL after decode aSrcUsed[%d] aDstLen[%d]"), aSrcUsed, aDstLen); + + DP1(_L ("CAdvancedAudioDecoder::ParseL err [%d]"),err); + + if (err == KErrNone) + { + if (iFrameTable) + { + iFrameTable->SubmitTableEntry(iAccLen); // to add an entry for the frame actually decoded + } + } + + if (err == KErrCorrupt) + { + aDstLen = 0; + // decode was not successful at this position, need to move forward because sync may still be found here. + TInt syncPos = SeekSync(aSrc+1, savedLen-1); // decoder's seek returns 0 if not found, so we need to use our own seek function + if (syncPos == savedLen-1) + { // search whole buffer - no sync found - so indicate the rest of the data has been used + aSrcUsed = savedLen; + } + else + { + aSrcUsed = syncPos+1; + } + err = KErrNone; + } + + iAccLen += aSrcUsed; + + if(err != KErrNone) + { // unrecoverable error + if (iSrc->LastBuffer()) + { // don't have to error on last buffer, just indicate all the data was used + aSrcUsed = savedLen; + } + else + { + User::Leave(err); + } + } + } + +// ----------------------------------------------------------------------------- +// CAdvancedAudioDecoder::SeekSync +// ----------------------------------------------------------------------------- +TInt CAdvancedAudioDecoder::SeekSync(TUint8* /*aBuf*/, TInt /*aBufLen*/) + { + return KErrNotSupported; + } + +TInt CAdvancedAudioDecoder::FrameLength(const TUint8* /*aBuf*/, TInt /*aBufLen*/, TInt& /*aFrameLength*/) + { + return KErrNotSupported; + } + + +// End of file