os/mm/mdfdevvideoextensions/nga_mdf_postprocessor_shai/src/NGAPostProcHwDevice.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     5 * under the terms of "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description:
    15 *
    16 */
    17 
    18 
    19 #include "NGAPostProcHwDevice.h"
    20 #include "NGAPostProcSessionManager.h"
    21 #include "NGAPostProcSurfaceHandler.h"
    22 
    23 //currently this uid only used if not under WINSCW environment since the only hw to use is bridge
    24 #define EStUidPixelFormatYUV_420MB  0x2001FBC1
    25 // post-processor info
    26 const TUid KUidVideoPostProcHwDevice = {KUidNGAPostProcHwDeviceImplUid};
    27 _LIT(KManufacturer, "Nokia Inc.");
    28 _LIT(KIdentifier, "Nokia S60 Video Post Processor Hardware Device Plugin");
    29 
    30 // --- Constants ---
    31 const TInt KMaxVBMBuffers      			= 4;
    32 const TInt KMinVBMInputWidth   			= 32; 
    33 const TInt KMinVBMInputHeight  			= 32;
    34 const TInt KMaxVBMInputWidth   			= 1280; 
    35 const TInt KMaxVBMInputHeight  			= 720;
    36 const TInt KRenderAhead 	     		= 50000;     
    37 const TInt KMaxRenderDelay     			= 50000;
    38 const TInt KPostingOfset       			= 0;    
    39 const TInt KColorConversionBuffers  	= 3;
    40 const TInt KMaxBuffersGceCanHold    	= 3;
    41 const TInt KDefPlayRate					= 100;
    42 const TInt KMaxAllowedSkipInNFrames 	= 40;
    43 #ifdef __cplusplus
    44 extern "C"
    45 {
    46 #endif
    47 
    48 int32 gColorConvYUVtoYUV422Int (tBaseVideoFrame *yuv420Frame, tBaseVideoFrame* yuv422Frame,
    49 							   uint8 outClrFmt, int16 stride); 
    50 
    51 int32 Emz_VDec_gColorConv_YUVtoRGB ( 
    52 	  tBaseVideoFrame *srcImage, uint8 *dstImage, tWndParam *srcWindow, 
    53 	  tWndParam *dstWindow, uint8 srcImageFormat, uint8 dstImageFormat,
    54 	  uint8 colorConvScheme);
    55 		 	  
    56 #ifdef __cplusplus
    57 }
    58 #endif
    59 
    60 //**************************************************
    61 
    62 CMMFVideoPostProcHwDevice* CNGAPostProcHwDevice::NewL() 
    63 { 
    64    PP_DEBUG(_L("CNGAPostProcHwDevice::NewL() ++"));
    65 
    66     CNGAPostProcHwDevice* self = new (ELeave) CNGAPostProcHwDevice; 
    67     CleanupStack::PushL(self);
    68     self->ConstructL(); 
    69     CleanupStack::Pop();
    70 
    71    PP_DEBUG(_L("CNGAPostProcHwDevice::NewL() --"));
    72     return (CMMFVideoPostProcHwDevice*)self; 
    73 }
    74 
    75 void CNGAPostProcHwDevice::ConstructL() 
    76 { 
    77    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::ConstructL() ++"), this);
    78     
    79     // support for VBM buffer interface
    80     iVBMBufferOptions.iNumInputBuffers  = KMaxVBMBuffers; 
    81     iVBMBufferOptions.iBufferSize = TSize(KMaxVBMInputWidth, KMaxVBMInputHeight);
    82     iPostingTimer = CNGAPostProcTimer::NewL(*this);
    83     User::LeaveIfError(iWsSession.Connect());
    84     
    85     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::ConstructL() --"), this);
    86 }
    87 
    88 CNGAPostProcHwDevice::CNGAPostProcHwDevice() 
    89         :   iProxy(NULL), 
    90             iInputDecoderDevice(NULL),
    91             iCurrentPlaybackPosition(TTimeIntervalMicroSeconds(0)),
    92             iPPState(EInitializing),
    93             iSurfaceHandler(NULL),
    94             iSessionManager(NULL),
    95             iIsInputEnded(EFalse),
    96             iPostingTimer(NULL),
    97             iFirstPictureUpdated(EFalse),
    98             iUsingExternalSurface(EFalse),
    99             iIsColorConversionNeeded(EFalse),
   100             iSurfaceCreatedEventPublished(EFalse),
   101             iOverflowPictureCounter(0),
   102             iVideoFrameBufSize(0),
   103             iResourceLost(EFalse),
   104             iRedrawDone(EFalse),
   105 			iRedrawSurfaceInUse(EFalse),
   106             iVBMObserver(NULL),
   107             iVBMEnabled(EFalse),        
   108             count(0),
   109             iSurfaceMask(surfaceHints::EAllowAllExternals),
   110             iSurfaceKey(TUid::Uid(surfaceHints::KSurfaceProtection)),
   111             iVideoSurfaceObserver(NULL),
   112             iVPObserver(NULL),
   113             iPicSize(0,0),
   114 			iAspectRatioNum(1),
   115 			iAspectRatioDenom(1),
   116             iStepFrameCount(0),
   117             iPlayRate(KDefPlayRate),
   118             iKeyFrameMode(EFalse),
   119             iFPObserver(NULL),
   120             iIsExternalChunk(EFalse)
   121 {
   122 	iSurfaceId 		 = TSurfaceId::CreateNullId();
   123 
   124 #if defined __WINSCW__ 
   125 	iAttributes().iPixelFormat    = EUidPixelFormatYUV_422Interleaved;
   126 #else    
   127 	iAttributes().iPixelFormat    = (TUidPixelFormat) EStUidPixelFormatYUV_420MB;
   128 #endif
   129 }
   130 
   131 CNGAPostProcHwDevice::~CNGAPostProcHwDevice()
   132 {
   133    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::~CNGAPostProcHwDevice() ++"), this);
   134    	if (iSessionManager)
   135     {
   136         iSessionManager->CancelNotifiers();
   137         delete iSessionManager;
   138         iSessionManager = NULL;
   139     }
   140    	
   141    	while (iSupportedInputFormats.Count()>0)
   142     {
   143 		iSupportedInputFormats.Remove(0);
   144     }
   145     
   146    	while (iProcessQ.Count()>0)
   147     {
   148 		iProcessQ.Remove(0);
   149     }
   150 
   151    	if(iPostingTimer)
   152     {
   153     	iPostingTimer->Cancel();
   154         delete iPostingTimer;
   155         iPostingTimer = NULL;
   156     }
   157     
   158     while (iVBMBufferReferenceQ.Count()>0)
   159     {
   160         TVideoPicture* pic = iVBMBufferReferenceQ[0];
   161         iVBMBufferReferenceQ.Remove(0);
   162         if (iColorConversionQ.Count()>0)
   163     	{
   164 	        iColorConversionQ.Remove(0);
   165 	    }
   166 
   167         if (pic->iHeader) delete pic->iHeader;
   168         delete pic->iData.iRawData;
   169         delete pic;
   170     }
   171     
   172     iSupportedInputFormats.Reset();
   173     iSupportedInputFormats.Close();
   174     
   175     iVBMBufferReferenceQ.Reset();
   176     iVBMBufferReferenceQ.Close();
   177     
   178     iColorConversionQ.Reset();
   179     iColorConversionQ.Close();
   180     
   181     iVBMBufferQ.Reset();
   182     iVBMBufferQ.Close();
   183     
   184     iProcessQ.Reset();
   185     iProcessQ.Close();
   186         
   187     iInputQ.Reset();
   188     iInputQ.Close();
   189     
   190     if (iSurfaceHandler)
   191     {
   192     	if(!iSurfaceId.IsNull())
   193     	{
   194     		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::UnregisterSurface"), this);
   195 			TInt numScreens = iWsSession.NumberOfScreens();
   196     		for(TInt i=0;i < numScreens;i++)
   197     		{
   198     			iWsSession.UnregisterSurface(i, iSurfaceId);
   199     		}
   200     		iWsSession.Flush();
   201         	TInt err = iSurfaceHandler->DestroySurface(iSurfaceId);
   202     	}
   203         delete iSurfaceHandler;
   204         iSurfaceHandler = NULL;
   205     }
   206     
   207     iWsSession.Close();
   208     if(!iIsExternalChunk)
   209     {
   210         iChunk.Close();
   211     }
   212     
   213     RDebug::Printf("------ Statistics of Post Processor ------");
   214     RDebug::Printf("    Pictures Received : %d", iPictureCounters.iTotalPictures);
   215     RDebug::Printf("    Pictures Displayed: %d", iPictureCounters.iPicturesDisplayed);
   216     RDebug::Printf("    Pictures Skipped  : %d", iPictureCounters.iPicturesSkipped);
   217     RDebug::Printf("    Pictures overflow : %d", iOverflowPictureCounter);
   218     RDebug::Printf("------------------------------------------");
   219     
   220    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:~() --"), this);
   221 }
   222 
   223 void CNGAPostProcHwDevice::SetInputFormatL(const TUncompressedVideoFormat&  aFormat) 
   224 { 
   225    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetInputFormatL() Pattern= %x ++"), this, aFormat.iYuvFormat.iPattern);
   226     if (iPPState != EInitializing)
   227     {
   228 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetInputFormatL() FAILED: Unexpected state"), this);
   229         User::Leave(KErrNotReady);
   230     }
   231 
   232 		iVideoFormat = aFormat; 
   233 		if( ((iVideoFormat.iYuvFormat.iPattern == EYuv420Chroma1) ||
   234 			(iVideoFormat.iYuvFormat.iPattern == EYuv420Chroma2) ||
   235     		(iVideoFormat.iYuvFormat.iPattern == EYuv420Chroma3) ))
   236 		{
   237 			iVideoFormat.iYuvFormat.iCoefficients  	     = EYuvBt709Range1;
   238     		iVideoFormat.iYuvFormat.iPattern       	     = EYuv422Chroma1;
   239     		iVideoFormat.iYuvFormat.iDataLayout          = EYuvDataInterleavedBE;
   240 			
   241 #if defined __WINSCW__				
   242 				iIsColorConversionNeeded = ETrue; 
   243 #else
   244 				iAttributes().iPixelFormat = (TUidPixelFormat) EStUidPixelFormatYUV_420MB;
   245 #endif
   246 		}	
   247 
   248    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetInputFormatL() WARNING: -- Not Found!"), this);
   249 }
   250 
   251 
   252 void CNGAPostProcHwDevice::SetInputDevice(CMMFVideoDecodeHwDevice* aDevice) 
   253 { 
   254    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetInputDevice() ++"), this);
   255 
   256     if (iPPState != EInitializing)
   257     {
   258 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetInputDevice() FAILED: unexpected state"), this);
   259         return;
   260 	}
   261 
   262     iInputDecoderDevice = aDevice;
   263 
   264    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetInputDevice() --"), this);
   265 }
   266 
   267 void CNGAPostProcHwDevice::GetOutputFormatListL(RArray<TUncompressedVideoFormat>& ) 
   268 { 
   269    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:GetOutputFormatListL() ++"), this);
   270 
   271 
   272 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:GetOutputFormatListL() --"), this);
   273 }
   274 
   275 void CNGAPostProcHwDevice::SetOutputFormatL(const TUncompressedVideoFormat&  ) 
   276 {
   277    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetOutputFormatL() ++"), this);
   278 
   279 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetOutputFormatL() --"), this);
   280 }
   281 
   282 void CNGAPostProcHwDevice::SetClockSource(MMMFClockSource* aClock) 
   283 { 
   284    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetClockSource() ++"), this);
   285     
   286     if (iPPState != EInitializing)
   287     {
   288 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetClockSource() FAILED: Unexpected state"), this);
   289         return;
   290 	}
   291     iClockSource = aClock;
   292 
   293    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetClockSource() --"), this);
   294 }
   295 
   296 void CNGAPostProcHwDevice::SetVideoDestScreenL(TBool /*aScreen*/) 
   297 { 
   298    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetVideoDestScreenL() ++"), this);
   299 
   300    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetVideoDestScreenL() --"), this);
   301 }
   302 
   303 void CNGAPostProcHwDevice::SetProxy(MMMFDevVideoPlayProxy& aProxy) 
   304 { 
   305    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetProxy() ++"), this);
   306 
   307     if (iPPState != EInitializing)
   308     {
   309 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetProxy() FAILED: Unexpected state"), this);
   310         return;
   311 	}
   312 
   313     iProxy = &aProxy;
   314 
   315    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetProxy() --"), this);
   316 }
   317 
   318 void CNGAPostProcHwDevice::Initialize() 
   319 {
   320    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Initialize ++"));
   321 	TInt err = KErrNone;
   322 
   323     if (iPPState != EInitializing)
   324     {
   325 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Initialize() FAILED: Unexpected state"), this);
   326         if (iProxy)
   327 		{
   328 			iProxy->MdvppInitializeComplete(this, KErrNotReady);
   329 		}
   330 		return;
   331 	}
   332 	if (!iSurfaceHandler)
   333     {
   334     	TRAP(err, iSurfaceHandler = CNGAPostProcSurfaceHandler::NewL());
   335     	if (err != KErrNone)
   336     	{
   337     	   PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Initialize -- failed to create SurfaceHandler."), this);
   338     	    if (iProxy)
   339 			{
   340 				iProxy->MdvppInitializeComplete(this, err);
   341 			}
   342 			return;
   343     	}
   344     }
   345     if (!iSessionManager)
   346     {
   347     	TRAP(err, iSessionManager = CNGAPostProcSessionManager::NewL());
   348     	if (err != KErrNone)
   349     	{
   350     	   PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Initialize -- failed to create SessionManager."), this);
   351     	    if (iProxy)
   352 			{
   353 				iProxy->MdvppInitializeComplete(this, err);
   354 			}
   355 			return;
   356     	}
   357     	iSessionManager->SetObserver(*this);
   358     }
   359 
   360   	if (iInputDecoderDevice)
   361 	{
   362 		MMmfVideoResourceHandler* handler = NULL;
   363 		handler = (MMmfVideoResourceHandler*)iInputDecoderDevice->CustomInterface(KUidMmfVideoResourceManagement);
   364 		if (handler)
   365 		{
   366 			handler->MmvrhSetObserver((MMmfVideoResourceObserver*)this);
   367 		}
   368 		else
   369 		{
   370 			PP_DEBUG(_L("ppHwDev[%x]:Initialize() decoder yet to implement MMmfVideoResourceHandler CI"), this);
   371 		}
   372 		
   373 		MMmfVideoPropertiesNotifier* VPHandler = NULL;
   374 		VPHandler = (MMmfVideoPropertiesNotifier*)iInputDecoderDevice->CustomInterface(KUidMmfVideoPropertiesManagement);
   375 		if (VPHandler)
   376 		{
   377 			PP_DEBUG(_L("ppHwDev[%x]:Initialize() Register for video property changes"), this);
   378 			VPHandler->MmvpnSetObserver((MMmfVideoPropertiesObserver*)this);
   379 		}
   380 		else
   381 		{
   382 			PP_DEBUG(_L("ppHwDev[%x]:Initialize() decoder yet to implement MMmfVideoPropertiesNotifier CI"), this);
   383 		}
   384 	}
   385 		
   386     // Initialize picture counters
   387 	iPictureCounters.iPicturesSkipped 	= 0;
   388 	iPictureCounters.iPicturesDisplayed = 0;
   389 	iPictureCounters.iTotalPictures = 0;
   390 	iOverflowPictureCounter = 0;
   391 	
   392 	iPPState = EInitialized;
   393 	if(iPostInitializeResponse)
   394 	{
   395 		
   396 		TRAP(err, iPostInitializeResponse->MmpirPostInitializeResponseL());
   397 	}
   398 	
   399 	if(!err)
   400 	{
   401 		TRAP(err, iSessionManager->CreateNotifierL(iInfo().iBuffers));
   402 	}
   403 	else
   404 	{
   405 		iPPState = EInitializing;
   406 	}
   407 	
   408 	if (iProxy)
   409 	{
   410 		iProxy->MdvppInitializeComplete(this, err);
   411 	}
   412    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Initialize --"), this);
   413 }
   414 
   415 void CNGAPostProcHwDevice::WritePictureL(TVideoPicture* aPicture) 
   416 { 
   417 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:WritePicture bufId = %d"), this,GetID(aPicture));
   418 	TVideoPicture* pic;
   419 	if (iPPState==EInitializing || iPPState==EStopped || iIsInputEnded)
   420     {
   421 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:WritePictureL() FAILED: Unexpected state"), this);
   422         User::Leave(KErrNotReady);
   423 	}
   424 
   425     if(!aPicture)
   426     {
   427 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:WritePictureL() FAILED: Invalid argument"), this);
   428 		User::Leave(KErrArgument);
   429 	}
   430 	pic = aPicture;	
   431 	iPictureCounters.iTotalPictures++;
   432 	if((iPPState != EPlaying) && (iFirstPictureUpdated))
   433 	{
   434 	//If decoder is fast enough, it can happen between Initialize->Start time gap between 
   435 	//DecodeHwDevice and PostProc_HwDevice. OR between Pause->Resume time gap as well.
   436 		AddToQ(pic);
   437 	}
   438 	else if( iInputQ.Count() > 0 )
   439 	{
   440 		AddToQ(pic);
   441 		AttemptToPost();
   442 	}
   443 	else
   444 	{
   445 		TTimeToPost timeToPost = EPostIt;
   446 		TInt64 delta = 0;
   447 	    if(iFirstPictureUpdated)
   448 		{
   449 			timeToPost = (TTimeToPost)IsTimeToPost(pic, delta);
   450 			if(!IsGceReady())
   451 		    {  
   452 				PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:WritePictureL GCE not ready"), this );
   453 				if(timeToPost == EPostIt)
   454 				{
   455                     timeToPost = EDelayIt;
   456 				}
   457 		    }
   458 		    if (delta > 0x7FFFFFFF)
   459 		    {
   460 		         PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:WritePictureL Too large delta .. skipping"), this ); 
   461 		         timeToPost = ESkipIt;
   462 		    }
   463 		}
   464 		else
   465 		{
   466 			if(!iSurfaceCreatedEventPublished)
   467                 {
   468                     PublishSurfaceCreated();
   469                 }
   470 			iFirstPictureUpdated = ETrue;
   471 		}
   472 		
   473 
   474 		switch(timeToPost)
   475 		{
   476 			case EDelayIt:
   477 			{
   478 				if(AddToQ(pic) != 0)
   479 				{
   480 					break;
   481 				}
   482 				iPostingTimer->Cancel();
   483 				SetTimer(delta);
   484 			}
   485 			break;
   486 			case EPostIt:
   487 			{
   488 		
   489 				if(iIsColorConversionNeeded)
   490 				{
   491 					TVideoPicture* ccPic;				
   492 	    			ccPic = DoColorConvert(pic); // output will be in ccPic
   493 	    			pic = ccPic;			   
   494 				}
   495 						
   496 				#ifdef _DUMP_YUV_FRAMES
   497 				captureYuv(pic);
   498 				#endif
   499 				TInt err = iSessionManager->PostPicture(iSurfaceId, GetID(pic), ETrue); 
   500 				if(err == KErrNone)
   501 				{
   502 				    iProcessQ.Append(pic);
   503 					iCurrentPlaybackPosition = pic->iTimestamp;
   504 				}
   505 				else
   506 				{
   507 					ReleasePicture(pic);
   508 				}
   509 			}
   510 			break;
   511 			case ESkipIt:
   512 			{
   513 				ReleasePicture(pic); 
   514 				PicturesSkipped();
   515 			}
   516 			break;
   517 		}
   518     }
   519 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:WritePicture --"), this);
   520 }
   521 
   522 
   523 CPostProcessorInfo* 
   524 CNGAPostProcHwDevice::PostProcessorInfoLC() 
   525 {
   526    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:PostProcessorInfoLC() ++"), this);
   527     TUncompressedVideoFormat yuvFormat;
   528     RArray<TUint32>                     SupportedPostProcess;
   529     TBool                               SupportedHwAcceleration = ETrue;   //Non-Accelerated ETrue, 
   530     TYuvToRgbCapabilities               SupportedYuvToRgbCapab; 
   531     TInt32                              SupportedRotations = ERotateNone; // no rotation supported
   532     
   533     TBool                               SupportedArbitraryScaling = EFalse; // no scaling supported
   534     RArray<TScaleFactor>                SupportedScaleFactors;
   535     TBool                               SupportedAntiAliasing = EFalse;
   536     
   537     //default
   538     yuvFormat.iDataFormat                     = EYuvRawData;
   539     yuvFormat.iYuvFormat.iYuv2RgbMatrix       = 0;
   540     yuvFormat.iYuvFormat.iRgb2YuvMatrix       = 0;
   541     yuvFormat.iYuvFormat.iAspectRatioNum      = 1;
   542     yuvFormat.iYuvFormat.iAspectRatioDenom    = 1;
   543     yuvFormat.iYuvFormat.iCoefficients  	  = EYuvBt709Range1;
   544     yuvFormat.iYuvFormat.iPattern       	  = EYuv422Chroma1;
   545     yuvFormat.iYuvFormat.iDataLayout          = EYuvDataInterleavedBE;
   546     
   547     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   548     
   549     yuvFormat.iYuvFormat.iPattern       	  = EYuv422Chroma2;
   550     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   551     
   552     yuvFormat.iYuvFormat.iCoefficients  	  = EYuvBt709Range0;
   553     yuvFormat.iYuvFormat.iPattern       	  = EYuv422Chroma1;
   554     yuvFormat.iYuvFormat.iDataLayout    	  = EYuvDataInterleavedBE;
   555     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   556     
   557     yuvFormat.iYuvFormat.iPattern       	  = EYuv422Chroma2;
   558     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   559     
   560     yuvFormat.iYuvFormat.iCoefficients  	  = EYuvBt709Range0;
   561     yuvFormat.iYuvFormat.iPattern       	  = EYuv422Chroma1;
   562     yuvFormat.iYuvFormat.iDataLayout    	  = EYuvDataInterleavedLE;
   563     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   564             
   565 	yuvFormat.iYuvFormat.iPattern       	  = EYuv422Chroma2;
   566     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   567 
   568     yuvFormat.iYuvFormat.iCoefficients  	  = EYuvBt709Range1;
   569     yuvFormat.iYuvFormat.iPattern       	  = EYuv422Chroma1;
   570     yuvFormat.iYuvFormat.iDataLayout    	  = EYuvDataInterleavedLE;
   571     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   572     
   573     yuvFormat.iYuvFormat.iPattern       	  = EYuv422Chroma2;
   574     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   575             
   576     yuvFormat.iYuvFormat.iCoefficients  	  = EYuvBt601Range0;
   577     yuvFormat.iYuvFormat.iPattern       	  = EYuv422Chroma1;
   578     yuvFormat.iYuvFormat.iDataLayout    	  = EYuvDataInterleavedBE;
   579     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   580     
   581     yuvFormat.iYuvFormat.iPattern       	  = EYuv422Chroma2;
   582     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   583 
   584     yuvFormat.iYuvFormat.iCoefficients  	  = EYuvBt601Range1;
   585     yuvFormat.iYuvFormat.iPattern       	  = EYuv422Chroma1;
   586     yuvFormat.iYuvFormat.iDataLayout    	  = EYuvDataInterleavedBE;
   587     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   588     
   589     yuvFormat.iYuvFormat.iPattern       	  = EYuv422Chroma2;
   590     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   591             
   592     yuvFormat.iYuvFormat.iCoefficients  	  = EYuvBt601Range0;
   593     yuvFormat.iYuvFormat.iPattern       	  = EYuv422Chroma1;
   594     yuvFormat.iYuvFormat.iDataLayout    	  = EYuvDataInterleavedLE;
   595     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   596     
   597     yuvFormat.iYuvFormat.iPattern       	  = EYuv422Chroma2;
   598     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   599 
   600     yuvFormat.iYuvFormat.iCoefficients  	  = EYuvBt601Range1;
   601     yuvFormat.iYuvFormat.iPattern       	  = EYuv422Chroma1;
   602     yuvFormat.iYuvFormat.iDataLayout    	  = EYuvDataInterleavedLE;
   603     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   604     
   605     yuvFormat.iYuvFormat.iPattern       	  = EYuv422Chroma2;
   606     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   607     
   608     //YUV 420 planar
   609     yuvFormat.iYuvFormat.iCoefficients  	  = EYuvBt709Range1;
   610     yuvFormat.iYuvFormat.iPattern       	  = EYuv420Chroma1;
   611     yuvFormat.iYuvFormat.iDataLayout    	  = EYuvDataPlanar;
   612     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   613 
   614     yuvFormat.iYuvFormat.iPattern       	  = EYuv420Chroma2;
   615     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   616 
   617     yuvFormat.iYuvFormat.iPattern       	  = EYuv420Chroma3;
   618     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   619 
   620     yuvFormat.iYuvFormat.iCoefficients  	  = EYuvBt709Range0;
   621     yuvFormat.iYuvFormat.iPattern       	  = EYuv420Chroma1;
   622     yuvFormat.iYuvFormat.iDataLayout    	  = EYuvDataPlanar;
   623     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   624 
   625     yuvFormat.iYuvFormat.iPattern       	  = EYuv420Chroma2;
   626     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   627 
   628     yuvFormat.iYuvFormat.iPattern       	  = EYuv420Chroma3;
   629     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   630 
   631     yuvFormat.iYuvFormat.iCoefficients  	  = EYuvBt601Range1;
   632     yuvFormat.iYuvFormat.iPattern       	  = EYuv420Chroma1;
   633     yuvFormat.iYuvFormat.iDataLayout    	  = EYuvDataPlanar;
   634     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   635 
   636     yuvFormat.iYuvFormat.iPattern       	  = EYuv420Chroma2;
   637     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   638 
   639     yuvFormat.iYuvFormat.iPattern       	  = EYuv420Chroma3;
   640     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   641 
   642     yuvFormat.iYuvFormat.iCoefficients  	  = EYuvBt601Range0;
   643     yuvFormat.iYuvFormat.iPattern       	  = EYuv420Chroma1;
   644     yuvFormat.iYuvFormat.iDataLayout    	  = EYuvDataPlanar;
   645     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   646 
   647     yuvFormat.iYuvFormat.iPattern       	  = EYuv420Chroma2;
   648     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   649 
   650     yuvFormat.iYuvFormat.iPattern       	  = EYuv420Chroma3;
   651     User::LeaveIfError(iSupportedInputFormats.Append(yuvFormat));
   652             
   653     CPostProcessorInfo* postProcessorInfo = CPostProcessorInfo::NewL( 
   654                 KUidVideoPostProcHwDevice, 
   655                 KManufacturer, 
   656                 KIdentifier, 
   657                 TVersion(1, 0, 0), 
   658                 iSupportedInputFormats.Array(),
   659                 SupportedPostProcess.Array(), 
   660                 SupportedHwAcceleration,   
   661                 ETrue,      //Direct Display
   662                 SupportedYuvToRgbCapab, 
   663                 SupportedRotations, 
   664                 SupportedArbitraryScaling,
   665                 SupportedScaleFactors.Array(), 
   666                 SupportedAntiAliasing);
   667                 
   668     CleanupStack::PushL(postProcessorInfo);            
   669    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:PostProcessorInfoLC() --"), this);
   670     return postProcessorInfo;
   671 }
   672 
   673 void CNGAPostProcHwDevice::MmvprcGetPlayRateCapabilitiesL(TVideoPlayRateCapabilities& aCap)
   674 {       
   675     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvprcGetPlayRateCapabilitiesL ++"), this);       
   676      aCap.iPlayForward = ETrue;       
   677      aCap.iPlayBackward = ETrue;       
   678      aCap.iStepForward = ETrue;       
   679      aCap.iStepBackward = ETrue;       
   680     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvprcGetPlayRateCapabilitiesL --"), this);       
   681 }       
   682 
   683 void CNGAPostProcHwDevice::MmvprcSetPlayRateL(const TInt aRate)
   684 {       
   685     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvprcSetPlayRateL ++"), this);       
   686      iPlayRate = aRate;
   687      if (iPlayRate<0)        
   688      {       
   689          iKeyFrameMode = ETrue;    
   690      }       
   691      else        
   692      {       
   693          iKeyFrameMode = EFalse;   
   694          ResetCountingBuffer();       
   695      }       
   696      //In fast forward go direct to key frame mode if speed >4X =     
   697     if (iPlayRate>KDefPlayRate*4)
   698      {       
   699          if (iFPObserver)        
   700          {       
   701              iFPObserver->MmvproKeyFrameModeRequest();       
   702              iKeyFrameMode=ETrue;       
   703          }       
   704      }       
   705     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvprcSetPlayRateL=%d --"), this, aRate);       
   706 }       
   707 
   708 TInt CNGAPostProcHwDevice::MmvprcPlayRateL()
   709 {       
   710    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvprcPlayRateL= ++"), this);       
   711    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvprcPlayRateL= --"), this);       
   712     return iPlayRate;       
   713 }       
   714 
   715 void CNGAPostProcHwDevice::MmvprcStepFrameL(const TInt aStep)
   716 {       
   717    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvprcStepFrameL= ++"), this);       
   718     iStepFrameCount = aStep;       
   719    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvprcStepFrameL=%d --"), this, aStep);       
   720 }       
   721 
   722 void CNGAPostProcHwDevice::MmvprcSetObserver(MMmfVideoPlayRateObserver& aObserver)
   723 {       
   724    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvprcSetObserver ++"), this);       
   725     iFPObserver  = &aObserver;
   726    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvprcSetObserver --"), this);
   727 } 
   728 
   729 void CNGAPostProcHwDevice::MmvsoSetSecureOutputL(TBool aSecure)
   730 {
   731 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvsoSetSecureOutputL aSecure = %d++"), this, aSecure);     
   732 	TInt err = KErrNone;  
   733     if(aSecure)
   734 	{
   735 		iSurfaceMask = surfaceHints::EAllowInternalOnly;
   736 	}
   737 	else
   738 	{
   739 		iSurfaceMask = surfaceHints::EAllowAllExternals;
   740 	}
   741 	if(!iSurfaceId.IsNull())
   742 	{
   743 		err = AddHints();
   744 		if(err != KErrNone)
   745 		{
   746 			PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvsoSetSecureOutputL -- leaving err = %d"), this, err);
   747 			User::Leave(err);
   748 		}
   749 	}
   750     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvsoSetSecureOutputL --"), this);
   751 }
   752 
   753 void CNGAPostProcHwDevice::MmavsoSetAllowedOutputL(TUint aAllowedOutputMask)
   754 {
   755    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmavsoSetAllowedOutputL aAllowedOutputMask=0x%08x ++"), this,aAllowedOutputMask);  
   756    TInt err = KErrNone;
   757    iSurfaceMask = surfaceHints::EAllowInternalOnly;
   758     if (aAllowedOutputMask == EVideoAllowAll)
   759     {
   760         iSurfaceMask = surfaceHints::EAllowAllExternals;
   761     }
   762     else if (aAllowedOutputMask == EVideoAllowInternalOnly)
   763     {
   764         iSurfaceMask = surfaceHints::EAllowInternalOnly;
   765     }
   766     else 
   767     {
   768         // we hope to find some valid output prefs
   769         if (aAllowedOutputMask & EVideoAllowAnalog)
   770         {
   771             iSurfaceMask |= surfaceHints::EAllowAnalog;
   772         }
   773         if (aAllowedOutputMask & EVideoAllowMacroVision)
   774         {
   775             iSurfaceMask |= surfaceHints::EAllowAnalogProtectionRequired;
   776         }
   777         if (aAllowedOutputMask & EVideoAllowHDMI)
   778         {
   779             iSurfaceMask |= surfaceHints::EAllowDigital;
   780         }
   781         if (aAllowedOutputMask & EVideoAllowHdmiHdcpRequested)
   782         {
   783             iSurfaceMask |= surfaceHints::EAllowDigitalProtectionRequested;
   784         }
   785         if (aAllowedOutputMask & EVideoAllowHdmiHdcpRequired)
   786         {
   787             iSurfaceMask |= surfaceHints::EAllowDigitalProtectionRequired;
   788         }
   789     }
   790     
   791 	if((!iSurfaceId.IsNull()))
   792 	{
   793 		err = AddHints();
   794 		if(err != KErrNone)
   795 		{
   796 			PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmavsoSetAllowedOutputL -- leaving err = %d"), this, err);
   797 			User::Leave(err);
   798 		}
   799 	}
   800     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmavsoSetAllowedOutputL --"), this);
   801 }	
   802 
   803 void CNGAPostProcHwDevice::SetPostProcessTypesL(TUint32 /*aCombination*/) 
   804 { 
   805 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetPostProcessTypesL ++"), this);
   806 	
   807    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetPostProcessTypesL --"), this);
   808 }
   809 
   810 void CNGAPostProcHwDevice::SetInputCropOptionsL(const TRect& /*aRect*/) 
   811 { 
   812 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetInputCropOptionsL ++"), this);
   813    
   814 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetInputCropOptionsL --"), this);
   815 }    
   816 
   817 void CNGAPostProcHwDevice::SetYuvToRgbOptionsL( const TYuvToRgbOptions&  /*aOptions*/, const TYuvFormat& /*aYuvFormat*/, TRgbFormat /*aRgbFormat*/) 
   818 { 
   819 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetYuvToRgbOptionsL ++"), this);
   820 
   821 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetYuvToRgbOptionsL --"), this);
   822 }
   823 
   824 void CNGAPostProcHwDevice::SetYuvToRgbOptionsL(const TYuvToRgbOptions& /*aOptions*/)
   825 {
   826 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetYuvToRgbOptionsL ++"), this);
   827 
   828 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetYuvToRgbOptionsL --"), this);
   829 }
   830 
   831 void CNGAPostProcHwDevice::SetRotateOptionsL(TRotationType ) 
   832 { 
   833 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetRotateOptionsL ++"), this);
   834     
   835 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetRotateOptionsL --"));
   836 }
   837 
   838 void CNGAPostProcHwDevice::SetScaleOptionsL(const TSize& /*aTargetSize*/, TBool /*aAntiAliasFiltering*/) 
   839 { 
   840 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetScaleOptionsL ++"), this);
   841     
   842    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetScaleOptionsL --"), this);
   843 }
   844 
   845 void CNGAPostProcHwDevice::SetOutputCropOptionsL(const TRect& /*aRect*/) 
   846 { 
   847 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetOutputCropOptionsL ++"), this);
   848     
   849 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetOutputCropOptionsL --"), this);
   850 }
   851 
   852 void CNGAPostProcHwDevice::SetPostProcSpecificOptionsL(const TDesC8& ) 
   853 { 
   854     //ignore 
   855 }
   856 
   857 void CNGAPostProcHwDevice::CommitL() 
   858 { 
   859 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:CommitL ++"), this);
   860 
   861    	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:CommitL --"), this);
   862 }
   863 
   864 void CNGAPostProcHwDevice::Revert() 
   865 {
   866 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Revert ++"), this);
   867     
   868 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Revert --"), this);
   869 }
   870 
   871 void CNGAPostProcHwDevice::StartDirectScreenAccessL( const TRect& /*aVideoRect*/, CFbsScreenDevice& /*aScreenDevice*/, const TRegion& /*aClipRegion*/) 
   872 { 
   873    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:StartDSA ++"), this);
   874     
   875    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:StartDSA --"), this);
   876 }
   877 
   878 void CNGAPostProcHwDevice::AbortDirectScreenAccess() 
   879 { 
   880    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:AbortDSA ++"), this);
   881 
   882    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:AbortDSA --"), this);
   883 }
   884 
   885 void CNGAPostProcHwDevice::SetScreenClipRegion(const TRegion& /*aRegion*/) 
   886 { 
   887    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetScreenClipRegion ++"), this);
   888     
   889     
   890    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetScreenClipRegion --"), this);
   891 }		    
   892 
   893 void CNGAPostProcHwDevice::SetPauseOnClipFail(TBool ) 
   894 { 
   895     //ignore. Post Processor will always behave as aPause==False. 
   896 }
   897 
   898 TBool CNGAPostProcHwDevice::IsPlaying()
   899 {
   900 	if( iPPState == EPlaying)
   901 	{
   902     	return ETrue; 
   903     }
   904     else
   905     {
   906     	return EFalse;
   907     }
   908 }
   909 
   910 void CNGAPostProcHwDevice::Redraw() 
   911 { 
   912 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Redraw ++"), this);
   913 	TInt err = KErrNone;
   914 	if(iRedrawSurfaceInUse && !iRedrawDone)
   915 	{
   916         err = AddHints();
   917         if (err != KErrNone)
   918         {
   919             PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Redraw -- failed to AddHints %d"), 
   920                          this, err);
   921             iProxy->MdvppFatalError(this, err);	
   922             return;   
   923         }
   924         PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Redraw registering the temp surface"), this);
   925 		err = RegisterSurface(iSurfaceId);
   926 		if (err != KErrNone)
   927 		{
   928 		   PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Redraw -- failed to Register Surface %d"), 
   929 		   				this, err);
   930 		   	iSurfaceHandler->DestroySurface(iSurfaceId);
   931 	   		iSurfaceId = TSurfaceId::CreateNullId();
   932 			iProxy->MdvppFatalError(this, err);	
   933 			return;   				
   934 		}
   935 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Redraw registering the temp surface done"), this);
   936         err = iSessionManager->PostPicture(iSurfaceId, 0, EFalse);
   937 		if (err != KErrNone)
   938 		{
   939 			iProxy->MdvppFatalError(this, err);	
   940 			return;
   941 		}
   942         PublishSurfaceCreated();
   943         iRedrawDone = ETrue;
   944     }
   945     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Redraw --"), this);
   946 }
   947 
   948 void CNGAPostProcHwDevice::Start() 
   949 {  
   950 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Start ++"), this);
   951 	iPPState = EPlaying;
   952 	
   953 	//TBC: when buffers given to post proc even before start. 
   954 	//Even the buffers must be available to PostProc but not displayed. 
   955 	//This will happen only when neighbouring decodeHwDevice decodes earlier than Start()
   956 	//call. Need to check if MDF guidelines allow this.
   957 	AttemptToPost();
   958 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Start --"), this);
   959 }
   960 
   961 void CNGAPostProcHwDevice::Stop() 
   962 { 
   963 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Stop ++"), this);
   964     iPPState = EStopped;
   965 	if (iSessionManager)
   966 	{
   967 	    iSessionManager->CancelNotifiers();
   968 	}
   969 	if (iPostingTimer)
   970 	{
   971         iPostingTimer->Cancel();
   972 	}
   973 	ReleaseProcessQ();
   974 	ReleaseInputQ();
   975 
   976 	//Stop must keep on displaying the last frame. Blank Screen must not be visible
   977 	//to client. No Unregistering of surface should happen here. 
   978 	//This Req is not necessary anymore. Only applicable to Pause.
   979 	
   980 	RDebug::Printf("------ Statistics of Post Processor ------");
   981     RDebug::Printf("    Pictures Received : %d", iPictureCounters.iTotalPictures);
   982     RDebug::Printf("    Pictures Displayed: %d", iPictureCounters.iPicturesDisplayed);
   983     RDebug::Printf("    Pictures Skipped  : %d", iPictureCounters.iPicturesSkipped);
   984     RDebug::Printf("------------------------------------------");
   985     
   986 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Stop --"), this);
   987 }
   988 
   989 void CNGAPostProcHwDevice::Pause()
   990 {
   991 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Pause ++"), this);
   992 	iPPState = EPaused;
   993     iPostingTimer->Cancel();
   994    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Pause --"), this);
   995 }
   996 
   997 void CNGAPostProcHwDevice::Resume()
   998 {
   999 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Resume ++"), this);
  1000 	iPPState = EPlaying;
  1001 	AttemptToPost();
  1002    	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Resume --"), this);
  1003 }
  1004 
  1005 void CNGAPostProcHwDevice::SetPosition(const TTimeIntervalMicroSeconds& aPlaybackPosition) 
  1006 {
  1007    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetPosition ++"), this);
  1008     
  1009     if (iPPState == EInitializing)
  1010     { 
  1011 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetPosition FAILED: Unexpected state"), this);
  1012         return;
  1013     }
  1014     if (iPPState == EPaused)
  1015     {	
  1016         iFirstPictureUpdated = EFalse;
  1017     }
  1018     iCurrentPlaybackPosition = aPlaybackPosition;  
  1019     
  1020     ReleaseInputQ();
  1021 
  1022    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetPosition --"), this);
  1023 }
  1024 
  1025 void CNGAPostProcHwDevice::FreezePicture(const TTimeIntervalMicroSeconds& ) 
  1026 { 
  1027     //TODO:
  1028 }
  1029 
  1030 void CNGAPostProcHwDevice::ReleaseFreeze(const TTimeIntervalMicroSeconds&  ) 
  1031 { 
  1032     //TODO:
  1033 }
  1034 
  1035 TTimeIntervalMicroSeconds 
  1036 CNGAPostProcHwDevice::PlaybackPosition() 
  1037 { 
  1038 	if (iPPState == EInitializing)
  1039     {
  1040         return TTimeIntervalMicroSeconds(0);
  1041     }
  1042     
  1043     return iCurrentPlaybackPosition; 
  1044 }
  1045 
  1046 TUint CNGAPostProcHwDevice::PictureBufferBytes() 
  1047 {   //TODO 
  1048     return 0; 
  1049 }
  1050 
  1051 void CNGAPostProcHwDevice::GetPictureCounters( CMMFDevVideoPlay::TPictureCounters&  aCounters) 
  1052 { 
  1053 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:GetPictureCounters ++"), this);
  1054 	
  1055 	if (iPPState == EInitializing)
  1056 		return;
  1057 	aCounters = iPictureCounters;
  1058 	
  1059    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:GetPictureCounters --"), this);
  1060 }
  1061 
  1062 void CNGAPostProcHwDevice::SetComplexityLevel(TUint ) 
  1063 { 
  1064     //not required 
  1065 }
  1066 
  1067 TUint CNGAPostProcHwDevice::NumComplexityLevels() 
  1068 { 
  1069     //not required 
  1070     return 1; 
  1071 }
  1072 
  1073 void CNGAPostProcHwDevice::GetComplexityLevelInfo(TUint , CMMFDevVideoPlay::TComplexityLevelInfo& ) 
  1074 { 
  1075     //not required 
  1076 }
  1077 
  1078 void CNGAPostProcHwDevice::ReturnPicture(TVideoPicture* ) 
  1079 { 
  1080 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:ReturnPicture +-"), this);
  1081     //not required for direct rendering 
  1082 }
  1083 
  1084 TBool CNGAPostProcHwDevice::GetSnapshotL(TPictureData& aPictureData, const TUncompressedVideoFormat& /*aFormat*/)
  1085 { 
  1086 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:GetSnapshotL %d %d ++"), this, iVBMEnabled, iProcessQ.Count());
  1087 	TVideoPicture* 		pic = NULL;
  1088 	TInt 				err = KErrNone;
  1089 	TBool				frameAvailable =EFalse;
  1090 	tWndParam			inputCropWindow;
  1091 	tWndParam			outputCropWindow;
  1092 	tBaseVideoFrame		inputFrame;
  1093 	inputFrame.lum 		= NULL; 
  1094 	
  1095 	if(aPictureData.iDataFormat == ERgbFbsBitmap)
  1096 	{	
  1097 		if(iProcessQ.Count())
  1098 		{
  1099 			pic = iProcessQ[0]; //frame already submitted for display
  1100 		}
  1101 		else if(iInputQ.Count())
  1102 		{
  1103 			pic = iInputQ[0]; //frame yet to be displayed
  1104 		}
  1105 		if(pic) 
  1106 		{
  1107 			if (iVBMEnabled)
  1108 		    {
  1109 				inputFrame.lum	= (TUint8*)pic->iData.iRawData->Ptr();
  1110 			}
  1111 			else
  1112 			{
  1113 				if (iInputDecoderDevice)
  1114 				{
  1115 					MMmfVideoFetchFrame* VFHandler = NULL;
  1116 					VFHandler = (MMmfVideoFetchFrame*)iInputDecoderDevice->CustomInterface(KUidMMFVideoFetchFrame);
  1117 					if (VFHandler)
  1118 					{
  1119 						PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:GetSnapshotL() fetch frame"), this);
  1120 						inputFrame.lum = (TUint8*)VFHandler->MmvffGetFrame(GetID(pic));
  1121 					}
  1122 					else
  1123 					{
  1124 						PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:GetSnapshotL() decoder yet to implement MMmfVideoFetchFrame CI"), this);
  1125 					}
  1126 				}
  1127 			}
  1128 		}
  1129 		if(inputFrame.lum)
  1130 		{
  1131 			inputFrame.cb	= inputFrame.lum + iPicSize.iWidth * iPicSize.iHeight;
  1132 			
  1133 			if( ((iVideoFormat.iYuvFormat.iPattern == EYuv420Chroma1) ||
  1134 				(iVideoFormat.iYuvFormat.iPattern == EYuv420Chroma2) ||
  1135 	    		(iVideoFormat.iYuvFormat.iPattern == EYuv420Chroma3) ))						
  1136 			{
  1137 				inputFrame.cr = inputFrame.lum + (iPicSize.iWidth * iPicSize.iHeight*5)/4;
  1138 			}
  1139 			else
  1140 			{
  1141 				inputFrame.cr = inputFrame.lum + (iPicSize.iWidth * iPicSize.iHeight*3)/2;
  1142 			}
  1143 			
  1144 			inputFrame.width	= (unsigned short)iPicSize.iWidth;
  1145 			inputFrame.height	= (unsigned short)iPicSize.iHeight;
  1146 			
  1147 			outputCropWindow.wndHeight  = iPicSize.iHeight;	
  1148 			outputCropWindow.wndWidth	= iPicSize.iWidth; 	
  1149 			outputCropWindow.xOffset	= 0;
  1150 			outputCropWindow.yOffset	= 0;
  1151 			
  1152 			inputCropWindow.wndHeight  = iPicSize.iHeight;	
  1153 			inputCropWindow.wndWidth	= iPicSize.iWidth; 	
  1154 			inputCropWindow.xOffset	= 0;
  1155 			inputCropWindow.yOffset	= 0;
  1156 			
  1157 			RFbsSession fbs;
  1158 			User::LeaveIfError(fbs.Connect());
  1159 			CFbsBitmap* iOutBitmap = aPictureData.iRgbBitmap;
  1160 			TInt status = iOutBitmap->Resize(iPicSize);
  1161 			if (status == KErrNone)
  1162 			{
  1163 				// Lock the heap to prevent the FBS server from invalidating the address
  1164 		        iOutBitmap->LockHeap();
  1165 		        TUint8* dataAddress = (TUint8*)iOutBitmap->DataAddress();
  1166 				err = ColorConvert(&inputFrame, dataAddress, &inputCropWindow, &outputCropWindow);
  1167 				iOutBitmap->UnlockHeap();
  1168 				frameAvailable = ETrue;
  1169 			}
  1170 			fbs.Disconnect();
  1171 		}
  1172 	}
  1173 	else
  1174 	{
  1175 		err = KErrNotSupported;
  1176 	}
  1177 	if(err != KErrNone)
  1178 	{
  1179 		User::Leave(err);
  1180 	}
  1181 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:GetSnapshotL --"), this);
  1182 	return(frameAvailable);
  1183 }
  1184 
  1185 void CNGAPostProcHwDevice::InputEnd() 
  1186 { 
  1187    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:InputEnd ++"), this);
  1188     
  1189 	if (iPPState!=EPlaying && iPPState!=EPaused)
  1190     {
  1191 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:InputEnd FAILED: Unexpected state"), this);
  1192         return;
  1193 	}
  1194     iIsInputEnded = ETrue;
  1195     
  1196     if( (iProcessQ.Count() <= 1) && (iInputQ.Count() == 0))
  1197         {
  1198 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:InputEnd() Stream end"), this);
  1199 		iProxy->MdvppStreamEnd();
  1200 	}
  1201     
  1202    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:InputEnd --"), this);
  1203 }
  1204 
  1205 TAny* CNGAPostProcHwDevice::CustomInterface(TUid aInterface)
  1206 {
  1207    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:CustomInterface UID = %d ++"), this, aInterface.iUid);
  1208 	
  1209 	if (aInterface == KUidMmfVideoBufferManagement)
  1210     {
  1211       return (MMmfVideoBufferManagement *)this;
  1212     }
  1213 	if (aInterface == KUidMMFVideoSurfaceSupport)
  1214 	{
  1215       return (MMMFVideoSurfaceSupport *)this;
  1216     }
  1217 	if (aInterface == KUidMMFVideoSurfaceHandleControl)
  1218 	{
  1219     	return (MMmfVideoSurfaceHandleControl *)this;
  1220   }    
  1221     if (aInterface == KUidMmfVideoPlayRateControl)
  1222     {
  1223       return (MMmfVideoPlayRateControl *)this;
  1224     } 
  1225     if (aInterface == KMmfVideoAdvancedSecureOutputUid)
  1226     {
  1227       return (MMmfAdvancedVideoSecureOutput *)this;
  1228     }
  1229     if (aInterface == KUidMmfVideoResourceManagement)
  1230     {
  1231       return (MMmfVideoResourceObserver *)this;
  1232     } 
  1233     if (aInterface == KUidMmfPostInitializeRequest)
  1234     {
  1235       return (MMmfPostInitializeRequest *)this;
  1236     }
  1237    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:CustomInterface --"), this);
  1238     return NULL;
  1239 }
  1240 
  1241 void CNGAPostProcHwDevice::BufferAvailable(TInt aBufId, TInt aStatus)
  1242 { 
  1243    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:CNGAPostProcHwDevice::BufferAvailable aStatus = %d aBufId = %d++"), this, aStatus, aBufId);
  1244     TVideoPicture* pic = NULL;
  1245     if((aStatus != KErrNone) && (aStatus != KErrOverflow) && (aStatus != KErrNotVisible))
  1246 	{
  1247 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:BufferAvailable FAILED: aStatus = %d"), this, aStatus);
  1248 		iProxy->MdvppFatalError(this, aStatus);
  1249 	}
  1250 
  1251 	if(aStatus == KErrOverflow)
  1252 	{
  1253 		iOverflowPictureCounter++;
  1254 		PicturesSkipped();
  1255 	}
  1256     	
  1257     if (iVBMEnabled)
  1258     {
  1259 		for(TInt i=0; i < iProcessQ.Count(); i++)
  1260 		{
  1261 			if(iVBMBufferReferenceQ[aBufId] == iProcessQ[i])
  1262 			{
  1263 				pic = iProcessQ[i];
  1264 				iProcessQ.Remove(i);				
  1265 				ReturnPicToDecoder(pic);
  1266 				if (iIsColorConversionNeeded)
  1267 				{
  1268 				    AddPictureToColorConversionQ(pic);
  1269 				}
  1270 				else
  1271 				{
  1272 				    AddPictureToVBMQ(pic);
  1273 				}
  1274 				break;
  1275 			}
  1276 		} 
  1277 	}
  1278 	else
  1279 	{
  1280 	    for(TInt i=0; i < iProcessQ.Count(); i++)
  1281 		{
  1282 			TInt bufId;
  1283 			if (iUsingExternalSurface)
  1284 			{
  1285 				bufId = GetExternalBufferID(iProcessQ[i]);
  1286 			}
  1287 			else
  1288 			{
  1289 				bufId = GetID(iProcessQ[i]);
  1290 			}
  1291 			
  1292 			if (aBufId == bufId)
  1293 			{
  1294 				pic = iProcessQ[i];
  1295 				iProcessQ.Remove(i);
  1296 				ReturnPicToDecoder(pic);
  1297 				break;
  1298 			}
  1299 		} 
  1300 	}
  1301 	
  1302 	if(aStatus == KErrNone)
  1303 	{
  1304 		if (!iKeyFrameMode && iPlayRate>KDefPlayRate)     
  1305 		{   
  1306 		 	if (iSkippedFramesCountingBuffer[iCurrentPosInFramesCountingBuffer]==1)        
  1307 		 	{       
  1308 		 		iSkippedFramesCountingBuffer[iCurrentPosInFramesCountingBuffer] = 0;       
  1309 		 		iSkippedFramesInLast64Frames--;       
  1310 		 	}       
  1311 		 	iCurrentPosInFramesCountingBuffer = ++iCurrentPosInFramesCountingBuffer%64;       
  1312 		} 
  1313 		iPictureCounters.iPicturesDisplayed++;
  1314 		if (iStepFrameCount != 0)
  1315         {       
  1316         	iStepFrameCount > 0 ? iStepFrameCount-- : iStepFrameCount++;		            	      
  1317             if (iStepFrameCount==0 && iFPObserver)        
  1318             {       
  1319             	iFPObserver->MmvproStepFrameComplete(pic->iTimestamp);       
  1320             }       
  1321         }
  1322 	}
  1323 	
  1324 	if(iPPState == EPlaying)
  1325 	{
  1326 		AttemptToPost();
  1327 	}
  1328 
  1329 	if( iIsInputEnded && (iProcessQ.Count() <= 1)  && (iInputQ.Count() == 0))
  1330 	{
  1331 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:BufferAvailable() Stream end"), this);
  1332 		iProxy->MdvppStreamEnd();
  1333 	}
  1334 	
  1335    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:CNGAPostProcHwDevice::BufferAvailable --"), this);
  1336 }
  1337 
  1338 //=== MMmfVideoBufferManagement ===
  1339 void CNGAPostProcHwDevice::MmvbmSetObserver(MMmfVideoBufferManagementObserver* aObserver)
  1340 {
  1341    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmSetObserver() ++"), this);
  1342 
  1343     if (iPPState != EInitializing)
  1344     {
  1345 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmSetObserver FAILED: Unexpected state"), this);
  1346         iProxy->MdvppFatalError(this, KErrNotReady);
  1347 	}
  1348 
  1349     iVBMObserver  = aObserver;
  1350 
  1351    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmSetObserver() --"), this);
  1352 }
  1353     
  1354 
  1355 void CNGAPostProcHwDevice::MmvbmEnable(TBool aEnable)
  1356 {
  1357     if (iPPState != EInitializing)
  1358     {
  1359 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmEnable FAILED: Unexpected state"), this);
  1360         iProxy->MdvppFatalError(this, KErrNotReady);
  1361 	}
  1362 
  1363     iVBMEnabled = aEnable;
  1364 }
  1365     
  1366 void CNGAPostProcHwDevice::MmvbmSetBufferOptionsL(const TBufferOptions& aOptions)
  1367 {
  1368    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmSetBufferOptionsL ++"), this);
  1369 
  1370     if (iPPState != EInitializing)
  1371     {
  1372 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmSetBufferOptionsL FAILED: Unexpected state"), this);
  1373         User::Leave(KErrNotReady);
  1374 	}
  1375 
  1376     // why limiting the number of buffers? any particular reason for this?
  1377     //if (aOptions.iNumInputBuffers > KMaxVBMBuffers || aOptions.iNumInputBuffers <= 1)          //at least two buffers
  1378     if (aOptions.iNumInputBuffers <= 1)          //at least two buffers
  1379     {
  1380 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmSetBufferOptionsL FAILED: Input buffer count limit"), this);
  1381         User::Leave(KErrNotSupported);
  1382 	}
  1383 
  1384     if (aOptions.iNumInputBuffers == 0 
  1385         || aOptions.iBufferSize.iWidth <= KMinVBMInputWidth 
  1386         || aOptions.iBufferSize.iHeight <= KMinVBMInputHeight  
  1387         || aOptions.iBufferSize.iWidth > KMaxVBMInputWidth 
  1388         || aOptions.iBufferSize.iHeight > KMaxVBMInputHeight)
  1389     {
  1390 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmSetBufferOptionsL FAILED: Unexpected buffer size"), this);
  1391         User::Leave(KErrArgument);
  1392 	}
  1393 
  1394     iVBMBufferOptions.iNumInputBuffers  = aOptions.iNumInputBuffers;
  1395     iVBMBufferOptions.iBufferSize       = aOptions.iBufferSize;
  1396 
  1397    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmSetBufferOptionsL --"), this);
  1398 }
  1399 
  1400 void CNGAPostProcHwDevice::MmvbmGetBufferOptions(TBufferOptions& aOptions)
  1401 {
  1402     if (iPPState == EInitializing)
  1403     {
  1404     	aOptions = iVBMBufferOptions;
  1405     }
  1406     else
  1407     {
  1408 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmGetBufferOptions FAILED: Unexpected state"), this);
  1409         iProxy->MdvppFatalError(this, KErrNotReady);
  1410 	}
  1411 }
  1412     
  1413 TVideoPicture* CNGAPostProcHwDevice::MmvbmGetBufferL(const TSize& aSize)
  1414     {
  1415    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmGetBufferL() ++"), this);
  1416     
  1417     TInt err = KErrNone;
  1418     TVideoPicture* lPic = NULL;
  1419 
  1420     if (iPPState == EInitializing)
  1421     {
  1422 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmGetBufferL() FAILED: Unexpected state"), this);
  1423         User::Leave(KErrNotReady);
  1424 	  }
  1425 
  1426     if (aSize.iWidth < KMinVBMInputWidth 
  1427         || aSize.iHeight < KMinVBMInputHeight
  1428         || aSize.iWidth > iVBMBufferOptions.iBufferSize.iWidth 
  1429         || aSize.iHeight > iVBMBufferOptions.iBufferSize.iHeight)
  1430   	{
  1431 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmGetBufferL() FAILED: Unexpected buffer size w=%d h=%d "), this,aSize.iWidth,aSize.iHeight );
  1432         User::Leave(KErrNotSupported);
  1433 		}
  1434 		
  1435 		if(iVBMBufferReferenceQ.Count() == 0)
  1436 		{
  1437 			iPicSize = aSize;
  1438 			err = SetupSurface();
  1439 			if(err)
  1440 			{
  1441 					PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmGetBufferL() Surface Setup Failed %d"), this, err);
  1442 					User::Leave(err);
  1443 			}
  1444 		}
  1445 		
  1446     if(!iVBMBufferQ.Count())
  1447     {
  1448        PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmGetBufferL() WARNING: Queue buffer count zero"), this);
  1449         return NULL;
  1450     }
  1451 
  1452     lPic    = iVBMBufferQ[0];
  1453     iVBMBufferQ.Remove(0);
  1454 
  1455    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmGetBufferL() -- %d"), this, lPic);
  1456     return lPic;
  1457 }
  1458     
  1459 void CNGAPostProcHwDevice::MmvbmReleaseBuffer(TVideoPicture* aBuffer)
  1460 {
  1461    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmReleaseBuffer() ++"), this);
  1462 
  1463     if(!aBuffer)
  1464     {
  1465 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmReleaseBuffer() FAILED: Invalid buffer ptr"), this);
  1466     	iProxy->MdvppFatalError(this, KErrArgument);
  1467 	}
  1468 
  1469     TInt err = iVBMBufferQ.Append(aBuffer);
  1470     if (err)
  1471     {
  1472 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmReleaseBuffer() FAILED: Failed to append"), this);
  1473 		iProxy->MdvppFatalError(this, err);
  1474 	}
  1475 
  1476    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvbmReleaseBuffer() --"), this);
  1477 }
  1478 
  1479 //=== MMMFVideoSurfaceSupport ===
  1480 
  1481 void CNGAPostProcHwDevice::MmvssUseSurfaces()
  1482 {
  1483 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvssUseSurfaces() ++"), this);
  1484 	// do nothing
  1485 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvssUseSurfaces() --"), this);
  1486 }
  1487 
  1488 TInt CNGAPostProcHwDevice::MmvshcCreateSurface(const RSurfaceManager::TSurfaceCreationAttributes& aAttributes, TInt aHandle, TSurfaceId& aSurfaceId)
  1489     {
  1490     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvshcCreateSurface() ++"), this);
  1491     TInt err(KErrNone);
  1492     
  1493     if(!iSurfaceId.IsNull())
  1494     {
  1495         PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvssCreateSurface Cleaning Surface"), this);
  1496         
  1497 		if (iVideoSurfaceObserver && iSurfaceCreatedEventPublished)
  1498 		{
  1499 			PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvshcCreateSurface - Telling client to remove old surface"), this);
  1500 			iVideoSurfaceObserver->MmvsoRemoveSurface();
  1501 			iSurfaceCreatedEventPublished = EFalse;
  1502 		}
  1503 		else
  1504 		{
  1505 			// We never told the client about the surface, so we must destroy it ourselves
  1506 			PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetupExternalSurface - Destroying old surface"), this);
  1507 			TInt numScreens = iWsSession.NumberOfScreens();
  1508     		for(TInt i=0;i < numScreens;i++)
  1509     		{
  1510     			iWsSession.UnregisterSurface(i, iSurfaceId);
  1511     		}
  1512    			iWsSession.Flush();
  1513 			iSurfaceHandler->DestroySurface(iSurfaceId);
  1514 		}
  1515 		//remove any handle to chunk. not needed perhaps
  1516 		iChunk.Close();
  1517 		
  1518     }
  1519         
  1520     // Create the surface handler if it doesn't exist.
  1521     if (!iSurfaceHandler)
  1522     {
  1523         TRAP(err, iSurfaceHandler = CNGAPostProcSurfaceHandler::NewL());
  1524         if (err != KErrNone)
  1525         {
  1526             PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvssCreateSurface -- failed to create SurfaceHandler."), this);
  1527             return err;
  1528         }
  1529     }
  1530          
  1531     iChunk.SetHandle(aHandle);
  1532     err = iSurfaceHandler->CreateSurface(aAttributes, aSurfaceId, iChunk);
  1533     if (err != KErrNone)
  1534     {
  1535        PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvssCreateSurface -- failed to create surface %d"), this, err);
  1536        return err;
  1537     }
  1538     iSurfaceId = aSurfaceId;
  1539     iIsExternalChunk = ETrue;
  1540 
  1541     err = RegisterSurface(iSurfaceId);
  1542     if (err != KErrNone)
  1543     {
  1544        PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvssCreateSurface -- failed RegisterSurface %d"), this, err);
  1545        iSurfaceHandler->DestroySurface(iSurfaceId);
  1546        iSurfaceId = TSurfaceId::CreateNullId();
  1547        return err;
  1548     }
  1549     
  1550     err = iSurfaceHandler->SurfaceInfo(iSurfaceId, iInfo);
  1551     if (err != KErrNone)
  1552     {
  1553         PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvssCreateSurface -- failed to get Surface info %d"), this, err);
  1554         return err;
  1555     }
  1556 
  1557     if(iAttributes().iPixelFormat == EUidPixelFormatYUV_422Interleaved) 
  1558         {
  1559             iVideoFrameBufSize          = iInfo().iSize.iWidth * iInfo().iSize.iHeight * 2;
  1560         }
  1561         else
  1562         {//EStUidPixelFormatYUV_420MB
  1563         // EUidPixelFormatYUV_420Planar            
  1564             iVideoFrameBufSize          =  iInfo().iSize.iWidth * iInfo().iSize.iHeight * 3/2;
  1565         }
  1566     
  1567      
  1568     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvshcCreateSurface err=%d"), this, err);
  1569     return err;
  1570     }
  1571 
  1572 void CNGAPostProcHwDevice::MmvssSetObserver(MMMFVideoSurfaceObserver& aObserver)
  1573 {
  1574 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvssSetObserver() ++"), this);
  1575 	iVideoSurfaceObserver = &aObserver;
  1576 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvssSetObserver() --"), this);
  1577 }
  1578 
  1579 void CNGAPostProcHwDevice::MmvssGetSurfaceParametersL(TSurfaceId& aSurfaceId, 
  1580 						TRect& aCropRect, TVideoAspectRatio& aPixelAspectRatio)
  1581 {
  1582 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvssGetSurfaceParametersL() ++"), this);
  1583 
  1584 	iSurfaceHandler->SurfaceInfo(iSurfaceId, iInfo);
  1585 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvssGetSurfaceParametersL() \
  1586 		surfaceWidth = %d surfaceHeight = %d SurfaceId = 0x%x --"), 
  1587 		this, iInfo().iSize.iWidth, iInfo().iSize.iHeight, iSurfaceId);
  1588 	aSurfaceId = iSurfaceId;
  1589 		aCropRect = TRect(0, 0, iInfo().iSize.iWidth, iInfo().iSize.iHeight);
  1590 		if((iPicSize.iWidth > 0) && (iPicSize.iHeight > 0))
  1591 		{
  1592 			aCropRect.Intersection( iPicSize);
  1593 		}
  1594 	aPixelAspectRatio = TVideoAspectRatio(iAspectRatioNum,iAspectRatioDenom);
  1595 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvssGetSurfaceParametersL()  \
  1596 		cropRectWidth = %d cropRectHeight = %d"), this, aCropRect.Width(), aCropRect.Height());
  1597 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvssGetSurfaceParametersL()  \
  1598 		PAR Num = %d PAR Denom = %d"), this, aPixelAspectRatio.iNumerator, aPixelAspectRatio.iDenominator);
  1599 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvssGetSurfaceParametersL() --"), this);
  1600 }
  1601 
  1602 void CNGAPostProcHwDevice::MmvssSurfaceRemovedL(const TSurfaceId& aSurfaceId)
  1603 {
  1604 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvssSurfaceRemovedL()++"), this);
  1605 	if(!aSurfaceId.IsNull())
  1606 	{
  1607 	    if(iSurfaceId == aSurfaceId)
  1608         {//closing down top surface....current surface.
  1609             if(iSessionManager)
  1610             {
  1611                 iSessionManager->CancelNotifiers();
  1612             }
  1613 	    }
  1614 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvssSurfaceRemovedL(): UnregisterSurface ID = 0x%x"), this, aSurfaceId );
  1615 		TInt numScreens = iWsSession.NumberOfScreens();
  1616 		for(TInt i=0;i < numScreens;i++)
  1617 		{
  1618 			iWsSession.UnregisterSurface(i, aSurfaceId);
  1619 		}
  1620 		iWsSession.Flush();
  1621 		iSurfaceHandler->DestroySurface(aSurfaceId);
  1622 		if(iSurfaceId == aSurfaceId)
  1623 		{
  1624 			iSurfaceCreatedEventPublished = EFalse;
  1625 			iSurfaceId = TSurfaceId::CreateNullId();
  1626 			 if(!iIsExternalChunk)
  1627 			 {
  1628 				iChunk.Close();
  1629 			 }
  1630 		}
  1631 	}
  1632 
  1633 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvssSurfaceRemovedL() --"), this);
  1634 }
  1635 
  1636 // === MMmfVideoPropertiesObserver ===
  1637     
  1638 void CNGAPostProcHwDevice::MmvpoUpdateVideoProperties(const TYuvFormat& aYuvFormat, const TSize& aPictureSize)
  1639 {
  1640 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvpoUpdateVideoProperties ++"), this);
  1641 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvpoUpdateVideoProperties PAR \
  1642 		iAspectRatioNum = %d, iAspectRatioDenom = %d"), this,
  1643 					 aYuvFormat.iAspectRatioNum,aYuvFormat.iAspectRatioDenom);
  1644 	iPicSize = aPictureSize;
  1645 	iAspectRatioNum = aYuvFormat.iAspectRatioNum;
  1646 	iAspectRatioDenom = aYuvFormat.iAspectRatioDenom;
  1647 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvpoUpdateVideoProperties Picture Size \
  1648 		iWidth = %d, iHeight = %d, iSurfaceCreatedEventPublished = %d"), 
  1649 		this, iPicSize.iWidth,iPicSize.iHeight, iSurfaceCreatedEventPublished?1:0);
  1650 			 
  1651 	if(iVPObserver)
  1652 	{
  1653 		iVPObserver->MmvpoUpdateVideoProperties(aYuvFormat, aPictureSize);
  1654 	} 
  1655 	if(iVideoSurfaceObserver && iSurfaceCreatedEventPublished)
  1656 	{
  1657     	iVideoSurfaceObserver->MmvsoSurfaceParametersChanged(); 
  1658     }
  1659 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvpoUpdateVideoProperties --"), this);
  1660 }
  1661 
  1662 // === MMmfVideoResourceObserver ===
  1663 
  1664 void CNGAPostProcHwDevice::MmvroResourcesLost(TUid )
  1665 {
  1666     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvroResourcesLost ++"), this);
  1667     if(!iResourceLost)
  1668     {
  1669 		iResourceLost = ETrue;
  1670 		iRedrawDone = EFalse;
  1671 		Pause();
  1672 		ReleaseInputQ();
  1673 		iSessionManager->CancelNotifiers();
  1674 		ReleaseProcessQ();
  1675 		if(iVideoSurfaceObserver && iSurfaceCreatedEventPublished)
  1676 		{
  1677 			PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvroResourcesLost - Telling client to remove surface"), this);
  1678 			iVideoSurfaceObserver->MmvsoRemoveSurface();
  1679 			iSurfaceCreatedEventPublished = EFalse;
  1680 		}
  1681 	}
  1682 	else if(iResourceLost && iRedrawDone)
  1683 	{
  1684 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvroResourcesLost ResourceLost happening \
  1685 					while Postprocessor is already in ResourceLoss state"), 
  1686 	   				this);
  1687 		iProxy->MdvppFatalError(this, KErrHardwareNotAvailable);	   				
  1688 	    return;		
  1689 	}
  1690 	else
  1691 	{
  1692 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvroResourcesLost Ignoring the \
  1693 					duplicate ResourceLoss call"), 
  1694 	   				this);
  1695 	}
  1696     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvroResourcesLost --"), this);
  1697 }
  1698 
  1699 // === MMmfVideoPropertiesNotifier ===
  1700     
  1701 void CNGAPostProcHwDevice::MmvpnSetObserver(MMmfVideoPropertiesObserver* aObserver)
  1702 {
  1703 	PP_DEBUG(_L("ppHwDev[%x]::MmvpnSetObserver ++"), this);
  1704 	iVPObserver = aObserver;
  1705 	PP_DEBUG(_L("ppHwDev[%x]::MmvpnSetObserver --"), this);
  1706 }
  1707 
  1708 void CNGAPostProcHwDevice::MmvroResourcesRestored(TUid )
  1709 {
  1710    	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvroResourcesRestored ++"), this);
  1711 	iFirstPictureUpdated = EFalse;
  1712 	iResourceLost = EFalse;
  1713    	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvroResourcesRestored state=%d --"), 
  1714    			this, iPPState);
  1715 }
  1716 
  1717 void CNGAPostProcHwDevice::MmvshcSetSurfaceHandle(const TSurfaceId &aSurfaceID)
  1718 {
  1719     
  1720     SetupExternalSurface(aSurfaceID);
  1721     
  1722 }
  1723 
  1724 void CNGAPostProcHwDevice::MmvshcRedrawBufferToSurface(TPtrC8& aRedrawBuffer)
  1725 {
  1726     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvshcRedrawBufferToSurface ++"), this);
  1727 	
  1728     TUint8*         lPtr;
  1729     TInt 			offset;
  1730 
  1731     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvshcRedrawBufferToSurface -- Creating %d x %d surface"), this, iPicSize.iWidth, iPicSize.iHeight);
  1732 
  1733    	TInt err = KErrNone;
  1734 	SetSurfaceAttributes(iPicSize, 1); 
  1735 	
  1736   	err = iSurfaceHandler->CreateSurface(iAttributes, iSurfaceId);
  1737   	if (err != KErrNone)
  1738 	{
  1739 	   PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvshcRedrawBufferToSurface -- failed to create Surface %d"), 
  1740 	   				this, err);
  1741 		iProxy->MdvppFatalError(this, err);	   				
  1742 	    return;
  1743 	}
  1744 
  1745 	err = iSurfaceHandler->SurfaceInfo(iSurfaceId, iInfo);
  1746 	if (err != KErrNone)
  1747 	{
  1748 	   PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvshcRedrawBufferToSurface -- failed to get Surface info %d"), 
  1749 	   				this, err);
  1750 	   	iSurfaceHandler->DestroySurface(iSurfaceId);
  1751 	   	iSurfaceId = TSurfaceId::CreateNullId();
  1752 		iProxy->MdvppFatalError(this, err);	   				
  1753 	    return;
  1754 	}
  1755 
  1756 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvshcRedrawBufferToSurface() \
  1757 		surfaceWidth = %d surfaceHeight = %d surfaceStride = %d"), this, iInfo().iSize.iWidth, iInfo().iSize.iHeight, iInfo().iStride);
  1758 
  1759 	TInt redrawBufferSize = aRedrawBuffer.Size();
  1760 	TInt surfaceSize = iInfo().iStride * iInfo().iSize.iHeight;
  1761 
  1762     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvshcRedrawBufferToSurface RedrawBuffer size= %d Surface size = %d"), this, redrawBufferSize, surfaceSize);
  1763 
  1764 	// Check whether redraw buffer will fit onto the surface.
  1765 	// If this check fails then we won't raise a fatal error - We just won't create the redraw surface
  1766 	if (redrawBufferSize > surfaceSize)
  1767 	{
  1768     	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvshcRedrawBufferToSurface Redraw buffer size larger than surface size"), this);
  1769     	iSurfaceHandler->DestroySurface(iSurfaceId);
  1770 	   	iSurfaceId = TSurfaceId::CreateNullId();
  1771     	return;
  1772 	}
  1773 
  1774 	err = iSurfaceHandler->MapSurface(iSurfaceId, iChunk);
  1775 	if (err != KErrNone)
  1776 	{
  1777 	   PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:MmvshcRedrawBufferToSurface -- failed to map Surface %d"), 
  1778 	   				this, err);
  1779 	   	iSurfaceHandler->DestroySurface(iSurfaceId);
  1780 	   	iSurfaceId = TSurfaceId::CreateNullId();
  1781 		iProxy->MdvppFatalError(this, err);	   				
  1782 	    return;
  1783 	}
  1784 	iIsExternalChunk = EFalse;
  1785     if((err = iSurfaceHandler->GetBufferOffset(iSurfaceId, 0, offset)) != KErrNone)
  1786     {
  1787     	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvshcRedrawBufferToSurface offset query failed %d"), this, err);
  1788     	iSurfaceHandler->DestroySurface(iSurfaceId);
  1789 	   	iSurfaceId = TSurfaceId::CreateNullId();
  1790 		iChunk.Close();
  1791     	iProxy->MdvppFatalError(this, err);
  1792     	return;
  1793     }
  1794 
  1795     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvshcRedrawBufferToSurface offset = %d"), this, offset);
  1796 
  1797 	lPtr = reinterpret_cast<TUint8*>(iChunk.Base() + offset);
  1798 	memcpy((TAny *)lPtr, (TAny *)aRedrawBuffer.Ptr(), redrawBufferSize);
  1799 
  1800 	iRedrawSurfaceInUse = ETrue;
  1801 
  1802 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvshcRedrawBufferToSurface(): New surface = 0x%x"), this, iSurfaceId);
  1803 
  1804     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::MmvshcRedrawBufferToSurface error = %d --"), this, err);
  1805 }
  1806 
  1807 TInt CNGAPostProcHwDevice::SetupExternalSurface(const TSurfaceId &aSurfaceID)
  1808 {
  1809 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetupExternalSurface(): aSurfaceID = 0x%x"), this, aSurfaceID );
  1810 
  1811     TInt err = KErrNone;
  1812     
  1813     if(!iSurfaceId.IsNull())
  1814     {
  1815 		if (iVideoSurfaceObserver && iSurfaceCreatedEventPublished)
  1816 		{
  1817 			PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetupExternalSurface - Telling client to remove old surface"), this);
  1818 			iVideoSurfaceObserver->MmvsoRemoveSurface();
  1819 			iSurfaceCreatedEventPublished = EFalse;
  1820 		}
  1821 		else
  1822 		{
  1823 			// We never told the client about the surface, so we must destroy it ourselves
  1824 			PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetupExternalSurface - Destroying old surface"), this);
  1825 			TInt numScreens = iWsSession.NumberOfScreens();
  1826     		for(TInt i=0;i < numScreens;i++)
  1827     		{
  1828     			iWsSession.UnregisterSurface(i, iSurfaceId);
  1829     		}
  1830    			iWsSession.Flush();
  1831 			iSurfaceHandler->DestroySurface(iSurfaceId);
  1832 		}
  1833 
  1834 		iChunk.Close();
  1835 	}
  1836     
  1837     iSurfaceId            = aSurfaceID;
  1838     iUsingExternalSurface = ETrue;
  1839     iRedrawSurfaceInUse = EFalse;
  1840 
  1841     // Create the surface handler if it doesn't exist.
  1842     if (!iSurfaceHandler)
  1843     {
  1844         TRAP(err, iSurfaceHandler = CNGAPostProcSurfaceHandler::NewL());
  1845         if (err != KErrNone)
  1846         {
  1847            PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetupExternalSurface -- failed to create SurfaceHandler."), this);
  1848             return err;
  1849         }
  1850     }
  1851     
  1852     err = iSurfaceHandler->OpenSurface(iSurfaceId);
  1853     if (err != KErrNone)
  1854 	{
  1855 	   PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetupExternalSurface -- failed OpenSurface %d"), 
  1856 	   				this, err);
  1857 	    return err;
  1858 	}
  1859     err = AddHints();
  1860     if (err != KErrNone)
  1861     {
  1862         PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetupExternalSurface -- failed to AddHints %d"), 
  1863                     this, err);
  1864         return err;
  1865     }
  1866 	err = RegisterSurface(iSurfaceId);
  1867 	if (err != KErrNone)
  1868 	{
  1869 	   PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetupExternalSurface -- failed RegisterSurface %d"), 
  1870 	   				this, err);
  1871 	   	iSurfaceHandler->DestroySurface(iSurfaceId);
  1872 	   	iSurfaceId = TSurfaceId::CreateNullId();
  1873 	    return err;
  1874 	}
  1875 
  1876     err = iSurfaceHandler->SurfaceInfo(iSurfaceId, iInfo);
  1877     if (err != KErrNone)
  1878     {
  1879         PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetupExternalSurface -- failed to get Surface info %d"), 
  1880                      this, err);
  1881         return err;
  1882     }
  1883  
  1884   PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetupExternalSurface err=%d"), this, err);
  1885    return err;
  1886 }
  1887 
  1888 //=== Internal ===
  1889 TVideoPicture* CNGAPostProcHwDevice::CreateBuffersL(TInt aBufId)
  1890 {
  1891 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::CreateBuffersL ++"), this);
  1892 	
  1893 	TVideoPicture*          lVideoPicture = NULL;
  1894     TUint8*                 lPtr;
  1895     TPtr8*                  lTemp;
  1896     TInt 					offset;
  1897     
  1898 	lVideoPicture = new (ELeave) TVideoPicture;
  1899     CleanupStack::PushL(lVideoPicture);
  1900     if(TInt err = iSurfaceHandler->GetBufferOffset(iSurfaceId, aBufId, offset) != KErrNone)
  1901     {
  1902     	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::CreateBuffersL offset query failed %d"), this, err);
  1903     }
  1904     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::CreateBuffersL offset = %d id =%d --"), this, offset, aBufId);
  1905     
  1906 	lPtr = reinterpret_cast<TUint8*>(iChunk.Base() + offset);
  1907 
  1908     lTemp = new (ELeave) TPtr8(lPtr, 0, (iVideoFrameBufSize ));
  1909     CleanupStack::PushL(lTemp);
  1910 
  1911     lVideoPicture->iData.iRawData   = lTemp;
  1912     lVideoPicture->iHeader = NULL ;
  1913     lVideoPicture->iLayerBitRates = NULL ;
  1914     
  1915     CleanupStack::Pop(2);
  1916     
  1917    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::CreateVBMBuffersL --"), this);
  1918     return lVideoPicture;
  1919 }
  1920 
  1921 void CNGAPostProcHwDevice::CreateVBMBuffersL()
  1922 {
  1923 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::CreateVBMBuffersL ++"), this);
  1924     
  1925     TInt err = KErrNone;
  1926     TVideoPicture* pic = NULL;
  1927     iVBMBufferReferenceQ.Reset();
  1928     iVBMBufferQ.Reset();
  1929     iColorConversionQ.Reset();
  1930 
  1931     for(TInt i = 0; i < iVBMBufferOptions.iNumInputBuffers; i++)
  1932     {
  1933         TRAP(err, pic = CreateBuffersL(i));
  1934 	    	if (err != KErrNone)
  1935 	    	{
  1936 	    	   PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Initialize -- failed to create VBM buffer %d"), this, err);
  1937 	    	    User::Leave(err);
  1938 	    	}
  1939 
  1940         // This will hold the references which will be used in destructor
  1941         User::LeaveIfError(iVBMBufferReferenceQ.Append(pic));
  1942         User::LeaveIfError(iVBMBufferQ.Append(pic));
  1943     }
  1944     if(iIsColorConversionNeeded)
  1945     {
  1946 		    for(TInt i = iVBMBufferOptions.iNumInputBuffers ; 
  1947 		    				 i < (iVBMBufferOptions.iNumInputBuffers + KColorConversionBuffers ); i++)
  1948 		    {
  1949 		        TRAP(err, pic = CreateBuffersL(i));
  1950 			    	if (err != KErrNone)
  1951 			    	{
  1952 			    	   PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Initialize -- failed to create VBM buffer %d"), this, err);
  1953 			    	    User::Leave(err);
  1954 			    	}
  1955 		
  1956 		        // This will hold the references which will be used in destructor
  1957 		        User::LeaveIfError(iVBMBufferReferenceQ.Append(pic));
  1958 		        User::LeaveIfError(iColorConversionQ.Append(pic));
  1959 		    }
  1960 		}
  1961 	    
  1962 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]::CreateVBMBuffersL --"), this);
  1963 }
  1964 
  1965 void CNGAPostProcHwDevice::ReturnPicToDecoder(TVideoPicture* aPic)
  1966 {
  1967    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:ReturnPicToDecoder ++"), this);
  1968 	if (aPic == NULL)
  1969 	{
  1970 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:ReleaseInputPicture FAILED: Invalid pic ptr."), this);
  1971 		return;
  1972 	}
  1973 	
  1974    	if (iInputDecoderDevice)
  1975     {
  1976        PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:ReleaseInputPicture .. before return picture. 2"), this);
  1977         iInputDecoderDevice->ReturnPicture(aPic);
  1978     }
  1979 	
  1980 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:ReturnPicToDecoder --"), this);
  1981 }
  1982 
  1983 TInt CNGAPostProcHwDevice::AttemptToPost()
  1984 {
  1985    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:AttemptToPost ++ Q:%d"), this, iInputQ.Count());
  1986    if (iPPState == EPaused)
  1987    {
  1988         return KErrNone;
  1989    }
  1990 
  1991     TInt err = KErrNotReady;
  1992     TInt count = iInputQ.Count();
  1993     TBool bDone = EFalse;
  1994     TVideoPicture* pic = PeekQ();   		
  1995   	while(pic && !bDone)
  1996   	{
  1997 	    if(!IsGceReady())
  1998 		{  
  1999 			PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:AttemptToPost GCE not ready"), this );
  2000 			return err; //no need to catch this error
  2001 		}
  2002 		TInt64 delta = 0;
  2003 		TTimeToPost	timeToPost = (TTimeToPost)IsTimeToPost(pic, delta);
  2004 		switch(timeToPost)
  2005 		{
  2006 			case EDelayIt:
  2007 			{
  2008 				iPostingTimer->Cancel();
  2009 				SetTimer(delta);
  2010 				bDone = ETrue;
  2011 			}
  2012 			break;
  2013 			case EPostIt:
  2014 			{
  2015 				RemoveFromQ(); // remove the pic that was returned by PeekQ				
  2016 				if(iIsColorConversionNeeded)
  2017 				{
  2018 				    TVideoPicture* ccPic;
  2019     				ccPic = DoColorConvert(pic); // output will be in ccPic
  2020     				pic = ccPic;
  2021 			    }
  2022 				
  2023                 #ifdef _DUMP_YUV_FRAMES
  2024                     captureYuv(pic);
  2025                 #endif
  2026 				TInt err = iSessionManager->PostPicture(iSurfaceId, GetID(pic), ETrue); 
  2027 				if(err == KErrNone)
  2028 				{
  2029 				    iProcessQ.Append(pic);
  2030 					iCurrentPlaybackPosition = pic->iTimestamp;
  2031 					if(!iFirstPictureUpdated)
  2032 					{
  2033 						iFirstPictureUpdated = ETrue;
  2034 						if(!iSurfaceCreatedEventPublished)
  2035                     	{
  2036                         	PublishSurfaceCreated();
  2037                     	}
  2038 					}
  2039 				}
  2040 				else
  2041 				{
  2042 					ReleasePicture(pic);
  2043 				}
  2044 										 					
  2045 				
  2046 			}	// end of postit
  2047 			break;
  2048 			case ESkipIt: 
  2049 			{
  2050 				RemoveFromQ();
  2051 				ReleasePicture(pic);
  2052 				PicturesSkipped();				
  2053 			}
  2054 			break;
  2055 		} // end of switch
  2056 		
  2057 		// get the next picture
  2058 		pic = PeekQ();	
  2059     } // end of while
  2060     
  2061    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:AttemptToPost --"), this);
  2062  	return err;
  2063 }
  2064 
  2065 TInt CNGAPostProcHwDevice::IsTimeToPost(TVideoPicture* frame, TInt64& delta)
  2066 {
  2067    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:IsTimeToPost ++"), this);
  2068 
  2069     if (!frame)
  2070     {
  2071 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:IsTimeToPost FAILED: Invalid frame ptr."), this);
  2072 		return KErrGeneral;
  2073 	}
  2074 
  2075     TInt resp = EPostIt;
  2076     // Frame presentation time
  2077     TInt64 uPresTime = frame->iTimestamp.Int64();
  2078       
  2079     // Check if this is an out of order frame in case of forward playback
  2080     if((iCurrentPlaybackPosition.Int64() > uPresTime) && (iPlayRate > 0))    
  2081     {      
  2082          PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:IsTimeToPost : Out of order frame (forward playback) Tfm=%d"), this,(TInt)uPresTime);
  2083          resp = ESkipIt;  //drop      
  2084     }      // Check if this is an out of order frame in case of backward playback
  2085     else if((iCurrentPlaybackPosition.Int64() < uPresTime) && (iPlayRate < 0))    
  2086     {      
  2087         PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:IsTimeToPost : Out of order frame (backward playback) Tfm=%d"), this,(TInt)uPresTime);
  2088         resp = ESkipIt;  //drop      
  2089     }
  2090     else if (iClockSource)
  2091     {
  2092         // The time to sync with.
  2093         TInt64 uSyncTime = iClockSource->Time().Int64();
  2094         
  2095         delta = uPresTime - uSyncTime;
  2096         if (( delta > KRenderAhead ) &&  (iPlayRate > 0))	// Delay condition not checked for 
  2097         {													// backward playback
  2098         	resp = EDelayIt;  //wait
  2099         }
  2100         else if ( (delta < (-KMaxRenderDelay) && (iPlayRate > 0))
  2101           		||  ((delta > KMaxRenderDelay) && (iPlayRate < 0)))
  2102         {
  2103             resp = ESkipIt;  //drop
  2104         }
  2105        PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:IsTimeToPost .. Tfm=%d, Tcs=%d, delta=%d"), this, (TInt)uPresTime, (TInt)uSyncTime, (TInt)delta);
  2106     }       
  2107    
  2108    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:IsTimeToPost -- %d BufID = %d"), this, resp, GetID(frame));
  2109     return resp;
  2110 }
  2111 
  2112 void CNGAPostProcHwDevice::ReleaseInputQ()
  2113 {
  2114 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:ReleaseInputQ ++ Q = %d"), this, iInputQ.Count());
  2115     while (iInputQ.Count()>0)
  2116     {
  2117     	ReleasePicture(iInputQ[0]);
  2118         iInputQ.Remove(0);
  2119     }
  2120    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:ReleaseInputQ --"), this);
  2121 }
  2122 
  2123 void CNGAPostProcHwDevice::ReleaseProcessQ()
  2124 {
  2125 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:ReleaseProcessQ ++ Q = %d"), this, iProcessQ.Count() );
  2126 	TVideoPicture* pic = NULL;
  2127 	
  2128     while (iProcessQ.Count()>0)
  2129     {
  2130 		pic = iProcessQ[0];
  2131 		iProcessQ.Remove(0);
  2132 		ReturnPicToDecoder(pic);
  2133     }
  2134    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:ReleaseProcessQ --"), this);
  2135 }
  2136 
  2137 void CNGAPostProcHwDevice::ReleasePicture(TVideoPicture *pic)
  2138 {
  2139    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:ReleasePicture ++"), this);
  2140 	if (pic == NULL)
  2141 	{
  2142 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:ReleaseInputPicture FAILED: Invalid pic ptr."), this);
  2143 		return;
  2144 	}
  2145 	
  2146    	if (iInputDecoderDevice)
  2147     {
  2148        PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:ReleaseInputPicture .. before return picture. 2"), this);
  2149         iInputDecoderDevice->ReturnPicture(pic);
  2150     }
  2151 	if (iVBMEnabled)
  2152     {
  2153         iVBMBufferQ.Append(pic);
  2154 
  2155         if ( !iIsInputEnded && iPPState != EStopped )
  2156         {
  2157             iVBMObserver->MmvbmoNewBuffers();
  2158         }
  2159 	}
  2160 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:ReleasePicture --"), this);
  2161 }
  2162 
  2163 void CNGAPostProcHwDevice::PublishSurfaceCreated()
  2164 {
  2165 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:PublishSurfaceCreated ++"), this);   
  2166 	if(iVideoSurfaceObserver)
  2167 	{
  2168 		iVideoSurfaceObserver->MmvsoSurfaceCreated();
  2169 		iSurfaceCreatedEventPublished = ETrue;
  2170 	}
  2171     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:PublishSurfaceCreated --"), this);
  2172 }
  2173 
  2174 TInt CNGAPostProcHwDevice::SetupSurface()
  2175 {
  2176 	TInt err = KErrNone;
  2177 	if(iVBMEnabled && iVBMObserver)
  2178     {
  2179     	SetSurfaceAttributes(iVBMBufferOptions.iBufferSize, iVBMBufferOptions.iNumInputBuffers);
  2180     	
  2181 	  	err = iSurfaceHandler->CreateSurface(iAttributes, iSurfaceId);
  2182 	  	if (err != KErrNone)
  2183     	{
  2184     	   PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Initialize -- failed to create Surface %d"), this, err);
  2185     	    return err;
  2186     	}
  2187     	err = iSurfaceHandler->MapSurface(iSurfaceId, iChunk);
  2188     	if (err != KErrNone)
  2189     	{
  2190     	   PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Initialize -- failed to map Surface %d"), this, err);
  2191     	  	iSurfaceHandler->DestroySurface(iSurfaceId);
  2192 	   		iSurfaceId = TSurfaceId::CreateNullId();
  2193     	    return err;
  2194     	}
  2195     	err = iSurfaceHandler->SurfaceInfo(iSurfaceId, iInfo);
  2196     	if (err != KErrNone)
  2197     	{
  2198     	   PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Initialize -- failed to get Surface info %d"), this, err);
  2199     	   	iSurfaceHandler->DestroySurface(iSurfaceId);
  2200 	   		iSurfaceId = TSurfaceId::CreateNullId();
  2201     	    return err;
  2202     	}
  2203     	TRAP(err, CreateVBMBuffersL());
  2204     	if (err != KErrNone)
  2205     	{
  2206     	   PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Initialize -- failed to create VBM buffer %d"), this, err);
  2207     	   	iSurfaceHandler->DestroySurface(iSurfaceId);
  2208 	   		iSurfaceId = TSurfaceId::CreateNullId();
  2209     	    return err;
  2210     	}
  2211         err = AddHints();
  2212         if (err != KErrNone)
  2213         {
  2214             PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Initialize -- failed to AddHints %d"), this, err);
  2215             return err;
  2216         }
  2217         err = RegisterSurface(iSurfaceId);
  2218         if (err != KErrNone)
  2219         {
  2220             PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:Initialize -- failed to RegisterSurface %d"), this, err);
  2221             iSurfaceHandler->DestroySurface(iSurfaceId);
  2222             iSurfaceId = TSurfaceId::CreateNullId();
  2223             return err;
  2224         }
  2225         
  2226     }
  2227     return err;
  2228 } 
  2229 
  2230 void CNGAPostProcHwDevice::SetSurfaceAttributes(const TSize& aSize, TInt aNumBuf)
  2231 {
  2232 	iAttributes().iSize                   = aSize; // size of the video frame
  2233     iAttributes().iBuffers            	  = aNumBuf;
  2234     
  2235     /* The stride needs to be calculated for the surface manager to know
  2236     how much memory to allocate */
  2237     
  2238     if(iAttributes().iPixelFormat == EUidPixelFormatYUV_420Planar)
  2239     	{
  2240     		iAttributes().iStride       = aSize.iWidth * 3/2;
  2241     		iVideoFrameBufSize			= aSize.iWidth * aSize.iHeight * 3/2;
  2242     	}
  2243     	else
  2244     	{
  2245     		iAttributes().iStride       = aSize.iWidth * 2;
  2246     		iVideoFrameBufSize			= aSize.iWidth * aSize.iHeight * 2;
  2247     	}
  2248     		
  2249     if(iIsColorConversionNeeded)
  2250     {
  2251     	iAttributes().iBuffers            = aNumBuf + KColorConversionBuffers;
  2252     }
  2253     else
  2254     {
  2255     	iAttributes().iBuffers            = aNumBuf;	
  2256     }
  2257     
  2258     iAttributes().iOffsetToFirstBuffer    = 0;
  2259 #if defined __WINSCW__ 
  2260     iAttributes().iAlignment              = 4;
  2261 #else //on hw, its always better to have page aligned chunks
  2262     iAttributes().iAlignment              = -1;
  2263 #endif
  2264     iAttributes().iContiguous             = ETrue;
  2265     iAttributes().iHintCount              = 0;
  2266     iAttributes().iMappable               = ETrue;
  2267 }
  2268 
  2269 TInt CNGAPostProcHwDevice::GetID(TVideoPicture *aPicture)
  2270 {
  2271     if (iUsingExternalSurface)
  2272     {
  2273 	    return GetExternalBufferID(aPicture);
  2274     }
  2275     else
  2276     {
  2277         TUint8* aPtr = (TUint8*) aPicture->iData.iRawData->Ptr();
  2278         return( (TInt) ((aPtr - iChunk.Base() - iAttributes().iOffsetToFirstBuffer) / 
  2279 			(iVideoFrameBufSize )));
  2280     }
  2281 }
  2282 
  2283 TInt CNGAPostProcHwDevice::GetExternalBufferID(TVideoPicture *aPicture)
  2284 {
  2285     // currently type cast the pointer as buffer ID.
  2286     // FIXME once the new data structure is available.
  2287     return( (TInt) aPicture->iData.iRawData->Ptr());
  2288 }
  2289 
  2290 TInt CNGAPostProcHwDevice::RegisterSurface(const TSurfaceId& aSurfaceId)
  2291 {
  2292 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:RegisterSurface(): RegisterSurface ID = 0x%x"), this, aSurfaceId);
  2293 	TInt err = KErrNone;
  2294 	TInt numScreens = iWsSession.NumberOfScreens();
  2295 	for(TInt i=0; (i < numScreens && err == KErrNone); i++)
  2296 	{
  2297 		err = iWsSession.RegisterSurface(i, aSurfaceId);
  2298 	}	
  2299 	return(err);
  2300 }
  2301 
  2302 TInt CNGAPostProcHwDevice::IsGceReady()
  2303 {
  2304     if(iProcessQ.Count() >= KMaxBuffersGceCanHold)
  2305     {
  2306     		return EFalse;
  2307     }
  2308     return ETrue;
  2309 }
  2310 
  2311 void CNGAPostProcHwDevice::SetTimer(TInt64 aDelta)
  2312 {
  2313 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetTimer .. aDelta=%d"), this, (TInt)aDelta);
  2314 	if(aDelta <= KRenderAhead)
  2315 	{
  2316 		if(aDelta < 0)
  2317 		{
  2318 			iPostingTimer->After(aDelta * -1);
  2319 		}
  2320 		else
  2321 		{
  2322 			iPostingTimer->After((aDelta - KRenderAhead) * -1);
  2323 		}
  2324 	}
  2325 	else
  2326 	{
  2327 		iPostingTimer->After(aDelta - KRenderAhead - KPostingOfset);
  2328 	}
  2329 }
  2330 //
  2331 // Convert YUV420 to YUV422InterLeaved.
  2332 //
  2333 TInt CNGAPostProcHwDevice::ConvertPostProcBuffer(TVideoPicture* pSrc, TVideoPicture* pDest)
  2334 {
  2335     PP_DEBUG(_L("CMdfPostingSurfaceProxy::ConvertPostProcBuffer ++"));
  2336     TInt err = KErrNone;
  2337     if (!pDest && !pSrc)
  2338 	{
  2339 		PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:ConvertPostProcBuffer FAILED: Invalid pic pSrc %x pDest %x."), this, pSrc, pDest);
  2340 		return KErrArgument;
  2341 	}
  2342     
  2343     // --- Prepare wrappers ---
  2344     tBaseVideoFrame tFrame420, tFrame422;
  2345     TInt    frameSize = pSrc->iData.iDataSize.iWidth * pSrc->iData.iDataSize.iHeight;
  2346 
  2347    PP_DEBUG(_L("CMdfPostingSurfaceProxy::ConvertPostProcBuffer .. w=%d, h=%d"), pSrc->iData.iDataSize.iWidth, pSrc->iData.iDataSize.iHeight);
  2348 
  2349     tFrame420.width = pSrc->iData.iDataSize.iWidth;
  2350     tFrame420.height= pSrc->iData.iDataSize.iHeight;
  2351     tFrame420.lum   = (TUint8*)pSrc->iData.iRawData->Ptr();
  2352     tFrame420.cb    = (TUint8*)tFrame420.lum + frameSize;
  2353     tFrame420.cr    = (TUint8*)tFrame420.lum + (frameSize*5)/4;
  2354     
  2355     tFrame422.width = pSrc->iData.iDataSize.iWidth;
  2356     tFrame422.height= pSrc->iData.iDataSize.iHeight;
  2357     tFrame422.lum   = (TUint8*)pDest->iData.iRawData->Ptr();
  2358     tFrame422.cb    = 0;
  2359     tFrame422.cr    = 0;
  2360     
  2361     // --- Convertion to posting buffer ---
  2362     TInt stride     = pSrc->iData.iDataSize.iWidth * 2;
  2363     EBufferLayout422 layout = YUV422INT_BE;
  2364         
  2365     err = gColorConvYUVtoYUV422Int(&tFrame420, &tFrame422, layout, stride);
  2366     if(err != KErrNone)
  2367     {
  2368     		PP_DEBUG(_L("CNGAPostProcHwDevice::ConvertPostProcBuffer .. err= %d."), err);
  2369     }
  2370 	return err;
  2371 }   
  2372 
  2373 void CNGAPostProcHwDevice::AddPictureToVBMQ(TVideoPicture *pic)
  2374 {
  2375    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:AddPictureToVBMQ ++"), this);
  2376     iVBMBufferQ.Append(pic);
  2377 
  2378     if ( !iIsInputEnded && iPPState != EStopped )
  2379     {
  2380         iVBMObserver->MmvbmoNewBuffers();
  2381     }
  2382 	
  2383 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:AddPictureToVBMQ --"), this);
  2384 }
  2385 
  2386 void CNGAPostProcHwDevice::AddPictureToColorConversionQ(TVideoPicture *pic)
  2387 {
  2388 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:AddPictureToColorConversionQ ++"), this);
  2389     iColorConversionQ.Append(pic);
  2390    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:AddPictureToColorConversionQ --"), this);
  2391 }
  2392 
  2393 #ifdef _DUMP_YUV_FRAMES
  2394 void CNGAPostProcHwDevice::captureYuv(TVideoPicture* aPicture)
  2395 {
  2396 	char buf[128];              
  2397 	sprintf(buf, "c:\\fb%d.yuv", count++);          
  2398 	FILE *fp = ::fopen(buf, "w");
  2399 	TInt size = aPicture->iData.iRawData->Size();
  2400 	//{FILE* f1 = fopen(MY_LOG_FILE_NAME, "a+"));if(f1){fprintf(f1, "Size  %d \n"), size );fclose(f1); }}
  2401 
  2402 	::fwrite(aPicture->iData.iRawData->Ptr(), 1, size, fp);
  2403 	::fclose(fp);    	
  2404 }
  2405 #endif
  2406 
  2407 void CNGAPostProcHwDevice::ResetCountingBuffer()
  2408 {       
  2409 	memset(iSkippedFramesCountingBuffer,0,sizeof(iSkippedFramesCountingBuffer));
  2410     iSkippedFramesInLast64Frames = 0;       
  2411     iCurrentPosInFramesCountingBuffer = 0;       
  2412 } 
  2413 
  2414 void CNGAPostProcHwDevice::PicturesSkipped()
  2415 {       
  2416 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:PicturesSkipped ++"), this);
  2417 	iPictureCounters.iPicturesSkipped++;
  2418 	if (!iKeyFrameMode && iPlayRate>KDefPlayRate)
  2419     {       
  2420     	if (iSkippedFramesCountingBuffer[iCurrentPosInFramesCountingBuffer]==0)        
  2421         {       
  2422         	iSkippedFramesCountingBuffer[iCurrentPosInFramesCountingBuffer] = 1;       
  2423             iSkippedFramesInLast64Frames++;       
  2424             if (iSkippedFramesInLast64Frames>KMaxAllowedSkipInNFrames && iFPObserver )       
  2425             {       
  2426             	iFPObserver->MmvproKeyFrameModeRequest();       
  2427                 iKeyFrameMode=ETrue;       
  2428                 ResetCountingBuffer();       
  2429             }       
  2430         }       
  2431         iCurrentPosInFramesCountingBuffer = ++iCurrentPosInFramesCountingBuffer%64;       
  2432     }
  2433     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:PicturesSkipped --"), this);   
  2434 }
  2435 
  2436 TVideoPicture* CNGAPostProcHwDevice::DoColorConvert(TVideoPicture* aPicture)
  2437 {
  2438     TVideoPicture *pOutPicture  = aPicture;
  2439     					    		
  2440 	if(iColorConversionQ.Count())
  2441     {
  2442 	    pOutPicture    = iColorConversionQ[0];
  2443 	    iColorConversionQ.Remove(0);
  2444 	    ConvertPostProcBuffer(aPicture, pOutPicture);
  2445 	   	pOutPicture->iTimestamp = aPicture->iTimestamp;
  2446 	    ReleasePicture(aPicture);    	    
  2447     }				    
  2448     else
  2449     {
  2450        PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:WritePictureL() FAILED: color conversion"), this);
  2451     }
  2452 
  2453 	return pOutPicture;
  2454 }
  2455 
  2456 TInt CNGAPostProcHwDevice::AddToQ(TVideoPicture* aPicture)
  2457 {
  2458 	TVideoPicture* pic = aPicture;
  2459 	TInt pos = -1;
  2460 	if(iInputQ.Count() == 0)
  2461 	{
  2462 		iInputQ.Append(pic);
  2463 	}
  2464 	else
  2465 	{
  2466 		pos = iInputQ.Count()-1;
  2467 		for(; pos >= 0; pos--)
  2468 		{
  2469 			if(pic->iTimestamp.Int64() > iInputQ[pos]->iTimestamp.Int64())
  2470 			{
  2471 				break;
  2472 			}
  2473 		} 
  2474 		if(iInputQ.Count() == pos+1)
  2475 		{
  2476 			iInputQ.Append(pic);
  2477 		}
  2478 		else
  2479 		{
  2480 			iInputQ.Insert(pic, pos+1);
  2481 		}
  2482 	}
  2483 	return pos+1;
  2484 }
  2485 
  2486 void CNGAPostProcHwDevice::RemoveFromQ()
  2487 {
  2488 	if(iInputQ.Count())
  2489 	{
  2490 		if(iPlayRate > 0)
  2491 		{
  2492 			iInputQ.Remove(0);
  2493 		}
  2494 		else
  2495 		{
  2496 			iInputQ.Remove(iInputQ.Count()-1);
  2497 		}
  2498 	}
  2499 }
  2500 
  2501 TVideoPicture* CNGAPostProcHwDevice::PeekQ()
  2502 {	
  2503 	TVideoPicture *pic = NULL;
  2504 	if(iInputQ.Count())
  2505 	{
  2506 		if(iPlayRate > 0)
  2507 		{			
  2508 			pic = iInputQ[0];
  2509 		}
  2510 		else
  2511 		{			
  2512 			pic = iInputQ[iInputQ.Count()-1];
  2513 		}	
  2514 	}
  2515 	return pic;
  2516 }
  2517 
  2518 TInt CNGAPostProcHwDevice::AddHints()
  2519 {
  2520    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:AddHints iSurfaceMask 0x%08x ++"), this, iSurfaceMask);
  2521    TInt err = KErrNone;
  2522    iHint.Set(iSurfaceKey,iSurfaceMask,ETrue);
  2523    err = iSurfaceHandler->AddSurfaceHint(iSurfaceId,iHint);
  2524    if(err == KErrAlreadyExists)
  2525    {
  2526 		err = KErrNone;
  2527 		err = iSurfaceHandler->SetSurfaceHint(iSurfaceId,iHint);
  2528    }
  2529    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:AddHints. err = %d --"), this,err);
  2530    iHint.iKey.iUid = surfaceHints::KSurfaceContent;
  2531    iHint.iValue = surfaceHints::EVideoPlayback;
  2532    iHint.iMutable = ETrue;
  2533    err = iSurfaceHandler->AddSurfaceHint(iSurfaceId,iHint);
  2534    if(err == KErrAlreadyExists)
  2535    {
  2536 		err = KErrNone;
  2537 		err = iSurfaceHandler->SetSurfaceHint(iSurfaceId,iHint);
  2538    }
  2539    PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:AddHints. err = %d --"), this,err);
  2540    return err;
  2541 }
  2542 
  2543 TInt CNGAPostProcHwDevice::ColorConvert(tBaseVideoFrame* aInputFrame, TUint8* aDestPtr, tWndParam* aInputCropWindow, tWndParam* aOutputCropWindow)
  2544 {
  2545 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:ColorConvert ++"), this);
  2546 	__ASSERT_ALWAYS(aDestPtr, User::Invariant());
  2547 	TInt				lError = E_SUCCESS;
  2548 	TInt				err = KErrNone;
  2549 	
  2550 	err = SetSourceFormat();
  2551 	if(err == KErrNone)
  2552 	{
  2553     	err = SetSourceRange();
  2554     	if(err == KErrNone)
  2555     	{
  2556 						
  2557 			lError = Emz_VDec_gColorConv_YUVtoRGB(aInputFrame,aDestPtr, 
  2558 						aInputCropWindow, aOutputCropWindow, iSourceFormat,
  2559 						EBitmapColor16MU, iSourceRange);
  2560 
  2561 			if(lError)
  2562 			{
  2563 				if(lError == E_OUT_OF_MEMORY)
  2564 					{
  2565 					err = KErrNoMemory;
  2566 					}
  2567 				else if(lError == E_FAILURE)
  2568 					{
  2569 					err = KErrNotSupported;
  2570 					}
  2571 				else
  2572 					{
  2573 					err = KErrGeneral;
  2574 					}
  2575 			}
  2576 		}
  2577 	}
  2578 	
  2579 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:ColorConvert --"), this);
  2580 	return err;
  2581 }
  2582 
  2583 TInt CNGAPostProcHwDevice::SetSourceFormat()
  2584 {
  2585 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetSourceFormatL ++"), this);
  2586 	TInt err = KErrNone;
  2587 	switch (iVideoFormat.iYuvFormat.iPattern)
  2588 	{
  2589 	    case EYuv420Chroma1:
  2590     		iSourceFormat = EYuv420Chroma1_Planar;
  2591     		break;
  2592         case EYuv420Chroma2:
  2593     		iSourceFormat = EYuv420Chroma2_Planar;
  2594     		break;
  2595         case EYuv420Chroma3:
  2596     		iSourceFormat = EYuv420Chroma3_Planar;
  2597     		break;
  2598 	    case EYuv422Chroma1:
  2599 			if( iVideoFormat.iYuvFormat.iDataLayout == EYuvDataInterleavedLE)
  2600     			iSourceFormat = EYuv422Chroma1_LE;
  2601 	    	else if( iVideoFormat.iYuvFormat.iDataLayout == EYuvDataInterleavedBE )
  2602 				iSourceFormat = EYuv422Chroma1_BE;
  2603 			else
  2604 			    err = KErrArgument;
  2605 			break;
  2606     	case EYuv422Chroma2:
  2607     		if( iVideoFormat.iYuvFormat.iDataLayout == EYuvDataInterleavedLE)
  2608 	    		iSourceFormat = EYuv422Chroma2_LE;
  2609     		else if( iVideoFormat.iYuvFormat.iDataLayout == EYuvDataInterleavedBE )
  2610     			iSourceFormat = EYuv422Chroma2_BE;
  2611 			else
  2612 			    err = KErrArgument;
  2613 			break;
  2614       default:
  2615     		err = KErrNotSupported;
  2616 	}
  2617 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetSourceFormatL --"), this);
  2618 	return err;
  2619 }
  2620 
  2621 
  2622 TInt CNGAPostProcHwDevice::SetSourceRange()
  2623 {
  2624 	PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetSourceRangeL ++"), this);
  2625 	TInt err = KErrNone;
  2626 	switch (iVideoFormat.iYuvFormat.iCoefficients)
  2627 	{
  2628 	    case EYuvBt601Range0:
  2629 			iSourceRange = EITU601_5_REDUCEDRANGE;
  2630             break;
  2631         case EYuvBt601Range1:
  2632 			iSourceRange = EITU601_5_FULLRANGE;
  2633 			break;
  2634         case EYuvBt709Range0:
  2635 			iSourceRange = EB709_REDUCEDRANGE;
  2636 			break;
  2637         case EYuvBt709Range1:
  2638 			iSourceRange = EB709_FULLRANGE;
  2639             break;
  2640 	    default:
  2641 		    err = KErrNotSupported;
  2642     }
  2643     PP_DEBUG(_L("CNGAPostProcHwDevice[%x]:SetSourceRangeL --"), this);
  2644     return err;
  2645 }
  2646 
  2647 CNGAPostProcTimer::CNGAPostProcTimer( CNGAPostProcHwDevice& aParent )
  2648 :CTimer(EPriorityHigh),iParent(aParent)
  2649 {
  2650 	CActiveScheduler::Add(this);
  2651 }
  2652 
  2653 CNGAPostProcTimer::~CNGAPostProcTimer()
  2654 {
  2655 	PP_DEBUG(_L("CNGAPostProcTimer[%x]:~CNGAPostProcTimer ++"), this);
  2656 	Cancel();
  2657 	PP_DEBUG(_L("CNGAPostProcTimer[%x]:~CNGAPostProcTimer --"), this);
  2658 }
  2659 
  2660 CNGAPostProcTimer* CNGAPostProcTimer::NewL( CNGAPostProcHwDevice& aParent )
  2661 {
  2662 	CNGAPostProcTimer* self = new (ELeave)CNGAPostProcTimer(aParent);
  2663 	CleanupStack::PushL( self );
  2664 	self->ConstructL();
  2665 	CleanupStack::Pop( self );
  2666 	return self;
  2667 }
  2668 
  2669 void CNGAPostProcTimer::ConstructL()
  2670 {
  2671 	CTimer::ConstructL();
  2672 }
  2673 
  2674 void CNGAPostProcTimer::RunL()
  2675 {
  2676 	PP_DEBUG(_L("CNGAPostProcTimer[%x]:RunL ++"), this);
  2677 	if (iStatus ==KErrCancel)
  2678 	{
  2679 		PP_DEBUG(_L("CNGAPostProcNotifier[%x]:CNGAPostProcNotifier:RunL State canceled"), this);
  2680 		return;
  2681 	}
  2682 	iParent.AttemptToPost();
  2683 	PP_DEBUG(_L("CNGAPostProcTimer[%x]:RunL --"), this);
  2684 }
  2685 
  2686 void CNGAPostProcHwDevice::MmpirPostInitializeRequest(MMmfPostInitializeResponse& aResponse)
  2687 	{
  2688 	iPostInitializeResponse = &aResponse;
  2689 	}