diff -r c378a0498b84 -r c9ec3f2fcd87 vtprotocolplugins/VideoSource/src/CVSDataSourceImp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vtprotocolplugins/VideoSource/src/CVSDataSourceImp.cpp Thu Jul 22 16:34:21 2010 +0100 @@ -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 +#include +#include +#include + +#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( aBuffer ) ) ); + } + else if( iSwitchPending ) + { + __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::FillBufferL(): Switch pending"), RThread().Id().operator TUint())); + FreeBufferL( static_cast( 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( aBuffer ) ) ); + } + else + { + __IF_DEBUG(Print(_L("VideoSource[%d]: CVSDataSourceImp::FillBufferL(): No switch -> normal FillBufferL()"), RThread().Id().operator TUint())); + FreeBufferL( static_cast( 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 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 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& 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