diff -r 000000000000 -r 1bce908db942 multimediacommscontroller/mmccvideosourcesink/src/mccvideosourceimpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/multimediacommscontroller/mmccvideosourcesink/src/mccvideosourceimpl.cpp Tue Feb 02 01:04:58 2010 +0200 @@ -0,0 +1,1531 @@ +/* +* 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 "mccvideosourceimpl.h" +#include "mccinternalcodecs.h" +#include "mmcccodecinformation.h" +#include "mmcccodech263.h" +#include "mmcccodecavc.h" +#include "mccvideosourcewrapper.h" +#include "mccvideosourcesinklogs.h" +#include "mccinternalevents.h" +#include "mmccinterfacedef.h" +#include "mccrateadaptationdef.h" +#include "mccdef.h" +#include "mccinternaldef.h" +#include "mccvideosourcekeyretriever.h" +#include "mccresources.h" + +_LIT8(KVideoCodecFourCC, "video/%S; %S"); + +const TInt KMccMaxVideoQueueSize = 10; +const TUint KMccBitrateTooLowLimit = 20000; + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::NewL +// ----------------------------------------------------------------------------- +// +CMccVideoSourceImpl* CMccVideoSourceImpl::NewL( + TUint32 aEndpointId, MMccResources* aMccResources, TBool aConfigKeyRetrieval ) + { + CMccVideoSourceImpl* self = new ( ELeave ) CMccVideoSourceImpl( + aEndpointId, aMccResources, aConfigKeyRetrieval ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::ConstructL +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::ConstructL() + { + iMediaRecorder = CMccVideoSourceWrapper::NewL(*this, *this); + iVideoCodec.iFourCC = TFourCC(); + iAudioFourCC = TFourCC(); + iFrameRate = KMccDefaultVideoFrameRate; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::CMccVideoSourceImpl +// ----------------------------------------------------------------------------- +// +CMccVideoSourceImpl::CMccVideoSourceImpl( + TUint32 aEndpointId, MMccResources* aMccResources, TBool aConfigKeyRetrieval ) : + iAudioEnabled( EFalse ), + iEndpointId( aEndpointId ), + iMccResources( aMccResources ), + iConfigKeyRetrieval( aConfigKeyRetrieval ) + { + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::~CMccVideoSourceImpl +// ----------------------------------------------------------------------------- +// +CMccVideoSourceImpl::~CMccVideoSourceImpl() + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::~CMccVideoSourceImpl" ) + + StopCameraMonitoring(); + + if ( iMediaRecorder ) + { + TRAP_IGNORE( iMediaRecorder->StopL() ) + } + + delete iVideoCodecFourCC; + delete iMediaRecorder; + iAsyncEventHandler = NULL; + + iVideoQueue.ResetAndDestroy(); + + delete iConfigKey; + delete iConfigKeyData; + + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::~CMccVideoSourceImpl, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SetResources +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::SetResources( MMccResources* aResources ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SetResources" ) + + iMccResources = aResources; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SetCameraHandler +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::SetCameraHandler( MMccCameraHandler& aCameraHandler ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SetCameraHandler" ) + + iCameraHandler = &aCameraHandler; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SourcePrimeL +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::SourcePrimeL( TBool aMultipleCodecs ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SourcePrimeL" ) + __ASSERT_ALWAYS( iMediaRecorder, User::Leave( KErrNotReady ) ); + __ASSERT_ALWAYS( iCameraHandler, User::Leave( KErrNotReady ) ); + + iMultipleCodecs = aMultipleCodecs; + + if ( !iCameraHandler->IsCameraReady() ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SourcePrimeL, camera not ready" ) + + HandleCameraReservationL(); + } + else if ( iMediaRecorder->State() == CCMRMediaRecorder::EStateNone ) + { + if ( !FullPrepareAllowed() ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SourcePrimeL, prepare partially" ) + + // Cannot prepare recorder yet fully, fake preparing and do it + // later automatically once recording is started + SendStreamEventToClient( KMccStreamPrepared, KErrNone, KMccAutomaticEvent ); + } + else + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SourcePrimeL, prepare fully" ) + + TUid encoderUid( KNullUid ); + DoCodecSpecificConfigurationL( encoderUid ); + + __ASSERT_ALWAYS( iVideoCodecFourCC, User::Leave( KErrNotReady ) ); + + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SourcePrimeL, opening source" ) + iMediaRecorder->OpenL( iAudioSource, iCameraHandler->Handle(), + *iVideoCodecFourCC, iAudioFourCC, encoderUid ) ; + } + } + else + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SourcePrimeL, not priming" ) + } + + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SourcePrimeL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SourcePlayL() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::SourcePlayL() + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SourcePlayL" ) + + TMccEventType event = KMccEventNone; + TUint32 eventNumData = 0; + iMultipleCodecs = EFalse; + + if ( iMediaRecorder->State() == CCMRMediaRecorder::EStateNone ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SourcePlayL, \ +not prepared, prepare in autoplay mode" ) + SetAutoPlayMode( ETrue ); + SourcePrimeL(); + } + else if ( iMediaRecorder->State() == CCMRMediaRecorder::EStateReadyToRecord ) + { + iMediaRecorder->PlayL(); + if ( AutoPlayMode() ) + { + event = KMccStreamResumed; + eventNumData = KMccAutomaticEvent; + SetAutoPlayMode( EFalse ); + } + else + { + event = KMccStreamStarted; + } + } + else + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SourcePlayL, \ +already playing or stopping" ) + } + + if ( event != KMccEventNone && !AutoPlayMode() ) + { + SendStreamEventToClient( event, KErrNone, eventNumData ); + } + + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SourcePlayL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SourcePauseL() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::SourcePauseL() + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SourcePauseL") + + iVideoConsumer = NULL; + iVideoConsumerBuffer = NULL; + SetAutoPlayMode( EFalse ); + + StopCameraMonitoring(); + + // Always stop the recorder, this will free camera resources + iMediaRecorder->StopL(); + + iVideoQueue.ResetAndDestroy(); + + SendStreamEventToClient( KMccStreamPaused ); + + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SourcePauseL, exit") + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SourceStopL() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::SourceStopL() + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SourceStopL" ) + __V_SOURCESINK_MEDIA_INT1("CMccVideoSourceImpl::SourceStopL, thread", \ + RThread().Id().operator TUint()); + iVideoConsumer = NULL; + iVideoConsumerBuffer = NULL; + iMultipleCodecs = EFalse; + iMediaRecorder->StopL(); + + iVideoQueue.ResetAndDestroy(); + + SendStreamEventToClient( KMccStreamStopped ); + + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SourceStopL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SourceDataTypeCode() +// ----------------------------------------------------------------------------- +// +TFourCC CMccVideoSourceImpl::SourceDataTypeCode( TMediaId aMediaId ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SourceDataTypeCode" ) + + if ( KUidMediaTypeVideo == aMediaId.iMediaType ) + { + return iVideoCodec.iFourCC; + } + else if ( KUidMediaTypeAudio == aMediaId.iMediaType ) + { + return iAudioFourCC; + } + else + { + return TFourCC( KMMFFourCCCodeNULL ); + } + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SetSourceDataTypeCode() +// ----------------------------------------------------------------------------- +// +TInt CMccVideoSourceImpl::SetSourceDataTypeCode( + TFourCC aCodec, + TMediaId aMediaId ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SetSourceDataTypeCode" ) + + if ( KUidMediaTypeVideo == aMediaId.iMediaType && + aCodec == iVideoCodec.iFourCC ) + { + return KErrNone; + } + else if ( KUidMediaTypeAudio == aMediaId.iMediaType && + aCodec == iAudioFourCC ) + { + return KErrNone; + } + else + { + return KErrNotSupported; + } + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::BufferEmptiedL() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::BufferEmptiedL( CMMFBuffer* /*aBuffer*/ ) + { + __V_SOURCESINK_MEDIA( "CMccVideoSourceImpl::BufferEmptiedL" ) + __ASSERT_ALWAYS( EFalse, User::Leave( KErrNotSupported ) ); + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::CanCreateSourceBuffer() +// ----------------------------------------------------------------------------- +// +TBool CMccVideoSourceImpl::CanCreateSourceBuffer() + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::CanCreateSourceBuffer, ETrue" ) + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::CreateSourceBufferL() +// ----------------------------------------------------------------------------- +// +CMMFBuffer* CMccVideoSourceImpl::CreateSourceBufferL( + TMediaId /*aMediaId*/, + TBool& /*aReference*/ ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::CreateSourceBufferL" ) + CMMFBuffer* buffer = NULL; + __ASSERT_ALWAYS( EFalse, User::Leave( KErrNotSupported ) ); + + return buffer; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SourceThreadLogon() +// ----------------------------------------------------------------------------- +// +TInt CMccVideoSourceImpl::SourceThreadLogon( MAsyncEventHandler& aEventHandler ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SourceThreadLogon" ) + iAsyncEventHandler = static_cast( &aEventHandler ); + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SourceThreadLogoff() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::SourceThreadLogoff() + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SourceThreadLogoff" ) + iAsyncEventHandler = NULL; + + iVideoQueue.ResetAndDestroy(); + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::FillBufferL() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::FillBufferL( + CMMFBuffer* aBuffer, + MDataSink* aConsumer, + TMediaId aMediaId ) + { + __V_SOURCESINK_MEDIA( "CMccVideoSourceImpl::FillBufferL" ) + + // Sink might want to indicate pause/stop by passing NULL buffer + if ( aBuffer ) + { + __ASSERT_ALWAYS ( aConsumer, User::Leave( KErrArgument ) ); + } + + if ( aMediaId.iMediaType == KUidMediaTypeVideo ) + { + __V_SOURCESINK_MEDIA( "CMccVideoSourceImpl::FillBufferL, video" ) + iVideoConsumer = aConsumer; + iVideoConsumerBuffer = aBuffer; + + WriteFirstBufferL(); + } + else + { + __V_SOURCESINK_MEDIA_INT1( "CMccVideoSourceImpl::FillBufferL, \ +unknown media, type=", aMediaId.iMediaType.iUid ) + User::Leave( KErrNotSupported ); + } + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::NegotiateSourceL() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::NegotiateSourceL( MDataSink& /*aDataSink*/ ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::NegotiateSourceL" ) + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::WriteBufferL() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::WriteBufferL( CCMRMediaBuffer* aBuffer ) + { + __V_SOURCESINK_MEDIA( "CMccVideoSourceImpl::WriteBufferL" ) + + __ASSERT_ALWAYS( aBuffer, User::Leave( KErrArgument ) ); + + if ( QueueBufferL( *aBuffer ) ) + { + WriteFirstBufferL(); + } + + __V_SOURCESINK_MEDIA( "CMccVideoSourceImpl::WriteBufferL, exit" ) + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SetVideoFrameSize() +// ----------------------------------------------------------------------------- +// +TInt CMccVideoSourceImpl::SetVideoFrameSize( TSize aSize ) + { + __V_SOURCESINK_CONTROLL_INT2( + "CMccVideoSourceImpl::SetVideoFrameSize (from mediarecorder), width", + aSize.iWidth, + " heigth", + aSize.iHeight ) + + iVideoCodec.iVideoHeight = aSize.iHeight; + iVideoCodec.iVideoWidth = aSize.iWidth; + + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SetAverageVideoBitRate() +// ----------------------------------------------------------------------------- +// +TInt CMccVideoSourceImpl::SetAverageVideoBitRate( TInt aBitRate ) + { + __V_SOURCESINK_CONTROLL_INT1( + "CMccVideoSourceImpl::SetAverageVideoBitRate (from mediarecorder)", + aBitRate ) + iVideoCodec.iAverageBitrate = (TUint)aBitRate; + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SetMaxVideoBitRate() +// ----------------------------------------------------------------------------- +// +TInt CMccVideoSourceImpl::SetMaxVideoBitRate( TInt aBitRate ) + { + __V_SOURCESINK_CONTROLL_INT1( + "CMccVideoSourceImpl::SetMaxVideoBitRate (from mediarecorder)", + aBitRate ) + + // Do not reset max bitrate as mediarecorder will call back with the same + // value which was given in SetVideoBitrate phase (i.e. value is meaningless) + aBitRate = aBitRate; + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SetAverageAudioBitRate() +// ----------------------------------------------------------------------------- +// +TInt CMccVideoSourceImpl::SetAverageAudioBitRate( TInt aBitRate ) + { + __V_SOURCESINK_CONTROLL_INT1( + "CMccVideoSourceImpl::SetAverageAudioBitRate (from mediarecorder)", + aBitRate ) + iAverageAudioBitRate = aBitRate; + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::MmroPrepareComplete() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::MmroPrepareComplete( TInt aError ) + { + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::MmroPrepareComplete=", aError ) + + if ( !aError ) + { + aError = SetVideoBitrate( iVideoCodec.iBitrate ); + if ( !aError ) + { + TRAP( aError, iMediaRecorder->SetVideoFrameRateL( iVideoCodec.iFramerate ) ); + + if ( !aError ) + { + TRateControlOptions options; + TRAP( aError, iMediaRecorder->GetVideoRateControlOptionsL( options ) ); + if ( !aError ) + { + __V_SOURCESINK_CONTROLL_INT1( + "Ratecontrol options:: control:", options.iControl ) + __V_SOURCESINK_CONTROLL_INT1( + "Ratecontrol options:: bitrate:", options.iBitrate ) + __V_SOURCESINK_CONTROLL_INT1( + "Ratecontrol options:: quality:", options.iPictureQuality ) + __V_SOURCESINK_CONTROLL_REAL( + "Ratecontrol options:: rate:", options.iPictureRate ) + __V_SOURCESINK_CONTROLL_REAL( + "Ratecontrol options:: qtt:", options.iQualityTemporalTradeoff ) + __V_SOURCESINK_CONTROLL_REAL( + "Ratecontrol options:: lqt:", options.iLatencyQualityTradeoff ) + + // Enable constant bitrate (CBR i.e. more strict bitrate control) + options.iLatencyQualityTradeoff = KMccLatencyQyalityTradeoff; + + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::MmroPrepareComplete, set CBR" ) + TRAP( aError, iMediaRecorder->SetVideoRateControlOptionsL( options ) ); + } + } + } + } + + + if ( AutoPlayMode() && !aError ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::MmroPrepareComplete, autoplay" ) + + TRAPD( err, SourcePlayL() ); + if ( err ) + { + SendStreamEventToClient( KMccStreamPrepared, err, KMccAutomaticEvent ); + } + } + else + { + SendStreamEventToClient( KMccStreamPrepared, aError, KMccAutomaticEvent ); + } + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::MmroStateChange() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::MmroStateChange( TInt aState, TInt aError ) + { + __V_SOURCESINK_CONTROLL_INT2( "CMccVideoSourceImpl::MmroStateChange, \ +aState=", aState, "aError=", aError ) + + if ( aError ) + { + SendStreamEventToClient( KMccStreamError, aError ); + } + else + { + switch ( aState ) + { + case CCMRMediaRecorder::EStateNone: + { + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::MmroStateChange, \ +aState=EStateNone, aError=", aError ) + } + break; + case CCMRMediaRecorder::EStateOpen: + { + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::MmroStateChange, \ +aState=EStateOpen, aError=", aError ) + } + break; + case CCMRMediaRecorder::EStatePreparing: + { + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::MmroStateChange, \ +aState=EStatePreparing, aError=", aError ) + } + break; + case CCMRMediaRecorder::EStateRecording: + { + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::MmroStateChange, \ +aState=EStateRecording, aError=", aError ) + } + break; + case CCMRMediaRecorder::EStatePausing: + { + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::MmroStateChange, \ +aState=EStatePausing, aError=", aError ) + } + break; + case CCMRMediaRecorder::EStateStopping: + { + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::MmroStateChange, \ +aState=EStateStopping, aError=", aError ) + } + break; + case CCMRMediaRecorder::EStateReadyToRecord: + { + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::MmroStateChange, \ +aState=EStateReadyToRecord, aError=", aError ) + } + break; + case CCMRMediaRecorder::EStatePaused: + { + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::MmroStateChange, \ +aState=EStatePaused, aError=", aError ) + } + break; + default: + break; + } + } + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::MmroTemporaryError() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::MmroTemporaryError( TInt aError ) + { + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::MmroTemporaryError=", + aError ) + + SendStreamEventToClient( KMccStreamError, aError ); + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::MmroFatalError() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::MmroFatalError( TInt aError ) + { + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::MmroFatalError=", aError ) + + SendStreamEventToClient( KMccStreamError, aError ); + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::CameraReady() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::CameraReady( TInt aError ) + { + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::CameraReady", aError ) + + if ( !aError ) + { + TRAP( aError, SourcePrimeL( iMultipleCodecs ) ); + } + + if ( aError ) + { + SendStreamEventToClient( KMccStreamError, aError ); + } + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SetVideoCodecL() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::SetVideoCodecL( const TMccCodecInfo& aVideoCodec ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SetVideoCodecL " ) + + iVideoCodec = aVideoCodec; + + if ( iVideoCodec.iConfigKey.Length() > 0 && !iConfigKey ) + { + __V_SOURCESINK_CONTROLL( "Setting config key" ) + iConfigKey = iVideoCodec.iConfigKey.AllocL(); + } + + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::SetVideoCodecL, iVideoHeight ", + iVideoCodec.iVideoHeight ) + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::SetVideoCodecL, iVideoWidth ", + iVideoCodec.iVideoWidth ) + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::SetVideoCodecL, iVideoFourCC ", + iVideoCodec.iFourCC.FourCC() ) + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::SetVideoCodecL, iVideoBitRate ", + iVideoCodec.iBitrate ) + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::SetVideoCodecL, iAverageVideoBitRate ", + iVideoCodec.iAverageBitrate ) + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::SetVideoCodecL, iMaxVideoBitRate ", + iVideoCodec.iMaxBitrate ) + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::SetVideoCodecL, iVideoCodecMode ", + iVideoCodec.iCodecMode ) + __V_SOURCESINK_CONTROLL_REAL( "CMccVideoSourceImpl::SetVideoCodecL, iFrameRate ", + iVideoCodec.iFramerate ) + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::GetVideoCodecL() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::GetVideoCodecL( TMccCodecInfo& aVideoCodec ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::GetVideoCodecL " ) + + aVideoCodec = iVideoCodec; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::GetSupportedVideoCodecsL() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::GetSupportedVideoCodecsL( RArray& /*aVideoTypes*/ ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::GetSupportedVideoCodecsL " ) + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SetAudioCodecL() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::SetAudioCodecL( const TMccCodecInfo& aAudioCodec ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SetAudioCodecL" ) + iAudioFourCC = aAudioCodec.iFourCC; + iAverageAudioBitRate = aAudioCodec.iAverageBitrate; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::GetAudioCodecL() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::GetAudioCodecL( TMccCodecInfo& aAudioCodec ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::GetAudioCodecL" ) + + aAudioCodec.iFourCC = iAudioFourCC; + aAudioCodec.iAverageBitrate = iAverageAudioBitRate; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::GetSupportedAudioCodecsL() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::GetSupportedAudioCodecsL( RArray& /*aAudioTypes*/ ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::GetSupportedAudioCodecsL" ) + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SetAudioEnabledL() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::SetAudioEnabledL( TBool aEnabled ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SetAudioEnabledL" ) + iAudioEnabled = aEnabled; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::AudioEnabledL() +// ----------------------------------------------------------------------------- +// +TBool CMccVideoSourceImpl::AudioEnabledL() const + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::AudioEnabledL" ) + return iAudioEnabled; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SetGainL() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::SetGainL( TInt aGain ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SetGainL" ) + iAudioGain = aGain; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::GainL() +// ----------------------------------------------------------------------------- +// +TInt CMccVideoSourceImpl::GainL() const + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::GainL" ) + + return iAudioGain; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::MaxGainL() +// ----------------------------------------------------------------------------- +// +TInt CMccVideoSourceImpl::MaxGainL() const + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::MaxGainL" ) + return iAudioGain; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::RateAdaptationRequest +// ----------------------------------------------------------------------------- +// +TInt CMccVideoSourceImpl::RateAdaptationRequest( + const TMccEvent& aInputData, + TMccEvent& aOutputData ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::RateAdaptationRequest, entry" ) + + TRAPD( err, RateAdaptationRequestL( aInputData, aOutputData ) ); + + __V_SOURCESINK_CONTROLL_INT1( + "CMccVideoSourceImpl::RateAdaptationRequest, exit with err:", err ) + + return err; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::IsStopped() +// ----------------------------------------------------------------------------- +// +TBool CMccVideoSourceImpl::IsStopped() const + { + return ( iMediaRecorder->State() == CCMRMediaRecorder::EStateNone ); + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::GetConfigKeyL() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::GetConfigKeyL( + const TMccCodecInfo& aVideoCodec, + TDes8& aConfigKey, + TBool aAllowAsyncRetrieval ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::GetConfigKeyL" ) + + if ( iConfigKey ) + { + __ASSERT_ALWAYS( iConfigKey->Length() <= aConfigKey.MaxLength(), + User::Leave( KErrArgument ) ); + aConfigKey.Copy( *iConfigKey ); + } + else + { + __ASSERT_ALWAYS( iCameraHandler != NULL, User::Leave( KErrNotReady ) ); + __ASSERT_ALWAYS( aAllowAsyncRetrieval, User::Leave( KErrNotReady ) ); + + CMccVideoSourceConfigKeyRetriever* retriever = + CMccVideoSourceConfigKeyRetriever::NewLC( *iCameraHandler ); + retriever->RetrieveL( aVideoCodec, aConfigKey ); + CleanupStack::PopAndDestroy( retriever ); + + iConfigKey = aConfigKey.AllocL(); + } + + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::GetConfigKeyL, entry" ) + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::HasConfigKey() +// ----------------------------------------------------------------------------- +// +TBool CMccVideoSourceImpl::HasConfigKey() const + { + return ( iConfigKey != NULL ); + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SendStreamEventToClient() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::SendStreamEventToClient( + TMccEventType aEventType, + TInt aError, + TUint32 aEventNumData ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SendStreamEventToClient" ) + + if ( iAsyncEventHandler ) + { + aEventType = aError ? KMccStreamError : aEventType; + + TMccEvent event( 0, + 0, + 0, + iEndpointId, + KMccEventCategoryStream, + aEventType, + aError, + KNullDesC8 ); + + event.iEventNumData = aEventNumData; + + TMccInternalEvent internalEvent( KMccVideoSourceUid, + EMccInternalEventNone, + event ); + + iAsyncEventHandler->SendEventToClient( internalEvent ); + } + else + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SendStreamEventToClient, \ + iAsyncEventHandler=NULL" ) + } + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SetAutoPlayMode() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::SetAutoPlayMode( TBool aIsInAutoPlayMode ) + { + iAutoPlayMode = aIsInAutoPlayMode; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::AutoPlayMode() +// ----------------------------------------------------------------------------- +// +TBool CMccVideoSourceImpl::AutoPlayMode() const + { + return iAutoPlayMode; + } + + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::CopyBufferData() +// ----------------------------------------------------------------------------- +// +TBool CMccVideoSourceImpl::CopyBufferData( + CMMFBuffer& aDstBuffer, + CCMRMediaBuffer& aSrcBuffer ) + { + CMMFDataBuffer& dstBuf = + static_cast( aDstBuffer ); + + __V_SOURCESINK_MEDIA_INT2( "CMccVideoSourceImpl::CopyBufferData, \ +src buf length =", aSrcBuffer.Data().Length(), " type =", aSrcBuffer.Type() ) + + __V_SOURCESINK_MEDIA_INT1( "CMccVideoSourceImpl::CopyBufferData, \ +dst buf size =", dstBuf.BufferSize() ) + + if ( aSrcBuffer.Type() == CCMRMediaBuffer::EVideoH264NALDecSpecInfo || + aSrcBuffer.Type() == CCMRMediaBuffer::EVideoH264BytestreamDecSpecInfo ) + { + __V_SOURCESINK_CONTROLL_STR8( "Decoder spec info:", aSrcBuffer.Data() ) + TRAP_IGNORE( SetConfigKeyL( aSrcBuffer.Data() ) ) + } + + TBool copied( EFalse ); + if ( dstBuf.Data().MaxLength() >= aSrcBuffer.Data().Length() ) + { + dstBuf.Data().Copy( aSrcBuffer.Data() ); + dstBuf.SetTimeToPlay( aSrcBuffer.TimeStamp().Int64() ); + dstBuf.SetLastBuffer( EFalse ); + copied = ETrue; + } + + return copied; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::CopyBufferData() +// ----------------------------------------------------------------------------- +// +TBool CMccVideoSourceImpl::CopyBufferData( + CMMFBuffer& aDstBuffer, + CMMFDataBuffer& aSrcBuffer ) + { + CMMFDataBuffer& dstBuf = + static_cast( aDstBuffer ); + + __V_SOURCESINK_MEDIA_INT1( "CMccVideoSourceImpl::CopyBufferData, \ +src buf size =", aSrcBuffer.BufferSize() ) + + __V_SOURCESINK_MEDIA_INT1( "CMccVideoSourceImpl::CopyBufferData, \ +dst buf size =", dstBuf.BufferSize() ) + + TBool copied( EFalse ); + if ( dstBuf.Data().MaxLength() >= aSrcBuffer.Data().Length() ) + { + dstBuf.Data().Copy( aSrcBuffer.Data() ); + dstBuf.SetTimeToPlay( aSrcBuffer.TimeToPlay() ); + dstBuf.SetLastBuffer( EFalse ); + copied = ETrue; + } + return copied; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::QueueBufferL() +// ----------------------------------------------------------------------------- +// +TBool CMccVideoSourceImpl::QueueBufferL( CCMRMediaBuffer& aBuffer ) + { + TBool queued( EFalse ); + + if ( iVideoQueue.Count() < KMccMaxVideoQueueSize ) + { + CMMFDataBuffer* dataBuf = CMMFDataBuffer::NewL( aBuffer.Data().Length() ); + CleanupStack::PushL( dataBuf ); + if ( CopyBufferData( *dataBuf, aBuffer ) ) + { + // Random access point buffers (IFrames) have special handling + if ( aBuffer.RandomAccessPoint() ) + { + AddIFrameToQueueL( dataBuf ); + CleanupStack::Pop( dataBuf ); + } + else + { + iVideoQueue.AppendL( dataBuf ); + CleanupStack::Pop( dataBuf ); + } + queued = ETrue; + } + else + { + CleanupStack::PopAndDestroy( dataBuf ); + } + } + return queued; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::FetchQueuedBuffer() +// ----------------------------------------------------------------------------- +// +CMMFDataBuffer* CMccVideoSourceImpl::FetchQueuedBuffer() + { + CMMFDataBuffer* queuedBuf = NULL; + if ( iVideoQueue.Count() > 0 ) + { + queuedBuf = iVideoQueue[ 0 ]; + iVideoQueue.Remove( 0 ); + } + return queuedBuf; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::DoBufferFilledL() +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::DoBufferFilledL() + { + CMMFBuffer* tempBuf = iVideoConsumerBuffer; + MDataSink* tempSink = iVideoConsumer; + iVideoConsumer = NULL; + iVideoConsumerBuffer = NULL; + + if ( tempSink ) + { + tempSink->BufferFilledL( tempBuf ); + } + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::SetVideoBitrate() +// ----------------------------------------------------------------------------- +// +TInt CMccVideoSourceImpl::SetVideoBitrate( TUint& aVideoBitrate ) + { + // Respect maximum negotiation bitrate and do not allow too low values + // + + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SetVideoBitrate" ) + + TUint videoBitrate( aVideoBitrate ); + + if ( videoBitrate > iMaxNegBitRate ) + { + __V_SOURCESINK_CONTROLL( + "CMccVideoSourceImpl:: bitrate higher than negotiated" ) + videoBitrate = iMaxNegBitRate; + } + + if ( videoBitrate > iVideoCodec.iMaxBitrate ) + { + __V_SOURCESINK_CONTROLL( + "CMccVideoSourceImpl:: bitrate higher than maximum set" ) + videoBitrate = iVideoCodec.iMaxBitrate; + } + + if ( videoBitrate < KMccBitrateTooLowLimit ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl:: bitrate too low" ) + videoBitrate = KMccBitrateTooLowLimit; + } + + TRAPD( err, iMediaRecorder->SetVideoBitrateL( videoBitrate ) ); + if ( err == KErrNone ) + { + aVideoBitrate = videoBitrate; + } + + __V_SOURCESINK_CONTROLL_INT1( + "CMccVideoSourceImpl::SetVideoBitrate, exit with err", err ) + + return err; + } + +// ----------------------------------------------------------------------------- +// CMccVideoSourceImpl::RateAdaptationRequestL +// ----------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::RateAdaptationRequestL( + const TMccEvent& aInputData, + TMccEvent& aOutputData ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::RateAdaptationRequestL" ) + + TMccRateAdaptationEventDataPackage inputdatapkg; + inputdatapkg.Copy(aInputData.iEventData); + TMccRateAdaptationEventData inputdata = inputdatapkg(); + TMccRateAdaptationEventData outputdata = TMccRateAdaptationEventData(); + +#ifdef RATECONTROL + + if ( iMediaRecorder && + ( iMediaRecorder->State() == CCMRMediaRecorder::EStateRecording || + iMediaRecorder->State() == CCMRMediaRecorder::EStatePaused ) ) + { + __V_SOURCESINK_CONTROLL( + "CMccVideoSourceImpl::RateAdaptationRequest EStateRecording or EStatePaused" ) + + TUint bitrate = 0; + + bitrate = iMediaRecorder->GetVideoBitrateL(); + + __V_SOURCESINK_CONTROLL( + "CMccVideoSourceImpl::RateAdaptationRequest GetVideoBitRateL done" ) + + outputdata.iBitrateOriginal = bitrate; + + __V_SOURCESINK_CONTROLL_INT1( + "CMccVideoSourceImpl::RateAdaptationRequest originalBitrate=", bitrate) + TUint mbitrate = TUint( inputdata.iRateAdaptationAdvice * TReal( bitrate ) ); + __V_SOURCESINK_CONTROLL_INT1( + "CMccVideoSourceImpl::RateAdaptationRequest modifiedBitrate=", mbitrate) + + TInt bitrateErr = SetVideoBitrate( mbitrate ); + if ( bitrateErr == KErrNone ) + { + __V_SOURCESINK_CONTROLL( + "CMccVideoSourceImpl::RateAdaptationRequest SetVideoBitRate ok" ) + iVideoCodec.iBitrate = mbitrate; // This will be used after pause/resume + outputdata.iBitrateModified = mbitrate; + } + else + { + __V_SOURCESINK_CONTROLL( + "CMccVideoSourceImpl::RateAdaptationRequest SetVideoBitRate nok" ) + outputdata.iBitrateModified = bitrate; + } + +#ifdef FRAMERATECONTROL + + TReal frameRate = KMccDefaultVideoFrameRate; + + if ( mbitrate > KIPULFrameRate10Limit ) + { + __V_SOURCESINK_CONTROLL_INT1( + "CMccVideoSourceImpl::RateAdaptationRequest frameRate=", (TInt) frameRate) + + frameRate = iFrameRate; + } + else if (mbitrate < KIPULFrameRate5Limit ) + { + __V_SOURCESINK_CONTROLL_INT1( + "CMccVideoSourceImpl::RateAdaptationRequest frameRate=", (TInt) frameRate) + + frameRate = Min( 5.0, (TUint) iFrameRate ); + } + else + { + __V_SOURCESINK_CONTROLL_INT1( + "CMccVideoSourceImpl::RateAdaptationRequest frameRate=", (TInt) frameRate) + + frameRate = Min( 10.0, (TUint) iFrameRate ); + } + + iMediaRecorder->SetVideoFrameRateL( frameRate ); + + __V_SOURCESINK_CONTROLL( + "CMccVideoSourceImpl::RateAdaptationRequest SetVideoFrameRateL done" ) + +#endif //FRAMERATECONTROL + + TMccRateAdaptationEventDataPackage temp( outputdata ); + aOutputData.iEventData.Copy( temp ); + + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::RateAdaptationRequest end" ) + return; + } + +#endif //RATECONTROL + + User::Leave( KErrNotSupported ); + } + +// --------------------------------------------------------------------------- +// CMccVideoSourceImpl::DoCodecSpecificConfigurationL +// --------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::DoCodecSpecificConfigurationL( TUid& aEncoderUid ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::DoCodecSpecificConfigurationL" ) + + TBuf8 sdpName = iVideoCodec.iSdpName; + + if ( iVideoCodec.iSdpName.FindF( KH263SdpName ) != KErrNotFound ) + { + __V_SOURCESINK_CONTROLL( "H263" ) + const TUint maxBitRateOne = 64000; + const TUint maxBitRateTwo = 128000; + + if ( iVideoCodec.iMaxBitrate <= maxBitRateOne ) + { + __V_SOURCESINK_CONTROLL( "level set 10" ) + iMaxNegBitRate = maxBitRateOne; + } + else if ( iVideoCodec.iMaxBitrate > maxBitRateOne && + iVideoCodec.iMaxBitrate <= maxBitRateTwo ) + { + __V_SOURCESINK_CONTROLL( "level set 45" ) + iMaxNegBitRate = maxBitRateTwo; + } + else + { + __V_SOURCESINK_CONTROLL( "max bitrate too high, set level 45" ) + iMaxNegBitRate = maxBitRateTwo; + iVideoCodec.iMaxBitrate = maxBitRateTwo; + } + + if ( iVideoCodec.iCodecMode == KH263FormatModeOld ) + { + __V_SOURCESINK_CONTROLL( "mode set 1998" ) + } + + // Always use H263-2000 mime type as mediarecorder doesn't support 1998 mode + sdpName = KH2632000SdpName; + } + else if ( iVideoCodec.iSdpName.CompareF( KAVCSdpName ) == 0 ) + { + __V_SOURCESINK_CONTROLL( "AVC" ) + + iMaxNegBitRate = iVideoCodec.iMaxBitrate; + __V_SOURCESINK_CONTROLL_INT1( "CMccVideoSourceImpl::DoCodecSpecificConfigurationL, EncodingDecodingDeviceUid:", + iVideoCodec.iEncodingDecodingDevice.iUid ) + aEncoderUid = iVideoCodec.iEncodingDecodingDevice; + } + else + { + // NOP + } + + HBufC8* fmtp = GetFmtpLC( iVideoCodec ); + + delete iVideoCodecFourCC; + iVideoCodecFourCC = NULL; + iVideoCodecFourCC = + HBufC8::NewL( KVideoCodecFourCC().Length() + KMaxSdpNameLength + fmtp->Length() ); + + iVideoCodecFourCC->Des().Format( KVideoCodecFourCC, &sdpName, &*fmtp ); + + CleanupStack::PopAndDestroy( fmtp ); + + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::DoCodecSpecificConfigurationL, exit" ); + } + +// --------------------------------------------------------------------------- +// CMccVideoSourceImpl::GetFmtpLC +// --------------------------------------------------------------------------- +// +HBufC8* CMccVideoSourceImpl::GetFmtpLC( const TMccCodecInfo& aCodecInfo ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::GetFmtpLC" ) + + CMccCodecInformationFactory* factory = CMccCodecInformationFactory::NewL(); + CleanupStack::PushL( factory ); + CMccCodecInformation* codec = + factory->CreateCodecInformationL( aCodecInfo.iSdpName ); + CleanupStack::PushL( codec ); + codec->SetValues( aCodecInfo ); + HBufC8* fmtp = codec->GetFmtpL().AllocL(); + CleanupStack::PopAndDestroy( codec ); + CleanupStack::PopAndDestroy( factory ); + CleanupStack::PushL( fmtp ); + + __V_SOURCESINK_CONTROLL_STR8( "fmtp:", *fmtp ) + + if ( aCodecInfo.iSdpName.CompareF( KAVCSdpName ) == 0 ) + { + __V_SOURCESINK_CONTROLL( "avc handling" ) + + TPtr8 ptrFmtp( fmtp->Des() ); + // Strip useless information off from SDP + // (mediarecorder does not accept packetization mode etc.) + TInt index = ptrFmtp.Find( KTxtProfileLevelId ); + if ( index >= 0 ) + { + _LIT8( KSemicolon, ";" ); + TInt semicolonIndex = ptrFmtp.Mid( index ).Find( KSemicolon ); + + if ( semicolonIndex > 0 ) + { + HBufC8* strippedFmtp = ptrFmtp.Mid( index, semicolonIndex ).AllocL(); + CleanupStack::PopAndDestroy( fmtp ); + fmtp = strippedFmtp; + CleanupStack::PushL( fmtp ); + __V_SOURCESINK_CONTROLL_STR8( "stripped fmtp:", *fmtp ) + } + } + } + + return fmtp; + } + +// --------------------------------------------------------------------------- +// CMccVideoSourceImpl::SetConfigKeyL +// Base 64 encoded version of key is more for session negotiation and does +// not need to be updated if it already existis. Raw data config key is +// used inside stream and it will represent current configuration information +// as it will be received from mediarecorded. Therefore keep updating it. +// --------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::SetConfigKeyL( const TDesC8& aData ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SetConfigKeyL" ) + + if ( iConfigKey == NULL ) + { + TInt bufferProgressIndex( 0 ); + TInt part1StartIndex = + TMccCodecInfo::FindAvcNaluStart( bufferProgressIndex, aData ); + __ASSERT_ALWAYS( part1StartIndex != KErrNotFound, User::Leave( KErrNotFound ) ); + + TInt part1EndIndex = TMccCodecInfo::FindAvcNaluEnd( bufferProgressIndex, aData ); + __ASSERT_ALWAYS( part1EndIndex != KErrNotFound, User::Leave( KErrNotFound ) ); + + TInt part2StartIndex = TMccCodecInfo::FindAvcNaluStart( bufferProgressIndex, aData ); + __ASSERT_ALWAYS( part2StartIndex != KErrNotFound, User::Leave( KErrNotFound ) ); + + TInt part2EndIndex = TMccCodecInfo::FindAvcNaluEnd( bufferProgressIndex, aData ); + __ASSERT_ALWAYS( part2EndIndex != KErrNotFound, User::Leave( KErrNotFound ) ); + + TInt part1Len = part1EndIndex - part1StartIndex; + HBufC8* confKeyPart1 = + MccConversionUtility::Base64EncodeLC( aData.Mid( part1StartIndex, part1Len ) ); + + TInt part2Len = part2EndIndex - part2StartIndex; + HBufC8* confKeyPart2 = + MccConversionUtility::Base64EncodeLC( aData.Mid( part2StartIndex, part2Len ) ); + + _LIT8( KMccVideoSourceNaluSeparator, "," ); + + iConfigKey = HBufC8::NewL( + confKeyPart1->Length() + + confKeyPart2->Length() + + KMccVideoSourceNaluSeparator().Length() ); + TPtr8 ptrConfigKey( iConfigKey->Des() ); + ptrConfigKey.Append( *confKeyPart1 ); + ptrConfigKey.Append( KMccVideoSourceNaluSeparator() ); + ptrConfigKey.Append( *confKeyPart2 ); + + CleanupStack::PopAndDestroy( confKeyPart2 ); + CleanupStack::PopAndDestroy( confKeyPart1 ); + + __V_SOURCESINK_CONTROLL_STR8( "base64 encoded:", *iConfigKey ) + } + + delete iConfigKeyData; + iConfigKeyData = NULL; + iConfigKeyData = aData.AllocL(); + + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::SetConfigKeyL, exit" ) + } + +// --------------------------------------------------------------------------- +// CMccVideoSourceImpl::FullPrepareAllowed +// --------------------------------------------------------------------------- +// +TBool CMccVideoSourceImpl::FullPrepareAllowed() + { + TBool allowed( !iMultipleCodecs ); + if ( iVideoCodec.iSdpName.CompareF( KAVCSdpName ) == 0 ) + { + // Config key needs to exists before full prepare is allowed for AVC + allowed &= ( iConfigKey != NULL || iConfigKeyRetrieval ); + } + + return allowed; + } + +// --------------------------------------------------------------------------- +// CMccVideoSourceImpl::WriteFirstBufferL +// --------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::WriteFirstBufferL() + { + if ( iVideoConsumerBuffer ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::WriteFirstBufferL" ) + + CMMFDataBuffer* queuedBuf = FetchQueuedBuffer(); + CleanupStack::PushL( queuedBuf ); + if ( queuedBuf && CopyBufferData( *iVideoConsumerBuffer, *queuedBuf ) ) + { + DoBufferFilledL(); + } + CleanupStack::PopAndDestroy( queuedBuf ); + + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::WriteFirstBufferL, exit" ) + } + } + +// --------------------------------------------------------------------------- +// CMccVideoSourceImpl::AddIFrameToQueueL +// In case of AVC is used, config data is sent before each iframe. +// Config data is not sent before first iframe or if queue doesn't have +// room for config data. +// --------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::AddIFrameToQueueL( CMMFDataBuffer* aBuffer ) + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::AddIFrameToQueueL" ) + + __ASSERT_ALWAYS( aBuffer, User::Leave( KErrArgument ) ); + + if ( iConfigKeyData && + ( iVideoCodec.iSdpName.CompareF( KAVCSdpName ) == 0 ) && + ( iVideoQueue.Count() < ( KMccMaxVideoQueueSize - 1 ) ) && + iFirstIFrameQueued ) + { + __V_SOURCESINK_CONTROLL( + "CMccVideoSourceImpl::AddIFrameToQueueL, adding config data" ) + + CMMFDataBuffer* configDataBuf = + CMMFDataBuffer::NewL( iConfigKeyData->Length() ); + CleanupStack::PushL( configDataBuf ); + configDataBuf->Data().Copy( *iConfigKeyData ); + configDataBuf->SetTimeToPlay( aBuffer->TimeToPlay() ); + configDataBuf->SetLastBuffer( EFalse ); + iVideoQueue.AppendL( configDataBuf ); + CleanupStack::Pop( configDataBuf ); + } + + if ( iMccResources ) + { + __V_SOURCESINK_CONTROLL( + "CMccVideoSourceImpl::AddIFrameToQueueL, store iframe info" ) + iMccResources->StoreKeyFrameInfoL( iEndpointId, *aBuffer ); + + __V_SOURCESINK_CONTROLL( + "CMccVideoSourceImpl::AddIFrameToQueueL, info stored" ) + } + + iVideoQueue.AppendL( aBuffer ); + + iFirstIFrameQueued = ETrue; + + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::AddIFrameToQueueL, exit" ) + } + +// --------------------------------------------------------------------------- +// CMccVideoSourceImpl::HandleCameraReservationL +// Camera is needed only for real once autoplay is enabled or config key +// is retrieved. If retrieving config key, we need to force camera creation. +// --------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::HandleCameraReservationL() + { + if ( AutoPlayMode() || iConfigKeyRetrieval ) + { + TBool forceImmediateCameraCreation( iConfigKeyRetrieval ); + + __V_SOURCESINK_CONTROLL_INT1( + "CMccVideoSourceImpl::HandleCameraReservationL, force", + forceImmediateCameraCreation ) + + User::LeaveIfError( iCameraHandler->MonitorCameraReservation( + *this, forceImmediateCameraCreation ) ); + } + else + { + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::HandleCameraReservationL, nop" ) + + SendStreamEventToClient( KMccStreamPrepared, KErrNone, KMccAutomaticEvent ); + } + __V_SOURCESINK_CONTROLL( "CMccVideoSourceImpl::HandleCameraReservationL, exit" ) + } + +// --------------------------------------------------------------------------- +// CMccVideoSourceImpl::StopCameraMonitoring +// --------------------------------------------------------------------------- +// +void CMccVideoSourceImpl::StopCameraMonitoring() + { + if ( iCameraHandler ) + { + // Unregister, ignore error as we might not be even monitoring + // Can release resource as if it was created just for temporary purpose + TBool forceImmediateCameraRelease( iConfigKeyRetrieval ); + iCameraHandler->StopCameraMonitoring( + *this, forceImmediateCameraRelease ); + } + } + +#ifndef EKA2 +// DLL interface code +EXPORT_C TInt E32Dll( TDllReason ) + { + return KErrNone; + } +#endif