os/mm/mmlibs/mmfw/tsrc/mmfunittest/videorenderer/src/testrenderer.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) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include "testrenderer.h"
    17 #include "videoframebuffer.h"
    18 #include "testgceharness.h"
    19 
    20 RTestRendererStep* RTestRendererStep::NewL(const TDesC& aStepName, TBool aTimed)
    21 	{
    22 	RTestRendererStep* self = new (ELeave) RTestRendererStep(aStepName, aTimed);
    23 	return self;
    24 	}
    25 
    26 RTestRendererStep::RTestRendererStep(const TDesC& aStepName, TBool aTimed) :
    27 	iVideoRenderer(NULL),
    28 	iTimed(aTimed)
    29 	{
    30 	iTestStepName = aStepName;
    31 
    32 	// size for buffer created
    33 	iSize.iWidth = 1024;
    34 	iSize.iHeight = 768;
    35 	iVideoFormat.iDataFormat = ERgbRawData;
    36 	iVideoFormat.iRgbFormat = ERgb32bit888;
    37 	}
    38 
    39 void RTestRendererStep::MvroVideoBufferAvailable()
    40 	{
    41 	INFO_PRINTF1(_L("MvroVideoBufferAvailable() callback received"));
    42 	TRAPD(err, FsmL(EBufferAvailable));
    43 	if (err != KErrNone)
    44 		{
    45 		ERR_PRINTF2(_L("FsmL(EBufferAvailable) failed with %d"), err);
    46 		EndTest(EFail);
    47 		}
    48 	}
    49 
    50 void RTestRendererStep::MvroBufferDisplayed(TInt aBufferId, const TTime& aTime)
    51 	{
    52 	INFO_PRINTF2(_L("MvroBufferDisplayed() callback received aBufferId=%d"), aBufferId);
    53 	iBufferId = aBufferId;
    54 	iDisplayedTime = aTime;
    55 	TRAPD(err, FsmL(EBufferDisplayed));
    56 	if (err != KErrNone)
    57 		{
    58 		ERR_PRINTF2(_L("FsmL(EBufferDisplayed) failed with %d"), err);
    59 		EndTest(EFail);
    60 		}
    61 	}
    62 
    63 void RTestRendererStep::MvroBufferSkipped(TInt aBufferId)
    64 	{
    65 	INFO_PRINTF2(_L("MvroBufferSkipped() callback received aBufferId=%d"), aBufferId);
    66 	iBufferId = aBufferId;
    67 	TRAPD(err, FsmL(EBufferSkipped));
    68 	if (err != KErrNone)
    69 		{
    70 		ERR_PRINTF2(_L("FsmL(EBufferSkipped) failed with %d"), err);
    71 		EndTest(EFail);
    72 		}
    73 	}
    74 
    75 TVerdict RTestRendererStep::DoTestStepPreambleL()
    76 	{
    77     // Install the Active Scheduler
    78     iActiveScheduler = new(ELeave) CActiveScheduler;
    79     CActiveScheduler::Install(iActiveScheduler);
    80 	iActiveSchedulerStarted = EFalse;
    81 		
    82     iBuffAvailCallback = 0;
    83     iBuffDisplayCallback = 0;
    84     iBuffSkipCallback = 0;
    85 
    86     // The following is required because of the panic tests.
    87     // When a thread panics the global pointer is not reset to NULL
    88     // and the following test fails because the pointer is hanging.
    89     // When testframework creates a thread to run the test step it also
    90     // defines a heap and the default process heap is not used. Therefore
    91     // when the thread dies the heap is no longer available.
    92 	CTestGCEHarness::ResetGlobalPointer();
    93     
    94     // Initialise Window server objects
    95     InitWservL();
    96 
    97     return EPass;
    98 	}
    99 
   100 TVerdict RTestRendererStep::DoTestStepPostambleL()
   101 	{
   102 	CActiveScheduler::Install(NULL);
   103 	delete iActiveScheduler;
   104     iActiveScheduler = NULL;
   105 
   106     // Destroy Window server objects
   107     DeInitWserv();
   108 
   109     return EPass;
   110 	}
   111 
   112 void RTestRendererStep::InitWservL()
   113     {
   114     TInt err = iWs.Connect();
   115     if (err != KErrNone)
   116         {
   117         // Access violation if ws is null
   118         ERR_PRINTF1(_L("Cannot test, no window server available"));
   119         User::Leave(err);
   120         }
   121 
   122     iScreen = new (ELeave) CWsScreenDevice(iWs); // make device for this session
   123     User::LeaveIfError(iScreen->Construct()); // and complete its construction
   124 
   125     iRootWindow = RWindowGroup(iWs);
   126     User::LeaveIfError(iRootWindow.Construct((TUint32)this, ETrue));
   127 
   128     iWindow = new(ELeave) RWindow(iWs);
   129     User::LeaveIfError(((RWindow*)iWindow)->Construct(iRootWindow,((TUint32)(this)) + 1));
   130     iWindow->SetExtent(TPoint(0,0), TSize(100,100));
   131     iWindow->SetVisible(ETrue);
   132     iWindow->SetRequiredDisplayMode(EColor16MA);
   133     iWindow->Activate();
   134     }
   135 
   136 void RTestRendererStep::DeInitWserv()
   137     {
   138     if (iWindow)
   139         {
   140         iWindow->Close();
   141         delete iWindow;
   142         iWindow = NULL;
   143         }
   144     iRootWindow.Close();
   145     delete iScreen;
   146     iScreen = NULL;
   147     iWs.Flush();
   148     iWs.Close();
   149     }
   150 
   151 TInt RTestRendererStep::SetBackgroundSurface(TSurfaceId& id)
   152 	{
   153 	TInt err = iWindow->SetBackgroundSurface(id);
   154 	iWs.Finish();
   155 	return err;
   156 	}
   157 
   158 void RTestRendererStep::RemoveBackgroundSurface()
   159 	{
   160 	iWindow->RemoveBackgroundSurface(ETrue);
   161 	}
   162 
   163 TVerdict RTestRendererStep::DoTestStepL()
   164 	{
   165 	__UHEAP_MARK;
   166 	
   167     // Call the state handler from IDLE state
   168     TRAPD(err, FsmL(EStartTest));
   169     if (err == KErrNone && iTestStepResult == EPass)
   170         {
   171         // Start the scheduler - Done only once !
   172     	iActiveSchedulerStarted = ETrue;
   173         CActiveScheduler::Start();    
   174         }
   175     else if (err != KErrNone)
   176     	{
   177         ERR_PRINTF2(_L("FsmL(EStartTest) leave with %d"), err);
   178     	iTestStepResult = EFail;
   179     	}
   180 
   181 	delete iVideoRenderer;
   182 	iVideoRenderer = NULL;
   183 
   184     // cleanup test harness
   185     CTestGCEHarness::Remove();
   186 	
   187 	__UHEAP_MARKEND;
   188 
   189     return iTestStepResult;
   190 	}
   191 
   192 void RTestRendererStep::FsmL(TTestRendererEvents aEventCode)
   193 	{
   194     switch (aEventCode)
   195         {
   196         case EStartTest:
   197         	{
   198         	iFsmState = EStateCreate;
   199         	TInt numBuffers = 1;
   200         	
   201         	INFO_PRINTF2(_L("CVideoRenderer::NewL() Timed=%d"), iTimed);
   202         	CTestGCEHarness::NewL(numBuffers);
   203             iVideoRenderer = CVideoRenderer::NewL(*this, iTimed);
   204             
   205             INFO_PRINTF1(_L("iVideoRenderer->GetSupportedFormatsL()"));
   206             RArray<TUncompressedVideoFormat> expectedArray;
   207             CleanupClosePushL(expectedArray);
   208             TUncompressedVideoFormat format;
   209             format.iDataFormat = ERgbRawData;
   210     		format.iRgbFormat = ERgb16bit444;
   211     		expectedArray.AppendL(format); // append EVideoRendererPixelFormatXRGB_4444
   212     		format.iDataFormat = ERgbRawData;
   213     		format.iRgbFormat = ERgb16bit565;
   214     		expectedArray.AppendL(format); // append EVideoRendererPixelFormatRGB_565
   215     		format.iDataFormat = ERgbRawData;
   216     		format.iRgbFormat = ERgb32bit888;
   217     		expectedArray.AppendL(format); // append EVideoRendererPixelFormatXRGB_8888:
   218 
   219     		RArray<TUncompressedVideoFormat> array;
   220             CleanupClosePushL(array);
   221         	iVideoRenderer->GetSupportedFormatsL(array);
   222         	TInt expectedCount = expectedArray.Count();
   223         	TESTL(array.Count() == expectedCount);
   224         	for (TInt i = 0; i < expectedCount; i++)
   225         		{
   226         		TESTL(expectedArray[i] == array[i]);
   227         		}
   228 
   229         	CleanupStack::PopAndDestroy(2, &expectedArray);
   230         	CreateSurfaceL(numBuffers);
   231         	
   232             break;
   233         	}
   234         case EBufferAvailable:
   235         	iBuffAvailCallback++;
   236         	if (iFsmState == EStateCreate && iBuffAvailCallback == 1)
   237         		{
   238 	            iFsmState = EStateUpdate;
   239 
   240 	        	// map surface to display
   241 	            TInt err = SetBackgroundSurface(iSurfaceId);
   242 	            if (err != KErrNone)
   243 	            	{
   244 		        	ERR_PRINTF2(_L("RWindow::SetBackgroundSurface() returned %d"), err);
   245                     EndTest(EFail);
   246                     break;
   247 	            	}
   248 
   249 	        	TTime presentationTime;
   250 	        	presentationTime.UniversalTime();
   251 	        	TTimeIntervalMicroSeconds microsec(500000); // use half a second delay
   252 	        	presentationTime += microsec;
   253 	        	GetNextBufferAndSubmitUpdateL(0, KRgbGreen, presentationTime);
   254         		}
   255         	else if (iFsmState == EStateUpdate && iBuffAvailCallback == 2)
   256         		{
   257 	        	iFsmState = EStateReleaseBuffer;
   258 
   259 	        	// buffer is available again after update;
   260         	    // try to get next buffer
   261         	    TVideoFrameBuffer* buffer;
   262 	            INFO_PRINTF1(_L("iVideoRenderer->NextBuffer() after update"));
   263 	        	buffer = iVideoRenderer->NextBuffer();
   264 	        	TESTL(buffer != NULL);
   265 	            INFO_PRINTF1(_L("iVideoRenderer->ReleaseBuffer()"));
   266 	        	iVideoRenderer->ReleaseBuffer(buffer);
   267         		}
   268         	else if (iFsmState == EStateReleaseBuffer)
   269         		{
   270         		if (iBuffDisplayCallback == 1)
   271         			{
   272             		// both release buffer callback and display callback are received, test complete with pass
   273                 	EndTest(EPass);
   274         			}
   275         		// else continue waiting for more callback
   276         		}
   277         	else
   278         		{
   279         		ERR_PRINTF2(_L("State %d was not expected when handling buffer available event."), iFsmState);
   280             	EndTest(EFail);
   281         		}
   282 
   283         	break;
   284         case EBufferDisplayed:
   285         	iBuffDisplayCallback++;
   286         	if ((iFsmState != EStateUpdate && iFsmState != EStateReleaseBuffer) ||
   287         		iBufferId != 0)
   288         		{
   289         		// not in a valid state
   290         		ERR_PRINTF2(_L("State %d was not expected when handing buffer displayed event."), iFsmState);
   291             	EndTest(EFail);
   292         		}
   293         	if (iFsmState == EStateReleaseBuffer && iBuffAvailCallback == 3)
   294         		{
   295         		// both release buffer callback and display callback are received, test complete with pass
   296         		EndTest(EPass);
   297         		}
   298         	// otherwise, haven't received release callback yet, continue waiting
   299         	break;
   300         default:
   301 			// unexpected event
   302 			ERR_PRINTF2(_L("Unexpected event code %d in RTestRendererStep::FsmL"), aEventCode);
   303         	EndTest(EFail);
   304         	break;
   305         }
   306 	}
   307 
   308 void RTestRendererStep::EndTest(TVerdict aVerdict)
   309 	{
   310     iTestStepResult = aVerdict;
   311     if (iActiveSchedulerStarted)
   312     	{
   313     	CActiveScheduler::Stop();
   314     	}
   315 	}
   316 
   317 void RTestRendererStep::CreateRendererAndSurfaceL(TInt aNumBuffers)
   318 	{
   319 	INFO_PRINTF2(_L("CVideoRenderer::NewL() Timed=%d"), iTimed);
   320 	CTestGCEHarness::NewL(aNumBuffers);
   321 	iVideoRenderer = CVideoRenderer::NewL(*this, iTimed);
   322 	CreateSurfaceL(aNumBuffers);
   323 	}
   324 
   325 void RTestRendererStep::CreateSurfaceL(TInt aNumBuffers)
   326 	{
   327 	INFO_PRINTF1(_L("iVideoRenderer->CreateSurfaceL()"));
   328 	iVideoRenderer->CreateSurfaceL(iSize, aNumBuffers, iVideoFormat, iSurfaceId);
   329 	}
   330 
   331 void RTestRendererStep::GetNextBufferAndSubmitUpdateL(TInt aExpectedBufId, TRgb aColor, const TTime& aPresentationTime)
   332 	{
   333     TVideoFrameBuffer* buffer = GetNextBufferL(aExpectedBufId, aColor);
   334     INFO_PRINTF1(_L("iVideoRenderer->UpdateBuffer()"));
   335 	iVideoRenderer->UpdateBuffer(buffer, aPresentationTime);
   336 	}
   337 
   338 TVideoFrameBuffer* RTestRendererStep::GetNextBufferL(TInt aExpectedBufId, TRgb aColor)
   339 	{
   340 	INFO_PRINTF1(_L("iVideoRenderer->NextBuffer()"));
   341 	TVideoFrameBuffer* buffer;
   342 	buffer = iVideoRenderer->NextBuffer();
   343 	TESTL(buffer != NULL);
   344 	TESTL(buffer->Format() == iVideoFormat);
   345 	TESTL(buffer->Stride() == iSize.iWidth *  4); // 4 bite per pixel for ERgb32bit888
   346 	TESTL(buffer->BufferId() == aExpectedBufId);
   347 	TESTL(buffer->Buffer() != NULL);
   348 	
   349 	TInt bufSize = buffer->Stride() * iSize.iHeight;
   350 	Mem::Fill(buffer->Buffer(), bufSize, aColor.Internal());
   351 	return buffer;
   352 	}
   353 
   354 RTestRendererReplaceStep* RTestRendererReplaceStep::NewL(const TDesC& aStepName, TBool aTimed)
   355 	{
   356 	RTestRendererReplaceStep* self = new (ELeave) RTestRendererReplaceStep(aStepName, aTimed);
   357 	return self;
   358 	}
   359 
   360 RTestRendererReplaceStep::RTestRendererReplaceStep(const TDesC& aStepName, TBool aTimed) :
   361 	RTestRendererStep(aStepName, aTimed)
   362 	{
   363 	}
   364 
   365 void RTestRendererReplaceStep::FsmL(TTestRendererEvents aEventCode)
   366 	{
   367 	switch (aEventCode)
   368 	    {
   369 	    case EStartTest:
   370 	    	iFsmState = EStateCreate;
   371 	        CreateRendererAndSurfaceL(1);
   372 	        break;
   373 	    case EBufferAvailable:
   374 	    	iBuffAvailCallback++;
   375 	    	if (iFsmState == EStateCreate && iBuffAvailCallback == 1)
   376 	    		{
   377 	            iFsmState = EStateUpdate;
   378 
   379     	    	// received the first callback, map surface to display
   380 	            TInt err = SetBackgroundSurface(iSurfaceId);
   381 	            TESTL(err == KErrNone);
   382 
   383 	            // send the buffer
   384 	            TTime presentationTime(0);
   385 	            GetNextBufferAndSubmitUpdateL(0, KRgbGreen, presentationTime);
   386 	    		}
   387 	    	else if (iFsmState == EStateUpdate)
   388 	    		{
   389 	    		if (iBuffDisplayCallback == 1 && iBuffAvailCallback == 2)
   390 	    			{
   391 	    			iFsmState = EStateReplaceSurface;
   392 	    			ReplaceSurfaceL();
   393 	    			}
   394 	    		}
   395 	    	else if (iFsmState == EStateReplaceSurface && iBuffAvailCallback == 1)
   396 	    		{
   397     	    	// received the first callback, map surface to display
   398 	            TInt err = SetBackgroundSurface(iSurfaceId);
   399 	            if (err != KErrNone)
   400 	            	{
   401 		        	ERR_PRINTF2(_L("RWindow::SetBackgroundSurface() returned %d"), err);
   402                     EndTest(EFail);
   403 	            	}
   404 	    		}
   405 	    	else if (iFsmState == EStateReplaceSurface && iBuffAvailCallback == 2)
   406             	{
   407 	            iFsmState = EStateUpdateAfterReplace;
   408 
   409 	            // send the buffer
   410 	            
   411 	            TTime presentationTime1;
   412 	            presentationTime1.UniversalTime();
   413 	            TTimeIntervalMicroSeconds delay(500);
   414 	            TTime presentationTime2 = presentationTime1 + delay;
   415 	            
   416 	            GetNextBufferAndSubmitUpdateL(0, KRgbGreen, presentationTime1);
   417 	            GetNextBufferAndSubmitUpdateL(1, KRgbGreen, presentationTime2);
   418             	}
   419 	    	else if (iFsmState == EStateUpdateAfterReplace)
   420 	    		{
   421 	    		if (iBuffDisplayCallback == 2 && iBuffAvailCallback == 3)
   422 	    			{
   423 	    			EndTest(EPass);
   424 	    			}
   425 	    		// else continue waiting for more callback
   426 	    		}
   427 	    	else
   428 	    		{
   429 	    		// unexpected state, fail test
   430 	    		ERR_PRINTF2(_L("State %d was not expected when handling buffer available event."), iFsmState);
   431 	        	EndTest(EFail);
   432 	    		}
   433 	
   434 	    	break;
   435 	    case EBufferDisplayed:
   436 	    	iBuffDisplayCallback++;
   437 	    	if (iFsmState == EStateUpdate && iBuffDisplayCallback == 1 && iBufferId == 0)
   438 	    		{
   439 	    		// receive display callback
   440 	        	if (iBuffAvailCallback == 2)
   441 	        		{
   442 	    			iFsmState = EStateReplaceSurface;
   443 	    			ReplaceSurfaceL();
   444 	        		}
   445 	    		}
   446 	    	else if (iFsmState == EStateUpdateAfterReplace && iBuffDisplayCallback == 1 && iBufferId == 0)
   447 	    		{
   448 	    		// receive display callback
   449 	    		}
   450 	    	else if (iFsmState == EStateUpdateAfterReplace && iBuffDisplayCallback == 2 && iBufferId == 1)
   451 	    		{
   452 	        	if (iBuffAvailCallback == 3)
   453 	        		{
   454 	    			EndTest(EPass);
   455 	        		}
   456 	        	// else haven't received all callback, continue waiting
   457 	    		}
   458 	    	else
   459 	    		{
   460 	    		// not in a valid state
   461 	    		ERR_PRINTF2(_L("State %d was not expected when handling buffer displayed event."), iFsmState);
   462 	        	EndTest(EFail);
   463 	    		}
   464 	    	break;
   465 	    case EBufferSkipped:
   466 	    	ERR_PRINTF1(_L("Frame unexpectedly skipped"));
   467         	EndTest(EFail);
   468 	    	break;
   469 	    }
   470 	}
   471 
   472 void RTestRendererReplaceStep::ReplaceSurfaceL()
   473 	{
   474 	// reset the number of callback
   475 	iBuffDisplayCallback = 0;
   476 	iBuffAvailCallback = 0;
   477 	
   478 	RemoveBackgroundSurface();
   479 	
   480 	// received all expected callback for update
   481 	// destroy surface and create new one for testing replace surface
   482 	INFO_PRINTF1(_L("iVideoRenderer->DestroySurface()"));
   483 	iVideoRenderer->DestroySurface(iSurfaceId);
   484 	TInt buffers = 2;
   485 	CTestGCEHarness::ResetBuffersL(buffers);
   486 	CreateSurfaceL(buffers);
   487 	}
   488 
   489 /**
   490 Standard static NewL() taking a callback function
   491 */
   492 CCallBackTimer* CCallBackTimer::NewL(TCallBack aCallBack, TPriority aPriority)
   493 	{
   494 	CCallBackTimer* self = new(ELeave) CCallBackTimer(aCallBack, aPriority);
   495 	CleanupStack::PushL(self);
   496 	self->ConstructL();
   497 	CleanupStack::Pop(self);
   498 	return self;
   499 	}
   500 
   501 /**
   502 Private c'tor
   503 */
   504 CCallBackTimer::CCallBackTimer(TCallBack aCallBack, TPriority aPriority) :
   505 	CTimer(aPriority), iCallBack(aCallBack)
   506 	{
   507 	CActiveScheduler::Add(this);
   508 	}
   509 
   510 /*
   511 Callback on timer complete
   512 */
   513 void CCallBackTimer::RunL()
   514 	{
   515 	iCallBack.CallBack();
   516 	}