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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include <mmf/devvideo/devvideopuconfig.h>
17 #include "mdfvideodecodehwdeviceadapter.h"
18 #include "displaymodeutils.h"
20 #if defined (SYMBIAN_MDFVIDEODECODERHWDEVICE_DEBUG)
21 #define DEBUG_PRINT RDebug::Print
24 #endif // defined (SYMBIAN_MDFVIDEODECODERHWDEVICE_DEBUG)
26 const TInt KOutputFormatsArraySize = 3;
27 const TInt KTenFPS = 10;
28 const TInt KOneSecond = 1000000;
29 const TInt KInputBufferSize = 8192;
31 _LIT(KDevVideoHwDeviceDecoderPanicCategory, "DevVideoHwDeviceDecoder");
32 void DevVideoHwDeviceDecoderPanic(TInt aReason)
34 User::Panic(KDevVideoHwDeviceDecoderPanicCategory, aReason);
38 Constructs a new instance of CMdfVideoDecodeHwDeviceAdapter.
39 @return "CMdfVideoDecodeHwDeviceAdapter*"
40 A pointer to the newly constructed HwDevice
42 CMdfVideoDecodeHwDeviceAdapter* CMdfVideoDecodeHwDeviceAdapter::NewL()
44 CMdfVideoDecodeHwDeviceAdapter* self = new (ELeave) CMdfVideoDecodeHwDeviceAdapter;
45 CleanupStack::PushL(self);
47 CleanupStack::Pop(self);
54 CMdfVideoDecodeHwDeviceAdapter::CMdfVideoDecodeHwDeviceAdapter()
58 void CMdfVideoDecodeHwDeviceAdapter::ConstructL()
60 // system clock without HAL
67 // reset picture format
68 iFormat.iDataFormat = (TImageDataFormat)0;
70 // Load the PU Loader plugin
71 iPuLoader = static_cast<CMdfPuLoader*>
72 (REComSession::CreateImplementationL(TUid::Uid(KUidPuLoaderImplementation), iPuLoaderDtorKey));
73 iState = EProcessingUnitLoaderLoaded;
79 CMdfVideoDecodeHwDeviceAdapter::~CMdfVideoDecodeHwDeviceAdapter()
81 DEBUG_PRINT(_L("HwDevice: Destroying"));
82 // stop playing if necessary
86 delete iScreenDeviceGc;
88 // destroy the buffer manager
89 delete iBufferManager;
90 // destroy the picture header
91 delete iPictureHeader;
93 // Unload the DecoderPU
96 iPuLoader->UnloadProcessingUnit(iDecoderPU);
101 delete iManufacturer;
102 REComSession::DestroyedImplementation(iPuLoaderDtorKey);
104 iInputVidFormats.ResetAndDestroy(); // will destroy contents as well
105 iOutputVidFormats.Close();
106 iPictureRates.Close();
108 DEBUG_PRINT(_L("HwDevice: Destroyed"));
112 @see CMMFVideoHwDevice::CustomInterface()
114 TAny* CMdfVideoDecodeHwDeviceAdapter::CustomInterface(TUid aInterface)
116 if (aInterface.iUid == KUidDevVideoHwDeviceAdapterSetup)
118 return static_cast<MDevVideoHwDeviceAdapterSetup*>(this);
124 @see CMMFVideoPlayHwDevice::PostProcessorInfoLC()
126 CPostProcessorInfo* CMdfVideoDecodeHwDeviceAdapter::PostProcessorInfoLC()
128 // post processor info will be obtained from the post processor plugin, if any
133 @see CMMFVideoPlayHwDevice::GetOutputFormatListL()
135 void CMdfVideoDecodeHwDeviceAdapter::GetOutputFormatListL(RArray<TUncompressedVideoFormat>& aFormats)
137 // TUncompressedVideoFormats is a union - therefore using hard initialisation
138 iOutputVidFormats.Reset();
139 TUncompressedVideoFormat outputFormats[KOutputFormatsArraySize];
141 outputFormats[0].iDataFormat = ERgbRawData;
142 outputFormats[0].iRgbFormat = ERgb16bit565;
143 iOutputVidFormats.AppendL(outputFormats[0]);
144 aFormats.AppendL(outputFormats[0]);
146 outputFormats[1].iDataFormat = ERgbFbsBitmap;
147 outputFormats[1].iRgbFormat = EFbsBitmapColor16M;
148 iOutputVidFormats.AppendL(outputFormats[1]);
149 aFormats.AppendL(outputFormats[1]);
151 outputFormats[2].iDataFormat = EYuvRawData;
152 iOutputVidFormats.AppendL(outputFormats[2]);
153 aFormats.AppendL(outputFormats[2]);
157 @see CMMFVideoPlayHwDevice::SetOutputFormatL()
159 void CMdfVideoDecodeHwDeviceAdapter::SetOutputFormatL(const TUncompressedVideoFormat& aFormat)
161 // check size and format are supported
162 if(iOutputVidFormats.Count() == 0)
164 User::Leave(KErrNotReady);
166 if(!iOutputVidFormats.Find(aFormat))
168 User::Leave(KErrNotSupported);
172 TDevVideoPlayPuConfig decodeConfig;
173 decodeConfig.iImageFormat = iFormat;
174 decodeConfig.iInputBufferSize = KInputBufferSize;
175 TPuConfigVideoPlayback puConfig(decodeConfig);
177 User::LeaveIfError(iDecoderPU->Configure(puConfig));
181 @see CMMFVideoPlayHwDevice::SetClockSource()
183 void CMdfVideoDecodeHwDeviceAdapter::SetClockSource(MMMFClockSource* aClock)
185 iClockSource = aClock;
189 @see CMMFVideoPlayHwDevice::SetVideoDestScreenL()
191 void CMdfVideoDecodeHwDeviceAdapter::SetVideoDestScreenL(TBool aScreen)
195 // NB we expect the output format to have been set before this is called
196 if(!iFormat.iDataFormat)
198 User::Leave(KErrNotReady);
201 // we support only bitmaps for DSA, not raw data
202 if(iFormat.iDataFormat != ERgbFbsBitmap)
204 User::Leave(KErrNotSupported);
209 iDSAEnabled = aScreen;
213 @see CMMFVideoPlayHwDevice::SetPostProcessTypesL()
215 void CMdfVideoDecodeHwDeviceAdapter::SetPostProcessTypesL(TUint32 /* aPostProcCombination */)
217 // the decoder is not configurable
218 User::Leave(KErrNotSupported);
222 @see CMMFVideoPlayHwDevice::SetInputCropOptionsL()
224 void CMdfVideoDecodeHwDeviceAdapter::SetInputCropOptionsL(const TRect& /* aRect */)
226 // the decoder is not configurable
227 User::Leave(KErrNotSupported);
231 @see CMMFVideoPlayHwDevice::SetYuvToRgbOptionsL()
233 void CMdfVideoDecodeHwDeviceAdapter::SetYuvToRgbOptionsL(const TYuvToRgbOptions& /* aOptions */, const TYuvFormat& /* aYuvFormat */, TRgbFormat /* aRgbFormat */)
235 // the decoder is not configurable
236 User::Leave(KErrNotSupported);
240 @see CMMFVideoPlayHwDevice::SetYuvToRgbOptionsL()
242 void CMdfVideoDecodeHwDeviceAdapter::SetYuvToRgbOptionsL(const TYuvToRgbOptions& /* aOptions */)
244 // the decoder is not configurable
245 User::Leave(KErrNotSupported);
249 @see CMMFVideoPlayHwDevice::SetRotateOptionsL()
251 void CMdfVideoDecodeHwDeviceAdapter::SetRotateOptionsL(TRotationType /* aRotationType */)
253 // the decoder is not configurable
254 User::Leave(KErrNotSupported);
258 @see CMMFVideoPlayHwDevice::SetScaleOptionsL()
260 void CMdfVideoDecodeHwDeviceAdapter::SetScaleOptionsL(const TSize& /* aTargetSize */, TBool /* aAntiAliasFiltering */)
262 // the decoder is not configurable
263 User::Leave(KErrNotSupported);
267 @see CMMFVideoPlayHwDevice::SetOutputCropOptionsL()
269 void CMdfVideoDecodeHwDeviceAdapter::SetOutputCropOptionsL(const TRect& /* aRect */)
271 // the decoder is not configurable
272 User::Leave(KErrNotSupported);
276 @see CMMFVideoPlayHwDevice::SetPostProcSpecificOptionsL()
278 void CMdfVideoDecodeHwDeviceAdapter::SetPostProcSpecificOptionsL(const TDesC8& /* aOptions */)
280 // the decoder is not configurable
281 User::Leave(KErrNotSupported);
285 @see CMMFVideoPlayHwDevice::Initialize()
287 void CMdfVideoDecodeHwDeviceAdapter::Initialize()
289 __ASSERT_ALWAYS(iProxy, DevVideoHwDeviceDecoderPanic(0));
291 TRAPD(err, InitializeL());
292 if(err == KErrNone && !iPUInitialized)
294 err = KErrNotSupported;
296 iProxy->MdvppInitializeComplete(this, err);
299 // private method : body of Initialize()
300 void CMdfVideoDecodeHwDeviceAdapter::InitializeL()
303 switch(iFormat.iDataFormat)
306 User::Leave(KErrNotReady);
313 User::Leave(KErrNotSupported);
317 // create and initialise the buffer manager
318 iBufferManager = CMdfVideoDecoderBufferManager::NewL();
320 iBufferManager->Init(iFormat);
321 iBufferManager->SetFrameSize(iFrameSize);
323 DEBUG_PRINT(_L("HwDevice: Buffer Manager initialized"));
325 // The actual frame rate will come from the VOL headers.
326 iFrameRate = KTenFPS;
328 // reset the player flags
330 iInputBufferWaiting = EFalse;
333 // create the player engine
334 iPlayerEngine = CMdfVideoPlayerEngine::NewL(*this);
336 RPointerArray<MMdfInputPort> inputPorts;
337 // Get ports and set observers
338 User::LeaveIfError(iDecoderPU->GetInputPorts(inputPorts));
339 if (inputPorts.Count()==0)
342 User::Leave(KErrNotFound);
344 iDecoderPUInputPort = inputPorts[0];
345 iDecoderPUInputPort->MipSetObserver(*this);
348 RPointerArray<MMdfOutputPort> outputPorts;
349 User::LeaveIfError(iDecoderPU->GetOutputPorts(outputPorts));
350 if (outputPorts.Count()==0)
353 User::Leave(KErrNotFound);
355 iDecoderPUOutputPort = outputPorts[0];
356 iDecoderPUOutputPort->MopSetObserver(*this);
359 iState = EProcessingUnitLoaded;
361 DEBUG_PRINT(_L("HwDevice: Decoder Processing Unit Loaded"));
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));
368 CVideoFrameBuffer& frameBuffer = iBufferManager->CreateFrameBufferL(TMMFDisplayModeUtils::DisplayMode(iFormat.iRgbFormat));
369 User::LeaveIfError(iDecoderPUOutputPort->MopUseBuffer(frameBuffer));
371 // VD: should not move the set up of the state after sending the Initialize() calls???
372 iState = EProcessingUnitInitializing;
374 // async call, that calls back to InitializeComplete()
375 iDecoderPU->Initialize();
377 DEBUG_PRINT(_L("HwDevice: Initialized OK"));
381 @see CMMFVideoPlayHwDevice::StartDirectScreenAccessL()
383 void CMdfVideoDecodeHwDeviceAdapter::StartDirectScreenAccessL(const TRect& aVideoRect, CFbsScreenDevice& aScreenDevice, const TRegion& aClipRegion)
385 // ensure SetVideoDestScreenL() has been called
388 User::Leave(KErrNotReady);
391 DEBUG_PRINT(_L("HwDevice: Starting DSA"));
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
400 User::LeaveIfError(aScreenDevice.CreateContext(iScreenDeviceGc));
401 iScreenDevice = &aScreenDevice;
402 iScreenDeviceRect = aVideoRect;
403 iScreenDeviceGc->SetClippingRegion(aClipRegion);
408 @see CMMFVideoPlayHwDevice::SetScreenClipRegion()
410 void CMdfVideoDecodeHwDeviceAdapter::SetScreenClipRegion(const TRegion& aRegion)
412 __ASSERT_ALWAYS(iScreenDeviceGc, DevVideoHwDeviceDecoderPanic(0));
414 iScreenDeviceGc->SetClippingRegion(aRegion);
418 @see CMMFVideoPlayHwDevice::SetPauseOnClipFail()
420 void CMdfVideoDecodeHwDeviceAdapter::SetPauseOnClipFail(TBool /* aPause */)
422 // not implemented - will pause by default
426 @see CMMFVideoPlayHwDevice::AbortDirectScreenAccess()
428 void CMdfVideoDecodeHwDeviceAdapter::AbortDirectScreenAccess()
430 DEBUG_PRINT(_L("HwDevice: Stopping DSA"));
431 iDSAStarted = EFalse;
435 @see CMMFVideoPlayHwDevice::IsPlaying()
437 TBool CMdfVideoDecodeHwDeviceAdapter::IsPlaying()
439 return (iState == EProcessingUnitExecuting ? ETrue : EFalse);
443 @see CMMFVideoPlayHwDevice::Redraw()
445 void CMdfVideoDecodeHwDeviceAdapter::Redraw()
449 DisplayLastFrameDirect();
454 @see CMMFVideoPlayHwDevice::Start()
456 void CMdfVideoDecodeHwDeviceAdapter::Start()
458 __ASSERT_ALWAYS(iPlayerEngine, DevVideoHwDeviceDecoderPanic(0));
459 __ASSERT_ALWAYS(iDecoderPU, DevVideoHwDeviceDecoderPanic(0));
461 if(iState != EProcessingUnitExecuting)
463 CVideoFrameBuffer* frameBuffer = NULL;
464 TRAPD(err, frameBuffer = &iBufferManager->GetEmptyFrameBufferL(ETrue));
467 iProxy->MdvppFatalError(this, err);
471 iDecoderPUOutputPort->MopReadData(*frameBuffer);
473 iDecoderPU->Execute();
474 TProcessingUnitState puState = iDecoderPU->State();
475 if(puState == EProcessingUnitInvalid)
479 iState = EProcessingUnitExecuting;
481 // if we are using raw decoding, then play as fast as we can,
482 // otherwise use the actual frame rate
483 TInt playerFrameRate;
486 playerFrameRate = TInt(iFrameRate);
490 playerFrameRate = CMdfVideoPlayerEngine::KUnsynchronized;
492 TRAP(err, iPlayerEngine->StartL(playerFrameRate));
495 // the player failed to start. this is a fatal error
496 iProxy->MdvppFatalError(this, err);
500 iProxy->MdvppNewBuffers();
506 @see CMMFVideoPlayHwDevice::Stop()
508 void CMdfVideoDecodeHwDeviceAdapter::Stop()
510 if(iState == EProcessingUnitExecuting)
512 iPlayerEngine->Stop();
514 iState = EProcessingUnitIdle;
519 @see CMMFVideoPlayHwDevice::Pause()
521 void CMdfVideoDecodeHwDeviceAdapter::Pause()
527 @see CMMFVideoPlayHwDevice::Resume()
529 void CMdfVideoDecodeHwDeviceAdapter::Resume()
535 @see CMMFVideoPlayHwDevice::SetPosition()
537 void CMdfVideoDecodeHwDeviceAdapter::SetPosition(const TTimeIntervalMicroSeconds& aPlaybackPosition)
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);
544 @see CMMFVideoPlayHwDevice::FreezePicture()
546 void CMdfVideoDecodeHwDeviceAdapter::FreezePicture(const TTimeIntervalMicroSeconds& /* aTimestamp */)
548 // not supported; we have no presentation timestamps
549 // however should not cause a fatal error
553 @see CMMFVideoPlayHwDevice::ReleaseFreeze()
555 void CMdfVideoDecodeHwDeviceAdapter::ReleaseFreeze(const TTimeIntervalMicroSeconds& /* aTimestamp */)
557 // not supported; we have no presentation timestamps
558 // however should not cause a fatal error
562 @see CMMFVideoPlayHwDevice::PlaybackPosition()
564 TTimeIntervalMicroSeconds CMdfVideoDecodeHwDeviceAdapter::PlaybackPosition()
566 if(iFrameRate == 0.0)
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));
577 @see CMMFVideoPlayHwDevice::PictureBufferBytes()
579 TUint CMdfVideoDecodeHwDeviceAdapter::PictureBufferBytes()
581 __ASSERT_ALWAYS(iBufferManager, DevVideoHwDeviceDecoderPanic(0));
583 return (iBufferManager->FrameBufferSize() * iBufferManager->MaxFrameBuffers());
587 @see CMMFVideoPlayHwDevice::GetPictureCounters()
589 void CMdfVideoDecodeHwDeviceAdapter::GetPictureCounters(CMMFDevVideoPlay::TPictureCounters& aCounters)
591 aCounters = iPictureCounters;
595 @see CMMFVideoPlayHwDevice::SetComplexityLevel()
597 void CMdfVideoDecodeHwDeviceAdapter::SetComplexityLevel(TUint /* aLevel */)
599 // separate complexity levels are not available; ignored
603 @see CMMFVideoPlayHwDevice::NumComplexityLevels()
605 TUint CMdfVideoDecodeHwDeviceAdapter::NumComplexityLevels()
607 // separate complexity levels are not available; return 1
612 @see CMMFVideoPlayHwDevice::GetComplexityLevelInfo()
614 void CMdfVideoDecodeHwDeviceAdapter::GetComplexityLevelInfo(TUint aLevel, CMMFDevVideoPlay::TComplexityLevelInfo& aInfo)
616 // ignore call if aLevel is not 0
619 aInfo = iComplexityLevelInfo;
624 @see CMMFVideoPlayHwDevice::ReturnPicture()
626 void CMdfVideoDecodeHwDeviceAdapter::ReturnPicture(TVideoPicture* aPicture)
628 __ASSERT_ALWAYS(iBufferManager, DevVideoHwDeviceDecoderPanic(0));
630 // return the frame buffer that has been emptied
631 TRAPD(err, iBufferManager->ReturnFrameBufferL(*aPicture, CVideoFrameBuffer::EEmptied));
634 if (!iLastFrameBufferReceived)
637 // request the next empty frame buffer
638 CVideoFrameBuffer* frameBuffer = NULL;
639 TRAP(err, frameBuffer = &iBufferManager->GetEmptyFrameBufferL(ETrue));
642 CMMFBuffer* buffer = *frameBuffer;
643 iDecoderPUOutputPort->MopReadData(*buffer);
646 // DoPostPictureNotify() will handle MdvppStreamEnd()
650 iProxy->MdvppFatalError(this, err);
652 ASSERT(err == KErrNone);
653 DoPostPictureNotify();
657 @see CMMFVideoPlayHwDevice::GetSnapshotL()
659 TBool CMdfVideoDecodeHwDeviceAdapter::GetSnapshotL(TPictureData& /*aPictureData*/, const TUncompressedVideoFormat& /*aFormat*/)
661 // not supported - no presentation timestamps
662 User::Leave(KErrNotSupported);
667 @see CMMFVideoPlayHwDevice::GetTimedSnapshotL()
669 void CMdfVideoDecodeHwDeviceAdapter::GetTimedSnapshotL(TPictureData* /*aPictureData*/, const TUncompressedVideoFormat& /*aFormat*/, const TTimeIntervalMicroSeconds& /*aPresentationTimestamp*/)
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);
677 @see CMMFVideoPlayHwDevice::GetTimedSnapshotL()
679 void CMdfVideoDecodeHwDeviceAdapter::GetTimedSnapshotL(TPictureData* /*aPictureData*/, const TUncompressedVideoFormat& /*aFormat*/, const TPictureId& /*aPictureId*/)
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);
687 @see CMMFVideoPlayHwDevice::CancelTimedSnapshot()
689 void CMdfVideoDecodeHwDeviceAdapter::CancelTimedSnapshot()
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);
697 @see CMMFVideoPlayHwDevice::GetSupportedSnapshotFormatsL()
699 void CMdfVideoDecodeHwDeviceAdapter::GetSupportedSnapshotFormatsL(RArray<TUncompressedVideoFormat>& /*aFormats*/)
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);
707 @see CMMFVideoPlayHwDevice::InputEnd()
709 void CMdfVideoDecodeHwDeviceAdapter::InputEnd()
711 __ASSERT_ALWAYS(iBufferManager, DevVideoHwDeviceDecoderPanic(0));
713 DEBUG_PRINT(_L("HwDevice: Input end"));
717 // if there isn't an outstanding write to the PU, write
719 if(!iWriteRequestOutstanding)
726 @see CMMFVideoDecodeHwDevice::VideoDecoderInfoLC()
728 CVideoDecoderInfo* CMdfVideoDecodeHwDeviceAdapter::VideoDecoderInfoLC()
730 // this is a complicated structure, ensure all fields are
731 // filled with some valid value
733 //if PU is not loaded panic
736 DevVideoHwDeviceDecoderPanic(KErrNotReady);
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
747 // construct the video decoder info object
748 CVideoDecoderInfo* vInfo = CVideoDecoderInfo::NewL(
752 TVersion(KVideoDecoderInfoVersionMaj, KVideoDecoderInfoVersionMin, KVideoDecoderInfoVersionBuild),
753 iInputVidFormats.Array(),
754 EFalse, // not accelerated
755 ETrue, // supports direct screen access
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 );
764 CleanupStack::PushL(vInfo);
770 @see CMMFVideoDecodeHwDevice::GetHeaderInformationL()
773 TVideoPictureHeader* CMdfVideoDecodeHwDeviceAdapter::GetHeaderInformationL(TVideoDataUnitType aDataUnitType, TVideoDataUnitEncapsulation aEncapsulation, TVideoInputBuffer* aDataUnit)
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.
779 __ASSERT_ALWAYS(iFormat.iDataFormat, DevVideoHwDeviceDecoderPanic(0));
781 TDevVideoHeaderPuConfig header;
782 header.iDataUnitType = aDataUnitType;
783 header.iDataUnitEncapsulation = aEncapsulation;
784 header.iHeaderData.Set(aDataUnit->iData.Ptr(),aDataUnit->iData.Size());
786 TPuConfigVideoHeader headerConfig(header);
788 // Configure the decoder with the Header Information
789 User::LeaveIfError(iDecoderPU->Configure(headerConfig));
791 // retrieve the picture information from the config structure
793 TPuConfigVideoPictureHeader pict;
794 User::LeaveIfError(iDecoderPU->GetConfig(pict));
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;
807 @see CMMFVideoDecodeHwDevice::ConfigureDecoderL()
809 void CMdfVideoDecodeHwDeviceAdapter::ConfigureDecoderL(const TVideoPictureHeader& /* aVideoPictureHeader */)
811 // there is nothing configurable
812 User::Leave(KErrNotSupported);
816 @see CMMFVideoDecodeHwDevice::ReturnHeader()
818 void CMdfVideoDecodeHwDeviceAdapter::ReturnHeader(TVideoPictureHeader* aHeader)
820 if(aHeader == iPictureHeader) // only free our created header
822 delete iPictureHeader;
823 iPictureHeader = NULL;
828 @see CMMFVideoDecodeHwDevice::SetInputFormatL()
830 void CMdfVideoDecodeHwDeviceAdapter::SetInputFormatL(const CCompressedVideoFormat& aFormat, TVideoDataUnitType aDataUnitType, TVideoDataUnitEncapsulation aEncapsulation, TBool aDataInOrder)
832 // EDuCodedPicture, EDuElementaryStream, aDataInOrder == ETrue
833 if(aFormat.MimeType() != iPuData->InputDataType())
835 User::Leave(KErrNotSupported);
837 if(aDataUnitType != EDuCodedPicture)
839 User::Leave(KErrNotSupported);
841 if(aEncapsulation != EDuElementaryStream)
843 User::Leave(KErrNotSupported);
847 User::Leave(KErrNotSupported);
852 @see CMMFVideoDecodeHwDevice::SynchronizeDecoding()
854 void CMdfVideoDecodeHwDeviceAdapter::SynchronizeDecoding(TBool aSynchronize)
856 iSynchronize = aSynchronize;
860 @see CMMFVideoDecodeHwDevice::SetBufferOptionsL()
862 void CMdfVideoDecodeHwDeviceAdapter::SetBufferOptionsL(const CMMFDevVideoPlay::TBufferOptions& aOptions)
864 // check values are within the constraints of this device
865 if(aOptions.iPreDecoderBufferPeriod != 0)
867 User::Leave(KErrNotSupported);
869 if(aOptions.iMaxPostDecodeBufferSize != 0)
871 User::Leave(KErrNotSupported);
873 if(aOptions.iPreDecoderBufferPeriod != 0)
875 User::Leave(KErrNotSupported);
877 if(aOptions.iPostDecoderBufferPeriod != 0)
879 User::Leave(KErrNotSupported);
881 if(aOptions.iMaxInputBufferSize > KVideoDecoderMaxDataBufferSize)
883 User::Leave(KErrNotSupported);
885 if(aOptions.iMinNumInputBuffers > 1)
887 User::Leave(KErrNotSupported);
889 // input is OK; write it
890 iBufferOptions = aOptions;
894 @see CMMFVideoDecodeHwDevice::GetBufferOptions()
896 void CMdfVideoDecodeHwDeviceAdapter::GetBufferOptions(CMMFDevVideoPlay::TBufferOptions& aOptions)
898 aOptions = iBufferOptions;
902 @see CMMFVideoDecodeHwDevice::SetHrdVbvSpec()
904 void CMdfVideoDecodeHwDeviceAdapter::SetHrdVbvSpec(THrdVbvSpecification /* aHrdVbvSpec */, const TDesC8& /* aHrdVbvParams */)
906 // the decoder is not configurable
907 // however this should not cause a fatal error
911 @see CMMFVideoDecodeHwDevice::SetOutputDevice()
913 void CMdfVideoDecodeHwDeviceAdapter::SetOutputDevice(CMMFVideoPostProcHwDevice* aDevice)
915 // we allow output to be sent to a post-processor,
916 // even though this plugin doesn not itself provide one
917 iPostProcOutputDevice = aDevice;
921 @see CMMFVideoDecodeHwDevice::DecodingPosition()
923 TTimeIntervalMicroSeconds CMdfVideoDecodeHwDeviceAdapter::DecodingPosition()
925 if(iFrameRate == 0.0)
929 // this is the total number of pictures decoded
930 return (iPictureCounters.iPicturesDecoded * (KOneSecond / (TInt)iFrameRate));
934 @see CMMFVideoDecodeHwDevice::PreDecoderBufferBytes()
936 TUint CMdfVideoDecodeHwDeviceAdapter::PreDecoderBufferBytes()
942 @see CMMFVideoDecodeHwDevice::GetBitstreamCounters()
944 void CMdfVideoDecodeHwDeviceAdapter::GetBitstreamCounters(CMMFDevVideoPlay::TBitstreamCounters& aCounters)
946 aCounters = iBitstreamCounters;
950 @see CMMFVideoDecodeHwDevice::NumFreeBuffers()
952 TUint CMdfVideoDecodeHwDeviceAdapter::NumFreeBuffers()
954 __ASSERT_ALWAYS(iBufferManager, DevVideoHwDeviceDecoderPanic(0));
956 if(!FrameBufferAvailable())
958 // if there are too many output buffers waiting, we refuse an input buffer
959 // until some output buffers have been processed.
964 return (iBufferManager->DataBuffersAvailable());
969 @see CMMFVideoDecodeHwDevice::GetBufferL()
971 This will return a buffer of the requested size, within min/max constraints
973 TVideoInputBuffer* CMdfVideoDecodeHwDeviceAdapter::GetBufferL(TUint /* aBufferSize */)
975 __ASSERT_ALWAYS(iBufferManager, DevVideoHwDeviceDecoderPanic(0));
977 TVideoInputBuffer& buf = iBufferManager->GetDataBufferL();
982 @see CMMFVideoDecodeHwDevice::WriteCodedDataL()
984 void CMdfVideoDecodeHwDeviceAdapter::WriteCodedDataL(TVideoInputBuffer* aInputBuffer)
986 // Leave on null input buffer
989 User::Leave(KErrArgument);
992 // increment received buffer count
993 iBitstreamCounters.iTotalPackets++;
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;
1003 @see CMMFVideoPlayHwDevice::CommitL()
1005 void CMdfVideoDecodeHwDeviceAdapter::CommitL()
1007 // the decoder is not configurable
1008 User::Leave(KErrNotSupported);
1012 @see CMMFVideoPlayHwDevice::Revert()
1014 void CMdfVideoDecodeHwDeviceAdapter::Revert()
1016 // the decoder is not configurable
1017 // however this should not cause a fatal error
1020 void CMdfVideoDecodeHwDeviceAdapter::SetProxy(MMMFDevVideoPlayProxy& aProxy)
1028 @see MMdfDecoderHwDeviceObserver::FrameBufferAvailable()
1030 TBool CMdfVideoDecodeHwDeviceAdapter::FrameBufferAvailable() const
1032 __ASSERT_ALWAYS(iBufferManager, DevVideoHwDeviceDecoderPanic(0));
1034 return (iBufferManager->EmptyFrameBuffersAvailable() > 0);
1038 @see MMdfVideoPlayerHwDeviceObserver::Time()
1040 TUint CMdfVideoDecodeHwDeviceAdapter::Time() const
1045 return iClockSource->Time().Int64();
1049 // system clock without HAL
1053 tt64 = ttime.Int64();
1054 return (tt64 - iSystemClock);
1059 @see MMdfVideoPlayerHwDeviceObserver::DisplayFrame()
1061 void CMdfVideoDecodeHwDeviceAdapter::DisplayFrame()
1063 __ASSERT_ALWAYS(iBufferManager, DevVideoHwDeviceDecoderPanic(0));
1065 CVideoFrameBuffer* frameBuffer = NULL;
1066 TRAPD(err, frameBuffer = &iBufferManager->GetFilledFrameBufferL(EFalse));
1069 // the buffer manager has failed
1070 DEBUG_PRINT(_L("HwDevice: Buffer Manager failed"));
1071 iProxy->MdvppFatalError(this, err);
1075 // is this the last buffer?
1076 iLastFrameBufferReceived = frameBuffer->LastBuffer();
1078 TVideoPicture& thePicture = *frameBuffer;
1080 // increment picture counter
1081 CMMFBuffer& theBuffer = *frameBuffer;
1082 if(theBuffer.BufferSize())
1084 iPictureCounters.iPicturesDisplayed++;
1087 iDisplayPictureAvailable = EFalse;
1089 // send it to post-processor output, DSA, or the client
1090 if(iPostProcOutputDevice)
1092 TRAP(err, iPostProcOutputDevice->WritePictureL(&thePicture));
1094 else if(iDSAStarted)
1096 DisplayFrameDirect(&thePicture);
1097 TRAP(err, iBufferManager->ReturnFrameBufferL(thePicture, CVideoFrameBuffer::EEmptied));
1099 if (!iLastFrameBufferReceived)
1101 CVideoFrameBuffer* frameBuffer = NULL;
1102 TRAP(err, frameBuffer = &iBufferManager->GetEmptyFrameBufferL(ETrue));
1103 if (err == KErrNone)
1105 iDecoderPUOutputPort->MopReadData(*frameBuffer);
1109 iProxy->MdvppFatalError(this, err);
1113 // DoPostPictureNotify() will handle MdvppStreamEnd()
1114 // NB we need to notify the client here as there will be no callback
1115 DoPostPictureNotify();
1119 iProxy->MdvppNewPicture(&thePicture);
1125 @see MMdfVideoPlayerHwDeviceObserver::DiscardFrame()
1127 void CMdfVideoDecodeHwDeviceAdapter::DiscardFrame()
1129 __ASSERT_ALWAYS(iBufferManager, DevVideoHwDeviceDecoderPanic(0));
1131 CVideoFrameBuffer* frameBuffer = NULL;
1132 TVideoPicture* thePicture = NULL;
1133 TRAPD(err, frameBuffer = &iBufferManager->GetFilledFrameBufferL(EFalse));
1136 // the buffer manager has failed
1137 DEBUG_PRINT(_L("HwDevice: Buffer Manager failed"));
1138 iProxy->MdvppFatalError(this, err);
1142 thePicture = *frameBuffer;
1144 // increment picture counter
1145 CMMFBuffer& theBuffer = *frameBuffer;
1146 if(theBuffer.BufferSize())
1148 iPictureCounters.iPicturesSkipped++;
1151 iDisplayPictureAvailable = EFalse;
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)
1158 DEBUG_PRINT(_L("HwDevice: ReturnFrameBufferL failed"));
1159 iProxy->MdvppFatalError(this, err);
1162 TRAP(err, frameBuffer = &iBufferManager->GetEmptyFrameBufferL(ETrue));
1163 if (err == KErrNone)
1165 iDecoderPUOutputPort->MopReadData(*frameBuffer);
1168 // NB we need to notify the client here as there will be no callback
1169 DoPostPictureNotify();
1174 @see MMdfVideoPlayerHwDeviceObserver::FrameAvailable()
1176 TBool CMdfVideoDecodeHwDeviceAdapter::FrameAvailable() const
1178 return iDisplayPictureAvailable;
1182 @see MMdfInputPortObserver::MipoWriteDataComplete()
1184 void CMdfVideoDecodeHwDeviceAdapter::MipoWriteDataComplete(const MMdfInputPort* aInputPort,
1185 CMMFBuffer* /* aBuffer */, TInt aErrorCode)
1187 iWriteRequestOutstanding = EFalse;
1188 __ASSERT_ALWAYS(aInputPort == iDecoderPUInputPort, DevVideoHwDeviceDecoderPanic(0));
1189 if (aErrorCode != KErrNone)
1191 iProxy->MdvppFatalError(this, aErrorCode);
1194 // Return the data buffer, the position tells us how much data
1198 TRAPD(err, iBufferManager->ReturnDataBufferL(*iInputBuffer));
1201 iProxy->MdvppNewBuffers();
1205 iProxy->MdvppFatalError(this, err);
1210 // Send an empty buffer to the decoder to signal the
1211 // end of the stream
1217 @see MMdfInputPortObserver::MipoStopComplete()
1219 void CMdfVideoDecodeHwDeviceAdapter::MipoDisconnectTunnelComplete(const MMdfInputPort* /* aInputPort */,
1220 TInt /* aErrorCode */)
1225 @see MMdfInputPortObserver::MipoRestartComplete()
1227 void CMdfVideoDecodeHwDeviceAdapter::MipoRestartTunnelComplete(const MMdfInputPort* /* aInputPort */,
1228 TInt /* aErrorCode */)
1233 @see MMdfOutputPortObserver::MopoReadDataComplete()
1235 void CMdfVideoDecodeHwDeviceAdapter::MopoReadDataComplete(const MMdfOutputPort* aOutputPort,
1236 CMMFBuffer* aBuffer, TInt aErrorCode)
1238 if(aErrorCode != KErrNone)
1240 iProxy->MdvppFatalError(this, aErrorCode);
1244 if(aOutputPort != iDecoderPUOutputPort)
1246 iProxy->MdvppFatalError(this, KErrArgument);
1250 // increment iPicturesDecoded
1251 if(aBuffer->BufferSize())
1253 iPictureCounters.iPicturesDecoded++;
1256 iDisplayPictureAvailable = ETrue;
1258 TRAPD(err, iBufferManager->ReturnFrameBufferL(aBuffer, CVideoFrameBuffer::EFilled, aBuffer->LastBuffer()));
1261 iProxy->MdvppFatalError(this, err);
1266 @see MMdfOutputPortObserver::MopoStopComplete()
1268 void CMdfVideoDecodeHwDeviceAdapter::MopoDisconnectTunnelComplete(const MMdfOutputPort* /* aOutputPort */,
1269 TInt /* aErrorCode */)
1274 @see MMdfOutputPortObserver::MopoRestartComplete()
1276 void CMdfVideoDecodeHwDeviceAdapter::MopoRestartTunnelComplete(const MMdfOutputPort* /* aOutputPort */,
1277 TInt /* aErrorCode */)
1282 @see MMdfProcessingUnitObserver::InitializeComplete()
1284 void CMdfVideoDecodeHwDeviceAdapter::InitializeComplete(const CMdfProcessingUnit* aPu, TInt aErrorCode)
1286 __ASSERT_ALWAYS(aPu == iDecoderPU, DevVideoHwDeviceDecoderPanic(0));
1288 if(aErrorCode != KErrNone)
1290 iProxy->MdvppFatalError(this, aErrorCode);
1294 iPUInitialized = ETrue;
1298 @see MMdfProcessingUnitObserver::ExecuteComplete()
1300 void CMdfVideoDecodeHwDeviceAdapter::ExecuteComplete(const CMdfProcessingUnit* aPu, TInt aErrorCode)
1302 __ASSERT_ALWAYS(aPu == iDecoderPU, DevVideoHwDeviceDecoderPanic(0));
1304 if(aErrorCode != KErrNone)
1306 iProxy->MdvppFatalError(this, aErrorCode);
1310 if (iState == EProcessingUnitExecuting)
1312 DEBUG_PRINT(_L("HwDevice: 3() - Stream end"));
1313 iProxy->MdvppStreamEnd();
1314 iState = EProcessingUnitIdle;
1318 // private method - DoPostPictureNotify
1319 void CMdfVideoDecodeHwDeviceAdapter::DoPostPictureNotify()
1321 __ASSERT_ALWAYS(iBufferManager, DevVideoHwDeviceDecoderPanic(0));
1323 DEBUG_PRINT(_L("HwDevice: PostPictureNotify"));
1324 // notify the client that an input buffer is available if we weren't able to
1326 if(iInputBufferWaiting && iBufferManager->DataBuffersAvailable())
1328 iInputBufferWaiting = EFalse;
1329 iProxy->MdvppNewBuffers();
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())
1336 iLastFrameBufferReceived = ETrue;
1339 // NB iLastFrameBufferReceived may have been set beforehand
1340 if(iLastFrameBufferReceived)
1342 DEBUG_PRINT(_L("HwDevice: Stream end"));
1343 iProxy->MdvppStreamEnd();
1347 // private method - display the frame using direct screen access
1348 void CMdfVideoDecodeHwDeviceAdapter::DisplayFrameDirect(TVideoPicture* aPicture)
1350 __ASSERT_ALWAYS(iScreenDevice, DevVideoHwDeviceDecoderPanic(0));
1352 DEBUG_PRINT(_L("HwDevice: Displaying frame using DSA"));
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();
1360 // private method - display the last frame using direct screen access
1361 void CMdfVideoDecodeHwDeviceAdapter::DisplayLastFrameDirect()
1363 __ASSERT_ALWAYS(iScreenDevice, DevVideoHwDeviceDecoderPanic(0));
1365 DEBUG_PRINT(_L("HwDevice: Redrawing last frame using DSA"));
1367 // NB this will only work if the picture is a CFbsBitmap
1368 const TPictureData* lastFrame = NULL;
1369 TRAPD(err, lastFrame = &iBufferManager->LastPictureL());
1372 CFbsBitmap* theBitmap = lastFrame->iRgbBitmap;
1373 iScreenDeviceGc->DrawBitmap(iScreenDeviceRect, theBitmap);
1374 iScreenDevice->Update();
1378 void CMdfVideoDecodeHwDeviceAdapter::LoadProcessingUnitL(const CImplementationInformation& aImplInfo)
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
1385 iPuData = CCodecApiVideoOpaqueData::NewL(aImplInfo.OpaqueData());
1386 iManufacturer = HBufC::NewL(iPuData->Manufacturer().Length());
1387 iManufacturer->Des().Copy(iPuData->Manufacturer());
1388 iMaxPictureSize = iPuData->MaxPictureSize();
1391 void CMdfVideoDecodeHwDeviceAdapter::SendLastBuffer()
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);