diff -r 000000000000 -r 5f000ab63145 phoneapp/phoneuiview/src/cphonevideoplayer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phoneapp/phoneuiview/src/cphonevideoplayer.cpp Mon Jan 18 20:18:27 2010 +0200 @@ -0,0 +1,715 @@ +/* +* Copyright (c) 2002-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: Video ringing tone player +* +*/ + + +// INCLUDE FILES +#include "CPhoneVideoPlayer.h" + +#include "PhoneUI.pan" +#include "MPhoneVideoPlayerObserver.h" +#include "CPhoneRingingTone.h" +#include "PhoneConstants.h" +#include "PhoneLogger.h" + +#include // CEikEnv +#include // CCoeEnv +#include // CVideoPlayerUtility + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CPhoneVideoPlayer::CPhoneVideoPlayer +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CPhoneVideoPlayer::CPhoneVideoPlayer( + MPhoneVideoPlayerObserver& aObserver ) + : + iObserver( aObserver ), + iVideoPlayer( NULL ), + iPlayerState( EVideoClosed ), + iVolume( 0 ) + { + } + +// ----------------------------------------------------------------------------- +// CPhoneVideoPlayer::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CPhoneVideoPlayer::ConstructL( + const TDesC& aFileName, + TInt aPriority, + TUint aPreference, + RWindow& aVideoTarget ) + { + // Screen and clip rectangles to window dimensions + TPoint wndPosition( aVideoTarget.AbsPosition() ); + TSize wndSize( aVideoTarget.Size() ); + TRect wndRect( wndPosition, wndSize ); + + // Create video player instance + iVideoPlayer = CVideoPlayerUtility::NewL( + *this, + aPriority, + static_cast( aPreference ), + CCoeEnv::Static()->WsSession(), + *CCoeEnv::Static()->ScreenDevice(), + aVideoTarget, + wndRect, + wndRect ); + + RFs fs = CEikonEnv::Static()->FsSession(); + User::LeaveIfError( iFileHandle.Open( fs, + aFileName, + EFileShareReadersOnly | + EFileStream | + EFileRead ) ); + + iVideoPlayer->OpenFileL( iFileHandle ); // async + + iPlayerState = EVideoOpening; + } + +// ----------------------------------------------------------------------------- +// CPhoneVideoPlayer::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CPhoneVideoPlayer* CPhoneVideoPlayer::NewL( + const CPhoneRingingTone& aRingingTone, + TInt aPriority, + TUint aPreference, + MPhoneVideoPlayerObserver& aObserver, + RWindow& aVideoTarget, + TBool aExtSecNeeded ) + { + // Check the file DRM property if extend secure is needed. + if ( aExtSecNeeded ) + { + __PHONELOG( EBasic, EPhoneUIView, "CPhoneVideoPlayer::NewL - check DRM extend security" ); + if ( !aRingingTone.IsFileInRom() && + !aRingingTone.IsFileDrmProtected() ) + { + __PHONELOG( EBasic, EPhoneUIView, "CPhoneVideoPlayer::NewL - DRM extend security permission denied" ); + User::Leave( KErrPermissionDenied ); + } + __PHONELOG( EBasic, EPhoneUIView, "CPhoneVideoPlayer::NewL - check DRM extend security - ok" ); + } + + CPhoneVideoPlayer* self = new(ELeave) CPhoneVideoPlayer( aObserver ); + + CleanupStack::PushL( self ); + self->ConstructL( + aRingingTone.FileName(), + aPriority, + aPreference, + aVideoTarget ); + CleanupStack::Pop( self ); + + return self; + } + +// ----------------------------------------------------------------------------- +// CPhoneVideoPlayer::New +// Two-phased constructor (non-leaving) +// ----------------------------------------------------------------------------- +// +CPhoneVideoPlayer* CPhoneVideoPlayer::New( + const CPhoneRingingTone& aRingingTone, + TInt aPriority, + TUint aPreference, + MPhoneVideoPlayerObserver& aObserver, + RWindow& aVideoTarget, + TBool aExtSecNeeded ) + { + CPhoneVideoPlayer* self = NULL; + + TRAP_IGNORE( self = CPhoneVideoPlayer::NewL( + aRingingTone, + aPriority, + aPreference, + aObserver, + aVideoTarget, + aExtSecNeeded ) ); + + return self; // this is NULL if NewL leaves + } + +// Destructor +CPhoneVideoPlayer::~CPhoneVideoPlayer() + { + if ( iVolumeRampTimer ) + { + iVolumeRampTimer->Cancel(); + delete iVolumeRampTimer; + } + + if ( iVideoPlayer ) + { + iVideoPlayer->Close(); + delete iVideoPlayer; + } + + iFileHandle.Close(); + + } + +// ----------------------------------------------------------------------------- +// CPhoneVideoPlayer::Play +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CPhoneVideoPlayer::Play( + TRingingType aRingType, + TInt aVolume ) + { + __PHONELOG2( + EBasic, + EPhoneUIView, + "CPhoneVideoPlayer::Play - aRingType(%d), aVolume(%d)", + aRingType, + aVolume ); + + __ASSERT_DEBUG( iVideoPlayer, Panic( EPhoneViewGeneralError ) ); + + iRingingType = aRingType; + iVolume = aVolume; + + switch( iPlayerState ) + { + case EVideoOpening: + case EVideoPreparing: + case EVideoOpen: + // see MvpuoPrepareComplete() + iToBePlayed = ETrue; + break; + + case EVideoReady: + iVideoPlayer->Play(); + iPlayerState = EVideoPlaying; + break; + + case EVideoPlaying: + case EVideoClosed: + case EVideoError: + default: + // NOP + break; + } + + return; + } + +// ----------------------------------------------------------------------------- +// CPhoneVideoPlayer::StopPlaying +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CPhoneVideoPlayer::StopPlaying() + { + __PHONELOG( EBasic, EPhoneUIView, "CPhoneVideoPlayer::StopPlaying" ); + + iToBePlayed = EFalse; + + if ( iVolumeRampTimer ) + { + iVolumeRampTimer->Cancel(); + } + + if ( iPlayerState == EVideoPlaying ) + { + iVideoPlayer->Stop(); + iPlayerState = EVideoReady; + } + } + +// ----------------------------------------------------------------------------- +// CPhoneVideoPlayer::PausePlaying +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CPhoneVideoPlayer::PausePlaying() + { + __LOGMETHODSTARTEND(EPhoneUIView, "CPhoneVideoPlayer::StopPlaying "); + TInt err = KErrNone; + + if ( iPlayerState == EVideoPlaying ) + { + TRAP( err, iVideoPlayer->PauseL() ); + if ( err == KErrNone ) + { + iPlayerState = EVideoPaused; + } + } + else + { + err = KErrNotReady; + } + + return err; + } + +// ----------------------------------------------------------------------------- +// CPhoneVideoPlayer::ResumePlaying +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CPhoneVideoPlayer::ResumePlaying() + { + __LOGMETHODSTARTEND(EPhoneUIView, "CPhoneVideoPlayer::ResumePlaying "); + + if ( iPlayerState == EVideoPaused ) + { + iVideoPlayer->Play(); + iPlayerState = EVideoPlaying; + } + } + +// ----------------------------------------------------------------------------- +// CPhoneVideoPlayer::MuteAudio +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CPhoneVideoPlayer::MuteAudio() + { + __PHONELOG( EBasic, EPhoneUIView, "CPhoneVideoPlayer::MuteAudio" ); + + if ( iVolumeRampTimer ) + { + iVolumeRampTimer->Cancel(); + } + + iVolume = 0; + SetVolume( 0 ); + } + +// ----------------------------------------------------------------------------- +// CPhoneVideoPlayer::SetVolume +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CPhoneVideoPlayer::SetVolume( TInt aVolume ) + { + __PHONELOG1( + EBasic, + EPhoneUIView, + "CPhoneVideoPlayer::SetVolume - aVolume(%d)", + aVolume ); + + TInt maxVolume( iVideoPlayer->MaxVolume() ); + maxVolume = ( maxVolume > 0 ) ? maxVolume : KPhoneVideoMaxVolumeLevel; + + TInt scaledVolume = ( aVolume * maxVolume ) / KPhoneVideoMaxVolumeLevel; + + TRAP_IGNORE( iVideoPlayer->SetVolumeL( scaledVolume ) ); + } + +// ----------------------------------------------------------------------------- +// CPhoneVideoPlayer::SetRingingType +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CPhoneVideoPlayer::SetRingingType( TRingingType aRingingType ) + { + __PHONELOG1( + EBasic, + EPhoneUIView, + "CPhoneVideoPlayer::SetRingingType - aRingingType(%d)", + aRingingType ); + + if ( aRingingType == ETypeAscending ) + { + if ( !iVolumeRampTimer ) + { + iVolumeRampTimer = CPeriodic::New( CActive::EPriorityStandard ); + } + + if ( iVolumeRampTimer && !iVolumeRampTimer->IsActive() ) + { + TCallBack cb( VolumeRampTimerCallback, this ); + + SetVolume( KPhoneVideoMinVolumeLevel ); + iRampedVolume = KPhoneVideoMinVolumeLevel; + iVolumeRampTimer->Start( + KPhoneVideoVolumeRampInterval, + KPhoneVideoVolumeRampInterval, + cb ); + } + } + } + +// ----------------------------------------------------------------------------- +// CPhoneVideoPlayer::VolumeRampTimerCallback +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CPhoneVideoPlayer::VolumeRampTimerCallback( TAny* aObj ) + { + return static_cast( aObj )->DoVolumeRamp(); + } + +// ----------------------------------------------------------------------------- +// CPhoneVideoPlayer::DoVolumeRamp +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TInt CPhoneVideoPlayer::DoVolumeRamp() + { + if ( iRampedVolume < iVolume ) + { + iRampedVolume = iRampedVolume + KPhoneVideoVolumeRampStep; + if ( iRampedVolume >= iVolume ) + { + // target volume level reached + iRampedVolume = iVolume; + iVolumeRampTimer->Cancel(); + } + + SetVolume( iRampedVolume ); + } + + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CPhoneVideoPlayer::State +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +CPhoneVideoPlayer::TVideoPlayerState CPhoneVideoPlayer::State() const + { + return iPlayerState; + } + +// ----------------------------------------------------------------------------- +// CPhoneVideoPlayer::VideoResolution +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +CPhoneVideoPlayer::TVideoResolution CPhoneVideoPlayer::VideoResolution() const + { + TSize frameSize( VideoFrameSize() ); + + // SubQCCIF video resolution is 128x96 pixels + if ( frameSize.iWidth == KPhoneVideoSubQCCIFWidth && + frameSize.iHeight == KPhoneVideoSubQCCIFHeight ) + { + return EVideoSubQCIF; + } + + return EVideoQCIF; + } + +// ----------------------------------------------------------------------------- +// CPhoneVideoPlayer::VideoResolution +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TSize CPhoneVideoPlayer::VideoFrameSize() const + { + TSize frameSize( 0,0 ); + + TRAPD( err, iVideoPlayer->VideoFrameSizeL( frameSize ) ); + + if ( err != KErrNone ) + { + return TSize(0,0); + } + + return frameSize; + } + +// ----------------------------------------------------------------------------- +// CPhoneVideoPlayer::AdjustToWindow +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CPhoneVideoPlayer::AdjustToWindow( RWindow& aDisplayWindow, + const TRect& aUncropPane ) + { + __ASSERT_DEBUG( iPlayerState == EVideoReady, Panic( EPhoneViewGeneralError ) ); + + // Get video frame dimensions + TSize frameSize( VideoFrameSize() ); + + if ( frameSize.iWidth == 0 || frameSize.iHeight == 0 ) + { + return; + } + + // Uncrop pane dimensions + TSize uncropPaneSize( aUncropPane.Size() ); + + // To cover display window: + // The video is scaled to match to dimensions of uncrop pane defined + // in Call Handling LAF. Video is centered to uncrop pane if exact + // match is not possible. + // Assumption is that video can be scaled to 50,150 or 200 + // percent from its original size (can't be scaled freely). + + ///////////////////////////// + // Calculate scaling factor + ///////////////////////////// + TInt dScaleFactor( KBaseScaleFactor ); // use integer arithmetic + + TInt xDelta( uncropPaneSize.iWidth - frameSize.iWidth ); + TInt yDelta( uncropPaneSize.iHeight - frameSize.iHeight ); + + if ( xDelta == 0 && yDelta == 0 ) + { + // correct size, scaling not needed + } + else if ( xDelta < 0 && yDelta == 0 ) + { + // wide, but cannot downscale -> just crop + } + else if ( yDelta < 0 && xDelta == 0 ) + { + // tall, but cannot downscale -> just crop + } + else if ( xDelta > 0 && yDelta > 0 ) + { + // small, narrow and flat -> enlarge + TInt xProp( ( KBaseScaleFactor * uncropPaneSize.iWidth ) / frameSize.iWidth ); + TInt yProp( ( KBaseScaleFactor * uncropPaneSize.iHeight ) / frameSize.iHeight ); + + dScaleFactor = xProp > yProp ? xProp : yProp; + } + else if ( xDelta < 0 && yDelta < 0 ) + { + // large, wide and tall -> downscale + TInt xProp( ( KBaseScaleFactor * uncropPaneSize.iWidth ) / frameSize.iWidth ); + TInt yProp( ( KBaseScaleFactor * uncropPaneSize.iHeight ) / frameSize.iHeight ); + + dScaleFactor = xProp > yProp ? xProp : yProp; + } + else if ( xDelta > 0 && yDelta <= 0 ) + { + // narrow -> enlarge + dScaleFactor = ( KBaseScaleFactor * uncropPaneSize.iWidth ) / frameSize.iWidth; + } + else if ( yDelta > 0 && xDelta <= 0 ) + { + // flat -> enlarge + dScaleFactor = ( KBaseScaleFactor * uncropPaneSize.iHeight ) / frameSize.iHeight; + } + else + { + // do nothing + } + + // Convert to float: 0.5, 1.5, 2.0 .. + TInt scaleFactor( dScaleFactor / KBaseScaleFactor ); + TInt remainder( dScaleFactor % KBaseScaleFactor ); + TReal32 fScaleFactor = (TReal) scaleFactor ; + + if ( scaleFactor > 0 ) // upscale + { + if ( remainder > KHalfBaseScale ) + { + fScaleFactor = fScaleFactor + KFullScaleFactor; + } + else if ( remainder > 0 ) + { + fScaleFactor = fScaleFactor + KHalfScaleFactor; + } + else // 0 + { + } + } + else // downscale + { + if ( remainder > KHalfBaseScale ) + { + fScaleFactor = KFullScaleFactor; + } + else + { + fScaleFactor = KHalfScaleFactor; + } + } + + //////////////////////////////////////////////// + // Calculate scaled frame size (virtual canvas) + //////////////////////////////////////////////// + TReal32 canvasWidth = fScaleFactor * (TReal32)frameSize.iWidth; + TReal32 canvasHeight = fScaleFactor * (TReal32)frameSize.iHeight; + TSize canvasSize( (TInt)canvasWidth, (TInt)canvasHeight ); + + //////////////////////////////////////////////// + // Crop by centering displayRect to canvasRect + //////////////////////////////////////////////// + TRect canvasRect( aUncropPane.iTl, canvasSize ); + TInt offsetX = (uncropPaneSize.iWidth - canvasSize.iWidth) / KCentering; + TInt offsetY = (uncropPaneSize.iHeight - canvasSize.iHeight) / KCentering; + canvasRect.Move( offsetX, offsetY ); + + // Video is autoscaled by video player + // iVideoPlayer->SetScaleFactorL(...); + + TRect clipRect( aDisplayWindow.AbsPosition(), aDisplayWindow.Size() ); + + //////////////////////////////////////////////// + // Update settings to player + //////////////////////////////////////////////// + TRAP_IGNORE( + iVideoPlayer->SetDisplayWindowL( + CCoeEnv::Static()->WsSession(), + *CCoeEnv::Static()->ScreenDevice(), + aDisplayWindow, + canvasRect, + clipRect ) ); + + } + + +// ========================================================= +// Callbacks from VideoPlayerutility +// ========================================================= + +// --------------------------------------------------------- +// see MVideoPlayerUtilityObserver::MvpuoOpenComplete +// --------------------------------------------------------- +void CPhoneVideoPlayer::MvpuoOpenComplete( TInt aError ) + { + __PHONELOG1( + EBasic, + EPhoneUIView, + "CPhoneVideoPlayer::MvpuoOpenComplete - aError(%d)", + aError ); + + if ( aError == KErrNone ) + { + // Prepare clip for playing + iPlayerState = EVideoPreparing; + iVideoPlayer->Prepare(); + } + else // Report error + { + iPlayerState = EVideoError; + iObserver.HandleVideoPlayerError( + MPhoneVideoPlayerObserver::EVideoPlayerInitializingFailure, + aError ); + } + } + +// --------------------------------------------------------- +// see MVideoPlayerUtilityObserver::MvpuoPrepareComplete +// --------------------------------------------------------- +void CPhoneVideoPlayer::MvpuoPrepareComplete( TInt aError ) + { + __PHONELOG1( + EBasic, + EPhoneUIView, + "CPhoneVideoPlayer::MvpuoPrepareComplete - aError(%d)", + aError ); + + if ( aError == KErrNone ) + { + iPlayerState = EVideoReady; + iObserver.HandleVideoPlayerInitComplete(); + + SetVolume( iVolume ); + SetRingingType( iRingingType ); + + if ( iToBePlayed ) + { + iVideoPlayer->Play(); + } + } + else // Report error + { + iPlayerState = EVideoError; + iObserver.HandleVideoPlayerError( + MPhoneVideoPlayerObserver::EVideoPlayerInitializingFailure, + aError ); + } + } + +// --------------------------------------------------------- +// see MVideoPlayerUtilityObserver::MvpuoFrameReady +// --------------------------------------------------------- +void CPhoneVideoPlayer::MvpuoFrameReady( CFbsBitmap& /*aFrame*/, + TInt /*aError*/ ) + { + // NOP + } + +// --------------------------------------------------------- +// see MVideoPlayerUtilityObserver::MvpuoPlayComplete +// Trapping callback as leaving not allowed. +// --------------------------------------------------------- +void CPhoneVideoPlayer::MvpuoPlayComplete( TInt aError ) + { + __PHONELOG1( + EBasic, + EPhoneUIView, + "CPhoneVideoPlayer::MvpuoPlayComplete - aError(%d)", + aError ); + + if ( aError == KErrNone ) + { + iPlayerState = EVideoReady; + + if ( iRingingType == ETypeRingingOnce ) + { + iObserver.HandleVideoPlayerPlayingComplete(); + } + else // continue playing + { + iVideoPlayer->Play(); + iPlayerState = EVideoPlaying; + } + } + else // report error + { + iPlayerState = EVideoError; + iObserver.HandleVideoPlayerError( + MPhoneVideoPlayerObserver::EVideoPlayerPlayingFailure, + aError ); + } + } + +// --------------------------------------------------------- +// see MVideoPlayerUtilityObserver::MvpuoEvent +// Trapping callback as leaving not allowed. +// --------------------------------------------------------- +void CPhoneVideoPlayer::MvpuoEvent( const TMMFEvent& /*aEvent*/ ) + { + // NOP + } + +// End of File