--- /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 <mcemanager.h>
+#include <mcecamerasource.h>
+#include <mcevideostream.h>
+#include <mcertpsink.h>
+#include <mcedisplaysink.h>
+#include <mcefilesink.h>
+#include <mcesession.h>
+#include <mcevideocodec.h>
+#include <mceh263codec.h>
+#include <mceavccodec.h>
+
+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<CMceVideoCodec>& 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<NCentralRepositoryConstants::KMaxBinaryLength> keys;
+ keys.Append( *configInfoInCenRep );
+
+ CMceVideoStream* stream = MusEngMceUtils::GetVideoOutStreamL( *iSession );
+ const RPointerArray<CMceVideoCodec>& 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;
+ }
+
+