diff -r 000000000000 -r f0cf47e981f9 mmsharing/mmshengine/src/musenglivesession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmsharing/mmshengine/src/musenglivesession.cpp Thu Dec 17 08:44:37 2009 +0200 @@ -0,0 +1,1124 @@ +/* +* 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: +* +*/ + + +// USER +#include "musenglivesession.h" +#include "musengsessionobserver.h" +#include "musenglivesessionobserver.h" +#include "musunittesting.h" +#include "musengmceutils.h" +#include "musenglogger.h" +#include "mussettings.h" + +// SYSTEM +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const TInt KMaxBrightness = 100; +const TInt KMinBrightness = -100; +const TInt KBrightnessStepSize = 10; + +// Names of AVC levels in string for config keys stored in CenRep +_LIT8( KMusAvcBitrateLevel1, "AvcBrL1=" ); +_LIT8( KMusAvcBitrateLevel1b, "AvcBrL1b=" ); +_LIT8( KMusAvcBitrateLevel1_1, "AvcBrL1_1=" ); +_LIT8( KMusAvcBitrateLevel1_2, "AvcBrL1_2=" ); +_LIT8( KMusAvcBitrateLevel1_3, "AvcBrL1_3=" ); +_LIT8( KMusAvcBitrateLevel2, "AvcBrL2=" ); + +_LIT8( KMusEncoderInfoTokenizer, ";" ); + +//Number of big and small zoom steps on Zoom scale +const TInt KZoomBigStepCount = 15; +const TInt KZoomSmallStepCount = KZoomBigStepCount*2; +const TInt KZoomStepMinSize = 1; + +const TInt64 KZoomFasterTime = 333333; // 1/3 second + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C CMusEngLiveSession* CMusEngLiveSession::NewL( + const TDesC& aFileName, + const TRect& aRect, + MMusEngSessionObserver& aSessionObserver, + MMusEngOutSessionObserver& aOutSessionObserver, + MMusEngLiveSessionObserver& aLiveSessionObserver, + TUint aSipProfileId ) + { + CMusEngLiveSession* self = new( ELeave ) CMusEngLiveSession( + aSessionObserver, + aOutSessionObserver, + aLiveSessionObserver, + aRect, + aFileName ); + CleanupStack::PushL( self ); + self->ConstructL( aSipProfileId ); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C CMusEngLiveSession* CMusEngLiveSession::NewL( + const TRect& aRect, + MMusEngSessionObserver& aSessionObserver, + MMusEngOutSessionObserver& aOutSessionObserver, + MMusEngLiveSessionObserver& aLiveSessionObserver, + TUint aSipProfileId ) + { + CMusEngLiveSession* self = new( ELeave ) CMusEngLiveSession( + aSessionObserver, + aOutSessionObserver, + aLiveSessionObserver, + aRect ); + CleanupStack::PushL( self ); + self->ConstructL( aSipProfileId ); + CleanupStack::Pop( self ); + return self; + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +CMusEngLiveSession::~CMusEngLiveSession() + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::~CMusEngLiveSession()" ) + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::~CMusEngLiveSession()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CMusEngLiveSession::CurrentZoomL() const + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::CurrentZoomL()" ) + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + CMceCameraSource* camera = MusEngMceUtils::GetCameraL( *iSession ); + + TInt currentZoom = camera->ZoomFactorL() + camera->DigitalZoomFactorL(); + + MUS_LOG1( "mus: [ENGINE] <- CMusEngLiveSession::CurrentZoomL( %d )", + currentZoom ) + + return currentZoom; + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMusEngLiveSession::SetZoomL( TInt aNewZoomFactor ) + { + MUS_LOG1( "mus: [ENGINE] -> CMusEngLiveSession::SetZoomL( %d )", + aNewZoomFactor ) + + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + __ASSERT_ALWAYS( aNewZoomFactor <= MaxZoomL() && + aNewZoomFactor >= MinZoomL(), + User::Leave( KErrArgument ) ); + + CMceCameraSource* camera = MusEngMceUtils::GetCameraL( *iSession ); + + if ( aNewZoomFactor <= iCameraInfo.iMaxZoom ) + { + MUS_LOG( "mus: [ENGINE] Optical zoom factor increased" ) + camera->SetZoomFactorL( aNewZoomFactor ); + } + + if ( aNewZoomFactor - iCameraInfo.iMaxZoom > 0 ) + { + camera->SetDigitalZoomFactorL( aNewZoomFactor - iCameraInfo.iMaxZoom ); + MUS_LOG1( "mus: [ENGINE] Digital zoom factor increased to %d", + aNewZoomFactor - iCameraInfo.iMaxZoom ) + } + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::SetZoomL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CMusEngLiveSession::MinZoomL() const + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::MinZoomL()" ) + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + // Although we do not need camera for return value, we have to have it in + // order to have proper iCameraInfo + MusEngMceUtils::GetCameraL( *iSession ); + + MUS_LOG1( "mus: [ENGINE] <- CMusEngLiveSession::MinZoomL( %d )", + iCameraInfo.iMinZoom ) + + return iCameraInfo.iMinZoom; + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CMusEngLiveSession::MaxZoomL() const + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::MaxZoomL()" ) + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + // Although we do not need camera for return value, we have to have it in + // order to have proper iCameraInfo + MusEngMceUtils::GetCameraL( *iSession ); + + TInt maxZoom = iCameraInfo.iMaxZoom + iCameraInfo.iMaxDigitalZoom; + + MUS_LOG1( "mus: [ENGINE] Max optical zoom( %d )", + iCameraInfo.iMaxZoom ) + MUS_LOG1( "mus: [ENGINE] Max digital zoom( %d )", + iCameraInfo.iMaxDigitalZoom ) + MUS_LOG1( "mus: [ENGINE] <- CMusEngLiveSession::MaxZoomL( %d )", + maxZoom ) + + return maxZoom; + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMusEngLiveSession::ZoomInL() + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::ZoomInL()" ) + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + CMceCameraSource* camera = MusEngMceUtils::GetCameraL( *iSession ); + + // First try to increase optical zoom factor. If in maximum value, try to + // increase digital zoom factor. + TInt stepSize = ZoomStepSize( iZoomInTime ); + TInt zoomFactor = camera->ZoomFactorL(); + TInt zoomDigitalFactor = camera->DigitalZoomFactorL(); + + //increate optical zoom factor + if ( zoomFactor + stepSize <= iCameraInfo.iMaxZoom ) + { + //optical zoom factor is enough + camera->SetZoomFactorL( zoomFactor + stepSize ); + stepSize = 0; + } + else if (zoomFactor < iCameraInfo.iMaxZoom) + { + stepSize -= iCameraInfo.iMaxZoom - zoomFactor; + camera->SetZoomFactorL( iCameraInfo.iMaxZoom ); + } + + //increate digital zoom factor + if (stepSize > 0) + { + if ( zoomDigitalFactor + stepSize <= iCameraInfo.iMaxDigitalZoom ) + { + camera->SetDigitalZoomFactorL( zoomDigitalFactor + stepSize ); + } + else + { + camera->SetDigitalZoomFactorL( iCameraInfo.iMaxDigitalZoom ); + MUS_LOG( "mus: [ENGINE] CMusEngLiveSession::ZoomInL(): Optical \ + and digital zoom factors are in maximum value" ) + } + } + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::ZoomInL()" ) + + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMusEngLiveSession::ZoomOutL() + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::ZoomOutL()" ) + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + CMceCameraSource* camera = MusEngMceUtils::GetCameraL( *iSession ); + + // First try to decrease digital zoom factor. If already zero, try to + // decrease optical zoom factor. + TInt stepSize = ZoomStepSize( iZoomOutTime ); + TInt zoomFactor = camera->ZoomFactorL(); + TInt zoomDigitalFactor = camera->DigitalZoomFactorL(); + + //decreate digital zoom factor firstly + if ( zoomDigitalFactor - stepSize >= 0 ) + { + //digital zoom factor is enough + camera->SetDigitalZoomFactorL( zoomDigitalFactor - stepSize ); + stepSize = 0; + } + else if ( zoomDigitalFactor > 0 ) + { + stepSize -= zoomDigitalFactor; + camera->SetDigitalZoomFactorL( 0 ); + MUS_LOG("mus: [ENGINE] Digigal Factor to zero") + } + + //decreate optical zoom factor firstly + if ( stepSize > 0 ) + { + if ( zoomFactor - stepSize > iCameraInfo.iMinZoom ) + { + camera->SetZoomFactorL( zoomFactor - stepSize ); + } + else + { + MUS_LOG( "mus: [ENGINE] CMusEngLiveSession::ZoomOutL(): Optical and \ + digital zoom factors are in minimum value" ) + camera->SetZoomFactorL( iCameraInfo.iMinZoom ); + } + } + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::ZoomOutL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMusEngLiveSession::ZoomDefaultL() + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::ZoomDefaultL()" ) + + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + CMceCameraSource* camera = MusEngMceUtils::GetCameraL( *iSession ); + + camera->SetZoomFactorL( iDefaultZoomFactor ); + camera->SetDigitalZoomFactorL( 0 ); + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::ZoomDefaultL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMusEngLiveSession::SetBrightnessL( TInt aBrightness ) const + { + MUS_LOG1( "mus: [ENGINE] -> CMusEngLiveSession::SetBrightnessL( %d )", + aBrightness ) + + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + CMceCameraSource* camera = MusEngMceUtils::GetCameraL( *iSession ); + camera->SetBrightnessL( aBrightness ); + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::SetBrightnessL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CMusEngLiveSession::CurrentBrightnessL() const + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::CurrentBrightnessL()" ) + + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + CMceCameraSource* camera = MusEngMceUtils::GetCameraL( *iSession ); + TInt currentBrightness = camera->BrightnessL(); + + MUS_LOG1( "mus: [ENGINE] <- CMusEngLiveSession::CurrentBrightnessL(): %d", + currentBrightness ) + + return currentBrightness; + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CMusEngLiveSession::MaxBrightnessL() const + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::MaxBrightnessL()" ) + + // maximum brightness is not in camera info, but a constant 100 + + MUS_LOG1( "mus: [ENGINE] <- CMusEngLiveSession::MaxBrightnessL(): %d", + KMaxBrightness ) + + return KMaxBrightness; + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CMusEngLiveSession::MinBrightnessL() const + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::MinBrightnessL()" ) + + // maximum brightness is not in camera info, but a constant -100 + + MUS_LOG1( "mus: [ENGINE] <- CMusEngLiveSession::MinBrightnessL(): %d", + KMinBrightness ) + + return KMinBrightness; + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMusEngLiveSession::IncreaseBrightnessL() + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::IncreaseBrightnessL()" ) + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + CMceCameraSource* camera = MusEngMceUtils::GetCameraL( *iSession ); + + TInt newBrightness = camera->BrightnessL() + KBrightnessStepSize; + + if ( newBrightness < KMaxBrightness ) + { + camera->SetBrightnessL( newBrightness ); + } + else + { + camera->SetBrightnessL( KMaxBrightness ); + } + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::IncreaseBrightnessL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMusEngLiveSession::DecreaseBrightnessL() + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::DecreaseBrightnessL()" ) + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + CMceCameraSource* camera = MusEngMceUtils::GetCameraL( *iSession ); + + TInt newBrightness = camera->BrightnessL() - KBrightnessStepSize; + + if ( newBrightness > KMinBrightness ) + { + camera->SetBrightnessL( newBrightness ); + } + else + { + camera->SetBrightnessL( KMinBrightness ); + } + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::DecreaseBrightnessL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMusEngLiveSession::BrightnessDefaultL() + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::BrightnessDefaultL()" ) + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + CMceCameraSource* camera = MusEngMceUtils::GetCameraL( *iSession ); + + camera->SetBrightnessL( iDefaultBrightness ); + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::BrightnessDefaultL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMusEngLiveSession::BrightnessAutoL() + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::BrightnessAutoL()" ) + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + CMceCameraSource* camera = MusEngMceUtils::GetCameraL( *iSession ); + + camera->SetBrightnessL( CCamera::EBrightnessAuto ); + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::BrightnessAutoL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMusEngLiveSession::RecordL( TBool aRecord ) + { + MUS_LOG1( "mus: [ENGINE] -> CMusEngLiveSession::RecordL( %d )", aRecord ) + + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + CMceMediaSink* fileSink = MusEngMceUtils::GetMediaSink( *iSession, + KMceFileSink ); + + __ASSERT_ALWAYS( fileSink, User::Leave( KErrNotReady ) ); + + if( aRecord && !fileSink->IsEnabled() ) + { + fileSink->EnableL(); + } + else if ( !aRecord && fileSink->IsEnabled() ) + { + fileSink->DisableL(); + } + else + { + // NOP + } + + MUS_LOG1( "mus: [ENGINE] <- CMusEngLiveSession::RecordL( %d )", aRecord ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TBool CMusEngLiveSession::IsRecording() + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::IsRecording()" ) + + TBool isRecording( EFalse ); + + CMceMediaSink* fileSink = MusEngMceUtils::GetMediaSink( *iSession, + KMceFileSink ); + if ( fileSink ) + { + isRecording = fileSink->IsEnabled(); + } + + MUS_LOG1( "mus: [ENGINE] <- CMusEngLiveSession::IsRecording(%d)", + isRecording ) + + return isRecording; + } + + +// ----------------------------------------------------------------------------- +// Enable camera if not already enabled +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMusEngLiveSession::PlayL() + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::PlayL()" ) + + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + CMceCameraSource* camera = MusEngMceUtils::GetCameraL( *iSession ); + + if ( !camera->IsEnabled() ) + { + camera->EnableL(); + } + else + { + MUS_LOG( "mus: [ENGINE] Camera already enabled, ignore request" ) + } + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::PlayL()" ) + } + + +// ----------------------------------------------------------------------------- +// Disable camera if not already disabled +// ----------------------------------------------------------------------------- +// +EXPORT_C void CMusEngLiveSession::PauseL() + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::PauseL()" ) + + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + CMceCameraSource* camera = MusEngMceUtils::GetCameraL( *iSession ); + + if ( camera->IsEnabled() ) + { + camera->DisableL(); + } + else + { + MUS_LOG( "mus: [ENGINE] Camera already disabled, ignore request" ) + } + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::PauseL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TBool CMusEngLiveSession::IsPlayingL() + { + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + return ( MusEngMceUtils::GetCameraL( *iSession )->IsEnabled() ); + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngLiveSession::InitializeZoomStepSize() + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::InitializeZoomStepSize()" ) + + iBigZoomStep = ( iCameraInfo.iMaxZoom + iCameraInfo.iMaxDigitalZoom - + iCameraInfo.iMinZoom ) / KZoomBigStepCount; + + if ( iBigZoomStep < KZoomStepMinSize ) + iBigZoomStep = KZoomStepMinSize; + + iSmallZoomStep = ( iCameraInfo.iMaxZoom + iCameraInfo.iMaxDigitalZoom - + iCameraInfo.iMinZoom ) / KZoomSmallStepCount; + + if ( iSmallZoomStep < KZoomStepMinSize ) + iSmallZoomStep = KZoomStepMinSize; + + MUS_LOG2( "mus: [ENGINE] iSmallZoomStep = %d, iBigZoomStep = %d", + iSmallZoomStep, iBigZoomStep ) + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::InitializeZoomStepSize()" ) + } + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngLiveSession::CompleteSessionStructureL( + CMceStreamBundle& /*aLocalBundle*/ ) + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::CompleteSessionStructureL()" ) + + __ASSERT_ALWAYS( iSession, User::Leave( KErrNotReady ) ); + + // Create outgoing video stream + CMceVideoStream* videoStream = CMceVideoStream::NewLC(); + + CMceRtpSink* rtpsink = CMceRtpSink::NewLC(); + videoStream->AddSinkL( rtpsink ); + CleanupStack::Pop( rtpsink ); + + CMceCameraSource* camera = CMceCameraSource::NewLC( *iManager ); + camera->DisableL(); // Start session in pause mode. + camera->GetCameraInfo( iCameraInfo ); + iDefaultZoomFactor = camera->ZoomFactorL(); + + InitializeZoomStepSize(); + + videoStream->SetSourceL( camera ); + CleanupStack::Pop( camera ); + + iSession->AddStreamL( videoStream ); + CleanupStack::Pop( videoStream ); + + // Construct recording stream if needed + if ( iRecordedFile != KNullDesC ) + { + CMceVideoStream* streamForRecording = CMceVideoStream::NewLC(); + + CMceFileSink* fileSink = CMceFileSink::NewLC( iRecordedFile ); + fileSink->DisableL(); // Start in not recording mode + streamForRecording->AddSinkL( fileSink ); + CleanupStack::Pop( fileSink ); + + streamForRecording->SetSourceL( camera ); + iSession->AddStreamL( streamForRecording ); + CleanupStack::Pop( streamForRecording ); + } + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::CompleteSessionStructureL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngLiveSession::HandleSessionStateChanged( + CMceSession& aSession, + TInt aStatusCode, + const TDesC8& aReasonPhrase ) + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::HandleSessionStateChanged" ) + + MUS_ENG_LOG_SESSION_STATE_AND_STATUS( aSession, aStatusCode, aReasonPhrase ) + + if ( iSession && + iSession == &aSession && + aSession.State() == CMceSession::EEstablished && + iStoreEncoderConfigInfo ) + { + iStoreEncoderConfigInfo = EFalse; + TRAPD( error, StoreEncoderConfigInfoL() ) + if ( error != KErrNone && error != KErrNotFound ) + { + // Only acceptable error is absence of repository entry, + // otherwise we inform user about failed session. + iSessionObserver.SessionFailed(); + } + } + + CMusEngMceSession::HandleSessionStateChanged( aSession, + aStatusCode, + aReasonPhrase ); + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::HandleSessionStateChanged" ) + } + + +// ----------------------------------------------------------------------------- +// Sets video codec attributes +// ----------------------------------------------------------------------------- +// +void CMusEngLiveSession::AdjustVideoCodecL( CMceVideoCodec& aVideoCodec ) + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::AdjustVideoCodecL()" ) + + CMusEngMceOutSession::AdjustVideoCodecL( aVideoCodec ); + + // Starting with 80Kbps will give better quality than starting with + // 64kbps.And if network behaves bad than anyhow we will drop down or + // if network is good guy than we climp up to 128. + // Esp in operator variance. No constant defined in MCE so defining + // one here. + const TInt KMushInitialBitrate = 80000; + MUS_LOG1( "mus: [ENGINE] - Intial bit rate set to %d",KMushInitialBitrate); + User::LeaveIfError( aVideoCodec.SetBitrate( KMushInitialBitrate ) ); + + if ( aVideoCodec.SdpName() == KMceSDPNameH263() || + aVideoCodec.SdpName() == KMceSDPNameH2632000() ) + { + // Set H.263 codec to allow all bitrates, set maximum to level 45 and + // start using level 10 and let the rate control raise it if possible + // Label:H263 + User::LeaveIfError( aVideoCodec.SetAllowedBitrates( + KMceAllowedH263BitrateAll ) ); + aVideoCodec.SetMaxBitrateL( KMceH263Level45Bitrate ); + } + else if ( aVideoCodec.SdpName() == KMceSDPNameH264() ) + { + User::LeaveIfError( aVideoCodec.SetAllowedBitrates( + KMceAvcCodecProfileIdBaseline | + KMceAvcCodecProfileIopConstraintSet | + KMceAvcBitrateLevel1b ) ); + + SetCodecConfigKeyL( aVideoCodec ); + SetEncodingDeviceL( aVideoCodec ); + } + else + { + // NOP + } + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::AdjustVideoCodecL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngLiveSession::AdjustAudioCodecL( CMceAudioCodec& aAudioCodec ) + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::AdjustAudioCodecL()" ) + + CMusEngMceOutSession::AdjustAudioCodecL( aAudioCodec ); + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::AdjustAudioCodecL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngLiveSession::DoCodecSelectionL( CMceVideoStream& aVideoStream ) + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::DoCodecSelectionL()" ) + + CMusEngMceSession::DoCodecSelectionL( aVideoStream ); + + if ( iVideoCodecList && + iVideoCodecList->Length() > 0 && + iVideoCodecList->FindF( KMceSDPNameH264 ) == KErrNotFound ) + { + // We know that recipient doesn't support AVC, so we do not offer it + const RPointerArray& codecs = aVideoStream.Codecs(); + + for ( TInt codecIndex = 0; codecIndex < codecs.Count(); ++codecIndex ) + { + if ( codecs[codecIndex]->SdpName() == KMceSDPNameH264() ) + { + aVideoStream.RemoveCodecL( *codecs[codecIndex] ); + // Since succesfull removal of a codec has changed the + // indexing, we have to reset the index + codecIndex = 0; + } + } + } + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::DoCodecSelectionL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngLiveSession::StreamStateChanged( CMceMediaStream& aStream, + CMceMediaSink& aSink ) + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::StreamStateChanged( sink )" ) + + if ( !iSession ) + { + return; + } + + MUS_ENG_LOG_STREAM_STATE( aStream ) + + CMceVideoStream* recordingStream = + MusEngMceUtils::GetRecordingStream( *iSession ); + + if ( recordingStream && + recordingStream == &aStream && + aStream.State() == CMceMediaStream::ENoResources && + aSink.IsEnabled() == EFalse ) + { + iLiveSessionObserver.DiskFull(); + } + else + { + // Cannot handle, forward to a base class + CMusEngMceSession::StreamStateChanged( aStream, aSink ); + } + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::StreamStateChanged( sink )" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +CMusEngLiveSession::CMusEngLiveSession( + MMusEngSessionObserver& aSessionObserver, + MMusEngOutSessionObserver& aOutSessionObserver, + MMusEngLiveSessionObserver& aLiveSessionObserver, + const TRect& aRect, + const TDesC& aRecordedFile ) + : CMusEngMceOutSession( aRect, + aSessionObserver, + aOutSessionObserver ), + iLiveSessionObserver( aLiveSessionObserver ), + iDefaultZoomFactor( -1 ), + iDefaultBrightness( 0 ), + iRecordedFile( aRecordedFile ), + iZoomInTime(0), + iZoomOutTime(0), + iSmallZoomStep( KZoomStepMinSize ), + iBigZoomStep( KZoomStepMinSize ) + { + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngLiveSession::ConstructL( TUint aSipProfileId ) + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::ConstructL()" ) + + CMusEngMceOutSession::ConstructL( aSipProfileId ); + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::ConstructL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngLiveSession::SetEncodingDeviceL( CMceVideoCodec& aVideoCodec ) + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::SetEncodingDeviceL()" ) + + // We try to read encoding device UID. If we do not succeed, we use default + + const TUid KDefaultEncodingDevice( TUid::Uid( 0x20001C13 ) ); + TUid encodingDevice( KDefaultEncodingDevice ); + TRAPD( error, + encodingDevice = MultimediaSharingSettings::EncodingDeviceL() ) + __ASSERT_ALWAYS( error == KErrNone || error == KErrNotFound, + User::Leave( error ) ); + aVideoCodec.SetPreferredEncodingDecodingDeviceL( encodingDevice ); + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::SetEncodingDeviceL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngLiveSession::SetCodecConfigKeyL( CMceVideoCodec& aVideoCodec ) + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::SetCodecConfigKeyL()" ) + + HBufC8* configKey( NULL ); + + // We try to read config key. If we do not succeed, we prepare to + // write keys to CenRep for the next time. + TRAPD( error, configKey = ReadCodecConfigKeyL( aVideoCodec ) ) + + if ( error == KErrNone ) + { + // There is a repository for config keys + if ( configKey ) + { + // ...and key is found. + CleanupStack::PushL( configKey ); + aVideoCodec.SetConfigKeyL( *configKey ); + CleanupStack::PopAndDestroy( configKey ); + } + else + { + // ...but key is not found, so it must be written to CenRep when + // available. + iStoreEncoderConfigInfo = ETrue; + } + } + else if ( error == KErrNotFound ) + { + // There is no repository for config keys so there is no point + // trying to write anything there. Session setup can still continue. + MUS_LOG1( "mus: [ENGINE] No repository for config keys [%d]", error ) + } + else + { + User::Leave( error ); + } + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::SetCodecConfigKeyL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +HBufC8* CMusEngLiveSession::ReadCodecConfigKeyL( + const CMceVideoCodec& aVideoCodec ) const + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::ReadCodecConfigKeyL()" ) + + HBufC8* key( NULL ); + + HBufC8* encoderInfo = MultimediaSharingSettings::EncoderConfigInfoLC(); + __ASSERT_ALWAYS( encoderInfo, User::Leave( KErrNotFound ) ); + + TPtrC8 keyId( ConfigKeyIdL( aVideoCodec ) ); + + TInt tokenStartPosition( encoderInfo->FindC( keyId ) ); + if ( tokenStartPosition > KErrNotFound ) + { + TInt tokenLength( encoderInfo->Mid( tokenStartPosition ).FindC( + KMusEncoderInfoTokenizer ) ); + if ( tokenLength > KErrNotFound ) + { + // Separate key from token by removing keyId + TInt keyStartPosition = tokenStartPosition + keyId.Length(); + TInt keyLength = tokenLength - keyId.Length(); + TPtrC8 keyPtr = encoderInfo->Mid( keyStartPosition, keyLength ); + key = keyPtr.AllocL(); + } + } + + CleanupStack::PopAndDestroy( encoderInfo ); + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::ReadCodecConfigKeyL()" ) + + return key; + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +void CMusEngLiveSession::StoreEncoderConfigInfoL() const + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::StoreEncoderConfigInfoL()" ) + + HBufC8* configInfoInCenRep = MultimediaSharingSettings::EncoderConfigInfoLC(); + __ASSERT_ALWAYS( configInfoInCenRep, User::Leave( KErrNotFound ) ); + + TBuf8 keys; + keys.Append( *configInfoInCenRep ); + + CMceVideoStream* stream = MusEngMceUtils::GetVideoOutStreamL( *iSession ); + const RPointerArray& codecs = stream->Codecs(); + + for ( TInt codecIndex = 0; codecIndex < codecs.Count(); ++codecIndex ) + { + if ( codecs[codecIndex]->SdpName().FindF( KMceSDPNameH264 ) >= 0 ) + { + const TPtrC8 keyId = ConfigKeyIdL( *codecs[codecIndex] ); + HBufC8* configKey = codecs[codecIndex]->ConfigKeyL(); + CleanupStack::PushL( configKey ); + + if ( configKey && + keys.FindF( keyId ) == KErrNotFound && + configInfoInCenRep->FindF( keyId ) == KErrNotFound ) + { + + if ( keys.Length() + + keyId.Length() + + configKey->Length() + + KMusEncoderInfoTokenizer().Length() < + NCentralRepositoryConstants::KMaxBinaryLength ) + { + keys.Append( keyId ); + keys.Append( *configKey ); + keys.Append( KMusEncoderInfoTokenizer ); + } + } + + CleanupStack::PopAndDestroy( configKey ); + } + } + + MultimediaSharingSettings::SetEncoderConfigInfoL( keys ); + + CleanupStack::PopAndDestroy( configInfoInCenRep ); + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::StoreEncoderConfigInfoL()" ) + } + + +// ----------------------------------------------------------------------------- +// +// ----------------------------------------------------------------------------- +// +const TPtrC8 CMusEngLiveSession::ConfigKeyIdL( + const CMceVideoCodec& aVideoCodec ) const + { + MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::ConfigKeyIdL()" ) + + // Currently works only for AVC + __ASSERT_ALWAYS( aVideoCodec.SdpName().FindF( KMceSDPNameH264 ) >= 0, + User::Leave( KErrArgument ) ); + + TPtrC8 configKeyTokenId; + + if ( aVideoCodec.AllowedBitrates() & KMceAvcBitrateLevel1 ) + { + configKeyTokenId.Set( KMusAvcBitrateLevel1() ); + } + else if ( aVideoCodec.AllowedBitrates() & KMceAvcBitrateLevel1b ) + { + configKeyTokenId.Set( KMusAvcBitrateLevel1b() ); + } + else if ( aVideoCodec.AllowedBitrates() & KMceAvcBitrateLevel1_1 ) + { + configKeyTokenId.Set( KMusAvcBitrateLevel1_1() ); + } + else if ( aVideoCodec.AllowedBitrates() & KMceAvcBitrateLevel1_2 ) + { + configKeyTokenId.Set( KMusAvcBitrateLevel1_2() ); + } + else if ( aVideoCodec.AllowedBitrates() & KMceAvcBitrateLevel1_3 ) + { + configKeyTokenId.Set( KMusAvcBitrateLevel1_3() ); + } + else if ( aVideoCodec.AllowedBitrates() & KMceAvcBitrateLevel2 ) + { + configKeyTokenId.Set( KMusAvcBitrateLevel2() ); + } + else + { + User::Leave( KErrNotFound ); + } + + MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::ConfigKeyIdL()" ) + + return configKeyTokenId; + } + + +// ----------------------------------------------------------------------------- +// Calculate the zoom step based time escaped +// ----------------------------------------------------------------------------- +TInt CMusEngLiveSession::ZoomStepSize( TInt64& aTime ) + { +// MUS_LOG( "mus: [ENGINE] -> CMusEngLiveSession::ZoomStepSize()" ) + TTime now; + now.HomeTime(); + TInt64 timeNow = now.Int64(); + TInt stepSize = ( ( timeNow - aTime ) <= KZoomFasterTime ) ? iBigZoomStep : iSmallZoomStep; + + aTime = now.Int64(); + + MUS_LOG1( "mus: [ENGINE] stepSize = %d", stepSize ); +// MUS_LOG( "mus: [ENGINE] <- CMusEngLiveSession::ZoomStepSize()" ) + return stepSize; + } + +