mmfenh/advancedaudiocontroller/audiocontrollerpluginsvariant/AdvancedAudioController/Src/AdvancedAudioDecoderHw.cpp
changeset 0 71ca22bcf22a
equal deleted inserted replaced
-1:000000000000 0:71ca22bcf22a
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  The functions in this module implements the common behavior
       
    15 *                for the audio decoder base class.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include "AdvancedAudioDecoder.h"
       
    22 #include "DebugMacros.h"
       
    23 #include <mmfdatabuffer.h>
       
    24 //#include <Mmfcodec.h>
       
    25 
       
    26 EXPORT_C TCodecProcessResult CAdvancedAudioDecoder::ProcessHwL(CMMFBuffer& aSrc, CMMFBuffer& aDst)
       
    27 	{
       
    28     DP0(_L ("CAdvancedAudioDecoder::ProcessAccelL ---start"));
       
    29 	
       
    30 	TMMFPtr8 codecSrc;
       
    31 	TMMFPtr8 codecDst;
       
    32 
       
    33 	TCodecProcessResult result;
       
    34 	result.iStatus = TCodecProcessResult::EProcessIncomplete;
       
    35 
       
    36 	//convert from generic CMMFBuffer to CMMFDataBuffer
       
    37 	iSrc = static_cast<const CMMFDataBuffer*>(&aSrc);
       
    38 	iDst = static_cast<CMMFDataBuffer*>(&aDst);
       
    39 
       
    40 	const TUint srcLen = iSrc->Data().Length();
       
    41 	const TUint dstAvail = iDst->Data().MaxLength() - iDst->Position();
       
    42 
       
    43 	if (!dstAvail)
       
    44 		User::Leave(KErrArgument);
       
    45 
       
    46 	TUint dstAdded = 0;
       
    47 	TUint srcUsed = 0;
       
    48 
       
    49 	TInt srcPos = iSrc->Position();
       
    50 	TInt dstPos = iDst->Position();
       
    51 
       
    52 //  DP4(_L ("CAdvancedAudioDecoder::ProcessAccelL: srcLen[%d], srcPos[%d] dstPos[%d], dstAvailLen[%d]"), srcLen, srcPos, dstPos, dstAvailLen);
       
    53 
       
    54 	while ((dstAdded < dstAvail) && (srcPos + srcUsed < srcLen))
       
    55         {
       
    56         codecSrc.Set(iSrc->Data());
       
    57         codecDst.Set(iDst->Data());
       
    58         codecDst.SetLength(codecDst.MaxLength());
       
    59 		codecSrc.Shift(srcPos + srcUsed);
       
    60 		codecDst.Shift(dstPos + dstAdded);
       
    61 
       
    62 //		DP2(_L ("CAdvancedAudioDecoder::ProcessAccelL: before ProcessDecodeL offsetting srcptr to srcPos[%d]+srcUsed[%d]"), srcPos, srcUsed);
       
    63 
       
    64 		ProcessParseL(&codecSrc, &codecDst);
       
    65 		if (!iEnabled)
       
    66 			{ // output buffer is invalid when stopped - don't use it
       
    67 	    	DP0(_L ("CAdvancedAudioDecoder::ProcessAccelL --- end - disabled - returning"));
       
    68 	    	result.iStatus = TCodecProcessResult::EProcessComplete;
       
    69 			return result;
       
    70 			}
       
    71 
       
    72         dstAdded += codecDst.Length();
       
    73         srcUsed += codecSrc.Length();
       
    74 
       
    75         if (iMarkPlayEnd)
       
    76         	{ // don't parse any more data
       
    77             DP0(_L ("CAdvancedAudioDecoder::ProcessAccelL --- mark play end breaking"));
       
    78 			break;        	
       
    79         	}
       
    80         }
       
    81 
       
    82 	result.iSrcBytesProcessed = srcUsed;
       
    83 	result.iDstBytesAdded     = dstAdded;
       
    84 
       
    85 	if (result.iDstBytesAdded && (result.iSrcBytesProcessed + srcPos >= srcLen))
       
    86 		result.iStatus = TCodecProcessResult::EProcessComplete;
       
    87 	else if (result.iDstBytesAdded < dstAvail)
       
    88 		result.iStatus = TCodecProcessResult::EDstNotFilled;
       
    89 	
       
    90     iDst->Data().SetLength(iDst->Position()+result.iDstBytesAdded);
       
    91 
       
    92     DP0(_L ("CAdvancedAudioDecoder::ProcessAccelL ---end"));
       
    93     return result;
       
    94 	}
       
    95 
       
    96 // -----------------------------------------------------------------------------
       
    97 // CAdvancedAudioDecoder::ProcessParseL
       
    98 // ProcessParseL method that shall be called from the ProcessL method to perform
       
    99 // the parsing of the encoded data
       
   100 // -----------------------------------------------------------------------------
       
   101 EXPORT_C void CAdvancedAudioDecoder::ProcessParseL(TMMFPtr8* aSrc, TMMFPtr8* aDst)
       
   102     {
       
   103     DP0(_L ("CAdvancedAudioDecoder::ProcessParseL ---start"));
       
   104     TUint8* srcPtr  = NULL;
       
   105     TUint8* dstPtr  = NULL;
       
   106     TInt    srcLen  = aSrc->Length();
       
   107     TInt    dstAvail= aDst->Length();
       
   108     TInt    srcUsed = 0;
       
   109     TInt    dstUsed = 0;
       
   110 
       
   111     //**************************************************
       
   112     //* Get Input Data:  Only want to process more input
       
   113     //* data if the output buffer is empty.
       
   114     //**************************************************
       
   115 
       
   116     if(iOutBufferCount == 0)
       
   117         {
       
   118         srcPtr = (TUint8*) aSrc->Ptr();
       
   119 
       
   120         //*************************************************
       
   121         //* If the input buffer is empty, and there is
       
   122         //* enough data in the input stream, then use the
       
   123         //* data from the input stream.  Else must append
       
   124         //* available input data to the input buffer.
       
   125         //*************************************************
       
   126 
       
   127         srcPtr = PrepareInFrame(srcPtr, srcLen, srcUsed);
       
   128 
       
   129         if (iInBufferCount > 0)
       
   130             {
       
   131             srcLen = iInBufferCount;
       
   132             }
       
   133         }
       
   134 
       
   135     //*************************************************
       
   136     //* If there is enough input data, then determine
       
   137     //* where the output should go (output stream or
       
   138     //* output buffer if output stream doesn't have
       
   139     //* enough room).  Then parse the data.
       
   140     //*************************************************
       
   141 
       
   142     if(srcPtr)
       
   143         {
       
   144         // Determine where to put output data
       
   145         dstPtr = (TUint8*) aDst->Ptr();
       
   146         dstUsed = iOutFrameLength;
       
   147 		TInt inLen, outLen;
       
   148 
       
   149 		outLen = dstAvail;
       
   150 		
       
   151         if(dstAvail < iOutFrameLength)
       
   152             {
       
   153 //	        DP2(_L ("CAdvancedAudioDecoder::ProcessParseL: dstAvail[%d], iOutFrameLength[%d]"), dstAvail, iOutFrameLength);
       
   154 
       
   155             dstPtr = iOutBuffer;
       
   156 			outLen = iOutFrameLength; // Set the dst length to the new length
       
   157             }
       
   158 
       
   159         // Parse one frame
       
   160         inLen = srcLen;
       
   161         
       
   162         ParseL(srcPtr, inLen, dstPtr, outLen);
       
   163 		if (!iEnabled)
       
   164 			{ // aDst and dstPtr invalid when stopped - don't use
       
   165 	    	DP0(_L ("CAdvancedAudioDecoder::ProcessParseL --- end - disabled - returning"));
       
   166 			return;
       
   167 			}
       
   168 
       
   169         // adjust in counters
       
   170         if (iInBufferCount > 0)
       
   171             {
       
   172             // if parse from the temp buf, adjust indexes
       
   173 //	    	DP3(_L ("CAdvancedAudioDecoder::ProcessParseL adjusting tempbuf after parse count[%d] indx[%d] used[%d]"),
       
   174 //	    			iInBufferCount, iInBufferIndx, inLen);
       
   175             iInBufferCount -= inLen;
       
   176             iInBufferIndx += inLen;
       
   177             }
       
   178         else
       
   179             {
       
   180             srcUsed = inLen;
       
   181             }
       
   182         
       
   183 		if ((inLen == 0) && (iSrc->LastBuffer()))
       
   184 			{
       
   185 			srcUsed = srcLen;
       
   186 			dstUsed = 0;
       
   187 			}
       
   188 
       
   189         // adjust out counters
       
   190         dstUsed = outLen;
       
   191         
       
   192         if (dstAvail < iOutFrameLength)
       
   193             iOutBufferCount = outLen;
       
   194         }
       
   195 
       
   196     //*************************************************
       
   197     //* If any data is stored in the output buffer,
       
   198     //* then output as much of it as well fit in the
       
   199     //* output stream.
       
   200     //*************************************************
       
   201 
       
   202     if(iOutBufferCount > 0)
       
   203         {
       
   204         dstUsed = Min (iOutBufferCount, dstAvail);
       
   205         TPtrC8 outPtr (iOutBufferPtr, dstUsed);
       
   206 
       
   207         aDst->SetLength(0);
       
   208         aDst->Append (outPtr);
       
   209 
       
   210         iOutBufferCount -= dstUsed;
       
   211         iOutBufferPtr   += dstUsed;
       
   212 
       
   213         if(iOutBufferCount == 0)
       
   214             {
       
   215             iOutBufferPtr = iOutBuffer;
       
   216             }
       
   217         }
       
   218 
       
   219 
       
   220     //*************************************************
       
   221     //* Modify the length attributes of the source and
       
   222     //* destination data streams to inform the caller
       
   223     //* of how much data was used in each buffer.
       
   224     //*************************************************
       
   225 
       
   226 
       
   227 //    DP2(_L ("CAdvancedAudioDecoder::ProcessParseL maxlen[%d] used[%d]"), aSrc->MaxLength(), srcUsed);
       
   228     aSrc->SetLength(srcUsed);
       
   229     aDst->SetLength(dstUsed);
       
   230     DP0(_L ("CAdvancedAudioDecoder::ProcessParseL ---end"));
       
   231     }
       
   232 
       
   233 // -----------------------------------------------------------------------------
       
   234 // CAdvancedAudioDecoder::PrepareInFrame
       
   235 // -----------------------------------------------------------------------------
       
   236 EXPORT_C TUint8* CAdvancedAudioDecoder::PrepareInFrame(TUint8* aSrc, TInt aSrcLen, TInt& aSrcUsed)
       
   237 	{
       
   238 //    DP0(_L ("CAdvancedAudioDecoder::PrepareInFrame ---start"));
       
   239     // note: aSrcUsed returns how much data is used from source buffer.
       
   240     // when it reaches the value of aSrcLen, we will be provided the next input buffer.
       
   241     // while we are decoding from the temp buf, we set it to 0 because we have not decoded any from
       
   242     // the current src buffer.
       
   243     TUint8* dataPtr = NULL;
       
   244 	aSrcUsed = 0;
       
   245 
       
   246     if (iInBufferCount == 0)
       
   247         {
       
   248         // decoding from src buffer
       
   249 //        DP2(_L("CAdvancedAudioDecoder::PrepareInFrame, aSrc[0x%x] aSrcLen[%d]"), aSrc, aSrcLen);
       
   250 
       
   251         iInBufferFilled = EFalse;
       
   252         iInBufferIndx = 0;
       
   253         
       
   254 		if (aSrcLen >= iMaxFrameSize)
       
   255 			{ // if enough data in input buffer, just use input buffer
       
   256 //			DP2(_L ("CAdvancedAudioDecoder::PrepareInFrame using input buffer[0x%x][0x%x]"), aSrc, aSrc[0]);
       
   257 			dataPtr = aSrc;
       
   258 			}
       
   259 		else if (iSrc->LastBuffer())
       
   260 			{ // if input buffer is last buffer, then use it
       
   261 //			DP2(_L ("CAdvancedAudioDecoder::PrepareInFrame using last input buffer[0x%x][0x%x]"), aSrc, aSrc[0]);
       
   262 			dataPtr = aSrc;
       
   263 			}
       
   264 		else
       
   265 			{
       
   266 			// save input data
       
   267 			// When not enough data in input buffer, move it to temp buffer
       
   268 //			DP5(_L ("CAdvancedAudioDecoder::PrepareInFrame moving to temp buffer[0x%x] src[0x%x]d0[0x%x]srclen[%d]dend[0x%x]"),
       
   269 //						iInBuffer, aSrc, aSrc[0], aSrcLen, aSrc[aSrcLen-1]);
       
   270 			Mem::Copy(iInBuffer, aSrc, aSrcLen);
       
   271 			iInBufferCount = aSrcLen;
       
   272 			aSrcUsed = aSrcLen;     // inform that we used input buffer so we will get a new input buffer
       
   273 			iInBufferIndx = 0;      // index will move with amount of data decoded
       
   274 			dataPtr = NULL;         // NULL prevents decoder from decoding. We need to fill rest of temp buffer
       
   275 			iUsedInBuffer = iInBufferCount;
       
   276 	        iSavedBytesCopiedFromSrc = 0;
       
   277 			}
       
   278         }
       
   279     else
       
   280         {
       
   281         // decoding from temp buffer
       
   282         dataPtr = iInBuffer+iInBufferIndx;  // index is adjusted after decode and ptr is data to decode
       
   283 //		DP4(_L ("CAdvancedAudioDecoder::PrepareInFrame using temp buffer dataPtr[0x%x] iInBufferIndx[%d] iInBufferCount[%d] iInBufferFilled[%d]"),
       
   284 //					dataPtr, iInBufferIndx, iInBufferCount, iInBufferFilled);
       
   285 		
       
   286 		if (!iInBufferFilled)
       
   287             {
       
   288             // need to fill rest of temp buffer
       
   289             TInt bytesToCopy = iSizeOfInBuffer-iUsedInBuffer;
       
   290             TInt bytesAvailable = aSrcLen;
       
   291             
       
   292             if (bytesAvailable < bytesToCopy)
       
   293                 {
       
   294                 bytesToCopy = bytesAvailable;
       
   295                 }
       
   296                 
       
   297             if (bytesToCopy)
       
   298                 {
       
   299                 // only do this once - partial input buffer means last buffer
       
   300 //				DP5(_L ("CAdvancedAudioDecoder::PrepareInFrame putting more to temp buffer dstptr[0x%x] srcptr[0x%x]d0[0x%x]cnt[%d]dend[0x%x]"),
       
   301 //							dataPtr+iUsedInBuffer, aSrc, aSrc[0], bytesToCopy, iInBuffer[KSizeOfInBuffer-1]);
       
   302        			Mem::Copy(dataPtr+iUsedInBuffer, aSrc, bytesToCopy);
       
   303         		iSavedBytesCopiedFromSrc = bytesToCopy; // save byte count used from this src buffer
       
   304 	        	iInBufferCount += bytesToCopy;
       
   305 	        	iUsedInBuffer += bytesToCopy;
       
   306 	        	iInBufferFilled = ETrue;
       
   307                 }
       
   308             }
       
   309         else
       
   310            	{
       
   311            	// temp buffer is filled and we are decoding from it
       
   312        	    TInt decodeOffsetIntoInputBuf = iSavedBytesCopiedFromSrc - iInBufferCount;
       
   313 //			DP1(_L ("CAdvancedAudioDecoder::PrepareInFrame using temp buf aSrcUsed[%d]"), decodeOffsetIntoInputBuf);
       
   314 
       
   315        	    if (decodeOffsetIntoInputBuf >= 0)
       
   316        	    	{
       
   317        	    	// within the temp buffer, we have decoded all of the prior src buffer's data
       
   318        	    	// we are decoding into the data copied from the current input buffer
       
   319        	    	// so we can set the pointer to start using input buffer again
       
   320     	        dataPtr = NULL; // NULL prevents decoder from decoding. Need to let src get updated by aSrcUsed
       
   321 				iInBufferCount = 0;
       
   322 				aSrcUsed = decodeOffsetIntoInputBuf;
       
   323 //				DP1(_L ("CAdvancedAudioDecoder::PrepareInFrame using inbuffer again, aSrcUsed[%d]"), aSrcUsed);
       
   324        	    	}
       
   325        	    else
       
   326        	    	{
       
   327        	    	aSrcUsed = 0; // here references current src buffer that we are not decoding from yet.
       
   328 //				DP1(_L ("CAdvancedAudioDecoder::PrepareInFrame using inbuffer again, aSrcUsed[%d] b"), aSrcUsed);
       
   329        	    	}	
       
   330         	}
       
   331         }
       
   332 
       
   333     return dataPtr;
       
   334 	}
       
   335 
       
   336 // -----------------------------------------------------------------------------
       
   337 // CAdvancedAudioDecoder::ParseL
       
   338 // -----------------------------------------------------------------------------
       
   339 EXPORT_C void CAdvancedAudioDecoder::ParseL(TUint8* aSrc, TInt& aSrcUsed, TUint8* aDst, TInt& aDstLen)
       
   340 	{
       
   341     DP1(_L ("CAdvancedAudioDecoder::ParseL [0x%x]"), aSrc[0]);
       
   342 	TInt savedLen = aSrcUsed;
       
   343 	TInt err = KErrNone;
       
   344 	TInt inLen = aSrcUsed;
       
   345 //    TAudioFrameInfo frameInfo;
       
   346 	TInt frameLen;
       
   347 
       
   348     // Parse one frame
       
   349 
       
   350 	err = FrameLength(aSrc, inLen, frameLen);
       
   351 	aSrcUsed = frameLen;
       
   352 	if (aSrcUsed > savedLen)
       
   353 		{ // in case util reports more bytes used than what is available at the end of the content
       
   354 		aSrcUsed = savedLen;
       
   355 		}
       
   356 
       
   357 	if (!iRenderEnabled)
       
   358 		{ // seeking
       
   359         aDstLen = 0;
       
   360 		}	
       
   361 	else
       
   362 		{
       
   363 		if (err == KErrNone)
       
   364 			{
       
   365 			Mem::Copy(aDst, aSrc, aSrcUsed);
       
   366 			aDstLen = aSrcUsed;
       
   367 			}
       
   368 		}
       
   369 
       
   370 	if (err != KErrNone)
       
   371 		{
       
   372 		aSrcUsed = 0;
       
   373         err = KErrCorrupt;
       
   374 		}	
       
   375 		
       
   376 //	DP2(_L ("CAdvancedAudioDecoder::ParseL after decode aSrcUsed[%d] aDstLen[%d]"), aSrcUsed, aDstLen);
       
   377 
       
   378     DP1(_L ("CAdvancedAudioDecoder::ParseL err [%d]"),err);
       
   379 
       
   380 	if (err == KErrNone)
       
   381 		{
       
   382 		if (iFrameTable)
       
   383 			{
       
   384 	   	    iFrameTable->SubmitTableEntry(iAccLen); // to add an entry for the frame actually decoded
       
   385 			}
       
   386 		}
       
   387 		
       
   388 	if (err == KErrCorrupt)
       
   389 		{
       
   390 		aDstLen = 0;
       
   391 		// decode was not successful at this position, need to move forward because sync may still be found here.
       
   392 		TInt syncPos = SeekSync(aSrc+1, savedLen-1); // decoder's seek returns 0 if not found, so we need to use our own seek function
       
   393 		if (syncPos == savedLen-1)
       
   394 			{ // search whole buffer - no sync found - so indicate the rest of the data has been used
       
   395 			aSrcUsed = savedLen;
       
   396 			}
       
   397 		else 
       
   398 			{
       
   399 			aSrcUsed = syncPos+1;
       
   400 			}	
       
   401 		err = KErrNone;
       
   402 		}
       
   403 
       
   404    	iAccLen += aSrcUsed;
       
   405 
       
   406     if(err != KErrNone)
       
   407         { // unrecoverable error
       
   408 	    if (iSrc->LastBuffer())
       
   409 			{ // don't have to error on last buffer, just indicate all the data was used
       
   410 			aSrcUsed = savedLen;
       
   411 			}
       
   412         else
       
   413             {
       
   414             User::Leave(err);
       
   415             }
       
   416         }
       
   417 	}
       
   418 
       
   419 // -----------------------------------------------------------------------------
       
   420 // CAdvancedAudioDecoder::SeekSync
       
   421 // -----------------------------------------------------------------------------
       
   422 TInt CAdvancedAudioDecoder::SeekSync(TUint8* /*aBuf*/, TInt /*aBufLen*/)
       
   423     {
       
   424     return KErrNotSupported;
       
   425     }
       
   426 
       
   427 TInt CAdvancedAudioDecoder::FrameLength(const TUint8* /*aBuf*/, TInt /*aBufLen*/, TInt& /*aFrameLength*/)
       
   428 	{
       
   429     return KErrNotSupported;
       
   430 	}
       
   431 
       
   432 
       
   433 // End of file