vtprotocolplugins/VideoSource/src/CVSDataSourceImp.cpp
changeset 0 ed9695c8bcbe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vtprotocolplugins/VideoSource/src/CVSDataSourceImp.cpp	Mon Nov 23 14:47:47 2009 +0200
@@ -0,0 +1,1315 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Video Source subsystem.
+*
+*/
+
+
+// INCLUDE FILES
+
+#include <fbs.h>
+#include <e32svr.h>
+#include <badesca.h>
+#include <mmfdatasourcesink.hrh>
+
+#include "CVSMMFDataBuffer.h"
+#include "CVSDataSourceImp.h"
+#include "VSPanic.h"
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// MACROS
+
+#ifdef _DEBUG
+#    define __IF_DEBUG(t) {RDebug::t;}
+#else
+#    define __IF_DEBUG(t)
+#endif
+
+// LOCAL CONSTANTS AND MACROS
+
+static const TInt KQcifWidth = 176;
+static const TInt KQcifHeight = 144;
+
+ // 4:2:0 planar and 32 bytes extra
+ static const TInt KSourceBufferSize =
+    ( KQcifWidth * KQcifHeight ) + ( ( KQcifWidth * KQcifHeight ) / 2 ) + 12;
+
+// Granularity for video frame format array
+static const TInt KNoOfSupportedFormats = 4;
+
+// How many sequential FillBufferL calls is supported
+static const TInt KNoOfSupportedBuffers = 2;
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// ============================ CVSProviderSwitchAO ============================
+
+// -----------------------------------------------------------------------------
+// CVSProviderSwitchAO::NewL
+// -----------------------------------------------------------------------------
+//
+CVSProviderSwitchAO* CVSProviderSwitchAO::NewL(
+    CVSDataSourceImp* aDataSourceImp )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::NewL() >>"), RThread().Id().operator TUint()));
+    CVSProviderSwitchAO* self =
+        new ( ELeave ) CVSProviderSwitchAO( aDataSourceImp );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop(); // self
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::NewL() <<"), RThread().Id().operator TUint()));
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CVSProviderSwitchAO::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CVSProviderSwitchAO::ConstructL()
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::ConstructL() >>"), RThread().Id().operator TUint()));
+    User::LeaveIfError( iSwitchCs.CreateLocal() );
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::ConstructL() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSProviderSwitchAO::CVSProviderSwitchAO
+// -----------------------------------------------------------------------------
+//
+CVSProviderSwitchAO::CVSProviderSwitchAO( CVSDataSourceImp* aDataSourceImp )
+: CActive( EPriorityStandard ), iDataSourceImp( aDataSourceImp )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::CVSProviderSwitchAO() >>"), RThread().Id().operator TUint()));
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::CVSProviderSwitchAO() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSProviderSwitchAO::~CVSProviderSwitchAO
+// -----------------------------------------------------------------------------
+//
+CVSProviderSwitchAO::~CVSProviderSwitchAO()
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::~CVSProviderSwitchAO() >>"), RThread().Id().operator TUint()));
+    iSwitchCs.Close();
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::~CVSProviderSwitchAO() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSProviderSwitchAO::ThreadLogon
+// -----------------------------------------------------------------------------
+//
+TInt CVSProviderSwitchAO::ThreadLogon( MAsyncEventHandler& aEventHandler )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::ThreadLogon() >>"), RThread().Id().operator TUint()));
+    iEventHandler = &aEventHandler;
+    RThread me;
+    iThreadId = me.Id();
+    CActiveScheduler::Add( this );
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::ThreadLogon() <<"), RThread().Id().operator TUint()));
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CVSProviderSwitchAO::ThreadLogoff
+// -----------------------------------------------------------------------------
+//
+void CVSProviderSwitchAO::ThreadLogoff()
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::ThreadLogoff() >>"), RThread().Id().operator TUint()));
+    if( RThread().Id().operator TUint() == iThreadId )
+        {
+        Deque();
+        iThreadId = 0;
+        iNewProvider = NULL;
+        }
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::ThreadLogoff() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSProviderSwitchAO::InitiateProviderSwitch
+// -----------------------------------------------------------------------------
+//
+void CVSProviderSwitchAO::InitiateProviderSwitch(
+    CVSDataProvider* aNewProvider )
+    {
+    iSwitchCs.Wait();
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::InitiateProviderSwitch() >>"), RThread().Id().operator TUint()));
+    iNewProvider = aNewProvider;
+    iStatus = KRequestPending;
+    SetActive();
+    Signal( KErrNone );
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::InitiateProviderSwitch() <<"), RThread().Id().operator TUint()));
+    iSwitchCs.Signal();
+    }
+
+// -----------------------------------------------------------------------------
+// CVSProviderSwitchAO::RunL
+// -----------------------------------------------------------------------------
+//
+void CVSProviderSwitchAO::RunL()
+    {
+    iSwitchCs.Wait();
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::RunL() >>"), RThread().Id().operator TUint()));
+    if( iStatus.Int() == KErrNone )
+        {
+        if ( iDataSourceImp->SwitchPending() )
+            {
+            Panic( EVSPanicSwitchAlreadyPending );
+            }
+        TRAPD(
+            leaveCode,
+            iDataSourceImp->DoProviderSwitchL( iNewProvider, *iEventHandler ) );
+        if ( leaveCode != KErrNone )
+            {
+            iDataSourceImp->ProviderSwitchError( leaveCode );
+            }
+        }
+    else
+        {
+        iNewProvider = NULL;
+        }
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::RunL() <<"), RThread().Id().operator TUint()));
+    iSwitchCs.Signal();
+    }
+
+// -----------------------------------------------------------------------------
+// CVSProviderSwitchAO::DoCancel
+// -----------------------------------------------------------------------------
+//
+void CVSProviderSwitchAO::DoCancel()
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::DoCancel() >>"), RThread().Id().operator TUint()));
+    // Nothing to do here. This AO is always signalled when it's activated.
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::DoCancel() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSProviderSwitchAO::Signal
+// -----------------------------------------------------------------------------
+//
+void CVSProviderSwitchAO::Signal( TInt aError )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::Signal() >>"), RThread().Id().operator TUint()));
+    if( IsActive() )
+        {
+        TRequestStatus* pStatus = &iStatus;
+        RThread me;
+        if( me.Id() == iThreadId )
+            {
+            User::RequestComplete( pStatus, aError );
+            }
+        else
+            {
+            if( me.Open( iThreadId ) == KErrNone )
+                {
+                *pStatus = KRequestPending;
+                me.RequestComplete( pStatus, aError );
+                me.Close();
+                }
+            else
+                {
+                Panic( EVSPanicThreadOpenFailure );
+                }
+            }
+        }
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSProviderSwitchAO::Signal() <<"), RThread().Id().operator TUint()));
+    }
+
+// ============================ CVSDataSourceObserverAO ========================
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceObserverAO::CVSDataSourceObserverAO
+// -----------------------------------------------------------------------------
+//
+CVSDataSourceObserverAO::CVSDataSourceObserverAO()
+: CActive( EPriorityStandard )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceObserverAO::CVSDataSourceObserverAO() >>"), RThread().Id().operator TUint()));
+    RThread me;
+    iThreadId = me.Id();
+    CActiveScheduler::Add( this );
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceObserverAO::CVSDataSourceObserverAO() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceObserverAO::~CVSDataSourceObserverA
+// -----------------------------------------------------------------------------
+//
+CVSDataSourceObserverAO::~CVSDataSourceObserverAO()
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceObserverAO::~CVSDataSourceObserverAO() >>"), RThread().Id().operator TUint()));
+    Cancel();
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceObserverAO::~CVSDataSourceObserverAO() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceObserverAO::vsProviderSwitchDone
+// -----------------------------------------------------------------------------
+//
+void CVSDataSourceObserverAO::vsProviderSwitchDone(
+    MVSDataSourceObserver& aObserver,
+    CVSDataProvider* aOldProvider )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceObserverAO::vsProviderSwitchDone() >>"), RThread().Id().operator TUint()));
+    iObserver = &aObserver;
+    iOldProvider = aOldProvider;
+    iStatus = KRequestPending;
+    SetActive();
+    Signal( KErrNone );
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceObserverAO::vsProviderSwitchDone() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceObserverAO::RunL
+// -----------------------------------------------------------------------------
+//
+void CVSDataSourceObserverAO::RunL()
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceObserverAO::RunL() >>"), RThread().Id().operator TUint()));
+    if( iStatus.Int() == KErrNone )
+        {
+        iObserver->vsProviderSwitchDone( iOldProvider );
+        }
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceObserverAO::RunL() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceObserverAO::DoCancel
+// -----------------------------------------------------------------------------
+//
+void CVSDataSourceObserverAO::DoCancel()
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceObserverAO::DoCancel() >>"), RThread().Id().operator TUint()));
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceObserverAO::DoCancel() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceObserverAO::Signal
+// -----------------------------------------------------------------------------
+//
+void CVSDataSourceObserverAO::Signal( TInt aError )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceObserverAO::Signal() >>"), RThread().Id().operator TUint()));
+    TRequestStatus* pStatus = &iStatus;
+    RThread me;
+    if( me.Id() == iThreadId )
+        {
+        User::RequestComplete( pStatus, aError );
+        }
+    else
+        {
+        if( me.Open( iThreadId ) == KErrNone )
+            {
+            *pStatus = KRequestPending;
+            me.RequestComplete( pStatus, aError );
+            me.Close();
+            }
+        else
+            {
+            Panic( EVSPanicThreadOpenFailure );
+            }
+        }
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceObserverAO::Signal() <<"), RThread().Id().operator TUint()));
+    }
+
+
+
+// =============================== CVSDataSource ===============================
+
+// -----------------------------------------------------------------------------
+// CVSDataSource::NewSourceL
+// -----------------------------------------------------------------------------
+//
+CVSDataSource* CVSDataSource::NewSourceL( MVSDataSourceObserver* aObserver )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSource::NewSourceL() >>"), RThread().Id().operator TUint()));
+    if ( aObserver == NULL )
+        {
+        User::Leave( KErrArgument );
+        }
+    CVSDataSource* self = CVSDataSourceImp::NewSourceL();
+    CleanupStack::PushL( self );
+    self->ConstructL( aObserver );
+    CleanupStack::Pop( self );
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSource::NewSourceL() <<"), RThread().Id().operator TUint()));
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSource::CVSDataSource
+// -----------------------------------------------------------------------------
+//
+CVSDataSource::CVSDataSource() : MVTVideoSource( KNullUid )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSource::CVSDataSource() >>"), RThread().Id().operator TUint()));
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSource::CVSDataSource() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSource::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CVSDataSource::ConstructL( MVSDataSourceObserver* aObserver )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSource::ConstructL() >>"), RThread().Id().operator TUint()));
+    iObserver = aObserver;
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSource::ConstructL() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::NewSourceL
+// -----------------------------------------------------------------------------
+//
+CVSDataSourceImp* CVSDataSourceImp::NewSourceL()
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::NewSourceL() >>"), RThread().Id().operator TUint()));
+    CVSDataSourceImp* self = new (ELeave) CVSDataSourceImp;
+    CleanupStack::PushL( self );
+    self->ConstructSourceL( KNullDesC8 );
+    CleanupStack::Pop( self );
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::NewSourceL() <<"), RThread().Id().operator TUint()));
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::SwitchDataProviderL
+// -----------------------------------------------------------------------------
+//
+void CVSDataSourceImp::SwitchDataProviderL(
+    CVSDataProvider* aNewProvider )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SwitchDataProviderL() >>"), RThread().Id().operator TUint()));
+    if ( aNewProvider == NULL )
+        {
+        __IF_DEBUG(Print(_L("SwitchDataProviderL(): NULL argument, leaving.")));
+        User::Leave( KErrArgument );
+        }
+    // Is new provider same as old, then no need to change provider
+    if ( aNewProvider == &DataProvider() )
+        {
+        __IF_DEBUG(Print(_L("SwitchDataProviderL(): New provider same as old: 0x%x"), aNewProvider));
+        Observer().vsProviderSwitchDone( aNewProvider );
+        __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SwitchDataProvider() <<"), RThread().Id().operator TUint()));
+        return;
+        }
+    // If Protocol is in the currently initializing itself then complete this switch
+    // request when Protocol ready (from SourcePlayL). No need to protect
+    // iProtoInitOngoing test with CS.
+    if ( iProtoInitOngoing )
+        {
+        __IF_DEBUG(Print(_L("PROTOCOL INIT ONGOING, PENDING SWITCH FOR A WHILE")));
+        iProtoInitCS.Wait();
+        iProviderSwitchRequestDuringProtoInit = ETrue;
+        iNewProvider = aNewProvider;
+        iProtoInitCS.Signal();
+        return;
+        }
+    // Switch provider
+    if ( iThreadLogonCalled )
+        {
+        iProviderSwitchAO->InitiateProviderSwitch( aNewProvider );
+        }
+    else
+        {
+        CVSDataProvider* oldProvider = SwitchProvider( aNewProvider );
+        Observer().vsProviderSwitchDone( oldProvider );
+        }
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SwitchDataProviderL() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::PauseSending
+// -----------------------------------------------------------------------------
+//
+void CVSDataSourceImp::PauseSending()
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::PauseSending() >>"), RThread().Id().operator TUint()));
+    iPauseCs.Wait();
+    iSendingPaused = ETrue;
+    iPauseCs.Signal();
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::PauseSending() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::ResumeSending
+// -----------------------------------------------------------------------------
+//
+void CVSDataSourceImp::ResumeSending()
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::ResumeSending() >>"), RThread().Id().operator TUint()));
+    iPauseCs.Wait();
+    iSendingPaused = EFalse;
+    iPauseCs.Signal();
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::ResumeSending() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::~CVSDataSourceImp
+// -----------------------------------------------------------------------------
+//
+CVSDataSourceImp::~CVSDataSourceImp()
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::~CVSDataSourceImp() >>"), RThread().Id().operator TUint()));
+    delete iDataSourceObserverAO;
+    delete iProviderSwitchAO;
+    iProtoMimeTypes.Close();
+    delete iSupportedVideoFormats;
+    iSupportedVideoSizes.Close();
+    iSupportedFrameRates.Close();
+    // Assuming no need to use critical section here
+    iFreeQueue.Close();
+    iActiveQueue.Close();
+    iAllocatedBuffers.ResetAndDestroy();
+    iQueueCs.Close();
+    iPauseCs.Close();
+    iProtoInitCS.Close();
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::~CVSDataSourceImp() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::FillBufferL
+// -----------------------------------------------------------------------------
+//
+void CVSDataSourceImp::FillBufferL(
+    CMMFBuffer* aBuffer,
+    MVTVideoSink* aConsumer,
+    TMediaId aMediaId )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::FillBufferL() >>"), RThread().Id().operator TUint()));
+
+    if ( aBuffer == NULL || aConsumer == NULL )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    if ( aBuffer->Type() != KUidMmfDataBuffer )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    DataProvider().SetFillBufferParams( aConsumer, aMediaId );
+
+    iPauseCs.Wait();
+    const TBool sendingPaused( iSendingPaused );
+    iPauseCs.Signal();
+
+    if( iSwitchOngoing )
+        {
+        __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::FillBufferL(): Switch ongoing"), RThread().Id().operator TUint()));
+        // queues are locked by us -> it's safe to modify queues without
+        // locking
+        User::LeaveIfError(
+            FreeBufferNoWait( static_cast<CVSMMFDataBuffer*>( aBuffer ) ) );
+        }
+    else if( iSwitchPending )
+        {
+        __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::FillBufferL(): Switch pending"), RThread().Id().operator TUint()));
+        FreeBufferL( static_cast<CVSMMFDataBuffer*>( aBuffer ) );
+        TRAPD(
+            err,
+            DoProviderSwitchL(
+                iProviderSwitchAO->NewDataProvider(),
+                iProviderSwitchAO->EventHandler() ) );
+        if( err != KErrNone )
+            {
+            __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::FillBufferL(): Error in switch = %d"), RThread().Id().operator TUint(), err));
+            // Not leaving from here (it was provider switch related error),
+            // let VT take care of the rest
+            ProviderSwitchError( err );
+            }
+        }
+    else if( sendingPaused )
+        {
+        __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::FillBufferL(): Sending Paused"), RThread().Id().operator TUint()));
+        // queues are locked by us -> it's safe to modify queues without
+        // locking
+        User::LeaveIfError(
+            FreeBufferNoWait( static_cast<CVSMMFDataBuffer*>( aBuffer ) ) );
+        }
+    else
+        {
+        __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::FillBufferL(): No switch -> normal FillBufferL()"), RThread().Id().operator TUint()));
+        FreeBufferL( static_cast<CVSMMFDataBuffer*>( aBuffer ) );
+        DataProvider().FillBufferL( aBuffer, aConsumer, aMediaId );
+        }
+
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::FillBufferL() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::BufferEmptiedL
+// -----------------------------------------------------------------------------
+//
+void CVSDataSourceImp::BufferEmptiedL( CMMFBuffer* /*aBuffer*/ )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::BufferEmptiedL() >>"), RThread().Id().operator TUint()));
+    User::Leave( KErrNotSupported );
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::BufferEmptiedL() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::CanCreateSourceBuffer
+// -----------------------------------------------------------------------------
+//
+TBool CVSDataSourceImp::CanCreateSourceBuffer()
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::CanCreateSourceBuffer() >>"), RThread().Id().operator TUint()));
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::CanCreateSourceBuffer) <<"), RThread().Id().operator TUint()));
+    return ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::CreateSourceBufferL
+// -----------------------------------------------------------------------------
+//
+CMMFBuffer* CVSDataSourceImp::CreateSourceBufferL(
+    TMediaId /*aMediaId*/,
+    TBool &aReference )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::CreateSourceBufferL() >>"), RThread().Id().operator TUint()));
+    if ( iRequestedBufferCount >= KNoOfSupportedBuffers )
+        {
+        User::Leave( KErrOverflow );
+        }
+    aReference = ETrue;
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::CreateSourceBufferL(): Returning buffer: %d [0x%08x]"), RThread().Id().operator TUint(), iRequestedBufferCount + 1, iAllocatedBuffers[ iRequestedBufferCount ]));
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::CreateSourceBufferL() <<"), RThread().Id().operator TUint()));
+    return iAllocatedBuffers[ iRequestedBufferCount++ ];
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::CreateSourceBufferL
+// -----------------------------------------------------------------------------
+//
+CMMFBuffer* CVSDataSourceImp::CreateSourceBufferL(
+    TMediaId /*aMediaId*/,
+    CMMFBuffer& /*aSinkBuffer*/,
+    TBool &aReference )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::CreateSourceBufferL() >>"), RThread().Id().operator TUint()));
+    if ( iRequestedBufferCount >= KNoOfSupportedBuffers )
+        {
+        User::Leave( KErrOverflow );
+        }
+    aReference = ETrue;
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::CreateSourceBufferL(): Returning buffer: %d [0x%08x]"), RThread().Id().operator TUint(), iRequestedBufferCount + 1, iAllocatedBuffers[ iRequestedBufferCount ]));
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::CreateSourceBufferL() <<"), RThread().Id().operator TUint()));
+    return iAllocatedBuffers[ iRequestedBufferCount++ ];
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::SourceThreadLogon
+// -----------------------------------------------------------------------------
+//
+TInt CVSDataSourceImp::SourceThreadLogon( MAsyncEventHandler& aEventHandler )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SourceThreadLogon() >>"), RThread().Id().operator TUint()));
+    __ASSERT_DEBUG( (&DataProvider()) != NULL,
+        Panic( EVSPanicProviderNotSet ) );
+    TInt err( KErrNone );
+    if( !iFbsStarted )
+        {
+        // Caller does not start the FBS server when compiled on proxy mode
+        // so we have to take care of that by ourself.
+        err = FbsStartup();
+        if( err == KErrNone )
+            {
+            err = RFbsSession::Connect();
+            if( err == KErrNone )
+                {
+                iFbsStarted = ETrue;
+                }
+            }
+        }
+    if( !iThreadLogonCalled && ( err == KErrNone ) )
+        {
+        err = DataProvider().SourceThreadLogon( aEventHandler );
+        if (err != KErrNone)
+            {
+            return err;
+            }
+        iProviderSwitchAO->ThreadLogon( aEventHandler );
+        iThreadLogonCalled = ETrue;
+        iProtoInitOngoing = ETrue;
+        }
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SourceThreadLogon() <<"), RThread().Id().operator TUint()));
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::SourceThreadLogoff
+// -----------------------------------------------------------------------------
+//
+void CVSDataSourceImp::SourceThreadLogoff()
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SourceThreadLogoff() >>"), RThread().Id().operator TUint()));
+
+    iThreadLogonCalled = EFalse;
+
+    if ( iProviderSwitchRequestDuringProtoInit )
+        {
+        __IF_DEBUG(Print(_L("PROTOCOL INIT FAILED, NOW COMPLETING THE SWITCH REQUEST WITH ERROR")));
+        iProviderSwitchRequestDuringProtoInit = EFalse;
+        ProviderSwitchError( KErrAbort );
+        }
+
+    if( &DataProvider() )
+        {
+        DataProvider().SourceThreadLogoff();
+        }
+
+    iSwitchOngoing = iSwitchPending = EFalse;
+
+    iProtoInitOngoing = EFalse;
+
+    // If provider switch ongoing complete it
+    if ( iProviderSwitchAO->NewDataProvider() != NULL )
+        {
+        CVSDataProvider* oldProvider =
+            SwitchProvider( iProviderSwitchAO->NewDataProvider() );
+        Observer().vsProviderSwitchDone( oldProvider );
+        }
+
+    iProviderSwitchAO->ThreadLogoff();
+
+    delete iFormat; iFormat = 0;
+
+    iCallFlags = 0;
+
+    // Clear iFreeQueue
+    while( iFreeQueue.Count() )
+        {
+        iFreeQueue.Remove( 0 );
+        }
+
+    // Clear iActiveQueue
+    while( iActiveQueue.Count() )
+        {
+        iActiveQueue.Remove( 0 );
+        }
+
+    // Set frame buffer to NULL for all buffers
+    for( TInt i = 0; i < iRequestedBufferCount; i++ )
+        {
+        TInt err = KErrNone;
+        // Does not leave when framebuffer is set to NULL
+        // Both type of buffers needs to be nulled
+        TRAP( err, iAllocatedBuffers[i]->SetFrameBufferL( ( MCameraBuffer* )NULL ));
+		TRAP( err, iAllocatedBuffers[i]->SetFrameBufferL( ( MFrameBuffer* )NULL ));        }
+
+    // All pre-created buffers are free again
+    iRequestedBufferCount = 0;
+
+    if( iFbsStarted )
+        {
+        RFbsSession::Disconnect();
+        iFbsStarted = EFalse;
+        }
+
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SourceThreadLogoff() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::SourcePrimeL
+// -----------------------------------------------------------------------------
+//
+TInt CVSDataSourceImp::SourcePrimeL()
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SourcePrimeL() >>"), RThread().Id().operator TUint()));
+    TRAPD( result, DataProvider().SourcePrimeL() );
+    if( ( result == KErrNone ) || ( result == KRequestPending ) )
+        {
+        iDSState = CVSDataSourceImp::EPrimed;
+        }
+    else
+        {
+        User::Leave( result );
+        }
+    iProtoInitOngoing = EFalse;
+    // If provider switch was requested when Proto was  initializing itself then
+    // fill switch request now
+    iProtoInitCS.Wait();
+    if ( iProviderSwitchRequestDuringProtoInit )
+        {
+        __IF_DEBUG(Print(_L("PROTOCOL INIT READY, NOW COMPLETING THE SWITCH REQUEST")));
+        iProviderSwitchRequestDuringProtoInit = EFalse;
+        iProviderSwitchAO->InitiateProviderSwitch( iNewProvider );
+        iNewProvider = NULL;
+        }
+    iProtoInitCS.Signal();
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SourcePrimeL() <<"), RThread().Id().operator TUint()));
+    return result;
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::SourcePlayL
+// -----------------------------------------------------------------------------
+//
+TInt CVSDataSourceImp::SourcePlayL()
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SourcePlayL() >>"), RThread().Id().operator TUint()));
+    if( !iSwitchOngoing )
+        {
+        DataProvider().SourcePlayL();
+        }
+    else
+        {
+        __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SourcePlayL(): Switch ongoing -> updating state only, play will be called after switch"), RThread().Id().operator TUint()));
+        }
+    iDSState = CVSDataSourceImp::EPlaying;
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SourcePlayL() <<"), RThread().Id().operator TUint()));
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::SourcePauseL
+// -----------------------------------------------------------------------------
+//
+TInt CVSDataSourceImp::SourcePauseL()
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SourcePauseL() >>"), RThread().Id().operator TUint()));
+    if( !iSwitchOngoing )
+        {
+        DataProvider().SourcePauseL();
+        }
+    else
+        {
+        __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SourcePlayL(): Switch ongoing -> updating state only"), RThread().Id().operator TUint()));
+        }
+    iDSState = CVSDataSourceImp::EPrimed;
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SourcePauseL() <<"), RThread().Id().operator TUint()));
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::SourceStopL
+// -----------------------------------------------------------------------------
+//
+TInt CVSDataSourceImp::SourceStopL()
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SourceStopL() >>"), RThread().Id().operator TUint()));
+    if( !iSwitchOngoing )
+        {
+        DataProvider().SourceStopL();
+        }
+    else
+        {
+        __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SourcePlayL(): Switch ongoing -> updating state only"), RThread().Id().operator TUint()));
+        }
+    iDSState = CVSDataSourceImp::EStopped;
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SourceStopL() <<"), RThread().Id().operator TUint()));
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::ConstructSourceL
+// -----------------------------------------------------------------------------
+//
+void CVSDataSourceImp::ConstructSourceL( const TDesC8& /*aInitData*/ )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::ConstructSourceL() >>"), RThread().Id().operator TUint()));
+    iYuv420PlanarDesc.Zero();
+    iYuv420PlanarDesc.Append( KVtVideoMIMETypeYUV420 );
+    User::LeaveIfError( iProtoMimeTypes.Append( &iYuv420PlanarDesc ) );
+    iProviderSwitchAO = CVSProviderSwitchAO::NewL( this );
+    iDataSourceObserverAO = new (ELeave) CVSDataSourceObserverAO();
+    iSupportedVideoFormats =
+        new (ELeave) CDesC8ArrayFlat( KNoOfSupportedFormats );
+    // Get formats supported by all providers
+    CVSDataProvider::EnumerateVideoFrameFormatsL( iSupportedVideoFormats );
+    // Get video frame sizes for specified format supported by all providers
+    TInt i, j;
+    i = j = 0;
+    for ( i = 0; i < iSupportedVideoFormats->Count(); i++ )
+        {
+        TPtrC8 format = iSupportedVideoFormats->MdcaPoint( i );
+        RArray<TSize> sizeArray;
+        CleanupClosePushL( sizeArray );
+        CVSDataProvider::EnumerateVideoFrameSizesL( sizeArray, format );
+        for ( j = 0; j < sizeArray.Count(); j++ )
+            {
+            TVSFrameSize sizePerFormat;
+            sizePerFormat.iFormat.Set( format );
+            sizePerFormat.iSize = sizeArray[j];
+            User::LeaveIfError( iSupportedVideoSizes.Append( sizePerFormat ) );
+            }
+        CleanupStack::PopAndDestroy(); // sizeArray
+        }
+    // Get video frame rates for specified frame format and size supported
+    // by all providers
+    for ( i = 0; i < iSupportedVideoSizes.Count(); i++ )
+        {
+        RArray<TReal32> rateArray;
+        CleanupClosePushL( rateArray );
+        CVSDataProvider::EnumerateVideoFrameRatesL(
+            rateArray,
+            iSupportedVideoSizes[i].iFormat,
+            iSupportedVideoSizes[i].iSize );
+        for ( j = 0; j < rateArray.Count(); j++ )
+            {
+            TVSFrameRate framePerSizeAndFormat;
+            framePerSizeAndFormat.iFormat.Set(
+                iSupportedVideoSizes[i].iFormat );
+            framePerSizeAndFormat.iSize = iSupportedVideoSizes[i].iSize;
+            framePerSizeAndFormat.iRate = rateArray[j];
+            User::LeaveIfError( iSupportedFrameRates.Append(
+                framePerSizeAndFormat ) );
+            }
+        CleanupStack::PopAndDestroy(); // rateArray
+        }
+    // Create queue criticalsection
+    User::LeaveIfError( iQueueCs.CreateLocal() );
+    // Create VTEng-Protocol guard
+    User::LeaveIfError( iPauseCs.CreateLocal() );
+    // Pre-create buffers
+    for( i = 0; i < KNoOfSupportedBuffers; i++ )
+        {
+        User::LeaveIfError( iFreeQueue.Append( 0 ) );
+        User::LeaveIfError( iActiveQueue.Append( 0 ) );
+        CVSMMFDataBuffer* buffer = CVSMMFDataBuffer::NewL( KSourceBufferSize );
+        CleanupStack::PushL( buffer );
+        User::LeaveIfError( iAllocatedBuffers.Append( buffer ) );
+        CleanupStack::Pop(); // buffer
+        }
+    for( i = 0; i < KNoOfSupportedBuffers; i++ )
+        {
+        iFreeQueue.Remove( 0 );
+        iActiveQueue.Remove( 0 );
+        }
+    // Init critical sections
+    User::LeaveIfError( iProtoInitCS.CreateLocal() );
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::ConstructSourceL() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::GetMultimediaTypesL
+// -----------------------------------------------------------------------------
+//
+const RArray<TDesC8*>& CVSDataSourceImp::GetMultimediaTypesL() const
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::GetMultimediaTypeL() >>"), RThread().Id().operator TUint()));
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::GetMultimediaTypeL() <<"), RThread().Id().operator TUint()));
+    return iProtoMimeTypes;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::SetFormatL
+// -----------------------------------------------------------------------------
+//
+void CVSDataSourceImp::SetFormatL( const TDesC8& aFormat )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SetFormatL() >>"), RThread().Id().operator TUint()));
+    if ( &DataProvider() == NULL )
+        {
+        User::Leave( KErrBadHandle );
+        }
+    TBool supported = EFalse;
+    for ( TInt i = 0; i < iSupportedVideoFormats->Count(); i++ )
+        {
+        TPtrC8 format = iSupportedVideoFormats->MdcaPoint( i );
+        if ( aFormat == format )
+            {
+            supported = ETrue;
+            break;
+            }
+        }
+    if ( !supported )
+        {
+        User::Leave( KErrNotSupported );
+        }
+    DataProvider().SetFormatL( aFormat );
+    delete iFormat; iFormat = 0;
+    iFormat = aFormat.AllocL();
+    iCallFlags |= ESetFormatCalled;
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SetFormatL() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::SetFrameRateL
+// -----------------------------------------------------------------------------
+//
+void CVSDataSourceImp::SetFrameRateL( TReal32 aFrameRate )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SetFrameRateL() >>"), RThread().Id().operator TUint()));
+    if ( &DataProvider() == NULL )
+        {
+        User::Leave( KErrBadHandle );
+        }
+    TBool supported = EFalse;
+    for ( TInt i = 0; i < iSupportedFrameRates.Count(); i++ )
+        {
+        TVSFrameRate rate = iSupportedFrameRates[i];
+        if ( rate.iFormat == iFormat->Des() && rate.iSize == iSize)
+            {
+            if ( aFrameRate == rate.iRate )
+                {
+                supported = ETrue;
+                break;
+                }
+            }
+        }
+    if ( !supported )
+        {
+        User::Leave( KErrNotSupported );
+        }
+    DataProvider().SetFrameRateL( aFrameRate );
+    iFrameRate = aFrameRate;
+    iCallFlags |= ESetFrameRateCalled;
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SetFrameRateL() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::SetVideoFrameSizeL
+// -----------------------------------------------------------------------------
+//
+void CVSDataSourceImp::SetVideoFrameSizeL( const TSize& aSize )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SetVideoFrameSizeL() >>"), RThread().Id().operator TUint()));
+    if ( &DataProvider() == NULL )
+        {
+        User::Leave( KErrBadHandle );
+        }
+    TBool supported = EFalse;
+    for ( TInt i = 0; i < iSupportedVideoSizes.Count(); i++ )
+        {
+        TVSFrameSize size = iSupportedVideoSizes[i];
+        if ( size.iFormat == iFormat->Des() )
+            {
+            if ( aSize == size.iSize )
+                {
+                supported = ETrue;
+                break;
+                }
+            }
+        }
+    if ( !supported )
+        {
+        User::Leave( KErrNotSupported );
+        }
+    DataProvider().SetVideoFrameSizeL( aSize );
+    iSize = aSize;
+    iCallFlags |= ESetSizeCalled;
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::SetVideoFrameSizeL() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::GetVideoFrameSizeL
+// -----------------------------------------------------------------------------
+//
+void CVSDataSourceImp::GetVideoFrameSizeL( TSize& aSize ) const
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::GetVideoFrameSizeL() >>"), RThread().Id().operator TUint()));
+    if ( &DataProvider() == NULL )
+        {
+        User::Leave( KErrBadHandle );
+        }
+    DataProvider().GetVideoFrameSizeL( aSize );
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::GetVideoFrameSizeL() <<"), RThread().Id().operator TUint()));
+    }
+
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::DoProviderSwitchL
+// -----------------------------------------------------------------------------
+//
+void CVSDataSourceImp::DoProviderSwitchL(
+    CVSDataProvider* aNewProvider,
+    MAsyncEventHandler& aEventHandler )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::DoProviderSwitchL() >>"), RThread().Id().operator TUint()));
+
+    iQueueCs.Wait();
+
+    // If there are entries in iActiveQueue wait until they are freed by Protocol
+    if ( iActiveQueue.Count() > 0 )
+        {
+        __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::DoProviderSwitchL(): activequeue count > 0, <<"), RThread().Id().operator TUint()));
+        iSwitchPending = ETrue;
+        iQueueCs.Signal();
+        return;
+        }
+    else
+        {
+        iSwitchPending = EFalse;
+        }
+
+    iSwitchOngoing = ETrue;
+
+    /*
+     * THE FOLLOWING CALLS USE CActiveSchedulerWait WHICH MEANS SOME OTHER
+     * OBJECT MAY RUN IN BETWEEN THE FOLLOWING CALLS I.E. THESE CALLS ARE NOT
+     * SYNCHRONOUS.
+     */
+
+    User::LeaveIfError( aNewProvider->SourceThreadLogon( aEventHandler ) );
+
+    // Is format set by the Protocol
+    if ( iCallFlags & ESetFormatCalled )
+        {
+        aNewProvider->SetFormatL( *iFormat );
+        }
+    // Is size set by the Protocol
+    if ( iCallFlags & ESetSizeCalled )
+        {
+        aNewProvider->SetVideoFrameSizeL( iSize );
+        }
+    // Is framerate set by the Protocol
+    if ( iCallFlags & ESetFrameRateCalled )
+        {
+        aNewProvider->SetFrameRateL( iFrameRate );
+        }
+    // Stop old provider
+    if ( &DataProvider() != NULL )
+        {
+        switch( iDSState )
+            {
+        case EPlaying:
+            DataProvider().SourcePauseL();
+            DataProvider().SourceStopL();
+            break;
+
+        case EPrimed:
+            DataProvider().SourceStopL();
+            break;
+
+        default:
+            break;
+            };
+        DataProvider().SourceThreadLogoff();
+        }
+
+    // Set new provider state according to current state
+    switch ( iDSState )
+        {
+        case EStopped:
+            break;
+
+        case EPrimed:
+        case EPlaying:
+            aNewProvider->PrimeL();
+
+            // check if SourcePlayL() was called during prime
+            if( iDSState == EPlaying )
+                {
+                aNewProvider->SourcePlayL();
+                aNewProvider->SwitchFrom( DataProvider() );
+                }
+            // or SourceStopL()
+            else if( iDSState == EStopped )
+                {
+                aNewProvider->SourceStopL();
+                }
+            break;
+        }
+    /*
+     * THE FOLLOWING CALLS ARE SUPPOSED TO BE SYNCHRONOUS IN THAT THEY DO NOT
+     * LET ACTIVE SCHEDULER RUN SOME OTHER OBJECT.
+     */
+
+    // Complete switch
+    CVSDataProvider* oldProvider = SwitchProvider( aNewProvider );
+
+    // Set consumer and media id
+    DataProvider().SetFillBufferParams(
+        oldProvider->Consumer(),
+        oldProvider->MediaId() );
+
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::DoProviderSwitchL(): iFreeQueue.Count() = %d, iActiveQueue.Count() = %d"), RThread().Id().operator TUint(), iFreeQueue.Count(), iActiveQueue.Count() ));
+
+    // If old provider has pending FillBufferL() calls -> call FillBufferL()
+    // for new provider if it is in Playing state.
+	if( iDSState == EPlaying )
+		{
+        for ( TInt i = 0; i < iFreeQueue.Count(); i++ )
+            {
+            iFreeQueue[ i ]->Reset();
+            DataProvider().FillBufferL(
+                iFreeQueue[i],
+                DataProvider().Consumer(),
+                DataProvider().MediaId() );
+    		}
+        }
+
+    // Buffers that are being used by Protocol are set to be needing a reset
+    for ( TInt i = 0; i < iActiveQueue.Count(); i++ )
+        {
+        iActiveQueue[ i ]->SetNeedsReset( ETrue );
+        }
+
+    iSwitchOngoing = EFalse;
+
+    iQueueCs.Signal();
+
+    iDataSourceObserverAO->vsProviderSwitchDone( Observer(), oldProvider );
+    iProviderSwitchAO->NewDataProvider() = NULL;
+
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::DoProviderSwitchL() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::CVSDataSourceImp
+// -----------------------------------------------------------------------------
+//
+void CVSDataSourceImp::ProviderSwitchError( TInt aError )
+    {
+    DataProvider().NotifyError( aError );
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::CVSDataSourceImp
+// -----------------------------------------------------------------------------
+//
+CVSDataSourceImp::CVSDataSourceImp()
+: iFreeQueue( KNoOfSupportedBuffers ), iActiveQueue( KNoOfSupportedBuffers )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::CVSDataSourceImp() >>"), RThread().Id().operator TUint()));
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::CVSDataSourceImp() <<"), RThread().Id().operator TUint()));
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::GetBufferL
+// -----------------------------------------------------------------------------
+//
+CVSMMFDataBuffer* CVSDataSourceImp::GetBufferL( TBool aRemove )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::GetBufferL() >>"), RThread().Id().operator TUint()));
+    if( !iQueueCs.IsBlocked() )
+        {
+        iPauseCs.Wait();
+        const TBool sendingPaused( iSendingPaused );
+        iPauseCs.Signal();
+
+        iQueueCs.Wait();
+
+        // while switch is pending, always return NULL we don't want to let
+        // buffer float around
+        if( iSwitchPending || sendingPaused )
+            {
+            iQueueCs.Signal();
+            __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::GetBufferL(): Switch pending or sending paused -> returning NULL"), RThread().Id().operator TUint()));
+            return 0;
+            }
+
+        // If no buffers in free (FillBufferL is called) queue -> return NULL
+        if( !iFreeQueue.Count() )
+            {
+            iQueueCs.Signal();
+            __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::GetBufferL(): NO free buffers -> returning NULL"), RThread().Id().operator TUint()));
+            return 0;
+            }
+        // Otherwise get first buffer
+        CVSMMFDataBuffer* temp = iFreeQueue[ 0 ];
+        // Move to active (BufferFilledL is called) queue if requested
+        if( aRemove )
+            {
+            iFreeQueue.Remove( 0 );
+            TInt err = iActiveQueue.Append( temp );
+            if ( err != KErrNone )
+                {
+                iQueueCs.Signal();
+                User::Leave( err );
+                }
+            }
+        iQueueCs.Signal();
+        __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::GetBufferL() returning [$%x]"), RThread().Id().operator TUint(), temp));
+        return temp;
+        }
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::GetBufferL(): blocked, returning [$%08x]"), RThread().Id().operator TUint(), 0));
+    return 0;
+    }
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::FreeBufferL
+// -----------------------------------------------------------------------------
+//
+void CVSDataSourceImp::FreeBufferL( CVSMMFDataBuffer* aBuffer )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::FreeBufferL() >>"), RThread().Id().operator TUint()));
+    iQueueCs.Wait();
+    TInt err = FreeBufferNoWait( aBuffer );
+    iQueueCs.Signal();
+    User::LeaveIfError( err );
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::FreeBufferL() <<"), RThread().Id().operator TUint()));
+    }
+
+
+// -----------------------------------------------------------------------------
+// CVSDataSourceImp::FreeBufferNoWait( CVSMMFDataBuffer* aBuffer )
+// -----------------------------------------------------------------------------
+//
+TInt CVSDataSourceImp::FreeBufferNoWait( CVSMMFDataBuffer* aBuffer )
+    {
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::FreeBufferNoWait() >>"), RThread().Id().operator TUint()));
+
+    // Append buffer into free (FillBufferL is called) queue
+    TInt err( KErrNone );
+
+    // Try finding buffer from active (BufferFilledL is called) queue
+    TInt actIdx = iActiveQueue.Find( aBuffer );
+
+    // If it is found, remove it from there
+    if( actIdx != KErrNotFound )
+        {
+        iActiveQueue.Remove( actIdx );
+        TRAP( err, aBuffer->ReleaseL() );
+        if( err != KErrNone )
+            {
+            return err;
+            }
+        }
+
+    if( iFreeQueue.Find( aBuffer ) == KErrNotFound )
+        {
+        err = iFreeQueue.Append( aBuffer );
+        }
+
+#ifdef _DEBUG
+    TBuf<256> b;
+    TInt i;
+    b = _L("Active: ");
+    for( i = 0; i < iActiveQueue.Count(); i++ )
+        {
+        if( i > 0 )
+            {
+            b.Append( _L(", ") );
+            }
+        TBuf<16> b1;
+        b1.Format( _L("[$%08x]"), iActiveQueue[i] );
+        b.Append( b1 );
+        }
+    RDebug::Print( b );
+
+    b = _L("Free  : ");
+    for( i = 0; i < iFreeQueue.Count(); i++ )
+        {
+        if( i > 0 )
+            {
+            b.Append( _L(", ") );
+            }
+        TBuf<16> b1;
+        b1.Format( _L("[$%08x]"), iFreeQueue[i] );
+        b.Append( b1 );
+        }
+    RDebug::Print( b );
+#endif
+    __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::FreeBufferNoWait() <<"), RThread().Id().operator TUint()));
+
+    return err;
+    }
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+//  End of File