diff -r 000000000000 -r 1bce908db942 multimediacommsengine/tsrc/MMCTestDriver/MCETester/src/TCmdUpdateSession.cpp --- /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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void TCmdUpdateSession::ExecuteL() + { + // ---------- Setup -------------------------------------------------------- + + // Get session + CMceSession* session = + reinterpret_cast(GetObjectForIdL(KSessionId, ETrue)); + const RPointerArray& 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(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& 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 ( &audioStream->BoundStreamL()); + + const RPointerArray& 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(streams[i]); + + //Select specified codec + if (selectedCodec.Compare( KNullDesC8 ) != 0) + { + DoVideoCodecSelectionL( *videoStream, &selectedCodec ); + } + + const RPointerArray& 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 ( &videoStream->BoundStreamL()); + + const RPointerArray& 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& 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& 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; + } + } + } + + }