mmlibs/mmfw/src/Client/Video/mmfclientvideoplayerbody.cpp
changeset 0 40261b775718
child 7 94dbab0a2133
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 
       
    17 #include <mmf/common/mmfstandardcustomcommands.h>  
       
    18 #include <mmf/common/mmfdrmcustomcommands.h>  
       
    19 #include <mmf/common/mmfvideo.h>
       
    20 #include <mmf/server/mmfdes.h>
       
    21 #include <mmf/server/mmffile.h>
       
    22 #include "mmfvideocallback.h"
       
    23 #include "VideoPlayerBody.h"
       
    24 #include "mmfclientvideocommon.h"
       
    25 #include "mmfclientutility.h"
       
    26 
       
    27 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    28 #include <mmf/common/mmfvideoenums.h>
       
    29 #endif
       
    30 
       
    31 #ifdef SYMBIAN_BUILD_GCE
       
    32 #include <videoplayer2.h>
       
    33 #include <surfaceeventhandler.h>
       
    34 #endif
       
    35 
       
    36 #ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
    37 #include <mmf/common/mmfpaniccodes.h>
       
    38 #include "mmfsubtitleutility.h"
       
    39 #endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
    40 
       
    41 using namespace ContentAccess;
       
    42 
       
    43 #ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
    44 
       
    45 #ifdef _DEBUG
       
    46 void VPUDebugPanicOrLeaveL(TInt aVPUPanicCode, TInt aLeaveCode)
       
    47 	{
       
    48 	_LIT(KMMFVideoPlayerUtilityPanicCategory, "MMFVideoPlayUtil");
       
    49 	User::Panic(KMMFVideoPlayerUtilityPanicCategory, aVPUPanicCode);
       
    50 	User::Leave(aLeaveCode); // added for leavescan
       
    51 	}
       
    52 
       
    53 #else
       
    54 void VPUDebugPanicOrLeaveL(TInt /*aVPUPanicCode*/, TInt aLeaveCode)
       
    55 	{
       
    56 	User::Leave(aLeaveCode);
       
    57 	}
       
    58 #endif //_DEBUG
       
    59 
       
    60 #endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
    61 
       
    62 CVideoPlayerUtility::CBody* CVideoPlayerUtility::CBody::NewL(CVideoPlayerUtility* aParent,
       
    63 															 MVideoPlayerUtilityObserver& aObserver,
       
    64 															 TInt aPriority,
       
    65 															 TInt aPref,
       
    66 															 RWsSession& aWs,
       
    67 															 CWsScreenDevice& aScreenDevice,
       
    68 															 RWindowBase& aWindow,
       
    69 															 const TRect& aScreenRect,
       
    70 															 const TRect& aClipRect)
       
    71 	{
       
    72 	CBody* self = new(ELeave) CBody(aParent, aObserver, aScreenDevice.GetScreenNumber(), aPriority, aPref);
       
    73 	CleanupStack::PushL(self);
       
    74 	self->ConstructL(aWs, aScreenDevice, aWindow, aScreenRect, aClipRect);
       
    75 	CleanupStack::Pop();
       
    76 	return self;
       
    77 	}
       
    78 
       
    79 #ifdef SYMBIAN_BUILD_GCE
       
    80 CVideoPlayerUtility::CBody* CVideoPlayerUtility::CBody::NewL(CVideoPlayerUtility2* aParent,
       
    81 															 MVideoPlayerUtilityObserver& aObserver,
       
    82 															 TInt aPriority,
       
    83 															 TInt aPref)
       
    84 	{
       
    85 	CBody* self = new(ELeave) CBody(aParent, aObserver, aPriority, aPref);
       
    86 	CleanupStack::PushL(self);
       
    87 	self->ConstructL();
       
    88 	CleanupStack::Pop();
       
    89 	return self;
       
    90 	}
       
    91 #endif // SYMBIAN_BUILD_GCE
       
    92 
       
    93 CVideoPlayerUtility::CBody::~CBody()
       
    94 	{
       
    95 	Close();
       
    96 	
       
    97 	delete iControllerImplementationInformation;
       
    98 	delete iDirectScreenAccess;
       
    99 	delete iFindAndOpenController;
       
   100 	delete iControllerEventMonitor;
       
   101 	delete iFrameCallback;
       
   102 	delete iAsyncCallback;
       
   103 	delete iMimeType;
       
   104 	delete iFrameBitmap;
       
   105 	if (iFbsSessionConnected)
       
   106 		iFbsSession.Disconnect();
       
   107 	}
       
   108 
       
   109 void CVideoPlayerUtility::CBody::Close()
       
   110 	{
       
   111 #ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
   112 	DisableSubtitles();
       
   113 #endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
   114 
       
   115 	if (iAsyncCallback)
       
   116 		iAsyncCallback->Cancel();
       
   117 	if (iFrameCallback)
       
   118 		iFrameCallback->Cancel();
       
   119 	if (iFindAndOpenController)
       
   120 		iFindAndOpenController->Close();
       
   121 	if (iControllerEventMonitor)
       
   122 		iControllerEventMonitor->Cancel();
       
   123 	if(iControllerImplementationInformation)
       
   124 		{
       
   125 		delete iControllerImplementationInformation;
       
   126 		iControllerImplementationInformation = NULL;
       
   127 		}
       
   128 
       
   129 #ifdef SYMBIAN_BUILD_GCE
       
   130 	iActiveDisplays.ResetAndDestroy();
       
   131 	iSurfaceId = TSurfaceId::CreateNullId();
       
   132 #endif
       
   133 
       
   134 	iController.Close();	
       
   135 	iControllerUid = KNullUid;
       
   136 	iControllerOpen = EFalse;
       
   137 	iDirectScreenAccessAbort = EFalse;
       
   138 	}
       
   139 
       
   140 CVideoPlayerUtility::CBody::CBody(CVideoPlayerUtility* aParent,
       
   141 								  MVideoPlayerUtilityObserver& aObserver,
       
   142 								  TInt aScreenNumber,
       
   143 								  TInt aPriority,
       
   144 								  TInt aPref) : 
       
   145 	iVideoControllerCustomCommands(iController),
       
   146 	iVideoPlayControllerCustomCommands(iController),
       
   147 	iAudioPlayDeviceCustomCommands(iController),
       
   148 	iAudioRecordDeviceCustomCommands(iController),
       
   149 	iVideoDRMExtCustomCommands(iController),
       
   150 	iDRMCustomCommands(iController),
       
   151 	iVideoPlayControllerExtCustomCommands(iController),	
       
   152 	iNotificationRegistrationCommands(iController),
       
   153 #ifdef SYMBIAN_BUILD_GCE
       
   154 	iVideoPlaySurfaceSupportCustomCommands(iController),
       
   155 #endif
       
   156 	iArnEventHolder(KNullUid),
       
   157 	iVideoSetInitScreenCustomCommands(iController),
       
   158 	iObserver(aObserver),
       
   159 	iState(EStopped),
       
   160 	iParent(aParent),
       
   161 	iScreenNumber(aScreenNumber)
       
   162 #ifdef SYMBIAN_BUILD_GCE
       
   163 	,iGlobalScaleWidth(100.0f),
       
   164 	iGlobalScaleHeight(100.0f),
       
   165 	iGlobalHorizPos(EHorizontalAlignCenter),
       
   166 	iGlobalVertPos(EVerticalAlignCenter)
       
   167 #endif
       
   168 	{
       
   169 	iPrioritySettings.iPriority = aPriority;
       
   170 	iPrioritySettings.iPref = aPref;
       
   171 	}
       
   172 
       
   173 #ifdef SYMBIAN_BUILD_GCE
       
   174 CVideoPlayerUtility::CBody::CBody(CVideoPlayerUtility2* aParent,
       
   175 				MVideoPlayerUtilityObserver& aObserver,
       
   176 				TInt aPriority,
       
   177 				TInt aPref) : 
       
   178 	iVideoControllerCustomCommands(iController),
       
   179 	iVideoPlayControllerCustomCommands(iController),
       
   180 	iAudioPlayDeviceCustomCommands(iController),
       
   181 	iAudioRecordDeviceCustomCommands(iController),
       
   182 	iVideoDRMExtCustomCommands(iController),
       
   183 	iDRMCustomCommands(iController),
       
   184 	iVideoPlayControllerExtCustomCommands(iController),
       
   185 	iNotificationRegistrationCommands(iController),
       
   186 	iVideoPlaySurfaceSupportCustomCommands(iController),
       
   187 	iArnEventHolder(KNullUid),
       
   188 	iVideoSetInitScreenCustomCommands(iController),
       
   189 	iObserver(aObserver),
       
   190 	iState(EStopped),
       
   191 	iParent(aParent),
       
   192 	iUsingVPU2(ETrue),
       
   193 	iGlobalScaleWidth(100.0f),
       
   194 	iGlobalScaleHeight(100.0f),
       
   195 	iGlobalHorizPos(EHorizontalAlignCenter),
       
   196 	iGlobalVertPos(EVerticalAlignCenter)
       
   197 	{
       
   198 	iPrioritySettings.iPriority = aPriority;
       
   199 	iPrioritySettings.iPref = aPref;
       
   200 	}
       
   201 
       
   202 void CVideoPlayerUtility::CBody::ConstructL()
       
   203 	{
       
   204 	CommonConstructL();
       
   205 	iFindAndOpenController = CMMFFindAndOpenController::NewL(*this);
       
   206 	iFindAndOpenController->SetSurfaceMode(iUsingVPU2, &iVideoPlaySurfaceSupportCustomCommands);
       
   207 	iFindAndOpenController->Configure(KUidMediaTypeVideo, iPrioritySettings, CMMFPluginSelectionParameters::EAllowOtherMediaIds);
       
   208 	iFindAndOpenController->ConfigureController(iController, *iControllerEventMonitor, CMMFFindAndOpenController::EPlayback);
       
   209 	}
       
   210 
       
   211 #endif // SYMBIAN_BUILD_GCE
       
   212 
       
   213 void CVideoPlayerUtility::CBody::ConstructL(RWsSession& aWs,
       
   214 						CWsScreenDevice& aScreenDevice,
       
   215 						RWindowBase& aWindow,
       
   216 						const TRect& aWindowRect,
       
   217 						const TRect& aClipRect)
       
   218 	{
       
   219 	CommonConstructL();
       
   220 	
       
   221 	SetDisplayWindowL(aWs, aScreenDevice, aWindow, aWindowRect, aClipRect);
       
   222 	iFindAndOpenController = CMMFFindAndOpenController::NewL(*this);
       
   223 #ifdef SYMBIAN_BUILD_GCE	
       
   224 	iFindAndOpenController->SetSurfaceMode(iUsingVPU2, &iVideoPlaySurfaceSupportCustomCommands);
       
   225 	
       
   226 	// If we open a controller with surface support we may render to surfaces.  We need to store these
       
   227 	// so we can add the display as a surface rendering target.
       
   228 
       
   229 	iWs = &aWs;
       
   230 	iDisplayId = aScreenDevice.GetScreenNumber();
       
   231 	iWindow = &aWindow;
       
   232 	iWindowRect = aWindowRect;
       
   233 	iClipRect = aClipRect;	
       
   234 
       
   235 #endif
       
   236 	iFindAndOpenController->Configure(KUidMediaTypeVideo, iPrioritySettings, CMMFPluginSelectionParameters::EAllowOtherMediaIds);
       
   237 	iFindAndOpenController->ConfigureController(iController, *iControllerEventMonitor, CMMFFindAndOpenController::EPlayback);
       
   238 	}
       
   239 
       
   240 void CVideoPlayerUtility::CBody::CommonConstructL()
       
   241 	{
       
   242 	iControllerEventMonitor = CMMFControllerEventMonitor::NewL(*this, iController);
       
   243 	iMimeType = HBufC8::NewL(KMaxMimeTypeLength);
       
   244 	iAsyncCallback = new (ELeave) CMMFVideoPlayerCallback(iObserver);
       
   245 	iFrameCallback = new (ELeave) CMMFVideoPlayerCallback(iObserver);
       
   246 	User::LeaveIfError(iFbsSession.Connect());
       
   247 	iFbsSessionConnected = ETrue;
       
   248 	}
       
   249 
       
   250 void CVideoPlayerUtility::CBody::Reset() 
       
   251 	{
       
   252 	Close();
       
   253 	
       
   254 	// reset all state variables
       
   255 	iEventOpenReceived = EFalse;
       
   256 	iCallbackOpenReceived = EFalse;
       
   257 	iOpenError = KErrNone;
       
   258 #ifdef SYMBIAN_BUILD_GCE
       
   259 	iGraphicsSurfaceSupported = EFalse;
       
   260 #endif
       
   261 	iControllerUid = KNullUid;
       
   262 	}
       
   263 
       
   264 void CVideoPlayerUtility::CBody::SetAndUpdateWindow()
       
   265 	{
       
   266 	if (iOpenError == KErrNone)	
       
   267 		{
       
   268 		// Set the display window and update display region if the controller doesn't support graphics surface. 		
       
   269 		iOpenError = iVideoPlayControllerCustomCommands.SetDisplayWindow(iWindowRect, iClipRect);
       
   270 		}
       
   271 
       
   272 	if (iOpenError == KErrNone && iDirectScreenAccess && iDirectScreenAccess->DrawingRegion())
       
   273 		{
       
   274 		iOpenError = iVideoPlayControllerCustomCommands.UpdateDisplayRegion(*iDirectScreenAccess->DrawingRegion());
       
   275 		}
       
   276 	}
       
   277 
       
   278 void CVideoPlayerUtility::CBody::MfaocComplete(		
       
   279 	TInt& aError, 
       
   280 	RMMFController*	/*aController*/,
       
   281 	TUid aControllerUid, 
       
   282 	TMMFMessageDestination* /*aSourceHandle*/, 
       
   283 	TMMFMessageDestination* /*aSinkHandle*/)
       
   284 	{
       
   285 	iCallbackOpenReceived = ETrue;
       
   286 
       
   287 	// save the error in iOpenError -
       
   288 	// unless HandleEvent(KMMFEventCategoryVideoOpenComplete) 
       
   289 	// has reported an error already
       
   290 	if (iOpenError == KErrNone)
       
   291 		iOpenError = aError;
       
   292 	
       
   293 	if (iOpenError == KErrNone)
       
   294 		{
       
   295 #ifdef SYMBIAN_BUILD_GCE
       
   296 		// Check if the graphics surfaces is supported
       
   297 		TInt err = CheckSurfaceSupported();
       
   298 	
       
   299 		if (!iGraphicsSurfaceSupported)
       
   300 			{
       
   301 			if (err != KErrNone && iUsingVPU2)
       
   302 				{
       
   303 				// Set KErrNotSupported if the controller doesn't support graphics surface and 
       
   304 				// the open source is using CVideoPlayerUtility2
       
   305 				iOpenError = err;
       
   306 				}
       
   307 			else
       
   308 				{
       
   309 				SetAndUpdateWindow();
       
   310 				}
       
   311 			}
       
   312 #else
       
   313 		SetAndUpdateWindow();
       
   314 #endif // SYMBIAN_BUILD_GCE	
       
   315 	
       
   316 		// now that the controller is open
       
   317 		if (iOpenError == KErrNone)
       
   318 			{
       
   319 			iControllerOpen = ETrue;
       
   320 			iControllerUid = aControllerUid;
       
   321 
       
   322 #ifdef SYMBIAN_BUILD_GCE		
       
   323 			// We are using a controller that supports graphics surfaces but are not in surface mode.  
       
   324 			// Call AddDisplay so we can render to surfaces using the CVideoUtility API.
       
   325 			if (iGraphicsSurfaceSupported && !iUsingVPU2)
       
   326 				{
       
   327 				if (iDirectScreenAccess)
       
   328 					{
       
   329 		 			iDirectScreenAccess->Cancel();
       
   330 					}
       
   331 				
       
   332 		        // When using surfaces for CVPU we use DoAddDisplayWindowL() which requires clip rectangle and video extent
       
   333 		        // as arguments. Video extent is not supported by CVPU so aWindowRect is used instead. This function
       
   334 		        // assumes these args are relative to the window. However they are relative to the display and must be
       
   335 		        // converted.
       
   336 		        TRect windowRectRelativeToWindow;
       
   337 		        TRect clipRectRelativeToWindow;     
       
   338 		        ConvertFromRelativeToDisplayToRelativeToWindow(*iWindow, iWindowRect, iClipRect, windowRectRelativeToWindow, clipRectRelativeToWindow);
       
   339 
       
   340 				TRAP(iOpenError, DoAddDisplayWindowL(*iWs, iDisplayId, *iWindow, clipRectRelativeToWindow, windowRectRelativeToWindow, NULL));				
       
   341 				}
       
   342 #endif		
       
   343 			}
       
   344 		// If an error occurred in any of the above, try for next controller if present
       
   345 		// in the selection list.
       
   346 		else
       
   347 			{
       
   348 			if(iFindAndOpenController->ControllerIndex() < (iFindAndOpenController->ControllerCount())-1)
       
   349 				{
       
   350 				aError = iOpenError;
       
   351 				
       
   352 				if (iAsyncCallback)
       
   353 					{
       
   354 					iAsyncCallback->Cancel();
       
   355 					}
       
   356 		
       
   357 				if (iControllerEventMonitor)
       
   358 					{
       
   359 					iControllerEventMonitor->Cancel();
       
   360 					}
       
   361 				iOpenError = KErrNone;
       
   362 					
       
   363 				return;
       
   364 				}
       
   365 				
       
   366 			Close();
       
   367 			}
       
   368 		}
       
   369 
       
   370 	if(iOpenError != KErrNone && !iControllerOpen)
       
   371 		{
       
   372 		if (iFindAndOpenController)	
       
   373 			{
       
   374 			//if try next controller was called when specific controller uid was 
       
   375 			//given, skip the searching and report error.
       
   376 			if(!iFindAndOpenController->StopTryLoadController()) 
       
   377 				{
       
   378 				if( !(aError == KErrNoMemory || aError == KErrCancel ) ) 
       
   379 					{
       
   380 					if(iFindAndOpenController->ControllerIndex() < (iFindAndOpenController->ControllerCount())-1)
       
   381 						{
       
   382 						aError = iOpenError;   // Actually tries to load controller
       
   383 						iOpenError = KErrNone;
       
   384 						return;
       
   385 						}
       
   386 					}
       
   387 				}
       
   388 			}
       
   389 		}
       
   390 	
       
   391 	// if we've already received the open complete event
       
   392 	// call the client now (otherwise wait for it)
       
   393 	if (iEventOpenReceived || iOpenError != KErrNone)
       
   394 		{
       
   395 		// stop a subsequent HandleEvent(KMMFEventCategoryVideoOpenComplete) 
       
   396 		// from issuing another callback to client
       
   397 		iCallbackOpenReceived = EFalse;
       
   398 		iAsyncCallback->Signal(iOpenError, CMMFVideoPlayerCallback::EOpenCompleteEvent);
       
   399 		}
       
   400 
       
   401 	}
       
   402 
       
   403 void CVideoPlayerUtility::CBody::OpenFileL(const TDesC& aFileName, TUid aControllerUid)
       
   404 	{
       
   405 	TMMFileSource filesource(aFileName, KDefaultContentObject, EPlay);
       
   406 	OpenFileL(filesource, aControllerUid);
       
   407 	}
       
   408 	
       
   409 void CVideoPlayerUtility::CBody::OpenFileL(const RFile& aFile, TUid aControllerUid)
       
   410 	{
       
   411 	RFile& file = const_cast<RFile&>(aFile);
       
   412 	TMMFileHandleSource filehandlesource(file, KDefaultContentObject, EPlay);
       
   413 	OpenFileL(filehandlesource, aControllerUid);
       
   414 	}
       
   415 
       
   416 void CVideoPlayerUtility::CBody::OpenFileL(const TMMSource& aSource, TUid aControllerUid)
       
   417 	{
       
   418 	// Make sure we are closed
       
   419 	Reset();
       
   420 
       
   421 	iFindAndOpenController->ConfigureSourceSink(
       
   422 		aSource,
       
   423 		CMMFFindAndOpenController::TSourceSink(KUidMmfAudioOutput));
       
   424 
       
   425 #ifdef SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
       
   426 	iFindAndOpenController->SetInitScreenNumber(iScreenNumber, &iVideoSetInitScreenCustomCommands);
       
   427 #endif
       
   428 
       
   429 	if (aControllerUid != KNullUid) 
       
   430 		{
       
   431 		iFindAndOpenController->OpenByControllerUid(aControllerUid);
       
   432 		}
       
   433 	else
       
   434 		{
       
   435 		iFindAndOpenController->OpenByFileSource(aSource);
       
   436 		}
       
   437 	}
       
   438 	
       
   439 //
       
   440 // This method launches and initializes plugin controller based on the stream 
       
   441 // source header passed in the descriptor buffer.
       
   442 //
       
   443 void CVideoPlayerUtility::CBody::OpenDesL(const TDesC8& aDescriptor, TUid aControllerUid)
       
   444 	{
       
   445 	// Make sure we are closed
       
   446 	Reset();
       
   447 
       
   448 	iFindAndOpenController->ConfigureSourceSink(
       
   449 		CMMFFindAndOpenController::TSourceSink(KUidMmfDescriptorSource, CMMFFindAndOpenController::GetConfigDescriptor(aDescriptor)), 
       
   450 		CMMFFindAndOpenController::TSourceSink(KUidMmfAudioOutput, KNullDesC8));
       
   451 	
       
   452 #ifdef SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
       
   453 	iFindAndOpenController->SetInitScreenNumber(iScreenNumber, &iVideoSetInitScreenCustomCommands);
       
   454 #endif
       
   455 		
       
   456 	if (aControllerUid!=KNullUid)
       
   457 		{
       
   458 		iFindAndOpenController->OpenByControllerUid(aControllerUid);
       
   459 		}
       
   460 	else
       
   461 		{
       
   462 		iFindAndOpenController->OpenByDescriptor(aDescriptor);
       
   463 		}
       
   464 	}
       
   465 	
       
   466 void CVideoPlayerUtility::CBody::OpenUrlL(const TDesC& aUrl, TInt aIapId, const TDesC8& aMimeType, TUid aControllerUid)
       
   467 	{
       
   468 	// Make sure we are closed
       
   469 	Reset();
       
   470 
       
   471 	CBufFlat* urlCfgBuffer = NULL;
       
   472     CMMFFindAndOpenController::GetConfigUrlL(urlCfgBuffer, aUrl, aIapId);
       
   473 
       
   474 	iFindAndOpenController->ConfigureSourceSink(
       
   475 		CMMFFindAndOpenController::TSourceSink(KUidMmfUrlSource, urlCfgBuffer->Ptr(0)), 
       
   476 		CMMFFindAndOpenController::TSourceSink(KUidMmfAudioOutput, KNullDesC8));
       
   477 	
       
   478 #ifdef SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
       
   479 	iFindAndOpenController->SetInitScreenNumber(iScreenNumber, &iVideoSetInitScreenCustomCommands);
       
   480 #endif
       
   481 		
       
   482 	if (aControllerUid!=KNullUid)
       
   483 		{
       
   484 		iFindAndOpenController->OpenByControllerUid(aControllerUid);
       
   485 		}
       
   486 	else
       
   487 		iFindAndOpenController->OpenByUrl(aUrl, aIapId, aMimeType);
       
   488 
       
   489 	delete urlCfgBuffer;
       
   490 	}
       
   491 
       
   492 void CVideoPlayerUtility::CBody::Play()
       
   493 	{
       
   494 	TInt err = iController.Prime();
       
   495 	if (err == KErrNone)
       
   496 		err = iController.Play();
       
   497 	if (err != KErrNone)
       
   498 	    {
       
   499 	    iAsyncCallback->Signal(err,CMMFVideoPlayerCallback::EPlayCompleteEvent);
       
   500 	    return;
       
   501 	    }
       
   502 	iState = EPlaying;
       
   503 	//If Audio Resource Notification request is pending - attempt now
       
   504 	if(iArnEventHolder != KNullUid)
       
   505 		{
       
   506 		err = iNotificationRegistrationCommands.RegisterAsClient(iArnEventHolder, iNotificationDataHolder);
       
   507 		iArnEventHolder = KNullUid;
       
   508 		iNotificationDataHolder = KNullDesC8;
       
   509 		if(err != KErrNone)
       
   510 			{
       
   511 			iAsyncCallback->Signal(err, CMMFVideoPlayerCallback::EPlayCompleteEvent);
       
   512 			}
       
   513 		}
       
   514 	}
       
   515 
       
   516 void CVideoPlayerUtility::CBody::Play(const TTimeIntervalMicroSeconds& aStartTime, const TTimeIntervalMicroSeconds& aEndTime)
       
   517 	{
       
   518 	TInt err = iController.Prime();
       
   519 	if (err == KErrNone)
       
   520 	err = iVideoPlayControllerCustomCommands.Play(aStartTime, aEndTime);
       
   521 	if (err != KErrNone)
       
   522 	    {
       
   523 	    iAsyncCallback->Signal(err, CMMFVideoPlayerCallback::EPlayCompleteEvent);
       
   524 	    return;
       
   525 	    }
       
   526 	iState = EPlaying;
       
   527 	//If Audio Resource Notification request is pending - attempt now
       
   528 	if(iArnEventHolder != KNullUid)
       
   529 		{
       
   530 		err = iNotificationRegistrationCommands.RegisterAsClient(iArnEventHolder, iNotificationDataHolder);			
       
   531 		iArnEventHolder = KNullUid;
       
   532 		iNotificationDataHolder = KNullDesC8;
       
   533 		if(err != KErrNone)
       
   534 			{
       
   535 			iAsyncCallback->Signal(err, CMMFVideoPlayerCallback::EPlayCompleteEvent);
       
   536 			}
       
   537 		}
       
   538 	}
       
   539 
       
   540 
       
   541 TInt CVideoPlayerUtility::CBody::Stop()
       
   542 	{
       
   543 	TInt err = iController.Stop();
       
   544 	iState = EStopped;
       
   545 	return err;
       
   546 	}
       
   547 
       
   548 void CVideoPlayerUtility::CBody::PauseL()
       
   549 	{
       
   550 	User::LeaveIfError(iController.Pause());
       
   551 	iState = EPaused;
       
   552 	}
       
   553 
       
   554 void CVideoPlayerUtility::CBody::SetVolumeL(TInt aVolume)
       
   555 	{
       
   556 	User::LeaveIfError(iAudioPlayDeviceCustomCommands.SetVolume(aVolume));
       
   557 	}
       
   558 
       
   559 void CVideoPlayerUtility::CBody::PrepareDSAL(RWsSession& aWs, CWsScreenDevice& aScreenDevice, RWindowBase& aWindow)
       
   560 	{
       
   561 	CDirectScreenAccess* old = iDirectScreenAccess;
       
   562 	iDirectScreenAccess = CDirectScreenAccess::NewL(aWs,aScreenDevice,aWindow,*this);
       
   563 	delete old;
       
   564 	iDirectScreenAccess->StartL();
       
   565 	}
       
   566 
       
   567 void CVideoPlayerUtility::CBody::SetDisplayWindowL(RWsSession& aWs, CWsScreenDevice& aScreenDevice,
       
   568 							RWindowBase& aWindow, const TRect& aWindowRect,
       
   569 							const TRect& aClipRect)
       
   570 	{	
       
   571 	iWindowRect = aWindowRect;
       
   572 	iClipRect = aClipRect;
       
   573 	
       
   574 #ifdef SYMBIAN_BUILD_GCE
       
   575 	// If called from CVideoPlayerUtility2, fail with KErrNotSupport. Otherwise, if the controller supports 
       
   576 	// the graphics surfaces, it will render to graphics surfaces. If the controller doesn't support 
       
   577 	// the graphics surfaces, it will use direct screen access.
       
   578 	if (iUsingVPU2)
       
   579 		{
       
   580 		User::Leave(KErrNotSupported);
       
   581 		}
       
   582 	// If the controller does not support GCE or the source has not been opened, start new DSA.
       
   583 	if (!iGraphicsSurfaceSupported)
       
   584 		{
       
   585 		PrepareDSAL(aWs, aScreenDevice, aWindow);
       
   586 		}
       
   587 
       
   588 	if (!iGraphicsSurfaceSupported && iControllerOpen)
       
   589 		{
       
   590 		// Set display window and update region, if controller is open
       
   591 		User::LeaveIfError(iVideoPlayControllerCustomCommands.SetDisplayWindow(iWindowRect,iClipRect));
       
   592 		User::LeaveIfError(iVideoPlayControllerCustomCommands.UpdateDisplayRegion(*iDirectScreenAccess->DrawingRegion()));
       
   593 		}
       
   594 		
       
   595 	if (iGraphicsSurfaceSupported && iControllerOpen)
       
   596 		{
       
   597 		// When the controller supports graphics surfaces, need to stop direct screen access.
       
   598  		if (iDirectScreenAccess)
       
   599  			{
       
   600  			iDirectScreenAccess->Cancel();
       
   601   			AbortNow(RDirectScreenAccess::ETerminateCancel);
       
   602  			}
       
   603 
       
   604 		// try to remove the display window first no matter it is active or not.
       
   605 		// This method won't leave
       
   606 		RemoveDisplayWindow(aWindow);
       
   607 		
       
   608 		// When using surfaces for CVPU we use DoAddDisplayWindowL() which requires clip rectangle and video extent
       
   609 		// as arguments. Video extent is not supported by CVPU so aWindowRect is used instead. This function
       
   610 		// assumes these args are relative to the window. However they are relative to the display and must be
       
   611 		// converted.
       
   612 		TRect windowRectRelativeToWindow;
       
   613 		TRect clipRectRelativeToWindow;		
       
   614 		ConvertFromRelativeToDisplayToRelativeToWindow(aWindow, aWindowRect, aClipRect, windowRectRelativeToWindow, clipRectRelativeToWindow);
       
   615 
       
   616         DoAddDisplayWindowL(aWs, aScreenDevice.GetScreenNumber(), aWindow, clipRectRelativeToWindow, windowRectRelativeToWindow, NULL);
       
   617 		}
       
   618 #else
       
   619 	PrepareDSAL(aWs, aScreenDevice, aWindow);
       
   620 	
       
   621 	if (iControllerOpen)
       
   622 		{
       
   623 		// Set display window and update region, if controller is open
       
   624 		User::LeaveIfError(iVideoPlayControllerCustomCommands.SetDisplayWindow(iWindowRect,iClipRect));
       
   625 		User::LeaveIfError(iVideoPlayControllerCustomCommands.UpdateDisplayRegion(*iDirectScreenAccess->DrawingRegion()));
       
   626 		if(iDirectScreenAccessAbort)
       
   627 			{
       
   628 			User::LeaveIfError(iVideoPlayControllerCustomCommands.DirectScreenAccessEvent(EResumeDSA));
       
   629 			iDirectScreenAccessAbort = EFalse;
       
   630 			}
       
   631 		}
       
   632 #endif
       
   633 	}
       
   634 
       
   635 TReal32 CVideoPlayerUtility::CBody::VideoFrameRateL() const
       
   636 	{
       
   637 	TReal32 framerate = 0;
       
   638 	User::LeaveIfError(iVideoControllerCustomCommands.GetFrameRate(framerate));
       
   639 	return framerate;
       
   640 	}
       
   641 
       
   642 
       
   643 void CVideoPlayerUtility::CBody::VideoFrameSizeL(TSize& aSize) const
       
   644 	{
       
   645 	User::LeaveIfError(iVideoControllerCustomCommands.GetVideoFrameSize(aSize));
       
   646 	}
       
   647 
       
   648 TInt CVideoPlayerUtility::CBody::Volume() const
       
   649 	{
       
   650 	TInt vol = 0;
       
   651 	iAudioPlayDeviceCustomCommands.GetVolume(vol);
       
   652 	return vol;
       
   653 	}
       
   654 
       
   655 
       
   656 void CVideoPlayerUtility::CBody::SetBalanceL(TInt aBalance)
       
   657 	{
       
   658 	User::LeaveIfError(iAudioPlayDeviceCustomCommands.SetBalance(aBalance));
       
   659 	}
       
   660 
       
   661 
       
   662 TInt CVideoPlayerUtility::CBody::Balance() const
       
   663 	{
       
   664 	TInt bal = 0;
       
   665 	iAudioPlayDeviceCustomCommands.GetBalance(bal);
       
   666 	return bal;
       
   667 	}
       
   668 
       
   669 void CVideoPlayerUtility::CBody::SetRotationL(TVideoRotation aRotation)
       
   670 	{
       
   671 #ifdef SYMBIAN_BUILD_GCE
       
   672 	if (!iGraphicsSurfaceSupported)
       
   673 		{
       
   674 		User::LeaveIfError(iVideoPlayControllerCustomCommands.SetRotation(aRotation));
       
   675 		}
       
   676 	else
       
   677 		{
       
   678 		// Rotation setting is not sent to controller when graphics surfaces are used.
       
   679 		// If the surface has been created, perform rotation with the help of graphics surfaces;
       
   680 		// otherwise, just store the rotation info.
       
   681 
       
   682 		TInt count = iActiveDisplays.Count();
       
   683 		
       
   684 		for (TInt i = 0; i < count; ++i)
       
   685 			{
       
   686 #ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
   687 			CMediaClientVideoDisplayBody* display = iActiveDisplays[i];
       
   688 			RArray<CMediaClientVideoDisplayBody::TWindowData>& windows = display->Windows();
       
   689 			TInt windowcount = windows.Count();	
       
   690 			for (TInt i = 0; i < windowcount; ++i)
       
   691 				{
       
   692 				CMediaClientVideoDisplayBody::TWindowData& window = windows[i];		
       
   693 				if (window.iRotation != aRotation)
       
   694 					{
       
   695 					// update config only if setting has actually changed
       
   696 					UpdateSurfaceAndSubtitleConfigL(*display, window, window.iClipRect, aRotation, iCropRegion);
       
   697 					}
       
   698 				}
       
   699 #else
       
   700 
       
   701 			iActiveDisplays[i]->SetRotationL(aRotation, iCropRegion);
       
   702 #endif//SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
   703 			}
       
   704 
       
   705 		iGlobalRotation = aRotation;
       
   706 
       
   707 		}
       
   708 #else 
       
   709 	User::LeaveIfError(iVideoPlayControllerCustomCommands.SetRotation(aRotation));
       
   710 #endif // SYMBIAN_BUILD_GCE
       
   711 	}
       
   712 
       
   713 TVideoRotation CVideoPlayerUtility::CBody::RotationL() const
       
   714 	{
       
   715 	TVideoRotation rot = EVideoRotationNone;
       
   716 #ifdef SYMBIAN_BUILD_GCE
       
   717 	if (!iGraphicsSurfaceSupported)
       
   718 		{		
       
   719 		User::LeaveIfError(iVideoPlayControllerCustomCommands.GetRotation(rot));		
       
   720 		}
       
   721 	else 
       
   722 		{
       
   723 		// Rotation setting is not retrieved from controller when graphics surfaces are used.
       
   724 		rot = iGlobalRotation;
       
   725 		}
       
   726 #else
       
   727 	User::LeaveIfError(iVideoPlayControllerCustomCommands.GetRotation(rot));
       
   728 #endif // SYMBIAN_BUILD_GCE
       
   729 	return rot;
       
   730 	}
       
   731 
       
   732 void CVideoPlayerUtility::CBody::SetScaleFactorL(TReal32 aWidthPercentage, TReal32 aHeightPercentage, TBool aAntiAliasFiltering)
       
   733 	{
       
   734 #ifdef SYMBIAN_BUILD_GCE
       
   735 	if (!iGraphicsSurfaceSupported)
       
   736 		{
       
   737 		User::LeaveIfError(iVideoPlayControllerCustomCommands.SetScaleFactor(aWidthPercentage, aHeightPercentage, aAntiAliasFiltering));
       
   738 		}
       
   739 	else
       
   740 		{
       
   741 		// Scale factor  setting is not sent to controller when graphics surfaces are used.
       
   742 		// If the surface has been created, perform scale factor with the help of graphics surfaces.
       
   743 		iAntiAliasFiltering = aAntiAliasFiltering;
       
   744 		iGlobalScaleWidth = aWidthPercentage;
       
   745 		iGlobalScaleHeight = aHeightPercentage;
       
   746 		iGlobalAutoScaleType = EAutoScaleNone;
       
   747 
       
   748 		TInt count = iActiveDisplays.Count();
       
   749 		
       
   750 		for (TInt i = 0; i < count; ++i)
       
   751 			{
       
   752 			iActiveDisplays[i]->SetScaleFactorL(aWidthPercentage, aHeightPercentage, iCropRegion);
       
   753 			}
       
   754 		}
       
   755 #else
       
   756 	User::LeaveIfError(iVideoPlayControllerCustomCommands.SetScaleFactor(aWidthPercentage, aHeightPercentage, aAntiAliasFiltering));
       
   757 #endif	// SYMBIAN_BUILD_GCE
       
   758 	}
       
   759 
       
   760 void CVideoPlayerUtility::CBody::GetScaleFactorL(TReal32& aWidthPercentage, TReal32& aHeightPercentage, TBool& aAntiAliasFiltering) const
       
   761 	{
       
   762 #ifdef SYMBIAN_BUILD_GCE
       
   763 	if (!iGraphicsSurfaceSupported)
       
   764 		{
       
   765 		User::LeaveIfError(iVideoPlayControllerCustomCommands.GetScaleFactor(aWidthPercentage, aHeightPercentage, aAntiAliasFiltering));
       
   766 		}
       
   767 	else
       
   768 		{
       
   769 		// Scale factor setting is not retrieved from controller when graphics surfaces are used.
       
   770 		
       
   771 		aWidthPercentage = iGlobalScaleWidth;
       
   772 		aHeightPercentage = iGlobalScaleHeight;	
       
   773 		
       
   774 		aAntiAliasFiltering = iAntiAliasFiltering;
       
   775 		}
       
   776 #else
       
   777 	User::LeaveIfError(iVideoPlayControllerCustomCommands.GetScaleFactor(aWidthPercentage, aHeightPercentage, aAntiAliasFiltering));	
       
   778 #endif // SYMBIAN_BUILD_GCE
       
   779 	}
       
   780 
       
   781 void CVideoPlayerUtility::CBody::SetCropRegionL(const TRect& aCropRegion)
       
   782 	{
       
   783 #ifdef SYMBIAN_BUILD_GCE
       
   784 	if (!iGraphicsSurfaceSupported)
       
   785 		{
       
   786 		User::LeaveIfError(iVideoPlayControllerCustomCommands.SetCropRegion(aCropRegion));
       
   787 		}
       
   788 	else
       
   789 		{
       
   790 		// Crop region setting is not sent to controller when graphics surfaces are used.
       
   791 		// If the surface has been created, perform crop region with the help of graphics surfaces;
       
   792 		// otherwise, just store the crop region info.
       
   793 		
       
   794 		iCropRegion = aCropRegion;
       
   795 		User::LeaveIfError(SetAllBackgroundSurfaces());
       
   796 		}
       
   797 #else
       
   798 	User::LeaveIfError(iVideoPlayControllerCustomCommands.SetCropRegion(aCropRegion));
       
   799 #endif // SYMBIAN_BUILD_GCE
       
   800 	}
       
   801 
       
   802 void CVideoPlayerUtility::CBody::GetCropRegionL(TRect& aCropRegion) const
       
   803 	{
       
   804 #ifdef SYMBIAN_BUILD_GCE
       
   805 	if (!iGraphicsSurfaceSupported )
       
   806 		{
       
   807 		User::LeaveIfError(iVideoPlayControllerCustomCommands.GetCropRegion(aCropRegion));
       
   808 		}
       
   809 	else
       
   810 		{
       
   811 		// Crop rectangle setting is not retrieved from controller when graphics surfaces are used.
       
   812 		aCropRegion = iCropRegion;
       
   813 		}
       
   814 #else
       
   815 	User::LeaveIfError(iVideoPlayControllerCustomCommands.GetCropRegion(aCropRegion));
       
   816 #endif // SYMBIAN_BUILD_GCE
       
   817 	}
       
   818 
       
   819 void CVideoPlayerUtility::CBody::Prepare()
       
   820 	{
       
   821 	TInt error = iVideoPlayControllerCustomCommands.Prepare();
       
   822 	if (error)
       
   823 		iObserver.MvpuoPrepareComplete(error);
       
   824 	}
       
   825 
       
   826 const TDesC8& CVideoPlayerUtility::CBody::VideoFormatMimeType() const
       
   827 	{
       
   828 	TPtr8 des = iMimeType->Des();
       
   829 	TInt err = iVideoControllerCustomCommands.GetVideoMimeType(des);
       
   830 	if (!err)
       
   831 		return *iMimeType;
       
   832 	else
       
   833 		return KNullDesC8;
       
   834 	}
       
   835 											 
       
   836 void CVideoPlayerUtility::CBody::RegisterForVideoLoadingNotification(MVideoLoadingObserver& aObserver)
       
   837 	{
       
   838 	iVideoLoadingObserver = &aObserver;
       
   839 	}
       
   840 
       
   841 TInt CVideoPlayerUtility::CBody::NumberOfMetaDataEntriesL() const
       
   842 	{
       
   843 	TInt num = 0;
       
   844 	User::LeaveIfError(iController.GetNumberOfMetaDataEntries(num));
       
   845 	return num;
       
   846 	}
       
   847 
       
   848 
       
   849 CMMFMetaDataEntry* CVideoPlayerUtility::CBody::MetaDataEntryL(TInt aMetaDataIndex) const
       
   850 	{
       
   851 	return iController.GetMetaDataEntryL(aMetaDataIndex);
       
   852 	}
       
   853 
       
   854 void CVideoPlayerUtility::CBody::SetPriorityL(TInt aPriority, TInt aPref)
       
   855 	{
       
   856 	iPrioritySettings.iPref = aPref;
       
   857 	iPrioritySettings.iPriority = aPriority;
       
   858 
       
   859 	TInt err = iController.SetPrioritySettings(iPrioritySettings);
       
   860 	if ((err == KErrNone) || (err == KErrNotReady))
       
   861 		{
       
   862 		iFindAndOpenController->Configure(KUidMediaTypeVideo, iPrioritySettings, CMMFPluginSelectionParameters::EAllowOtherMediaIds);
       
   863 		}
       
   864 	else
       
   865 		{
       
   866 		User::Leave(err);
       
   867 		}
       
   868 	}
       
   869 
       
   870 void CVideoPlayerUtility::CBody::PriorityL(TInt & aPriority, TMdaPriorityPreference &aPref) const 
       
   871 	{
       
   872 	aPriority = iPrioritySettings.iPriority;
       
   873 	aPref = TMdaPriorityPreference(iPrioritySettings.iPref);
       
   874 	}
       
   875 
       
   876 
       
   877 void CVideoPlayerUtility::CBody::SetPositionL(const TTimeIntervalMicroSeconds& aPosition)
       
   878 	{
       
   879 	User::LeaveIfError(iController.SetPosition(aPosition));
       
   880 	}
       
   881 
       
   882 
       
   883 TTimeIntervalMicroSeconds CVideoPlayerUtility::CBody::DurationL() const
       
   884 	{
       
   885 	TTimeIntervalMicroSeconds duration;
       
   886 	User::LeaveIfError(iController.GetDuration(duration));
       
   887 	return duration;
       
   888 	}
       
   889 
       
   890 TTimeIntervalMicroSeconds CVideoPlayerUtility::CBody::PositionL() const
       
   891 	{
       
   892 	TTimeIntervalMicroSeconds position;
       
   893 	User::LeaveIfError(iController.GetPosition(position));
       
   894 	return position;
       
   895 	}
       
   896 
       
   897 TInt CVideoPlayerUtility::CBody::MaxVolume() const
       
   898 	{
       
   899 	TInt maxVol = 0;
       
   900 	iAudioPlayDeviceCustomCommands.GetMaxVolume(maxVol);
       
   901 	return maxVol;
       
   902 	}
       
   903 
       
   904 void CVideoPlayerUtility::CBody::GetFrameL(TDisplayMode aDisplayMode, TBool aUseIntentAPI, TIntent aIntent)
       
   905 	{
       
   906 	delete iFrameBitmap;
       
   907 	iFrameBitmap = NULL;
       
   908 	iFrameBitmap = new (ELeave) CFbsBitmap;
       
   909 	User::LeaveIfError(iFrameBitmap->Create(TSize(0,0),aDisplayMode));
       
   910 
       
   911 	iFrameCallback->SetFrame(*iFrameBitmap);
       
   912 
       
   913 	if (aUseIntentAPI)
       
   914 		{
       
   915 		iVideoDRMExtCustomCommands.GetFrame(*iFrameBitmap, aIntent, iFrameCallback->ActiveStatus());
       
   916 		}
       
   917 	else
       
   918 		{
       
   919 		iVideoPlayControllerCustomCommands.GetFrame(*iFrameBitmap, iFrameCallback->ActiveStatus());
       
   920 		}
       
   921 	}
       
   922 
       
   923 MMMFDRMCustomCommand* CVideoPlayerUtility::CBody::GetDRMCustomCommand()
       
   924 	{
       
   925 	// TODO: check controller supports MMMFDRMCustomCommandImplementor
       
   926 	TInt error = iDRMCustomCommands.EvaluateIntent(ContentAccess::EPeek);
       
   927 	if (error==KErrNone)
       
   928 		{
       
   929 		return static_cast<MMMFDRMCustomCommand*>(&iDRMCustomCommands);
       
   930 		}
       
   931 	else
       
   932 		{
       
   933 		return NULL;
       
   934 		}
       
   935 	}
       
   936 	
       
   937 TInt CVideoPlayerUtility::CBody::VideoBitRateL() const
       
   938 	{
       
   939 	TInt bitRate;
       
   940 	User::LeaveIfError(iVideoControllerCustomCommands.GetVideoBitRate(bitRate));
       
   941 	return bitRate;
       
   942 	}
       
   943 
       
   944 TInt CVideoPlayerUtility::CBody::AudioBitRateL() const
       
   945 	{
       
   946 	TInt bitRate;
       
   947 	User::LeaveIfError(iVideoControllerCustomCommands.GetAudioBitRate(bitRate));
       
   948 	return bitRate;
       
   949 	}
       
   950 
       
   951 TBool CVideoPlayerUtility::CBody::AudioEnabledL() const
       
   952 	{
       
   953 	TBool enabled;
       
   954 	User::LeaveIfError(iVideoPlayControllerCustomCommands.GetAudioEnabled(enabled));
       
   955 	return enabled;
       
   956 	}
       
   957 	
       
   958 	
       
   959 void CVideoPlayerUtility::CBody::RefreshFrameL()
       
   960 	{
       
   961 	User::LeaveIfError(iVideoPlayControllerCustomCommands.RefreshFrame());
       
   962 	}
       
   963 
       
   964 TFourCC CVideoPlayerUtility::CBody::AudioTypeL() const
       
   965 	{
       
   966 	TFourCC codec;
       
   967 	User::LeaveIfError(iVideoControllerCustomCommands.GetAudioCodec(codec));
       
   968 	return codec;
       
   969 	}
       
   970 
       
   971 
       
   972 void CVideoPlayerUtility::CBody::HandleEvent(const TMMFEvent& aEvent)
       
   973 	{
       
   974 	if (aEvent.iEventType == KMMFEventCategoryVideoOpenComplete)
       
   975 		{
       
   976 		// if we haven't had a MfaocComplete() callback yet,
       
   977 		// we need to delay the call back to the client
       
   978 		// because the source/sink will not have been opened yet.
       
   979 		iEventOpenReceived = ETrue;
       
   980 		if (iOpenError == KErrNone)
       
   981 			iOpenError = aEvent.iErrorCode;
       
   982 		if (iCallbackOpenReceived)
       
   983 			iObserver.MvpuoOpenComplete(aEvent.iErrorCode);
       
   984 		}
       
   985 	else if (aEvent.iEventType == KMMFEventCategoryVideoPrepareComplete)
       
   986 		{
       
   987 		iObserver.MvpuoPrepareComplete(aEvent.iErrorCode);
       
   988 		}
       
   989 	else if (aEvent.iEventType == KMMFEventCategoryPlaybackComplete)
       
   990 		{
       
   991 		iObserver.MvpuoPlayComplete(aEvent.iErrorCode);
       
   992 		}
       
   993 	else if (aEvent.iEventType == KMMFEventCategoryVideoLoadingStarted)
       
   994 		{
       
   995 		if (iVideoLoadingObserver)
       
   996 			iVideoLoadingObserver->MvloLoadingStarted();
       
   997 		}
       
   998 	else if (aEvent.iEventType == KMMFEventCategoryVideoLoadingComplete)
       
   999 		{
       
  1000 		if (iVideoLoadingObserver)
       
  1001 			iVideoLoadingObserver->MvloLoadingComplete();
       
  1002 		}
       
  1003 	else if(aEvent.iEventType == KMMFEventCategoryAudioResourceAvailable)
       
  1004 		{
       
  1005 		if(iAudioResourceNotificationCallBack != NULL)
       
  1006 			{
       
  1007 			TBuf8<TMMFAudioConfig::KNotificationDataBufferSize> notificationData;
       
  1008 			if (KErrNone != iNotificationRegistrationCommands.GetResourceNotificationData(aEvent.iEventType, notificationData))
       
  1009 				{
       
  1010 				notificationData.SetLength(0);
       
  1011 				}
       
  1012 			iAudioResourceNotificationCallBack->MarncResourceAvailable(aEvent.iEventType, notificationData);	
       
  1013 			}
       
  1014 		}
       
  1015 #ifdef SYMBIAN_BUILD_GCE
       
  1016 	else if(aEvent.iEventType == KMMFEventCategoryVideoSurfaceCreated)
       
  1017 		{
       
  1018 		TInt error = SurfaceCreated();
       
  1019 			
       
  1020 		if (error != KErrNone)	
       
  1021 			{
       
  1022 			// Send error to the client
       
  1023 			TMMFEvent generalError(KMMFEventCategoryVideoPlayerGeneralError, error);
       
  1024 			iObserver.MvpuoEvent(generalError);	
       
  1025 			}
       
  1026 		}
       
  1027 	else if(aEvent.iEventType == KMMFEventCategoryVideoSurfaceParametersChanged)
       
  1028 		{
       
  1029 		TInt error = SurfaceParametersChanged();
       
  1030 				
       
  1031 		if (error != KErrNone)	
       
  1032 			{
       
  1033 			// Send error to the client
       
  1034 			TMMFEvent generalError(KMMFEventCategoryVideoPlayerGeneralError, error);
       
  1035 			iObserver.MvpuoEvent(generalError);	
       
  1036 			}
       
  1037 		}		
       
  1038 	else if(aEvent.iEventType == KMMFEventCategoryVideoRemoveSurface)
       
  1039 		{
       
  1040 		// Check surface is created
       
  1041 		TInt error = RemoveSurface(ETrue);
       
  1042 			
       
  1043 		if (error != KErrNone)
       
  1044 			{
       
  1045 			// Send error to the client
       
  1046 			TMMFEvent generalError(KMMFEventCategoryVideoPlayerGeneralError, error);
       
  1047 			iObserver.MvpuoEvent(generalError);	
       
  1048 			}
       
  1049 		}
       
  1050 #endif // SYMBIAN_BUILD_GCE	
       
  1051 #ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
  1052 	else if(aEvent.iEventType == KMMFEventCategoryVideoSubtitleCrpReady)
       
  1053 		{
       
  1054 		if (iSubtitleUtility)
       
  1055 			{
       
  1056 			// subtitle has not been disabled before event arrive
       
  1057 			RWindow* window = FindWindowWithWsHandle(iActiveDisplays, aEvent.iErrorCode);
       
  1058 			if (window)
       
  1059 				{
       
  1060 				// window has not been removed before event arrive
       
  1061 				iSubtitleUtility->HandleCrpReady(*window);
       
  1062 				}
       
  1063 			}
       
  1064 		}
       
  1065 #endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
  1066 	else 
       
  1067 		// Pass on all unrecognised events to the client
       
  1068 		iObserver.MvpuoEvent(aEvent);
       
  1069 	}
       
  1070 
       
  1071 #ifdef SYMBIAN_BUILD_GCE
       
  1072 TInt CVideoPlayerUtility::CBody::SurfaceCreated()
       
  1073 	{
       
  1074 	TInt count = iActiveDisplays.Count();
       
  1075 	TBool replaceSurface = !(iSurfaceId.IsNull());
       
  1076 	TSurfaceId oldSurfaceId(iSurfaceId);
       
  1077 	
       
  1078 	// first remove surface if one already in use
       
  1079 	if(replaceSurface)
       
  1080 		{
       
  1081 		for (TInt i = 0; i < count; i++)
       
  1082 			{
       
  1083 			CMediaClientVideoDisplayBody* display = iActiveDisplays[i];
       
  1084 			display->RemoveSurface(EFalse);
       
  1085 			}
       
  1086 		iSurfaceId = TSurfaceId::CreateNullId();
       
  1087 		}
       
  1088 	
       
  1089 	TSurfaceId surfaceId;
       
  1090 	TRect cropRect;
       
  1091 	TVideoAspectRatio aspectRatio;
       
  1092 	
       
  1093 	TInt error = iVideoPlaySurfaceSupportCustomCommands.GetSurfaceParameters(surfaceId, 
       
  1094 										cropRect, 
       
  1095 										aspectRatio);
       
  1096 	if(error != KErrNone)
       
  1097 		{
       
  1098 		if(replaceSurface)
       
  1099 				{
       
  1100 				// ignore error
       
  1101 				iVideoPlaySurfaceSupportCustomCommands.SurfaceRemoved(oldSurfaceId);
       
  1102 				}
       
  1103 		return error;
       
  1104 		}
       
  1105 	
       
  1106 	// loop through all displays, if any fail continue and report error later
       
  1107 	TInt error2;
       
  1108 	for (TInt i = 0; i < count; ++i)
       
  1109 		{
       
  1110 		error2 = iActiveDisplays[i]->SurfaceCreated(surfaceId, cropRect, aspectRatio, iCropRegion);
       
  1111 		if(error2 != KErrNone)
       
  1112 			{
       
  1113 			error = error2;
       
  1114 			}
       
  1115 		}
       
  1116 	
       
  1117 	// now store surface details
       
  1118 	iSurfaceId = surfaceId;
       
  1119 	iSurfaceCropRect = cropRect;
       
  1120 	iAspectRatio = aspectRatio;
       
  1121 	
       
  1122 	// if surface already existed tell video adaptation it is no longer in use. Video adaptation
       
  1123 	// will remove the surface when it receives this call therefore the following code must be done at the
       
  1124 	// end of this function.
       
  1125 	if (replaceSurface)
       
  1126         {
       
  1127         error2 = iVideoPlaySurfaceSupportCustomCommands.SurfaceRemoved(oldSurfaceId);
       
  1128         if (error2 != KErrNone)
       
  1129             {
       
  1130             error = error2;
       
  1131             }
       
  1132         }
       
  1133     return error;
       
  1134 	}
       
  1135 
       
  1136 TInt CVideoPlayerUtility::CBody::SurfaceParametersChanged()
       
  1137 	{
       
  1138 	if (iSurfaceId.IsNull())
       
  1139 		{
       
  1140 		return KErrNotSupported;
       
  1141 		}
       
  1142 	
       
  1143 	TSurfaceId surfaceId;
       
  1144 	TRect cropRect;
       
  1145 	TVideoAspectRatio aspectRatio;
       
  1146 	
       
  1147 	TInt error = iVideoPlaySurfaceSupportCustomCommands.GetSurfaceParameters(surfaceId, 
       
  1148 										cropRect, 
       
  1149 										aspectRatio);
       
  1150 	if (error != KErrNone)
       
  1151 		{
       
  1152 		return error;
       
  1153 		}
       
  1154 	
       
  1155 	if (iSurfaceId != surfaceId)
       
  1156 		{
       
  1157 		return KErrInUse;
       
  1158 		}
       
  1159 
       
  1160 	TInt count = iActiveDisplays.Count();
       
  1161 	TInt error2 = KErrNone;
       
  1162 	for (TInt i = 0; i < count; ++i)
       
  1163 		{
       
  1164 		// ignore error and continue to set parameters
       
  1165 		iActiveDisplays[i]->SurfaceParametersChanged(surfaceId, cropRect, aspectRatio);
       
  1166 		
       
  1167 		// save the error for the first failure and attempt to redraw remaining displays
       
  1168 		error2 = iActiveDisplays[i]->RedrawWindows(iCropRegion);
       
  1169 		if ((error2 != KErrNone) && (error == KErrNone))
       
  1170 			{
       
  1171 			error = error2;
       
  1172 			}
       
  1173 		}
       
  1174 	return error;
       
  1175 	}
       
  1176 		
       
  1177 TInt CVideoPlayerUtility::CBody::SetAllBackgroundSurfaces()
       
  1178 	{
       
  1179 	TInt count = iActiveDisplays.Count();
       
  1180 	TInt err = KErrNone;
       
  1181 	
       
  1182 	for (TInt i = 0; i < count; ++i)
       
  1183 		{
       
  1184 		CMediaClientVideoDisplayBody* display = iActiveDisplays[i];
       
  1185 		err = display->RedrawWindows(iCropRegion);
       
  1186 			
       
  1187 		if (err != KErrNone)
       
  1188 			{
       
  1189 			break;
       
  1190 			}
       
  1191 		}
       
  1192 	return err;
       
  1193 	}
       
  1194 
       
  1195 TInt CVideoPlayerUtility::CBody::RemoveSurface(TBool aControllerEvent)
       
  1196 	{
       
  1197 	if (iSurfaceId.IsNull())
       
  1198 		{
       
  1199 		return KErrNotFound;
       
  1200 		}
       
  1201 	
       
  1202 	TInt count = iActiveDisplays.Count();
       
  1203 	for (TInt i = 0; i < count; i++)
       
  1204 		{
       
  1205 		iActiveDisplays[i]->RemoveSurface(aControllerEvent);
       
  1206 		}
       
  1207 	
       
  1208 	TInt error = iVideoPlaySurfaceSupportCustomCommands.SurfaceRemoved(iSurfaceId);
       
  1209 
       
  1210 	iSurfaceId = TSurfaceId::CreateNullId();
       
  1211 	
       
  1212 	return error;
       
  1213 	}
       
  1214 	
       
  1215 #endif // SYMBIAN_BUILD_GCE
       
  1216 
       
  1217 void CVideoPlayerUtility::CBody::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/)
       
  1218 	{
       
  1219 	if (iControllerOpen)
       
  1220 		{
       
  1221 		iVideoPlayControllerCustomCommands.DirectScreenAccessEvent(EAbortDSA);
       
  1222 		iDirectScreenAccessAbort = ETrue;
       
  1223 		}
       
  1224 	}
       
  1225 
       
  1226 void CVideoPlayerUtility::CBody::Restart(RDirectScreenAccess::TTerminationReasons /*aReason*/) 
       
  1227 	{
       
  1228 	__ASSERT_ALWAYS(iDirectScreenAccess, User::Panic(_L("iDirectScreenAccess is NULL"), KErrArgument)); // should always be valid if we have a callback from it
       
  1229 	TRAPD( err, iDirectScreenAccess->StartL());
       
  1230 
       
  1231 	if (iControllerOpen)
       
  1232 		{
       
  1233 		if (err == KErrNone)
       
  1234 			{
       
  1235 			iVideoPlayControllerCustomCommands.UpdateDisplayRegion(*iDirectScreenAccess->DrawingRegion());
       
  1236 			iVideoPlayControllerCustomCommands.DirectScreenAccessEvent(EResumeDSA);
       
  1237 			}
       
  1238 		}
       
  1239 	}
       
  1240 
       
  1241 TInt CVideoPlayerUtility::CBody::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom)
       
  1242 	{
       
  1243 	return iController.CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom);
       
  1244 	}
       
  1245 	
       
  1246 TInt CVideoPlayerUtility::CBody::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2)
       
  1247 	{
       
  1248 	return iController.CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2);
       
  1249 	}
       
  1250 	
       
  1251 void CVideoPlayerUtility::CBody::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom, TRequestStatus& aStatus)
       
  1252 	{
       
  1253 	iController.CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom, aStatus);
       
  1254 	}
       
  1255 	
       
  1256 void CVideoPlayerUtility::CBody::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TRequestStatus& aStatus)
       
  1257 	{
       
  1258 	iController.CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aStatus);
       
  1259 	}
       
  1260 	
       
  1261 void CVideoPlayerUtility::CBody::SetVideoFrameRateL(TReal32 aFramesPerSecond)
       
  1262 	{
       
  1263 	User::LeaveIfError(iVideoControllerCustomCommands.SetFrameRate(aFramesPerSecond));
       
  1264 	}
       
  1265 
       
  1266 const CMMFControllerImplementationInformation& CVideoPlayerUtility::CBody::ControllerImplementationInformationL()
       
  1267 	{
       
  1268 	if (!iControllerImplementationInformation)
       
  1269 		{
       
  1270 		if (iControllerUid==KNullUid)
       
  1271 			User::Leave(KErrNotReady);
       
  1272 		iControllerImplementationInformation = CMMFControllerImplementationInformation::NewL(iControllerUid);
       
  1273 		}
       
  1274 	return *iControllerImplementationInformation;
       
  1275 	}
       
  1276 	
       
  1277 void CVideoPlayerUtility::CBody::GetVideoLoadingProgressL(TInt& aPercentageProgress)
       
  1278 	{
       
  1279 	User::LeaveIfError(iVideoPlayControllerCustomCommands.GetLoadingProgress(aPercentageProgress));
       
  1280 	}
       
  1281 
       
  1282 void CVideoPlayerUtility::CBody::StopDirectScreenAccessL()
       
  1283 	{
       
  1284 #ifdef SYMBIAN_BUILD_GCE
       
  1285 	if (iUsingVPU2)
       
  1286 		{
       
  1287 		User::Leave(KErrNotSupported);
       
  1288 		}
       
  1289 
       
  1290 	if (!iGraphicsSurfaceSupported)
       
  1291 		{
       
  1292 		__ASSERT_ALWAYS(iDirectScreenAccess, User::Panic(_L("iDirectScreenAccess is NULL"), KErrArgument));
       
  1293 		iDirectScreenAccess->Cancel();
       
  1294 		AbortNow(RDirectScreenAccess::ETerminateCancel);
       
  1295 		}
       
  1296 #else
       
  1297 	__ASSERT_ALWAYS(iDirectScreenAccess, User::Panic(_L("iDirectScreenAccess is NULL"), KErrArgument));
       
  1298 	iDirectScreenAccess->Cancel();
       
  1299 	AbortNow(RDirectScreenAccess::ETerminateCancel);
       
  1300 #endif // SYMBIAN_BUILD_GCE
       
  1301 	}
       
  1302 	
       
  1303 void CVideoPlayerUtility::CBody::StartDirectScreenAccessL()
       
  1304 	{
       
  1305 #ifdef SYMBIAN_BUILD_GCE
       
  1306 	if (iUsingVPU2)
       
  1307 		{
       
  1308 		User::Leave(KErrNotSupported);
       
  1309 		}
       
  1310 
       
  1311 	if (!iGraphicsSurfaceSupported)
       
  1312 		{
       
  1313 		// ETerminateCancel is a dummy value that is ignored by Restart()
       
  1314 		Restart(RDirectScreenAccess::ETerminateCancel);
       
  1315 		}
       
  1316 #else
       
  1317 	// ETerminateCancel is a dummy value that is ignored by Restart()
       
  1318 	Restart(RDirectScreenAccess::ETerminateCancel);
       
  1319 #endif  // SYMBIAN_BUILD_GCE
       
  1320 	}
       
  1321 
       
  1322 //registers for notification when audio resource is available.
       
  1323 TInt CVideoPlayerUtility::CBody::RegisterAudioResourceNotification( MMMFAudioResourceNotificationCallback& aCallback, 
       
  1324 																	TUid aNotificationEventUid, 
       
  1325 																	const TDesC8& aNotificationRegistrationData)
       
  1326 	{
       
  1327 	//if not valid notification event id, return;
       
  1328 	if(aNotificationEventUid != KMMFEventCategoryAudioResourceAvailable)
       
  1329 		{
       
  1330 		return KErrNotSupported;
       
  1331 		}
       
  1332 		
       
  1333 	iAudioResourceNotificationCallBack = &aCallback;
       
  1334 	TInt err = iNotificationRegistrationCommands.RegisterAsClient(aNotificationEventUid, aNotificationRegistrationData);
       
  1335 	if(err == KErrNotReady)
       
  1336 		{
       
  1337 		//save the request - so that registration can be attempted on play
       
  1338 		iArnEventHolder = 	aNotificationEventUid;
       
  1339 		iNotificationDataHolder = aNotificationRegistrationData;
       
  1340 		return KErrNone;
       
  1341 		}
       
  1342 	iArnEventHolder = KNullUid;
       
  1343 	iNotificationDataHolder = KNullDesC8;
       
  1344 	return err;
       
  1345 	}
       
  1346 
       
  1347 //Cancels the registration for audio resource notification.
       
  1348 TInt CVideoPlayerUtility::CBody::CancelRegisterAudioResourceNotification(TUid aNotificationEventId)
       
  1349 	{
       
  1350 	//if not valid notification event id, return;
       
  1351 	if(aNotificationEventId != KMMFEventCategoryAudioResourceAvailable)
       
  1352 		{
       
  1353 		return KErrNotSupported;
       
  1354 		}
       
  1355 	TInt err = iNotificationRegistrationCommands.CancelRegisterAsClient(aNotificationEventId);
       
  1356 	if(err == KErrNotReady)
       
  1357 		{
       
  1358 		if(iArnEventHolder == KNullUid)	
       
  1359 			{
       
  1360 			return KErrCancel;
       
  1361 			}
       
  1362 		//iArnEventHolder has data to re-attempt registration ;
       
  1363 		//but reattempt is not made(which is done in play);hence return KErrNone
       
  1364 		iArnEventHolder = KNullUid;
       
  1365 		iNotificationDataHolder = KNullDesC8;
       
  1366 		return KErrNone;
       
  1367 		}
       
  1368 	return err;
       
  1369 	}
       
  1370 
       
  1371 //Waits for the client to resume the play even after the default timer expires.
       
  1372 TInt CVideoPlayerUtility::CBody::WillResumePlay()
       
  1373 	{
       
  1374 	return iNotificationRegistrationCommands.WillResumePlay();
       
  1375 	}
       
  1376 
       
  1377 // This method will fail with KErrNotSupported when using CVideoPlayerUtility2, otherwise
       
  1378 // set the screen number.
       
  1379 TInt CVideoPlayerUtility::CBody::SetInitScreenNumber(TInt aScreenNumber)
       
  1380 	{
       
  1381 #ifdef SYMBIAN_BUILD_GCE
       
  1382 	// If the method is called from CVideoPlayerUtility2, return KErrNotSupport
       
  1383 	if (iUsingVPU2)
       
  1384 		{
       
  1385 		return KErrNotSupported;
       
  1386 		}
       
  1387 #endif
       
  1388 		
       
  1389 #ifdef SYMBIAN_ENABLE_MMF_MULTISCREEN_SUPPORT
       
  1390 	iScreenNumber = aScreenNumber;
       
  1391 	return KErrNone;
       
  1392 #else
       
  1393 	aScreenNumber = aScreenNumber;//added to remove the warning
       
  1394 	return KErrNotSupported;
       
  1395 #endif
       
  1396 	}
       
  1397 
       
  1398 #ifdef SYMBIAN_BUILD_GCE
       
  1399 //-------------------------------------------------------------------------------
       
  1400 
       
  1401 void CVideoPlayerUtility::CBody::AddDisplayWindowL(RWsSession& aWs, CWsScreenDevice& aScreenDevice, 
       
  1402 							RWindow& aWindow, const TRect& aVideoExtent, 
       
  1403 							const TRect& aWindowClipRect)
       
  1404 	{
       
  1405 	// set window and get display ID for the window
       
  1406 	TRect windowRect = TRect(aWindow.Size()); 
       
  1407 	
       
  1408 	// Check the rectangle is contained completely within the window
       
  1409 	if (!RectContains(windowRect, aWindowClipRect))
       
  1410 		{
       
  1411 		// NOTE: TRect::Contains() is not used for comparison here as point located on the right hand 
       
  1412 		//       side or bottom is considered to be outside the rectangle, which is not the desirable 
       
  1413 		//       behaviour in this case
       
  1414 		User::Leave(KErrArgument);
       
  1415 		}
       
  1416 		
       
  1417 	DoAddDisplayWindowL(aWs, aScreenDevice.GetScreenNumber(), aWindow, aWindowClipRect, aVideoExtent, &aWindow);
       
  1418 	}
       
  1419 	
       
  1420 void CVideoPlayerUtility::CBody::AddDisplayWindowL(RWsSession& aWs, CWsScreenDevice& aScreenDevice, RWindow& aWindow)
       
  1421 	{
       
  1422 	DoAddDisplayWindowL(aWs, aScreenDevice.GetScreenNumber(), aWindow, TRect(aWindow.Size()), TRect(aWindow.Size()), &aWindow);
       
  1423 	}
       
  1424 
       
  1425 void CVideoPlayerUtility::CBody::DoAddDisplayWindowL(RWsSession& aWs, TInt aDisplayId, RWindowBase& aWindow,
       
  1426 								const TRect& aClipRect, const TRect& aVideoExtent, RWindow* aWindow2)
       
  1427 	{
       
  1428 	iWs = &aWs;
       
  1429 
       
  1430 	// check opening the source is complete and the client has been recieved an MvpuoOpenComplete() callback
       
  1431 	if (!iControllerOpen)
       
  1432 		{
       
  1433 		User::Leave(KErrNotReady);
       
  1434 		}
       
  1435 
       
  1436 	// make sure window isn't already added on another display
       
  1437 	TRAPD(err, CMediaClientVideoDisplayBody::FindDisplayWithWindowL(iActiveDisplays, aWindow));
       
  1438 	if (err != KErrNotFound)
       
  1439 		{
       
  1440 		// If err is something else but KErrNone leave
       
  1441 		User::LeaveIfError(err);
       
  1442 		// Window is already in use
       
  1443 		User::Leave(KErrInUse);
       
  1444 		}
       
  1445 
       
  1446 	TInt pos = iActiveDisplays.FindInOrder(aDisplayId, CMediaClientVideoDisplayBody::CompareByDisplay);
       
  1447 	CMediaClientVideoDisplayBody* display = NULL;
       
  1448 
       
  1449 	if (pos == KErrNotFound)
       
  1450 		{
       
  1451 		if(iSurfaceId.IsNull())
       
  1452 			{
       
  1453 			display = CMediaClientVideoDisplayBody::NewL(aDisplayId);
       
  1454 			}
       
  1455 		else
       
  1456 			{
       
  1457 			display = CMediaClientVideoDisplayBody::NewL(aDisplayId, iSurfaceId, iSurfaceCropRect, iAspectRatio);
       
  1458 			}
       
  1459 		CleanupStack::PushL(display);
       
  1460 		iActiveDisplays.InsertInOrderL(display, CMediaClientVideoDisplayBody::Compare);
       
  1461 		CleanupStack::Pop(display);
       
  1462 		}
       
  1463 	else 
       
  1464 		{
       
  1465 		User::LeaveIfError(pos);
       
  1466 		display = iActiveDisplays[pos];
       
  1467 		}
       
  1468 
       
  1469 	display->AddDisplayWindowL(&aWindow, aClipRect, iCropRegion, aVideoExtent, iGlobalScaleWidth, iGlobalScaleHeight,
       
  1470 								iGlobalRotation, iGlobalAutoScaleType, iGlobalHorizPos, iGlobalVertPos, aWindow2);
       
  1471 
       
  1472 #ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
  1473 	if (iSubtitleUtility)
       
  1474 		{
       
  1475 		// subtitles were enabled already, so enable subtitles on this window
       
  1476 		TMMFSubtitleWindowConfig config;
       
  1477 		config.iWindowId = aWindow.WsHandle();
       
  1478 		config.iWindowClipRect = aClipRect;
       
  1479 		config.iDisplayMode = aWindow.DisplayMode();
       
  1480 		config.iRotation = iGlobalRotation;
       
  1481 		iSubtitleUtility->AddSubtitleConfig(config); // ignore error from add subtitle config because the window can still display video properly
       
  1482 		}
       
  1483 #endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
  1484 	}
       
  1485 
       
  1486 void CVideoPlayerUtility::CBody::RemoveDisplayWindow(RWindowBase& aWindow)
       
  1487 	{
       
  1488 	CMediaClientVideoDisplayBody* display = NULL;
       
  1489 	TRAPD(err, display = CMediaClientVideoDisplayBody::FindDisplayWithWindowL(iActiveDisplays, aWindow));
       
  1490 	
       
  1491 	if (err == KErrNone)
       
  1492 		{		
       
  1493 		display->RemoveDisplayWindow(aWindow);
       
  1494 	
       
  1495 		if (!display->IsUsed())
       
  1496 
       
  1497 			{
       
  1498 			TInt pos = iActiveDisplays.Find(display);
       
  1499 			iActiveDisplays.Remove(pos);
       
  1500 			delete display;
       
  1501 			}
       
  1502 
       
  1503 #ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
  1504 		if (iSubtitleUtility)
       
  1505 			{
       
  1506 			// subtitles are enabled, so remove window config, ignore error
       
  1507 			iSubtitleUtility->RemoveSubtitleConfig(aWindow.WsHandle());
       
  1508 			}
       
  1509 #endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
  1510 		}	
       
  1511 	}
       
  1512 
       
  1513 void CVideoPlayerUtility::CBody::AddDisplayL(TInt aDisplay, MMMFSurfaceEventHandler& aEventHandler)
       
  1514 	{
       
  1515 	if (!iControllerOpen)
       
  1516 		{
       
  1517 		User::Leave(KErrNotReady);
       
  1518 		}
       
  1519 	
       
  1520 	TInt err = iActiveDisplays.FindInOrder(aDisplay, CMediaClientVideoDisplayBody::CompareByDisplay);
       
  1521 	
       
  1522 	if (err == KErrNotFound)
       
  1523 		{
       
  1524 		CMediaClientVideoDisplayBody* display;
       
  1525 		if(iSurfaceId.IsNull())
       
  1526 			{
       
  1527 			display = CMediaClientVideoDisplayBody::NewL(aDisplay);
       
  1528 			}
       
  1529 		else
       
  1530 			{
       
  1531 			display = CMediaClientVideoDisplayBody::NewL(aDisplay, iSurfaceId, iSurfaceCropRect, iAspectRatio);
       
  1532 			}
       
  1533 		CleanupStack::PushL(display);
       
  1534 		iActiveDisplays.InsertInOrderL(display, CMediaClientVideoDisplayBody::Compare);
       
  1535 		CleanupStack::Pop(display);
       
  1536 		display->AddDisplayL(aEventHandler);
       
  1537 		}
       
  1538 	else
       
  1539 		{
       
  1540 		User::LeaveIfError(err);
       
  1541 		iActiveDisplays[err]->AddDisplayL(aEventHandler);
       
  1542 		}
       
  1543 	}
       
  1544 
       
  1545 void CVideoPlayerUtility::CBody::RemoveDisplay(TInt aDisplay)
       
  1546 	{
       
  1547 	TInt pos = iActiveDisplays.FindInOrder(aDisplay, CMediaClientVideoDisplayBody::CompareByDisplay);
       
  1548 	
       
  1549 	if (pos >= KErrNone)
       
  1550 		{
       
  1551 		CMediaClientVideoDisplayBody* disp = iActiveDisplays[pos];
       
  1552 		disp->RemoveDisplay();
       
  1553 		
       
  1554 		if (!disp->HasWindows())
       
  1555 			{
       
  1556 			iActiveDisplays.Remove(pos);
       
  1557 			delete disp;
       
  1558 			}
       
  1559 		}
       
  1560 	}
       
  1561 
       
  1562 void CVideoPlayerUtility::CBody::ConvertFromRelativeToDisplayToRelativeToWindow(
       
  1563             const RWindowBase& aWindow,
       
  1564             const TRect& aFromWindowRect,
       
  1565             const TRect& aFromClipRect,
       
  1566             TRect& aToWindowRect,
       
  1567             TRect& aToClipRect)
       
  1568     {
       
  1569     TPoint windowOrigin = aWindow.AbsPosition();
       
  1570     
       
  1571     // window rect
       
  1572     aToWindowRect.iTl.iX = aFromWindowRect.iTl.iX - windowOrigin.iX;
       
  1573     aToWindowRect.iTl.iY = aFromWindowRect.iTl.iY - windowOrigin.iY;
       
  1574     aToWindowRect.iBr.iX = aFromWindowRect.iBr.iX - windowOrigin.iX;
       
  1575     aToWindowRect.iBr.iY = aFromWindowRect.iBr.iY - windowOrigin.iY;
       
  1576     
       
  1577     // clip rect
       
  1578     aToClipRect.iTl.iX = aFromClipRect.iTl.iX - windowOrigin.iX;
       
  1579     aToClipRect.iTl.iY = aFromClipRect.iTl.iY - windowOrigin.iY;
       
  1580     aToClipRect.iBr.iX = aFromClipRect.iBr.iX - windowOrigin.iX;
       
  1581     aToClipRect.iBr.iY = aFromClipRect.iBr.iY - windowOrigin.iY;
       
  1582     }
       
  1583 
       
  1584 void CVideoPlayerUtility::CBody::SetVideoExtentL(const RWindowBase& aWindow, const TRect& aVideoExtent)
       
  1585 	{
       
  1586 	// check opening the source is complete and the client has been recieved an MvpuoOpenComplete() callback
       
  1587 	if (!iControllerOpen)
       
  1588 		{
       
  1589 		User::Leave(KErrNotReady);
       
  1590 		}
       
  1591 		
       
  1592 	CMediaClientVideoDisplayBody* display = CMediaClientVideoDisplayBody::FindDisplayWithWindowL(iActiveDisplays, aWindow);
       
  1593 	display->SetVideoExtentL(aWindow, aVideoExtent, iCropRegion);
       
  1594 	}
       
  1595 
       
  1596 void CVideoPlayerUtility::CBody::SetWindowClipRectL(const RWindowBase& aWindow, const TRect& aWindowClipRect)
       
  1597 	{
       
  1598     // check opening the source is complete and the client has been recieved an MvpuoOpenComplete() callback
       
  1599 	if (!iControllerOpen)
       
  1600 		{
       
  1601 		User::Leave(KErrNotReady);
       
  1602 		}
       
  1603 
       
  1604 	TRect winRect(aWindow.Size());
       
  1605 
       
  1606 	if (!RectContains(winRect, aWindowClipRect))
       
  1607 		{
       
  1608 		User::Leave(KErrArgument);
       
  1609 		}
       
  1610 		
       
  1611 	CMediaClientVideoDisplayBody* display = CMediaClientVideoDisplayBody::FindDisplayWithWindowL(iActiveDisplays, aWindow);
       
  1612 #ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
  1613 	RArray<CMediaClientVideoDisplayBody::TWindowData>& windows = display->Windows();
       
  1614 	TInt pos = windows.Find(aWindow.WsHandle(), CMediaClientVideoDisplayBody::TWindowData::CompareByWsHandle);
       
  1615 	User::LeaveIfError(pos);
       
  1616 	
       
  1617 	CMediaClientVideoDisplayBody::TWindowData& currentWin = windows[pos];
       
  1618 	if (currentWin.iClipRect != aWindowClipRect)
       
  1619 		{
       
  1620 		// update config only if setting has actually changed
       
  1621 		UpdateSurfaceAndSubtitleConfigL(*display, currentWin, aWindowClipRect, currentWin.iRotation, iCropRegion);
       
  1622 		}
       
  1623 #else
       
  1624 	display->SetWindowClipRectL(aWindow, aWindowClipRect, iCropRegion);
       
  1625 #endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
  1626 	}
       
  1627 
       
  1628 // Check if the controller supports the graphics surface. Has to be called after resource opened.
       
  1629 TInt CVideoPlayerUtility::CBody::CheckSurfaceSupported()
       
  1630 	{
       
  1631 	TInt err = iFindAndOpenController->SurfaceSupported();
       
  1632 		
       
  1633 	if (err == KErrNone)
       
  1634 		{
       
  1635 		iGraphicsSurfaceSupported = ETrue;
       
  1636 		}
       
  1637 	else 
       
  1638 		{
       
  1639 		iGraphicsSurfaceSupported = EFalse;
       
  1640 		}
       
  1641 		
       
  1642 	return err;
       
  1643 	}
       
  1644 
       
  1645 TBool CVideoPlayerUtility::CBody::RectContains(const TRect& aLeft, const TRect& aRight)
       
  1646 	{
       
  1647 	return !(aLeft.iTl.iX > aRight.iTl.iX || 
       
  1648 			aLeft.iTl.iY > aRight.iTl.iY ||
       
  1649 	    	aLeft.iBr.iX < aRight.iBr.iX || 
       
  1650 	    	aLeft.iBr.iY < aRight.iBr.iY);
       
  1651 	}
       
  1652 	
       
  1653 	
       
  1654 void CVideoPlayerUtility::CBody::SetAutoScaleL(const RWindowBase& aWindow, TAutoScaleType aScaleType)
       
  1655 	{
       
  1656 	SetAutoScaleL(aWindow, aScaleType, EHorizontalAlignCenter, EVerticalAlignCenter);
       
  1657 	}
       
  1658 	
       
  1659 void CVideoPlayerUtility::CBody::SetAutoScaleL(const RWindowBase& aWindow, TAutoScaleType aScaleType, TInt aHorizPos, TInt aVertPos)
       
  1660 	{
       
  1661 	if (!iControllerOpen)
       
  1662 		{
       
  1663 		User::Leave(KErrNotReady);
       
  1664 		}
       
  1665 		
       
  1666 	CMediaClientVideoDisplayBody* display = CMediaClientVideoDisplayBody::FindDisplayWithWindowL(iActiveDisplays, aWindow);
       
  1667 	display->SetAutoScaleL(aWindow, aScaleType, aHorizPos, aVertPos, iCropRegion);
       
  1668 	}
       
  1669 
       
  1670 void CVideoPlayerUtility::CBody::SetRotationL(const RWindowBase& aWindow, TVideoRotation aRotation)
       
  1671 	{
       
  1672 	if (!iControllerOpen)
       
  1673 		{
       
  1674 		User::Leave(KErrNotReady);
       
  1675 		}
       
  1676 
       
  1677 	CMediaClientVideoDisplayBody* display = CMediaClientVideoDisplayBody::FindDisplayWithWindowL(iActiveDisplays, aWindow);
       
  1678 #ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
  1679 	RArray<CMediaClientVideoDisplayBody::TWindowData>& windows = display->Windows();
       
  1680 	TInt pos = windows.Find(aWindow.WsHandle(), CMediaClientVideoDisplayBody::TWindowData::CompareByWsHandle);
       
  1681 	User::LeaveIfError(pos);
       
  1682 	
       
  1683 	CMediaClientVideoDisplayBody::TWindowData& currentWin = windows[pos];
       
  1684 	if (currentWin.iRotation != aRotation)
       
  1685 		{
       
  1686 		UpdateSurfaceAndSubtitleConfigL(*display, currentWin, currentWin.iClipRect, aRotation, iCropRegion);
       
  1687 		}
       
  1688 #else
       
  1689 	display->SetRotationL(aWindow, aRotation, iCropRegion);
       
  1690 #endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
  1691 	}
       
  1692 	
       
  1693 TVideoRotation CVideoPlayerUtility::CBody::RotationL(const RWindowBase& aWindow) const
       
  1694 	{
       
  1695 	if (!iControllerOpen)
       
  1696 		{
       
  1697 		User::Leave(KErrNotReady);
       
  1698 		}
       
  1699 	CMediaClientVideoDisplayBody* display = CMediaClientVideoDisplayBody::FindDisplayWithWindowL(iActiveDisplays, aWindow);
       
  1700 	return display->RotationL(aWindow);
       
  1701 	}
       
  1702 	
       
  1703 void CVideoPlayerUtility::CBody::SetScaleFactorL(const RWindowBase& aWindow, TReal32 aWidthPercentage, TReal32 aHeightPercentage)
       
  1704 	{
       
  1705 	if (!iControllerOpen)
       
  1706 		{
       
  1707 		User::Leave(KErrNotReady);
       
  1708 		
       
  1709 		}
       
  1710 	CMediaClientVideoDisplayBody* display = CMediaClientVideoDisplayBody::FindDisplayWithWindowL(iActiveDisplays, aWindow);
       
  1711 	display->SetScaleFactorL(aWindow, aWidthPercentage, aHeightPercentage, iCropRegion);
       
  1712 	}
       
  1713 	
       
  1714 void CVideoPlayerUtility::CBody::GetScaleFactorL(const RWindowBase& aWindow, TReal32& aWidthPercentage, TReal32& aHeightPercentage) const
       
  1715 	{
       
  1716 	if (!iControllerOpen)
       
  1717 		{
       
  1718 		User::Leave(KErrNotReady);
       
  1719 		
       
  1720 		}
       
  1721 	CMediaClientVideoDisplayBody* display = CMediaClientVideoDisplayBody::FindDisplayWithWindowL(iActiveDisplays, aWindow);
       
  1722 	display->GetScaleFactorL(aWindow, aWidthPercentage, aHeightPercentage);
       
  1723 	}
       
  1724 
       
  1725 void CVideoPlayerUtility::CBody::SetExternalDisplaySwitchingL(TInt aDisplay, TBool aControl)
       
  1726     {
       
  1727     TInt pos = iActiveDisplays.FindInOrder(aDisplay, CMediaClientVideoDisplayBody::CompareByDisplay);
       
  1728     
       
  1729     User::LeaveIfError(pos);
       
  1730     
       
  1731     iActiveDisplays[pos]->SetExternalDisplaySwitchingL(aControl);
       
  1732     }
       
  1733 
       
  1734 #endif // SYMBIAN_BUILD_GCE
       
  1735 
       
  1736 void CVideoPlayerUtility::CBody::SetPlayVelocityL(TInt aVelocity)
       
  1737 	{
       
  1738 	// Leave if Open is not yet called on controller.
       
  1739 	if(!iEventOpenReceived)
       
  1740 		{
       
  1741 		User::Leave(KErrNotReady);
       
  1742 		}
       
  1743 	
       
  1744 	User::LeaveIfError(iVideoPlayControllerExtCustomCommands.SetPlayVelocity(aVelocity));	
       
  1745 	}
       
  1746 
       
  1747 const TInt KDefaultPlayVelocity = 100;
       
  1748 
       
  1749 TInt CVideoPlayerUtility::CBody::PlayVelocityL() const
       
  1750 	{
       
  1751 	TInt velocity;
       
  1752 	TInt error;
       
  1753 
       
  1754 	// Leave if Open is not yet called.
       
  1755 	if( !iEventOpenReceived )
       
  1756 		{
       
  1757 		User::Leave(KErrNotReady);
       
  1758 		}
       
  1759 	
       
  1760 	error = iVideoPlayControllerExtCustomCommands.PlayVelocity(velocity);
       
  1761 	/* if customcommand is not implemented by controller pluggin return default value(100) */
       
  1762 	if (KErrNotSupported == error)
       
  1763 		{
       
  1764 		velocity = KDefaultPlayVelocity;
       
  1765 		}
       
  1766 	else
       
  1767 		{
       
  1768 		User::LeaveIfError(	error );	
       
  1769 		}
       
  1770 	return velocity;
       
  1771 	}
       
  1772 void CVideoPlayerUtility::CBody::StepFrameL(TInt aStep)
       
  1773 	{
       
  1774 	//Leave if not in paused state. This functionality is supported only in paused state.
       
  1775 	if( (!iEventOpenReceived ) || ( EPaused != iState ) )
       
  1776 		{
       
  1777 		User::Leave(KErrNotReady);
       
  1778 		}
       
  1779 
       
  1780 	User::LeaveIfError(iVideoPlayControllerExtCustomCommands.StepFrame(aStep));
       
  1781 	}
       
  1782 void CVideoPlayerUtility::CBody::GetPlayRateCapabilitiesL(TVideoPlayRateCapabilities& aCapabilities) const
       
  1783 	{
       
  1784 	TInt error;
       
  1785 
       
  1786 	// Leave if Open is not yet called on controller.
       
  1787 	if( !iEventOpenReceived )
       
  1788 		{
       
  1789 		User::Leave(KErrNotReady);
       
  1790 		}
       
  1791 	
       
  1792 	error = iVideoPlayControllerExtCustomCommands.GetPlayRateCapabilities(aCapabilities);
       
  1793 	/* if customcommand is not implemented by controller pluggin return not supported */
       
  1794 	if (KErrNotSupported == error)
       
  1795 		{
       
  1796 		aCapabilities.iPlayBackward = EFalse;
       
  1797 		aCapabilities.iPlayForward = EFalse;
       
  1798 		aCapabilities.iStepBackward = EFalse;
       
  1799 		aCapabilities.iStepForward = EFalse;
       
  1800 		}
       
  1801 	else
       
  1802 		{
       
  1803 		User::LeaveIfError(error);
       
  1804 		}	
       
  1805 	}
       
  1806 void CVideoPlayerUtility::CBody::SetVideoEnabledL(TBool aVideoEnabled)
       
  1807 	{
       
  1808 	// Leave if Open is not yet called or not in stopped state.
       
  1809 	if( (!iEventOpenReceived ) || ( EStopped != iState ) )
       
  1810 		{
       
  1811 		User::Leave(KErrNotReady);
       
  1812 		}
       
  1813 	
       
  1814 	User::LeaveIfError(iVideoPlayControllerExtCustomCommands.SetVideoEnabled(aVideoEnabled));
       
  1815 	}
       
  1816 TBool CVideoPlayerUtility::CBody::VideoEnabledL() const
       
  1817 	{
       
  1818 	TBool videoEnabled;
       
  1819 	TInt error;
       
  1820 
       
  1821 	// Leave if Open is not yet called.
       
  1822 	if( !iEventOpenReceived )
       
  1823 		{
       
  1824 		User::Leave(KErrNotReady);
       
  1825 		}
       
  1826 	
       
  1827 	error = iVideoPlayControllerExtCustomCommands.VideoEnabled(videoEnabled);
       
  1828 	/* if customcommand is not implemented by controller pluggin return default value ETrue */
       
  1829 	if (KErrNotSupported == error)
       
  1830 		{
       
  1831 		videoEnabled = ETrue;
       
  1832 		}
       
  1833 	else
       
  1834 		{
       
  1835 		User::LeaveIfError(error);
       
  1836 		}	
       
  1837 	return videoEnabled;
       
  1838 	}
       
  1839 void CVideoPlayerUtility::CBody::SetAudioEnabledL(TBool aAudioEnabled)
       
  1840 	{
       
  1841 	// Leave if Open is not yet called or not in stopped state.
       
  1842 	if( (!iEventOpenReceived ) || ( EStopped != iState ) )
       
  1843 		{
       
  1844 		User::Leave(KErrNotReady);
       
  1845 		}
       
  1846 	
       
  1847 	User::LeaveIfError(iVideoPlayControllerExtCustomCommands.SetAudioEnabled(aAudioEnabled));
       
  1848 	}
       
  1849 void CVideoPlayerUtility::CBody::SetAutoScaleL(TAutoScaleType aScaleType)
       
  1850 	{
       
  1851 	SetAutoScaleL(aScaleType, EHorizontalAlignCenter, EVerticalAlignCenter);
       
  1852 	}
       
  1853 void CVideoPlayerUtility::CBody::SetAutoScaleL(TAutoScaleType aScaleType, TInt aHorizPos, TInt aVertPos)
       
  1854 	{
       
  1855 	// Leave if Open is not yet called.
       
  1856 	if(!iEventOpenReceived )
       
  1857 		{
       
  1858 		User::Leave(KErrNotReady);
       
  1859 		}	
       
  1860 
       
  1861 #ifdef SYMBIAN_BUILD_GCE
       
  1862 	if (!iGraphicsSurfaceSupported)
       
  1863 		{
       
  1864 		User::LeaveIfError(iVideoPlayControllerExtCustomCommands.SetAutoScale(aScaleType, aHorizPos, aVertPos));
       
  1865 		}
       
  1866 	else
       
  1867 		{
       
  1868 		// Auto scale setting is not sent to controller when graphics surfaces are used.
       
  1869 		// If the surface has been created, perform auto scale with the help of graphics surfaces;
       
  1870 		// otherwise, just store the auto scale info.
       
  1871 		iGlobalAutoScaleType = aScaleType;
       
  1872 		iGlobalHorizPos = aHorizPos;
       
  1873 		iGlobalVertPos = aVertPos;
       
  1874 		
       
  1875 		TInt count = iActiveDisplays.Count();
       
  1876 		
       
  1877 		for (TInt i = 0; i < count; ++i)
       
  1878 			{
       
  1879 			iActiveDisplays[i]->SetAutoScaleL(aScaleType, aHorizPos, aVertPos, iCropRegion);
       
  1880 			}
       
  1881 		}
       
  1882 #else
       
  1883 	User::LeaveIfError(iVideoPlayControllerExtCustomCommands.SetAutoScale(aScaleType, aHorizPos, aVertPos));
       
  1884 #endif // SYMBIAN_BUILD_GCE
       
  1885 	}
       
  1886 
       
  1887 #ifdef SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
  1888 TBool CVideoPlayerUtility::CBody::SubtitlesAvailable()
       
  1889 	{
       
  1890 	if (!iControllerOpen)
       
  1891 		{
       
  1892 		return EFalse;
       
  1893 		}
       
  1894 
       
  1895 	return CMMFSubtitleUtility::SubtitlesAvailable(iController);
       
  1896 	}
       
  1897 
       
  1898 void CVideoPlayerUtility::CBody::EnableSubtitlesL()
       
  1899 	{
       
  1900 	// Check if video file and controller is opened
       
  1901 	__ASSERT_ALWAYS(iControllerOpen, VPUDebugPanicOrLeaveL(EMMFVideoPlayerUtilityFileNotOpened, KErrNotReady));
       
  1902 	// Check if subtitles are already enabled
       
  1903 	__ASSERT_ALWAYS(!iSubtitleUtility, User::Leave(KErrInUse));
       
  1904 	// Check if display window is added
       
  1905 	TBool windowsAdded = EFalse;
       
  1906 	for (TInt i = iActiveDisplays.Count()-1; (i >= 0 && windowsAdded == EFalse); --i)
       
  1907 		{
       
  1908 		CMediaClientVideoDisplayBody* display = iActiveDisplays[i];
       
  1909 		windowsAdded = display->HasWindows();
       
  1910 		}
       
  1911 	__ASSERT_ALWAYS(windowsAdded, VPUDebugPanicOrLeaveL(EMMFVideoPlayerUtilityNoWindowAdded, KErrNotReady));
       
  1912 
       
  1913 
       
  1914 	iSubtitleUtility = CMMFSubtitleUtility::NewL(iController, *iWs);
       
  1915 	TInt err = iSubtitleUtility->EnableSubtitles();
       
  1916 	if (KErrNone != err)
       
  1917 		{
       
  1918 		delete iSubtitleUtility;
       
  1919 		iSubtitleUtility = NULL;
       
  1920 		if (KErrNotSupported == err || KErrNotFound == err)
       
  1921 			{
       
  1922 			// controller does not support subtitles or subtitle source not found,
       
  1923 			// panic client because they should have called SubtitlesAvailable first
       
  1924 			VPUDebugPanicOrLeaveL(EMMFVideoPlayerUtilitySubtitleNotSupported, err);
       
  1925 			}
       
  1926 		
       
  1927 		// leave in release mode or any other error
       
  1928 		User::Leave(err);
       
  1929 		}
       
  1930 
       
  1931 	TBool subtitleEnabled = EFalse;
       
  1932 	TInt count = iActiveDisplays.Count();
       
  1933 	
       
  1934 	// add the windows in the orders that they were added
       
  1935 	for (TInt i = 0; i < count; ++i)
       
  1936 		{
       
  1937 		CMediaClientVideoDisplayBody* display = iActiveDisplays[i];
       
  1938 		err = EnableSubtitles(*display);
       
  1939 		
       
  1940 		if (KErrNone == err)
       
  1941 			{
       
  1942 			subtitleEnabled = ETrue;
       
  1943 			}
       
  1944 		}
       
  1945 
       
  1946 	// no subtitle window was enabled successfully, enable subtitle failed
       
  1947 	if (!subtitleEnabled)
       
  1948 		{
       
  1949 		DisableSubtitles();	// disable subtitle on controller side
       
  1950 		User::Leave(err); // Leave with error returned by last EnableSubtitles call
       
  1951 		}
       
  1952 	}
       
  1953 
       
  1954 void CVideoPlayerUtility::CBody::DisableSubtitles()
       
  1955 	{
       
  1956 	if (iSubtitleUtility)
       
  1957 		{
       
  1958 		iSubtitleUtility->DisableSubtitles();
       
  1959 		
       
  1960 		delete iSubtitleUtility;
       
  1961 		iSubtitleUtility = NULL;
       
  1962 		}
       
  1963 	}
       
  1964 
       
  1965 TArray<TLanguage> CVideoPlayerUtility::CBody::SupportedSubtitleLanguagesL()
       
  1966 	{
       
  1967 	// Check if subtitles have been enabled
       
  1968 	__ASSERT_ALWAYS(iSubtitleUtility, VPUDebugPanicOrLeaveL(EMMFVideoPlayerUtilitySubtitleNotEnabled, KErrNotReady));
       
  1969 
       
  1970 	return iSubtitleUtility->SupportedSubtitleLanguagesL();
       
  1971 	}
       
  1972 
       
  1973 TLanguage CVideoPlayerUtility::CBody::SubtitleLanguageL()
       
  1974 	{
       
  1975 	// Check if subtitles have been enabled
       
  1976 	__ASSERT_ALWAYS(iSubtitleUtility, VPUDebugPanicOrLeaveL(EMMFVideoPlayerUtilitySubtitleNotEnabled, KErrNotReady));
       
  1977 
       
  1978 	return iSubtitleUtility->SubtitleLanguage();
       
  1979 	}
       
  1980 
       
  1981 void CVideoPlayerUtility::CBody::SetSubtitleLanguageL(TLanguage aLanguage)
       
  1982 	{
       
  1983 	// Check if subtitles have been enabled
       
  1984 	__ASSERT_ALWAYS(iSubtitleUtility, VPUDebugPanicOrLeaveL(EMMFVideoPlayerUtilitySubtitleNotEnabled, KErrNotReady));
       
  1985 
       
  1986 	TInt err = iSubtitleUtility->SetSubtitleLanguage(aLanguage);
       
  1987 	if (KErrNotSupported == err)
       
  1988 		{
       
  1989 		// panic on debug because client should call SupportedSubtitleLanguagesL() first
       
  1990 		VPUDebugPanicOrLeaveL(EMMFVideoPlayerUtilitySubtitleLanguageNotSupported, KErrNotSupported);
       
  1991 		}
       
  1992 	User::LeaveIfError(err);
       
  1993 	}
       
  1994 
       
  1995 void CVideoPlayerUtility::CBody::RedrawSubtitle(RWindow& aWindow, const TRect &aRect)
       
  1996 	{
       
  1997 	if (iSubtitleUtility)
       
  1998 		{
       
  1999 		// subtitle is enabled
       
  2000 		RWindow* window = FindWindowWithWsHandle(iActiveDisplays, aWindow.WsHandle());
       
  2001 		if (window) // check that window was added for video playback
       
  2002 			{
       
  2003 			iSubtitleUtility->RedrawSubtitle(aWindow, aRect);
       
  2004 			}
       
  2005 		}
       
  2006 	// else ignore the redraw request
       
  2007 	}
       
  2008 
       
  2009 RWindow* CVideoPlayerUtility::CBody::FindWindowWithWsHandle(const RPointerArray<CMediaClientVideoDisplayBody>& aDisplays, TInt aWsHandle)
       
  2010 	{
       
  2011 	TInt count = aDisplays.Count();
       
  2012 	
       
  2013 	for (TInt i = 0; i < count; ++i)
       
  2014 		{
       
  2015 		CMediaClientVideoDisplayBody* display = aDisplays[i];
       
  2016 		RArray<CMediaClientVideoDisplayBody::TWindowData>& windows = display->Windows();
       
  2017 		TInt pos = windows.Find(aWsHandle, CMediaClientVideoDisplayBody::TWindowData::CompareByWsHandle);
       
  2018 		if (pos >= 0)
       
  2019 			{
       
  2020 			return windows[pos].iWindow2;
       
  2021 			}
       
  2022 		}
       
  2023 		
       
  2024 	return NULL;
       
  2025 	}
       
  2026 
       
  2027 // Update the supplied window with the new clip rect and rotation
       
  2028 // If updating of surface failed, this function leave after restoring the original aWindowData
       
  2029 void CVideoPlayerUtility::CBody::UpdateSurfaceAndSubtitleConfigL(CMediaClientVideoDisplayBody& aDisplay,CMediaClientVideoDisplayBody::TWindowData& aWindowData, const TRect& aClipRect, TVideoRotation aRotation, const TRect& aCropRegion)
       
  2030 	{
       
  2031 	TRect oldClipRect = aWindowData.iClipRect;
       
  2032 	TVideoRotation oldRotation = aWindowData.iRotation;
       
  2033 	
       
  2034 	aWindowData.iClipRect = aClipRect;
       
  2035 	aWindowData.iRotation = aRotation;
       
  2036 	
       
  2037 	if (aDisplay.IsSurfaceCreated())
       
  2038 		{
       
  2039 		TInt err = aDisplay.SetBackgroundSurface(aWindowData, aCropRegion);
       
  2040 		if (KErrNone != err)
       
  2041 			{
       
  2042 			aWindowData.iClipRect = oldClipRect;
       
  2043 			aWindowData.iRotation = oldRotation;
       
  2044 			User::Leave(err);
       
  2045 			}
       
  2046 		}
       
  2047 	
       
  2048 	// Set background was successful or surface was not created, so 
       
  2049 	// update subtitle config if subtitles are enabled
       
  2050 	if (iSubtitleUtility)
       
  2051 		{
       
  2052 		TMMFSubtitleWindowConfig config;
       
  2053 		GetSubtitleConfigFromWindowData(aWindowData, config);
       
  2054 
       
  2055 		iSubtitleUtility->UpdateSubtitleConfig(config);
       
  2056 		}
       
  2057 	}
       
  2058 
       
  2059 void CVideoPlayerUtility::CBody::GetSubtitleConfigFromWindowData(CMediaClientVideoDisplayBody::TWindowData& aWindowData, TMMFSubtitleWindowConfig& aConfig)
       
  2060 	{
       
  2061 	aConfig.iWindowId = aWindowData.iWindow->WsHandle();
       
  2062 	aConfig.iWindowClipRect = aWindowData.iClipRect;
       
  2063 	aConfig.iDisplayMode = aWindowData.iWindow->DisplayMode();
       
  2064 	aConfig.iRotation = aWindowData.iRotation;
       
  2065 	
       
  2066 	}
       
  2067 TInt CVideoPlayerUtility::CBody::EnableSubtitles(CMediaClientVideoDisplayBody& aDisplay)
       
  2068 	{
       
  2069 	TBool windowAdded = EFalse;
       
  2070 	RArray<CMediaClientVideoDisplayBody::TWindowData> windows = aDisplay.Windows();
       
  2071 	
       
  2072  	TInt count = windows.Count();
       
  2073 	TInt err = KErrNone;	
       
  2074 	// add the windows in the orders that they are added
       
  2075 	for (TInt i = 0; i < count; ++i)
       
  2076 		{
       
  2077 		err = AddSubtitleConfig(windows[i]);
       
  2078 		if (KErrNone == err)
       
  2079 			{
       
  2080 			windowAdded = ETrue;
       
  2081 			}
       
  2082 		}
       
  2083 
       
  2084 	// Return the error code returned by the last AddSubtitleConfig call.
       
  2085 	if (!windowAdded)
       
  2086 		{
       
  2087 		return err;
       
  2088 		}
       
  2089 	
       
  2090 	return KErrNone;
       
  2091 	}
       
  2092 
       
  2093 TInt CVideoPlayerUtility::CBody::AddSubtitleConfig(CMediaClientVideoDisplayBody::TWindowData& aWindowData)
       
  2094 	{
       
  2095 	ASSERT(iSubtitleUtility);
       
  2096 	TMMFSubtitleWindowConfig config;
       
  2097 	GetSubtitleConfigFromWindowData(aWindowData, config);
       
  2098 	
       
  2099 	return iSubtitleUtility->AddSubtitleConfig(config);
       
  2100 	}
       
  2101 #endif //SYMBIAN_MULTIMEDIA_SUBTITLE_SUPPORT
       
  2102