mmfenh/advancedaudiocontroller/audiocontrollerpluginsvariant/AdvancedAudioController/Src/AdvancedAudioDecoder.cpp
changeset 0 71ca22bcf22a
child 7 709f89d8c047
child 12 5a06f39ad45b
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 
       
    25 
       
    26 // CONSTANTS
       
    27 
       
    28 // ============================ MEMBER FUNCTIONS ===============================
       
    29 
       
    30 // -----------------------------------------------------------------------------
       
    31 // C++ default constructor can NOT contain any code, that
       
    32 // might leave.
       
    33 // -----------------------------------------------------------------------------
       
    34 //
       
    35 EXPORT_C CAdvancedAudioDecoder::CAdvancedAudioDecoder(
       
    36 	TInt aPriority)
       
    37     :   CActive(aPriority),
       
    38     	iState(EIdle),
       
    39         iSharedBuffers(NULL),
       
    40         iMMFDevSound(NULL),
       
    41     	iObserver(NULL)
       
    42     {
       
    43     DP0(_L("CAdvancedAudioDecoder::CAdvancedAudioDecoder()"));
       
    44 
       
    45     iDecoderUtilityObserver = NULL;
       
    46     iFrameTable = NULL;
       
    47     }
       
    48 
       
    49 // Destructor
       
    50 EXPORT_C CAdvancedAudioDecoder::~CAdvancedAudioDecoder()
       
    51 	{
       
    52     DP0(_L("CAdvancedAudioDecoder::~CAdvancedAudioDecoder()"));
       
    53 	iRenderEnableConfig.Close();
       
    54 	iRenderDisableConfig.Close();
       
    55 	iMarkPlayEndConfig.Close();
       
    56 	iUnMarkPlayEndConfig.Close();
       
    57 	iEnableConfig.Close();
       
    58 	iDisableConfig.Close();
       
    59 	delete iConvertBuffer;
       
    60 	delete iChannelAndSampleRateConverterFactory;
       
    61 	}
       
    62 
       
    63 // -----------------------------------------------------------------------------
       
    64 // CAdvancedAudioDecoder::SetDevSound
       
    65 // Sets the DevSound instance.
       
    66 // -----------------------------------------------------------------------------
       
    67 //
       
    68 EXPORT_C void CAdvancedAudioDecoder::SetDevSound(
       
    69 	CMMFDevSound& aDevSound)
       
    70 	{
       
    71 	iMMFDevSound = &aDevSound;
       
    72 	}
       
    73 
       
    74 // -----------------------------------------------------------------------------
       
    75 // CAdvancedAudioDecoder::SetObserver
       
    76 // Sets the observer instance.
       
    77 // -----------------------------------------------------------------------------
       
    78 //
       
    79 EXPORT_C void CAdvancedAudioDecoder::SetObserver(
       
    80 	MAdvancedAudioDecoderObserver& aObserver)
       
    81 	{
       
    82 	iObserver = &aObserver;
       
    83 	}
       
    84 	
       
    85 // -----------------------------------------------------------------------------
       
    86 // CAdvancedAudioDecoder::SetDecoderUtilityObserver
       
    87 // Sets the observer instance.
       
    88 // -----------------------------------------------------------------------------
       
    89 //
       
    90 EXPORT_C void CAdvancedAudioDecoder::SetDecoderUtilityObserver(MAdvancedAudioDecoderUtilityObserver& aDecoderUtilityObserver)
       
    91 	{
       
    92 	iDecoderUtilityObserver = &aDecoderUtilityObserver;
       
    93 	}
       
    94 
       
    95 // -----------------------------------------------------------------------------
       
    96 // CAdvancedAudioDecoder::SetSourceBuffers
       
    97 // Sets the source buffer for conversion operations.
       
    98 // -----------------------------------------------------------------------------
       
    99 //
       
   100 EXPORT_C void CAdvancedAudioDecoder::SetSourceBuffers(
       
   101 	RPointerArray<CMMFDataBuffer>* aBuffers)
       
   102 	{
       
   103 	iSharedBuffers = aBuffers;
       
   104 	}
       
   105 
       
   106 // -----------------------------------------------------------------------------
       
   107 // CAdvancedAudioDecoder::SetConfigL
       
   108 // Sets audio decoder settings and attributes
       
   109 // -----------------------------------------------------------------------------
       
   110 //
       
   111 EXPORT_C void CAdvancedAudioDecoder::SetConfigL(
       
   112     TUint aSourceSampleRate,
       
   113     TUint aSourceChannels,
       
   114     TUint aSWConvertSampleRate,
       
   115     TUint aSWConvertChannels,
       
   116     const RArray<TInt>& aCodecConfigData,
       
   117     TInt aIndex)
       
   118     {
       
   119     DP0(_L("CAdvancedAudioDecoder::SetConfigL"));
       
   120 
       
   121 	CodecConfig(const_cast<RArray<TInt>&>(aCodecConfigData));
       
   122 
       
   123 	QueueThisBuffer(aIndex); // will set iNextBuffer (current buffer) and update iSharedBufferIndex (to next buffer)
       
   124 
       
   125    	if(aSourceSampleRate != aSWConvertSampleRate)  // Sampling Rate Conversion is needed
       
   126    		{
       
   127 	    if (!iChannelAndSampleRateConverterFactory)
       
   128 			{
       
   129 		    iChannelAndSampleRateConverterFactory = new(ELeave) CMMFChannelAndSampleRateConverterFactory;
       
   130 	    	iChannelAndSampleRateConverter = iChannelAndSampleRateConverterFactory->CreateConverterL(aSourceSampleRate, aSourceChannels,
       
   131 		                                                                                         aSWConvertSampleRate, aSWConvertChannels);
       
   132 		    }
       
   133 		iNeedsSWConversion = ETrue;
       
   134     	}
       
   135 
       
   136 	Enable();
       
   137     }
       
   138 
       
   139 // -----------------------------------------------------------------------------
       
   140 // CAdvancedAudioDecoder::FillBuffer
       
   141 // Request to fill the specified buffer with converted data.
       
   142 // -----------------------------------------------------------------------------
       
   143 //
       
   144 EXPORT_C void CAdvancedAudioDecoder::FillBufferL(
       
   145 	CMMFBuffer* aBuffer)
       
   146 	{
       
   147     DP0(_L("CAdvancedAudioDecoder::FillBufferL"));
       
   148 	iBufferToFill = aBuffer;
       
   149 	iState = EDecoding;
       
   150 	iStatus = KRequestPending; // service request would be made here and pending set by service provider
       
   151     SetActive();
       
   152 	Ready(KErrNone);
       
   153 	}
       
   154 
       
   155 // -----------------------------------------------------------------------------
       
   156 // CAdvancedAudioDecoder::Stop
       
   157 // Stops decoding process.
       
   158 // -----------------------------------------------------------------------------
       
   159 //
       
   160 EXPORT_C void CAdvancedAudioDecoder::Stop()
       
   161 	{
       
   162     DP0(_L("CAdvancedAudioDecoder::Stop"));
       
   163 
       
   164 	iState = EIdle;
       
   165 	Disable();
       
   166 	RenderEnable();
       
   167 	iEventPos = 0;
       
   168 
       
   169 	// cancel any outstanding FrameTable Seeking event callback
       
   170 	if (iFrameTable)
       
   171 	    {
       
   172 	    TInt err = iFrameTable->UnRegisterForEvent(CFrameTable::EPosReached, this);
       
   173 	    // Fix for the error ou1cimx1#137567 - SXUU-7S9SLD
       
   174 	    //TInt err1 = iFrameTable->UnRegisterForEvent(CFrameTable::EPlayWindowEndPosReached, this);
       
   175 	    //if (err|err1 != KErrNone)
       
   176 	    if (err != KErrNone)
       
   177 	        {
       
   178             //DP2(_L("CAdvancedAudioDecoder::Stop, UnRegisterForEvent errs[%d][%d]"), err, err1);
       
   179 	        DP1(_L("CAdvancedAudioDecoder::Stop, UnRegisterForEvent err[%d]"), err);
       
   180 	        }
       
   181 	    }	
       
   182 	}
       
   183 
       
   184 EXPORT_C TInt CAdvancedAudioDecoder::SetSourceReference(TUint aTimeMs, TUint aPos)
       
   185 	{
       
   186     if (!iFrameTable)
       
   187         return KErrNotSupported;
       
   188 
       
   189     return iFrameTable->SetSourceReference(aTimeMs, aPos);
       
   190 	}
       
   191 
       
   192 // -----------------------------------------------------------------------------
       
   193 // CAdvancedAudioDecoder::FindFramePosFromTime
       
   194 // -----------------------------------------------------------------------------
       
   195 //
       
   196 EXPORT_C TInt CAdvancedAudioDecoder::FindFramePosFromTime(TUint& aTimeMs, TUint& aPos)
       
   197 	{
       
   198     if (!iFrameTable)
       
   199         return KErrNotSupported;
       
   200 
       
   201     return iFrameTable->FindFramePosFromTime(aTimeMs, aPos);
       
   202 	}
       
   203 
       
   204 EXPORT_C TInt CAdvancedAudioDecoder::FindFrameTimeFromPos(TUint& aTime, TUint& aPos)
       
   205     {
       
   206     if (!iFrameTable)
       
   207         return KErrNotSupported;
       
   208     
       
   209     return iFrameTable->FindFrameTimeFromPos(aTime, aPos);
       
   210     }
       
   211 
       
   212 	
       
   213 // -----------------------------------------------------------------------------
       
   214 // CAdvancedAudioDecoder::LastFramePos
       
   215 // -----------------------------------------------------------------------------
       
   216 //
       
   217 EXPORT_C TInt CAdvancedAudioDecoder::LastFramePos(TUint& aPos)
       
   218 	{
       
   219     if (!iFrameTable)
       
   220         return KErrNotSupported;
       
   221 
       
   222     return iFrameTable->LastFramePos(aPos);
       
   223 	}
       
   224 	
       
   225 // -----------------------------------------------------------------------------
       
   226 // CAdvancedAudioDecoder::LastFrameTime
       
   227 // -----------------------------------------------------------------------------
       
   228 //
       
   229 EXPORT_C TInt CAdvancedAudioDecoder::LastFrameTime(TUint& aTimeMs)
       
   230 	{
       
   231     if (!iFrameTable)
       
   232         return KErrNotSupported;
       
   233 
       
   234     return iFrameTable->LastFrameTime(aTimeMs);
       
   235 	}
       
   236 	
       
   237 // -----------------------------------------------------------------------------
       
   238 // CAdvancedAudioDecoder::ResetTable
       
   239 // -----------------------------------------------------------------------------
       
   240 //
       
   241 EXPORT_C TInt CAdvancedAudioDecoder::ResetTable()
       
   242 	{
       
   243     if (!iFrameTable)
       
   244         return KErrNotSupported;
       
   245 
       
   246     iFrameTable->ResetTable();
       
   247     return KErrNone;
       
   248 	}
       
   249 
       
   250 // -----------------------------------------------------------------------------
       
   251 // CAdvancedAudioDecoder::SeekToTimeMs
       
   252 // -----------------------------------------------------------------------------
       
   253 //	
       
   254 EXPORT_C TInt CAdvancedAudioDecoder::SeekToTimeMs(TUint aTimeMs)
       
   255 	{
       
   256     if (!iFrameTable)
       
   257         return KErrNotSupported;
       
   258     if (aTimeMs == KMaxTUint)
       
   259         {
       
   260         // Only other place that we unregister is when we stop the decoder.
       
   261         // Here we need to unregister explicitly such as when there is an outstanding
       
   262         // seek and we seek again, but if we are not playing yet, we won't stop the output
       
   263         // and unregister outstanding events by stopping the output.
       
   264         DP0(_L("CAdvancedAudioDecoder::SeekToTimeMs unregistering events"));
       
   265         TInt status1 = iFrameTable->UnRegisterForEvent(CFrameTable::EPosReached, this);
       
   266         return status1;
       
   267         }
       
   268     
       
   269     RenderDisable();
       
   270     iSeekToTimeMs = aTimeMs;
       
   271     return iFrameTable->RegisterForEvent(CFrameTable::EPosReached, this, aTimeMs);
       
   272 	}
       
   273 
       
   274 // -----------------------------------------------------------------------------
       
   275 // CAdvancedAudioDecoder::SetPlayEndTimeMs
       
   276 // -----------------------------------------------------------------------------
       
   277 //	
       
   278 EXPORT_C TInt CAdvancedAudioDecoder::SetPlayWindowEndTimeMs(TUint aTimeMs)
       
   279 	{
       
   280 	TInt status = KErrNotSupported;
       
   281     if (iFrameTable)
       
   282     	{
       
   283 	    if (aTimeMs == 0)
       
   284     		{
       
   285 	    	status = iFrameTable->UnRegisterForEvent(CFrameTable::EPlayWindowEndPosReached, this);
       
   286 	    	}
       
   287     	else
       
   288 	    	{
       
   289     		status = iFrameTable->RegisterForEvent(CFrameTable::EPlayWindowEndPosReached, this, aTimeMs);
       
   290     		}	
       
   291     	}
       
   292     return status;
       
   293 	}
       
   294 
       
   295 // -----------------------------------------------------------------------------
       
   296 // CAdvancedAudioDecoder::BitRate
       
   297 // -----------------------------------------------------------------------------
       
   298 //	
       
   299 EXPORT_C TInt CAdvancedAudioDecoder::BitRate()
       
   300 	{
       
   301 	if (!iFrameTable)
       
   302         return KErrNotSupported;
       
   303 
       
   304 	return iFrameTable->Bitrate();
       
   305 	}
       
   306 
       
   307 // -----------------------------------------------------------------------------
       
   308 // CAdvancedAudioDecoder::EnableDecodeIntervalEvent
       
   309 // -----------------------------------------------------------------------------
       
   310 //	
       
   311 EXPORT_C TInt CAdvancedAudioDecoder::EnableDecodeIntervalEvent(TBool aEnable, TUint aTimeMs)
       
   312 	{
       
   313     if (!iFrameTable)
       
   314         return KErrNotSupported;
       
   315     else
       
   316 	    {
       
   317     	if (aEnable)
       
   318             return iFrameTable->RegisterForEvent(CFrameTable::EDecodeInterval, this, aTimeMs);
       
   319         else
       
   320             return iFrameTable->UnRegisterForEvent(CFrameTable::EDecodeInterval, this);
       
   321     	}
       
   322     }
       
   323 
       
   324 
       
   325 // -----------------------------------------------------------------------------
       
   326 // CAdvancedAudioDecoder::HandleFrameTableEvent
       
   327 // -----------------------------------------------------------------------------
       
   328 //	
       
   329 EXPORT_C TInt CAdvancedAudioDecoder::HandleFrameTableEvent(CFrameTable::TFrameTableEvent aEvent)
       
   330 	{
       
   331 	TInt status = KErrNone;
       
   332 	switch (aEvent)
       
   333 		{
       
   334 		case CFrameTable::EPlayWindowEndPosReached:
       
   335 		case CFrameTable::EPosReached:
       
   336 			RenderEnable();
       
   337 		    if (iDecoderUtilityObserver)
       
   338 		        {
       
   339 		        if (aEvent == CFrameTable::EPosReached)
       
   340 		        	{
       
   341 		            DP0(_L("CAdvancedAudioDecoder::HandleFrameTableEvent, EPosReached"));
       
   342 			        // to allow the iTimePositionInMicroSecs to be updated to seek time in controller
       
   343 					TInt offsets;
       
   344 					TUint pos;
       
   345 					status = iDecoderUtilityObserver->GetOffsets(offsets);
       
   346 					status = iFrameTable->GetLastPosEvent(pos);
       
   347 		            DP2(_L("CAdvancedAudioDecoder::HandleFrameTableEvent, pos = %U, offsets = %U"),pos,offsets);
       
   348 					iEventPos = pos + offsets;
       
   349    					iDecoderUtilityObserver->SeekPositionReached(iSeekToTimeMs);
       
   350 		        	}
       
   351 		        else
       
   352 		        	{ // play window end
       
   353                     DP0(_L("CAdvancedAudioDecoder::HandleFrameTableEvent play window end reached"));
       
   354    					iDecoderUtilityObserver->PlayWindowEndPositionReached();
       
   355    					MarkPlayEnd();
       
   356 		        	}
       
   357 		        }
       
   358 			break;
       
   359 			
       
   360 		case CFrameTable::EDecodeInterval:
       
   361             DP0(_L("CAdvancedAudioDecoder::HandleFrameTableEvent, EDecodeInterval"));
       
   362 		
       
   363 		    if (iDecoderUtilityObserver)
       
   364 		        {
       
   365 			    iDecoderUtilityObserver->DecodeIntervalEvent();
       
   366 		        }
       
   367 		    
       
   368 			break;
       
   369 			
       
   370 		default:
       
   371 		    User::Panic(_L("CAdvancedAudioDecoder::HandleFrameTableEvent, Unexpected event"), KErrArgument);
       
   372 		    break;
       
   373 		}
       
   374 		
       
   375 	return status;
       
   376 	}
       
   377 
       
   378 // -----------------------------------------------------------------------------
       
   379 // CAdvancedAudioDecoder::Ready
       
   380 // Utility function to post a request complete
       
   381 // -----------------------------------------------------------------------------
       
   382 //
       
   383 void CAdvancedAudioDecoder::Ready(
       
   384     const TInt aStatus)
       
   385     {
       
   386     TRequestStatus* stat = &iStatus;
       
   387     User::RequestComplete(stat, aStatus);
       
   388     }
       
   389 
       
   390 
       
   391 // -----------------------------------------------------------------------------
       
   392 // CAdvancedAudioDecoder::QueueThisBuffer
       
   393 // gets buffer at aBufferIndex ready for decoding
       
   394 // -----------------------------------------------------------------------------
       
   395 //
       
   396 EXPORT_C void CAdvancedAudioDecoder::QueueThisBuffer(TUint aBufferIndex)
       
   397 	{
       
   398     iNextBuffer = (*iSharedBuffers)[aBufferIndex];
       
   399         
       
   400     DP4(_L("CAdvancedAudioDecoder::QueueThisBuffer, Index[%d] [%x] last[%d] pos[%d]"), 
       
   401    			aBufferIndex, static_cast<CMMFDataBuffer*>(iNextBuffer)->Data().Ptr(), iNextBuffer->LastBuffer(), iNextBuffer->Position());
       
   402 
       
   403     iSharedBufferIndex = aBufferIndex + 1;
       
   404      
       
   405     if (iSharedBufferIndex == iSharedBuffers->Count())
       
   406      	{
       
   407    	    iSharedBufferIndex = 0;
       
   408        	}
       
   409 
       
   410     iFrameTable->ShrinkTable();
       
   411 	}
       
   412 
       
   413 // -----------------------------------------------------------------------------
       
   414 // CAdvancedAudioDecoder::NextSharedBufferL
       
   415 // Determine the next available shared buffer from the pool of shared buffers
       
   416 // iNextBuffer is actually the current buffer in use
       
   417 // iSharedBufferIndex points to the next buffer to be used
       
   418 // -----------------------------------------------------------------------------
       
   419 //
       
   420 void CAdvancedAudioDecoder::NextSharedBufferL()
       
   421     {
       
   422     CMMFBuffer* refillBuffer = NULL;
       
   423     // index is the next buffer, index-1 is current buffer, check 2 buffers back from the one being selected
       
   424     TInt checkBufIndex = iSharedBufferIndex-2;
       
   425     	
       
   426     if (checkBufIndex < 0)
       
   427     	{
       
   428         checkBufIndex = checkBufIndex+iSharedBuffers->Count();
       
   429     	}
       
   430     	
       
   431     if ((*iSharedBuffers)[checkBufIndex]->Status() == EBeingEmptied)
       
   432         {
       
   433         if (iSharedBuffers->Count() <= 2)
       
   434             {
       
   435             DP1(_L("CAdvancedAudioDecoder::NextSharedBufferL leave, EBeingEmptied is used on Count[%d]"), iSharedBuffers->Count());
       
   436             User::Leave(KErrAbort);
       
   437             }
       
   438         DP2(_L("CAdvancedAudioDecoder::NextSharedBufferL, index[%d] [%x] is EBeingEmptied"), 
       
   439             	checkBufIndex, static_cast<CMMFDataBuffer*>((*iSharedBuffers)[checkBufIndex])->Data().Ptr() );
       
   440         refillBuffer = (*iSharedBuffers)[checkBufIndex];
       
   441 	    }
       
   442 	if (refillBuffer)
       
   443 		{
       
   444     	iObserver->RefillBuffer(refillBuffer);
       
   445 		}
       
   446     if ((*iSharedBuffers)[iSharedBufferIndex]->Status() == EFull)
       
   447    	    {
       
   448         QueueThisBuffer(iSharedBufferIndex);
       
   449    	    DP1(_L("CAdvancedAudioDecoder::NextSharedBufferL, After Increment, index[%d]"), iSharedBufferIndex);
       
   450      	}
       
   451    	else
       
   452    		{
       
   453        	DP2(_L("CAdvancedAudioDecoder::NextSharedBufferL - not ready, Index[%d] [%x]"),
       
   454        					iSharedBufferIndex, static_cast<CMMFDataBuffer*>((*iSharedBuffers)[iSharedBufferIndex])->Data().Ptr() );
       
   455         QueueThisBuffer(iSharedBufferIndex); // we should still have the buffer ready to be used when it is filled
       
   456         User::Leave(KErrBufferNotReady);
       
   457    	 	}
       
   458     }
       
   459 
       
   460 // -----------------------------------------------------------------------------
       
   461 // CAdvancedAudioDecoder::RunL
       
   462 // Invoke by the active scheduler when a request completes
       
   463 // -----------------------------------------------------------------------------
       
   464 //
       
   465 EXPORT_C void CAdvancedAudioDecoder::RunL()
       
   466 	{
       
   467     DP0(_L("CAdvancedAudioDecoder::RunL"));
       
   468 	if (iState == EDecoding)
       
   469 		{
       
   470 		TRAPD(err,HandleFillBufferL());
       
   471 		if (err) // if error is encountered, an event is generated and the playback is paused.
       
   472 			{
       
   473 			iObserver->SendEvent(TMMFEvent(KMMFEventCategoryPlaybackComplete, err));
       
   474 			}
       
   475 		}
       
   476 	}
       
   477 
       
   478 // -----------------------------------------------------------------------------
       
   479 // CAdvancedAudioDecoder::HandleFillBufferL
       
   480 // Handle the request to fill the specified buffer with converted data.
       
   481 // Fill next buffer with audio data. If soft codec, data must first be decoded.
       
   482 // If source buffer is depleted, a request to the controller is sent to refill
       
   483 // the buffer with more data and the next source buffer is used.
       
   484 // -----------------------------------------------------------------------------
       
   485 //
       
   486 EXPORT_C void CAdvancedAudioDecoder::HandleFillBufferL()
       
   487 	{
       
   488     DP3(_L("CAdvancedAudioDecoder::HandleFillBufferL ptr[%x] iRenderEnabled[%d] Position[%d]"), static_cast<CMMFDataBuffer*>(iNextBuffer)->Data().Ptr(), iRenderEnabled, iNextBuffer->Position());
       
   489     DP3(_L("CAdvancedAudioDecoder::HandleFillBufferL frm#[%d] d0[%x] dp[%x]"), static_cast<CMMFDataBuffer*>(iNextBuffer)->FrameNumber(), static_cast<CMMFDataBuffer*>(iNextBuffer)->Data().Ptr()[0],
       
   490      static_cast<CMMFDataBuffer*>(iNextBuffer)->Data().Ptr()[iNextBuffer->Position()]);
       
   491 
       
   492     iBufferToFill->SetPosition(0);
       
   493 	static_cast<CMMFDataBuffer*>(iBufferToFill)->Data().SetLength(0);
       
   494     iBufferToFill->SetLastBuffer(EFalse);
       
   495 
       
   496     TCodecProcessResult result;
       
   497     TBool moreProcessing = ETrue;
       
   498 
       
   499     while (moreProcessing)
       
   500         {
       
   501         TRAPD(err, result = ProcessL(*iNextBuffer, *iBufferToFill));
       
   502         DP4(_L ("CAdvancedAudioDecoder::HandleFillBufferL - ProcessL stat[%d] result[%d] iEnabled[%d] iMarkPlayEnd[%d]"),
       
   503                 err, result, iEnabled, iMarkPlayEnd);
       
   504    		if (!iEnabled)
       
   505             { // output buffers are invalid when stopped - don't use them
       
   506 	        DP0(_L ("CAdvancedAudioDecoder::HandleFillBufferL - disabled - returning"));
       
   507             return;
       
   508             }
       
   509 
       
   510         if (err != 0)
       
   511             {
       
   512             if (err == KErrCorrupt)
       
   513                 { // go ahead and use corrupt if the codec determines the data is corrupt.
       
   514                 User::Leave(KErrCorrupt);
       
   515                 }
       
   516             else
       
   517                 { // don't use KErrDied or controller will pause
       
   518                 User::Leave(KErrGeneral);
       
   519                 }
       
   520             }
       
   521 		
       
   522 		if (iMarkPlayEnd)
       
   523 			{
       
   524             DP0(_L ("CAdvancedAudioDecoder::HandleFillBufferL marking play end"));
       
   525             iNextBuffer->SetLastBuffer(ETrue);
       
   526             iMarkPlayEnd = EFalse;
       
   527             result.iStatus = TCodecProcessResult::EEndOfData;
       
   528 			}
       
   529 //      DP5(_L ("CAdvancedAudioDecoder::HandleFillBufferL after decode istatus[%d] iSrcBytesProcessed[%d] iDstBytesAdded[%d] srcPosition[%d] dstPosition[%d]"),
       
   530 //               result.iStatus, result.iSrcBytesProcessed, result.iDstBytesAdded, iNextBuffer->Position(), iBufferToFill->Position());
       
   531 
       
   532 	    TInt bytesInDstBuf = iBufferToFill->Position()+result.iDstBytesAdded;
       
   533 	    TInt bytesUsedFromSrcBuf = iNextBuffer->Position()+result.iSrcBytesProcessed;
       
   534 	   	DP3(_L("CAdvancedAudioDecoder::HandleFillBufferL bytesUsedFromSrcBuf[%d] Position[%d] iSrcBytesProcessed[%d]"), 
       
   535 	   			bytesUsedFromSrcBuf, iNextBuffer->Position(), result.iSrcBytesProcessed);
       
   536 	    
       
   537         if ((result.iStatus == TCodecProcessResult::EProcessComplete ||
       
   538 				result.iStatus == TCodecProcessResult::EEndOfData ||
       
   539 				result.iStatus == TCodecProcessResult::EDstNotFilled) && iNextBuffer->LastBuffer())
       
   540             {
       
   541    			iBufferToFill->SetPosition(bytesInDstBuf);
       
   542   			iNextBuffer->SetPosition(bytesUsedFromSrcBuf);
       
   543 		   	DP2(_L("CAdvancedAudioDecoder::HandleFillBufferL set pos[%d] in src buf[0x%x]"), 
       
   544 		   			bytesUsedFromSrcBuf, static_cast<CMMFDataBuffer*>(iNextBuffer)->Data().Ptr());
       
   545   			
       
   546             DP0(_L ("CAdvancedAudioDecoder::HandleFillBufferL setting output buffer as last buffer"));
       
   547             iBufferToFill->SetLastBuffer(ETrue);
       
   548             moreProcessing = EFalse;
       
   549             }
       
   550         else
       
   551             {
       
   552             switch (result.iStatus)
       
   553                 {
       
   554                 case TCodecProcessResult::EProcessComplete:
       
   555                 	// finished processing input buffer, all data in output buffer
       
   556                 case TCodecProcessResult::EDstNotFilled:
       
   557                 	// the output buffer is not full
       
   558                 case TCodecProcessResult::EProcessIncomplete:
       
   559                 	// the output buffer was filled before all the input buffer was processed
       
   560                     {                
       
   561                     iBufferToFill->SetPosition(bytesInDstBuf);
       
   562                     iNextBuffer->SetPosition(bytesUsedFromSrcBuf);
       
   563 				   	DP2(_L("CAdvancedAudioDecoder::HandleFillBufferL set pos[%d] in src buf[0x%x]"), 
       
   564 				   			bytesUsedFromSrcBuf, static_cast<CMMFDataBuffer*>(iNextBuffer)->Data().Ptr());
       
   565   			
       
   566                     
       
   567                     TInt srclength = static_cast<CMMFDataBuffer*>(iNextBuffer)->Data().Length();
       
   568                 	TInt dstlength = static_cast<CMMFDataBuffer*>(iBufferToFill)->Data().Length();
       
   569 					TInt dstmaxlength = static_cast<CMMFDataBuffer*>(iBufferToFill)->Data().MaxLength();
       
   570 
       
   571                     // bytesUsedFromSrcBuf should always be <= iNextBuffer's length
       
   572 					if (bytesUsedFromSrcBuf == srclength)
       
   573                         {
       
   574                         // all input buffer used
       
   575                         if (iNextBuffer->LastBuffer())
       
   576                             {
       
   577                             DP0(_L ("CAdvancedAudioDecoder::HandleFillBufferL all src used - setting output last buffer"));
       
   578                             iBufferToFill->SetLastBuffer(ETrue);
       
   579                             moreProcessing = EFalse;
       
   580                             }
       
   581                         else
       
   582                             {
       
   583                             // for streaming model keep this used buffer until we start decoding from the next buffer
       
   584 							// so we can be sure to have  entries in the seek table for the next buffer for pause resume cases
       
   585 							// for which we have non-seekable sources.
       
   586 							// if we did send it to be refilled, we might pause before we start decoding into the next buffer
       
   587 							// we could be decoding from the temp holding buffer in the codec.
       
   588                             // setting buffer status to EBeingEmptied indicates we are done with the buffer.
       
   589                             // it will be sent for refill later by NextSharedBufferL().
       
   590                             static_cast<CMMFDataBuffer*>(iNextBuffer)->SetStatus(EBeingEmptied);
       
   591                             NextSharedBufferL();
       
   592                             // length can only be <= maxlength
       
   593 							if (dstlength == dstmaxlength)
       
   594 								{
       
   595 								moreProcessing = EFalse;
       
   596 								}
       
   597                             }
       
   598                         }
       
   599                     else
       
   600                         {
       
   601                         // length can only be <= maxlength
       
   602 						if (dstlength == dstmaxlength)
       
   603                             moreProcessing = EFalse;
       
   604                         }
       
   605                         
       
   606                     break;
       
   607                     }
       
   608 
       
   609                 case TCodecProcessResult::EEndOfData:
       
   610                     {
       
   611                     DP0(_L("CAdvancedAudioDecoder::HandleFillBufferL, EEndOfData"));
       
   612                     iBufferToFill->SetLastBuffer(ETrue);
       
   613                     moreProcessing = EFalse;
       
   614                     break;
       
   615                     }
       
   616 
       
   617                 default:
       
   618                     {
       
   619                     DP0(_L("CAdvancedAudioDecoder::HandleFillBufferL, leave on unexpected Result"));
       
   620                     User::Leave(KErrGeneral);
       
   621                     break;
       
   622                     }
       
   623                 }
       
   624             }
       
   625             
       
   626         // break the loop during seeking, in case desired position is already reach during ProcessL
       
   627         if (!iRenderEnabled)
       
   628         	{
       
   629             moreProcessing = EFalse;
       
   630         	}
       
   631         }
       
   632 
       
   633     if (iNeedsSWConversion && iRenderEnabled)
       
   634     	{
       
   635 	    iBufferToEmpty = iBufferToFill;
       
   636 		CMMFDataBuffer* audio;
       
   637 		
       
   638         if (iConvertBuffer)
       
   639             {
       
   640             delete iConvertBuffer;
       
   641             iConvertBuffer = NULL;
       
   642             }
       
   643             
       
   644 		iConvertBuffer = CMMFDataBuffer::NewL(static_cast<CMMFDataBuffer*>(iBufferToFill)->Data().Length());
       
   645 		iChannelAndSampleRateConverter->Convert(*(static_cast<CMMFDataBuffer*>(iBufferToFill)), *iConvertBuffer);
       
   646 		audio = iConvertBuffer;
       
   647 
       
   648 		//copy our converted data back into the real buffer to return to DevSound Output
       
   649 		TDes8& dest = static_cast<CMMFDataBuffer*>(iBufferToFill)->Data();
       
   650 		dest.SetLength(0);
       
   651 		dest.Copy(audio->Data());
       
   652     	}
       
   653 
       
   654     if (iRenderEnabled)
       
   655     	{
       
   656         DP1(_L("CAdvancedAudioDecoder::HandleFillBufferL, iObserver->BufferFilled[%x]"),
       
   657         		static_cast<CMMFDataBuffer*>(iBufferToFill)->Data().Ptr());
       
   658     	iObserver->BufferFilled(iBufferToFill);     // send output buffer to devsound
       
   659     	}
       
   660     else
       
   661     	{
       
   662     	if (iBufferToFill->LastBuffer())
       
   663     		{
       
   664         	DP1(_L("CAdvancedAudioDecoder::HandleFillBufferL, iObserver->BufferFilled[%x] is last buffer"),
       
   665 		       		static_cast<CMMFDataBuffer*>(iBufferToFill)->Data().Ptr());
       
   666 	    	iObserver->BufferFilled(iBufferToFill); // be sure to send a last buffer to DS
       
   667     		}
       
   668     	else
       
   669     		{
       
   670 			if (iState == EDecoding)
       
   671 				{
       
   672 				FillBufferL(iBufferToFill);
       
   673 				}
       
   674     		}	
       
   675     	}
       
   676     	
       
   677     }
       
   678 
       
   679 // -----------------------------------------------------------------------------
       
   680 // CAdvancedAudioDecoder::DoCancel
       
   681 // Cancels the current and any on going requests/tasks.
       
   682 // -----------------------------------------------------------------------------
       
   683 //
       
   684 EXPORT_C void CAdvancedAudioDecoder::DoCancel()
       
   685     {
       
   686     }
       
   687 
       
   688 EXPORT_C void CAdvancedAudioDecoder::RenderDisable()
       
   689 	{
       
   690    	DP0(_L("CAdvancedAudioDecoder::RenderDisable"));
       
   691 	iRenderEnabled = EFalse;
       
   692 	CodecCmd(ERenderDisable);
       
   693 	}
       
   694 	
       
   695 EXPORT_C void CAdvancedAudioDecoder::RenderEnable()
       
   696 	{
       
   697    	DP0(_L("CAdvancedAudioDecoder::RenderEnable"));
       
   698 	iRenderEnabled = ETrue;
       
   699 	CodecCmd(ERenderEnable);
       
   700 	}
       
   701 
       
   702 EXPORT_C void CAdvancedAudioDecoder::Disable()
       
   703 	{
       
   704    	DP0(_L("CAdvancedAudioDecoder::Disable"));
       
   705 	iEnabled = EFalse;
       
   706 	CodecCmd(EDisable);
       
   707 	}
       
   708 	
       
   709 EXPORT_C void CAdvancedAudioDecoder::Enable()
       
   710 	{
       
   711    	DP0(_L("CAdvancedAudioDecoder::Enable"));
       
   712 	iEnabled = ETrue;
       
   713 	CodecCmd(EEnable);
       
   714 	}
       
   715 
       
   716 EXPORT_C void CAdvancedAudioDecoder::MarkPlayEnd()
       
   717 	{
       
   718     DP0(_L("CAdvancedAudioDecoder::MarkPlayEnd"));
       
   719 	iMarkPlayEnd = ETrue;
       
   720 	CodecCmd(EMarkPlayEnd);
       
   721 	}
       
   722 
       
   723 EXPORT_C void CAdvancedAudioDecoder::UnMarkPlayEnd()
       
   724 	{
       
   725     DP0(_L("CAdvancedAudioDecoder::UnMarkPlayEnd"));
       
   726 	iMarkPlayEnd = EFalse;
       
   727 	CodecCmd(EUnMarkPlayEnd);
       
   728 	}
       
   729 
       
   730 EXPORT_C TInt CAdvancedAudioDecoder::CodecConfig(RArray<TInt>& /*aConfig*/)
       
   731 	{
       
   732     DP0(_L("CAdvancedAudioDecoder::CodecConfig not supported"));
       
   733 	return KErrNotSupported;
       
   734 	}
       
   735 	
       
   736 //EXPORT_C TInt CAdvancedAudioDecoder::IsSeeking(TBool& aIsSeeking)
       
   737 //	{
       
   738 //    if (!iFrameTable)
       
   739 //        return KErrNotSupported;
       
   740 //    return iFrameTable->IsSeeking(aIsSeeking);
       
   741 //	}
       
   742 
       
   743 EXPORT_C void CAdvancedAudioDecoder::ResetL()
       
   744 	{
       
   745     DP0(_L("CAdvancedAudioDecoder::ResetL"));
       
   746 	iSoftCodec->ResetL();
       
   747 	// Enable the decoder for processing, to resume playback
       
   748 	Enable();
       
   749 	}
       
   750 
       
   751 EXPORT_C TBool CAdvancedAudioDecoder::IsHwAccelerated()
       
   752 	{
       
   753     DP0(_L ("CAdvancedAudioDecoder::IsHwAccelerated false"));
       
   754 	return EFalse;
       
   755 	}
       
   756 
       
   757 EXPORT_C TCodecProcessResult CAdvancedAudioDecoder::ProcessL(CMMFBuffer& aSrc, CMMFBuffer& aDst)
       
   758 	{
       
   759     DP0(_L ("CAdvancedAudioDecoder::ProcessL"));
       
   760 	TCodecProcessResult result;
       
   761     result = iSoftCodec->ProcessL(aSrc, aDst);
       
   762     return result;
       
   763 	}
       
   764 
       
   765 EXPORT_C TInt CAdvancedAudioDecoder::CodecCmd(TCodecCmd aCmd)
       
   766 	{
       
   767     DP0(_L ("CAdvancedAudioDecoder::CodecCmd"));
       
   768 	TInt stat = KErrNone;
       
   769 	switch (aCmd)
       
   770 		{
       
   771 		case ERenderDisable:
       
   772 			DP0(_L("CAdvancedAudioDecoder::CodecCmd RenderDisable"));
       
   773 			TRAP(stat, iSoftCodec->ConfigureL(KUidConfig, reinterpret_cast<TDesC8&>(iRenderDisableConfig)));
       
   774 			break;
       
   775 		case ERenderEnable:
       
   776 			DP0(_L("CAdvancedAudioDecoder::CodecCmd RenderEnable"));
       
   777 			TRAP(stat, iSoftCodec->ConfigureL(KUidConfig, reinterpret_cast<TDesC8&>(iRenderEnableConfig)));
       
   778 			break;
       
   779 		case EDisable:
       
   780 			DP0(_L("CAdvancedAudioDecoder::CodecCmd Disable"));
       
   781 			TRAP(stat, iSoftCodec->ConfigureL(KUidConfig, reinterpret_cast<TDesC8&>(iDisableConfig)));
       
   782 			break;
       
   783 		case EEnable:
       
   784 			DP0(_L("CAdvancedAudioDecoder::CodecCmd Enable"));
       
   785 			TRAP(stat, iSoftCodec->ConfigureL(KUidConfig, reinterpret_cast<TDesC8&>(iEnableConfig)));
       
   786 			break;
       
   787 		case EMarkPlayEnd:
       
   788 			DP0(_L("CAdvancedAudioDecoder::CodecCmd MarkPlayEnd"));
       
   789 			TRAP(stat, iSoftCodec->ConfigureL(KUidConfig, reinterpret_cast<TDesC8&>(iMarkPlayEndConfig)));
       
   790 			break;
       
   791 		case EUnMarkPlayEnd:
       
   792 			DP0(_L("CAdvancedAudioDecoder::CodecCmd UnMarkPlayEnd"));
       
   793 			TRAP(stat, iSoftCodec->ConfigureL(KUidConfig, reinterpret_cast<TDesC8&>(iUnMarkPlayEndConfig)));
       
   794 			break;
       
   795 		default:
       
   796 			break;	
       
   797 		}
       
   798 	return stat;	
       
   799 	}
       
   800 
       
   801 
       
   802 // End of file