os/mm/mmdevicefw/mdf/src/video/decoderadapter/mdfvideodecodehwdeviceadapter.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include <mmf/devvideo/devvideopuconfig.h>
    17 #include "mdfvideodecodehwdeviceadapter.h"
    18 #include "displaymodeutils.h"
    19 
    20 #if defined (SYMBIAN_MDFVIDEODECODERHWDEVICE_DEBUG)
    21 #define DEBUG_PRINT RDebug::Print
    22 #else
    23 #define DEBUG_PRINT
    24 #endif // defined (SYMBIAN_MDFVIDEODECODERHWDEVICE_DEBUG)
    25 
    26 const TInt KOutputFormatsArraySize = 3;
    27 const TInt KTenFPS = 10;
    28 const TInt KOneSecond = 1000000;
    29 const TInt KInputBufferSize = 8192;
    30 
    31 _LIT(KDevVideoHwDeviceDecoderPanicCategory, "DevVideoHwDeviceDecoder");
    32 void DevVideoHwDeviceDecoderPanic(TInt aReason)
    33 	{
    34 	User::Panic(KDevVideoHwDeviceDecoderPanicCategory, aReason);
    35 	}
    36 	
    37 /* 
    38  Constructs a new instance of CMdfVideoDecodeHwDeviceAdapter.
    39  @return    "CMdfVideoDecodeHwDeviceAdapter*"
    40             A pointer to the newly constructed HwDevice
    41  */
    42 CMdfVideoDecodeHwDeviceAdapter* CMdfVideoDecodeHwDeviceAdapter::NewL()
    43 	{
    44 	CMdfVideoDecodeHwDeviceAdapter* self = new (ELeave) CMdfVideoDecodeHwDeviceAdapter;
    45 	CleanupStack::PushL(self);
    46 	self->ConstructL();
    47 	CleanupStack::Pop(self);
    48 	return self;	
    49 	}
    50 
    51 /*
    52  Default constructor
    53 */
    54 CMdfVideoDecodeHwDeviceAdapter::CMdfVideoDecodeHwDeviceAdapter()
    55 	{
    56 	}
    57 	
    58 void CMdfVideoDecodeHwDeviceAdapter::ConstructL()
    59 	{
    60 	// system clock without HAL
    61 	TInt64 tt64;
    62 	TTime ttime;
    63 	ttime.HomeTime();
    64 	tt64 = ttime.Int64();
    65 	iSystemClock = tt64;
    66 
    67 	// reset picture format
    68 	iFormat.iDataFormat = (TImageDataFormat)0;
    69 	
    70 	// Load the PU Loader plugin
    71 	iPuLoader = static_cast<CMdfPuLoader*>
    72 		(REComSession::CreateImplementationL(TUid::Uid(KUidPuLoaderImplementation), iPuLoaderDtorKey));	
    73 	iState = EProcessingUnitLoaderLoaded;
    74 	}
    75 
    76 /*
    77  Default destructor
    78 */
    79 CMdfVideoDecodeHwDeviceAdapter::~CMdfVideoDecodeHwDeviceAdapter()
    80 	{
    81 	DEBUG_PRINT(_L("HwDevice: Destroying"));
    82 	// stop playing if necessary
    83 	Stop();
    84 	
    85 	delete iPlayerEngine;
    86 	delete iScreenDeviceGc;
    87 
    88 	// destroy the buffer manager
    89 	delete iBufferManager;
    90 	// destroy the picture header
    91 	delete iPictureHeader;	
    92 	
    93 		// Unload the DecoderPU
    94 	if (iDecoderPU)
    95 		{
    96 		iPuLoader->UnloadProcessingUnit(iDecoderPU);
    97 		}
    98 		
    99 	delete iPuLoader;	
   100 	delete iPuData;
   101 	delete iManufacturer;
   102 	REComSession::DestroyedImplementation(iPuLoaderDtorKey);			
   103 
   104 	iInputVidFormats.ResetAndDestroy(); // will destroy contents as well
   105 	iOutputVidFormats.Close();
   106 	iPictureRates.Close();
   107 
   108 	DEBUG_PRINT(_L("HwDevice: Destroyed"));
   109 	}
   110 
   111 /*
   112  @see CMMFVideoHwDevice::CustomInterface()
   113  */
   114 TAny* CMdfVideoDecodeHwDeviceAdapter::CustomInterface(TUid aInterface)
   115 	{
   116 	if (aInterface.iUid == KUidDevVideoHwDeviceAdapterSetup)
   117 		{
   118 		return static_cast<MDevVideoHwDeviceAdapterSetup*>(this);
   119 		}
   120 	return NULL;
   121 	}
   122 
   123 /*
   124  @see CMMFVideoPlayHwDevice::PostProcessorInfoLC()
   125  */
   126 CPostProcessorInfo* CMdfVideoDecodeHwDeviceAdapter::PostProcessorInfoLC()
   127 	{
   128 	// post processor info will be obtained from the post processor plugin, if any
   129 	return NULL;
   130 	}
   131 
   132 /*
   133  @see CMMFVideoPlayHwDevice::GetOutputFormatListL()
   134  */
   135 void CMdfVideoDecodeHwDeviceAdapter::GetOutputFormatListL(RArray<TUncompressedVideoFormat>& aFormats)
   136 	{
   137 	// TUncompressedVideoFormats is a union - therefore using hard initialisation
   138 	iOutputVidFormats.Reset();
   139 	TUncompressedVideoFormat outputFormats[KOutputFormatsArraySize];
   140 	
   141 	outputFormats[0].iDataFormat = ERgbRawData;
   142 	outputFormats[0].iRgbFormat = ERgb16bit565;
   143 	iOutputVidFormats.AppendL(outputFormats[0]);
   144 	aFormats.AppendL(outputFormats[0]);
   145 	
   146 	outputFormats[1].iDataFormat = ERgbFbsBitmap;
   147 	outputFormats[1].iRgbFormat = EFbsBitmapColor16M;
   148 	iOutputVidFormats.AppendL(outputFormats[1]);
   149 	aFormats.AppendL(outputFormats[1]);
   150 	
   151 	outputFormats[2].iDataFormat = EYuvRawData;
   152 	iOutputVidFormats.AppendL(outputFormats[2]);
   153 	aFormats.AppendL(outputFormats[2]);
   154 	}
   155 
   156 /*
   157  @see CMMFVideoPlayHwDevice::SetOutputFormatL()
   158  */
   159 void CMdfVideoDecodeHwDeviceAdapter::SetOutputFormatL(const TUncompressedVideoFormat& aFormat)
   160 	{
   161 	// check size and format are supported
   162 	if(iOutputVidFormats.Count() == 0) 
   163 		{
   164 		User::Leave(KErrNotReady);
   165 		}
   166 	if(!iOutputVidFormats.Find(aFormat)) 
   167 		{
   168 		User::Leave(KErrNotSupported);
   169 		}
   170 	
   171 	iFormat = aFormat;
   172 	TDevVideoPlayPuConfig decodeConfig;
   173 	decodeConfig.iImageFormat = iFormat;		
   174 	decodeConfig.iInputBufferSize = KInputBufferSize;	
   175 	TPuConfigVideoPlayback puConfig(decodeConfig);
   176 
   177 	User::LeaveIfError(iDecoderPU->Configure(puConfig));
   178 	}
   179 
   180 /*
   181  @see CMMFVideoPlayHwDevice::SetClockSource()
   182  */
   183 void CMdfVideoDecodeHwDeviceAdapter::SetClockSource(MMMFClockSource* aClock)
   184 	{
   185 	iClockSource = aClock;
   186 	}
   187 
   188 /*
   189  @see CMMFVideoPlayHwDevice::SetVideoDestScreenL()
   190  */
   191 void CMdfVideoDecodeHwDeviceAdapter::SetVideoDestScreenL(TBool aScreen)
   192 	{
   193 	if(aScreen) 
   194 		{
   195 		// NB we expect the output format to have been set before this is called
   196 		if(!iFormat.iDataFormat) 
   197 			{
   198 			User::Leave(KErrNotReady);
   199 			}
   200 	
   201 		// we support only bitmaps for DSA, not raw data
   202 		if(iFormat.iDataFormat != ERgbFbsBitmap) 
   203 			{
   204 			User::Leave(KErrNotSupported);
   205 			}
   206 		}
   207 	
   208 	// ETrue = use DSA
   209 	iDSAEnabled = aScreen;
   210 	}
   211 
   212 /*
   213  @see CMMFVideoPlayHwDevice::SetPostProcessTypesL()
   214  */
   215 void CMdfVideoDecodeHwDeviceAdapter::SetPostProcessTypesL(TUint32 /* aPostProcCombination */)
   216 	{
   217 	// the decoder is not configurable
   218 	User::Leave(KErrNotSupported);
   219 	}
   220 
   221 /*
   222  @see CMMFVideoPlayHwDevice::SetInputCropOptionsL()
   223  */
   224 void CMdfVideoDecodeHwDeviceAdapter::SetInputCropOptionsL(const TRect& /* aRect */)
   225 	{
   226 	// the decoder is not configurable
   227 	User::Leave(KErrNotSupported);
   228 	}
   229 
   230 /*
   231  @see CMMFVideoPlayHwDevice::SetYuvToRgbOptionsL()
   232  */
   233 void CMdfVideoDecodeHwDeviceAdapter::SetYuvToRgbOptionsL(const TYuvToRgbOptions& /* aOptions */, const TYuvFormat& /* aYuvFormat */, TRgbFormat /* aRgbFormat */)
   234 	{
   235 	// the decoder is not configurable
   236 	User::Leave(KErrNotSupported);
   237 	}
   238 
   239 /*
   240  @see CMMFVideoPlayHwDevice::SetYuvToRgbOptionsL()
   241  */
   242 void CMdfVideoDecodeHwDeviceAdapter::SetYuvToRgbOptionsL(const TYuvToRgbOptions& /* aOptions */)
   243 	{
   244 	// the decoder is not configurable
   245 	User::Leave(KErrNotSupported);
   246 	}
   247 
   248 /*
   249  @see CMMFVideoPlayHwDevice::SetRotateOptionsL()
   250  */
   251 void CMdfVideoDecodeHwDeviceAdapter::SetRotateOptionsL(TRotationType /* aRotationType */)
   252 	{
   253 	// the decoder is not configurable
   254 	User::Leave(KErrNotSupported);
   255 	}
   256 
   257 /*
   258  @see CMMFVideoPlayHwDevice::SetScaleOptionsL()
   259  */
   260 void CMdfVideoDecodeHwDeviceAdapter::SetScaleOptionsL(const TSize& /* aTargetSize */, TBool /* aAntiAliasFiltering */)
   261 	{
   262 	// the decoder is not configurable
   263 	User::Leave(KErrNotSupported);
   264 	}
   265 
   266 /*
   267  @see CMMFVideoPlayHwDevice::SetOutputCropOptionsL()
   268  */
   269 void CMdfVideoDecodeHwDeviceAdapter::SetOutputCropOptionsL(const TRect& /* aRect */)
   270 	{
   271 	// the decoder is not configurable
   272 	User::Leave(KErrNotSupported);
   273 	}
   274 
   275 /*
   276  @see CMMFVideoPlayHwDevice::SetPostProcSpecificOptionsL()
   277  */
   278 void CMdfVideoDecodeHwDeviceAdapter::SetPostProcSpecificOptionsL(const TDesC8& /* aOptions */)
   279 	{
   280 	// the decoder is not configurable
   281 	User::Leave(KErrNotSupported);
   282 	}
   283 
   284 /*
   285  @see CMMFVideoPlayHwDevice::Initialize()
   286  */
   287 void CMdfVideoDecodeHwDeviceAdapter::Initialize()
   288 	{
   289 	__ASSERT_ALWAYS(iProxy, DevVideoHwDeviceDecoderPanic(0));
   290 
   291 	TRAPD(err, InitializeL());
   292 	if(err == KErrNone && !iPUInitialized)
   293 		{
   294 		err = KErrNotSupported;		
   295 		}	
   296 	iProxy->MdvppInitializeComplete(this, err);
   297 	}
   298 
   299 // private method : body of Initialize()
   300 void CMdfVideoDecodeHwDeviceAdapter::InitializeL()
   301 	{
   302 	// pre-check format
   303 	switch(iFormat.iDataFormat) 
   304 		{
   305 		case 0:
   306 			User::Leave(KErrNotReady);
   307 			break;
   308 		case ERgbRawData:
   309 		case ERgbFbsBitmap:
   310 		case EYuvRawData:
   311 			break;
   312 		default:
   313 			User::Leave(KErrNotSupported);
   314 			break;
   315 		}
   316 		
   317 	// create and initialise the buffer manager
   318 	iBufferManager = CMdfVideoDecoderBufferManager::NewL();
   319 
   320 	iBufferManager->Init(iFormat);
   321 	iBufferManager->SetFrameSize(iFrameSize);
   322 	
   323 	DEBUG_PRINT(_L("HwDevice: Buffer Manager initialized"));
   324 
   325 	// The actual frame rate will come from the VOL headers.
   326 	iFrameRate = KTenFPS;
   327 	
   328 	// reset the player flags
   329 	iPrimed = EFalse;
   330 	iInputBufferWaiting = EFalse;	
   331 	iInputEnd = EFalse;
   332 	
   333 	// create the player engine
   334 	iPlayerEngine = CMdfVideoPlayerEngine::NewL(*this);
   335 
   336 	RPointerArray<MMdfInputPort> inputPorts;
   337 	// Get ports and set observers
   338 	User::LeaveIfError(iDecoderPU->GetInputPorts(inputPorts));
   339 	if (inputPorts.Count()==0)
   340 		{
   341 		inputPorts.Close();
   342 		User::Leave(KErrNotFound);
   343 		}
   344 	iDecoderPUInputPort = inputPorts[0];
   345 	iDecoderPUInputPort->MipSetObserver(*this);
   346 	inputPorts.Close();
   347 
   348 	RPointerArray<MMdfOutputPort> outputPorts;
   349 	User::LeaveIfError(iDecoderPU->GetOutputPorts(outputPorts));
   350 	if (outputPorts.Count()==0)
   351 		{
   352 		outputPorts.Close();
   353 		User::Leave(KErrNotFound);
   354 		}
   355 	iDecoderPUOutputPort = outputPorts[0];
   356 	iDecoderPUOutputPort->MopSetObserver(*this);
   357 	outputPorts.Close();
   358 		
   359 	iState = EProcessingUnitLoaded;
   360 
   361 	DEBUG_PRINT(_L("HwDevice: Decoder Processing Unit Loaded"));
   362 	
   363 	// Create the buffers that are associated with the input and output ports
   364 	iInputBuffer = &iBufferManager->CreateDataBufferL(iDecoderPUInputPort->MipBufferSize());
   365 	iPUInputBuffer = *iInputBuffer;
   366 	User::LeaveIfError(iDecoderPUInputPort->MipUseBuffer(*iPUInputBuffer));		
   367 	
   368 	CVideoFrameBuffer& frameBuffer = iBufferManager->CreateFrameBufferL(TMMFDisplayModeUtils::DisplayMode(iFormat.iRgbFormat));
   369 	User::LeaveIfError(iDecoderPUOutputPort->MopUseBuffer(frameBuffer));
   370 	
   371 	// VD: should not move the set up of the state after sending the Initialize() calls???
   372 	iState = EProcessingUnitInitializing;
   373 
   374 	// async call, that calls back to InitializeComplete()
   375 	iDecoderPU->Initialize();	
   376 		
   377 	DEBUG_PRINT(_L("HwDevice: Initialized OK"));
   378 	}
   379 
   380 /*
   381  @see CMMFVideoPlayHwDevice::StartDirectScreenAccessL()
   382  */
   383 void CMdfVideoDecodeHwDeviceAdapter::StartDirectScreenAccessL(const TRect& aVideoRect, CFbsScreenDevice& aScreenDevice, const TRegion& aClipRegion)
   384 	{
   385 	// ensure SetVideoDestScreenL() has been called
   386 	if(!iDSAEnabled)
   387 		{
   388 		User::Leave(KErrNotReady);
   389 		}
   390 	
   391 	DEBUG_PRINT(_L("HwDevice: Starting DSA"));
   392 
   393 	iDSAStarted = ETrue;
   394 
   395 	// the CDirectScreenAccess must be created by the client app.
   396 	// the CFbsScreenDevice (only) is passed across...
   397 	// we need to blit the bitmap into it, i.e. we need to create our own GC
   398 	if(!iScreenDevice) 
   399 		{		
   400 		User::LeaveIfError(aScreenDevice.CreateContext(iScreenDeviceGc));
   401 		iScreenDevice = &aScreenDevice;
   402 		iScreenDeviceRect = aVideoRect;
   403 		iScreenDeviceGc->SetClippingRegion(aClipRegion);
   404 		}
   405 	}
   406 
   407 /*
   408  @see CMMFVideoPlayHwDevice::SetScreenClipRegion()
   409  */
   410 void CMdfVideoDecodeHwDeviceAdapter::SetScreenClipRegion(const TRegion& aRegion)
   411 	{
   412 	__ASSERT_ALWAYS(iScreenDeviceGc, DevVideoHwDeviceDecoderPanic(0));
   413 
   414 	iScreenDeviceGc->SetClippingRegion(aRegion);
   415 	}
   416 
   417 /*
   418  @see CMMFVideoPlayHwDevice::SetPauseOnClipFail()
   419  */
   420 void CMdfVideoDecodeHwDeviceAdapter::SetPauseOnClipFail(TBool /* aPause */)
   421 	{
   422 	// not implemented - will pause by default
   423 	}
   424 
   425 /*
   426  @see CMMFVideoPlayHwDevice::AbortDirectScreenAccess()
   427  */
   428 void CMdfVideoDecodeHwDeviceAdapter::AbortDirectScreenAccess()
   429 	{
   430 	DEBUG_PRINT(_L("HwDevice: Stopping DSA"));
   431 	iDSAStarted = EFalse;
   432 	}
   433 
   434 /*
   435  @see CMMFVideoPlayHwDevice::IsPlaying()
   436  */
   437 TBool CMdfVideoDecodeHwDeviceAdapter::IsPlaying()
   438 	{
   439 	return (iState == EProcessingUnitExecuting ? ETrue : EFalse);
   440 	}
   441 
   442 /*
   443  @see CMMFVideoPlayHwDevice::Redraw()
   444  */
   445 void CMdfVideoDecodeHwDeviceAdapter::Redraw()
   446 	{
   447 	if(iDSAStarted) 
   448 		{
   449 		DisplayLastFrameDirect(); 
   450 		}
   451 	}
   452 
   453 /*
   454  @see CMMFVideoPlayHwDevice::Start()
   455  */
   456 void CMdfVideoDecodeHwDeviceAdapter::Start()
   457 	{
   458 	__ASSERT_ALWAYS(iPlayerEngine, DevVideoHwDeviceDecoderPanic(0));
   459 	__ASSERT_ALWAYS(iDecoderPU, DevVideoHwDeviceDecoderPanic(0));
   460 	
   461 	if(iState != EProcessingUnitExecuting)
   462 		{		
   463 		CVideoFrameBuffer* frameBuffer = NULL;
   464 		TRAPD(err, frameBuffer = &iBufferManager->GetEmptyFrameBufferL(ETrue));
   465 		if (err != KErrNone)
   466 			{
   467 			iProxy->MdvppFatalError(this, err);
   468 			return;
   469 			}
   470 		
   471 		iDecoderPUOutputPort->MopReadData(*frameBuffer);
   472 		
   473 		iDecoderPU->Execute();
   474 		TProcessingUnitState puState = iDecoderPU->State();
   475 		if(puState == EProcessingUnitInvalid) 
   476 			{
   477 			return;	
   478 			}
   479 		iState = EProcessingUnitExecuting;
   480 
   481 		// if we are using raw decoding, then play as fast as we can,
   482 		// otherwise use the actual frame rate
   483 		TInt playerFrameRate;
   484 		if(iSynchronize) 
   485 			{
   486 			playerFrameRate = TInt(iFrameRate);
   487 			}
   488 		else 
   489 			{
   490 			playerFrameRate = CMdfVideoPlayerEngine::KUnsynchronized;
   491 			}
   492 		TRAP(err, iPlayerEngine->StartL(playerFrameRate));			
   493 		if(err != KErrNone) 
   494 			{
   495 			// the player failed to start. this is a fatal error
   496 			iProxy->MdvppFatalError(this, err);
   497 			}
   498 		else 
   499 			{			
   500 			iProxy->MdvppNewBuffers();
   501 			}
   502 		}
   503 	}
   504 
   505 /*
   506  @see CMMFVideoPlayHwDevice::Stop()
   507  */
   508 void CMdfVideoDecodeHwDeviceAdapter::Stop()
   509 	{
   510 	if(iState == EProcessingUnitExecuting)
   511 		{
   512 		iPlayerEngine->Stop();
   513 		iDecoderPU->Stop();		
   514 		iState = EProcessingUnitIdle;
   515 		}
   516 	}
   517 
   518 /*
   519  @see CMMFVideoPlayHwDevice::Pause()
   520  */
   521 void CMdfVideoDecodeHwDeviceAdapter::Pause()
   522 	{
   523 	Stop();
   524 	}
   525 
   526 /*
   527  @see CMMFVideoPlayHwDevice::Resume()
   528  */
   529 void CMdfVideoDecodeHwDeviceAdapter::Resume()
   530 	{
   531 	Start();
   532 	}
   533 
   534 /*
   535  @see CMMFVideoPlayHwDevice::SetPosition()
   536  */
   537 void CMdfVideoDecodeHwDeviceAdapter::SetPosition(const TTimeIntervalMicroSeconds& aPlaybackPosition)
   538 	{
   539 	TPuConfigTimestamp timeStamp(aPlaybackPosition);
   540 	// we have no way report a failure here, and it is not a fatal error so any error is ignored
   541 	iDecoderPU->Configure(timeStamp);
   542 	}
   543 /*
   544  @see CMMFVideoPlayHwDevice::FreezePicture()
   545  */
   546 void CMdfVideoDecodeHwDeviceAdapter::FreezePicture(const TTimeIntervalMicroSeconds& /* aTimestamp */)
   547 	{
   548 	// not supported; we have no presentation timestamps
   549 	// however should not cause a fatal error
   550 	}
   551 
   552 /*
   553  @see CMMFVideoPlayHwDevice::ReleaseFreeze()
   554  */
   555 void CMdfVideoDecodeHwDeviceAdapter::ReleaseFreeze(const TTimeIntervalMicroSeconds& /* aTimestamp */)
   556 	{
   557 	// not supported; we have no presentation timestamps
   558 	// however should not cause a fatal error
   559 	}
   560 
   561 /*
   562  @see CMMFVideoPlayHwDevice::PlaybackPosition()
   563  */
   564 TTimeIntervalMicroSeconds CMdfVideoDecodeHwDeviceAdapter::PlaybackPosition()
   565 	{
   566 	if(iFrameRate == 0.0) 
   567 		{
   568 		return 0;
   569 		}
   570 	// this is the total number of pictures displayed or discarded
   571 	// NB it is NOT equivalent to the number of pictures decoded, as the
   572 	// player may be running a few frames behind the decoder	
   573 	return ((iPictureCounters.iPicturesDisplayed + iPictureCounters.iPicturesSkipped) * (KOneSecond / (TInt)iFrameRate));
   574 	}
   575 
   576 /*
   577  @see CMMFVideoPlayHwDevice::PictureBufferBytes()
   578  */
   579 TUint CMdfVideoDecodeHwDeviceAdapter::PictureBufferBytes()
   580 	{
   581 	__ASSERT_ALWAYS(iBufferManager, DevVideoHwDeviceDecoderPanic(0));
   582 	
   583 	return (iBufferManager->FrameBufferSize() * iBufferManager->MaxFrameBuffers());
   584 	}
   585 
   586 /*
   587  @see CMMFVideoPlayHwDevice::GetPictureCounters()
   588  */
   589 void CMdfVideoDecodeHwDeviceAdapter::GetPictureCounters(CMMFDevVideoPlay::TPictureCounters& aCounters)
   590 	{
   591 	aCounters = iPictureCounters;
   592 	}
   593 
   594 /*
   595  @see CMMFVideoPlayHwDevice::SetComplexityLevel()
   596  */
   597 void CMdfVideoDecodeHwDeviceAdapter::SetComplexityLevel(TUint /* aLevel */)
   598 	{
   599 	// separate complexity levels are not available; ignored
   600 	}
   601 
   602 /*
   603  @see CMMFVideoPlayHwDevice::NumComplexityLevels()
   604  */
   605 TUint CMdfVideoDecodeHwDeviceAdapter::NumComplexityLevels()
   606 	{
   607 	// separate complexity levels are not available; return 1
   608 	return 1;
   609 	}
   610 
   611 /*
   612  @see CMMFVideoPlayHwDevice::GetComplexityLevelInfo()
   613  */
   614 void CMdfVideoDecodeHwDeviceAdapter::GetComplexityLevelInfo(TUint aLevel, CMMFDevVideoPlay::TComplexityLevelInfo& aInfo)
   615 	{
   616 	// ignore call if aLevel is not 0
   617 	if(aLevel == 0) 
   618 		{
   619 		aInfo = iComplexityLevelInfo;
   620 		}
   621 	}
   622 
   623 /*
   624  @see CMMFVideoPlayHwDevice::ReturnPicture()
   625  */
   626 void CMdfVideoDecodeHwDeviceAdapter::ReturnPicture(TVideoPicture* aPicture)
   627 	{
   628 	__ASSERT_ALWAYS(iBufferManager, DevVideoHwDeviceDecoderPanic(0));
   629 
   630 	// return the frame buffer that has been emptied
   631 	TRAPD(err, iBufferManager->ReturnFrameBufferL(*aPicture, CVideoFrameBuffer::EEmptied));
   632 	if (err == KErrNone)
   633 		{
   634 		if (!iLastFrameBufferReceived)
   635 			{
   636 			
   637 			// request the next empty frame buffer
   638 			CVideoFrameBuffer* frameBuffer = NULL;
   639 			TRAP(err, frameBuffer = &iBufferManager->GetEmptyFrameBufferL(ETrue));
   640 			if (err == KErrNone)
   641 				{
   642 				CMMFBuffer* buffer = *frameBuffer;
   643 				iDecoderPUOutputPort->MopReadData(*buffer);
   644 				}
   645 			}
   646 		// DoPostPictureNotify() will handle MdvppStreamEnd()	
   647 		}
   648 	else
   649 		{
   650 		iProxy->MdvppFatalError(this, err);
   651 		}
   652 	ASSERT(err == KErrNone);
   653 	DoPostPictureNotify();
   654 	}
   655 
   656 /*
   657  @see CMMFVideoPlayHwDevice::GetSnapshotL()
   658  */
   659 TBool CMdfVideoDecodeHwDeviceAdapter::GetSnapshotL(TPictureData& /*aPictureData*/, const TUncompressedVideoFormat& /*aFormat*/)
   660 	{
   661 	// not supported - no presentation timestamps
   662 	User::Leave(KErrNotSupported);
   663 	return EFalse;
   664 	}
   665 
   666 /*
   667  @see CMMFVideoPlayHwDevice::GetTimedSnapshotL()
   668  */
   669 void CMdfVideoDecodeHwDeviceAdapter::GetTimedSnapshotL(TPictureData* /*aPictureData*/, const TUncompressedVideoFormat& /*aFormat*/, const TTimeIntervalMicroSeconds& /*aPresentationTimestamp*/)
   670 	{
   671 	// this method should be called on the post processor not on the decoder
   672 	// ending up here is a programming error and hence a PANIC condition
   673 	DevVideoHwDeviceDecoderPanic(0);
   674 	}
   675 
   676 /*
   677  @see CMMFVideoPlayHwDevice::GetTimedSnapshotL()
   678  */
   679 void CMdfVideoDecodeHwDeviceAdapter::GetTimedSnapshotL(TPictureData* /*aPictureData*/, const TUncompressedVideoFormat& /*aFormat*/, const TPictureId& /*aPictureId*/)
   680 	{
   681 	// this method should be called on the post processor not on the decoder
   682 	// ending up here is a programming error and hence a PANIC condition
   683 	DevVideoHwDeviceDecoderPanic(0);
   684 	}
   685 
   686 /*
   687  @see CMMFVideoPlayHwDevice::CancelTimedSnapshot()
   688  */
   689 void CMdfVideoDecodeHwDeviceAdapter::CancelTimedSnapshot()
   690 	{
   691 	// this method should be called on the post processor not on the decoder
   692 	// ending up here is a programming error and hence a PANIC condition
   693 	DevVideoHwDeviceDecoderPanic(0);
   694 	}
   695 
   696 /*
   697  @see CMMFVideoPlayHwDevice::GetSupportedSnapshotFormatsL()
   698  */
   699 void CMdfVideoDecodeHwDeviceAdapter::GetSupportedSnapshotFormatsL(RArray<TUncompressedVideoFormat>& /*aFormats*/)
   700 	{
   701 	// this method should be called on the post processor not on the decoder
   702 	// ending up here is a programming error and hence a PANIC condition
   703 	DevVideoHwDeviceDecoderPanic(0);
   704 	}
   705 
   706 /*
   707  @see CMMFVideoPlayHwDevice::InputEnd()
   708  */
   709 void CMdfVideoDecodeHwDeviceAdapter::InputEnd()
   710 	{
   711 	__ASSERT_ALWAYS(iBufferManager, DevVideoHwDeviceDecoderPanic(0));
   712 
   713 	DEBUG_PRINT(_L("HwDevice: Input end"));
   714 	
   715 	iInputEnd = ETrue;
   716 
   717 	// if there isn't an outstanding write to the PU, write
   718 	// an empty buffer	
   719 	if(!iWriteRequestOutstanding) 
   720 		{
   721 		SendLastBuffer();
   722 		}
   723 	}
   724 
   725 /*
   726  @see CMMFVideoDecodeHwDevice::VideoDecoderInfoLC()
   727  */
   728 CVideoDecoderInfo* CMdfVideoDecodeHwDeviceAdapter::VideoDecoderInfoLC()
   729 	{
   730 	// this is a complicated structure, ensure all fields are
   731 	// filled with some valid value
   732 	
   733 	//if PU is not loaded panic
   734 	if(iPuData == NULL)	
   735 		{
   736 		DevVideoHwDeviceDecoderPanic(KErrNotReady);	
   737 		}
   738 	// supported formats array
   739 	iInputVidFormats.Reset();
   740 	CCompressedVideoFormat* vidCV = NULL;
   741 	vidCV = CCompressedVideoFormat::NewL(iPuData->InputDataType() , KNullDesC8);
   742 	CleanupStack::PushL(vidCV);
   743 	iInputVidFormats.AppendL(vidCV);
   744 	CleanupStack::Pop(vidCV);	// CCompressedVideo object is destroyed in destructor
   745 	
   746 
   747 	// construct the video decoder info object
   748 	CVideoDecoderInfo* vInfo = CVideoDecoderInfo::NewL(
   749 		iPuUid, 
   750 		*iManufacturer,
   751 		KNullDesC,
   752 		TVersion(KVideoDecoderInfoVersionMaj, KVideoDecoderInfoVersionMin, KVideoDecoderInfoVersionBuild),
   753 		iInputVidFormats.Array(),
   754 		EFalse, // not accelerated
   755 		ETrue, // supports direct screen access
   756 		iMaxPictureSize, 
   757 		KMaxTUint32, // max bitrate supported
   758 		iPuData->MaxPictureRates().Array(),
   759 		EFalse, // picture loss not supported,
   760 		EFalse, // slice loss not supported,
   761 		KVideoDecoderInfoCSInfo,
   762 		KVideoDecoderInfoISInfo );
   763 
   764 	CleanupStack::PushL(vInfo);
   765 	return vInfo;
   766 	}
   767 
   768 
   769 /*
   770  @see CMMFVideoDecodeHwDevice::GetHeaderInformationL()
   771  */
   772  
   773 TVideoPictureHeader* CMdfVideoDecodeHwDeviceAdapter::GetHeaderInformationL(TVideoDataUnitType aDataUnitType, TVideoDataUnitEncapsulation aEncapsulation, TVideoInputBuffer* aDataUnit)
   774 	{
   775 	// NB this may be called EITHER before OR after the decoder is initialized.
   776 	// ensure at least that SetOutputFormatL() has been called before this, 
   777 	// as the decoder requires it to be able to initialize.
   778 	
   779 	__ASSERT_ALWAYS(iFormat.iDataFormat, DevVideoHwDeviceDecoderPanic(0));
   780 	
   781 	TDevVideoHeaderPuConfig header;
   782 	header.iDataUnitType = aDataUnitType;
   783 	header.iDataUnitEncapsulation = aEncapsulation;
   784 	header.iHeaderData.Set(aDataUnit->iData.Ptr(),aDataUnit->iData.Size());
   785 	
   786 	TPuConfigVideoHeader headerConfig(header);
   787 	
   788 	// Configure the decoder with the Header Information
   789 	User::LeaveIfError(iDecoderPU->Configure(headerConfig));
   790 	
   791 	// retrieve the picture information from the config structure
   792 	
   793 	TPuConfigVideoPictureHeader pict; 
   794 	User::LeaveIfError(iDecoderPU->GetConfig(pict));
   795 	
   796 	delete iPictureHeader;
   797 	iPictureHeader = NULL;
   798 	// Create a new header from the returned data
   799 	iPictureHeader = new (ELeave)TVideoPictureHeader(
   800 							*TPuConfigVideoPictureHeader::GetStructure(pict));
   801 	iFrameSize = iPictureHeader->iSizeInMemory;
   802 	return iPictureHeader;
   803 	
   804 	}
   805 
   806 /*
   807  @see CMMFVideoDecodeHwDevice::ConfigureDecoderL()
   808  */
   809 void CMdfVideoDecodeHwDeviceAdapter::ConfigureDecoderL(const TVideoPictureHeader& /* aVideoPictureHeader */)
   810 	{
   811 	// there is nothing configurable
   812 	User::Leave(KErrNotSupported);
   813 	}
   814 
   815 /*
   816  @see CMMFVideoDecodeHwDevice::ReturnHeader()
   817  */
   818 void CMdfVideoDecodeHwDeviceAdapter::ReturnHeader(TVideoPictureHeader* aHeader)
   819 	{
   820 	if(aHeader == iPictureHeader) // only free our created header
   821 		{
   822 		delete iPictureHeader;
   823 		iPictureHeader = NULL;	
   824 		}
   825 	}
   826 
   827 /*
   828  @see CMMFVideoDecodeHwDevice::SetInputFormatL()
   829  */
   830 void CMdfVideoDecodeHwDeviceAdapter::SetInputFormatL(const CCompressedVideoFormat& aFormat, TVideoDataUnitType aDataUnitType, TVideoDataUnitEncapsulation aEncapsulation, TBool aDataInOrder)
   831 	{
   832 	// EDuCodedPicture, EDuElementaryStream, aDataInOrder == ETrue
   833 	if(aFormat.MimeType() != iPuData->InputDataType()) 
   834 		{
   835 		User::Leave(KErrNotSupported);	
   836 		}
   837 	if(aDataUnitType != EDuCodedPicture) 
   838 		{
   839 		User::Leave(KErrNotSupported);	
   840 		}
   841 	if(aEncapsulation != EDuElementaryStream) 
   842 		{
   843 		User::Leave(KErrNotSupported);	
   844 		}
   845 	if(!aDataInOrder) 
   846 		{
   847 		User::Leave(KErrNotSupported);	
   848 		}
   849 	}
   850 
   851 /*
   852  @see CMMFVideoDecodeHwDevice::SynchronizeDecoding()
   853  */
   854 void CMdfVideoDecodeHwDeviceAdapter::SynchronizeDecoding(TBool aSynchronize)
   855 	{
   856 	iSynchronize = aSynchronize;
   857 	}
   858 
   859 /*
   860  @see CMMFVideoDecodeHwDevice::SetBufferOptionsL()
   861  */
   862 void CMdfVideoDecodeHwDeviceAdapter::SetBufferOptionsL(const CMMFDevVideoPlay::TBufferOptions& aOptions)
   863 	{
   864 	// check values are within the constraints of this device
   865 	if(aOptions.iPreDecoderBufferPeriod != 0) 
   866 		{
   867 		User::Leave(KErrNotSupported);
   868 		}
   869 	if(aOptions.iMaxPostDecodeBufferSize != 0) 
   870 		{
   871 		User::Leave(KErrNotSupported);
   872 		}
   873 	if(aOptions.iPreDecoderBufferPeriod != 0) 
   874 		{
   875 		User::Leave(KErrNotSupported);
   876 		}
   877 	if(aOptions.iPostDecoderBufferPeriod != 0) 
   878 		{
   879 		User::Leave(KErrNotSupported);
   880 		}
   881 	if(aOptions.iMaxInputBufferSize > KVideoDecoderMaxDataBufferSize) 
   882 		{
   883 		User::Leave(KErrNotSupported);
   884 		}
   885 	if(aOptions.iMinNumInputBuffers > 1) 
   886 		{
   887 		User::Leave(KErrNotSupported);
   888 		}
   889 	// input is OK; write it
   890 	iBufferOptions = aOptions;	
   891 	}
   892 
   893 /*
   894  @see CMMFVideoDecodeHwDevice::GetBufferOptions()
   895  */
   896 void CMdfVideoDecodeHwDeviceAdapter::GetBufferOptions(CMMFDevVideoPlay::TBufferOptions& aOptions)
   897 	{
   898 	aOptions = iBufferOptions;	
   899 	}
   900 
   901 /*
   902  @see CMMFVideoDecodeHwDevice::SetHrdVbvSpec()
   903  */
   904 void CMdfVideoDecodeHwDeviceAdapter::SetHrdVbvSpec(THrdVbvSpecification /* aHrdVbvSpec */, const TDesC8& /* aHrdVbvParams */)
   905 	{
   906 	// the decoder is not configurable
   907 	// however this should not cause a fatal error
   908 	}
   909 
   910 /*
   911  @see CMMFVideoDecodeHwDevice::SetOutputDevice()
   912  */
   913 void CMdfVideoDecodeHwDeviceAdapter::SetOutputDevice(CMMFVideoPostProcHwDevice* aDevice)
   914 	{
   915 	// we allow output to be sent to a post-processor,
   916 	// even though this plugin doesn not itself provide one
   917 	iPostProcOutputDevice = aDevice;
   918 	}
   919 
   920 /*
   921  @see CMMFVideoDecodeHwDevice::DecodingPosition()
   922  */
   923 TTimeIntervalMicroSeconds CMdfVideoDecodeHwDeviceAdapter::DecodingPosition()
   924 	{
   925 	if(iFrameRate == 0.0) 
   926 		{
   927 		return 0;
   928 		}
   929 	// this is the total number of pictures decoded	
   930 	return (iPictureCounters.iPicturesDecoded * (KOneSecond / (TInt)iFrameRate));
   931 	}
   932 
   933 /*
   934  @see CMMFVideoDecodeHwDevice::PreDecoderBufferBytes()
   935  */
   936 TUint CMdfVideoDecodeHwDeviceAdapter::PreDecoderBufferBytes()
   937 	{
   938 	return 0;
   939 	}
   940 
   941 /*
   942  @see CMMFVideoDecodeHwDevice::GetBitstreamCounters()
   943  */
   944 void CMdfVideoDecodeHwDeviceAdapter::GetBitstreamCounters(CMMFDevVideoPlay::TBitstreamCounters& aCounters)
   945 	{
   946 	aCounters = iBitstreamCounters;
   947 	}
   948 
   949 /*
   950  @see CMMFVideoDecodeHwDevice::NumFreeBuffers()
   951  */
   952 TUint CMdfVideoDecodeHwDeviceAdapter::NumFreeBuffers()
   953 	{
   954 	__ASSERT_ALWAYS(iBufferManager, DevVideoHwDeviceDecoderPanic(0));
   955 
   956 	if(!FrameBufferAvailable()) 
   957 		{
   958 		// if there are too many output buffers waiting, we refuse an input buffer
   959 		// until some output buffers have been processed.
   960 		return 0;
   961 		}
   962 	else 
   963 		{
   964 		return (iBufferManager->DataBuffersAvailable());
   965 		}
   966 	}
   967 
   968 /*
   969  @see CMMFVideoDecodeHwDevice::GetBufferL()
   970  
   971  This will return a buffer of the requested size, within min/max constraints
   972  */
   973 TVideoInputBuffer* CMdfVideoDecodeHwDeviceAdapter::GetBufferL(TUint /* aBufferSize */)
   974 	{
   975 	__ASSERT_ALWAYS(iBufferManager, DevVideoHwDeviceDecoderPanic(0));
   976 
   977 	TVideoInputBuffer& buf = iBufferManager->GetDataBufferL();
   978 	return &buf;
   979 	}
   980 
   981 /*
   982  @see CMMFVideoDecodeHwDevice::WriteCodedDataL()
   983  */
   984 void CMdfVideoDecodeHwDeviceAdapter::WriteCodedDataL(TVideoInputBuffer* aInputBuffer)
   985 	{
   986 	// Leave on null input buffer
   987 	if(!aInputBuffer) 
   988 		{
   989 		User::Leave(KErrArgument);
   990 		}
   991 		
   992 	// increment received buffer count
   993 	iBitstreamCounters.iTotalPackets++;
   994 	
   995 	CMMFDataBuffer* dataBuffer = static_cast<CMMFDataBuffer*>(iPUInputBuffer);
   996 	dataBuffer->Data().SetLength(aInputBuffer->iData.Length());
   997 	dataBuffer->SetPosition(0);
   998 	iDecoderPUInputPort->MipWriteData(*iPUInputBuffer);
   999 	iWriteRequestOutstanding = ETrue;	
  1000 	}
  1001 	
  1002 /*
  1003  @see CMMFVideoPlayHwDevice::CommitL()
  1004  */
  1005 void CMdfVideoDecodeHwDeviceAdapter::CommitL()
  1006 	{
  1007 	// the decoder is not configurable
  1008 	User::Leave(KErrNotSupported);
  1009 	}
  1010 	
  1011 /*
  1012  @see CMMFVideoPlayHwDevice::Revert()
  1013  */
  1014 void CMdfVideoDecodeHwDeviceAdapter::Revert()
  1015 	{
  1016 	// the decoder is not configurable
  1017 	// however this should not cause a fatal error
  1018 	}
  1019 
  1020 void CMdfVideoDecodeHwDeviceAdapter::SetProxy(MMMFDevVideoPlayProxy& aProxy)
  1021 	{
  1022 	ASSERT(!iProxy);
  1023 	iProxy = &aProxy;
  1024 	}
  1025 	
  1026 
  1027 /*
  1028  @see MMdfDecoderHwDeviceObserver::FrameBufferAvailable()
  1029  */
  1030 TBool CMdfVideoDecodeHwDeviceAdapter::FrameBufferAvailable() const
  1031 	{
  1032 	__ASSERT_ALWAYS(iBufferManager, DevVideoHwDeviceDecoderPanic(0));
  1033 
  1034 	return (iBufferManager->EmptyFrameBuffersAvailable() > 0);
  1035 	}
  1036 
  1037 /*
  1038  @see MMdfVideoPlayerHwDeviceObserver::Time()
  1039  */
  1040 TUint CMdfVideoDecodeHwDeviceAdapter::Time() const 
  1041 	{
  1042 	
  1043 	if(iClockSource) 
  1044 		{
  1045 		return iClockSource->Time().Int64();
  1046 		}
  1047 	else 
  1048 		{
  1049 		// system clock without HAL
  1050 		TInt64 tt64;
  1051 		TTime ttime;
  1052 		ttime.HomeTime();
  1053 		tt64 = ttime.Int64();
  1054 		return (tt64 - iSystemClock);
  1055 		}
  1056 	}
  1057 
  1058 /*
  1059  @see MMdfVideoPlayerHwDeviceObserver::DisplayFrame()
  1060  */
  1061 void CMdfVideoDecodeHwDeviceAdapter::DisplayFrame()
  1062 	{
  1063 	__ASSERT_ALWAYS(iBufferManager, DevVideoHwDeviceDecoderPanic(0));
  1064 
  1065 	CVideoFrameBuffer* frameBuffer = NULL;
  1066 	TRAPD(err, frameBuffer = &iBufferManager->GetFilledFrameBufferL(EFalse));
  1067 	if(err != KErrNone) 
  1068 		{
  1069 		// the buffer manager has failed
  1070 		DEBUG_PRINT(_L("HwDevice: Buffer Manager failed"));
  1071 		iProxy->MdvppFatalError(this, err);
  1072 		}
  1073 	else	
  1074 		{
  1075 		// is this the last buffer?
  1076 		iLastFrameBufferReceived = frameBuffer->LastBuffer();
  1077 		
  1078 		TVideoPicture& thePicture = *frameBuffer;
  1079 		
  1080 		// increment picture counter
  1081 		CMMFBuffer& theBuffer = *frameBuffer;
  1082 		if(theBuffer.BufferSize()) 
  1083 			{
  1084 			iPictureCounters.iPicturesDisplayed++;
  1085 			}
  1086 
  1087 		iDisplayPictureAvailable = EFalse;
  1088 		
  1089 		// send it to post-processor output, DSA, or the client
  1090 		if(iPostProcOutputDevice) 
  1091 			{
  1092 			TRAP(err, iPostProcOutputDevice->WritePictureL(&thePicture));
  1093 			}
  1094 		else if(iDSAStarted) 
  1095 			{
  1096 			DisplayFrameDirect(&thePicture);
  1097 			TRAP(err, iBufferManager->ReturnFrameBufferL(thePicture, CVideoFrameBuffer::EEmptied));
  1098 		
  1099 			if (!iLastFrameBufferReceived)
  1100 				{
  1101 				CVideoFrameBuffer* frameBuffer = NULL;
  1102 				TRAP(err, frameBuffer = &iBufferManager->GetEmptyFrameBufferL(ETrue));
  1103 				if (err == KErrNone)
  1104 					{
  1105 					iDecoderPUOutputPort->MopReadData(*frameBuffer);
  1106 					}
  1107 				else 
  1108 					{
  1109 					iProxy->MdvppFatalError(this, err);		
  1110 					return;
  1111 					}
  1112 				}
  1113 			// DoPostPictureNotify() will handle MdvppStreamEnd()	
  1114 			// NB we need to notify the client here as there will be no callback
  1115 			DoPostPictureNotify(); 
  1116 			}
  1117 		else 
  1118 			{
  1119 			iProxy->MdvppNewPicture(&thePicture);
  1120 			}
  1121 		}
  1122 	}
  1123 
  1124 /*
  1125  @see MMdfVideoPlayerHwDeviceObserver::DiscardFrame()
  1126  */
  1127 void CMdfVideoDecodeHwDeviceAdapter::DiscardFrame()
  1128 	{
  1129 	__ASSERT_ALWAYS(iBufferManager, DevVideoHwDeviceDecoderPanic(0));
  1130 
  1131 	CVideoFrameBuffer* frameBuffer = NULL;
  1132 	TVideoPicture* thePicture = NULL;
  1133 	TRAPD(err, frameBuffer = &iBufferManager->GetFilledFrameBufferL(EFalse));
  1134 	if(err != KErrNone) 
  1135 		{
  1136 		// the buffer manager has failed
  1137 		DEBUG_PRINT(_L("HwDevice: Buffer Manager failed"));
  1138 		iProxy->MdvppFatalError(this, err);
  1139 		}
  1140 	else	
  1141 		{
  1142 		thePicture = *frameBuffer;
  1143 
  1144 		// increment picture counter
  1145 		CMMFBuffer& theBuffer = *frameBuffer;
  1146 		if(theBuffer.BufferSize()) 
  1147 			{
  1148 			iPictureCounters.iPicturesSkipped++;	
  1149 			}
  1150 
  1151 		iDisplayPictureAvailable = EFalse;
  1152 
  1153 		// this should never leave, as thePicture has been given to us by 
  1154 		// iBufferManager to start with.
  1155 		TRAP(err, iBufferManager->ReturnFrameBufferL(*thePicture, CVideoFrameBuffer::EEmptied));
  1156 		if (err != KErrNone)
  1157 			{			
  1158 			DEBUG_PRINT(_L("HwDevice: ReturnFrameBufferL failed"));
  1159 			iProxy->MdvppFatalError(this, err);
  1160 			}		
  1161 
  1162 		TRAP(err, frameBuffer = &iBufferManager->GetEmptyFrameBufferL(ETrue));
  1163 		if (err == KErrNone)
  1164 			{
  1165 			iDecoderPUOutputPort->MopReadData(*frameBuffer);
  1166 			}
  1167 	
  1168 		// NB we need to notify the client here as there will be no callback
  1169 		DoPostPictureNotify(); 
  1170 		}
  1171 	}
  1172 
  1173 /*
  1174  @see MMdfVideoPlayerHwDeviceObserver::FrameAvailable()
  1175  */
  1176 TBool CMdfVideoDecodeHwDeviceAdapter::FrameAvailable() const
  1177 	{
  1178 	return iDisplayPictureAvailable;
  1179 	}
  1180 	
  1181 /*
  1182  @see MMdfInputPortObserver::MipoWriteDataComplete()
  1183  */
  1184 void CMdfVideoDecodeHwDeviceAdapter::MipoWriteDataComplete(const MMdfInputPort* aInputPort,
  1185 		CMMFBuffer* /* aBuffer */, TInt aErrorCode)
  1186 	{
  1187 	iWriteRequestOutstanding = EFalse;
  1188 	__ASSERT_ALWAYS(aInputPort == iDecoderPUInputPort, DevVideoHwDeviceDecoderPanic(0));
  1189 	if (aErrorCode != KErrNone)
  1190 		{
  1191 		iProxy->MdvppFatalError(this, aErrorCode);
  1192 		return;
  1193 		}
  1194 	// Return the data buffer, the position tells us how much data
  1195 	// was used	
  1196 	if (!iInputEnd)
  1197 		{
  1198 		TRAPD(err, iBufferManager->ReturnDataBufferL(*iInputBuffer));
  1199 		if(err == KErrNone)
  1200 			{
  1201 			iProxy->MdvppNewBuffers();
  1202 			}	
  1203 		else
  1204 			{
  1205 			iProxy->MdvppFatalError(this, err);
  1206 			}
  1207 		}
  1208 	else
  1209 		{
  1210 		// Send an empty buffer to the decoder to signal the
  1211 		// end of the stream
  1212 		SendLastBuffer();
  1213 		}
  1214 	}
  1215 	
  1216 /*
  1217  @see MMdfInputPortObserver::MipoStopComplete()
  1218  */		
  1219 void CMdfVideoDecodeHwDeviceAdapter::MipoDisconnectTunnelComplete(const MMdfInputPort* /* aInputPort */,
  1220 	TInt /* aErrorCode */)
  1221 	{	
  1222 	}
  1223 	
  1224 /*
  1225  @see MMdfInputPortObserver::MipoRestartComplete()
  1226  */		
  1227 void CMdfVideoDecodeHwDeviceAdapter::MipoRestartTunnelComplete(const MMdfInputPort* /* aInputPort */,
  1228 	TInt /* aErrorCode */)
  1229 	{	
  1230 	}
  1231 	
  1232 /*
  1233  @see MMdfOutputPortObserver::MopoReadDataComplete()
  1234  */
  1235 void CMdfVideoDecodeHwDeviceAdapter::MopoReadDataComplete(const MMdfOutputPort* aOutputPort,
  1236 	CMMFBuffer* aBuffer, TInt aErrorCode)	
  1237 	{
  1238 	if(aErrorCode != KErrNone)
  1239 		{
  1240 		iProxy->MdvppFatalError(this, aErrorCode);
  1241 		return;
  1242 		}
  1243 	
  1244 	if(aOutputPort != iDecoderPUOutputPort)
  1245 		{
  1246 		iProxy->MdvppFatalError(this, KErrArgument);
  1247 		return;
  1248 		}
  1249 		
  1250 	// increment iPicturesDecoded
  1251 	if(aBuffer->BufferSize())
  1252 		{
  1253 		iPictureCounters.iPicturesDecoded++; 
  1254 		}
  1255 
  1256 	iDisplayPictureAvailable = ETrue;
  1257 	
  1258 	TRAPD(err, iBufferManager->ReturnFrameBufferL(aBuffer, CVideoFrameBuffer::EFilled, aBuffer->LastBuffer()));
  1259 	if(err != KErrNone)
  1260 		{
  1261 		iProxy->MdvppFatalError(this, err);
  1262 		}			
  1263 	}
  1264 
  1265 /*
  1266  @see MMdfOutputPortObserver::MopoStopComplete()
  1267  */	
  1268 void CMdfVideoDecodeHwDeviceAdapter::MopoDisconnectTunnelComplete(const MMdfOutputPort* /* aOutputPort */,
  1269 	TInt /* aErrorCode */)
  1270 	{	
  1271 	}
  1272 
  1273 /*
  1274  @see MMdfOutputPortObserver::MopoRestartComplete()
  1275  */	
  1276 void CMdfVideoDecodeHwDeviceAdapter::MopoRestartTunnelComplete(const MMdfOutputPort* /* aOutputPort */,
  1277 	TInt /* aErrorCode */)
  1278 	{	
  1279 	}
  1280 	
  1281 /*
  1282  @see MMdfProcessingUnitObserver::InitializeComplete()
  1283  */	
  1284 void CMdfVideoDecodeHwDeviceAdapter::InitializeComplete(const CMdfProcessingUnit* aPu, TInt aErrorCode)
  1285 	{
  1286 	__ASSERT_ALWAYS(aPu == iDecoderPU, DevVideoHwDeviceDecoderPanic(0));
  1287 	
  1288 	if(aErrorCode != KErrNone)
  1289 		{
  1290 		iProxy->MdvppFatalError(this, aErrorCode);
  1291 		return;
  1292 		}
  1293 			
  1294 	iPUInitialized = ETrue;	
  1295 	}
  1296 	
  1297 /*
  1298  @see MMdfProcessingUnitObserver::ExecuteComplete()
  1299  */	
  1300 void CMdfVideoDecodeHwDeviceAdapter::ExecuteComplete(const CMdfProcessingUnit* aPu, TInt aErrorCode)
  1301 	{
  1302 	__ASSERT_ALWAYS(aPu == iDecoderPU, DevVideoHwDeviceDecoderPanic(0));
  1303 	
  1304 	if(aErrorCode != KErrNone)
  1305 		{
  1306 		iProxy->MdvppFatalError(this, aErrorCode);
  1307 		return;
  1308 		}	
  1309 	
  1310 	if (iState == EProcessingUnitExecuting)
  1311 		{
  1312 		DEBUG_PRINT(_L("HwDevice: 3() - Stream end"));
  1313 		iProxy->MdvppStreamEnd();
  1314 		iState = EProcessingUnitIdle;
  1315 		}			
  1316 	}	
  1317 
  1318 // private method - DoPostPictureNotify
  1319 void CMdfVideoDecodeHwDeviceAdapter::DoPostPictureNotify()
  1320 	{
  1321 	__ASSERT_ALWAYS(iBufferManager, DevVideoHwDeviceDecoderPanic(0));
  1322 
  1323 	DEBUG_PRINT(_L("HwDevice: PostPictureNotify"));
  1324 	// notify the client that an input buffer is available if we weren't able to
  1325 	// do it before
  1326 	if(iInputBufferWaiting && iBufferManager->DataBuffersAvailable()) 
  1327 		{
  1328 		iInputBufferWaiting = EFalse;
  1329 		iProxy->MdvppNewBuffers();
  1330 		}
  1331 	
  1332 	// at this point, if there are no frames left, the input buffer is free
  1333 	// and InputEnd() has been called, then we have finished.
  1334 	if(iInputEnd && !iBufferManager->FilledFrameBuffersAvailable() && iBufferManager->DataBuffersAvailable()) 
  1335 		{
  1336 		iLastFrameBufferReceived = ETrue;
  1337 		}
  1338 		
  1339 	// NB iLastFrameBufferReceived may have been set beforehand
  1340 	if(iLastFrameBufferReceived)
  1341 		{
  1342 		DEBUG_PRINT(_L("HwDevice: Stream end"));
  1343 		iProxy->MdvppStreamEnd();
  1344 		}
  1345 	}
  1346 
  1347 // private method - display the frame using direct screen access
  1348 void CMdfVideoDecodeHwDeviceAdapter::DisplayFrameDirect(TVideoPicture* aPicture) 
  1349 	{
  1350 	__ASSERT_ALWAYS(iScreenDevice, DevVideoHwDeviceDecoderPanic(0));
  1351 	
  1352 	DEBUG_PRINT(_L("HwDevice: Displaying frame using DSA"));
  1353 	// draw into our GC
  1354 	// NB this will only work if the picture is a CFbsBitmap
  1355 	CFbsBitmap* theBitmap = aPicture->iData.iRgbBitmap;
  1356 	iScreenDeviceGc->DrawBitmap(iScreenDeviceRect, theBitmap);
  1357 	iScreenDevice->Update();	
  1358 	}
  1359 	
  1360 // private method - display the last frame using direct screen access
  1361 void CMdfVideoDecodeHwDeviceAdapter::DisplayLastFrameDirect() 
  1362 	{
  1363 	__ASSERT_ALWAYS(iScreenDevice, DevVideoHwDeviceDecoderPanic(0));
  1364 
  1365 	DEBUG_PRINT(_L("HwDevice: Redrawing last frame using DSA"));
  1366 	// redraw
  1367 	// NB this will only work if the picture is a CFbsBitmap
  1368 	const TPictureData* lastFrame = NULL;
  1369 	TRAPD(err, lastFrame = &iBufferManager->LastPictureL());
  1370 	if(!err) 
  1371 		{
  1372 		CFbsBitmap* theBitmap = lastFrame->iRgbBitmap;
  1373 		iScreenDeviceGc->DrawBitmap(iScreenDeviceRect, theBitmap);
  1374 		iScreenDevice->Update();
  1375 		}
  1376 	}
  1377 
  1378 void CMdfVideoDecodeHwDeviceAdapter::LoadProcessingUnitL(const CImplementationInformation& aImplInfo)
  1379 	{
  1380 	__ASSERT_ALWAYS(iPuLoader, DevVideoHwDeviceDecoderPanic(0));
  1381 	iPuUid = aImplInfo.ImplementationUid();
  1382 	iDecoderPU = iPuLoader->LoadProcessingUnitL(*this, iPuUid);	
  1383 	// store the opaque data associated with this PU so we can extract information about 
  1384 	// the PU later
  1385 	iPuData = CCodecApiVideoOpaqueData::NewL(aImplInfo.OpaqueData());
  1386 	iManufacturer = HBufC::NewL(iPuData->Manufacturer().Length());
  1387 	iManufacturer->Des().Copy(iPuData->Manufacturer());
  1388 	iMaxPictureSize = iPuData->MaxPictureSize();
  1389 	}
  1390 
  1391 void CMdfVideoDecodeHwDeviceAdapter::SendLastBuffer()
  1392 	{
  1393 	__ASSERT_ALWAYS(iPUInputBuffer, DevVideoHwDeviceDecoderPanic(0));
  1394 	__ASSERT_ALWAYS(iDecoderPUInputPort, DevVideoHwDeviceDecoderPanic(0));
  1395 	// Send an empty buffer to the decoder to signal the
  1396 	// end of the stream
  1397 	iPUInputBuffer->SetLastBuffer(ETrue);
  1398 	CMMFDataBuffer* dataBuffer = static_cast<CMMFDataBuffer*>(iPUInputBuffer);
  1399 	dataBuffer->Data().SetLength(0);
  1400 	dataBuffer->SetPosition(0);
  1401 	iDecoderPUInputPort->MipWriteData(*iPUInputBuffer);	
  1402 	}