--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/browserplugins/browseraudiovideoplugin/src/BavpControllerVideo.cpp Mon Mar 30 12:49:49 2009 +0300
@@ -0,0 +1,1347 @@
+/*
+* 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 the License "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: Controller class for handling browser requests to play video
+*
+*/
+
+
+// INCLUDE FILES
+#include <mmf/common/mmferrors.h>
+#include <aknclearer.h>
+#include <AknUtils.h>
+
+#include "BavpPlugin.h"
+#include "BavpLogger.h"
+#include "BavpControllerVideo.h"
+#include "BavpView.h"
+#include "BavpViewFullScreen.h"
+#include <mmf/common/mmfcontrollerframework.h>
+#include <MMFScalingCustomCommandConstants.h>
+
+// CONSTANTS
+// One second represented in microseconds
+const TInt KBavpOneSecond = 1000000;
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+CBavpControllerVideo* CBavpControllerVideo::NewL( MBavpView* aView,
+ TUint aAccessPtId,
+ TBavpMediaType aMediaType,
+ const TDesC& aFileName )
+ {
+ CBavpControllerVideo* self = new( ELeave ) CBavpControllerVideo( aView, aAccessPtId );
+
+ Log( EFalse, _L("CBavpControllerVideo::NewL this="), (TInt)self );
+
+ CleanupStack::PushL( self );
+ self->ConstructL( aMediaType, aFileName );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::~CBavpControllerVideo()
+// Destructor
+// -----------------------------------------------------------------------------
+CBavpControllerVideo::~CBavpControllerVideo()
+ {
+ Log( EFalse, _L("CBavpControllerVideo::~CBavpControllerVideo this="), (TInt)this );
+
+ // If currently playing, call Stop before you close and delete
+ if ( iCurrentState == EBavpPlaying && iVideoPlayer)
+ {
+ iVideoPlayer->Stop();
+ }
+
+ // Close the video plugin, and delete it
+ if ( iVideoPlayer )
+ {
+ iVideoPlayer->Close();
+ delete iVideoPlayer;
+ }
+
+ // CIdle AO used for display update
+ if ( iDisplayUpdater )
+ {
+ delete iDisplayUpdater;
+ }
+
+ if ( iBackLightUpdater )
+ {
+ iBackLightUpdater->Cancel();
+ delete iBackLightUpdater;
+ }
+ // Used for displaying content in full screen
+ if ( iBavpViewFullScreen )
+ {
+ delete iBavpViewFullScreen;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::CBavpControllerVideo
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+CBavpControllerVideo::CBavpControllerVideo( MBavpView* aView, TUint aAccessPtId )
+ : CBavpController( aView, aAccessPtId )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::ConstructL( TBavpMediaType aMediaType,
+ const TDesC& aFileName )
+ {
+ // Construct the BavpController base class
+ BaseConstructL( aMediaType, aFileName );
+
+ // Create CIdle (AO) to update the display
+ iDisplayUpdater = CIdle::NewL( CActive::EPriorityIdle );
+ iBackLightUpdater=CHeartbeat::NewL(CActive::EPriorityStandard);
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::PrepareCompleteL
+// Handle the leaving methods needed by MvpuoPrepareComplete
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::PrepareCompleteL()
+ {
+ // Resolution
+ TSize size;
+ iVideoPlayer->VideoFrameSizeL(size);
+ iClipInfo->iResolutionHeight = size.iHeight;
+ iClipInfo->iResolutionWidth = size.iWidth;
+
+ // Bitrate
+ iClipInfo->iBitrate = iVideoPlayer->VideoBitRateL() +
+ iVideoPlayer->AudioBitRateL();
+
+ TInt iMetaCount = iVideoPlayer->NumberOfMetaDataEntriesL();
+ CMMFMetaDataEntry* metaData = NULL;
+
+ for ( TInt i = 0; i < iMetaCount; i++ )
+ {
+ metaData = iVideoPlayer->MetaDataEntryL( i );
+
+ Log( EFalse, _L("metaData index="), i );
+ Log( EFalse, metaData->Name() );
+ Log( EFalse, metaData->Value() );
+
+ // Check if seekable
+ if ( !metaData->Name().CompareF( KBavpSeekable ) )
+ {
+ if ( !metaData->Value().CompareF( KBavpFalse ) )
+ {
+ iClipInfo->iSeekable = EFalse;
+ }
+ }
+
+ // Check if live stream
+ if ( !metaData->Name().CompareF( KBavpLiveStream ) )
+ {
+ if ( !metaData->Value().CompareF( KBavpTrue ) )
+ {
+ // Live stream is not seekable
+ iClipInfo->iLiveStream = ETrue;
+ iClipInfo->iSeekable = EFalse;
+ }
+ }
+
+ delete metaData;
+ } // end of for
+
+ // Set up the max volume
+ iClipInfo->iMaxVolume = iVideoPlayer->MaxVolume();
+ iPlayerMaxVolume = iClipInfo->iMaxVolume;
+
+ // Duration
+ iClipInfo->iDurationInSeconds = iVideoPlayer->DurationL();
+
+ // Audio track
+ iClipInfo->iAudioTrack = iVideoPlayer->AudioEnabledL();
+
+ // Video track
+ iClipInfo->iVideoTrack = iVideoPlayer->VideoBitRateL();
+
+ if ( IsClipSeekable() )
+ {
+ iVideoPlayer->SetPositionL( iClipInfo->iPosition );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::InitVideoPlayer
+// The non-leaving version that calls the leaving version. Closes the current
+// player and prepares the MMF to play the video
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::InitVideoPlayer()
+ {
+ TRAP_IGNORE( InitVideoPlayerL() );
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::InitVideoPlayerL
+// Closes the current player and prepares the MMF to play the video
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::InitVideoPlayerL()
+ {
+ Log( EFalse, _L("CBavpControllerVideo::InitVideoPlayerL()") );
+
+ // If videoplayer is already opened, close and delete it
+ if ( iVideoPlayer )
+ {
+ iVideoPlayer->Close();
+ delete iVideoPlayer;
+ iVideoPlayer = NULL;
+ }
+
+ // Get the rect to display
+ TRect rect( iBavpView->CoeControl().Rect() );
+ TPoint pt = iBavpView->WindowInst().AbsPosition();
+ rect.Move( pt.iX, pt.iY );
+
+ CEikonEnv* eikon = CEikonEnv::Static();
+ RWsSession& ws = eikon->WsSession();
+ CWsScreenDevice* screenDevice = eikon->ScreenDevice();
+
+ // Clip rect manipulation.
+ // Calculate the rect for display, including title and status pane
+ TRect clipRect = GetClipRect( rect );
+
+ Log( EFalse, _L("InitVideoPlayerL() - calling CVideoPlayerUtility::NewL") );
+
+ // Initialize the videoplayer
+ iVideoPlayer = CVideoPlayerUtility::NewL( *this, EMdaPriorityNormal,
+ EMdaPriorityPreferenceNone,
+ ws, *screenDevice,
+ iBavpView->WindowInst(), rect,
+ clipRect);
+
+ // Register for loading notification
+ iVideoPlayer->RegisterForVideoLoadingNotification( *this );
+
+ switch ( iClipInfo->iMediaType )
+ {
+ case ELocalVideoFile:
+ Log( EFalse, _L("InitVideoPlayerL() - calling OpenVideoFile") );
+ OpenVideoFileL();
+ break;
+
+ case ELocalRamFile:
+ case EUrl:
+ case ELocalSdpFile:
+#if defined(BRDO_ASX_FILE)
+ case ELocalAsxFile:
+#endif // BRDO_ASX_FILE
+ Log( EFalse, _L("InitVideoPlayerL() - calling OpenVideoUrlL") );
+ OpenVideoUrlL();
+ break;
+
+ // Not supported
+ case ELocalAudioPlaylist:
+ default:
+ User::Leave( KErrNotSupported );
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::UnInitVideoPlayer
+// Closes the player and delete the instance
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::UnInitVideoPlayer()
+ {
+ Log( EFalse, _L("CBavpControllerVideo::UnInitVideoPlayer()") );
+
+ if ( iVideoPlayer )
+ {
+ iVideoPlayer->Close();
+ delete iVideoPlayer;
+ iVideoPlayer = NULL;
+ }
+
+ iCurrentState = EBavpNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::RotateScreen90
+// Rotate the screen if needed
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::RotateScreen90()
+ {
+ Log( EFalse, _L("CBavpControllerVideo::RotateScreen90()") );
+
+ TRect screenRect;
+ AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screenRect );
+
+ // Rotate only if screen rect height is greater than its width
+ if ( screenRect.Height() > screenRect.Width() )
+ {
+ TRAP_IGNORE( iVideoPlayer->SetRotationL( EVideoRotationClockwise90 ) );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::RevertToFullScreenL
+// Set full screen display mode
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::RevertToFullScreenL()
+ {
+ Log( EFalse, _L("CBavpControllerVideo::RevertToFullScreenL()"));
+ CBavpPluginEcomMain* npm = (CBavpPluginEcomMain*)Dll::Tls();
+ bool fullscreen = true;
+
+ iVideoPlayer->StopDirectScreenAccessL();
+ iClipInfo->iInFullScreenMode = ETrue;
+
+ npm->Funcs()->setvalue(iBavpView->bavPlugin()->getNPP(),
+ NPPVpluginFullScreenBool,
+ static_cast<void*>(&fullscreen));
+ iBavpView->ControllerStateChangedL();
+
+ CEikonEnv* eikon = CEikonEnv::Static();
+ RWsSession& ws = eikon->WsSession();
+ CWsScreenDevice* screenDevice = eikon->ScreenDevice();
+
+ iNormalScreenRect = iBavpView->CoeControl().Rect();
+ TPoint pt = iBavpView->WindowInst().AbsPosition();
+ iNormalScreenRect.Move(pt.iX, pt.iY);
+ TRect screenRect = eikon->EikAppUi()->ApplicationRect();
+
+ CCoeControl* parentView = iBavpView->CoeControl().Parent();
+ parentView->SetRect(screenRect);
+ iBavpView->CoeControl().SetExtent(TPoint(0,0), screenRect.Size());
+
+ iVideoPlayer->SetDisplayWindowL( ws, *screenDevice,
+ iBavpView->WindowInst(),
+ screenRect, screenRect );
+
+ RotateScreen90();
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::RevertToNormalScreenL
+// Set back to normal display mode
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::RevertToNormalScreenL()
+ {
+ Log( EFalse, _L("CBavpControllerVideo::RevertToNormalScreenL()") );
+ CEikonEnv* eikon = CEikonEnv::Static();
+ RWsSession& ws = eikon->WsSession();
+ CWsScreenDevice* screenDevice = eikon->ScreenDevice();
+ CBavpPluginEcomMain* npm = (CBavpPluginEcomMain*)Dll::Tls();
+ bool fullscreen = false;
+
+ iVideoPlayer->StopDirectScreenAccessL();
+
+ npm->Funcs()->setvalue(iBavpView->bavPlugin()->getNPP(),
+ NPPVpluginFullScreenBool,
+ static_cast<void*>(&fullscreen));
+
+ CCoeControl* parentView = iBavpView->CoeControl().Parent();
+ parentView->SetRect(iNormalScreenRect);
+ iBavpView->CoeControl().SetExtent(TPoint(0,0), iNormalScreenRect.Size());
+
+ iClipInfo->iInFullScreenMode = EFalse;
+ RefreshRectCoordinatesL();
+ iVideoPlayer->SetRotationL( EVideoRotationNone );
+ iBavpView->ControllerStateChangedL();
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::ToggleScreen
+// Start a call back for the display screen switches (Full Screen to
+// Normal Screen)
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::ToggleScreen()
+ {
+ if ( iDisplayUpdater->IsActive() )
+ {
+ iDisplayUpdater->Cancel();
+ }
+
+ iDisplayUpdater->Start( TCallBack( CBavpControllerVideo::WaitForScreenSwitch,
+ this ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::RefreshRectCoordinatesL
+// Refresh the coordinates of rect for display
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::RefreshRectCoordinatesL()
+ {
+ Log( EFalse, _L("CBavpControllerVideo::RefreshRectCoordinatesL()") );
+
+ if ( IsClipFullScreen() ) {
+ return;
+ }
+ if ( iVideoPlayer )
+ {
+ TRect rect( iBavpView->CoeControl().Rect() );
+
+ TRect wr(iBavpView->WindowRect()); //can have negative coordinates
+ //if video scrolled out of viewport
+ // Windows' absolute position, relative to the current screen
+ TPoint pt = iBavpView->WindowInst().AbsPosition();
+ rect.Move( pt.iX, pt.iY );
+ wr.Move( pt.iX, pt.iY );
+
+
+ CEikonEnv* eikon = CEikonEnv::Static();
+ RWsSession& ws = eikon->WsSession();
+ CWsScreenDevice* screenDevice = eikon->ScreenDevice();
+
+ // Reset clipRect
+ TRect clipRect = rect;
+ clipRect = GetClipRect( rect );
+
+ Log( EFalse, _L("\nPosition: == clipRect to DAS: ==\n") );
+ Log( EFalse, _L("\nPosition:: clipRect.x = \n"), clipRect.iTl.iX );
+ Log( EFalse, _L("\nPosition:: clipRect.y = \n"), clipRect.iTl.iY );
+ Log( EFalse, _L("\nPosition:2: clipRect.x = \n"), clipRect.iBr.iX );
+ Log( EFalse, _L("\nPosition:2: clipRect.y = \n"), clipRect.iBr.iY );
+
+ TRAP_IGNORE
+ (
+ iVideoPlayer->SetDisplayWindowL( ws, *screenDevice,
+ iBavpView->WindowInst(),
+ wr, clipRect );
+ );
+ if( iCurrentState == EBavpPaused || iCurrentState == EBavpStopped || iCurrentState == EBavpPlayComplete )
+ {
+ iVideoPlayer->RefreshFrameL();
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::WaitForScreenSwitch
+// Switches between normal screen and full screen
+// -----------------------------------------------------------------------------
+TInt CBavpControllerVideo::WaitForScreenSwitch( TAny* aThisData )
+ {
+ TRAP_IGNORE( WaitForScreenSwitchL( aThisData ) );
+ return KErrNone;
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::WaitForScreenSwitch
+// Switches between normal screen and full screen
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::WaitForScreenSwitchL( TAny* aThisData )
+ {
+ Log( EFalse, _L("CBavpControllerVideo::WaitForScreenSwitchL()") );
+
+ // Use static cast
+ CBavpControllerVideo* thisData = STATIC_CAST(CBavpControllerVideo*, aThisData);
+
+ // Switch from Normal screen mode to Full Screen mode
+ if ( !thisData->IsClipFullScreen() )
+ {
+ thisData->RevertToFullScreenL();
+
+ }
+ else if ( thisData->IsClipFullScreen() )
+ {
+ // Switch from Full Screen mode to Normal Screen mode
+ thisData->RevertToNormalScreenL();
+
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::DoFastForwardL
+// Fast forwards the video
+// -----------------------------------------------------------------------------
+TInt CBavpControllerVideo::DoFastForwardL( TAny* aThisData )
+ {
+ CBavpControllerVideo* thisData = STATIC_CAST( CBavpControllerVideo*, aThisData );
+ TTimeIntervalMicroSeconds skipPosition( 0 );
+ TTimeIntervalMicroSeconds currentPosition( thisData->iVideoPlayer->PositionL() );
+
+ Log( EFalse, _L("CBavpControllerVideo::DoFastForwardL() - currentPosition = "),
+ currentPosition.Int64() );
+
+ // If we're not at the end of clip, skip forward a few positions
+ if ( currentPosition < thisData->iClipInfo->iDurationInSeconds )
+ {
+ skipPosition = currentPosition.Int64() + KSkipToPosition;
+
+ // If skip pass end of clip, set to the end of clip
+ if ( skipPosition > thisData->iClipInfo->iDurationInSeconds )
+ {
+ skipPosition = thisData->iClipInfo->iDurationInSeconds;
+ }
+
+ Log( EFalse, _L("CBavpControllerVideo::DoFastForwardL() - skipPosition = "),
+ skipPosition.Int64() );
+
+ // Set the position
+ thisData->iVideoPlayer->SetPositionL( skipPosition );
+
+ // Refresh the frame
+ thisData->iVideoPlayer->RefreshFrameL();
+ thisData->iClipInfo->iPosition = skipPosition;
+ }
+ else
+ {
+ // Fast Forward reached the end of the clip, cancel the fast forward
+ thisData->iPositionUpdater->Cancel();
+ thisData->iClipInfo->iPosition = thisData->iClipInfo->iDurationInSeconds;
+ // Set the state to complete since it reached the end of the clip
+ thisData->iCurrentState = EBavpFastForwardComplete;
+ Log( EFalse, _L("CBavpControllerVideo::DoFastForwardL() - End of clip") );
+ }
+
+ return ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::DoRewindL
+// Rewinds the video
+// -----------------------------------------------------------------------------
+TInt CBavpControllerVideo::DoRewindL( TAny* aThisData )
+ {
+ CBavpControllerVideo* thisData = STATIC_CAST( CBavpControllerVideo*, aThisData );
+ TTimeIntervalMicroSeconds skipPosition( 0 );
+ TTimeIntervalMicroSeconds currentPosition( thisData->iVideoPlayer->PositionL() );
+
+ Log( EFalse, _L("CBavpControllerVideo::DoFastForwardL() - currentPosition = "),
+ currentPosition.Int64() );
+
+ // We're not at the beginning of the clip, rewind a few positions
+ if ( currentPosition > 0 )
+ {
+ skipPosition = currentPosition.Int64() - KSkipToPosition;
+
+ // If skip pass beginning of clip, set to the beginning of clip
+ if ( skipPosition < 0 )
+ {
+ skipPosition = 0;
+ }
+
+ Log( EFalse, _L("CBavpControllerVideo::RewindL() - skipPosition = "),
+ skipPosition.Int64() );
+
+ // Set the position
+ thisData->iVideoPlayer->SetPositionL( skipPosition );
+
+ // Refresh the frame
+ thisData->iVideoPlayer->RefreshFrameL();
+ thisData->iClipInfo->iPosition = skipPosition;
+ }
+ else
+ {
+ // Rewind reached the beginning of the clip, cancel the rewind
+ thisData->iPositionUpdater->Cancel();
+ thisData->iClipInfo->iPosition = 0;
+ // Set the state to complete since it reached beginning of clip
+ thisData->iCurrentState = EBavpRewindComplete;
+ Log( EFalse, _L("CBavpControllerVideo::RewindL() - beginning of clip") );
+ }
+
+ return ETrue;
+ }
+
+// --------------------------------------------------------------------------
+// CBavpControllerVideo::HandleError
+// Handle error codes. We can receive errors from the MMF Video Player
+// and its MMF callbacks (mvpuoPlayComplete, etc).
+// The MMF errors are for handling content issues, such as decoding content
+// and network access.
+// NOTES:
+// MMF errors start at -12000, see /epoc32/include/mmf/common/MMFErrors.h
+// MMF also returns -1 (KErrNotFound) and few other system-wide errors
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::HandleError( TInt aError )
+ {
+ Log( EFalse, _L("In CBavpControllerVideo::HandleError(): err="), aError );
+
+ switch ( aError )
+ {
+ case KErrSessionClosed: // When we stop live streaming
+ if ( iCurrentState == EBavpBuffering ||
+ iCurrentState == EBavpStopped )
+ {
+ Log( EFalse, _L("HandleError: iCurrentState=Buffering or Stopped and err=KErrSessionClosed") );
+ // Controller needs to be re-initialized, whenever
+ // live streaming is "Stopped"
+ // iCurrentState = EBavpNone, set by UnInitVideoPlayer
+ UnInitVideoPlayer();
+ // Set state to stopped, because we "stop" live content
+ iCurrentState = EBavpStopped;
+ }
+ else if ( iCurrentState == EBavpPlaying ||
+ iCurrentState == EBavpPaused )
+ {
+ Log( EFalse, _L("HandleError:iCurrentState=Playing or Paused and err=KErrSessionClosed") );
+ // If the window is not on top, it might be a video or phone
+ // call interrupt
+ TRAP_IGNORE
+ (
+ if ( !iBavpView->IsTopWindowL() )
+ {
+ InitVideoPlayer();
+ }
+ ) // end of TRAP_IGNORE
+ }
+ else
+ {
+ }
+ break;
+
+ case KErrDisconnected:
+ // If the window is not on top, it might be a video or phone
+ // call interrupt
+ Log( EFalse, _L("HandleError: err=KErrDisconnected") );
+ TRAP_IGNORE
+ (
+ if ( !iBavpView->IsTopWindowL() )
+ {
+ InitVideoPlayer();
+ }
+ ) // end of TRAP_IGNORE
+ break;
+
+ case KErrMMVideoDevice:
+ case KErrMMAudioDevice:
+ HandleMultiInstanceError();
+ break;
+
+ // Errors from MMF (i.e. MvpuoPrepareComplete, MvpuoPlayComplete...)
+ case KErrNotFound:
+ case KErrNotSupported:
+ case KErrCorrupt:
+ case KErrInUse:
+ case KErrNoMemory:
+ case KErrAbort:
+ case KErrArgument:
+ case KErrCouldNotConnect:
+ case KErrTimedOut:
+ case KErrHardwareNotAvailable:
+ case KErrOverflow:
+ case KErrMMNotEnoughBandwidth:
+ case KErrMMNetworkRead:
+ case KErrMMNetworkWrite:
+ case KErrMMServerNotSupported:
+ case KErrMMUDPReceive:
+ case KErrMMInvalidProtocol:
+ case KErrMMInvalidURL:
+ case KErrMMProxyServer:
+ case KErrMMDecoder:
+ case KErrMMPartialPlayback:
+ // Close the player and delete player instance.
+ // iCurrentState = EBavpNone, set by UnInitVideoPlayer.
+ UnInitVideoPlayer();
+
+ // Display we have bad content
+ Log( EFalse, _L("HandleError: state=BadContent") );
+ iCurrentState = EBavpBadContent;
+ iBavpView->UpdateView();
+ break;
+
+ default:
+ // Do nothing
+ break;
+
+ } // end of switch
+
+ Log( EFalse, _L("Out CBavpControllerVideo::HandleError()") );
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::HandleKeysL
+// Handles user key presses when we're Activated (aka Top of CCoeControl stack)
+// -----------------------------------------------------------------------------
+TKeyResponse CBavpControllerVideo::HandleKeysL( const TKeyEvent& aKeyEvent,
+ TEventCode aType )
+ {
+ TKeyResponse keyResponse( EKeyWasNotConsumed );
+
+ // If we're in full screen mode, and any key is pressed, toggle to normal
+ // screen. Consume all key presses (down, key, up) when in full screen mode.
+ if ( IsClipFullScreen() )
+ {
+ if ( aType == EEventKeyDown )
+ {
+ ToggleScreen();
+ }
+ keyResponse = EKeyWasConsumed;
+ }
+ else
+ {
+ // Use the default HandleKeysL method
+ keyResponse = CBavpController::HandleKeysL( aKeyEvent, aType );
+ }
+
+ return keyResponse;
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::HandleCommandL
+// Default implementation, override as needed.
+// Handles the commands from the Option Menu defined in TBavpCommandIds
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::HandleCommandL( TBavpCommandIds aCommand )
+ {
+ Log( EFalse, _L("CBavpControllerVideo::HandleCommandL(): aCommand="), (TInt)aCommand );
+
+ switch ( aCommand )
+ {
+ case EBavpCmdPlayFullScreen:
+ ToggleScreen();
+ break;
+
+ default:
+ // Use the default HandleCommandL method
+ CBavpController::HandleCommandL( aCommand );
+ break;
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::PlayAudioVideoL
+// Handles request to open and play an audio or video content
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::PlayAudioVideoL()
+ {
+ Log( EFalse, _L("CBavpControllerVideo::PlayAudioVideoL() ") );
+
+ if ( iClipInfo->iMediaType == ELocalRamFile )
+ {
+ ParseRamFileL();
+ }
+#if defined(BRDO_ASX_FILE)
+ else if ( iClipInfo->iMediaType == ELocalAsxFile )
+ {
+ ParseAsxFileL();
+ }
+#endif // BRDO_ASX_FILE
+ // Check for the mediatype and open the file
+ InitVideoPlayerL();
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::Stop
+// Stops video from playing, if playing.
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::Stop()
+ {
+ Log( EFalse, _L("CBavpControllerVideo::Stop") );
+
+ // If we are fast forwarding or rewind, stop the position updater
+ iPositionUpdater->Cancel();
+
+ if ( iVideoPlayer )
+ {
+ // Stop video and set the state to stop
+ iVideoPlayer->Stop();
+ iCurrentState = EBavpStopped;
+
+ iClipInfo->iPosition = 0;
+ TRAP_IGNORE
+ (
+ iVideoPlayer->SetPositionL( iClipInfo->iPosition );
+ iVideoPlayer->RefreshFrameL();
+ );
+ }
+
+ // The videoPlayer can play audio-only content, so we need to updateDisplay
+ // to show the audio stop animation
+ if ( !IsClipVideo() )
+ {
+ iBavpView->UpdateView();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::PlayL
+// Plays video
+//
+// NOTE: The MMF throws an error when interrupted by a telephone call, so
+// iCurrentState=EBavpBadContent and PlayL called after call is done.
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::PlayL()
+ {
+ Log( EFalse, _L("CBavpControllerVideo::PlayL") );
+
+ if ( !iVideoPlayer || !iPlayerInitialized )
+ {
+ // 1) Live-stream clip that was stopped will close the iVideoPlayer and
+ // need buffering, because Play() will have to be reinitialized with
+ // server.
+ // 2) The initialization of multiple video instances and a single
+ // playback hardware/software (ie Julie H/W) will cause the second plus
+ // instances to return an error. HandleError() will display stop animation,
+ // and if the user selects PlayL(), and the iVideoPlayer needs to be
+ // reinitialized.
+ //
+ // The buffering animation will be stopped, when MvpuoPrepareComplete()
+ // is called.
+ iCurrentState = EBavpBuffering;
+ iBavpView->UpdateView();
+ Log( EFalse, _L("PlayL - Calling InitVideoPlayerL()") );
+
+ // This calls OpenUrlL or OpenFileL, which will call iVideoPlayer->Play
+ InitVideoPlayerL();
+ return;
+ }
+
+ if ( iCurrentState == EBavpPaused ||
+ iCurrentState == EBavpFastForwarding ||
+ iCurrentState == EBavpRewinding )
+ {
+ // If we are fast forwarding or rewind, pause
+ if ( iPositionUpdater->IsActive() )
+ {
+ // PauseL stops the PositionUpdater
+ PauseL();
+ }
+
+ // We are resuming play and the clip is seekable, get the last
+ // position and adjust the last position, if needed
+ if ( iClipInfo->iPosition >=
+ iClipInfo->iDurationInSeconds.Int64() - KBavpOneSecond )
+ {
+ // Take back one second if too near end of clip
+ TTimeIntervalMicroSeconds adjustPosition =
+ iClipInfo->iPosition.Int64() - KBavpOneSecond;
+
+ // Negative value is not allowed, use beginning of clip
+ if ( adjustPosition.Int64() < 0 )
+ {
+ adjustPosition = 0;
+ }
+
+ // Use the adjusted position
+ iClipInfo->iPosition = adjustPosition;
+ }
+ }
+ else
+ {
+ // Handle all other states, EBavpStopped, EBavpPlayComplete,
+ // EBavpRewindComplete, EBavpFastForwardComplete, EBavpBadContent
+ iClipInfo->iPosition = 0;
+ }
+
+ if ( IsClipOnDemand() && iCurrentState == EBavpStopped )
+ {
+ // On-demand that was stopped will need buffering,
+ // because Play() will have to be reinitialized with server.
+ // The buffering animation is stopped, for on-demand when
+ // MvloLoadingComplete() is called
+ iCurrentState = EBavpBuffering;
+ Log( EFalse, _L("PlayL - Set EBavpBuffering") );
+ }
+ else
+ {
+ // Set state and update view to stop any animations running
+ iCurrentState = EBavpPlaying;
+ Log( EFalse, _L("PlayL - Set EBavpPlaying") );
+ }
+
+ iBavpView->UpdateView();
+
+ iVideoPlayer->SetPositionL( iClipInfo->iPosition );
+ iVideoPlayer->Play();
+ // ETwelveOClock: Timer tick is on the second - from Symbian
+ if (!iBackLightUpdater->IsActive())
+ {
+ iBackLightUpdater->Start( ETwelveOClock, this );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::PauseL
+// Pauses video while playing. Saves the last position, if seekable content.
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::PauseL()
+ {
+ Log( EFalse, _L("CBavpControllerVideo::PauseL") );
+
+ // If the position updater is running, stop it
+ iPositionUpdater->Cancel();
+
+ if ( iVideoPlayer )
+ {
+ //disable screensaver
+ iBackLightUpdater->Cancel();
+ if ( IsClipSeekable() )
+ {
+ // Seekable content, save position for possible resume
+ iVideoPlayer->PauseL();
+ iClipInfo->iPosition = iVideoPlayer->PositionL();
+ iCurrentState = EBavpPaused;
+ }
+ else
+ {
+ // Not seekable content, i.e. Live stream
+ iVideoPlayer->Stop();
+ iClipInfo->iPosition = 0;
+ iVideoPlayer->SetPositionL( iClipInfo->iPosition );
+ iCurrentState = EBavpStopped;
+ }
+ }
+ // The videoPlayer can play audio-only content, so we need to updateDisplay
+ // to show the audio paused animation
+ if ( !IsClipVideo() )
+ {
+ iBavpView->UpdateView();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerAudio::FastForwardL
+// Fast forwards the video. This is only called on seekable and local file
+// content.
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::FastForwardL()
+ {
+ // Check that the content can be Fast Forwarded, this is used when media key
+ // is pressed. We don't allow the user to select FF from Option Menu, if this
+ // condition is not already meet.
+ if ( !IsClipSeekable() && !IsClipLocalMedia() )
+ {
+ return;
+ }
+
+ // If playing, pause it (PauseL stops the PositionUpdater)
+ if ( iCurrentState == EBavpPlaying )
+ {
+ PauseL();
+ }
+
+ iCurrentState = EBavpFastForwarding;
+ iPositionUpdater->Start( KInitialDelay, KUpdateFrequency,
+ TCallBack( &DoFastForwardL, this ) );
+ if (!iBackLightUpdater->IsActive())
+ {
+ iBackLightUpdater->Start( ETwelveOClock, this );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerAudio::RewindL
+// Rewinds the video. This is only called on seekable and local file
+// content.
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::RewindL()
+ {
+ // Check that the content can be Rewound, this is used when media key
+ // is pressed. We don't allow the user to select FF from Option Menu, if this
+ // condition is not already meet.
+ if ( !IsClipSeekable() && !IsClipLocalMedia() )
+ {
+ return;
+ }
+
+ // If playing, pause it (PauseL stops the PositionUpdater)
+ if ( iCurrentState == EBavpPlaying )
+ {
+ PauseL();
+ }
+
+ iCurrentState = EBavpRewinding;
+ iPositionUpdater->Start( KInitialDelay, KUpdateFrequency,
+ TCallBack( &DoRewindL, this ) );
+ if (!iBackLightUpdater->IsActive())
+ {
+ iBackLightUpdater->Start( ETwelveOClock, this );
+ }
+
+ }
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::OpenVideoUrlL
+// Handles request to open the url link
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::OpenVideoUrlL()
+ {
+ Log( EFalse, _L("CBavpControllerVideo::OpenUrlL() entered") );
+
+ // Note: Play() is called from MvpuoPrepareComplete()
+ iVideoPlayer->OpenUrlL( *iClipInfo->iUrl, iAccessPtId,
+ KNullDesC8, KRopControllerUid );
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::OpenVideoFileL
+// Open a video file
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::OpenVideoFileL()
+ {
+ Log( EFalse, _L("CBavpControllerVideo::OpenFileL() ") );
+
+ // Note: Play() is called from MvpuoPrepareComplete()
+ iVideoPlayer->OpenFileL( *iClipInfo->iFileName );
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::SetPlayerVolume
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::SetPlayerVolume( TInt aVolume )
+ {
+ if ( iVideoPlayer && iPlayerInitialized )
+ {
+ // The CR volume is 0-10, convert to Video player volume 0-100
+ TInt playerVolume = ( aVolume * iPlayerMaxVolume ) / KCRVolumeMax;
+
+ // Set Video player volume
+ TRAP_IGNORE( iVideoPlayer->SetVolumeL( playerVolume) );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::GetPlayerVolume
+// -----------------------------------------------------------------------------
+TInt CBavpControllerVideo::GetPlayerVolume()
+ {
+ TInt playerVolume( 0 );
+ TInt CRVolume( 0 );
+
+ if ( iVideoPlayer && iPlayerInitialized )
+ {
+ // Video player returns 0-100
+ playerVolume = iVideoPlayer->Volume();
+
+ // Convert to CR volume 0-10
+ CRVolume = ( playerVolume * KCRVolumeMax ) / iPlayerMaxVolume;
+ }
+
+ return CRVolume;
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::MvpuoOpenComplete
+// Notification to the client that the opening of the video clip has completed,
+// successfully, or otherwise.
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::MvpuoOpenComplete( TInt aError )
+ {
+ Log( EFalse, _L("MvpuoOpenComplete err="), aError );
+
+ if ( aError != KErrNone )
+ {
+ // Got an error from the MMF callback
+ HandleError( aError );
+ }
+ else
+ {
+ // No error opening player, proceed with preparing player
+ iVideoPlayer->Prepare();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::MvpuoPrepareComplete
+// Notification to the client that the opening of the video clip has been prepared
+// successfully, or otherwise.
+// This callback is called in response to a call to CVideoPlayerUtility::Prepare().
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::MvpuoPrepareComplete( TInt aError )
+ {
+ Log( EFalse, _L("MvpuoPrepareComplete err="), aError );
+
+ if ( aError != KErrNone )
+ {
+ HandleError( aError );
+ }
+ else
+ {
+ // Proceed with initialization and playing content
+
+ // Video player initialized and ready for interaction,
+ // volume, option menus, etc...
+ iPlayerInitialized = ETrue;
+
+ // Cleanup clip info
+ iClipInfo->ReInit();
+
+ // Handle all of the leaving methods of preparing the clip and
+ // controller. Reading meta data, max volume, ...
+ TRAP_IGNORE( PrepareCompleteL() );
+
+ // Full screen display mode, rotate if necessary
+ if ( IsClipFullScreen() )
+ {
+ RotateScreen90();
+ }
+
+ // Use the iCurrrentVolume, everytime we "set" the volume in the
+ // BavpController we check for Profile setting, so we can use it here
+ SetPlayerVolume( iCurrentVolume );
+
+ // Start to play this media object
+ iVideoPlayer->Play();
+
+ // Stop the buffering animation now, to avoid screen flicker
+ iCurrentState = EBavpPlaying;
+ iBavpView->UpdateView();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::MvpuoPlayComplete
+// Notification that video playback has completed. This is not called if playback
+// is explicitly stopped by calling Stop.
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::MvpuoPlayComplete( TInt aError )
+ {
+ Log( EFalse, _L("MvpuoPlayComplete err="), aError );
+
+ if ( aError != KErrNone )
+ {
+ // Got an error from the MMF callback
+ HandleError( aError );
+ }
+ else
+ {
+ // No error, proceed with playing complete
+ iCurrentState = EBavpPlayComplete;
+ iClipInfo->iPosition = 0;
+
+ // Set the previous call state to complete, this will ensure we
+ // don't try to replay the content if a call comes in
+ iPreCallState = EBavpPlayComplete;
+
+ // Revert back to normal screen if it's full screen display
+ if ( IsClipFullScreen() )
+ {
+ TRAP_IGNORE
+ (
+ RevertToNormalScreenL();
+ iBavpView->ControllerStateChangedL();
+ );
+ }
+
+ iBavpView->UpdateView();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::MvpuoEvent
+// General event notification from controller. These events are specified by the
+// supplier of the controller. Take the user initiaiated event, like selecting
+// "pause" from the menu item, or another MMF event and convert into a
+// "video plugin error", so we can process in HandleError().
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::MvpuoEvent( const TMMFEvent& aEvent )
+ {
+ Log( EFalse, _L("MvpuoEvent aEvent.iErrorCode="), aEvent.iErrorCode );
+
+ if ( aEvent.iEventType == KMMFEventCategoryVideoPlayerGeneralError )
+ {
+ HandleError( aEvent.iErrorCode );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::MvloLoadingComplete
+// Notification that video clip loading/rebuffering has started
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::MvloLoadingStarted()
+ {
+ Log( EFalse, _L("MvloLoadingStarted") );
+
+ if ( iCurrentState != EBavpPlaying )
+ {
+ // Start the buffering animation
+ iCurrentState = EBavpBuffering;
+ iBavpView->UpdateView();
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::MvloLoadingComplete
+// Notification that video clip loading/rebuffering has completed
+// and starting to play
+// -----------------------------------------------------------------------------
+void CBavpControllerVideo::MvloLoadingComplete()
+ {
+ Log( EFalse, _L("MvloLoadingComplete") );
+
+ if ( !iBackLightUpdater->IsActive() )
+ {
+ iBackLightUpdater->Start( ETwelveOClock, this );
+ }
+ // Stop the buffering animation
+ iCurrentState = EBavpPlaying;
+ iBavpView->UpdateView();
+ }
+
+ // -----------------------------------------------------------------------------
+// CBavpControllerVideo::getPositionL
+// To get the current position of the clip
+// -----------------------------------------------------------------------------
+
+ TTimeIntervalMicroSeconds CBavpControllerVideo::getPositionL()
+ {
+ if ( iVideoPlayer )
+ {
+ return iVideoPlayer->PositionL();
+ }
+ return NULL;
+ }
+
+ // -----------------------------------------------------------------------------
+// CBavpControllerVideo::setPositionL
+// To set the position of the clip
+// -----------------------------------------------------------------------------
+
+ void CBavpControllerVideo::setPositionL(TTimeIntervalMicroSeconds val)
+ {
+ if ( iVideoPlayer )
+ {
+ if ( !IsClipSeekable() && !IsClipLocalMedia() )
+ {
+ return;
+ }
+
+ TBool didWePause = EFalse;
+ // If playing, pause it (PauseL stops the PositionUpdater)
+ if ( iCurrentState == EBavpPlaying )
+ {
+ PauseL();
+ didWePause = ETrue;
+ }
+
+ if ( (val > iClipInfo->iDurationInSeconds ) || (val < 0) )
+ {
+ val = 0;
+ }
+
+ iVideoPlayer->SetPositionL(val);
+ iVideoPlayer->RefreshFrameL();
+ iClipInfo->iPosition = val;
+ if ( didWePause )
+ {
+ PlayL();
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::Beat
+// Call HandleScreenSaver
+// -----------------------------------------------------------------------------
+//
+void CBavpControllerVideo::Beat()
+ {
+ HandleScreenSaver();
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::Synchronize
+// Call HandleScreenSaver
+// -----------------------------------------------------------------------------
+//
+void CBavpControllerVideo::Synchronize()
+ {
+ HandleScreenSaver();
+ }
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::HandleScreenSaver
+// To disable backlight for screensaver if needed
+// -----------------------------------------------------------------------------
+//
+void CBavpControllerVideo::HandleScreenSaver()
+{
+ Log( EFalse, _L("CBavpControllerVideo::HandleScreenSaver() entered" ));
+
+ //disable screensaver when it's in playing|forwarding|backwarding mode
+ if ( NoScreenSaverMode() && iVideoPlayer )
+ {
+ User::ResetInactivityTime();
+ }
+}
+
+TBool CBavpControllerVideo::NoScreenSaverMode()
+{
+ return (iCurrentState == EBavpPlaying ||
+ iCurrentState == EBavpFastForwarding ||
+ iCurrentState == EBavpRewinding);
+}
+
+
+// -----------------------------------------------------------------------------
+// CBavpControllerVideo::SetDefaultAspectRatioL
+// Sets default aspect ratio (code is taken from mmplayer)
+// -----------------------------------------------------------------------------
+/*
+ * This function was added for consistency with mmplayer.
+ * Not used is 5.0 (tube) since we want to preserve correct
+ * aspect ratio and this function will stretch the video to
+ * the full screen, which due to tube screen size doesn't match
+ * to correct ratio.
+ * If needed it should be called in WaitForScreenSwitchL() after
+ * screen mode changed.
+ */
+void CBavpControllerVideo::SetDefaultAspectRatioL()
+{
+ TSize frameSize;
+ TRect rect = iBavpView->CoeControl().Rect();
+
+ if ( iVideoPlayer ) {
+
+ iVideoPlayer->VideoFrameSizeL( frameSize );
+ }
+
+ if ( frameSize.iWidth > 0 && frameSize.iHeight > 0) {
+
+ TMMFScalingType scalingType = EMMFNatural;
+
+ TReal32 videoAspectRatio = (TReal)frameSize.iWidth /
+ (TReal)frameSize.iHeight;
+ TReal32 dispAspectRatio = (TReal)rect.Width() / (TReal)rect.Height();
+
+ // Choose the scaling type through the rule:
+ // videoAspectRatio - iDisplayAspectRatio > 0.1 ==> zoom
+ // videoAspectRatio - iDisplayAspectRatio < 0.1 ==> stretch
+ // videoAspectRatio = iDisplayAspectRatio ==> natural
+ if ( videoAspectRatio - dispAspectRatio > 0.1 ) {
+ scalingType = EMMFZoom;
+ }
+ else if ( videoAspectRatio != dispAspectRatio ) {
+ scalingType = EMMFStretch;
+ }
+
+ TMMFMessageDestinationPckg destinationPckg(KUidInterfaceMMFControllerScalingMsg );
+
+ TPckgBuf<TInt> scaleTypePckg( scalingType );
+
+ iVideoPlayer->CustomCommandSync( destinationPckg,
+ EMMFSetScalingType,
+ scaleTypePckg,
+ KNullDesC8 );
+ iVideoPlayer->RefreshFrameL();
+
+ }
+}
+
+void CBavpControllerVideo::HandleInComingCallL()
+
+{
+ if ( IsClipFullScreen() )
+ {
+ RevertToNormalScreenL();
+ }
+}
+// End of File