multimediacommsengine/tsrc/MMCTestDriver/MCETester/src/TCmdUpdateSession.cpp
changeset 0 1bce908db942
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommsengine/tsrc/MMCTestDriver/MCETester/src/TCmdUpdateSession.cpp	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,461 @@
+/*
+* Copyright (c) 2005 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
+*
+*/
+
+
+
+#include "MCEConstants.h"
+#include "TCmdUpdateSession.h"
+#include "CTcMCEContext.h"
+
+#include <mcedefs.h>
+#include <MCESession.h>
+#include <MceMediaStream.h>
+#include <MceAudioStream.h>
+#include <MceVideoStream.h>
+
+#include <MCERtpSource.h>
+#include <MCEMicSource.h>
+#include <mcefilesource.h>
+#include <MceMediaSink.h>
+#include <MCESpeakerSink.h>
+#include <mcedisplaysink.h>
+#include <mcefilesink.h>
+#include <MCEAMRCodec.h>
+#include <MceCodec.h>
+#include <MceVideoCodec.h>
+#include <MceAvcCodec.h>
+
+void TCmdUpdateSession::ExecuteL()
+	{	
+	// ---------- Setup --------------------------------------------------------
+
+	// Get session
+	CMceSession* session = 
+		reinterpret_cast<CMceSession*>(GetObjectForIdL(KSessionId, ETrue));
+	const RPointerArray<CMceMediaStream>& streams = session->Streams();
+
+	TInt keepAliveTimer = ExtractIntegerL( KParamKeepAliveValue, 0, EFalse );
+	keepAliveTimer = Max( 0, keepAliveTimer );
+	keepAliveTimer = Min( KMaxTUint8, keepAliveTimer );
+	
+	TBool setDtmfPri = ExtractBooleanL( KParamSetDtmfPri, EFalse );	
+	
+	_LIT8( DTMF, "telephone-event" );	
+	//source path for audiofile
+	TPtrC8 pathAudioFile = ExtractTextL( KParamAudioFileSource, EFalse );
+	
+	//get path for media file sink
+	TPtrC8 mediaFileSink = ExtractTextL( KParamMediaFileSink, EFalse );
+	
+	TPtrC8 selectedCodec = ExtractTextL( KParamSelectCodec, EFalse );
+	
+	//get the inactivity timer value for rtp source
+	TInt rtpInactivityTimer = ExtractIntegerL(KParamRTPInactivityTimer, 0, EFalse);
+		
+	for ( TInt i = 0; i < streams.Count(); ++i )
+        {        
+        CMceMediaStream* tmpStream;
+        tmpStream = streams[i];        
+        // Setting the Audio Stream
+        if ( streams[i]->Type() == KMceAudio )
+            {
+
+            CMceAudioStream* audioStream = 
+                                    static_cast<CMceAudioStream*>(streams[i]);                                    
+			
+            //setting the media file source for the stream
+            if (pathAudioFile.Compare( KNullDesC8 ) != 0) 
+	            {		            
+	           //Setting FileSource if the parameter has been set
+		        if ( streams[i]->Source()->Type() == KMceMicSource) 
+			        {
+			        iSessionHelper.SetMediaFileSourceL( iContext.MCEManager(), *tmpStream, pathAudioFile);
+		    	    }
+		    	else if ( audioStream->BoundStream() ) 
+			    	{
+			    	iSessionHelper.SetMediaFileSourceL( iContext.MCEManager(), tmpStream->BoundStreamL(), pathAudioFile);
+			    	}
+				else
+					{
+					// Keep pc-lint happy
+					}
+	            }            
+         
+          	const RPointerArray<CMceAudioCodec>& codecsMain =  audioStream->Codecs();
+    	
+	    	for (TInt j = codecsMain.Count()-1; j >= 0;  j--)
+				{
+				if (setDtmfPri && codecsMain[j]->SdpName().Compare(DTMF))
+					{
+					iSessionHelper.SetCodecPrioritiesL(*codecsMain[j], iSessionHelper.dtmf);
+					}
+				if ( audioStream->Source()->Type() == KMceRTPSource )
+	          		{
+	          		// set priority for downlink
+	          		iSessionHelper.SetCodecPrioritiesL(*codecsMain[j], iSessionHelper.downlink);
+	          		}
+	          	else
+	          		{
+	          		// set priority for uplink
+	          		iSessionHelper.SetCodecPrioritiesL(*codecsMain[j], iSessionHelper.uplink);
+	          		
+					if ( keepAliveTimer )
+						{
+						iSessionHelper.SetKeepaliveL(*codecsMain[j], keepAliveTimer );
+						}	
+	          		}      
+				}
+       	
+	    	//setting priorities for bound stream
+           	if (audioStream->BoundStream())
+              	{
+              	CMceAudioStream* audioStreamBound = 
+                                    static_cast<CMceAudioStream*> ( &audioStream->BoundStreamL());
+              	
+              	const RPointerArray<CMceAudioCodec>& codecs =  audioStreamBound->Codecs();
+    	  
+    	        for (TInt j = codecs.Count()-1; j >= 0;  j--)
+					{
+					if (setDtmfPri && codecs[j]->SdpName().Compare(DTMF))
+						{
+						iSessionHelper.SetCodecPrioritiesL(*codecs[j], iSessionHelper.dtmf);
+						}
+					if ( audioStream->BoundStreamL().Source()->Type() == KMceRTPSource )
+	              		{
+	              		// set priority for downlink
+	              		iSessionHelper.SetCodecPrioritiesL(*codecs[j], iSessionHelper.downlink);
+	              		}
+              		else
+	              		{
+	              		// set priority for uplink
+	              		iSessionHelper.SetCodecPrioritiesL(*codecs[j], iSessionHelper.uplink);
+	                	if ( keepAliveTimer )
+	            			{
+	                		iSessionHelper.SetKeepaliveL(*codecs[j], keepAliveTimer );
+							}
+	              		}
+            		}
+				}
+				
+            }
+        
+        // Setting the Video Stream
+        if ( streams[i]->Type() == KMceVideo )
+            {
+
+            CMceVideoStream* videoStream = 
+                                    static_cast<CMceVideoStream*>(streams[i]);
+            
+            //Select specified codec
+            if (selectedCodec.Compare( KNullDesC8 ) != 0) 
+		        {
+		        	DoVideoCodecSelectionL( *videoStream, &selectedCodec );
+		        }
+            
+           	const RPointerArray<CMceVideoCodec>& codecsMainVideo =  videoStream->Codecs(); 
+	    	for (TInt j = codecsMainVideo.Count()-1; j >= 0;  j--)
+				{
+				if ( videoStream->Source()->Type() == KMceRTPSource )
+	          		{
+	          		// set priority for downlink
+	          		iSessionHelper.SetCodecPrioritiesL(*codecsMainVideo[j],
+	          										   iSessionHelper.downlink);
+	          		}
+	          	else
+	          		{
+	          		// set priority for uplink
+	          		iSessionHelper.	SetCodecPrioritiesL(*codecsMainVideo[j],
+	          											iSessionHelper.uplink);
+	            	if ( keepAliveTimer )
+	            		{
+	            		((CMceCodec*)codecsMainVideo[j])->SetKeepAliveTimerL(
+	            			keepAliveTimer );
+	            		}
+	          		}      
+				}
+          	
+           	if(videoStream->BoundStream())
+              	{
+              	CMceVideoStream* videoStreamBound = 
+                                    static_cast<CMceVideoStream*> ( &videoStream->BoundStreamL());
+              	
+              	const RPointerArray<CMceVideoCodec>& codecsv =  videoStreamBound->Codecs();  
+    	        for (TInt j = codecsv.Count()-1; j >= 0;  j--)
+					{
+					if ( videoStream->BoundStreamL().Source()->Type() == KMceRTPSource )
+	              		{
+	              		// set priority for downlink
+	              		iSessionHelper.SetCodecPrioritiesL(*codecsv[j], iSessionHelper.downlink);
+	              		}
+              		else
+	              		{
+	              		// set priority for uplink
+	              		iSessionHelper.SetCodecPrioritiesL(*codecsv[j], iSessionHelper.uplink);
+	                	if ( keepAliveTimer )
+	            			{
+	                		((CMceCodec*)codecsv[j])->SetKeepAliveTimerL( keepAliveTimer );
+	              			}
+	              		}
+            		}
+				}
+            }
+        
+        //set Inactivity timer for RTP source for each stream
+        if( rtpInactivityTimer != 0 )
+        	iSessionHelper.SetRtpInactivityTimerL(*tmpStream, rtpInactivityTimer);
+        }
+
+	// ---------- Execution ----------------------------------------------------
+   
+	//setting the media file sink
+	 if (mediaFileSink.Compare( KNullDesC8 ) != 0) 
+		{
+		SetMediaFileSinkL( *session, &mediaFileSink);
+		}
+	 
+	// Get timeout 
+	TInt timeout = ExtractIntegerL( KParamTimeout, 0, EFalse );
+    // Timeout is given to API in milliseconds, but is going to change to 
+    // seconds, so translate it here instead of TTCN
+    //timeout = 1000 * timeout; 
+    
+	// Get ContentType
+	HBufC8* contentType = HBufCParameterL(ExtractTextL(KParamContentType, 
+													   EFalse));
+	CleanupStack::PushL( contentType );
+	
+	// Get Headers
+	CDesC8Array* headers = ExtractHeadersL( EFalse );
+	if (!headers)
+		{
+		headers = new (ELeave) CDesC8ArrayFlat(1);	
+		}
+	headers->AppendL(_L8("event: ttcn"));	
+	CleanupStack::PushL( headers );
+	// Get Content
+	HBufC8* body = HBufCParameterL(ExtractTextL(KParamBody, EFalse));
+	CleanupStack::PushL( body );
+	
+	// Get ContentHeaders
+	CDesC8Array* contentHeaders = ExtractArrayL(KParamContentHeaders, EFalse );
+	CleanupStack::PushL(contentHeaders);
+	
+	if ( !headers && !body && !contentType &&contentHeaders->Count()<=0 && timeout == 0 )
+		{
+		CleanupStack::PopAndDestroy( contentHeaders); contentHeaders = NULL;
+		CleanupStack::PopAndDestroy( body ); body = NULL;
+		CleanupStack::PopAndDestroy( headers ); headers = NULL;
+		CleanupStack::PopAndDestroy( contentType ); contentType = NULL;
+		session->UpdateL();
+		}
+	else
+		{
+		session->UpdateL( timeout, headers, contentType, body, contentHeaders );
+		CleanupStack::Pop( contentHeaders);
+		CleanupStack::Pop( body );
+		CleanupStack::Pop( headers );
+		CleanupStack::Pop( contentType );	
+		}
+
+
+	CMceSession::TState state = session->State();	
+		
+	// ---------- Response creation --------------------------------------------
+
+
+ 	AddIdResponseL( KSessionId, *session );
+ 
+	// Add Session state	
+	AddIntegerResponseL( KResponseState, state );
+	AddTextualSessionStateL( state );
+
+	}
+	
+TBool TCmdUpdateSession::Match( const TTcIdentifier& aId )
+	{
+	return TTcMceCommandBase::Match( aId, _L8("UpdateSession") );
+	}
+
+TTcCommandBase* TCmdUpdateSession::CreateL( MTcTestContext& aContext )
+	{
+	return new( ELeave ) TCmdUpdateSession( aContext );
+	}
+	
+void TCmdUpdateSession::DoVideoCodecSelectionL( CMceVideoStream& aVideoStream, TPtrC8* aCodec  )	
+	{	
+	const RPointerArray<CMceVideoCodec>& codecs = aVideoStream.Codecs();
+    
+    if(aCodec->FindF(KMceSDPNameH264())!= KErrNotFound )
+	    {
+	    //Select only the H264 codec	   
+	    const CMceVideoCodec* avcSingleNal = NULL;
+	    const CMceVideoCodec* avcNonInterleaved = NULL;
+	    
+	    for ( TInt codecIndex = 0; codecIndex < codecs.Count(); ++codecIndex )
+	        {
+	        if ( codecs[codecIndex]->SdpName() == KMceSDPNameH264() )
+	            { 
+	            if ( codecs[codecIndex]->CodecMode() == KMceAvcModeSingleNal )
+	                {
+	                // Store a pointer to the Single NAL codec with best bitrate
+	                if ( !avcSingleNal || 
+	                     ( avcSingleNal && codecs[codecIndex]->MaxBitRate() > 
+	                                       avcSingleNal->MaxBitRate() ) )
+	                    {
+	                    avcSingleNal = codecs[codecIndex];
+	                    }
+	                }  
+	            else if ( codecs[codecIndex]->CodecMode() == 
+	                                                KMceAvcModeNonInterleaved )
+	                {
+	                // Store a pointer to the Non-Interleaved codec with best bitrate
+	                if ( !avcNonInterleaved || 
+	                     ( avcNonInterleaved && codecs[codecIndex]->MaxBitRate() > 
+	                                            avcNonInterleaved->MaxBitRate() ) )
+	                    {
+	                    avcNonInterleaved = codecs[codecIndex];
+	                    }
+	                }
+	            else 
+	                {
+	                // NOP, we do not care about interleaved AVC
+	                }
+	            }
+	        }
+	    
+	    const CMceVideoCodec* selectedCodec = NULL;
+	    
+	    if ( avcNonInterleaved )
+	        {
+	        selectedCodec = avcNonInterleaved;
+	        }
+	    else
+	        {
+	        selectedCodec = avcSingleNal;
+	        }
+	   
+	    if ( selectedCodec )
+	        {
+	        // Remove all other codecs
+	        for ( TInt codecIndex = 0; codecIndex < codecs.Count(); ++codecIndex )
+	            {
+	            if ( codecs[codecIndex] != selectedCodec )
+	                {
+	                aVideoStream.RemoveCodecL( *codecs[codecIndex] );
+	                // Since succesfull removal of a codec has decreased the amount
+	                // of codecs in array by one, we have to reset the index
+	                codecIndex = 0;
+	                }
+	            }   
+	        }
+	    }
+	    else
+	    {
+	   	//select others codecs
+	    TBool codecModeBasedRemovalNeeded( EFalse );
+
+		//check first if the codec is present
+	    for ( TInt codecIndex = 0; codecIndex < codecs.Count(); ++codecIndex )
+	        {
+	        const CMceVideoCodec& currentCodec = *codecs[codecIndex];
+	        if ( aCodec->FindF(  currentCodec.SdpName()) != KErrNotFound )
+	           	codecModeBasedRemovalNeeded = ETrue; 	            		            		      
+			}
+	    
+	    //remove codecs
+	    if( codecModeBasedRemovalNeeded )
+	    	{	    	    
+		    for ( TInt codecIndex = 0; codecIndex < codecs.Count(); ++codecIndex )
+		        {
+		        const CMceVideoCodec& currentCodec = *codecs[codecIndex];
+		        if ( aCodec->FindF( currentCodec.SdpName()) == KErrNotFound )
+		           	aVideoStream.RemoveCodecL( *codecs[codecIndex] );    		            		      
+				}
+	    	}
+	    }
+
+	}
+
+
+void TCmdUpdateSession::SetMediaFileSinkL( CMceSession& aSession, TPtrC8* aFile )
+	{
+	TBool video(EFalse);
+	TBool audio(EFalse);
+	if( aFile->Find(_L8(".mp4")) != KErrNotFound )
+		video = ETrue;
+	if( aFile->Find(_L8(".3gp")) != KErrNotFound )
+		audio = ETrue;
+	
+	const RPointerArray<CMceMediaStream>& streams = aSession.Streams();
+	
+	for ( TInt i = 0; i < streams.Count(); ++i )
+        {        
+        CMceMediaStream* tmpStream;
+        tmpStream = streams[i];        
+        if( video )
+        	{
+			if ( tmpStream->Type() == KMceVideo )
+				{
+				CMceVideoStream* videoOutStreamFile = CMceVideoStream::NewL();
+				CleanupStack::PushL( videoOutStreamFile );
+				
+				//use the same source which was used for outgoing video stream	
+				if( tmpStream->Source()->Type() != KMceRTPSource )
+					{
+					videoOutStreamFile->SetSourceL( tmpStream->Source() );
+					}
+				else
+					{
+					if( tmpStream->BoundStream() )
+						if( tmpStream->BoundStreamL().Source()->Type() != KMceRTPSource )
+							videoOutStreamFile->SetSourceL(tmpStream->BoundStreamL().Source());
+					}
+				
+				iSessionHelper.SetMediaFileSinkL(*videoOutStreamFile, *aFile);
+				aSession.AddStreamL( videoOutStreamFile );
+				CleanupStack::Pop( videoOutStreamFile );				
+				break;	//only one file sink can be added for testing
+				}
+        	}
+        if( audio )
+			{
+			if ( tmpStream->Type() == KMceAudio )
+				{
+				CMceAudioStream* audioOutStreamFile = CMceAudioStream::NewL();
+				CleanupStack::PushL( audioOutStreamFile );
+				
+				//use the same source which was used for outgoing audio stream	
+				if( tmpStream->Source()->Type() != KMceRTPSource )
+					{
+					audioOutStreamFile->SetSourceL( tmpStream->Source() );
+					}
+				else
+					{
+					if(tmpStream->BoundStream())
+						if( tmpStream->BoundStreamL().Source()->Type() != KMceRTPSource )
+							audioOutStreamFile->SetSourceL(tmpStream->BoundStreamL().Source());
+					}
+				
+				iSessionHelper.SetMediaFileSinkL(*audioOutStreamFile, *aFile);
+				aSession.AddStreamL( audioOutStreamFile );
+				CleanupStack::Pop( audioOutStreamFile );				
+				break;
+				}
+			}
+        }
+	
+	}