diff -r 000000000000 -r 1bce908db942 multimediacommsengine/mmcesrv/mmcemediamanager/src/mcevideosdpcodec.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/multimediacommsengine/mmcesrv/mmcemediamanager/src/mcevideosdpcodec.cpp Tue Feb 02 01:04:58 2010 +0200 @@ -0,0 +1,609 @@ +/* +* 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: +* +*/ + + + + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mcemediadefs.h" +#include "mcevideosdpcodec.h" +#include "mcevideostream.h" +#include "mcecomsession.h" +#include "mcecomvideostream.h" +#include "mcecomvideocodec.h" +#include "mceh263codec.h" +#include "mcecomfactory.h" +#include "mcecomrtpsource.h" +#include "mcecomrtpsink.h" +#include "mcecomcamerasource.h" +#include "mcecomdisplaysink.h" +#include "mcemmlogs.h" +#include "mcesip.h" + + + +const TInt KFrameSizeLength = KMceSdpNumericAttributeLength * 3; + + +// ================= MEMBER FUNCTIONS ======================= + +// ----------------------------------------------------------------------------- +// CMceVideoSdpCodec::NewL +// ----------------------------------------------------------------------------- +// +CMceVideoSdpCodec* CMceVideoSdpCodec::NewL() + { + RStringF video = MCE_SDP_STRING_VIDEOL(); + + CMceVideoSdpCodec* self = new (ELeave) CMceVideoSdpCodec( video ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CMceVideoSdpCodec::CMceVideoSdpCodec +// ----------------------------------------------------------------------------- +// +CMceVideoSdpCodec::CMceVideoSdpCodec( RStringF aMedia ) + : CMceMediaSdpCodec( aMedia ) + { + } + + +// ----------------------------------------------------------------------------- +// CMceVideoSdpCodec::ConstructL +// ----------------------------------------------------------------------------- +// +void CMceVideoSdpCodec::ConstructL() + { + CMceMediaSdpCodec::ConstructL(); + + iFrameSizeAttr = iStringPool.OpenFStringL( KMceVideoFrameSizeAttribute ); + } + +// ----------------------------------------------------------------------------- +// CMceVideoSdpCodec::~CMceVideoSdpCodec +// ----------------------------------------------------------------------------- +// +CMceVideoSdpCodec::~CMceVideoSdpCodec() + { + iFrameSizeAttr.Close(); + } + + +// ----------------------------------------------------------------------------- +// CMceVideoSdpCodec::Encodes +// ----------------------------------------------------------------------------- +// +TBool CMceVideoSdpCodec::Encodes( const CMceComMediaStream& aStream ) const + { + return aStream.iStreamType != CMceComMediaStream::ELocalStream && + aStream.iType == KMceVideo; + } + + +// ----------------------------------------------------------------------------- +// CMceVideoSdpCodec::CodecsL +// ----------------------------------------------------------------------------- +// +const RPointerArray& CMceVideoSdpCodec::CodecsL( CMceComMediaStream& aStream ) const + { + __ASSERT_ALWAYS( aStream.iType == KMceVideo, User::Leave( KErrArgument ) ); + MCE_DEFINE_VIDEO( stream, aStream ); + + return reinterpret_cast< const RPointerArray< CMceComCodec >& >( stream.Codecs() ); + } + +// ----------------------------------------------------------------------------- +// CMceVideoSdpCodec::EncodeRtpmapAttributeLC +// ----------------------------------------------------------------------------- +// +CSdpFmtAttributeField* CMceVideoSdpCodec::EncodeRtpmapAttributeLC( CMceComCodec& aCodec ) const + { + MCEMM_DEBUG("CMceVideoSdpCodec::EncodeRtpmapAttributeLC(), Entry "); + + MCE_DEFINE_VIDEO_CODEC( codec, aCodec ); + CSdpFmtAttributeField* rtpmapAttribute = NULL; + + TUint payloadType = codec.iPayloadType; + // Get the encoding name + TPtrC8 codecName = codec.iSdpName; + TUint clockRate = codec.iClockRate; + + // create rtpmap field for current codec + rtpmapAttribute = EncodeRtpMapFieldsL( payloadType, + codecName, + clockRate, + KMceSdpOptionalEncodingParam ); + + + CleanupStack::PushL( rtpmapAttribute ); + + MCEMM_DEBUG_SVALUE("encoded rtpmap", rtpmapAttribute->Value() ); + + MCEMM_DEBUG("CMceVideoSdpCodec::EncodeRtpmapAttributeLC(), Exit "); + return rtpmapAttribute; + + + } + + +// ----------------------------------------------------------------------------- +// CMceVideoSdpCodec::EncodeMediaAttributesL +// ----------------------------------------------------------------------------- +// +void CMceVideoSdpCodec::EncodeMediaAttributesL( CMceComCodec& aCodec, + CSdpMediaField& aMediaLine, + CSdpFmtAttributeField& aRtpmap ) const + { + MCEMM_DEBUG("CMceVideoSdpCodec::EncodeMediaAttributesL(), Entry "); + MCE_DEFINE_VIDEO_CODEC( codec, aCodec ); + + EncodeFrameRateAttributeL( codec, aMediaLine, aRtpmap ); + EncodeFrameSizeAttributeL( codec, aMediaLine, aRtpmap ); + + MCEMM_DEBUG("CMceVideoSdpCodec::EncodeMediaAttributesL(), Exit "); + } + + +// ----------------------------------------------------------------------------- +// CMceVideoSdpCodec::DecodeMediaAttributesL +// ----------------------------------------------------------------------------- +// + +void CMceVideoSdpCodec::DecodeMediaAttributesL( + CSdpMediaField& aMediaLine, + CMceComCodec& aCodec, + CSdpFmtAttributeField& /*aRtpmap*/ ) const + + + { + MCEMM_DEBUG("CMceVideoSdpCodec::DecodeMediaAttributesL(), Entry "); + MCE_DEFINE_VIDEO_CODEC( codec, aCodec ); + + RPointerArray& attrfields = aMediaLine.AttributeFields(); + + for ( TInt index = 0; index < attrfields.Count(); index++ ) + { + CSdpAttributeField* attrfield = attrfields[ index ]; + RStringF attribute = attrfield->Attribute(); + + if ( attribute == SDP_STRING( SdpCodecStringConstants::EAttributeFramerate ) ) + { + const TDesC8& framerate = attrfield->Value(); + TReal frameRateVal = ConvertDesToRealL( framerate ); + MCEMM_DEBUG_SVALUE("decoded framerate", framerate ); + + // Do not update frame rate for receive stream, but is anyway good + // to know at media side what framerate sender is about to use. + TReal& updateFrameRate = codec.Stream()->SendStream() ? + codec.iFrameRate : codec.iReceiveFrameRate; + + updateFrameRate = frameRateVal; + } + else if ( codec.Stream()->SendStream() && attribute == iFrameSizeAttr ) + { + const TDesC8& framesize = attrfield->Value(); + + TInt ind1 = framesize.Locate( KMceSipBlank ); + TInt ind2 = framesize.Locate( KMceSipDash ); + TInt widthStartPos( ind1 + 1 ); + TInt heightStartPos( ind2 + 1 ); + + if ( ind1 != KErrNotFound && + ind2 != KErrNotFound && + widthStartPos < ind2 && + heightStartPos < framesize.Length() && + ConvertDesToUintL( framesize.Mid( 0, ind1 ) ) == + codec.iPayloadType ) + { + codec.iResolutionWidth = + ConvertDesToIntL( + framesize.Mid( widthStartPos, ind2 - widthStartPos ) ); + + codec.iResolutionHeight = + ConvertDesToIntL( framesize.Mid( heightStartPos ) ); + + MCEMM_DEBUG_SVALUE("decoded framesize", framesize ); + + } + } + else + { + // NOP + } + } + + MCEMM_DEBUG("CMceVideoSdpCodec::DecodeMediaAttributesL(), Exit "); + + } + + + +// ----------------------------------------------------------------------------- +// CMceVideoSdpCodec::DecodeSessionMediaAttributesL +// ----------------------------------------------------------------------------- +// +void CMceVideoSdpCodec::DecodeSessionMediaAttributesL( CMceComMediaStream& aStream, + CSdpDocument& aSdpDocument ) const + { + MCEMM_DEBUG("CMceVideoSdpCodec::DecodeSessionMediaAttributesL(), Entry "); + MCE_DEFINE_VIDEO( stream, aStream ); + + RPointerArray& attrfields = + aSdpDocument.AttributeFields(); + + const RPointerArray& codecs = stream.Codecs(); + // look for the framerate attribute, 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(); + if ( attribute == SDP_STRING( SdpCodecStringConstants::EAttributeFramerate ) ) + { + TReal frameRate = ConvertDesToRealL( attrfield->Value() ); + MCEMM_DEBUG_SVALUE("decoded framerate", attrfield->Value() ); + for ( TInt j = 0; j < codecs.Count(); j++ ) + { + TReal& updateFrameRate = stream.SendStream() ? + codecs[ j ]->iFrameRate : codecs[ j ]->iReceiveFrameRate; + updateFrameRate = frameRate; + } + } + } + + MCEMM_DEBUG("CMceVideoSdpCodec::ParseSessionFrameRateAttributeL(), Exit "); + + } + + +// ----------------------------------------------------------------------------- +// CMceVideoSdpCodec::EncodeFrameRateAttributeL +// ----------------------------------------------------------------------------- +// +void CMceVideoSdpCodec::EncodeFrameRateAttributeL( + CMceComVideoCodec& aCodec, + CSdpMediaField& aMedia, + CSdpFmtAttributeField& aFmtpline ) const + { + MCEMM_DEBUG("CMceVideoSdpCodec::EncodeFrameRateAttributeL(), Entry "); + + RStringF attributeFrameRate = + SDP_STRING( SdpCodecStringConstants::EAttributeFramerate ); + + HBufC8* frameRate = ConvertTRealToDesLC( aCodec.iFrameRate ); + + MCEMM_DEBUG_SVALUE("encoded framerate", *frameRate ); + + CSdpAttributeField* frameRateLine = + CSdpAttributeField::NewL( attributeFrameRate, *frameRate ); + CleanupStack::PopAndDestroy( frameRate ); + CleanupStack::PushL( frameRateLine ); + aMedia.AttributeFields().AppendL( frameRateLine ); + CleanupStack::Pop( frameRateLine ); + + + // This creates dependency between framerate and payload type + frameRateLine->AssignTo( aFmtpline ); + + MCEMM_DEBUG("CMceVideoSdpCodec::EncodeFrameRateAttributeL(), Exit "); + } + +// ----------------------------------------------------------------------------- +// CMceVideoSdpCodec::EncodeFrameSizeAttributeL +// ----------------------------------------------------------------------------- +// +void CMceVideoSdpCodec::EncodeFrameSizeAttributeL( + CMceComVideoCodec& aCodec, + CSdpMediaField& aMedia, + CSdpFmtAttributeField& aFmtpline ) const + { + MCEMM_DEBUG("CMceVideoSdpCodec::EncodeFrameSizeAttributeL(), Entry "); + + HBufC8* frameSize = + HBufC8::NewLC( KMceVideoFrameSizeFormat().Length() + + KFrameSizeLength ); + + TPtr8 ptrFrameSize( frameSize->Des() ); + ptrFrameSize.AppendFormat( KMceVideoFrameSizeFormat, + aCodec.iPayloadType, + aCodec.iResolutionWidth, + aCodec.iResolutionHeight ); + + MCEMM_DEBUG_SVALUE("encoded framesize", ptrFrameSize ); + + CSdpAttributeField* frameSizeLine = + CSdpAttributeField::NewL( iFrameSizeAttr, *frameSize ); + CleanupStack::PopAndDestroy( frameSize ); + CleanupStack::PushL( frameSizeLine ); + aMedia.AttributeFields().AppendL( frameSizeLine ); + CleanupStack::Pop( frameSizeLine ); + + frameSizeLine->AssignTo( aFmtpline ); + + MCEMM_DEBUG("CMceVideoSdpCodec::EncodeFrameSizeAttributeL(), Exit "); + } + +// ----------------------------------------------------------------------------- +// CMceVideoSdpCodec::CreateStreamLC +// ----------------------------------------------------------------------------- +// +CMceComMediaStream* CMceVideoSdpCodec::CreateStreamLC( TInt aType ) const + { + MCEMM_DEBUG("CMceVideoSdpCodec::CreateStreamLC(), Entry "); + CMceComVideoStream* videostream = NULL; + + if( aType == SdpCodecStringConstants::EAttributeSendonly ) + { + // downlink + MCEMM_DEBUG( "create downlink" ); + videostream = CreateDownlinkStreamL(); + } + else if( aType == SdpCodecStringConstants::EAttributeRecvonly ) + { + // uplink + MCEMM_DEBUG( "create uplink" ); + videostream = CreateUplinkStreamL(); + + } + else + { + // sendrcv + // create two way stream + // create downlink + MCEMM_DEBUG( "create two-way stream"); + videostream = CreateDownlinkStreamL(); + CleanupStack::PushL( videostream ); + // create bounded uplink + CMceComVideoStream *boundUplink = CreateUplinkStreamL(); + CleanupStack::PushL( boundUplink ); + videostream->BindL( boundUplink ); + CleanupStack::Pop( boundUplink ); + CleanupStack::Pop( videostream ); + } + + CleanupStack::PushL( videostream ); + + + MCEMM_DEBUG("CMceVideoSdpCodec::CreateStreamLC(), Exit "); + return videostream; + + } + + +// ----------------------------------------------------------------------------- +// CMceVideoSdpCodec::UpdateStreamL +// ----------------------------------------------------------------------------- +// +void CMceVideoSdpCodec::UpdateStreamL( CMceComMediaStream& aStream, TInt aDirection ) const + { + + MCEMM_DEBUG("CMceVideoSdpCodec::UpdateStreamL(), Entry "); + MCE_DEFINE_VIDEO( stream, aStream ); + + CMceComVideoStream* videostream = 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"); + videostream = CreateUplinkStreamL(); + } + break; + } + case SdpCodecStringConstants::EAttributeSendonly: + { + //if direction is changed + if ( aDirection != SdpCodecStringConstants::EAttributeRecvonly ) + { + MCEMM_DEBUG("update from sendonly to recv"); + MCEMM_DEBUG("create downlink"); + videostream = CreateDownlinkStreamL(); + } + break; + } + case SdpCodecStringConstants::EAttributeSendrecv: + default: + { + break; + } + } + } + + if ( videostream ) + { + CleanupStack::PushL( videostream ); + + MCEMM_DEBUG("cloning codecs"); + + for( TInt index = 0; index < stream.CodecCount(); index++ ) + { + CMceComVideoCodec* codec = + static_cast( stream.CodecL( index )->CloneL() ); + CleanupStack::PushL( codec ); + MCEMM_DEBUG_SVALUE("cloned codec", codec->iSdpName ); + videostream->AddCodecL( codec ); + CleanupStack::Pop( codec ); + } + + stream.BindL( videostream ); + + videostream->InitializeL( *aStream.Session() ); + + MCEMM_DEBUG("binded stream created"); + CleanupStack::Pop( videostream ); + + + } + + MCEMM_DEBUG("CMceVideoSdpCodec::UpdateStreamL(), Exit "); + + } + +// ----------------------------------------------------------------------------- +// CMceVideoSdpCodec::CreateCodecLC +// ----------------------------------------------------------------------------- +// +CMceComCodec* CMceVideoSdpCodec::CreateCodecLC( CSdpFmtAttributeField& aRtpmap ) const + { + MCEMM_DEBUG("CMceVideoSdpCodec::CreateCodecLC(), Entry "); + + CMceComVideoCodec* 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("CMceVideoSdpCodec::CreateCodecLC(), invalid payloadtype value ", uintValPT ) + User::Leave( KErrNotSupported ); + } + if ( IsSupported( codecName ) ) + { + TMceComVideoCodecFactory factory; + codec = factory.CreateLC( codecName ); + codec->iClockRate = uintValCR; + codec->iPayloadType = uintValPT; + MCEMM_DEBUG_SVALUE("created codec", codecName ); + MCEMM_DEBUG_DVALUE("clock rate", uintValCR ) + MCEMM_DEBUG_DVALUE("payload", uintValPT ) + } + else + { + MCEMM_DEBUG_SVALUE("not supported codec", codecName ); + } + + MCEMM_DEBUG("CMceVideoSdpCodec::CreateCodecLC(), Exit "); + + return codec; + + } + +// ----------------------------------------------------------------------------- +// CMceVideoSdpCodec::CreateCodecLC +// ----------------------------------------------------------------------------- +// +CMceComCodec* CMceVideoSdpCodec::CreateCodecLC( TUint aPayload, + CSdpMediaField& /*aMediaLine*/ ) const + { + MCEMM_DEBUG("CMceVideoSdpCodec::CreateCodecLC( payload ), Entry "); + + TMceComVideoCodecFactory factory; + CMceComVideoCodec* codec = NULL; + + codec = factory.CreateCodecLC( aPayload ); + if ( codec && !IsSupported( codec->iSdpName ) ) + { + CleanupStack::PopAndDestroy( codec ); + codec = NULL; + } + + MCEMM_DEBUG("CMceVideoSdpCodec::CreateCodecLC( payload ), Exit "); + + return codec; + } + + +// ----------------------------------------------------------------------------- +// CMceVideoSdpCodec::CreateUplinkStreamL +// ----------------------------------------------------------------------------- +// +CMceComVideoStream* CMceVideoSdpCodec::CreateUplinkStreamL() const + { + MCEMM_DEBUG("CMceVideoSdpCodec::CreateUplinkStreamL(), Entry "); + + CMceComVideoStream* videoStream = CMceComVideoStream::NewL(); + CleanupStack::PushL( videoStream ); + // uplink + CMceComCameraSource* cameraSource = CMceComCameraSource::NewL(); + CleanupStack::PushL( cameraSource ); + cameraSource->InitializeL( + static_cast ( *videoStream ) ); + videoStream->SetSourceL( cameraSource ); + CleanupStack::Pop( cameraSource ); + CMceComRtpSink* rtpSink = CMceComRtpSink::NewL(); + CleanupStack::PushL( rtpSink ); + rtpSink->InitializeL( static_cast ( *videoStream ) ); + videoStream->AddSinkL( rtpSink ); + CleanupStack::Pop( rtpSink ); + CleanupStack::Pop( videoStream ); + + MCEMM_DEBUG("CMceVideoSdpCodec::CreateUplinkStreamL(), Exit "); + + return videoStream; + } + +// ----------------------------------------------------------------------------- +// CMceVideoSdpCodec::CreateDownlinkStreamL +// ----------------------------------------------------------------------------- +// +CMceComVideoStream* CMceVideoSdpCodec::CreateDownlinkStreamL() const + { + MCEMM_DEBUG("CMceVideoSdpCodec::CreateDownlinkStreamL(), Entry "); + + CMceComVideoStream* videoStream = CMceComVideoStream::NewL(); + CleanupStack::PushL( videoStream ); + // downlink + CMceComRtpSource* rtpSource = CMceComRtpSource::NewL(); + CleanupStack::PushL( rtpSource ); + rtpSource->InitializeL( static_cast ( *videoStream ) ); + videoStream->SetSourceL( rtpSource ); + CleanupStack::Pop( rtpSource ); + CMceComDisplaySink* display = CMceComDisplaySink::NewL(); + CleanupStack::PushL( display ); + display->InitializeL( static_cast ( *videoStream ) ); + videoStream->AddSinkL( display ); + CleanupStack::Pop( display ); + CleanupStack::Pop( videoStream ); + + MCEMM_DEBUG("CMceVideoSdpCodec::CreateDownlinkStreamL(), Exit "); + + return videoStream; + } + +