multimediacommsengine/mmcesrv/mmcemediamanager/src/mceaudiosdpcodec.cpp
changeset 0 1bce908db942
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommsengine/mmcesrv/mmcemediamanager/src/mceaudiosdpcodec.cpp	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,535 @@
+/*
+* 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:    
+*
+*/
+
+
+
+
+// INCLUDE FILES
+#include <e32base.h>
+#include <e32std.h>
+#include <e32def.h>
+#include <stringpool.h>
+
+#include <sdpdocument.h>
+#include <sdpcodecstringconstants.h>
+#include <sdpcodecstringpool.h>
+#include <sdpmediafield.h>
+#include <sdpattributefield.h>
+#include <sdprtpmapvalue.h>
+#include <sdpfmtattributefield.h>
+#include <sdporiginfield.h>
+
+#include "mcemediadefs.h"
+#include "mceaudiosdpcodec.h"
+#include "mcecomaudiostream.h"
+#include "mceaudiostream.h"
+#include "mcecomaudiocodec.h"
+#include "mcemediadefs.h"
+#include "mcecomfactory.h"
+#include "mcemmlogs.h"
+#include "mcecomrtpsource.h"
+#include "mcecomspeakersink.h"
+#include "mcecommicsource.h"
+#include "mcecomrtpsink.h"
+#include "mcedefs.h"
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+
+// -----------------------------------------------------------------------------
+// CMceAudioSdpCodec::NewL
+// -----------------------------------------------------------------------------
+//
+CMceAudioSdpCodec* CMceAudioSdpCodec::NewL()
+    {
+    RStringF audio = MCE_SDP_STRING_AUDIOL();
+        
+    CMceAudioSdpCodec* self = new (ELeave) CMceAudioSdpCodec( audio );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    return self;
+    
+    }
+
+// -----------------------------------------------------------------------------
+// CMceAudioSdpCodec::CMceAudioSdpCodec
+// -----------------------------------------------------------------------------
+//
+CMceAudioSdpCodec::CMceAudioSdpCodec( RStringF aMedia )
+    : CMceMediaSdpCodec( aMedia )
+    {
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMceAudioSdpCodec::~CMceAudioSdpCodec
+// -----------------------------------------------------------------------------
+//
+CMceAudioSdpCodec::~CMceAudioSdpCodec()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CMceAudioSdpCodec::Encodes
+// -----------------------------------------------------------------------------
+//
+TBool CMceAudioSdpCodec::Encodes( const CMceComMediaStream& aStream ) const
+    {
+    return aStream.iStreamType != CMceComMediaStream::ELocalStream &&
+           aStream.iType == KMceAudio;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMceAudioSdpCodec::CodecsL
+// -----------------------------------------------------------------------------
+//
+const RPointerArray<CMceComCodec>& CMceAudioSdpCodec::CodecsL( CMceComMediaStream& aStream ) const
+    {
+    __ASSERT_ALWAYS( aStream.iType == KMceAudio, User::Leave( KErrArgument ) );
+    MCE_DEFINE_AUDIO( stream, aStream );
+
+	return reinterpret_cast< const RPointerArray< CMceComCodec >& >( stream.Codecs() );
+    }
+
+// -----------------------------------------------------------------------------
+// CMceAudioSdpCodec::EncodeRtpmapAttributeLC
+// -----------------------------------------------------------------------------
+//
+CSdpFmtAttributeField* CMceAudioSdpCodec::EncodeRtpmapAttributeLC( CMceComCodec& aCodec ) const
+    {
+    MCEMM_DEBUG( "CMceAudioSdpCodec::EncodeRtpmapAttributeLC(), Entry" )
+    MCE_DEFINE_AUDIO_CODEC( codec, aCodec );
+    
+    CSdpFmtAttributeField* rtpmapAttribute = NULL;
+    
+    TUint payloadType = codec.iPayloadType;
+    TPtrC8 codecName = codec.iSdpName; 
+    TUint samplingFreq = codec.iSamplingFreq;      
+        
+    // Create rtpmap field for current codec
+    rtpmapAttribute = EncodeRtpMapFieldsL( payloadType, 
+                                           codecName, 
+                                           samplingFreq,
+                                           KMceSdpOptionalEncodingParam );
+    
+    CleanupStack::PushL( rtpmapAttribute );
+    
+    MCEMM_DEBUG_SVALUE( "encoded rtpmap", rtpmapAttribute->Value() )
+    MCEMM_DEBUG( "CMceAudioSdpCodec::EncodeRtpmapAttributeLC(), Exit" )
+    
+    return rtpmapAttribute;
+    
+    
+    }
+
+// -----------------------------------------------------------------------------
+// CMceAudioSdpCodec::EncodeMediaAttributesL
+// -----------------------------------------------------------------------------
+//
+void CMceAudioSdpCodec::EncodeMediaAttributesL( CMceComCodec& aCodec, 
+                                                CSdpMediaField& aMediaLine, 
+                                                CSdpFmtAttributeField& aRtpmap ) const
+    {
+    MCEMM_DEBUG( "CMceAudioSdpCodec::EncodeMediaAttributesL(), Entry" )
+    MCE_DEFINE_AUDIO_CODEC( codec, aCodec );
+    
+    if ( aCodec.Stream()->ReceiveStream() )
+        {
+        if ( codec.iPTime && 
+             codec.iMaxPTime &&
+             !FindAttribute( SdpCodecStringConstants::EAttributePtime, aMediaLine ) )
+            {            
+            RStringF attributePtime = SDP_STRING( SdpCodecStringConstants::EAttributePtime );
+            RStringF attributeMaxPtime = SDP_STRING( SdpCodecStringConstants::EAttributeMaxptime );
+               
+            MCE_DEFINE_DECSTR( ptime, codec.iPTime )
+            MCE_DEFINE_DECSTR( maxptime, codec.iMaxPTime )
+            
+            CSdpAttributeField* ptimeLine = 
+                CSdpAttributeField::NewLC( attributePtime, ptime );
+            CSdpAttributeField* maxptimeLine = 
+                CSdpAttributeField::NewLC( attributeMaxPtime, maxptime );
+
+            MCEMM_DEBUG_SVALUE( "encoded ptime", ptime )
+            MCEMM_DEBUG_SVALUE( "encoded maxptime", maxptime )
+
+            aMediaLine.AttributeFields().AppendL( ptimeLine );
+            // this creates dependency between ptime and payload type
+            ptimeLine->AssignTo( aRtpmap );
+            CleanupStack::Pop( maxptimeLine ); 
+            
+            aMediaLine.AttributeFields().AppendL( maxptimeLine );
+            // this creates dependency between maxptime and payload type
+            maxptimeLine->AssignTo( aRtpmap ); 
+            CleanupStack::Pop( ptimeLine ); 
+            }
+        }
+        
+    MCEMM_DEBUG( "CMceAudioSdpCodec::EncodeMediaAttributesL(), Exit" )
+    }
+    
+// -----------------------------------------------------------------------------
+// CMceAudioSdpCodec::DecodeMediaAttributesL 
+// -----------------------------------------------------------------------------
+//
+void CMceAudioSdpCodec::DecodeMediaAttributesL(
+    CSdpMediaField& aMediaLine, 
+    CMceComCodec& aCodec,
+    CSdpFmtAttributeField& /*aRtpmap*/ ) const
+    {
+    MCEMM_DEBUG( "CMceAudioSdpCodec::DecodeMediaAttributesL(), Entry ")
+    
+    MCE_DEFINE_AUDIO_CODEC( codec, aCodec );
+    
+    if ( aCodec.Stream()->SendStream() )
+        {
+		RPointerArray<CSdpAttributeField>& attrfields =
+		    aMediaLine.AttributeFields();
+		
+		// Packet times are negotiated at session or media line level and thus 
+		// several codecs share common packet time values.
+        for ( TInt index = 0; index < attrfields.Count(); index++ )
+            {
+            CSdpAttributeField* attrfield = attrfields[ index ];
+            RStringF attribute;
+            attribute = attrfield->Attribute();
+            if ( attribute ==
+                 SDP_STRING( SdpCodecStringConstants::EAttributePtime ) )
+                {
+                TUint ptime = ConvertDesToUintL( attrfield->Value() );
+                codec.SetPTime( ptime );
+                
+                MCEMM_DEBUG_DVALUE( "decoded ptime", ptime )
+                }
+            else if ( attribute ==
+                 SDP_STRING( SdpCodecStringConstants::EAttributeMaxptime ) )
+                {
+                TUint maxptime = ConvertDesToUintL( attrfield->Value() );
+                codec.SetMaxPTime( maxptime );
+                
+                MCEMM_DEBUG_DVALUE( "decoded maxptime", maxptime )
+                }
+            else
+                {
+                // do not mind other attributes
+                }
+            }
+        }
+    
+    MCEMM_DEBUG_DVALUES( "exit ptime", codec.iPTime,
+                         "maxptime", codec.iMaxPTime )
+    MCEMM_DEBUG("CMceAudioSdpCodec::DecodeMediaAttributesL(), Exit ")
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMceAudioSdpCodec::CreateStreamLC
+// -----------------------------------------------------------------------------
+//
+CMceComMediaStream* CMceAudioSdpCodec::CreateStreamLC( TInt aType ) const
+    {
+    MCEMM_DEBUG( "CMceAudioSdpCodec::CreateStreamLC(), Entry" )
+    CMceComAudioStream* audiostream = NULL;
+            
+    if( aType == SdpCodecStringConstants::EAttributeSendonly )
+        {
+        // downlink
+        MCEMM_DEBUG( "create downlink" )
+        audiostream = CreateDownlinkStreamL();
+        }
+    else if( aType == SdpCodecStringConstants::EAttributeRecvonly )        
+        {
+        // uplink 
+        MCEMM_DEBUG( "create uplink" )
+        audiostream = CreateUplinkStreamL();
+        }
+    else
+        {
+        // sendrcv 
+        // create two way stream
+        // create downlink
+        MCEMM_DEBUG( "create two-way stream" )
+        audiostream = CreateDownlinkStreamL();
+        CleanupStack::PushL( audiostream );
+        // create bounded uplink
+        CMceComAudioStream *boundUplink = CreateUplinkStreamL();
+        CleanupStack::PushL( boundUplink );
+        audiostream->BindL( boundUplink );
+        CleanupStack::Pop( boundUplink ); 
+        CleanupStack::Pop( audiostream );
+        }
+    
+    CleanupStack::PushL( audiostream );
+    
+    MCEMM_DEBUG( "CMceAudioSdpCodec::CreateStreamLC(), Exit" )
+    return audiostream;
+    
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMceAudioSdpCodec::UpdateStreamL
+// -----------------------------------------------------------------------------
+//
+void CMceAudioSdpCodec::UpdateStreamL( CMceComMediaStream& aStream, TInt aDirection ) const
+    {
+    MCEMM_DEBUG( "CMceAudioSdpCodec::UpdateStreamL(), Entry ")
+    MCE_DEFINE_AUDIO( stream, aStream );
+
+    CMceComAudioStream* audiostream = NULL;
+    TInt streamType = stream.SdpStreamType();
+    
+    if ( aDirection != SdpCodecStringConstants::EAttributeInactive )
+        {
+        switch( streamType )
+            {
+            case SdpCodecStringConstants::EAttributeRecvonly:
+                {
+                //if direction is changed
+                if ( aDirection != SdpCodecStringConstants::EAttributeSendonly )
+                    {
+                    MCEMM_DEBUG( "update from recvonly to send" )
+                    MCEMM_DEBUG( "create uplink" )
+                    audiostream = CreateUplinkStreamL();
+                    }
+                break;
+                }
+            case SdpCodecStringConstants::EAttributeSendonly:
+                {
+                //if direction is changed
+                if ( aDirection != SdpCodecStringConstants::EAttributeRecvonly )
+                    {
+                    MCEMM_DEBUG( "update from sendonly to recv" )
+                    MCEMM_DEBUG( "create downlink" )
+                    audiostream = CreateDownlinkStreamL();
+                    }
+                break;
+                }
+            case SdpCodecStringConstants::EAttributeSendrecv:
+            default:
+                {
+                break;
+                }
+            }
+        }
+        
+    if ( audiostream )
+        {
+        CleanupStack::PushL( audiostream );
+
+        MCEMM_DEBUG( "cloning codecs" )
+        
+        for( TInt index = 0; index < stream.CodecCount(); ++index )
+            {
+            CMceComAudioCodec* codec = 
+                static_cast<CMceComAudioCodec*>( stream.CodecL( index )->CloneL() );
+            CleanupStack::PushL( codec );
+            
+            MCEMM_DEBUG_SVALUE( "cloned codec", codec->iSdpName )
+            
+            audiostream->AddCodecL( codec );
+            CleanupStack::Pop( codec );
+            }
+
+        stream.BindL( audiostream );
+        audiostream->InitializeL( *aStream.Session() );
+        
+        MCEMM_DEBUG( "binded stream created" )
+        CleanupStack::Pop( audiostream ); 
+        }
+    
+    MCEMM_DEBUG( "CMceAudioSdpCodec::UpdateStreamL(), Exit" )
+    }
+
+// -----------------------------------------------------------------------------
+// CMceAudioSdpCodec::CreateCodecLC
+// -----------------------------------------------------------------------------
+//
+CMceComCodec* CMceAudioSdpCodec::CreateCodecLC( CSdpFmtAttributeField& aRtpmap ) const
+    {
+    MCEMM_DEBUG( "CMceAudioSdpCodec::CreateCodecLC(), Entry" )
+    
+    CMceComAudioCodec* codec = NULL;
+    
+    const TDesC8& payloadType = aRtpmap.Format();
+    const TDesC8& attributeValue = aRtpmap.Value();
+    TSdpRtpmapValue rtpmapValue = TSdpRtpmapValue::DecodeL( attributeValue );
+
+    TPtrC8 codecName = rtpmapValue.iEncName;
+    TPtrC8 clockRate = rtpmapValue.iClockrate;
+    
+    TUint uintValPT = ConvertDesToUintL( payloadType );
+    TUint uintValCR = ConvertDesToUintL( clockRate );
+
+    if ( uintValPT > KMceMaxPTValue )
+        {
+		MCEMM_DEBUG_DVALUE("CMceAudioSdpCodec::CreateCodecLC(), invalid payloadtype value ", uintValPT )
+		User::Leave( KErrNotSupported );        	
+        }
+    if ( IsSupported( codecName ) && IsPayloadTypeSupported( codecName, uintValPT ) )
+        {
+        TMceComAudioCodecFactory factory;
+        codec =  factory.CreateLC( codecName );
+        codec->iSamplingFreq = uintValCR;
+        codec->iPayloadType = uintValPT;
+        MCEMM_DEBUG_SVALUE( "created codec", codecName )
+        MCEMM_DEBUG_DVALUE( "sampling frequence", uintValCR )
+        MCEMM_DEBUG_DVALUE( "payload", uintValPT )
+        }
+    else
+        {
+        MCEMM_DEBUG_SVALUE( "not supported codec", codecName )
+        }
+        
+    MCEMM_DEBUG( "CMceAudioSdpCodec::CreateCodecLC(), Exit" )
+    
+    return codec;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CMceAudioSdpCodec::CreateCodecLC
+// -----------------------------------------------------------------------------
+//
+CMceComCodec* CMceAudioSdpCodec::CreateCodecLC( TUint aPayload, 
+                                                CSdpMediaField& /*aMediaLine*/ ) const
+    {
+    MCEMM_DEBUG( "CMceAudioSdpCodec::CreateCodecLC( payload ), Entry" )
+    
+    TMceComAudioCodecFactory factory;
+    CMceComAudioCodec* codec = NULL;
+    
+    codec = factory.CreateCodecLC( aPayload );
+    if ( codec && !IsSupported( codec->iSdpName ) )
+        {
+        CleanupStack::PopAndDestroy( codec );
+        codec = NULL;
+        }
+
+    MCEMM_DEBUG( "CMceAudioSdpCodec::CreateCodecLC( payload ), Exit" )
+    
+    return codec;
+    }
+
+    
+// -----------------------------------------------------------------------------
+// CMceAudioSdpCodec::DecodeSessionMediaAttributesL
+// -----------------------------------------------------------------------------
+//
+void CMceAudioSdpCodec::DecodeSessionMediaAttributesL( CMceComMediaStream& aStream, 
+                                                       CSdpDocument& aSdpDocument ) const
+    {
+    MCEMM_DEBUG( "CMceAudioSdpCodec::DecodeSessionMediaAttributesL(), Entry" )
+    MCE_DEFINE_AUDIO( stream, aStream );
+    
+    if ( stream.SendStream() )
+        {
+        RPointerArray<CSdpAttributeField>& attrfields = 
+                                                aSdpDocument.AttributeFields();
+
+        // look for the ptime and maxptime attributes, go through all
+        // attribute fields and apply to all codecs in the stream if found
+        for ( TInt index = 0; index < attrfields.Count(); index++ )
+            {
+            CSdpAttributeField* attrfield = attrfields[ index ];
+            RStringF attribute = attrfield->Attribute();
+            TInt j = 0;
+            if ( attribute == SDP_STRING( SdpCodecStringConstants::EAttributePtime ) )
+                {
+                MCEMM_DEBUG_SVALUE( "decoded ptime", attrfield->Value() )
+
+                for ( j = 0; j < stream.CodecCount(); j++ )
+                    {
+                    stream.CodecL( j )->iPTime = ConvertDesToUintL( attrfield->Value() );
+                    }
+                }
+            else if ( attribute == SDP_STRING( SdpCodecStringConstants::EAttributeMaxptime ) )
+                {
+                MCEMM_DEBUG_SVALUE( "decoded maxptime", attrfield->Value() )
+
+                for ( j = 0; j < stream.CodecCount(); j++ )
+                    {
+                    stream.CodecL( j )->iMaxPTime = ConvertDesToUintL( attrfield->Value() );
+                    }   
+                }
+            }
+        }
+        
+    MCEMM_DEBUG( "CMceAudioSdpCodec::DecodeSessionMediaAttributesL(), Exit" )
+    }
+    
+// -----------------------------------------------------------------------------
+// CMceAudioSdpCodec::CreateUplinkStreamL
+// -----------------------------------------------------------------------------
+//
+CMceComAudioStream* CMceAudioSdpCodec::CreateUplinkStreamL() const
+    {
+    MCEMM_DEBUG( "CMceAudioSdpCodec::CreateUplinkStreamL(), Entry" )
+    
+    CMceComAudioStream *audiostream = CMceComAudioStream::NewL();
+    CleanupStack::PushL( audiostream );
+    // uplink           
+    CMceComMicSource* micSource = CMceComMicSource::NewL();
+    CleanupStack::PushL( micSource );
+    micSource->InitializeL( static_cast<CMceComAudioStream&> ( *audiostream ) );
+    audiostream->SetSourceL( micSource );
+    CleanupStack::Pop( micSource );
+    CMceComRtpSink* rtpSink = CMceComRtpSink::NewL();
+    CleanupStack::PushL( rtpSink );
+    rtpSink->InitializeL( static_cast<CMceComAudioStream&> ( *audiostream ) );
+    audiostream->AddSinkL( rtpSink );
+    CleanupStack::Pop( rtpSink ); 
+    CleanupStack::Pop( audiostream );
+    
+    MCEMM_DEBUG( "CMceAudioSdpCodec::CreateUplinkStreamL(), Exit" )
+    
+    return audiostream;
+    }
+
+// -----------------------------------------------------------------------------
+// CMceAudioSdpCodec::CreateDownlinkStreamL
+// -----------------------------------------------------------------------------
+//
+CMceComAudioStream* CMceAudioSdpCodec::CreateDownlinkStreamL() const
+    {
+    MCEMM_DEBUG( "CMceAudioSdpCodec::CreateDownlinkStreamL(), Entry" )
+
+    CMceComAudioStream *audiostream = CMceComAudioStream::NewL();
+    CleanupStack::PushL( audiostream ); 
+    // downlink         
+    CMceComRtpSource* rtpSource = CMceComRtpSource::NewL();
+    CleanupStack::PushL( rtpSource );
+    rtpSource->InitializeL( static_cast<CMceComAudioStream&> ( *audiostream ) );
+    audiostream->SetSourceL( rtpSource );
+    CleanupStack::Pop( rtpSource );
+    CMceComSpeakerSink* speaker = CMceComSpeakerSink::NewL();
+    CleanupStack::PushL( speaker );
+    speaker->InitializeL( static_cast<CMceComAudioStream&> ( *audiostream ) );
+    audiostream->AddSinkL( speaker );
+    CleanupStack::Pop( speaker ); 
+    CleanupStack::Pop( audiostream );
+    
+    MCEMM_DEBUG( "CMceAudioSdpCodec::CreateDownlinkStreamL(), Exit" )
+    
+    return audiostream;
+    }
+
+