mmfenh/enhancedmediaclient/Plugins/DataBufferSource/src/DataBufferSource.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:  S60 DataBuffer Data Source Plugin implementation
       
    15 *  Version     : %version: bh1mmcf#14.1.4 %
       
    16 *
       
    17 */
       
    18 
       
    19 #include "DataBufferDataSource.h"
       
    20 #include <mmf/server/mmfdatabuffer.h>
       
    21 #include "DataBufferSourceCustomCommands.h"
       
    22 #include "SourceQueueItem.h"
       
    23 #include "SinkQueueItem.h"
       
    24 #include "DataCopyEngineAO.h"
       
    25 #include "DataBufferSourceUid.h"
       
    26 #include <MultimediaDataSourceEvents.h>
       
    27 #include "DRMConfigIntfcImpl.h"
       
    28 #include <mmfdatasink.h>
       
    29 #include <mmfdatapath.h>
       
    30 #include "tracemacros.h"
       
    31 
       
    32 const TUint KMaxHeapForBuffering = 0x40000; // 256 KB (1 MB = default controller heap size).
       
    33 
       
    34 CDataBufferSource* CDataBufferSource::NewL(TUid aType )
       
    35     {
       
    36     EMC_TRACE1(_L("CDataBufferSource::NewL"));
       
    37     CDataBufferSource* self = new (ELeave) CDataBufferSource(aType);
       
    38     CleanupStack::PushL(self);
       
    39     self->ConstructL();
       
    40     CleanupStack::Pop(self);
       
    41     return self;
       
    42     }
       
    43 
       
    44 CDataBufferSource::CDataBufferSource(TUid aType)
       
    45 : MDataSource(aType)
       
    46     {
       
    47     }
       
    48 
       
    49 CDataBufferSource::~CDataBufferSource(void)
       
    50     {
       
    51     }
       
    52 
       
    53 void CDataBufferSource::ConstructL (void)
       
    54     {
       
    55     }
       
    56 
       
    57 // From MDataSource begins
       
    58 TUid CDataBufferSource::DataSourceType() const
       
    59     {
       
    60     return KMmfDataBufferSource;
       
    61     }
       
    62 
       
    63 
       
    64 TFourCC CDataBufferSource::SourceDataTypeCode(TMediaId /*aMediaId*/ )
       
    65     {
       
    66     TFourCC fourCC;        
       
    67     iMultiMediaSource->GetDataTypeCode(fourCC);
       
    68     return fourCC;
       
    69     }
       
    70 
       
    71 TInt CDataBufferSource::SetSourceDataTypeCode(TFourCC aSourceFourCC,
       
    72                                                   TMediaId /*aMediaId*/ )
       
    73     {
       
    74     iMultiMediaSource->SetDataTypeCode(aSourceFourCC);
       
    75     return KErrNone;
       
    76     }
       
    77 
       
    78 void CDataBufferSource::FillBufferL(CMMFBuffer* aBuffer,
       
    79                                         MDataSink* aConsumer,
       
    80                                         TMediaId /*aMediaId*/ )
       
    81     {
       
    82     User::LeaveIfError( iMultiMediaSource->ServiceFillBuffer( aBuffer, NULL, aConsumer ) );
       
    83     }
       
    84 
       
    85 void CDataBufferSource::BufferEmptiedL(CMMFBuffer* /*aBuffer*/ )
       
    86     {
       
    87     User::Leave(KErrUnknown);
       
    88     }
       
    89 
       
    90 TBool CDataBufferSource::CanCreateSourceBuffer()
       
    91     {
       
    92     return EFalse;
       
    93     }
       
    94 
       
    95 CMMFBuffer* CDataBufferSource::CreateSourceBufferL(TMediaId /*aMediaId*/,
       
    96                                                        TBool &/*aReference*/ )
       
    97     {
       
    98     /*    CMMFBuffer* newBuffer = 0; //dummy
       
    99     return newBuffer;
       
   100     */
       
   101     return NULL;
       
   102     }
       
   103 
       
   104 TInt CDataBufferSource::SourceThreadLogon( MAsyncEventHandler& /*aEventHandler*/ )
       
   105     {
       
   106     return iMultiMediaSource->Open();
       
   107     }
       
   108 
       
   109 void CDataBufferSource::SourceThreadLogoff()
       
   110     {
       
   111     iMultiMediaSource->Close();
       
   112     }
       
   113 
       
   114 void CDataBufferSource::SourcePrimeL()
       
   115     {
       
   116     EMC_TRACE1(_L("CDataBufferSource::SourcePrimeL"));
       
   117     User::LeaveIfError(iMultiMediaSource->Prime());
       
   118     }
       
   119 
       
   120 void CDataBufferSource::SourcePlayL()
       
   121     {
       
   122     EMC_TRACE1(_L("CDataBufferSource::SourcePlayL"));
       
   123     User::LeaveIfError(iMultiMediaSource->Play());
       
   124     }
       
   125 
       
   126 void CDataBufferSource::SourceStopL()
       
   127     {
       
   128     EMC_TRACE1(_L("CDataBufferSource::SourceStopL"));
       
   129     User::LeaveIfError(iMultiMediaSource->Stop());
       
   130     }
       
   131 
       
   132 
       
   133 void CDataBufferSource::ConstructSourceL(const TDesC8& /*aInitData*/ )
       
   134     {
       
   135     }
       
   136 
       
   137 void CDataBufferSource::SourceCustomCommand(TMMFMessage& aMessage)
       
   138     {
       
   139     iMultiMediaSource->SourceCustomCommand(aMessage);        
       
   140     }
       
   141 
       
   142 void CDataBufferSource::SetMultimediaSource(CDataBufferMultimediaSource& aMultimediaSource)
       
   143     {
       
   144     iMultiMediaSource = &aMultimediaSource;   
       
   145     }
       
   146 // From MDataSource begins
       
   147 
       
   148 // From CMultimediaDataSource begins
       
   149 
       
   150 EXPORT_C CDataBufferMultimediaSource* CDataBufferMultimediaSource::NewL(MDataSource& aDataSource)
       
   151     {
       
   152     EMC_TRACE1(_L("CDataBufferMultimediaSource::NewL"));
       
   153     CDataBufferMultimediaSource* self = new (ELeave) CDataBufferMultimediaSource(aDataSource);
       
   154     CleanupStack::PushL(self);
       
   155     self->ConstructL();
       
   156     CleanupStack::Pop(self);
       
   157     return self;
       
   158     }
       
   159 
       
   160 
       
   161 CDataBufferMultimediaSource::CDataBufferMultimediaSource(MDataSource& aDataSource)
       
   162 : iSrcItemsCount(0),
       
   163 iSnkItemsCount(0),
       
   164 iSrcBytes(0),
       
   165 iSnkBytes(0),
       
   166 iSizeBytes(0),
       
   167 iTransferRate(0),
       
   168 iBufferedDataSize(0),
       
   169 iLastBufferReceived(EFalse),
       
   170 iParentDataSource(&aDataSource)
       
   171     {
       
   172     // iState from Base
       
   173     iState = ECLOSED;
       
   174     iBufferingConfig.iType = TBufferingConfig::BUFFERINGNONE;
       
   175     iBufferingConfig.iAmount = 0;
       
   176     iMessage = NULL;
       
   177     }
       
   178 
       
   179 CDataBufferMultimediaSource::~CDataBufferMultimediaSource(void)
       
   180     {
       
   181     EMC_TRACE1(_L("CDataBufferMultimediaSource::~CDataBufferMultimediaSource"));
       
   182     
       
   183     // Cancel data copying
       
   184     if(iDataCopyEngineAO)
       
   185     	{
       
   186     	iDataCopyEngineAO->Cancel();
       
   187     	delete iDataCopyEngineAO;
       
   188     	}
       
   189     
       
   190     iState = ECLOSED;
       
   191     // Empty source queue
       
   192     EmptySourceQueue();
       
   193     delete iSourceQueue;
       
   194     EmptySinkQueue();
       
   195     // Empty sink queue
       
   196     delete iSinkQueue;
       
   197     iAllowedOutputDeviceList.Close();
       
   198     }
       
   199 
       
   200 void CDataBufferMultimediaSource::ConstructL (void)
       
   201     {
       
   202     static_cast<CDataBufferSource*>(iParentDataSource)->SetMultimediaSource(*this);
       
   203     iSourceQueue = new(ELeave) TSglQue<CSourceQueueItem>(_FOFF(CSourceQueueItem, iLink));
       
   204     iSinkQueue = new(ELeave) TSglQue<CSinkQueueItem>(_FOFF(CSinkQueueItem, iLink));
       
   205     iDataCopyEngineAO = CDataCopyEngineAO::NewL(iSourceQueue, iSinkQueue, *this);
       
   206     }
       
   207 
       
   208 
       
   209 TInt CDataBufferMultimediaSource::SetObserver( MMultimediaDataSourceObserver& aObserver )
       
   210     {
       
   211     TInt status(KErrNotReady);
       
   212     switch ( iState )
       
   213         {
       
   214         case ECLOSED:
       
   215             iObserver = &aObserver;
       
   216             status = KErrNone;
       
   217             break;
       
   218         case ESTOPPED:
       
   219         case EPRIMED:
       
   220         case EEXECUTING:
       
   221         case EBUFFERING:
       
   222         default:
       
   223             EMC_TRACE2(_L("CDataBufferMultimediaSource::SetObserver[Illegal cmd on state[%d]]"), iState );
       
   224             break;
       
   225         };
       
   226     return status;
       
   227     }
       
   228 
       
   229 TInt CDataBufferMultimediaSource::GetObserver( MMultimediaDataSourceObserver*& aObserver )
       
   230     {
       
   231     aObserver = iObserver;
       
   232     return KErrNone;
       
   233     }
       
   234 
       
   235 void CDataBufferMultimediaSource::Event( TUid aEvent )
       
   236     {
       
   237     if ( aEvent == KMultimediaDataSourceEventBitRateChanged )
       
   238         {
       
   239         if(iMessage)
       
   240             {
       
   241             if(!iMessage->IsCompleted())
       
   242                 {
       
   243                 iMessage->Complete(KErrNone);
       
   244                 delete iMessage;
       
   245                 iMessage = NULL;
       
   246                 }
       
   247             }
       
   248         }
       
   249     }
       
   250 
       
   251 TInt CDataBufferMultimediaSource::SetDataTypeCode(TFourCC aSourceFourCC )
       
   252     {
       
   253     TInt status(KErrNone);
       
   254     iSourceFourCC = aSourceFourCC;
       
   255     return status;
       
   256     }
       
   257 
       
   258 TInt CDataBufferMultimediaSource::GetDataTypeCode(TFourCC& aSourceFourCC )
       
   259     {
       
   260     TInt status(KErrNone);
       
   261     aSourceFourCC = iSourceFourCC;
       
   262     return status;
       
   263     }
       
   264 
       
   265 TInt CDataBufferMultimediaSource::GetSize( TUint& aSize )
       
   266     {
       
   267     TInt status(KErrNone);
       
   268     aSize = iSizeBytes;
       
   269     return status;
       
   270     }
       
   271 
       
   272 TInt CDataBufferMultimediaSource::Open()
       
   273     {
       
   274     TInt status(KErrNotReady);
       
   275     EMC_TRACE2(_L("CDataBufferSource::Open iState[%d]"),iState);
       
   276     switch ( iState )
       
   277         {
       
   278         case ECLOSED:
       
   279             iState = ESTOPPED;
       
   280             status = KErrNone;
       
   281             break;
       
   282         case ESTOPPED:
       
   283         case EPRIMED:
       
   284         case EEXECUTING:
       
   285         case EBUFFERING:
       
   286         default:
       
   287             status = KErrNone;
       
   288             EMC_TRACE2(_L("CDataBufferMultimediaSource::Open[Illegal cmd on state[%d]]"), iState );
       
   289             break;
       
   290         };
       
   291     return status;
       
   292     }
       
   293 
       
   294 TInt CDataBufferMultimediaSource::Close()
       
   295     {
       
   296     TInt status(KErrNone);
       
   297     EMC_TRACE2(_L("CDataBufferSource::Close iState[%d]"),iState);
       
   298     iState = ECLOSED;
       
   299     // Clear app buffers
       
   300     EmptySinkQueue();
       
   301     iSnkBytes = 0;
       
   302     // Clear observer buffers
       
   303     EmptySourceQueue();
       
   304     iSrcBytes = 0;
       
   305     return status;
       
   306     }
       
   307 
       
   308 TInt CDataBufferMultimediaSource::Prime()
       
   309     {
       
   310     TInt status(KErrNotReady);
       
   311     EMC_TRACE2(_L("CDataBufferSource::Prime iState[%d]"),iState);
       
   312     switch ( iState )
       
   313         {
       
   314         case ESTOPPED:
       
   315             iState = EPRIMED;
       
   316             status = KErrNone;
       
   317             break;
       
   318         case EPRIMED:
       
   319             // Clear observer buffers
       
   320             EmptySinkQueue();
       
   321             iSnkBytes = 0;
       
   322             status = KErrNone;
       
   323             break;
       
   324         case ECLOSED:
       
   325         case EEXECUTING:
       
   326         case EBUFFERING:
       
   327         default:
       
   328             EMC_TRACE2(_L("CDataBufferMultimediaSource::Prime[Illegal cmd on state[%d]]"), iState );
       
   329             break;
       
   330         };
       
   331     return status;
       
   332     }
       
   333 
       
   334 TInt CDataBufferMultimediaSource::Play()
       
   335     {
       
   336     TInt status(KErrNotReady);
       
   337     EMC_TRACE2(_L("CDataBufferSource::Play iState[%d]"),iState); 
       
   338     switch ( iState )
       
   339         {
       
   340         case EPRIMED:
       
   341             iState = EEXECUTING;
       
   342             iDataCopyEngineAO->Start();
       
   343             status = KErrNone;
       
   344             break;
       
   345         case EEXECUTING:
       
   346         case EBUFFERING:
       
   347             // No op
       
   348             status = KErrNone;
       
   349             break;
       
   350         case ECLOSED:
       
   351         case ESTOPPED:
       
   352         default:
       
   353             EMC_TRACE2(_L("CDataBufferMultimediaSource::Play[Illegal cmd on state[%d]]"), iState );
       
   354             break;
       
   355         };
       
   356     return status;
       
   357     }
       
   358 
       
   359 TInt CDataBufferMultimediaSource::Stop()
       
   360     {
       
   361     TInt status(KErrNotReady);
       
   362     EMC_TRACE2(_L("CDataBufferSource::Stop iState[%d]"),iState); 
       
   363     switch ( iState )
       
   364         {
       
   365         case EPRIMED:
       
   366         case EEXECUTING:
       
   367         case EBUFFERING:
       
   368             iState = ESTOPPED;
       
   369             
       
   370             // Stop data copy engine
       
   371             iDataCopyEngineAO->Stop();
       
   372 
       
   373             // Clear observer buffers
       
   374             status = EmptySourceQueue();
       
   375             iSrcBytes = 0;
       
   376             iLastBufferReceived = EFalse;
       
   377             
       
   378             // Clear app buffers
       
   379             status = EmptySinkQueue();
       
   380             iSnkBytes = 0;
       
   381             
       
   382             status = KErrNone;
       
   383             break;
       
   384         case ESTOPPED:
       
   385 
       
   386             // Stop data copy engine
       
   387             iDataCopyEngineAO->Stop();
       
   388 
       
   389             // Clear user buffers
       
   390             status = EmptySourceQueue();
       
   391             iSrcBytes = 0;
       
   392             iLastBufferReceived = EFalse;
       
   393             break;
       
   394         case ECLOSED:
       
   395         default:
       
   396             EMC_TRACE2(_L("CDataBufferMultimediaSource::Stop[Illegal cmd on state[%d]]"), iState );
       
   397             break;
       
   398         };
       
   399     return status;
       
   400     }
       
   401 
       
   402 TInt CDataBufferMultimediaSource::FillBuffer( CMMFBuffer* aBuffer )
       
   403     {
       
   404     return ServiceFillBuffer( aBuffer, iObserver, NULL );
       
   405     }
       
   406 
       
   407 TInt CDataBufferMultimediaSource::GetInterface(
       
   408         TUid aInterfaceId,
       
   409         TVersion& aVer,
       
   410         TAny*& aInterfaceImpl )
       
   411     {
       
   412     TInt status(KErrNotFound);
       
   413     aInterfaceImpl = NULL;
       
   414     if ( ( aInterfaceId == KDRMConfigIntfc ) &&
       
   415          ( ( aVer.iMajor == KDRMConfigIntfcMajorVer1 ) &&
       
   416            ( aVer.iMinor == KDRMConfigIntfcMinorVer1 ) &&
       
   417            ( aVer.iBuild == KDRMConfigIntfcBuildVer1 ) ) )
       
   418             {
       
   419             CDRMConfigIntcfImpl* temp(NULL);
       
   420             TRAP(status, temp = CDRMConfigIntcfImpl::NewL(*this));
       
   421             if ( status == KErrNone )
       
   422                 {
       
   423                 this->SetChild(*((CChildIntfc*)temp));
       
   424                 temp->SetParent(*(CParentIntfc*)this);
       
   425                 aInterfaceImpl = (CDRMConfigIntfc*)temp;
       
   426                 }
       
   427             }
       
   428     return status;
       
   429     }
       
   430 
       
   431 TAny* CDataBufferMultimediaSource::CustomInterface( TUid /*aInterfaceUid*/ )
       
   432     {
       
   433     return NULL;
       
   434     }
       
   435 
       
   436 
       
   437 // From CMultimediaDataSource ends
       
   438 
       
   439 // From MDataCopyEngineObserver begins
       
   440 void CDataBufferMultimediaSource::SourceQueueItemProcessed()
       
   441     {
       
   442     iSrcItemsCount--;
       
   443     EMC_TRACE2(_L("CDataBufferMultimediaSource::SourceQueueItemProcessed[SrcItemsCount(%d)]"), iSrcItemsCount);
       
   444     
       
   445     CSourceQueueItem* srcItem = iSourceQueue->First();
       
   446     iSourceQueue->Remove(*srcItem);
       
   447     srcItem->CompleteMessage(KErrNone);
       
   448     delete srcItem;
       
   449     }
       
   450 
       
   451 void CDataBufferMultimediaSource::SinkQueueItemProcessed()
       
   452     {
       
   453     iSnkItemsCount--;
       
   454     
       
   455     CSinkQueueItem* item = iSinkQueue->First();
       
   456     iSinkQueue->Remove(*item);
       
   457     iSnkBytes += item->Buffer()->Data().Length();
       
   458     EMC_TRACE3(_L("CDataBufferMultimediaSource::SinkQueueItemProcessed[Src[%d]B. Snk[%d]B]"), iSrcBytes, iSnkBytes);
       
   459     
       
   460     // If this is the last buffer being sent to the controller
       
   461     // empty the rest of the items in the sink queue
       
   462     if ( item->Buffer()->LastBuffer() )
       
   463         {
       
   464         EMC_TRACE1(_L("CDataBufferMultimediaSource::SinkQueueItemProcessed[LASTBUFFER]"));
       
   465         CSinkQueueItem* tempItem;
       
   466         while ( !iSinkQueue->IsEmpty() )
       
   467             {
       
   468             tempItem = iSinkQueue->First();
       
   469             iSinkQueue->Remove(*tempItem);
       
   470             delete tempItem;
       
   471             iSnkItemsCount--;
       
   472             }
       
   473         iSnkBytes = 0;
       
   474         
       
   475         iState = ESTOPPED;
       
   476         iSrcBytes = 0;
       
   477         }
       
   478     // Signal the controller, based on which FillBuffer API was called,
       
   479     // make the appriopriate callback.
       
   480     if ( item->Observer() )
       
   481         {
       
   482         item->Observer()->BufferFilled(item->Buffer());
       
   483         }
       
   484     else
       
   485         {
       
   486         TRAP_IGNORE(item->Consumer()->BufferFilledL(item->Buffer()));
       
   487         }
       
   488     delete item;
       
   489     }
       
   490 // From MDataCopyEngineObserver ends
       
   491 
       
   492 // To be called by DRMConfig Interface begins
       
   493 TInt CDataBufferMultimediaSource::GetDRMType( TDRMType& aDRMType )
       
   494     {
       
   495     TInt status(KErrNotReady);
       
   496     switch ( iState )
       
   497         {
       
   498         case EPRIMED:
       
   499         case EEXECUTING:
       
   500         case EBUFFERING:
       
   501             aDRMType = iDRMType;
       
   502             status = KErrNone;
       
   503             break;
       
   504         case ECLOSED:
       
   505         case ESTOPPED:
       
   506         default:
       
   507             EMC_TRACE2(_L("CDataBufferMultimediaSource::GetDRMType[Illegal cmd on state[%d]]"), iState );
       
   508             break;
       
   509         };
       
   510     return status;
       
   511     }
       
   512 
       
   513 TInt CDataBufferMultimediaSource::GetAllowedOutputDeviceCount( TInt& aCount )
       
   514     {
       
   515     TInt status(KErrNotReady);
       
   516     switch ( iState )
       
   517         {
       
   518         case EPRIMED:
       
   519         case EEXECUTING:
       
   520         case EBUFFERING:
       
   521             aCount = iAllowedOutputDeviceList.Count();
       
   522             status = KErrNone;
       
   523             break;
       
   524         case ECLOSED:
       
   525         case ESTOPPED:
       
   526         default:
       
   527             EMC_TRACE2(_L("CDataBufferMultimediaSource::GetDRMType[Illegal cmd on state[%d]]"), iState );
       
   528             break;
       
   529         };
       
   530     return status;
       
   531     }
       
   532 
       
   533 TInt CDataBufferMultimediaSource::GetAllowedOutputDevice(
       
   534                 TInt aIndex,
       
   535                 TDRMAllowedOutputDevice& aOutputDevice )
       
   536     {
       
   537     TInt status(KErrNotReady);
       
   538     switch ( iState )
       
   539         {
       
   540         case EPRIMED:
       
   541         case EEXECUTING:
       
   542         case EBUFFERING:
       
   543             status = KErrArgument;
       
   544             if ( (0 <= aIndex ) && ( aIndex < iAllowedOutputDeviceList.Count() ) )
       
   545                 {
       
   546                 aOutputDevice = iAllowedOutputDeviceList[aIndex];
       
   547                 status = KErrNone;
       
   548                 }
       
   549             break;
       
   550         case ECLOSED:
       
   551         case ESTOPPED:
       
   552         default:
       
   553             EMC_TRACE2(_L("CDataBufferMultimediaSource::GetDRMType[Illegal cmd on state[%d]]"), iState );
       
   554             break;
       
   555         };
       
   556     return status;
       
   557     }
       
   558 // To be called by DRMConfig Interface ends
       
   559 
       
   560 void CDataBufferMultimediaSource::SourceCustomCommand(TMMFMessage& aMessage)
       
   561     {
       
   562     TInt err(KErrNone);
       
   563     EMC_TRACE1(_L("CDataBufferMultimediaSource::SourceCustomCommand "));
       
   564     switch ( aMessage.Function() )
       
   565         {
       
   566         case EProcessBuffer:
       
   567             {
       
   568             CSourceQueueItem* item = NULL;
       
   569             TRAPD(err, item = CSourceQueueItem::NewL(aMessage));
       
   570             if (err == KErrNone)
       
   571                 {
       
   572                 iSourceQueue->AddLast(*item);
       
   573                 iSrcItemsCount++;
       
   574                 iSrcBytes += item->DataSize();
       
   575                 EMC_TRACE6(_L("EProcessBuffer>State[%d] Src[%d]B Snk[%d]B] LB[%d] SeqNum[%d]"), \
       
   576                     iState, iSrcBytes, iSnkBytes, item->IsLastBuffer(), item->GetBufferSequenceNumber());
       
   577                 
       
   578                 iLastBufferReceived = item->IsLastBuffer();
       
   579                 
       
   580                 // If we are in EBUFFERING state, check if source can transition
       
   581                 // to EEXECUTING state
       
   582                 if ( ( iState == EBUFFERING ) && 
       
   583                     ( ( ( iSrcBytes - iSnkBytes ) >= iBufferedDataSize ) || ( iLastBufferReceived ) ) )
       
   584                     {
       
   585                     iState = EEXECUTING;
       
   586                     // Signal to start copy AO
       
   587                     iDataCopyEngineAO->Start();
       
   588                     }
       
   589                 else
       
   590                     {
       
   591                     iDataCopyEngineAO->SourceQueueChanged();
       
   592                     }
       
   593 
       
   594                 }
       
   595             }
       
   596             break;
       
   597             
       
   598         case ECancel:
       
   599             {
       
   600             EMC_TRACE1(_L("EProcessBuffer>Cancel"));
       
   601             err = DoHandleCancel( aMessage );
       
   602             }
       
   603             break;
       
   604             
       
   605         case ESetSize:
       
   606             {
       
   607             // Read size info
       
   608             TPckgBuf<TInt> sizePckg;
       
   609             err = aMessage.ReadData1FromClient(sizePckg);
       
   610             if ( err == KErrNone )
       
   611                 {
       
   612                 iSizeBytes = sizePckg();
       
   613                 EMC_TRACE2(_L("ESetSize>SizeSet[%d] Bytes"), iSizeBytes);
       
   614                 // The message is handled completely.
       
   615                 aMessage.Complete(KErrNone);
       
   616                 
       
   617                 // Signal the observer that there is a new size changed event.
       
   618                 if ( iObserver )
       
   619                     {
       
   620                     iObserver->Event(KMultimediaDataSourceObserverEventSourceSizeChanged);
       
   621                     }
       
   622                 }
       
   623             // If we are in EBUFFERING state, re-calculate iBufferedDataSize,
       
   624             // check if source can transition to EEXECUTING state
       
   625             }
       
   626             break;
       
   627         
       
   628         case EGetCurrentBufferingConfig :
       
   629             {
       
   630             TPckgBuf<TBufferingConfig> sizePckg;	 
       
   631             EMC_TRACE3(_L("EGetCurrentBufferingConfig>BufType[%d] BufAmt[%d]Bytes"), \
       
   632                     iBufferingConfig.iType, iBufferingConfig.iAmount);
       
   633             sizePckg() = iBufferingConfig ;	
       
   634             aMessage.WriteDataToClient(sizePckg);
       
   635             aMessage.Complete(KErrNone);
       
   636             }
       
   637             break;
       
   638         
       
   639         case ESetBufferingConfig:
       
   640             {
       
   641             // Read size info
       
   642             TPckgBuf<TBufferingConfig> sizePckg;
       
   643             err = aMessage.ReadData1FromClient(sizePckg);
       
   644             if ( err == KErrNone )
       
   645                 {
       
   646                 iBufferingConfig = sizePckg();
       
   647                 EMC_TRACE3(_L("ESetBufferingConfig>BufType[%d] BufAmt[%d]Bytes"), \
       
   648                         iBufferingConfig.iType, iBufferingConfig.iAmount);
       
   649                 // The message is handled completely.
       
   650                 aMessage.Complete(KErrNone);
       
   651                 }
       
   652             }
       
   653             break;
       
   654         
       
   655         case EGetBitRate:
       
   656             {
       
   657             TPckgBuf<TUint> bitRatePckg;
       
   658             EMC_TRACE2(_L("EGetBitRate>[%d]"), iObserverBitRate);
       
   659             bitRatePckg() = iObserverBitRate ;	
       
   660             aMessage.WriteDataToClient(bitRatePckg);
       
   661             aMessage.Complete(KErrNone);
       
   662             }
       
   663             break;         
       
   664 
       
   665         case EGetBufferingConfigSupported:
       
   666             {
       
   667 			if(iObserverBitRate)
       
   668 				{
       
   669 				aMessage.Complete(KErrNone);
       
   670 				}
       
   671 			else
       
   672 				{
       
   673 				iMessage = new(ELeave) TMMFMessage(aMessage);
       
   674 				}
       
   675             }
       
   676             break;    
       
   677 
       
   678         case ESetDRMConfig:
       
   679             // Need to complete the message in this function
       
   680             // and return KErrNone
       
   681             err = HandleSetDRMConfig(aMessage);
       
   682             break;
       
   683         default:
       
   684             err = KErrArgument;
       
   685             break;
       
   686         };
       
   687     
       
   688     // If any error
       
   689     if (err != KErrNone)
       
   690         {
       
   691         EMC_TRACE2(_L("CDataBufferMultimediaSource::SourceCustomCommand:Completing message with error[%d]"), err);
       
   692         aMessage.Complete(err);
       
   693         }
       
   694     }
       
   695 
       
   696 
       
   697 TInt CDataBufferMultimediaSource::ServiceFillBuffer( CMMFBuffer* aBuffer,
       
   698                                               MMultimediaDataSourceObserver* aObserver,
       
   699                                               MDataSink* aConsumer )
       
   700     {
       
   701     TInt status(KErrNotReady);
       
   702     switch ( iState )
       
   703         {
       
   704         case EPRIMED:
       
   705         case EBUFFERING:
       
   706             {
       
   707             status = AppendBufferToSinkQueue( aBuffer, aObserver, aConsumer );
       
   708             }
       
   709             break;
       
   710         case EEXECUTING:
       
   711             {
       
   712             status = AppendBufferToSinkQueue( aBuffer, aObserver, aConsumer );
       
   713             
       
   714             if ( status == KErrNone )
       
   715                 {
       
   716                 // If not enough data, determine buffered data size, pause
       
   717                 // data copy engine AO and move to EBUFFERING state.
       
   718                 if ( !iLastBufferReceived && ( ( iSrcBytes - iSnkBytes ) < ( aBuffer->RequestSize() ) ) )
       
   719                     {
       
   720                     CalculateBufferdDataSize();
       
   721                     
       
   722                     if(iBufferedDataSize > 0)
       
   723                         {
       
   724                         iDataCopyEngineAO->Pause();
       
   725                         iState = EBUFFERING;
       
   726                         }
       
   727                     else
       
   728                         {
       
   729                         iDataCopyEngineAO->SinkQueueChanged();
       
   730                         }          
       
   731                     }
       
   732                 else
       
   733                     {
       
   734                     iDataCopyEngineAO->SinkQueueChanged();
       
   735                     }
       
   736                 }
       
   737             }
       
   738             break;
       
   739             
       
   740         case ECLOSED:
       
   741         case ESTOPPED:
       
   742             status = KErrNone;
       
   743             break;
       
   744         default:
       
   745             EMC_TRACE2(_L("CDataBufferMultimediaSource::ServiceFillBuffer[Illegal cmd on state[%d]]"), iState );
       
   746             break;
       
   747         };
       
   748     return status;
       
   749     }
       
   750 
       
   751 TInt CDataBufferMultimediaSource::AppendBufferToSinkQueue( CMMFBuffer* aBuffer,
       
   752                                                     MMultimediaDataSourceObserver* aObserver,
       
   753                                                     MDataSink* aConsumer )
       
   754     {
       
   755     TInt status(KErrNone);
       
   756     // Add observer buffer to queue
       
   757     CMMFDataBuffer* dest = static_cast<CMMFDataBuffer*>( aBuffer );
       
   758     TDes8& destBufferDes = dest->Data();
       
   759     
       
   760     CSinkQueueItem* request(NULL);
       
   761     
       
   762     TRAP( status, request = CSinkQueueItem::NewL( aBuffer, aObserver, aConsumer ) );
       
   763     if ( status == KErrNone )
       
   764         {
       
   765         iSinkQueue->AddLast(*request);
       
   766         iSnkItemsCount++;
       
   767         
       
   768         EMC_TRACE5(_L("CDataBufferMultimediaSource::AppendBufferToQueue[ReqSize[%d]SrcItems[%d]SnkItems[%d]]Avail[%d]B"), \
       
   769             aBuffer->RequestSize(), iSrcItemsCount, iSnkItemsCount, (iSrcBytes - iSnkBytes) );
       
   770         }
       
   771     return status;
       
   772     }
       
   773 
       
   774 TInt CDataBufferMultimediaSource::EmptySourceQueue()
       
   775     {
       
   776     TInt status(KErrNone);
       
   777     // Complete and empty source queue
       
   778     EMC_TRACE2(_L("CDataBufferSource::EmptySourceQueue() iState[%d]"),iState); 
       
   779     CSourceQueueItem* srcItem;
       
   780     while ( !iSourceQueue->IsEmpty() )
       
   781         {
       
   782         srcItem = iSourceQueue->First();
       
   783         iSourceQueue->Remove(*srcItem);
       
   784         srcItem->CompleteMessage(KErrCancel);
       
   785         delete srcItem;
       
   786         }
       
   787     iSrcItemsCount = 0;
       
   788     return status;
       
   789     }
       
   790 
       
   791 TInt CDataBufferMultimediaSource::EmptySinkQueue()
       
   792     {
       
   793     TInt status(KErrNone);
       
   794     // Empty sink queue
       
   795     EMC_TRACE2(_L("CDataBufferSource::EmptySinkQueue() iState[%d]"),iState); 
       
   796     CSinkQueueItem* snkItem;
       
   797     while ( !iSinkQueue->IsEmpty() )
       
   798         {
       
   799         snkItem = iSinkQueue->First();
       
   800         iSinkQueue->Remove(*snkItem);
       
   801         delete snkItem;
       
   802         }
       
   803     
       
   804     iSnkItemsCount = 0;
       
   805     return status;
       
   806     }
       
   807 
       
   808 void CDataBufferMultimediaSource::CalculateBufferdDataSize()
       
   809     {
       
   810     iBufferedDataSize = 0;
       
   811     EMC_TRACE2(_L("CDataBufferSource::CalculateBufferdDataSize() iState[%d]"),iState);     
       
   812     // Get the bit rate from observer
       
   813     iObserver->GetBitRate( iObserverBitRate );
       
   814     
       
   815     // If we don't know observer bit rate
       
   816     if ((iObserverBitRate == 0 ) && (!iSinkQueue->First()) )
       
   817         {// Just buffer until the observer buffer can be filled
       
   818         iBufferedDataSize = iSinkQueue->First()->Buffer()->RequestSize();
       
   819         }
       
   820     else
       
   821         {
       
   822         if(iBufferingConfig.iType == TBufferingConfig::BUFFERINGNONE)
       
   823             {
       
   824                 iBufferedDataSize = 0;
       
   825             }
       
   826         else if ( iBufferingConfig.iType == TBufferingConfig::FIXEDSIZE)
       
   827             {
       
   828                 iBufferedDataSize = iBufferingConfig.iAmount;
       
   829             }
       
   830         else
       
   831             {
       
   832                 iBufferedDataSize = (iBufferingConfig.iAmount * iObserverBitRate) / 8;
       
   833             }            
       
   834         }
       
   835     
       
   836     // In case of streaming make sure this doesn't exceed the heap memory
       
   837     iBufferedDataSize = iBufferedDataSize > KMaxHeapForBuffering ? KMaxHeapForBuffering : iBufferedDataSize;
       
   838     EMC_TRACE2(_L("CDataBufferMultimediaSource::CalculateBufferdDataSize[%d]"), iBufferedDataSize );
       
   839     }
       
   840 
       
   841 TInt CDataBufferMultimediaSource::HandleSetDRMConfig(  TMMFMessage& aMessage )
       
   842     {
       
   843     TInt status(KErrNone);
       
   844     TRAP(status, DoSetDRMConfigL( aMessage ));
       
   845     EMC_TRACE2(_L("CDataBufferMultimediaSource::HandleSetDRMConfig[%d]"), status );
       
   846     aMessage.Complete(status);
       
   847     return status;
       
   848     }
       
   849 
       
   850 void CDataBufferMultimediaSource::DoSetDRMConfigL( TMMFMessage& aMessage )
       
   851     {
       
   852     switch ( iState )
       
   853         {
       
   854         case ECLOSED:
       
   855         case ESTOPPED:
       
   856             {
       
   857             // Create buffer to hold data
       
   858             HBufC8* buf = HBufC8::NewLC( aMessage.SizeOfData1FromClient() );
       
   859             TPtr8 ptr = buf->Des();
       
   860 
       
   861             // Read data from client.
       
   862             aMessage.ReadData1FromClientL( ptr );
       
   863         
       
   864            	RDesReadStream stream(ptr);
       
   865             CleanupClosePushL(stream);
       
   866             
       
   867             // Get DRM Type
       
   868             iDRMType = (TDRMType)stream.ReadInt32L();
       
   869             // Get Allowed Output Device Count
       
   870             TInt count = stream.ReadInt32L();
       
   871             // Get Allowed Output Device items
       
   872             iAllowedOutputDeviceList.Reset(); // If any
       
   873            	for (TInt i=0; i<count; i++)
       
   874               	{
       
   875            		iAllowedOutputDeviceList.Append((TDRMAllowedOutputDevice)stream.ReadInt32L());
       
   876            		}
       
   877            	CleanupStack::PopAndDestroy(&stream);
       
   878            	CleanupStack::PopAndDestroy(buf);
       
   879             }
       
   880             break;
       
   881 
       
   882         case EPRIMED:
       
   883         case EEXECUTING:
       
   884         case EBUFFERING:
       
   885         default:
       
   886             EMC_TRACE2(_L("CDataBufferMultimediaSource::DoSetDRMConfigL[Illegal cmd on state[%d]]"), iState );
       
   887             User::Leave(KErrNotReady);
       
   888             break;
       
   889         };
       
   890     }
       
   891 
       
   892 TInt CDataBufferMultimediaSource::DoHandleCancel( TMMFMessage& aMessage )
       
   893     {
       
   894     TInt status(KErrNone);
       
   895     TPckgBuf<TUint> bufSeqPckg;
       
   896     status = aMessage.ReadData1FromClient(bufSeqPckg);            
       
   897     if ( status == KErrNone )
       
   898         {
       
   899         CSourceQueueItem* item (NULL);
       
   900         TSglQueIter<CSourceQueueItem> itemIter(*iSourceQueue);
       
   901         while ( (item = itemIter++) != NULL )
       
   902             {
       
   903             if ( item->GetBufferSequenceNumber() == bufSeqPckg() )
       
   904                 { // We found what we are looking for
       
   905                 break; // from while ( item != NULL )
       
   906                 }
       
   907             }
       
   908         // If we have the item we are looking for
       
   909         if ( item != NULL )
       
   910             {
       
   911             aMessage.Complete( KErrNone );
       
   912             iSourceQueue->Remove(*item);
       
   913             item->CompleteMessage(KErrCancel);
       
   914             delete item;
       
   915             }
       
   916         else
       
   917             {
       
   918             aMessage.Complete( KErrNotFound );
       
   919             }
       
   920         }
       
   921     return status;
       
   922     }
       
   923 
       
   924 TInt CDataBufferMultimediaSource::EvaluateIntent( ContentAccess::TIntent /*aIntent*/ )
       
   925     {
       
   926     return KErrNone;
       
   927     }
       
   928 
       
   929 TInt CDataBufferMultimediaSource::ExecuteIntent( ContentAccess::TIntent /*aIntent*/ )
       
   930     {
       
   931     return KErrNone;
       
   932     }
       
   933 
       
   934 // End of file