diff -r 000000000000 -r 71ca22bcf22a mmfenh/enhancedmediaclient/Client/src/Components/ClientDataBufferSource/ClientDataBufferSource.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmfenh/enhancedmediaclient/Client/src/Components/ClientDataBufferSource/ClientDataBufferSource.cpp Tue Feb 02 01:08:46 2010 +0200 @@ -0,0 +1,527 @@ +/* +* 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: Implementation of the ClientDataBufferSource class. +* +*/ + + + +#include "ClientDataBufferSource.h" +#include "DataBufferQueueItem.h" +#include "DataBufferSourceCustomCommands.h" +#include "EventNotifier.h" +#include "DataBufferProcessedEvent.h" +#include "DataBufferSourceUid.h" +#include "DRMConfigIntfcImpl.h" + +#include +#include +#include +#include +#include +#include "tracemacros.h" + +#define RETURN_IF_ERROR(x) if(x != KErrNone) return x + +using namespace multimedia; + +// CONSTANTS +const TInt KMinBufferSize = 5120; + + +CClientDataBufferSource::CClientDataBufferSource() +:iDRMType(ENone) + { + iFixedDurationSupport = false; + } + +CClientDataBufferSource::~CClientDataBufferSource() + { + delete iMimeType; + EmptyQueue(); + delete iEventNotifier; + delete iAudioBufferQueue; + delete iBufTypeSupportEvent; + iAllowedOutputDeviceList.Close(); + } + +TInt CClientDataBufferSource::PostConstructor() + { + TInt status(KErrNone); + // Make sure this doesn't get called second time around. + if ( !iEventNotifier ) + { + TRAP(status, iEventNotifier = CEventNotifier::NewL()); + } + + RETURN_IF_ERROR(status); + + iAudioBufferQueue = new TSglQue(_FOFF(CDataBufferQueueItem, iLink)); + if (!iAudioBufferQueue) + { + status = KErrNoMemory; + } + RETURN_IF_ERROR(status); + + TRAP(status,iBufTypeSupportEvent = CBufTypeSupEventAO::NewL(*this)); + + return status; + } + +TInt CClientDataBufferSource::AddObserver( MControlObserver& aObserver ) + { + return iEventNotifier->AddObserver( aObserver ); + } + +TInt CClientDataBufferSource::RemoveObserver( MControlObserver& aObserver ) + { + return iEventNotifier->RemoveObserver( aObserver ); + } + +TUid CClientDataBufferSource::Type() + { + return KDataBufferSourceControl; + } + +TControlType CClientDataBufferSource::ControlType() + { + return ESourceControl; + } + +TInt CClientDataBufferSource::GetSize( TUint& aSize ) + { + TInt status(KErrNone); + aSize = iSourceSize; + return status; + } + +TInt CClientDataBufferSource::GetMimeType( TDes8& aMimeType ) + { + aMimeType.Copy(*iMimeType); + return KErrNone; + } + +TInt CClientDataBufferSource::Close() + { + TInt status(KErrNone); + iBufferSeqNum = 0; + return status; + } + +TInt CClientDataBufferSource::Open( TDesC8& aMimeType , MDataBuffer& /*aHeaderData */) + { + TInt status(KErrNotSupported); + // Source is already attached to controller + if ( iServerSourceExists ) + { + status = KErrInUse; + } + else + { + delete iMimeType; + iMimeType = NULL; + TRAP( status, iMimeType = aMimeType.AllocL() ); + iBufferSeqNum = 0; + } + return status; + } + +TInt CClientDataBufferSource::GetMinimumBufferSize( TUint& aBufferSize ) + { + TInt status(KErrNone); + aBufferSize = KMinBufferSize; + return status; + } + +TInt CClientDataBufferSource::SetSize( TUint aSize ) + { + TInt status(KErrNone); + iSourceSize = aSize; + if ( iServerSourceExists ) + { + TPckgBuf pckg(aSize); + status = iCustomCommand->CustomCommandSync( iSourceHandlePckg, ESetSize, pckg, KNullDesC8 ); + } + return status; + } + +TInt CClientDataBufferSource::WriteData(MDataBuffer& aBuffer ) + { + EMC_TRACE3(_L("CClientDataBufferSource::WriteData:size[%d]lastbuf[%d]"), \ + aBuffer.GetBufferPtr().Length(), aBuffer.IsLastBuffer()); +/* + TUint8* bufPtr = const_cast(aBuffer.GetBufferPtr().Ptr()); + if ( aBuffer.GetBufferPtr().Length() > 5 ) + { + RDebug::Print(_L("CClientDataBufferSource::WriteData data[0x%x][0x%x][0x%x][0x%x][0x%x]"), \ + *bufPtr,*(bufPtr+1),*(bufPtr+2),*(bufPtr+3),*(bufPtr+4)); + } +*/ + + TInt status(KErrNotReady); + // For now we can only write audio data only if controller is loaded + // and source is added to controller. + if ( iServerSourceExists ) + { + // Append item to queue + CDataBufferQueueItem* item(NULL); + TRAP(status, item = CDataBufferQueueItem::NewL( *this, + aBuffer, + aBuffer.IsLastBuffer(), + iBufferSeqNum )); + RETURN_IF_ERROR(status); + + iAudioBufferQueue->AddLast(*item); + + // Send data to server source + item->SetActive(); + TPckgBuf bufSeqNum; + bufSeqNum() = iBufferSeqNum; + iCustomCommand->CustomCommandAsync( + iSourceHandlePckg, + (TInt)EProcessBuffer, + aBuffer.GetBufferPtr(), + item->GetDataBufferAttributesDesc(), + item->iStatus); + status = KErrNone; + iBufferSeqNum++; + } + return status; + } + +TInt CClientDataBufferSource::EmptyBuffers() + { + TInt status(KErrNone); + return status; + } + +TInt CClientDataBufferSource::GetBufferingConfig(TBufferingConfig& aConfig) + { + TPckgBuf pckg; + if(iServerSourceExists) + { + iCustomCommand->CustomCommandSync( iSourceHandlePckg, EGetCurrentBufferingConfig, KNullDesC8, KNullDesC8, pckg ); + aConfig = pckg(); + return KErrNone; + } + else + { + return KErrNotFound; + } + } + +TInt CClientDataBufferSource::SetBufferingConfig(TBufferingConfig aConfig) + { + TPckgBuf pckg(aConfig); + if ( iServerSourceExists) + { + iCustomCommand->CustomCommandSync( iSourceHandlePckg, ESetBufferingConfig, pckg, KNullDesC8 ); + return KErrNone; + } + else + { + return KErrNotFound; + } + } + +TInt CClientDataBufferSource::GetBitRate(TUint& aRate) + { + //Source Custom Command + TPckgBuf pckg; + if(iServerSourceExists) + { + iCustomCommand->CustomCommandSync( iSourceHandlePckg, EGetBitRate, KNullDesC8, KNullDesC8, pckg ); + aRate = pckg(); + return KErrNone; + } + else + { + aRate = 0; + return KErrNotFound; + } + } + +TInt CClientDataBufferSource::GetBufferingTypesSupported(TArray& aArray) + { + RArray temp; + temp.Array() = aArray; + temp.Append(TBufferingConfig::BUFFERINGNONE); + temp.Append(TBufferingConfig::FIXEDSIZE); + if(iFixedDurationSupport) + { + temp.Append(TBufferingConfig::FIXEDDURATION); + } + aArray = temp.Array(); + return KErrNone; + } + +TInt CClientDataBufferSource::GetInterface( + TUid aInterfaceId, + TVersion& aVer, + TAny*& aInterfaceImpl ) + { + TInt status(KErrNotFound); + aInterfaceImpl = NULL; + if ( ( aInterfaceId == KDRMConfigIntfc ) && + ( ( aVer.iMajor == KDRMConfigIntfcMajorVer1 ) && + ( aVer.iMinor == KDRMConfigIntfcMinorVer1 ) && + ( aVer.iBuild == KDRMConfigIntfcBuildVer1 ) ) ) + { + CDRMConfigIntcfImpl* temp(NULL); + TRAP(status, temp = CDRMConfigIntcfImpl::NewL(*this)); + if ( status == KErrNone ) + { + this->SetChild(*((CChildIntfc*)temp)); + temp->SetParent(*(CParentIntfc*)this); + aInterfaceImpl = (CDRMConfigIntfc*)temp; + } + } + return status; + } + +void CClientDataBufferSource::ServerSourceCreated( MCustomCommand& aCustomCommand, + TMMFMessageDestination& aSourceHandle ) + { + iServerSourceExists = ETrue; + iCustomCommand = &aCustomCommand; + iSourceHandle = aSourceHandle; + iSourceHandlePckg() = aSourceHandle; + + // Send DRM Config to server side plugin + TRAP_IGNORE( DoCommitDRMConfigL() ); + + iBufTypeSupportEvent->SetActive(); + iCustomCommand->CustomCommandAsync( + iSourceHandlePckg, + (TInt)EGetBufferingConfigSupported, + KNullDesC8, + KNullDesC8, + iBufTypeSupportEvent->iStatus); + + } + +void CClientDataBufferSource::ServerSourceDeleted() + { + iServerSourceExists = EFalse; + iCustomCommand = NULL; + // Do client buffer cleanup + // It should've already been done when server side source was deleted. + // This is just to make sure. + } + +TBool CClientDataBufferSource::IsEncrypted() + { + return KErrNotSupported; + } + +TUid CClientDataBufferSource::GetSourceUid() + { + return KMmfDataBufferSource; + } + +TInt CClientDataBufferSource::GetHeaderData(TPtr& /*aPtr*/) + { + return KErrNotSupported; + } + + +void CClientDataBufferSource::BufferProcessed( CDataBufferQueueItem* aItem ) + { + // Create a event object + CDataBufferProcessedEvent* event = new CDataBufferProcessedEvent( + &(aItem->DataBuffer()), + aItem->Error() ); + + // Remove the item from the list and delete it. + iAudioBufferQueue->Remove(*aItem); + delete aItem; + + // Send event to client that buffer is processed + iEventNotifier->Event( this, MSourceControlObserver::KBufferProcessedEvent, event ); + } + +void CClientDataBufferSource::HandleCancel( CDataBufferQueueItem& aItem ) + { + EMC_TRACE1(_L("CClientDataBufferSource::HandleCancel:")); + if ( iServerSourceExists ) + { + TPckgBuf bufSeqPckg(aItem.GetBufferSequenceNumber()); + iCustomCommand->CustomCommandSync( + iSourceHandlePckg, + (TInt)ECancel, + bufSeqPckg, + KNullDesC8 + ); + } + else + { + aItem.CompleteSelf(KErrDied); + } + } + +void CClientDataBufferSource::BufferingTypesSupportedChanged() + { + iFixedDurationSupport = true; + } + +TInt CClientDataBufferSource::SetDRMType( TDRMType aDRMType ) + { + TInt status(KErrNone); + switch (aDRMType) + { + case ENone: + case EOMA1: + case EOMA2: + case EWMDRM: + iDRMType = aDRMType; + break; + default: + status = KErrArgument; + break; + }; + return status; + } + +TInt CClientDataBufferSource::GetDRMType( TDRMType& aDRMType ) + { + TInt status(KErrNone); + aDRMType = iDRMType; + return status; + } + +TInt CClientDataBufferSource::AppendAllowedOutputDevice( TDRMAllowedOutputDevice aOutputDevice ) + { + TInt status(KErrAlreadyExists); + switch (aOutputDevice) + { + case EAudioAllowAll: + case EAudioAllowAnalog: + case EAudioAllowFMTx: + case EAudioAllowBTA2DP: + case EAudioAllowBTHFPHSP: + case EAudioAllowUplink: + case EAudioAllowUSB: + case EAudioAllowRecording: + case EAudioAllowVisualization: + /** + * RIM CR 417-7642: HDMI with HDCP to Resctricted Audio Output API + * Due to addition of new ENUMs to CRestrictedAudioOutput::TAllowedOutputPreference for HDMI and HDCP + * EAllowAudioHDMI and EAllowAudioHdmiHdcpRequired,the same is matched by adding + * EAudioAllowHDMI and EAudioAllowHdmiHdcpRequired + */ + case EAudioAllowHDMI: + case EAudioAllowHdmiHdcpRequired: + if ( iAllowedOutputDeviceList.Find( aOutputDevice ) == KErrNotFound ) + { + status = iAllowedOutputDeviceList.Append( aOutputDevice ); + } + break; + default: + status = KErrArgument; + break; + }; + return status; + } + +TInt CClientDataBufferSource::RemoveAllowedOutputDevice( TDRMAllowedOutputDevice aOutputDevice ) + { + TInt status = iAllowedOutputDeviceList.Find( aOutputDevice ); + if ( status == KErrNotFound ) + { + iAllowedOutputDeviceList.Remove(status); + status = KErrNone; + } + return status; + } + +TInt CClientDataBufferSource::GetAllowedOutputDeviceCount( TInt& aCount ) + { + TInt status(KErrNone); + aCount = iAllowedOutputDeviceList.Count(); + return status; + } + +TInt CClientDataBufferSource::GetAllowedOutputDevice( TInt aIndex, TDRMAllowedOutputDevice& aOutputDevice ) + { + TInt status(KErrArgument); + if ( aIndex <= iAllowedOutputDeviceList.Count() ) + { + aOutputDevice = iAllowedOutputDeviceList[aIndex]; + status = KErrNone; + } + return status; + } + +TInt CClientDataBufferSource::ResetDRMConfig() + { + iDRMType = ENone; + iAllowedOutputDeviceList.Reset(); + return KErrNone; + } + +TInt CClientDataBufferSource::CommitDRMConfig() + { + TInt status(KErrNone); + TRAP(status, DoCommitDRMConfigL()); + return status; + } + +void CClientDataBufferSource::EmptyQueue() + { + CDataBufferQueueItem* bufferItem; + while ( !iAudioBufferQueue->IsEmpty() ) + { + bufferItem = iAudioBufferQueue->First(); + iAudioBufferQueue->Remove(*bufferItem); + delete bufferItem; + } + } + +void CClientDataBufferSource::DoCommitDRMConfigL() + { + if ( iServerSourceExists ) + { + // Package DRM Info into a descriptor and send it to server side plugin + TInt descSize = sizeof(TDRMType); // For iDRMType + descSize += sizeof(TInt); // For array size + descSize += (iAllowedOutputDeviceList.Count() * sizeof(TDRMAllowedOutputDevice)); // For array + + HBufC8* buf(NULL); + buf = HBufC8::NewL(descSize); + CleanupStack::PushL(buf); + + RDesWriteStream stream; + TPtr8 ptr = buf->Des(); + stream.Open(ptr); + CleanupClosePushL(stream); + + // Write DRM Type + stream.WriteInt32L(iDRMType); + // Write Allowed Output Device Count + stream.WriteInt32L(iAllowedOutputDeviceList.Count()); + // Write Allowed Output Device enumeration + for (TInt i=0;iCustomCommandSync( iSourceHandlePckg, ESetDRMConfig, ptr, KNullDesC8 )); + + // Delete objects + CleanupStack::PopAndDestroy(&stream);//stream + CleanupStack::PopAndDestroy(buf);//stream + } + } + +// End of file