mmfenh/enhancedmediaclient/Plugins/CacheSource/src/CacheSource.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 Cache Data Source Plugin implementation
       
    15 *
       
    16 */
       
    17 
       
    18 #include "CacheSource.h"
       
    19 #include "SinkQueueItem.h"
       
    20 #include "CacheSourceUid.h"
       
    21 #include <MultimediaDataSourceEvents.h>
       
    22 #include "ReadWriteRequestAO.h"
       
    23 #include <mmfdatabuffer.h>
       
    24 
       
    25 #ifdef _DEBUG
       
    26 #define DEBPRN1(str)        RDebug::Print(str);
       
    27 #define DEBPRN2(str, val1)   RDebug::Print(str, val1);
       
    28 #define DEBPRN3(str, val1, val2)   RDebug::Print(str, val1, val2);
       
    29 #define DEBPRN4(str, val1, val2, val3)   RDebug::Print(str, val1, val2, val3);
       
    30 #define DEBPRN5(str, val1, val2, val3, val4)   RDebug::Print(str, val1, val2, val3, val4);
       
    31 #else
       
    32 #define DEBPRN1(str)
       
    33 #define DEBPRN2(str, val1)
       
    34 #define DEBPRN3(str, val1, val2)
       
    35 #define DEBPRN4(str, val1, val2, val3)
       
    36 #define DEBPRN5(str, val1, val2, val3, val4)
       
    37 #endif // _DEBUG
       
    38 
       
    39 
       
    40 const TUint KTransferBufferSize = 8192;
       
    41 
       
    42 EXPORT_C CCacheSource* CCacheSource::NewL(CMultimediaDataSource* aDataSource, CDataSourceConfigIntfc* aDataSourceConfig )
       
    43     {
       
    44     DEBPRN1(_L("CCacheSource::NewL"));
       
    45     CCacheSource* self = new (ELeave) CCacheSource(aDataSource,aDataSourceConfig);
       
    46     CleanupStack::PushL(self);
       
    47     self->ConstructL();
       
    48     CleanupStack::Pop(self);
       
    49     return self;
       
    50     }
       
    51 
       
    52 CCacheSource::CCacheSource(CMultimediaDataSource* aDataSource,CDataSourceConfigIntfc* aDataSourceConfig )
       
    53 : iDataSource(aDataSource),iDataSourceConfig(aDataSourceConfig)
       
    54     {
       
    55     // iState from Base
       
    56     iState = ECLOSED;
       
    57     iFileSize = 0;
       
    58     iLastBufferWritten = false;
       
    59     iAbsBufferStart = 0;
       
    60     iAbsBufferEnd = 0;
       
    61     iBufferReadPos = 0;
       
    62     iSeekStart = 0;
       
    63     iSeekEnd = 0;
       
    64     iSnkBytes = 0;
       
    65     iDataBuffer = NULL;
       
    66     iCacheLocation = NULL;
       
    67     }
       
    68 
       
    69 CCacheSource::~CCacheSource()
       
    70     {
       
    71     DEBPRN1(_L("CCacheSource::~CCacheSource"));
       
    72     iState = ECLOSED;
       
    73     EmptySinkQueue();
       
    74     // Empty sink queue
       
    75     delete iSinkQueue;
       
    76     delete iDataSourceObserver;
       
    77     delete iTransferBuffer;
       
    78     delete iReadRequest;
       
    79     delete iWriteRequest;
       
    80     delete iDataSource;
       
    81     
       
    82     if(iCacheType == CDataSourceConfigIntfc::EFILE)
       
    83         {
       
    84         if(iCacheLocation)
       
    85             {
       
    86             delete iCacheLocation;    
       
    87             }
       
    88         iFile.Close();
       
    89         iFs.Delete(iFileName);
       
    90         iFs.Close();
       
    91         }
       
    92     else
       
    93         {
       
    94         delete iDataBuffer;
       
    95         }        
       
    96     }
       
    97 
       
    98 void CCacheSource::ConstructL (void)
       
    99     {
       
   100     DEBPRN1(_L("CCacheSource::ConstructL ENTER"));
       
   101     iSinkQueue = new(ELeave) TSglQue<CSinkQueueItem>(_FOFF(CSinkQueueItem, iLink));
       
   102     iDataSourceObserver = CMDataSourceObserver::NewL(iDataSource,this);
       
   103     iTransferBuffer = CMMFDataBuffer::NewL(KTransferBufferSize);
       
   104     iTransferBuffer->SetRequestSizeL(KTransferBufferSize);
       
   105     iWriteRequest = CReadWriteRequestAO::NewL(*this,CReadWriteRequestAO::EWriteRequest);
       
   106     iWriteRequest->SetBuffer(iTransferBuffer);
       
   107     iReadRequest = CReadWriteRequestAO::NewL(*this,CReadWriteRequestAO::EReadRequest);
       
   108     iReadRequest->SetBuffer(iTransferBuffer);
       
   109     iDataSourceConfig->GetCacheType(iCacheType);
       
   110     DEBPRN1(_L("CCacheSource::ConstructL EXIT"));        
       
   111     }
       
   112 
       
   113 
       
   114 
       
   115 // From CMultimediaDataSource begins
       
   116 TInt CCacheSource::SetObserver( MMultimediaDataSourceObserver& aObserver )
       
   117     {
       
   118     TInt status(KErrNone);    
       
   119     iObserver = &aObserver;
       
   120     return status;
       
   121     }
       
   122 
       
   123 TInt CCacheSource::GetObserver( MMultimediaDataSourceObserver*& aObserver )
       
   124     {
       
   125     aObserver = iObserver;
       
   126     return KErrNone;
       
   127     }
       
   128 
       
   129 void CCacheSource::Event( TUid aEvent )
       
   130     {
       
   131     // CAll the Parent DataSource
       
   132     iDataSource->Event(aEvent);
       
   133     }
       
   134 
       
   135 TInt CCacheSource::SetDataTypeCode(TFourCC aSourceFourCC )
       
   136     {
       
   137     TInt status(KErrNone);
       
   138     status = iDataSource->SetDataTypeCode(aSourceFourCC);
       
   139     return status;
       
   140     }
       
   141 
       
   142 TInt CCacheSource::GetDataTypeCode(TFourCC& aSourceFourCC )
       
   143     {
       
   144     TInt status(KErrNone);
       
   145     status = iDataSource->GetDataTypeCode(aSourceFourCC);
       
   146     return status;
       
   147     }
       
   148 
       
   149 TInt CCacheSource::GetSize( TUint& aSize )
       
   150     {
       
   151     TInt status(KErrNone);
       
   152     status = iDataSource->GetSize(aSize);
       
   153     return status;
       
   154     }
       
   155 
       
   156 TInt CCacheSource::Open()
       
   157     {
       
   158     TInt status(KErrNone);
       
   159     DEBPRN1(_L("CCacheSource::Open"));                 
       
   160     status = iDataSource->Open();
       
   161     return status;
       
   162     }
       
   163 
       
   164 TInt CCacheSource::Close()
       
   165     {
       
   166     TInt status(KErrNone);
       
   167     DEBPRN1(_L("CCacheSource::Close"));                 
       
   168     status = iDataSource->Close();
       
   169     return status;
       
   170     }
       
   171 
       
   172 TInt CCacheSource::Prime()
       
   173     {
       
   174     TInt status(KErrNone);
       
   175     DEBPRN1(_L("CCacheSource::Prime"));             
       
   176     status = iDataSource->Prime();
       
   177 
       
   178     iDataSourceConfig->GetCacheType(iCacheType);
       
   179     if(iCacheType == CDataSourceConfigIntfc::EFILE)
       
   180         {
       
   181 	    status = iFs.Connect();
       
   182 	    if(status == KErrNone)
       
   183 	        {
       
   184 	        	if(iCacheLocation)
       
   185 	            {
       
   186 	            delete iCacheLocation;
       
   187 	            iCacheLocation = NULL;                
       
   188 	            }
       
   189 	        iCacheLocation = HBufC16::NewL(KMaxFileName);
       
   190 	        TPtr des = iCacheLocation->Des();
       
   191 	        iDataSourceConfig->GetCacheLocation(des);
       
   192 	
       
   193 	        TInt err = iFile.Temp(iFs,des,iFileName,EFileWrite);
       
   194 			status = err;
       
   195 			}
       
   196         }
       
   197     else
       
   198         {
       
   199         TUint cacheSize = 0;
       
   200         iDataSourceConfig->GetCacheSize(cacheSize);            
       
   201         
       
   202         if(iDataBuffer)
       
   203             {
       
   204             delete iDataBuffer;
       
   205             iDataBuffer = NULL;            
       
   206             }
       
   207         TRAP(status,iDataBuffer = CMMFDataBuffer::NewL( cacheSize ));
       
   208         if(status == KErrNone)
       
   209         	{
       
   210         	iDataBuffer->Data().SetLength(cacheSize);
       
   211         	}
       
   212         }        
       
   213 
       
   214     //status = iDataSource->FillBuffer(iTransferBuffer);
       
   215     return status;
       
   216     }
       
   217 
       
   218 TInt CCacheSource::Play()
       
   219     {
       
   220      TInt status(KErrNone);
       
   221     DEBPRN1(_L("CCacheSource::Play"));         
       
   222     status = iDataSource->Play();
       
   223     return status;
       
   224     }
       
   225 
       
   226 TInt CCacheSource::Stop()
       
   227     {
       
   228     TInt status(KErrNone);
       
   229     DEBPRN1(_L("CCacheSource::Stop"));    
       
   230     status = iDataSource->Stop();
       
   231     iFileSize = 0;
       
   232     iLastBufferWritten = false;
       
   233     iAbsBufferStart = 0;
       
   234     iAbsBufferEnd = 0;
       
   235     iBufferReadPos = 0;
       
   236     iSeekStart = 0;
       
   237     iSeekEnd = 0;
       
   238     iSnkBytes = 0;
       
   239     iTransferBuffer->SetLastBuffer(EFalse);
       
   240     if(iCacheType == CDataSourceConfigIntfc::EFILE)
       
   241         {
       
   242         iFile.Close();
       
   243         iFs.Delete(iFileName);
       
   244         }
       
   245     return status;
       
   246     }
       
   247 
       
   248 TInt CCacheSource::FillBuffer( CMMFBuffer* aBuffer )
       
   249     {
       
   250     TInt status(KErrNone);
       
   251     ASSERT(aBuffer);
       
   252     CMMFDataBuffer* dest = static_cast<CMMFDataBuffer*>( aBuffer );
       
   253     TDes8& destBufferDes = dest->Data();
       
   254     
       
   255     DEBPRN4(_L("CCacheSource::FillBuffer RequestSize[%d] AbsBufEnd[%d] SnkBytes[%d]"),aBuffer->RequestSize(),iAbsBufferEnd,iSnkBytes); 
       
   256     
       
   257     AppendBufferToSinkQueue(dest);
       
   258     
       
   259     if(iCacheType == CDataSourceConfigIntfc::EFILE)
       
   260         {
       
   261         if(((iSnkBytes + aBuffer->RequestSize())  < iFileSize) || iLastBufferWritten)
       
   262             {
       
   263             status = ServiceFillBuffer();
       
   264             }
       
   265         else
       
   266             {
       
   267             if(!iLastBufferWritten)
       
   268                 {
       
   269 				iTransferBuffer->Data().FillZ();
       
   270 				iTransferBuffer->Data().SetLength(0);
       
   271 				iDataSource->FillBuffer(iTransferBuffer);                
       
   272 				}
       
   273                 
       
   274             status = KErrUnderflow;                                
       
   275             }        
       
   276         }
       
   277     else
       
   278         {
       
   279         if((aBuffer->RequestSize() < (iAbsBufferEnd - iAbsBufferReadPos)) || iLastBufferWritten)
       
   280             {
       
   281             status = ServiceFillBuffer();                
       
   282             }
       
   283         else
       
   284             {
       
   285             if(!iLastBufferWritten)                
       
   286                 {
       
   287 				iTransferBuffer->Data().FillZ();
       
   288 				iTransferBuffer->Data().SetLength(0);
       
   289 				iDataSource->FillBuffer(iTransferBuffer);                
       
   290 				}
       
   291             
       
   292             status = KErrUnderflow;                
       
   293             }                                
       
   294         }        
       
   295     return status;
       
   296     }
       
   297 
       
   298 TInt CCacheSource::ServiceFillBuffer()
       
   299     {
       
   300     TInt status(KErrNone);
       
   301     if ( iSinkQueue->IsEmpty() )
       
   302         return status;
       
   303     
       
   304     CSinkQueueItem* snkItem = iSinkQueue->First();
       
   305     iSinkQueue->Remove(*snkItem);
       
   306     iSnkItemsCount--;
       
   307     CMMFBuffer* buffer = snkItem->Buffer();
       
   308     delete snkItem;
       
   309     
       
   310     if(iCacheType == CDataSourceConfigIntfc::EFILE)
       
   311         {
       
   312         iReadRequest->SetBuffer(buffer);
       
   313         iReadRequest->SetActive();
       
   314         if((iSnkBytes + iReadRequest->Buffer()->RequestSize()) > iFileSize)
       
   315             {
       
   316             iReadRequest->Buffer()->SetLastBuffer(ETrue);    
       
   317             }
       
   318 
       
   319         iFile.Read(iSnkBytes,iReadRequest->Buffer()->Data(),iReadRequest->iStatus);
       
   320         iSnkBytes += iReadRequest->Buffer()->RequestSize();
       
   321         }
       
   322     else
       
   323         {
       
   324         iReadRequest->SetBuffer(buffer);
       
   325         
       
   326         DEBPRN4(_L("CCacheSource::ServiceFillBuffer DataSize[%d] iBufferReadPos[%d] SnkBytes[%d]"),iDataBuffer->Data().Size(),iBufferReadPos,iSnkBytes); 
       
   327         if((iBufferReadPos + iReadRequest->Buffer()->RequestSize()) > iAbsBufferEnd)
       
   328             {
       
   329             iReadRequest->Buffer()->SetLastBuffer(ETrue);    
       
   330             }
       
   331         
       
   332         iDataBuffer->SetPosition(iBufferReadPos);
       
   333         
       
   334         if((iBufferReadPos + iReadRequest->Buffer()->RequestSize()) <= iDataBuffer->Data().Size())
       
   335             {
       
   336             iReadRequest->Buffer()->Data().Copy(iDataBuffer->Data().MidTPtr(iBufferReadPos,iReadRequest->Buffer()->RequestSize()));
       
   337             iBufferReadPos += iReadRequest->Buffer()->RequestSize();
       
   338             }
       
   339         else
       
   340             {
       
   341             TInt dataToCopy = iDataBuffer->Data().Size() - iBufferReadPos;
       
   342             iReadRequest->Buffer()->Data().Append(iDataBuffer->Data().MidTPtr(iBufferReadPos,dataToCopy));
       
   343             iBufferReadPos = 0;
       
   344             TInt dataLeftToCopy = iReadRequest->Buffer()->RequestSize() - dataToCopy;
       
   345             iReadRequest->Buffer()->Data().Append(iDataBuffer->Data().MidTPtr(iBufferReadPos,dataLeftToCopy));            
       
   346             iBufferReadPos +=  dataLeftToCopy;                   
       
   347             DEBPRN4(_L("CCacheSource::ServiceFillBuffer dataToCopy[%d] dataLeftToCopy[%d] SnkBytes[%d]"),dataToCopy,dataLeftToCopy,iBufferReadPos);         
       
   348             }            
       
   349 
       
   350         iSnkBytes += iReadRequest->Buffer()->Data().Length();     
       
   351         DEBPRN4(_L("CCacheSource::ServiceFillBuffer RequestSize[%d] iBufferReadPos[%d] SnkBytes[%d]"),iReadRequest->Buffer()->RequestSize(),iBufferReadPos,iSnkBytes);                 
       
   352         iReadRequest->SetActive();
       
   353         TRequestStatus* status = &(iReadRequest->iStatus);
       
   354         User::RequestComplete(status,KErrNone);
       
   355         }        
       
   356     return status;        
       
   357     }
       
   358 
       
   359 TAny* CCacheSource::CustomInterface( TUid /*aInterfaceUid*/ )
       
   360     {
       
   361     return NULL;    
       
   362     }
       
   363 
       
   364 TInt CCacheSource::GetSeekingSupport( TBool& aSeekSupport )
       
   365     {
       
   366     aSeekSupport = ETrue;
       
   367     return KErrNone;
       
   368     };
       
   369 
       
   370 TInt CCacheSource::GetRandomSeekingSupport( TBool& aSeekSupport )
       
   371     {
       
   372     aSeekSupport = EFalse;
       
   373     return KErrNone;
       
   374     };
       
   375 
       
   376 // Seek Implementation
       
   377 
       
   378 TInt CCacheSource::Seek(TUint aPosInBytes)
       
   379     {
       
   380     TInt status(KErrNone);
       
   381     DEBPRN2(_L("CCacheSource::Seek[%d]"),aPosInBytes);    
       
   382     
       
   383     if(iCacheType == CDataSourceConfigIntfc::EFILE)
       
   384         {
       
   385 		// This is File Seek so the SeekPosition has to be less
       
   386 		// then the File Size otherwise we leave        	
       
   387         if(aPosInBytes <= iFileSize)
       
   388             {
       
   389             iSnkBytes = aPosInBytes;
       
   390             }
       
   391         else
       
   392             {
       
   393             status = KErrNotReady;        
       
   394             }
       
   395         }
       
   396     else
       
   397         {
       
   398         DEBPRN3(_L("CCacheSource::Seek AbsBufStart[%d] AbsBufEnd[%d]"),iAbsBufferStart,iAbsBufferEnd);            
       
   399         // Here we seek in the Buffer, so we can only seek from the begining of the
       
   400         // buffer window. which is iAbsBufferStart
       
   401         if(aPosInBytes >= iAbsBufferStart)
       
   402             {
       
   403             iAbsBufferReadPos = aPosInBytes;
       
   404             TInt seekDelta = aPosInBytes - iAbsBufferStart;
       
   405             if(seekDelta <= (iDataBuffer->Data().MaxLength() - iSeekStart))
       
   406                 {
       
   407                 iBufferReadPos = iSeekStart + seekDelta;    
       
   408                 }
       
   409             else
       
   410                 {
       
   411                 iBufferReadPos = seekDelta - (iDataBuffer->Data().MaxLength() - iSeekStart);    
       
   412                 }                    
       
   413             }
       
   414         else
       
   415             {
       
   416             status = KErrNotReady;    
       
   417             }                
       
   418         }        
       
   419     return status;        
       
   420     }
       
   421 
       
   422 // From CMultimediaDataSource ends
       
   423 
       
   424 TInt CCacheSource::ServiceBufferFilled( CMMFBuffer* aBuffer )
       
   425     {
       
   426     TInt status(KErrNone);
       
   427     CMMFDataBuffer* dest = static_cast<CMMFDataBuffer*>( aBuffer );
       
   428     TDes8& destBufferDes = dest->Data();
       
   429     
       
   430     if(iCacheType == CDataSourceConfigIntfc::EFILE)
       
   431         {
       
   432         iWriteRequest->SetActive();
       
   433         iFile.Write(iFileSize,destBufferDes,iWriteRequest->iStatus);
       
   434         iFileSize = iFileSize + dest->BufferSize();    
       
   435         DEBPRN3(_L("CCacheSource::ServiceBufferFilled FileSize[%d] LastBuffer[%d]"),iFileSize,dest->LastBuffer());
       
   436         if(dest->LastBuffer())
       
   437             {
       
   438             iLastBufferWritten = ETrue;
       
   439             dest->SetLastBuffer(EFalse);
       
   440             }
       
   441         }
       
   442     else
       
   443         {
       
   444         iWriteRequest->SetActive();
       
   445 
       
   446         iDataBuffer->SetPosition(iSeekEnd);
       
   447         
       
   448         if((iSeekEnd + dest->BufferSize()) <= iDataBuffer->Data().MaxLength())
       
   449             {
       
   450             iDataBuffer->Data().Replace(iSeekEnd,dest->Data().Size(),dest->Data());
       
   451             iSeekEnd += dest->Data().Size();
       
   452             }
       
   453         else
       
   454             {
       
   455             TInt copyEndData = iDataBuffer->Data().MaxLength() - iSeekEnd;    
       
   456             iDataBuffer->Data().Replace(iSeekEnd,copyEndData,dest->Data().MidTPtr(0,copyEndData));
       
   457             TInt dataLeftToCopy = dest->Data().Size() - copyEndData;
       
   458             iSeekEnd = 0;
       
   459             iDataBuffer->Data().Replace(iSeekEnd,dataLeftToCopy,dest->Data().MidTPtr(copyEndData,dataLeftToCopy));
       
   460             iSeekEnd = dataLeftToCopy;
       
   461             }            
       
   462         
       
   463         iAbsBufferEnd += dest->BufferSize();    
       
   464         if(iAbsBufferEnd < iDataBuffer->Data().MaxLength())
       
   465             {
       
   466             iAbsBufferStart = 0;    
       
   467             }
       
   468         else
       
   469             {
       
   470             iAbsBufferStart =  iAbsBufferEnd - iDataBuffer->Data().MaxLength();   
       
   471             }            
       
   472         
       
   473         if(iAbsBufferEnd < iDataBuffer->Data().MaxLength())
       
   474             {
       
   475             iSeekStart = 0;    
       
   476             }
       
   477         else
       
   478             {
       
   479             iSeekStart = iSeekEnd;    
       
   480             }            
       
   481         
       
   482         DEBPRN4(_L("CCacheSource::ServiceBufferFilled DataSize[%d] AbsBufferEnd[%d] LastBuffer[%d]"),iDataBuffer->Data().Size(),iAbsBufferEnd,dest->LastBuffer());
       
   483         if(dest->LastBuffer())
       
   484             iLastBufferWritten = ETrue;            
       
   485             
       
   486         TRequestStatus* status = &(iWriteRequest->iStatus);
       
   487         User::RequestComplete(status,KErrNone);
       
   488         }        
       
   489     return status;
       
   490     }
       
   491 
       
   492 void CCacheSource::ReadRequestComplete(CReadWriteRequestAO* aRequest,TRequestStatus& aStatus)
       
   493     {
       
   494     if(aStatus != KErrNone)
       
   495         {
       
   496         }
       
   497     else
       
   498         {
       
   499         if(aRequest->RequestType() == CReadWriteRequestAO::EReadRequest)
       
   500             {
       
   501             DEBPRN3(_L("CCacheSource::ReadRequestComplete [%d] [%d]"),aRequest->Buffer()->Data().Size(),aRequest->Buffer()->RequestSize());
       
   502             iObserver->BufferFilled(aRequest->Buffer());
       
   503             }
       
   504         else
       
   505             {
       
   506 			CSinkQueueItem* snkItem = iSinkQueue->First();
       
   507 			iSinkQueue->Remove(*snkItem);
       
   508 			iSnkItemsCount--;
       
   509 			CMMFBuffer* buffer = snkItem->Buffer();
       
   510 			delete snkItem;
       
   511 			FillBuffer(buffer);
       
   512             }
       
   513         }        
       
   514     }
       
   515 
       
   516 
       
   517 TInt CCacheSource::AppendBufferToSinkQueue( CMMFBuffer* aBuffer )
       
   518     {
       
   519     TInt status(KErrNone);
       
   520     // Add observer buffer to queue
       
   521     CMMFDataBuffer* dest = static_cast<CMMFDataBuffer*>( aBuffer );
       
   522     TDes8& destBufferDes = dest->Data();
       
   523     
       
   524     CSinkQueueItem* request(NULL);
       
   525     
       
   526     TRAP( status, request = CSinkQueueItem::NewL( aBuffer ) );
       
   527     if ( status == KErrNone )
       
   528         {
       
   529         iSinkQueue->AddLast(*request);
       
   530         iSnkItemsCount++;
       
   531         }
       
   532     return status;
       
   533     }
       
   534 
       
   535 TInt CCacheSource::EmptySinkQueue()
       
   536     {
       
   537     TInt status(KErrNone);
       
   538     // Empty sink queue
       
   539     CSinkQueueItem* snkItem;
       
   540     while ( !iSinkQueue->IsEmpty() )
       
   541         {
       
   542         snkItem = iSinkQueue->First();
       
   543         iSinkQueue->Remove(*snkItem);
       
   544         delete snkItem;
       
   545         }
       
   546     
       
   547     iSnkItemsCount = 0;
       
   548     return status;
       
   549     }
       
   550 
       
   551 //From MMultimediaDataSourceObserver
       
   552 
       
   553 
       
   554 CMDataSourceObserver::CMDataSourceObserver(CMultimediaDataSource* aDataSource ,CMultimediaDataSource* aParent)
       
   555                                :iDataSource(aDataSource)
       
   556                                ,iParent(aParent)
       
   557     {
       
   558     }
       
   559 
       
   560 // -----------------------------------------------------------------------------
       
   561 // CSinkQueueItem::ConstructL
       
   562 // Symbian 2nd phase constructor can leave.
       
   563 // -----------------------------------------------------------------------------
       
   564 //
       
   565 void CMDataSourceObserver::ConstructL()
       
   566     {
       
   567     iDataSource->SetObserver(*this);    
       
   568     }
       
   569 
       
   570 // -----------------------------------------------------------------------------
       
   571 // CSinkQueueItem::NewL
       
   572 // Two-phased constructor.
       
   573 // -----------------------------------------------------------------------------
       
   574 //
       
   575 CMDataSourceObserver* CMDataSourceObserver::NewL(CMultimediaDataSource* aDataSource ,CMultimediaDataSource* aParent)
       
   576     {
       
   577     CMDataSourceObserver* self = new(ELeave) CMDataSourceObserver( aDataSource, aParent );
       
   578     CleanupStack::PushL(self);
       
   579     self->ConstructL();
       
   580     CleanupStack::Pop(self);
       
   581     return self;
       
   582     }
       
   583 
       
   584 
       
   585 // -----------------------------------------------------------------------------
       
   586 // CSinkQueueItem::~CSinkQueueItem
       
   587 // Destructor
       
   588 // -----------------------------------------------------------------------------
       
   589 //
       
   590 CMDataSourceObserver::~CMDataSourceObserver()
       
   591     {
       
   592     }
       
   593 
       
   594 void CMDataSourceObserver::BufferFilled( CMMFBuffer* aBuffer )
       
   595     {
       
   596     (static_cast<CCacheSource*>(iParent))->ServiceBufferFilled(aBuffer);        
       
   597     }
       
   598 
       
   599 void CMDataSourceObserver::Event( TUid aEvent )
       
   600     {
       
   601     MMultimediaDataSourceObserver* obsvr(NULL);    
       
   602     iParent->GetObserver(obsvr);
       
   603     obsvr->Event(aEvent);    
       
   604     }
       
   605 
       
   606 TInt CMDataSourceObserver::GetBitRate( TUint& aBitRate )
       
   607     {
       
   608     TInt status(KErrNone);
       
   609     MMultimediaDataSourceObserver* obsvr(NULL);    
       
   610     iParent->GetObserver(obsvr);
       
   611     status = obsvr->GetBitRate(aBitRate);    
       
   612     return status;
       
   613     }
       
   614 
       
   615 // End of file