mmfenh/enhancedmediaclient/Client/src/Components/ClientDataBufferSource/ClientDataBufferSource.cpp
changeset 0 71ca22bcf22a
--- /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 <e32std.h>
+#include <MCustomCommand.h>
+#include <DataBuffer.h>
+#include <MimeTypes.h>
+#include <SourceControlObserver.h>
+#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<CDataBufferQueueItem>(_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<TInt> 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<TUint8*>(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<TUint> 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<TBufferingConfig> pckg;
+    if(iServerSourceExists)
+        {
+		iCustomCommand->CustomCommandSync( iSourceHandlePckg, EGetCurrentBufferingConfig, KNullDesC8, KNullDesC8, pckg );
+		aConfig = pckg();
+		return KErrNone;
+        }
+    else
+        {
+		return KErrNotFound;    
+        }
+    }
+    
+TInt CClientDataBufferSource::SetBufferingConfig(TBufferingConfig aConfig)
+    {
+	TPckgBuf<TBufferingConfig> pckg(aConfig);
+	if ( iServerSourceExists)
+		{
+		iCustomCommand->CustomCommandSync( iSourceHandlePckg, ESetBufferingConfig, pckg, KNullDesC8 );              
+		return KErrNone;    
+		}
+	else
+		{
+		return KErrNotFound;    
+		}
+    }
+    
+TInt CClientDataBufferSource::GetBitRate(TUint& aRate)
+    {
+    //Source Custom Command
+    TPckgBuf<TUint> pckg;
+    if(iServerSourceExists)
+        {
+		iCustomCommand->CustomCommandSync( iSourceHandlePckg, EGetBitRate, KNullDesC8, KNullDesC8, pckg );
+		aRate = pckg();
+		return KErrNone;
+        }
+    else
+        {
+		aRate = 0;
+		return KErrNotFound;    
+        }
+    }
+              
+TInt CClientDataBufferSource::GetBufferingTypesSupported(TArray<TBufferingConfig::TBufferingType>& aArray)
+    {
+	RArray<TBufferingConfig::TBufferingType> 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<TUint> 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;i<iAllowedOutputDeviceList.Count();i++)
+    	    {
+    		stream.WriteInt32L(iAllowedOutputDeviceList[i]);
+    	    }
+    	ptr.SetLength(descSize);
+        User::LeaveIfError(iCustomCommand->CustomCommandSync( iSourceHandlePckg, ESetDRMConfig, ptr, KNullDesC8 ));
+        
+    	// Delete objects
+    	CleanupStack::PopAndDestroy(&stream);//stream
+    	CleanupStack::PopAndDestroy(buf);//stream
+        }
+    }
+
+// End of file