mdfdevvideoextensions/nga_mdf_postprocessor_shai/src/NGAPostProcHwDevice.cpp
changeset 58 b6dbf97aba93
equal deleted inserted replaced
57:1cbb0d5bf7f2 58:b6dbf97aba93
       
     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 	}