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