# HG changeset patch # User hgs # Date 1286572157 -3600 # Node ID 5d29cba61097b8b1af6b8f0eeb01c939bdf06d49 2010wk38_02 diff -r 000000000000 -r 5d29cba61097 mmvideo_plat/omxilvideoextensions_api/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmvideo_plat/omxilvideoextensions_api/group/bld.inf Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,23 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +#ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED + +PRJ_EXPORTS +../inc/omxilsymbianvideographicsinkextensions.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(openmax/il/extensions/omxilsymbianvideographicsinkextensions.h) +../inc/omxildroppedframeeventextension.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(openmax/il/extensions/omxildroppedframeeventextension.h) + +#endif // NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED diff -r 000000000000 -r 5d29cba61097 mmvideo_plat/omxilvideoextensions_api/inc/omxildroppedframeeventextension.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmvideo_plat/omxilvideoextensions_api/inc/omxildroppedframeeventextension.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@ipublishedPartner +*/ + +#ifndef OMXILDROPPEDFRAMEEVENTEXTENSION_H_ +#define OMXILDROPPEDFRAMEEVENTEXTENSION_H_ + +#include + +/** + * The string that can be passed to get the index for the dropped frame event extension + */ +const char sOmxNokiaIndexParamDroppedFrameEvent [] = "OMX.NOKIA.INDEX.PARAM.DROPPEDFRAMEEVENT"; + +/** + * Custom OpenMAX IL structure for the dropped frame error extension. + */ +struct OMX_NOKIA_PARAM_DROPPEDFRAMEEVENT + { + OMX_U32 nSize; /** Size of this structure, in Bytes */ + OMX_VERSIONTYPE nVersion; /** OMX specification version information */ + OMX_U32 nPortIndex; /** Port that this structure applies to */ + OMX_BOOL bEnabled; /** Flag to indicate whether to generate the event */ + }; + +#endif /* OMXILDROPPEDFRAMEEVENTEXTENSION_H_ */ diff -r 000000000000 -r 5d29cba61097 mmvideo_plat/omxilvideoextensions_api/inc/omxilsymbianvideographicsinkextensions.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmvideo_plat/omxilvideoextensions_api/inc/omxilsymbianvideographicsinkextensions.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +/** + @file + @internalComponent +*/ + +#ifndef OMXILSYMBIANVIDEOGRAPHICSINKEXTENSIONS_H +#define OMXILSYMBIANVIDEOGRAPHICSINKEXTENSIONS_H + + +#include + + +/** + * The string that the Symbian's OpenMAX IL Graphic Sink component will + * translate into a 32-bit OpenMAX IL index to support the TSurfaceConfig class + */ +const char sOmxSymbianGfxSurfaceConfig [] = "OMX.SYMBIAN.INDEX.PARAM.VIDEO.GFX.SURFACECONFIG"; + + +/** + * Custom OpenMAX IL structure to be used as a container for an + * TSurfaceConfig class + */ +struct OMX_SYMBIAN_VIDEO_PARAM_SURFACECONFIGURATION + { + OMX_U32 nSize; // Size of this structure, in Bytes + OMX_VERSIONTYPE nVersion; // OMX specification version information + OMX_U32 nPortIndex; // Port that this structure applies to + OMX_PTR pSurfaceConfig; // This is a pointer to TSurfaceConfig class + }; + + +#endif // OMXILSYMBIANVIDEOGRAPHICSINKEXTENSIONS_H diff -r 000000000000 -r 5d29cba61097 mmvideo_plat/omxilvideoextensions_api/omxilvideoextensions_api.metaxml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmvideo_plat/omxilvideoextensions_api/omxilvideoextensions_api.metaxml Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,15 @@ + + + OpenMAX IL Video Extensions API + Symbian-specific extension APIs exposed by the graphic sink and video scheduler OpenMAX IL components. + c++ + omxilvideocomps + + + + + + no + no + + diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/group/bld.inf Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +// The export of this IBY is deliberately not guarded by #ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED so that it +// can always be #included by other IBYs/OBYs. However, if NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED is not defined +// then the IBY will effectively be empty and not include anything in the ROM. + +PRJ_EXPORTS +videoomxilcompref.iby /epoc32/rom/include/videoomxilcompref.iby diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/group/videoomxilcompref.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/group/videoomxilcompref.iby Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifndef VIDEOMXILCOMPREF_IBY +#define VIDEOMXILCOMPREF_IBY + +#include +#include + +#endif // VIDEOMXILCOMPREF_IBY diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/group/bld.inf Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +PRJ_PLATFORMS +BASEDEFAULT + +PRJ_EXPORTS +// The export of the IBY is deliberately not guarded by #ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED so that it +// can always be #included by other IBYs/OBYs. However, if NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED is not defined +// then the IBY will effectively be empty and not include anything in the ROM. + +./omxil3gpdemuxer.iby /epoc32/rom/include/omxil3gpdemuxer.iby + +PRJ_MMPFILES +#ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED +./omxil3gpdemuxer.mmp +#endif // NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/group/omxil3gpdemuxer.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/group/omxil3gpdemuxer.iby Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifndef OMXIL3GPDEMUXER_IBY +#define OMXIL3GPDEMUXER_IBY + +#ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED + +#include <3gplibrary.iby> +#include + +ECOM_PLUGIN(omxil3gpdemuxer.dll, omxil3gpdemuxer.rsc) + +#endif + +#endif // OMXIL3GPDEMUXER_IBY diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/group/omxil3gpdemuxer.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/group/omxil3gpdemuxer.mmp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2008 - 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include "../src/omxil3gpdemuxer.hrh" + +TARGET omxil3gpdemuxer.dll +TARGETTYPE PLUGIN +UID 0x10009D8D KUidSymbianOmxIL3gpDemuxerDll +CAPABILITY All -TCB + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +USERINCLUDE ../src + +SOURCEPATH ../src + +SOURCE comxil3gpdemuxer.cpp comxil3gpdemuxerprocessingfunction.cpp comxil3gpdemuxerconfigmanager.cpp +SOURCE comxil3gpdemuxertimeinputport.cpp comxil3gpdemuxeraudiooutputport.cpp comxil3gpdemuxervideooutputport.cpp +SOURCE c3gpdemuxer.cpp omxil3gpdemuxerpanic.cpp comxil3gpdemuxerrequesthelper.cpp + +START RESOURCE omxil3gpdemuxer.rss +TARGET omxil3gpdemuxer.rsc +END + +nostrictdef + +LIBRARY euser.lib efsrv.lib inetprotutil.lib ecom.lib 3gplibrary.lib +LIBRARY omxilcomponentcommon.lib +STATICLIBRARY omxilcomponentif.lib + +// Uncomment to activate debug tracing in this module +//MACRO _OMXIL_COMMON_DEBUG_TRACING_ON diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/c3gpdemuxer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/c3gpdemuxer.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,1063 @@ +/* +* Copyright (c) 2008 - 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** + @file + @internalComponent + */ + +#include "log.h" +#include +#include +#include "c3gpdemuxer.h" +#include "omxil3gpdemuxerpanic.h" +#include "comxil3gpdemuxertimeinputport.h" +#include "comxil3gpdemuxeraudiooutputport.h" +#include "comxil3gpdemuxervideooutputport.h" + +C3GPDemuxer::CPort* C3GPDemuxer::CPort::NewL(TInt aBufferCount) + { + CPort* self = new (ELeave) CPort(); + CleanupStack::PushL(self); + self->ConstructL(aBufferCount); + CleanupStack::Pop(self); + return self; + } + +C3GPDemuxer::CPort::CPort() : + iEOS(EFalse) + { + } + +void C3GPDemuxer::CPort::ConstructL(TInt aBufferCount) + { + iBuffers.ReserveL(aBufferCount); + } + +C3GPDemuxer::CPort::~CPort() + { + iBuffers.Reset(); + } + +C3GPDemuxer* C3GPDemuxer::NewL(MOmxILCallbackNotificationIf& aCallbacks) + { + C3GPDemuxer* self = new (ELeave) C3GPDemuxer(aCallbacks); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +void C3GPDemuxer::ConstructL() + { + i3GPParser = C3GPParse::NewL(); + } + +C3GPDemuxer::C3GPDemuxer(MOmxILCallbackNotificationIf& aCallbacks) : + CActive(EPriorityStandard), + iCallbacks(aCallbacks), + iVideoType(E3GPNoVideo), + iAudioType(E3GPNoAudio), + iFirstVideoFrame(ETrue), + iFirstAudioFrame(ETrue), + iAsyncBuf(0, 0) + { + iOmxAudioFormat.iCoding = OMX_AUDIO_CodingMax; + iOmxVideoFormat.iCoding = OMX_VIDEO_CodingMax; + + for (TInt port = 0; port < COmxIL3GPDemuxer::EPortIndexMax; ++port) + { + iPort[port] = NULL; + } + + CActiveScheduler::Add(this); + } + +C3GPDemuxer::~C3GPDemuxer() + { + Cancel(); + + DeleteBufferQueue(); + + if (i3GPParser) + { + HandleIfError(i3GPParser->Complete()); + delete i3GPParser; + } + } + +OMX_ERRORTYPE C3GPDemuxer::AcquireResources(const TDesC& aFilename) + { + DEBUG_PRINTF(_L8("C3GPDemuxer::AcquireResources")); + + TInt error = i3GPParser->Open(aFilename); + if (error == KErrNone) + { + iParserOpened = ETrue; + + if (iStartTimePosition != 0) + { + SetPosition(iStartTimePosition, iStartKeyFrame); + iSeekPosition = iStartTimePosition; + iStartTimePosition = 0; + } + + TRAP(error, CreateBufferQueueL()); + } + + return SymbianOSErrorToOmx(error); + } + +void C3GPDemuxer::ReleaseResources() + { + DeleteBufferQueue(); + + if (i3GPParser) + { + HandleIfError(i3GPParser->Complete()); + iParserOpened = EFalse; + } + } + +void C3GPDemuxer::Start() + { + if (iPaused && iState != EStateWaitingToStart) + { + if (iState != EStateFillingBuffer) + { + Cancel(); + + // Self complete so that we start to process any buffer received while + // we were in paused state + CompleteSelf(); + } + } + else + { + Cancel(); + iState = EStateWaitingForBuffer; + // Self complete so that we start to process any buffer received while + // we were in idle state + CompleteSelf(); + } + + iPaused = EFalse; + } + +OMX_ERRORTYPE C3GPDemuxer::Stop() + { + Cancel(); + + if (iState == EStateFillingBuffer) + { + i3GPParser->CancelReadFrame(); + } + + iState = EStateWaitingToStart; + StartWaitingForBuffer(); + + iAudioHeadersSent = EFalse; + iFirstAudioFrame = ETrue; + iVideoHeadersSent = EFalse; + iFirstVideoFrame = ETrue; + iPaused = EFalse; + + TInt error = SetPosition(0, EFalse); + + return SymbianOSErrorToOmx(error); + } + +void C3GPDemuxer::Pause() + { + iPaused = ETrue; + } + +TBool C3GPDemuxer::Invalid() const + { + return iInvalid; + } + +void C3GPDemuxer::ProcessThisBufferL(OMX_BUFFERHEADERTYPE* aBufferHeader, + TUint32 aPortIndex) + { + __ASSERT_DEBUG(iBufferQueueCreated, Panic(EProcessThisBufferLNoBufferQueue)); + + aBufferHeader->nFilledLen = 0; + aBufferHeader->nOffset = 0; + aBufferHeader->nTimeStamp = 0; + aBufferHeader->nFlags = 0; + + if (iBufferQueueCreated) + { + TBufferMessage buffer; + buffer.iBufferHeader = aBufferHeader; + buffer.iPortIndex = aPortIndex; + User::LeaveIfError(iBufferQueue.Send(buffer)); + } + else + { + User::Leave(KErrNotReady); + } + } + +void C3GPDemuxer::FlushBuffers(TUint32 aPortIndex) + { + __ASSERT_DEBUG(aPortIndex == OMX_ALL || aPortIndex < COmxIL3GPDemuxer::EPortIndexMax, User::Invariant()); + + if (aPortIndex == OMX_ALL || aPortIndex < COmxIL3GPDemuxer::EPortIndexMax) + { + Cancel(); + ReceiveQueuedBuffers(); + + if (aPortIndex == OMX_ALL || iCurrentPort == aPortIndex) + { + if (iState == EStateFillingBuffer) + { + // We are about to flush a buffer that is being filled. + // Cancel the read operation. + i3GPParser->CancelReadFrame(); + } + + iState = EStateWaitingForBuffer; + } + + if (aPortIndex == OMX_ALL) + { + for (TInt portIndex = 0; portIndex < COmxIL3GPDemuxer::EPortIndexMax; ++portIndex) + { + DoFlushBuffers(portIndex); + } + } + else + { + DoFlushBuffers(aPortIndex); + } + + // Unless we are waiting for a read to complete, we need to self + // complete just in case the ReceiveQueuedBuffers() call above + // received new buffers + if (iState != EStateFillingBuffer) + { + CompleteSelf(); + } + } + } + +void C3GPDemuxer::DoFlushBuffers(TUint32 aPortIndex) + { + if (iPort[aPortIndex]) + { + OMX_DIRTYPE direction = OMX_DirOutput; + if (aPortIndex == COmxIL3GPDemuxer::EPortIndexTimeInput) + { + direction = OMX_DirInput; + } + + RQueuedBuffers& buffers = iPort[aPortIndex]->iBuffers; + while (buffers.Count() > 0) + { + iCallbacks.BufferDoneNotification(buffers[0], aPortIndex, direction); + buffers.Remove(0); + } + } + } + +TBool C3GPDemuxer::RemoveBuffer(OMX_BUFFERHEADERTYPE* aBufferHeader, + OMX_DIRTYPE aDirection) + { + TInt port = 0; + if (aDirection == OMX_DirOutput) + { + port = aBufferHeader->nOutputPortIndex; + } + else if (aDirection == OMX_DirInput) + { + port = aBufferHeader->nInputPortIndex; + } + else + { + Panic(ERemoveBufferInvalidDirection); + } + + __ASSERT_DEBUG(port >= 0 && port < COmxIL3GPDemuxer::EPortIndexMax, Panic(ERemoveBufferInvalidPort)); + + TBool found = EFalse; + + if (port >= 0 && port < COmxIL3GPDemuxer::EPortIndexMax) + { + Cancel(); + ReceiveQueuedBuffers(); + + if (iPort[port]) + { + RQueuedBuffers& buffers = iPort[port]->iBuffers; + for (TInt buf = 0; buf < buffers.Count(); ++buf) + { + if (buffers[buf] == aBufferHeader) + { + if (iCurrentPort == port && buf == 0) + { + if (iState == EStateFillingBuffer) + { + // We are about to remove a buffer that is being filled. + // Cancel the read operation. + i3GPParser->CancelReadFrame(); + } + iState = EStateWaitingForBuffer; + } + + buffers[buf]->nFilledLen = 0; + buffers.Remove(buf); + found = ETrue; + break; + } + } + } + + // Unless we are waiting for a read to complete, we need to self + // complete just in case the ReceiveQueuedBuffers() call above + // received new buffers + if (iState != EStateFillingBuffer) + { + CompleteSelf(); + } + } + + return found; + } + +TBool C3GPDemuxer::GetVideoFormat(TSize& aFrameSize, TVideoFormat& aFormat) const + { + if (!iVideoPropertiesRead) + { + return EFalse; + } + aFrameSize.iWidth = iVideoWidth; + aFrameSize.iHeight = iVideoHeight; + aFormat = iOmxVideoFormat; + return ETrue; + } + +TBool C3GPDemuxer::GetAudioFormat(TAudioFormat& aFormat) const + { + if (!iAudioPropertiesRead) + { + return EFalse; + } + aFormat = iOmxAudioFormat; + return ETrue; + } + +OMX_ERRORTYPE C3GPDemuxer::GetVideoTimestamp(OMX_TICKS& aOmxticks) + { + TInt err = KErrNone; + + TUint timestampInMilliSec(0); + + if (iParserOpened) + { + // return last requested seek time + timestampInMilliSec = iSeekPosition; + } + else + { + timestampInMilliSec = iStartTimePosition; + } + + if (err == KErrNone) + { + aOmxticks = timestampInMilliSec * 1000; + } + + return SymbianOSErrorToOmx(err); + } + +OMX_ERRORTYPE C3GPDemuxer::Seek(const OMX_TICKS& aOmxticks, OMX_TIME_SEEKMODETYPE aSeekModeType) + { + TInt err = KErrNone; + + //Set the firstFrame flags to true + iFirstVideoFrame = ETrue; + iFirstAudioFrame = ETrue; + + TUint timeInMilliSec = aOmxticks / 1000; + TBool keyFrame(aSeekModeType == OMX_TIME_SeekModeFast); + + if (iParserOpened) + { + err = SetPosition(timeInMilliSec, keyFrame); + if (err != KErrNone) + { + iSeekPosition = timeInMilliSec; + } + } + else + { + iStartTimePosition = timeInMilliSec; + iStartKeyFrame = keyFrame; + } + + return SymbianOSErrorToOmx(err); + } + +OMX_ERRORTYPE C3GPDemuxer::DetectStreams() + { + iAudioPropertiesRead = EFalse; + + TUint s_audioLength; + TInt s_audioFramesPerSample; + TUint s_audioAvgBitRate; + TUint s_audioTimeScale; + TInt error = i3GPParser->GetAudioProperties(iAudioType, s_audioLength, + s_audioFramesPerSample, s_audioAvgBitRate, s_audioTimeScale); + + if (error != KErrNotSupported) + { + if (error) + { + return SymbianOSErrorToOmx(error); + } + else + { + iOmxAudioFormat.iFramesPerSample = s_audioFramesPerSample; + iOmxAudioFormat.iSampleRate = s_audioTimeScale; + iOmxAudioFormat.iAverageBitrate = s_audioAvgBitRate; + switch (iAudioType) + { + case E3GPQcelp13K: + { + iOmxAudioFormat.iCoding = OMX_AUDIO_CodingQCELP13; + } + break; + case E3GPMpeg4Audio: + { + iOmxAudioFormat.iCoding = OMX_AUDIO_CodingAAC; + } + break; + case E3GPAmrNB: + case E3GPAmrWB: + { + iOmxAudioFormat.iCoding = OMX_AUDIO_CodingAMR; + } + break; + default: + { + iOmxAudioFormat.iCoding = OMX_AUDIO_CodingMax; + } + } + + iAudioPropertiesRead = ETrue; + } + + } + iVideoPropertiesRead = EFalse; + + TSize vidSize(iVideoWidth, iVideoHeight); + TUint s_vidLength = 0; + TReal s_vidFrameRate = 0.0; + TUint s_vidAvgBitRate = 0; + TSize s_vidSize; + TUint s_vidTimeScale = 0; + + error = i3GPParser->GetVideoProperties(iVideoType, s_vidLength, + s_vidFrameRate, s_vidAvgBitRate, s_vidSize, s_vidTimeScale); + + if (error != KErrNotSupported) + { + if (error) + { + return SymbianOSErrorToOmx(error); + } + else + { + iVideoWidth = s_vidSize.iWidth; + iVideoHeight = s_vidSize.iHeight; + + // translate library video type to OpenMAX IL coding and profile type + switch (iVideoType) + { + case E3GPMpeg4Video: + iOmxVideoFormat.iCoding = OMX_VIDEO_CodingMPEG4; + break; + case E3GPH263Profile0: + iOmxVideoFormat.iCoding = OMX_VIDEO_CodingH263; + iOmxVideoFormat.iProfile.h263 + = OMX_VIDEO_H263ProfileBaseline; + break; + case E3GPH263Profile3: + iOmxVideoFormat.iCoding = OMX_VIDEO_CodingH263; + iOmxVideoFormat.iProfile.h263 = OMX_VIDEO_H263ProfileISWV2; + break; + case E3GPAvcProfileBaseline: + iOmxVideoFormat.iCoding = OMX_VIDEO_CodingAVC; + iOmxVideoFormat.iProfile.avc = OMX_VIDEO_AVCProfileBaseline; + break; + default: + // do not return an error here, the error is signalled after the transition to Executing + iOmxVideoFormat.iCoding = OMX_VIDEO_CodingMax; + break; + } + } + iVideoPropertiesRead = ETrue; + } + + return OMX_ErrorNone; + } + + +OMX_ERRORTYPE C3GPDemuxer::GetMetadataL(OMX_CONFIG_METADATAITEMTYPE* aMetadata) + { + // Metadata key size must be at least 4 + if (aMetadata->nKeySizeUsed < 4) + { + return OMX_ErrorBadParameter; + } + + T3GPUdtaLocation udtaLocation; + TUint32 udtaAtomType = Pack32(aMetadata->nKey); + TUint32 buffersize = aMetadata->nValueMaxSize; + + RBuf8 buffer; + CleanupClosePushL(buffer); + User::LeaveIfError(buffer.Create(buffersize)); + + TUint atomIndex = 0; + if (aMetadata->nMetadataItemIndex != OMX_ALL) + { + atomIndex = aMetadata->nMetadataItemIndex; + } + + TInt error = KErrNone; + + switch (aMetadata->eScopeMode) + { + case OMX_MetadataScopeAllLevels: + { + TUint subatomCount = 0; + udtaLocation = E3GPUdtaMoov; + + error = i3GPParser->GetUserDataAtom(udtaAtomType, udtaLocation, buffer, subatomCount); + + if (error == KErrNone) + { + if (atomIndex == 0) + { + break; + } + else if (atomIndex <= subatomCount) + { + error = i3GPParser->GetUserDataAtom(udtaAtomType, udtaLocation, buffer, atomIndex); + break; + } + else + { + atomIndex -= (subatomCount + 1); + } + } + else if (error != KErrNotFound) + { + break; + } + + subatomCount = 0; + udtaLocation = E3GPUdtaVideoTrak; + error = i3GPParser->GetUserDataAtom(udtaAtomType, udtaLocation, + buffer, subatomCount); + if (error == KErrNone) + { + if (atomIndex == 0) + { + break; + } + else if (atomIndex <= subatomCount) + { + error = i3GPParser->GetUserDataAtom(udtaAtomType, udtaLocation, buffer, atomIndex); + break; + } + else + { + atomIndex -= (subatomCount + 1); + } + } + else if (error != KErrNotFound) + { + break; + } + + udtaLocation = E3GPUdtaAudioTrak; + error = i3GPParser->GetUserDataAtom(udtaAtomType, udtaLocation, + buffer, atomIndex); + } + break; + case OMX_MetadataScopeTopLevel: + { + udtaLocation = E3GPUdtaMoov; + error = i3GPParser->GetUserDataAtom(udtaAtomType, udtaLocation, + buffer, atomIndex); + } + break; + case OMX_MetadataScopePortLevel: + { + if (aMetadata->nScopeSpecifier + == COmxIL3GPDemuxer::EPortIndexVideoOutput) + { + udtaLocation = E3GPUdtaVideoTrak; + error = i3GPParser->GetUserDataAtom(udtaAtomType, udtaLocation, + buffer, atomIndex); + } + else if (aMetadata->nScopeSpecifier == COmxIL3GPDemuxer::EPortIndexAudioOutput) + { + udtaLocation = E3GPUdtaAudioTrak; + error = i3GPParser->GetUserDataAtom(udtaAtomType, udtaLocation, buffer, atomIndex); + } + else + { + error = KErrArgument; + } + } + break; + default: + { + error = KErrArgument; + } + } + + if (error == KErrNone) + { + // strip size and atom type from the buffer + Mem::Copy(aMetadata->nValue, (buffer.Ptr() + 8), (buffer.Size() - 8)); + aMetadata->nValueSizeUsed = (buffer.Size() - 8); + } + + CleanupStack::PopAndDestroy();//buffer + return SymbianOSErrorToOmx(error); + } + +void C3GPDemuxer::RunL() + { + iWaitingOnBufferQueue = EFalse; + ReceiveQueuedBuffers(); + + if (iPaused || iInvalid || iState == EStateWaitingToStart) + { + StartWaitingForBuffer(); + return; + } + + if (iState == EStateWaitingToSubmit) + { + SubmitBuffer(); + } + + if (!ProcessBuffers()) + { + iState = EStateWaitingForBuffer; + StartWaitingForBuffer(); + } + } + +void C3GPDemuxer::DoCancel() + { + if (iWaitingOnBufferQueue) + { + iWaitingOnBufferQueue = EFalse; + iBufferQueue.CancelDataAvailable(); + } + } + +TBool C3GPDemuxer::ProcessBuffers() + { + TUint32 startPort = iCurrentPort; + + do + { + if (iPort[iCurrentPort]->iBuffers.Count() > 0 && !iPort[iCurrentPort]->iEOS) + { + DoProcessBuffer(); + return ETrue; + } + } + while (NextPort() != startPort); + + return EFalse; + } + +void C3GPDemuxer::DoProcessBuffer() + { + iState = EStateFillingBuffer; + + iCurrentBuffer = iPort[iCurrentPort]->iBuffers[0]; + iPort[iCurrentPort]->iBuffers.Remove(0); + + switch(iCurrentPort) + { + case COmxIL3GPDemuxer::EPortIndexTimeInput: + { + ProcessTimeBuffer(); + break; + } + case COmxIL3GPDemuxer::EPortIndexAudioOutput: + { + FillAudioBuffer(); + break; + } + case COmxIL3GPDemuxer::EPortIndexVideoOutput: + { + FillVideoBuffer(); + break; + } + } + } + +void C3GPDemuxer::ProcessTimeBuffer() + { + // TODO + User::Invariant(); + } + +void C3GPDemuxer::FillAudioBuffer() + { + if (!iAudioHeadersSent) + { + TPtr8 audioBuffer(iCurrentBuffer->pBuffer + iCurrentBuffer->nOffset + iCurrentBuffer->nFilledLen, + 0, + static_cast(iCurrentBuffer->nAllocLen - iCurrentBuffer->nOffset - iCurrentBuffer->nFilledLen)); + TInt error = i3GPParser->GetAudioDecoderSpecificInfo(audioBuffer); + + if (error == KErrNone) + { + iCurrentBuffer->nFilledLen = audioBuffer.Length(); + iCurrentBuffer->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; + iAudioHeadersSent = ETrue; + SubmitBuffer(); + CompleteSelf(); + } + else + { + HandleIfError(error); + } + return; + } + + iAsyncBuf.Set(iCurrentBuffer->pBuffer + iCurrentBuffer->nOffset + iCurrentBuffer->nFilledLen + ,0 + ,static_cast(iCurrentBuffer->nAllocLen - iCurrentBuffer->nOffset - iCurrentBuffer->nFilledLen)); + i3GPParser->ReadAudioFrames(*this, iAsyncBuf); + } + +void C3GPDemuxer::FillVideoBuffer() + { + if (!iVideoHeadersSent) + { + iCurrentBuffer->nOffset = 0; + + TPtr8 videoBuffer(iCurrentBuffer->pBuffer + iCurrentBuffer->nOffset + iCurrentBuffer->nFilledLen, + 0, + static_cast(iCurrentBuffer->nAllocLen - iCurrentBuffer->nOffset - iCurrentBuffer->nFilledLen)); + TInt error = i3GPParser->GetVideoDecoderSpecificInfo(videoBuffer); + + if (error == KErrNone) + { + iCurrentBuffer->nFilledLen = videoBuffer.Length(); + iCurrentBuffer->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; + iVideoHeadersSent = ETrue; + SubmitBuffer(); + CompleteSelf(); + } + else + { + HandleIfError(error); + } + return; + } + + iAsyncBuf.Set(&iCurrentBuffer->pBuffer[0] + ,static_cast((iCurrentBuffer->nFilledLen + iCurrentBuffer->nOffset)) + ,static_cast(iCurrentBuffer->nAllocLen)); + i3GPParser->ReadVideoFrame(*this, iAsyncBuf); + } + +void C3GPDemuxer::AudioFramesAvailable(TInt aError, TUint /*aReturnedFrames*/, + TUint aTimeStampInMs, TUint /*aTimeStampInTimescale*/) + { + HandleIfError(aError); + + if (!iInvalid) + { + // Check if this is the last frame. It is the last frame if + // GetAudioFramesSize returns KErrNotFound + TUint frameSize = 0; + TInt nextFrameError = i3GPParser->GetAudioFramesSize(frameSize); + + FileReadComplete(nextFrameError, aTimeStampInMs, iFirstAudioFrame, EFalse); + } + } + +void C3GPDemuxer::VideoFrameAvailable(TInt aError, TBool aKeyFrame, TUint +aTimeStampInMs, TUint /*aTimeStampInTimescale*/) + { + HandleIfError(aError); + + if (!iInvalid) + { + // Check if this is the last frame. It is the last frame if + // GetVideoFramesSize returns KErrNotFound + TUint frameSize = 0; + TInt nextFrameError = i3GPParser->GetVideoFrameSize(frameSize); + + FileReadComplete(nextFrameError, aTimeStampInMs, iFirstVideoFrame, aKeyFrame); + } + } + +void C3GPDemuxer::FileReadComplete(TInt aNextFrameError, TUint32 aTimeStamp, TBool& aFirstFrame, TBool aKeyFrame) + { + // aNextFrameError is the error code returned when checking the size of the + // next audio or video frame. If the error code is KErrNotFound, this + // shows that no more frames exist in that stream so the end of stream flag + // should be set when sending out the buffer. + if (aNextFrameError == KErrNotFound) + { + iPort[iCurrentPort]->iEOS = ETrue; + } + else + { + HandleIfError(aNextFrameError); + } + + if (!iInvalid) + { + iCurrentBuffer->nFilledLen += iAsyncBuf.Length(); + + // Set presentation time + iCurrentBuffer->nTimeStamp = aTimeStamp * 1000; + + if (aFirstFrame) + { + iCurrentBuffer->nFlags |= OMX_BUFFERFLAG_STARTTIME; + aFirstFrame = EFalse; + } + else + { + iCurrentBuffer->nFlags &= ~OMX_BUFFERFLAG_STARTTIME; + } + + if (aKeyFrame) + { + iCurrentBuffer->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; + } + else + { + iCurrentBuffer->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME; + } + + // Demuxer just puts one whole frame into a buffer so we + // can set the end of frame flag + iCurrentBuffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + + SubmitBuffer(); + CompleteSelf(); + } + } + +void C3GPDemuxer::SubmitBuffer() + { + if (!iPaused) + { + if (iPort[iCurrentPort]->iEOS) + { + iCurrentBuffer->nFlags |= OMX_BUFFERFLAG_EOS; + iCallbacks.EventNotification(OMX_EventBufferFlag, iCurrentPort, + iCurrentBuffer->nFlags, NULL); + } + #if 0 + else if (iCurrentBuffer->nFlags & OMX_BUFFERFLAG_STARTTIME) + { + iCallbacks.EventNotification(OMX_EventBufferFlag, iCurrentPort, + iCurrentBuffer->nFlags, NULL); + } + #endif + + iCallbacks.BufferDoneNotification(iCurrentBuffer, iCurrentPort, + OMX_DirOutput); + + iState = EStateWaitingForBuffer; + NextPort(); + } + else + { + iState = EStateWaitingToSubmit; + } + } + +void C3GPDemuxer::CreateBufferQueueL() + { + DEBUG_PRINTF(_L8("C3GPDemuxer::CreateBufferQueueL++")); + + iPort[COmxIL3GPDemuxer::EPortIndexTimeInput] = CPort::NewL(KMaxTimeBuffers); + iPort[COmxIL3GPDemuxer::EPortIndexAudioOutput] = CPort::NewL(KMaxAudioBuffers); + iPort[COmxIL3GPDemuxer::EPortIndexVideoOutput] = CPort::NewL(KMaxVideoBuffers); + + User::LeaveIfError(iBufferQueue.CreateLocal(KMaxTimeBuffers + KMaxAudioBuffers + KMaxVideoBuffers)); + iBufferQueueCreated = ETrue; + iState = EStateWaitingToStart; + StartWaitingForBuffer(); + + DEBUG_PRINTF(_L8("C3GPDemuxer::CreateBufferQueueL--")); + } + +void C3GPDemuxer::DeleteBufferQueue() + { + if (iBufferQueueCreated) + { + Cancel(); + iBufferQueueCreated = EFalse; + iBufferQueue.Close(); + } + + for (TInt port = 0; port < COmxIL3GPDemuxer::EPortIndexMax; ++port) + { + delete iPort[port]; + iPort[port] = NULL; + } + } + +void C3GPDemuxer::HandleIfError(TInt aError) + { + OMX_ERRORTYPE omxError = SymbianOSErrorToOmx(aError); + + if (omxError != OMX_ErrorNone) + { + iInvalid = ETrue; + iCallbacks.ErrorEventNotification(omxError); + } + } + +// Helper function to convert Symbian OS standard error code to c style error code +OMX_ERRORTYPE C3GPDemuxer::SymbianOSErrorToOmx(TInt aError) const + { + OMX_ERRORTYPE error = OMX_ErrorUndefined; + + switch (aError) + { + case (KErrNone): + { + error = OMX_ErrorNone; + } + break; + case (KErrNoMemory): + { + error = OMX_ErrorInsufficientResources; + } + break; + case (KErrOverflow): + { + error = OMX_ErrorOverflow; + } + break; + case (KErrAccessDenied): + { + error = OMX_ErrorContentPipeOpenFailed; + } + break; + case (KErrCorrupt): + { + error = OMX_ErrorStreamCorrupt; + } + break; + case (KErrArgument): + { + error = OMX_ErrorUnsupportedSetting; + } + break; + default: + { + error = OMX_ErrorUndefined; + } + } + return error; + } + +void C3GPDemuxer::ReceiveQueuedBuffers() + { + if (iBufferQueueCreated) + { + TBufferMessage message; + while(iBufferQueue.Receive(message) != KErrUnderflow) + { + // Port buffers are pre-reserved so append should always work + if (iPort[message.iPortIndex]->iBuffers.Append(message.iBufferHeader) != KErrNone) + { + Panic(EReceiveQueuedBuffersAppendFailed); + } + } + } + } + +void C3GPDemuxer::StartWaitingForBuffer() + { + if (iBufferQueueCreated) + { + iWaitingOnBufferQueue = ETrue; + iBufferQueue.NotifyDataAvailable(iStatus); + SetActive(); + } + } + +void C3GPDemuxer::CompleteSelf() + { + iStatus = KRequestPending; + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + } + +TInt C3GPDemuxer::NextPort() + { + ++iCurrentPort; + iCurrentPort %= COmxIL3GPDemuxer::EPortIndexMax; + return iCurrentPort; + } + +/** Packs four bytes into a 32bit number */ +TUint32 C3GPDemuxer::Pack32(const TUint8* aPtr) + { + TUint32 x = *aPtr++ << 24; + x |= *aPtr++ << 16; + x |= *aPtr++ << 8; + x |= *aPtr++; + return x; + } + +TInt C3GPDemuxer::SetPosition(TUint aTimePosition, TBool aKeyFrame) + { + TUint audioPosition = 0; + TUint videoPosition = 0; + + TInt err = i3GPParser->Seek(aTimePosition, aKeyFrame, audioPosition, videoPosition); + if(err) + { + return err; + } + + // clear EOS state so buffer handling resumes if previously hit EOS + // TODO is this thread safe? + iPort[0]->iEOS = EFalse; + iPort[1]->iEOS = EFalse; + + return KErrNone; + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/c3gpdemuxer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/c3gpdemuxer.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,165 @@ +/* +* Copyright (c) 2008 - 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef C3GPDEMUXER_H +#define C3GPDEMUXER_H + +#include +#include +#include + +#include "comxil3gpdemuxer.h" +#include "tvideoformat.h" +#include "taudioformat.h" + +class MOmxILCallbackNotificationIf; + +NONSHARABLE_CLASS(C3GPDemuxer) : public CActive + ,public M3GPParseCallback + + { +public: + static C3GPDemuxer* NewL(MOmxILCallbackNotificationIf& aCallbacks); + ~C3GPDemuxer(); + + OMX_ERRORTYPE AcquireResources(const TDesC& aFilename); + void ReleaseResources(); + void Start(); + OMX_ERRORTYPE Stop(); + void Pause(); + TBool Invalid() const; + + void ProcessThisBufferL(OMX_BUFFERHEADERTYPE* aBufferHeader, TUint32 aPortIndex); + void FlushBuffers(TUint32 aPortIndex); + TBool RemoveBuffer(OMX_BUFFERHEADERTYPE* aBufferHeader, OMX_DIRTYPE aDirection); + + TBool GetVideoFormat(TSize& aFrameSize, TVideoFormat& aFormat) const; + TBool GetAudioFormat(TAudioFormat& aFormat) const; + OMX_ERRORTYPE GetVideoTimestamp(OMX_TICKS& aOmxTicks); + OMX_ERRORTYPE Seek(const OMX_TICKS& aOmxTicks, OMX_TIME_SEEKMODETYPE aSeekModeType); + OMX_ERRORTYPE DetectStreams(); + OMX_ERRORTYPE GetMetadataL(OMX_CONFIG_METADATAITEMTYPE* aMetadata); + +protected: + void RunL(); + void DoCancel(); + +private: + typedef RPointerArray RQueuedBuffers; + + class CPort : public CBase + { + public: + static CPort* NewL(TInt aBufferCount); + ~CPort(); + + private: + CPort(); + void ConstructL(TInt aBufferCount); + + public: + // Queue of buffers waiting to be processed. Buffers are not owned. + RQueuedBuffers iBuffers; + TBool iEOS; + }; + + class TBufferMessage + { + public: + OMX_BUFFERHEADERTYPE* iBufferHeader; + TUint32 iPortIndex; + }; + + enum TState + { + EStateWaitingToStart, + EStateWaitingForBuffer, + EStateFillingBuffer, + EStateWaitingToSubmit + }; + +private: + C3GPDemuxer(MOmxILCallbackNotificationIf& aCallbacks); + void ConstructL(); + void DoFlushBuffers(TUint32 aPortIndex); + TBool ProcessBuffers(); + void DoProcessBuffer(); + void ProcessTimeBuffer(); + void FillAudioBuffer(); + void FillVideoBuffer(); + void FileReadComplete(TInt aNextFrameError, TUint32 aTimeStamp, TBool& aFirstFrame, TBool aKeyFrame); + void SubmitBuffer(); + void CreateBufferQueueL(); + void DeleteBufferQueue(); + void HandleIfError(TInt aError); + OMX_ERRORTYPE SymbianOSErrorToOmx(TInt aError) const; + void ReceiveQueuedBuffers(); + void StartWaitingForBuffer(); + void CompleteSelf(); + TInt NextPort(); + TUint32 Pack32(const TUint8* aPtr); + TInt SetPosition(TUint aTimePosition, TBool aKeyFrame); + + //M3GPParseCallback functions + void AudioFramesAvailable(TInt aError, TUint aReturnedFrames, TUint aTimeStampInMs, TUint aTimeStampInTimescale); + void VideoFrameAvailable(TInt aError, TBool aKeyFrame, TUint aTimeStampInMs, TUint aTimeStampInTimescale); + +private: + MOmxILCallbackNotificationIf& iCallbacks; + TUint32 iCurrentPort; + OMX_BUFFERHEADERTYPE* iCurrentBuffer; // Not owned + CPort* iPort[COmxIL3GPDemuxer::EPortIndexMax]; + C3GPParse* i3GPParser; + + TBool iVideoPropertiesRead; + T3GPVideoType iVideoType; + TVideoFormat iOmxVideoFormat; + TUint32 iVideoWidth; + TUint32 iVideoHeight; + + TBool iAudioPropertiesRead; + T3GPAudioType iAudioType; + TAudioFormat iOmxAudioFormat; + + TBool iInvalid; + TBool iPaused; + TState iState; + + TBool iVideoHeadersSent; + TBool iAudioHeadersSent; + TBool iFirstVideoFrame; + TBool iFirstAudioFrame; + + RMsgQueue iBufferQueue; + TBool iBufferQueueCreated; + TBool iWaitingOnBufferQueue; + + TPtr8 iAsyncBuf; + + TBool iParserOpened; + TUint iStartTimePosition; + TBool iStartKeyFrame; + TUint iSeekPosition; // The requested seek time in ms. + }; + +#endif //C3GPDEMUXER_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxer.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,204 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + + +#include +#include +#include + +#include "comxil3gpdemuxer.h" +#include "comxil3gpdemuxertimeinputport.h" +#include "comxil3gpdemuxeraudiooutputport.h" +#include "comxil3gpdemuxervideooutputport.h" +#include "comxil3gpdemuxerprocessingfunction.h" +#include "comxil3gpdemuxerconfigmanager.h" +#include "omxil3gpdemuxer.hrh" + +_LIT8(KSymbianOmxIL3gpDemuxerName, "OMX.SYMBIAN.OTHER.CONTAINER_DEMUXER.3GP"); +_LIT8(KSymbianOmxIL3gpDemuxerRole, "container_demuxer"); + +OMXIL_COMPONENT_ECOM_ENTRYPOINT(KUidSymbianOmxIL3gpDemuxer); + +OMX_ERRORTYPE SymbianErrorToOmx(TInt aError); + +// Component Entry Point +OMX_ERRORTYPE OMX_ComponentInit(OMX_HANDLETYPE aComponent) + { + TInt err = COmxIL3GPDemuxer::CreateComponent(aComponent); + return SymbianErrorToOmx(err); + } + +TInt COmxIL3GPDemuxer::CreateComponent(OMX_HANDLETYPE hComponent) + { + COmxIL3GPDemuxer* self = new COmxIL3GPDemuxer(); + + if (!self) + { + return KErrNoMemory; + } + + TRAPD(err, self->ConstructL(hComponent)); + if(err) + { + delete self; + } + return err; + } + +COmxIL3GPDemuxer::COmxIL3GPDemuxer() + { + // nothing to do + } + +void COmxIL3GPDemuxer::ConstructL(OMX_HANDLETYPE hComponent) + { + COmxILComponent::ConstructL(hComponent); + MOmxILCallbackNotificationIf* callbackNotificationIf=CreateCallbackManagerL(COmxILComponent::EOutofContext); + + COmxIL3GPDemuxerProcessingFunction* pProcessingFunction = COmxIL3GPDemuxerProcessingFunction::NewL(*callbackNotificationIf); + RegisterProcessingFunction(pProcessingFunction); + + CreatePortManagerL(COmxILComponent::ENonBufferSharingPortManager, + TOmxILSpecVersion(), // Component's OMX Version + 1, // The number of audio ports in this component + 0, // The starting audio port index + 0, // The number of image ports in this component + 0, // The starting image port index + 1, // The number of video ports in this component + 1, // The starting video port index + 1, // The number of other ports in this component + 2 // The starting other port index + ); + + RPointerArray roleList; + CleanupClosePushL(roleList); + roleList.AppendL(&KSymbianOmxIL3gpDemuxerRole); + COmxIL3GPDemuxerConfigManager* configManager = COmxIL3GPDemuxerConfigManager::NewL(KSymbianOmxIL3gpDemuxerName, TOmxILSpecVersion(), roleList, *(static_cast(pProcessingFunction))); + RegisterConfigurationManager(configManager); + CleanupStack::PopAndDestroy(&roleList); + + static_cast(pProcessingFunction)->SetConfigManager(*configManager); + + AddAudioOutputPortL(); + AddVideoOutputPortL(); + AddTimeInputPortL(); + + InitComponentL(); + } + +COmxIL3GPDemuxer::~COmxIL3GPDemuxer() + { + } + +void COmxIL3GPDemuxer::AddTimeInputPortL() + { + TOmxILSpecVersion specVersion; + + TOmxILCommonPortData portData( + specVersion, + EPortIndexTimeInput, + OMX_DirInput, + 1, // minimum number of buffers + 0, // minimum buffer size, in bytes + OMX_PortDomainOther, + OMX_TRUE, // contigious buffers + 4, // 4-byte alignment + OMX_BufferSupplyUnspecified, + COmxILPort::KBufferMarkPropagationPortNotNeeded + ); + + RArray supportedOtherFormats; + + CleanupClosePushL(supportedOtherFormats); + supportedOtherFormats.Append(OMX_OTHER_FormatTime); + + COmxIL3GPDemuxerTimeInputPort* timeInputPort = COmxIL3GPDemuxerTimeInputPort::NewL(portData, supportedOtherFormats, + *(static_cast(GetProcessingFunction()))); + + CleanupStack::PopAndDestroy(&supportedOtherFormats); + CleanupStack::PushL(timeInputPort); + User::LeaveIfError(AddPort(timeInputPort, OMX_DirInput)); + CleanupStack::Pop();//timeInputPort + } + +void COmxIL3GPDemuxer::AddAudioOutputPortL() + { + TOmxILSpecVersion specVersion; + + TOmxILCommonPortData portData( + specVersion, + EPortIndexAudioOutput, + OMX_DirOutput, + 1, // minimum number of buffers + 1600, // minimum buffer size, in bytes + OMX_PortDomainAudio, + OMX_FALSE, // do not need contigious buffers + 4, // 4-byte alignment + OMX_BufferSupplyUnspecified, + EPortIndexAudioOutput + ); + + COmxIL3GPDemuxerAudioOutputPort* audioOutputPort = COmxIL3GPDemuxerAudioOutputPort::NewL(portData, *(static_cast(GetProcessingFunction()))); + CleanupStack::PushL(audioOutputPort); + User::LeaveIfError(AddPort(audioOutputPort, OMX_DirOutput)); + CleanupStack::Pop();//audioOutputPort + + static_cast(GetProcessingFunction())->SetAudioPort(*audioOutputPort); + } + +void COmxIL3GPDemuxer::AddVideoOutputPortL() + { + TOmxILSpecVersion specVersion; + + TOmxILCommonPortData portData( + specVersion, + EPortIndexVideoOutput, + OMX_DirOutput, + 1, // minimum number of buffers, we don't need buffers for format detection + 62400, // minimum buffer size, in bytes, TODO autodetect this + OMX_PortDomainVideo, + OMX_FALSE, // do not need contigious buffers + 4, // 4-byte alignment + OMX_BufferSupplyUnspecified, + EPortIndexVideoOutput + ); + + COmxIL3GPDemuxerVideoOutputPort* videoOutputPort = COmxIL3GPDemuxerVideoOutputPort::NewL(portData, *(static_cast(GetProcessingFunction()))); + CleanupStack::PushL(videoOutputPort); + User::LeaveIfError(AddPort(videoOutputPort, OMX_DirOutput)); + CleanupStack::Pop();//videoOutputPort + static_cast(GetProcessingFunction())->SetVideoPort(*videoOutputPort); + } + +OMX_ERRORTYPE SymbianErrorToOmx(TInt aError) + { + switch(aError) + { + case KErrNone: + return OMX_ErrorNone; + case KErrNoMemory: + return OMX_ErrorInsufficientResources; + default: + return OMX_ErrorUndefined; + } + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxer.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef COMXIL3GPDEMUXER_H +#define COMXIL3GPDEMUXER_H + +#include + +class COmxIL3GPDemuxerTimeInputPort; +class COmxIL3GPDemuxerAudioOutputPort; +class COmxIL3GPDemuxerVideoOutputPort; + +NONSHARABLE_CLASS(COmxIL3GPDemuxer) : public COmxILComponent + { +public: + enum TPortIndex + { + EPortIndexAudioOutput, + EPortIndexVideoOutput, + EPortIndexTimeInput, // time port currently not used + EPortIndexMax // Must be last + }; + +public: + static TInt CreateComponent(OMX_HANDLETYPE hComponent); + ~COmxIL3GPDemuxer(); + +private: + COmxIL3GPDemuxer(); + void ConstructL(OMX_HANDLETYPE hComponent); + +private: + void AddTimeInputPortL(); + void AddAudioOutputPortL(); + void AddVideoOutputPortL(); + }; + +#endif //COMXIL3GPDEMUXER_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxeraudiooutputport.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxeraudiooutputport.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,201 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include "log.h" +#include "comxil3gpdemuxeraudiooutputport.h" +#include "comxil3gpdemuxerprocessingfunction.h" +#include "taudioformat.h" + +// TODO: Possibly add other mime types, for now only AAC handled +_LIT8(KMimeTypeAudioAac, "audio/aac"); +_LIT(K3GPDemuxerAudioPortPanic, "COmxIL3GPDemuxerVideoOutputPort"); + + +COmxIL3GPDemuxerAudioOutputPort* COmxIL3GPDemuxerAudioOutputPort::NewL(const TOmxILCommonPortData& aCommonPortData, + COmxIL3GPDemuxerProcessingFunction& aProcessingFunction) + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerAudioOutputPort::NewL")); + // TODO this array must be left empty, to be removed from the audio port constructor + + COmxIL3GPDemuxerAudioOutputPort* self = new(ELeave) COmxIL3GPDemuxerAudioOutputPort(aProcessingFunction); + CleanupStack::PushL(self); + self->ConstructL(aCommonPortData); + CleanupStack::Pop(self); + return self; + } + +void COmxIL3GPDemuxerAudioOutputPort::ConstructL(const TOmxILCommonPortData& aCommonPortData) + { + RArray supportedCodings; + CleanupClosePushL(supportedCodings); + supportedCodings.AppendL(OMX_AUDIO_CodingAAC); + COmxILAudioPort::ConstructL(aCommonPortData, supportedCodings); + CleanupStack::PopAndDestroy(&supportedCodings); + + OMX_PARAM_PORTDEFINITIONTYPE& paramPortDefinition=GetParamPortDefinition(); + // We have to finish with iParamPortDefinition + paramPortDefinition.eDomain = OMX_PortDomainAudio; + paramPortDefinition.format.audio.pNativeRender = 0; + + // TODO: Possible add in the future other mime types that can be handled by + // this audio port... for now only AAC Check + // COmxILAudioPort::iParamAudioPortFormat.nIndex and use + // COmxILAudioPort::iSupportedAudioFormats[iParamAudioPortFormat.nIndex] + + iMimeTypeBuf.CreateL(KMimeTypeAudioAac(), KMimeTypeAudioAac().Length() + 1); + + TUint8* pTUint = const_cast(iMimeTypeBuf.PtrZ()); + paramPortDefinition.format.audio.cMIMEType = reinterpret_cast(pTUint); + + paramPortDefinition.format.audio.bFlagErrorConcealment = OMX_FALSE; + paramPortDefinition.format.audio.eEncoding = OMX_AUDIO_CodingAAC; + } + +COmxIL3GPDemuxerAudioOutputPort::COmxIL3GPDemuxerAudioOutputPort(COmxIL3GPDemuxerProcessingFunction& aProcessingFunction) +: iProcessingFunction(&aProcessingFunction) + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerAudioOutputPort::COmxIL3GPDemuxerAudioOutputPort")); + } + +COmxIL3GPDemuxerAudioOutputPort::~COmxIL3GPDemuxerAudioOutputPort() + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerAudioOutputPort::~COmxIL3GPDemuxerAudioOutputPort")); + iMimeTypeBuf.Close(); + } + +OMX_ERRORTYPE COmxIL3GPDemuxerAudioOutputPort::GetLocalOmxParamIndexes(RArray& aIndexArray) const + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerAudioOutputPort::GetLocalOmxParamIndexes")); + OMX_ERRORTYPE omxRetValue = COmxILAudioPort::GetLocalOmxParamIndexes(aIndexArray); + if (omxRetValue != OMX_ErrorNone) + { + return omxRetValue; + } + + TInt err = aIndexArray.InsertInOrder(OMX_IndexParamNumAvailableStreams); + // Note that index duplication is OK. + if (err == KErrNone || err == KErrAlreadyExists) + { + err = aIndexArray.InsertInOrder(OMX_IndexParamActiveStream); + } + + if (err != KErrNone && err != KErrAlreadyExists) + { + return OMX_ErrorInsufficientResources; + } + + return OMX_ErrorNone; + } + +OMX_ERRORTYPE COmxIL3GPDemuxerAudioOutputPort::GetLocalOmxConfigIndexes(RArray& aIndexArray) const + { + return COmxILAudioPort::GetLocalOmxConfigIndexes(aIndexArray); + } + +OMX_ERRORTYPE COmxIL3GPDemuxerAudioOutputPort::GetParameter(OMX_INDEXTYPE aParamIndex, + TAny* apComponentParameterStructure) const + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerAudioOutputPort::GetParameter")); + switch(aParamIndex) + { + case OMX_IndexParamNumAvailableStreams: + { + OMX_PARAM_U32TYPE* u32Type = reinterpret_cast(apComponentParameterStructure); + u32Type->nU32 = iProcessingFunction->NumAvailableStreams(COmxIL3GPDemuxer::EPortIndexAudioOutput); + return OMX_ErrorNone; + } + + case OMX_IndexParamActiveStream: + { + OMX_PARAM_U32TYPE* u32Type = reinterpret_cast(apComponentParameterStructure); + u32Type->nU32 = iProcessingFunction->ActiveStream(COmxIL3GPDemuxer::EPortIndexAudioOutput); + return OMX_ErrorNone; + } + + default: + { + return COmxILAudioPort::GetParameter(aParamIndex, apComponentParameterStructure); + } + } + } + +OMX_ERRORTYPE COmxIL3GPDemuxerAudioOutputPort::SetParameter(OMX_INDEXTYPE aParamIndex, + const TAny* apComponentParameterStructure, + TBool& aUpdateProcessingFunction) + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerAudioOutputPort::SetParameter")); + switch(aParamIndex) + { + case OMX_IndexParamActiveStream: + { + const OMX_PARAM_U32TYPE* u32Type = reinterpret_cast(apComponentParameterStructure); + return iProcessingFunction->SetActiveStream(COmxIL3GPDemuxer::EPortIndexAudioOutput, u32Type->nU32); + } + + default: + { + return COmxILAudioPort::SetParameter(aParamIndex, apComponentParameterStructure, aUpdateProcessingFunction); + } + } + } + +OMX_ERRORTYPE COmxIL3GPDemuxerAudioOutputPort::SetFormatInPortDefinition( + const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition, + TBool& /*aUpdateProcessingFunction*/) + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerAudioOutputPort::SetFormatInPortDefinition")); + + if (aPortDefinition.nBufferCountActual > KMaxAudioBuffers) + { + return OMX_ErrorBadParameter; + } + + GetParamPortDefinition().format.audio = aPortDefinition.format.audio; + + return OMX_ErrorNone; + } + +TBool COmxIL3GPDemuxerAudioOutputPort::IsTunnelledPortCompatible(const OMX_PARAM_PORTDEFINITIONTYPE& /*aPortDefinition*/) const + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerAudioOutputPort::IsTunnelledPortCompatible")); + + // This function only gets called on input ports, so panic if this is ever called + User::Panic(K3GPDemuxerAudioPortPanic, KErrGeneral); + return EFalse; // to keep compiler happy + } + +void COmxIL3GPDemuxerAudioOutputPort::FormatDetected(const TAudioFormat& aFormat) + { + GetParamPortDefinition().format.audio.eEncoding = aFormat.iCoding; + } + +OMX_AUDIO_CODINGTYPE COmxIL3GPDemuxerAudioOutputPort::AudioFormat() + { + return GetParamPortDefinition().format.audio.eEncoding; + } + +/** Returns the number of buffers configured on this port. */ +TInt COmxIL3GPDemuxerAudioOutputPort::BufferCount() const + { + return GetParamPortDefinition().nBufferCountActual; + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxeraudiooutputport.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxeraudiooutputport.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,70 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef COMXIL3GPDEMUXERAUDIOOUTPUTPORT_H +#define COMXIL3GPDEMUXERAUDIOOUTPUTPORT_H + +#include + +class COmxIL3GPDemuxerProcessingFunction; +class TAudioFormat; + +const TInt KMaxAudioBuffers = 10; + +NONSHARABLE_CLASS(COmxIL3GPDemuxerAudioOutputPort) : public COmxILAudioPort + { +public: + static COmxIL3GPDemuxerAudioOutputPort* NewL(const TOmxILCommonPortData& aCommonPortData, + COmxIL3GPDemuxerProcessingFunction& aProcessingFunction); + ~COmxIL3GPDemuxerAudioOutputPort(); + + void FormatDetected(const TAudioFormat& aFormat); + OMX_AUDIO_CODINGTYPE AudioFormat(); + TInt BufferCount() const; + + // from COmxILAudioPort + OMX_ERRORTYPE GetLocalOmxParamIndexes(RArray& aIndexArray) const; + OMX_ERRORTYPE GetLocalOmxConfigIndexes(RArray& aIndexArray) const; + OMX_ERRORTYPE GetParameter(OMX_INDEXTYPE aParamIndex, + TAny* apComponentParameterStructure) const; + OMX_ERRORTYPE SetParameter(OMX_INDEXTYPE aParamIndex, + const TAny* apComponentParameterStructure, + TBool& aUpdateProcessingFunction); + +protected: + // from COmxILAudioPort + OMX_ERRORTYPE SetFormatInPortDefinition(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition, + TBool& aUpdateProcessingFunction); + TBool IsTunnelledPortCompatible(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition) const; + +private: + COmxIL3GPDemuxerAudioOutputPort(COmxIL3GPDemuxerProcessingFunction& aProcessingFunction); + + void ConstructL(const TOmxILCommonPortData& aCommonPortData); + +private: + RBuf8 iMimeTypeBuf; + COmxIL3GPDemuxerProcessingFunction* iProcessingFunction; // not owned + }; + +#endif //COMXIL3GPDEMUXERAUDIOOUTPUTPORT_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerconfigmanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerconfigmanager.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,243 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include + +#include "comxil3gpdemuxerprocessingfunction.h" +#include "comxil3gpdemuxerconfigmanager.h" +#include "c3gpdemuxer.h" + + + +COmxIL3GPDemuxerConfigManager* COmxIL3GPDemuxerConfigManager::NewL( + const TDesC8& aComponentName, + const OMX_VERSIONTYPE& aComponentVersion, + const RPointerArray& aComponentRoleList, + COmxIL3GPDemuxerProcessingFunction& aPf) + { + COmxIL3GPDemuxerConfigManager* self = new(ELeave) COmxIL3GPDemuxerConfigManager(aPf); + CleanupStack::PushL(self); + self->ConstructL(aComponentName, aComponentVersion, aComponentRoleList); + CleanupStack::Pop(self); + return self; + } + +COmxIL3GPDemuxerConfigManager::COmxIL3GPDemuxerConfigManager(COmxIL3GPDemuxerProcessingFunction& aPf): + iSeekMode(OMX_TIME_SeekModeFast), + iPf(aPf) + { + // nothing to do + } + +void COmxIL3GPDemuxerConfigManager::ConstructL(const TDesC8& aComponentName, + const OMX_VERSIONTYPE& aComponentVersion, + const RPointerArray& aComponentRoleList) + { + COmxILConfigManager::ConstructL(aComponentName, aComponentVersion, aComponentRoleList); + } + +COmxIL3GPDemuxerConfigManager::~COmxIL3GPDemuxerConfigManager() + { + delete iUri; + delete iFilename; + } + +OMX_ERRORTYPE COmxIL3GPDemuxerConfigManager::GetParameter(OMX_INDEXTYPE aParamIndex, + TAny* aComponentParameterStructure) const + { + // try the base class first + OMX_ERRORTYPE error = COmxILConfigManager::GetParameter(aParamIndex, aComponentParameterStructure); + if(error != OMX_ErrorUnsupportedIndex) + { + return error; + } + + if(aParamIndex == OMX_IndexParamContentURI) + { + if(!iUri) + { + // content URI has not yet been set + return OMX_ErrorUnsupportedSetting; // TODO check return code + } + OMX_PARAM_CONTENTURITYPE* contentUri = reinterpret_cast(aComponentParameterStructure); + TPtr8 destDes(contentUri->contentURI, contentUri->nSize - _FOFF(OMX_PARAM_CONTENTURITYPE, contentURI)); + // using >= as a byte has to be left for the null terminator + if(iUri->Length() >= destDes.MaxLength()) + { + // not enough room in supplied struct to copy URI + return OMX_ErrorOverflow; // TODO check return code + } + else + { + destDes = *iUri; + destDes.Append('\0'); + return OMX_ErrorNone; + } + } + else if (aParamIndex == OMX_IndexConfigMetadataItem) + { + if(!iDemuxer) + { + return OMX_ErrorNotReady; + } + + OMX_CONFIG_METADATAITEMTYPE* metaData = reinterpret_cast(aComponentParameterStructure); + OMX_ERRORTYPE omxError = OMX_ErrorNone; + TRAPD(error, omxError = iDemuxer->GetMetadataL(metaData)); + if (error != KErrNone) + { + return OMX_ErrorUndefined; + } + else + { + return omxError; + } + } + + return OMX_ErrorUnsupportedIndex; + } + +OMX_ERRORTYPE COmxIL3GPDemuxerConfigManager::SetParameter(OMX_INDEXTYPE aParamIndex, + const TAny* aComponentParameterStructure, + OMX_BOOL aInitTime) + { + // try the base class first + OMX_ERRORTYPE error = COmxILConfigManager::SetParameter(aParamIndex, aComponentParameterStructure, aInitTime); + if(error != OMX_ErrorUnsupportedIndex) + { + return error; + } + + if(aParamIndex == OMX_IndexParamContentURI) + { + const OMX_PARAM_CONTENTURITYPE* contentUri = reinterpret_cast(aComponentParameterStructure); + TPtrC8 uriDes(contentUri->contentURI); + + // validate URI by converting to filename + TUriParser8 parser; + if(parser.Parse(uriDes) != KErrNone) + { + return OMX_ErrorBadParameter; + } + + HBufC* newFilename = NULL; + TInt error; + TRAP(error, newFilename = parser.GetFileNameL()); + if(error == KErrNoMemory) + { + return OMX_ErrorInsufficientResources; + } + else if(error != KErrNone) + { + return OMX_ErrorBadParameter; + } + + // retain a copy of the original URI for GetParameter + HBufC8* newUri = HBufC8::New(uriDes.Length()); + if(!newUri) + { + delete newFilename; + return OMX_ErrorInsufficientResources; + } + *newUri = uriDes; + + delete iUri; + iUri = newUri; + delete iFilename; + iFilename = newFilename; + + return iPf.ParamIndication(aParamIndex, aComponentParameterStructure); + } + + return OMX_ErrorUnsupportedIndex; + } + +OMX_ERRORTYPE COmxIL3GPDemuxerConfigManager::GetConfig(OMX_INDEXTYPE aConfigIndex, + TAny* apComponentConfigStructure) const + { + switch (aConfigIndex) + { + case OMX_IndexConfigTimePosition: + { + if(!iDemuxer) + { + return OMX_ErrorNotReady; + } + OMX_TIME_CONFIG_TIMESTAMPTYPE* timestampType = reinterpret_cast(apComponentConfigStructure); + return iDemuxer->GetVideoTimestamp(timestampType->nTimestamp); + } + + case OMX_IndexConfigTimeSeekMode: + { + OMX_TIME_CONFIG_SEEKMODETYPE* seekModeType = reinterpret_cast(apComponentConfigStructure); + seekModeType->eType = iSeekMode; + return OMX_ErrorNone; + } + + default: + { + return COmxILConfigManager::GetConfig(aConfigIndex, apComponentConfigStructure); + } + } + } + +OMX_ERRORTYPE COmxIL3GPDemuxerConfigManager::SetConfig(OMX_INDEXTYPE aConfigIndex, + const TAny* apComponentConfigStructure) + { + switch (aConfigIndex) + { + case OMX_IndexConfigTimePosition: + { + const OMX_TIME_CONFIG_TIMESTAMPTYPE* timestampType = reinterpret_cast(apComponentConfigStructure); + if (OMX_TIME_SeekModeAccurate == iSeekMode) + { + return OMX_ErrorUnsupportedSetting; //Accurate mode is not supported currently. + } + //Currently only the fast mode is supported so not using iSeekMode as parameter. + iDemuxer->Seek(timestampType->nTimestamp, OMX_TIME_SeekModeFast); + return iPf.ConfigIndication(aConfigIndex, apComponentConfigStructure); + } + + case OMX_IndexConfigTimeSeekMode: + { + const OMX_TIME_CONFIG_SEEKMODETYPE* seekModeType = reinterpret_cast(apComponentConfigStructure); + iSeekMode = seekModeType->eType; + return iPf.ConfigIndication(aConfigIndex, apComponentConfigStructure); + } + + default: + { + return COmxILConfigManager::SetConfig(aConfigIndex, apComponentConfigStructure); + } + } + } + +const HBufC* COmxIL3GPDemuxerConfigManager::Filename() const + { + return iFilename; + } + +void COmxIL3GPDemuxerConfigManager::SetDemuxer(C3GPDemuxer& aDemuxer) + { + iDemuxer = &aDemuxer; + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerconfigmanager.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerconfigmanager.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef COMXIL3GPDEMUXERCONFIGMANAGER_H +#define COMXIL3GPDEMUXERCONFIGMANAGER_H + +#include + +// Forward declarations +class C3GPDemuxer; + + +NONSHARABLE_CLASS(COmxIL3GPDemuxerConfigManager) : public COmxILConfigManager + { +public: + static COmxIL3GPDemuxerConfigManager* NewL( + const TDesC8& aComponentName, + const OMX_VERSIONTYPE& aComponentVersion, + const RPointerArray& aComponentRoles, + COmxIL3GPDemuxerProcessingFunction& aPf); + + ~COmxIL3GPDemuxerConfigManager(); + + // from COmxILConfigManager + OMX_ERRORTYPE GetParameter(OMX_INDEXTYPE aParamIndex, + TAny* aComponentParameterStructure) const; + OMX_ERRORTYPE SetParameter(OMX_INDEXTYPE aParamIndex, + const TAny* aComponentParameterStructure, + OMX_BOOL aInitTime = OMX_TRUE); + OMX_ERRORTYPE GetConfig(OMX_INDEXTYPE aConfigIndex, + TAny* apComponentConfigStructure) const; + OMX_ERRORTYPE SetConfig(OMX_INDEXTYPE aConfigIndex, + const TAny* apComponentConfigStructure); + + /** can return NULL if parameter has not been set. */ + const HBufC* Filename() const; + void SetDemuxer(C3GPDemuxer& aDemuxer); + +private: + COmxIL3GPDemuxerConfigManager(COmxIL3GPDemuxerProcessingFunction& aPf); + + void ConstructL(const TDesC8& aComponentName, + const OMX_VERSIONTYPE& aComponentVersion, + const RPointerArray& aComponentRoles); + +private: + HBufC8* iUri; + HBufC* iFilename; + C3GPDemuxer* iDemuxer; // Not owned + OMX_TIME_SEEKMODETYPE iSeekMode; + COmxIL3GPDemuxerProcessingFunction& iPf; + }; + +#endif //COMXIL3GPDEMUXERCONFIGMANAGER_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerprocessingfunction.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerprocessingfunction.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,429 @@ +/* +* Copyright (c) 2008 - 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include "log.h" +#include "comxil3gpdemuxerprocessingfunction.h" +#include "comxil3gpdemuxerconfigmanager.h" +#include "comxil3gpdemuxervideooutputport.h" +#include "comxil3gpdemuxeraudiooutputport.h" +#include "c3gpdemuxer.h" +#include + + +COmxIL3GPDemuxerProcessingFunction* COmxIL3GPDemuxerProcessingFunction::NewL(MOmxILCallbackNotificationIf& aCallbacks) + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerProcessingFunction::NewL")); + + COmxIL3GPDemuxerProcessingFunction* self = new (ELeave) COmxIL3GPDemuxerProcessingFunction(aCallbacks); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +COmxIL3GPDemuxerProcessingFunction::COmxIL3GPDemuxerProcessingFunction(MOmxILCallbackNotificationIf& aCallbacks) : + COmxILProcessingFunction(aCallbacks) + { + } + +void COmxIL3GPDemuxerProcessingFunction::ConstructL() + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerProcessingFunction::ConstructL")); + + iDemuxer = C3GPDemuxer::NewL(iCallbacks); + + // this is used in the Idle->Executing transition to issue the port changed events in the correct order + // we create the callback now so it cannot fail later on + iStreamDetectCallback = new(ELeave) CAsyncCallBack(TCallBack(StreamDetectCallBack, this), CAsyncCallBack::EPriorityHigh); + + iRequestHelper = COmxIL3GPDemuxerRequestHelper::NewL(this); + } + +COmxIL3GPDemuxerProcessingFunction::~COmxIL3GPDemuxerProcessingFunction() + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerProcessingFunction::~COmxIL3GPDemuxerProcessingFunction")); + + delete iDemuxer; + delete iStreamDetectCallback; + delete iRequestHelper; + } + +void COmxIL3GPDemuxerProcessingFunction::SetConfigManager(COmxIL3GPDemuxerConfigManager& aConfigManager) + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerProcessingFunction::SetConfigManager")); + + iConfigManager = &aConfigManager; + iConfigManager->SetDemuxer(*iDemuxer); + } + +OMX_ERRORTYPE COmxIL3GPDemuxerProcessingFunction::StateTransitionIndication(TStateIndex aNewState) + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerProcessingFunction::StateTransitionIndication")); + + return iRequestHelper->StateTransitionIndication(aNewState); + } + +OMX_ERRORTYPE COmxIL3GPDemuxerProcessingFunction::DoStateTransitionIndication(TStateIndex aNewState) + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerProcessingFunction::DoStateTransitionIndication")); + + OMX_ERRORTYPE omxError = OMX_ErrorNone; + + switch(aNewState) + { + case EStateExecuting: + { + DEBUG_PRINTF(_L8("StateTransitionIndication : OMX_StateExecuting")); + + // Cause PortFormatDetected and PortSettingsChanged with + // the format detected from the file. + + // However, we want this to occur after the idle->executing + // completion notification, which FsmTransition() will queue + // after this function completes. So we use a CAsyncCallBack + // to create the events at some time after FsmTransition() + // completes. A high priority is chosen to avoid being starved + // by other busy AOs, in particular the callback manager(s). + + if(!iStreamsDetected) + { + iStreamDetectCallback->CallBack(); + } + else + { + iDemuxer->Start(); + iExecuting = ETrue; + } + + break; + } + + case ESubStateLoadedToIdle: + { + DEBUG_PRINTF(_L8("StateTransitionIndication : OMX_StateLoadedToIdle")); + + const HBufC* filename = iConfigManager->Filename(); + if(filename) + { + // get the maximum buffer count for a port + omxError = iDemuxer->AcquireResources(*filename); + } + else + { + // no file name has been set + omxError = OMX_ErrorUnsupportedSetting; + } + break; + } + + case EStateIdle: + { + DEBUG_PRINTF(_L8("StateTransitionIndication : OMX_StateIdle")); + + if (iExecuting) + { + iExecuting = EFalse; + iDemuxer->Stop(); + } + break; + } + + case EStateLoaded: + { + DEBUG_PRINTF(_L8("StateTransitionIndication : OMX_StateLoaded")); + + iDemuxer->ReleaseResources(); + iStreamsDetected = EFalse; + break; + } + + case EStatePause: + { + DEBUG_PRINTF(_L8("StateTransitionIndication : OMX_StatePause")); + + iDemuxer->Pause(); + break; + } + + default: + { + break; + } + } + + return omxError; + } + +OMX_ERRORTYPE COmxIL3GPDemuxerProcessingFunction::BufferFlushingIndication(TUint32 aPortIndex, + OMX_DIRTYPE aDirection) + { + DEBUG_PRINTF2(_L8("COmxIL3GPDemuxerProcessingFunction::BufferFlushingIndication : aPortIndex[%d]"), aPortIndex); + + return iRequestHelper->BufferFlushingIndication(aPortIndex, aDirection); + } + +OMX_ERRORTYPE COmxIL3GPDemuxerProcessingFunction::DoBufferFlushingIndication(TUint32 aPortIndex, + OMX_DIRTYPE /*aDirection*/) + { + DEBUG_PRINTF2(_L8("COmxIL3GPDemuxerProcessingFunction::DoBufferFlushingIndication : aPortIndex[%d]"), aPortIndex); + + iDemuxer->FlushBuffers(aPortIndex); + return OMX_ErrorNone; + } + +OMX_ERRORTYPE COmxIL3GPDemuxerProcessingFunction::ParamIndication(OMX_INDEXTYPE /*aParamIndex*/, + const TAny* /*apComponentParameterStructure*/) + { + return OMX_ErrorNone; + } + +OMX_ERRORTYPE COmxIL3GPDemuxerProcessingFunction::ConfigIndication(OMX_INDEXTYPE /*aConfigIndex*/, + const TAny* /*apComponentConfigStructure*/) + { + return OMX_ErrorNone; + } + +OMX_ERRORTYPE COmxIL3GPDemuxerProcessingFunction::BufferIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, + OMX_DIRTYPE /*aDirection*/) + { + DEBUG_PRINTF2(_L8("COmxIL3GPDemuxerProcessingFunction::BufferIndication >: [%X]"), apBufferHeader); + + // Check if the previous buffer processing invalidated the demuxer + if (iDemuxer->Invalid()) + { + return OMX_ErrorInvalidState; + } + + TUint32 portIndex; + portIndex = apBufferHeader->nOutputPortIndex; + + if (portIndex >= COmxIL3GPDemuxer::EPortIndexMax) + { + return OMX_ErrorBadPortIndex; + } + + TRAPD(err, iDemuxer->ProcessThisBufferL(apBufferHeader, portIndex)); + + DEBUG_PRINTF2(_L8("COmxIL3GPDemuxerProcessingFunction::BufferIndication :< size [%d]"), apBufferHeader->nFilledLen); + + if (err == KErrNone) + { + return OMX_ErrorNone; + } + else + { + return OMX_ErrorUndefined; + } + } + +OMX_BOOL COmxIL3GPDemuxerProcessingFunction::BufferRemovalIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, + OMX_DIRTYPE aDirection) + { + DEBUG_PRINTF2(_L8("COmxIL3GPDemuxerProcessingFunction::BufferRemovalIndication >: [%X]"), apBufferHeader); + + return iRequestHelper->BufferRemovalIndication(apBufferHeader, aDirection); + } + +OMX_BOOL COmxIL3GPDemuxerProcessingFunction::DoBufferRemovalIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, OMX_DIRTYPE aDirection) + { + DEBUG_PRINTF2(_L8("COmxIL3GPDemuxerProcessingFunction::DoBufferRemovalIndication : BUFFER [%X]"), apBufferHeader); + + if (iDemuxer->RemoveBuffer(apBufferHeader, aDirection)) + { + return OMX_TRUE; + } + + return OMX_FALSE; + } + +OMX_U32 COmxIL3GPDemuxerProcessingFunction::NumAvailableStreams(COmxIL3GPDemuxer::TPortIndex aPortType) + { + switch(aPortType) + { + case COmxIL3GPDemuxer::EPortIndexVideoOutput: + { + TSize frameSize; + TVideoFormat format; + TBool videoAvailable = iDemuxer->GetVideoFormat(frameSize, format); + return videoAvailable ? 1 : 0; + } + + case COmxIL3GPDemuxer::EPortIndexAudioOutput: + { + TAudioFormat format; + return iDemuxer->GetAudioFormat(format) ? 1 : 0; + } + + default: + User::Invariant(); + return 0; + } + } + +OMX_U32 COmxIL3GPDemuxerProcessingFunction::ActiveStream(COmxIL3GPDemuxer::TPortIndex /*aPortType*/) + { + //TODO + return 0; + } + +OMX_ERRORTYPE COmxIL3GPDemuxerProcessingFunction::SetActiveStream(COmxIL3GPDemuxer::TPortIndex aPortType, OMX_U32 aActiveStream) + { + switch(aPortType) + { + case COmxIL3GPDemuxer::EPortIndexVideoOutput: + { + TSize frameSize; + TVideoFormat format; + TBool videoAvailable = iDemuxer->GetVideoFormat(frameSize, format); + if(videoAvailable && aActiveStream == 0) + { + return OMX_ErrorNone; + } + else + { + return OMX_ErrorUnsupportedSetting; + } + } + case COmxIL3GPDemuxer::EPortIndexAudioOutput: + // TODO +//ZK return OMX_ErrorNotImplemented; + return OMX_ErrorNone; + + default: + return OMX_ErrorUnsupportedIndex; + } + } + +void COmxIL3GPDemuxerProcessingFunction::SetVideoPort(COmxIL3GPDemuxerVideoOutputPort& aVideoPort) + { + iVideoPort = &aVideoPort; + } + +void COmxIL3GPDemuxerProcessingFunction::SetAudioPort(COmxIL3GPDemuxerAudioOutputPort& aAudioPort) + { + iAudioPort = &aAudioPort; + } + +TInt COmxIL3GPDemuxerProcessingFunction::StreamDetectCallBack(TAny* aPtr) + { + reinterpret_cast(aPtr)->DoStreamDetect(); + return KErrNone; + } + +void COmxIL3GPDemuxerProcessingFunction::DoStreamDetect() + { + OMX_ERRORTYPE error = iDemuxer->DetectStreams(); + if(error) + { + iCallbacks.EventNotification(OMX_EventError, (TUint32)OMX_ErrorFormatNotDetected, 0, NULL); + return; + } + + // video format has been discovered + // check against port definition + // if autodetect, cause a PortSettingsChanged event + // if not autodetect and detected format is different, cause an error event + TSize size; + TVideoFormat format; + TBool videoAvailable = iDemuxer->GetVideoFormat(size, format); + // errors from EventNotification are ignored - these will be + // OMX_ErrorInsufficientResources if the callback could not be + // created or added to the queue. In this case, we probably want + // the callback manager to send an out-of-band error event to the + // IL client but this does not happen in 1509 yet + if(format.iCoding == OMX_VIDEO_CodingMax) + { + // format could not be mapped, and so is unsupported + iCallbacks.EventNotification(OMX_EventError, (TUint32) OMX_ErrorFormatNotDetected, 0, NULL); + // only send FormatNotDetected once for the component, not for both ports + return; + } + else + { + if (iVideoPort->IsEnabled()) + { + iStreamsDetected = ETrue; + if (iVideoPort->VideoFormat() == OMX_VIDEO_CodingAutoDetect) + { + if(videoAvailable) + { + iVideoPort->FormatDetected(size, format); + } + // TODO spec doesn't say what the params should be for PortFormatDetected + iCallbacks.EventNotification(OMX_EventPortFormatDetected, COmxIL3GPDemuxer::EPortIndexVideoOutput, 0, NULL); + iCallbacks.EventNotification(OMX_EventPortSettingsChanged, OMX_IndexParamPortDefinition, COmxIL3GPDemuxer::EPortIndexVideoOutput, NULL); + } + else + { + if (iVideoPort->VideoFormat() != format.iCoding) + { + iStreamsDetected = EFalse; + iCallbacks.EventNotification(OMX_EventError, (TUint32)OMX_ErrorFormatNotDetected, 0, NULL); + return; + } + } + } + } + + TAudioFormat audioFormat; + TBool audioAvailable = iDemuxer->GetAudioFormat(audioFormat); + + if(audioFormat.iCoding == OMX_AUDIO_CodingMax) + { + // format could not be mapped, and so is unsupported + iCallbacks.EventNotification(OMX_EventError, (TUint32)OMX_ErrorFormatNotDetected, 0, NULL); + return; + } + else + { + if (iAudioPort->IsEnabled()) + { + iStreamsDetected = ETrue; + if (iAudioPort->AudioFormat() == OMX_AUDIO_CodingAutoDetect) + { + if (audioAvailable) + { + iAudioPort->FormatDetected(audioFormat); + } + iCallbacks.EventNotification(OMX_EventPortFormatDetected, COmxIL3GPDemuxer::EPortIndexAudioOutput, 0, NULL); + iCallbacks.EventNotification(OMX_EventPortSettingsChanged, OMX_IndexParamPortDefinition, COmxIL3GPDemuxer::EPortIndexAudioOutput, NULL); + } + else + { + if (iAudioPort->AudioFormat() != audioFormat.iCoding) + { + iStreamsDetected = EFalse; + iCallbacks.EventNotification(OMX_EventError, (TUint32)OMX_ErrorFormatNotDetected, 0, NULL); + return; + } + } + } + } + //Only start the demuxer if one of its ports is enabled. + if (iStreamsDetected) + { + iDemuxer->Start(); + iExecuting = ETrue; + } + } + diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerprocessingfunction.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerprocessingfunction.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,81 @@ +/* +* Copyright (c) 2008 - 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef COMXIL3GPDEMUXERPROCESSINGFUNCTION_H +#define COMXIL3GPDEMUXERPROCESSINGFUNCTION_H + +#include +#include "comxil3gpdemuxer.h" +#include "comxil3gpdemuxerrequesthelper.h" + +class COmxIL3GPDemuxerConfigManager; +class COmxIL3GPDemuxerVideoOutputPort; +class COmxIL3GPDemuxerAudioOutputPort; +class C3GPDemuxer; + +NONSHARABLE_CLASS(COmxIL3GPDemuxerProcessingFunction) : public COmxILProcessingFunction + { +public: + static COmxIL3GPDemuxerProcessingFunction* NewL(MOmxILCallbackNotificationIf& aCallbacks); + ~COmxIL3GPDemuxerProcessingFunction(); + + void SetConfigManager(COmxIL3GPDemuxerConfigManager& aConfigManager); + void SetVideoPort(COmxIL3GPDemuxerVideoOutputPort& aVideoPort); + void SetAudioPort(COmxIL3GPDemuxerAudioOutputPort& aAudioPort); + OMX_ERRORTYPE StateTransitionIndication(TStateIndex aNewState); + OMX_ERRORTYPE BufferFlushingIndication(TUint32 aPortIndex, OMX_DIRTYPE aDirection); + OMX_ERRORTYPE ParamIndication(OMX_INDEXTYPE aParamIndex, const TAny* apComponentParameterStructure); + OMX_ERRORTYPE ConfigIndication(OMX_INDEXTYPE aConfigIndex, const TAny* apComponentConfigStructure); + OMX_ERRORTYPE BufferIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, OMX_DIRTYPE aDirection); + OMX_BOOL BufferRemovalIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, OMX_DIRTYPE aDirection); + + OMX_U32 NumAvailableStreams(COmxIL3GPDemuxer::TPortIndex aPortType); + OMX_U32 ActiveStream(COmxIL3GPDemuxer::TPortIndex aPortType); + OMX_ERRORTYPE SetActiveStream(COmxIL3GPDemuxer::TPortIndex aPortType, OMX_U32 aActiveStream); + +private: + COmxIL3GPDemuxerProcessingFunction(MOmxILCallbackNotificationIf& aCallbacks); + void ConstructL(); + + OMX_ERRORTYPE DoStateTransitionIndication(TStateIndex aNewState); + OMX_ERRORTYPE DoBufferFlushingIndication(TUint32 aPortIndex, OMX_DIRTYPE aDirection); + OMX_BOOL DoBufferRemovalIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, OMX_DIRTYPE aDirection); + + static TInt StreamDetectCallBack(TAny* aPtr); + void DoStreamDetect(); + +private: + C3GPDemuxer* iDemuxer; + COmxIL3GPDemuxerConfigManager* iConfigManager; // not owned + COmxIL3GPDemuxerVideoOutputPort* iVideoPort; // not owned + COmxIL3GPDemuxerAudioOutputPort* iAudioPort; // not owned + CAsyncCallBack* iStreamDetectCallback; + + TBool iStreamsDetected; + TBool iExecuting; + + COmxIL3GPDemuxerRequestHelper* iRequestHelper; + friend class COmxIL3GPDemuxerRequestHelper; + }; + +#endif //COMXIL3GPDEMUXERPROCESSINGFUNCTION_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerrequesthelper.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerrequesthelper.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,233 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include "log.h" +#include "comxil3gpdemuxerrequesthelper.h" +#include "comxil3gpdemuxerprocessingfunction.h" +#include "comxil3gpdemuxer.h" + +COmxIL3GPDemuxerRequestHelper* COmxIL3GPDemuxerRequestHelper::NewL(COmxILProcessingFunction* aProcessingFunction) + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerRequestHelper::NewL")); + + COmxIL3GPDemuxerRequestHelper* self = new (ELeave) COmxIL3GPDemuxerRequestHelper(aProcessingFunction); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +COmxIL3GPDemuxerRequestHelper::COmxIL3GPDemuxerRequestHelper(COmxILProcessingFunction* aProcessingFunction): + CActive(EPriorityStandard), + iProcessingFunction(aProcessingFunction), + iFunctionCode(EC3GPDemuxerFunctionCodeNone) + { + CActiveScheduler::Add(this); + } + +void COmxIL3GPDemuxerRequestHelper::ConstructL() + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerRequestHelper::ConstructL")); + + RThread me; + iConstructionThreadId = me.Id(); + + iStatus = KRequestPending; + SetActive(); + } + +COmxIL3GPDemuxerRequestHelper::~COmxIL3GPDemuxerRequestHelper() + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerRequestHelper::~COmxIL3GPDemuxerRequestHelper")); + + Cancel(); // safe as takes place in core thread which has Active Scheduler running. + } + +void COmxIL3GPDemuxerRequestHelper::RunL() + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerRequestHelper::RunL")); + + __ASSERT_DEBUG(iStatus == KErrNone, User::Panic(_L("Demuxer COmxIL3GPDemuxerRequestHelper::RunL"), KErrUnknown)); + + iStatus = KRequestPending; + SetActive(); + + // list of requests that need to be synchronised with AS + switch(iFunctionCode) + { + case EC3GPDemuxerFunctionCodeStateTransitionIndication: + DoStateTransitionIndication(); + break; + + case EC3GPDemuxerFunctionCodeBufferFlushingIndication: + DoBufferFlushingIndication(); + break; + + case EC3GPDemuxerFunctionCodeBufferRemovalIndication: + DoBufferRemovalIndication(); + break; + + default: + // should never reach here + User::Panic(_L("COmxIL3GPDemuxerRequestHelper"), KErrArgument); + } + + TRequestStatus *status = iCallingStatus; + RThread callingThread; + callingThread.Open(iCallingThreadId); + callingThread.RequestComplete(status, KErrNone); + callingThread.Close(); + } + +void COmxIL3GPDemuxerRequestHelper::DoCancel() + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerRequestHelper::DoCancel")); + + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrCancel); + } + +OMX_ERRORTYPE COmxIL3GPDemuxerRequestHelper::StateTransitionIndication(TStateIndex aNewState) + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerRequestHelper::StateTransitionIndication")); + + iNewState = aNewState; + + RThread me; + if(me.Id() != iConstructionThreadId) + { + // in different thread to that which 'this' was constructed + iFunctionCode = EC3GPDemuxerFunctionCodeStateTransitionIndication; + DoRequest(); + } + else + { + // in same thread to that which 'this' was constructed therefore + // active scheduler must exist and following call is safe + DoStateTransitionIndication(); + } + + return iOMXError; + } + +OMX_ERRORTYPE COmxIL3GPDemuxerRequestHelper::BufferFlushingIndication(TUint32 aPortIndex, OMX_DIRTYPE aDirection) + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerRequestHelper::BufferFlushingIndication")); + + iPortIndex = aPortIndex; + iDirection = aDirection; + + RThread me; + if(me.Id() != iConstructionThreadId) + { + // in different thread to that which 'this' was constructed + iFunctionCode = EC3GPDemuxerFunctionCodeBufferFlushingIndication; + DoRequest(); + } + else + { + // in same thread to that which 'this' was constructed therefore + // active scheduler must exist and following call is safe + DoBufferFlushingIndication(); + } + + return iOMXError; + } + +OMX_BOOL COmxIL3GPDemuxerRequestHelper::BufferRemovalIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, OMX_DIRTYPE aDirection) + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerRequestHelper::BufferRemovalIndication")); + + ipBufferHeader = apBufferHeader; + iDirection = aDirection; + + RThread me; + if(me.Id() != iConstructionThreadId) + { + // in different thread to that which 'this' was constructed + iFunctionCode = EC3GPDemuxerFunctionCodeBufferRemovalIndication; + DoRequest(); + } + else + { + // in same thread to that which 'this' was constructed therefore + // active scheduler must exist and following call is safe + DoBufferRemovalIndication(); + } + + return iOMXBool; + } + +void COmxIL3GPDemuxerRequestHelper::DoRequest() + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerRequestHelper::DoRequest")); + + RThread me; + iCallingThreadId = me.Id(); + TRequestStatus requestStatus = KRequestPending; + iCallingStatus = &requestStatus; + + // send request to active scheduler thread + RThread schedulerThread; + schedulerThread.Open(iConstructionThreadId); + + TRequestStatus* schedulerRequest = &iStatus; + schedulerThread.RequestComplete(schedulerRequest, KErrNone); + schedulerThread.Close(); + + // block until request completes + User::WaitForRequest(requestStatus); + + iFunctionCode = EC3GPDemuxerFunctionCodeNone; + } + +void COmxIL3GPDemuxerRequestHelper::DoStateTransitionIndication() + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerRequestHelper::DoStateTransitionIndication")); + + COmxIL3GPDemuxerProcessingFunction* processingFunction = + dynamic_cast(iProcessingFunction); + + iOMXError = processingFunction->DoStateTransitionIndication(iNewState); + } + +void COmxIL3GPDemuxerRequestHelper::DoBufferFlushingIndication() + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerRequestHelper::DoBufferFlushingIndication")); + + COmxIL3GPDemuxerProcessingFunction* processingFunction = + dynamic_cast(iProcessingFunction); + + iOMXError = processingFunction->DoBufferFlushingIndication(iPortIndex, iDirection); + } + +void COmxIL3GPDemuxerRequestHelper::DoBufferRemovalIndication() + { + DEBUG_PRINTF(_L8("COmxIL3GPDemuxerRequestHelper::DoBufferRemovalIndication")); + + COmxIL3GPDemuxerProcessingFunction* processingFunction = + dynamic_cast(iProcessingFunction); + + iOMXBool = processingFunction->DoBufferRemovalIndication(ipBufferHeader, iDirection); + } + diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerrequesthelper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerrequesthelper.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,78 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include +#include + +#ifndef COMXIL3GPDEMUXERREQUESTHELPER_H +#define COMXIL3GPDEMUXERREQUESTHELPER_H + +NONSHARABLE_CLASS(COmxIL3GPDemuxerRequestHelper) : public CActive + { +public: + static COmxIL3GPDemuxerRequestHelper * NewL(COmxILProcessingFunction* aProcessingFunction); + ~COmxIL3GPDemuxerRequestHelper(); + void RunL(); + void DoCancel(); + + OMX_ERRORTYPE StateTransitionIndication(TStateIndex aNewState); + OMX_ERRORTYPE BufferFlushingIndication(TUint32 aPortIndex, OMX_DIRTYPE aDirection); + OMX_BOOL BufferRemovalIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, OMX_DIRTYPE aDirection); + +private: + COmxIL3GPDemuxerRequestHelper(COmxILProcessingFunction* aProcessingFunction); + void ConstructL(); + + void DoRequest(); + void DoStateTransitionIndication(); + void DoBufferFlushingIndication(); + void DoBufferRemovalIndication(); + +private: + enum TEC3GPDemuxerFunctionCode + { + EC3GPDemuxerFunctionCodeNone, + EC3GPDemuxerFunctionCodeStateTransitionIndication, + EC3GPDemuxerFunctionCodeBufferFlushingIndication, + EC3GPDemuxerFunctionCodeBufferRemovalIndication + + // ... more to be added when required + }; + +private: + COmxILProcessingFunction* iProcessingFunction; // not owned + TEC3GPDemuxerFunctionCode iFunctionCode; + + TStateIndex iNewState; + OMX_ERRORTYPE iOMXError; + TUint32 iPortIndex; + OMX_DIRTYPE iDirection; + OMX_BUFFERHEADERTYPE* ipBufferHeader; // not owned + OMX_BOOL iOMXBool; + + TThreadId iConstructionThreadId; + TRequestStatus* iCallingStatus; // not owned + TThreadId iCallingThreadId; + }; + +#endif //COMXIL3GPDEMUXERREQUESTHELPER_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxertimeinputport.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxertimeinputport.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include "comxil3gpdemuxertimeinputport.h" +#include "comxil3gpdemuxerprocessingfunction.h" + +COmxIL3GPDemuxerTimeInputPort* COmxIL3GPDemuxerTimeInputPort::NewL(const TOmxILCommonPortData& aCommonPortData, + const RArray& aSupportedOtherFormats, + COmxIL3GPDemuxerProcessingFunction& aProcessingFunction) + { + COmxIL3GPDemuxerTimeInputPort* tip = new(ELeave) COmxIL3GPDemuxerTimeInputPort(aProcessingFunction); + CleanupStack::PushL(tip); + tip->ConstructL(aCommonPortData, aSupportedOtherFormats); + CleanupStack::Pop(tip); + return tip; + } + +COmxIL3GPDemuxerTimeInputPort::COmxIL3GPDemuxerTimeInputPort(COmxIL3GPDemuxerProcessingFunction& aProcessingFunction) : + iProcessingFunction(&aProcessingFunction) + { + } + +COmxIL3GPDemuxerTimeInputPort::~COmxIL3GPDemuxerTimeInputPort() + { + } + +OMX_ERRORTYPE COmxIL3GPDemuxerTimeInputPort::GetLocalOmxParamIndexes(RArray& aIndexArray) const + { + return COmxILOtherPort::GetLocalOmxParamIndexes(aIndexArray); + } + +OMX_ERRORTYPE COmxIL3GPDemuxerTimeInputPort::GetLocalOmxConfigIndexes(RArray& aIndexArray) const + { + return COmxILOtherPort::GetLocalOmxConfigIndexes(aIndexArray); + } + +OMX_ERRORTYPE COmxIL3GPDemuxerTimeInputPort::GetParameter(OMX_INDEXTYPE aParamIndex, + TAny* apComponentParameterStructure) const + { + return COmxILOtherPort::GetParameter(aParamIndex, apComponentParameterStructure); + } + +OMX_ERRORTYPE COmxIL3GPDemuxerTimeInputPort::SetParameter(OMX_INDEXTYPE aParamIndex, + const TAny* apComponentParameterStructure, + TBool& aUpdateProcessingFunction) + { + return COmxILOtherPort::SetParameter(aParamIndex, apComponentParameterStructure, aUpdateProcessingFunction); + } + +OMX_ERRORTYPE COmxIL3GPDemuxerTimeInputPort::SetFormatInPortDefinition(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition, + TBool& /*aUpdateProcessingFunction*/) + { + if (aPortDefinition.nBufferCountActual > KMaxTimeBuffers) + { + return OMX_ErrorBadParameter; + } + + // Just ignore this. It has to be a time format. + return OMX_ErrorNone; + } + +TBool COmxIL3GPDemuxerTimeInputPort::IsTunnelledPortCompatible(const OMX_PARAM_PORTDEFINITIONTYPE& /*aPortDefinition*/) const + { + return ETrue; + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxertimeinputport.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxertimeinputport.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef COMXIL3GPDEMUXERTIMEINPUTPORT_H +#define COMXIL3GPDEMUXERTIMEINPUTPORT_H + +#include + +class COmxIL3GPDemuxerProcessingFunction; + +const TInt KMaxTimeBuffers = 4; + +NONSHARABLE_CLASS(COmxIL3GPDemuxerTimeInputPort) : public COmxILOtherPort + { +public: + static COmxIL3GPDemuxerTimeInputPort* NewL(const TOmxILCommonPortData& aCommonPortData, + const RArray& aSupportedOtherFormats, + COmxIL3GPDemuxerProcessingFunction& aProcessingFunction); + ~COmxIL3GPDemuxerTimeInputPort(); + + // from COmxILOtherPort + OMX_ERRORTYPE GetLocalOmxParamIndexes(RArray& aIndexArray) const; + OMX_ERRORTYPE GetLocalOmxConfigIndexes(RArray& aIndexArray) const; + OMX_ERRORTYPE GetParameter(OMX_INDEXTYPE aParamIndex, + TAny* apComponentParameterStructure) const; + OMX_ERRORTYPE SetParameter(OMX_INDEXTYPE aParamIndex, + const TAny* apComponentParameterStructure, + TBool& aUpdateProcessingFunction); + +protected: + // from COmxILOtherPort + OMX_ERRORTYPE SetFormatInPortDefinition(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition, + TBool& aUpdateProcessingFunction); + TBool IsTunnelledPortCompatible(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition) const; + +private: + COmxIL3GPDemuxerTimeInputPort(COmxIL3GPDemuxerProcessingFunction& aProcessingFunction); + +private: + COmxIL3GPDemuxerProcessingFunction* iProcessingFunction; // not owned + }; + +#endif //COMXIL3GPDEMUXERTIMEINPUTPORT_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxervideooutputport.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxervideooutputport.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,214 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include "comxil3gpdemuxervideooutputport.h" +#include "comxil3gpdemuxerprocessingfunction.h" +#include "tvideoformat.h" + + +_LIT(K3GPDemuxerVideoPortPanic, "COmxIL3GPDemuxerVideoOutputPort"); + +COmxIL3GPDemuxerVideoOutputPort* COmxIL3GPDemuxerVideoOutputPort::NewL(const TOmxILCommonPortData& aCommonPortData, COmxIL3GPDemuxerProcessingFunction& aProcessingFunction) + + { + // TODO these arrays must left empty, to be removed from the video port constructor + RArray supportedCodings; + RArray supportedColorFormats; + CleanupClosePushL(supportedCodings); + CleanupClosePushL(supportedColorFormats); + + COmxIL3GPDemuxerVideoOutputPort* self = new(ELeave) COmxIL3GPDemuxerVideoOutputPort(aProcessingFunction); + CleanupStack::PushL(self); + self->ConstructL(aCommonPortData, supportedCodings, supportedColorFormats); + CleanupStack::Pop(self); + + CleanupStack::PopAndDestroy(2, &supportedCodings); + + return self; + } + +COmxIL3GPDemuxerVideoOutputPort::COmxIL3GPDemuxerVideoOutputPort(COmxIL3GPDemuxerProcessingFunction& aProcessingFunction) : + iProcessingFunction(&aProcessingFunction) + { + } + +void COmxIL3GPDemuxerVideoOutputPort::ConstructL(const TOmxILCommonPortData& aCommonPortData, + const RArray& aSupportedCodings, + const RArray& aSupportedColorFormats) + { + COmxILVideoPort::ConstructL(aCommonPortData, aSupportedCodings, aSupportedColorFormats); + GetParamPortDefinition().format.video.eCompressionFormat = OMX_VIDEO_CodingAutoDetect; + // as there are only four items, do not require a sort order + // if this list gets larger consider using binary search + GetSupportedVideoFormats().AppendL(OMX_VIDEO_CodingAutoDetect); + GetSupportedVideoFormats().AppendL(OMX_VIDEO_CodingAVC); + GetSupportedVideoFormats().AppendL(OMX_VIDEO_CodingH263); + GetSupportedVideoFormats().AppendL(OMX_VIDEO_CodingMPEG4); + + GetSupportedColorFormats().AppendL(OMX_COLOR_FormatUnused); + } + +COmxIL3GPDemuxerVideoOutputPort::~COmxIL3GPDemuxerVideoOutputPort() + { + } + +OMX_ERRORTYPE COmxIL3GPDemuxerVideoOutputPort::GetLocalOmxParamIndexes(RArray& aIndexArray) const + { + OMX_ERRORTYPE omxRetValue = COmxILVideoPort::GetLocalOmxParamIndexes(aIndexArray); + if (omxRetValue != OMX_ErrorNone) + { + return omxRetValue; + } + + TInt err = aIndexArray.InsertInOrder(OMX_IndexParamNumAvailableStreams); + // Note that index duplication is OK. + if (err == KErrNone || err == KErrAlreadyExists) + { + err = aIndexArray.InsertInOrder(OMX_IndexParamActiveStream); + } + + if (err != KErrNone && err != KErrAlreadyExists) + { + return OMX_ErrorInsufficientResources; + } + + return OMX_ErrorNone; + } + +OMX_ERRORTYPE COmxIL3GPDemuxerVideoOutputPort::GetLocalOmxConfigIndexes(RArray& aIndexArray) const + { + return COmxILVideoPort::GetLocalOmxConfigIndexes(aIndexArray); + } + +OMX_ERRORTYPE COmxIL3GPDemuxerVideoOutputPort::GetParameter(OMX_INDEXTYPE aParamIndex, + TAny* apComponentParameterStructure) const + { + switch(aParamIndex) + { + case OMX_IndexParamNumAvailableStreams: + { + OMX_PARAM_U32TYPE* u32Type = reinterpret_cast(apComponentParameterStructure); + u32Type->nU32 = iProcessingFunction->NumAvailableStreams(COmxIL3GPDemuxer::EPortIndexVideoOutput); + return OMX_ErrorNone; + } + + case OMX_IndexParamActiveStream: + { + OMX_PARAM_U32TYPE* u32Type = reinterpret_cast(apComponentParameterStructure); + u32Type->nU32 = iProcessingFunction->ActiveStream(COmxIL3GPDemuxer::EPortIndexVideoOutput); + return OMX_ErrorNone; + } + + default: + { + return COmxILVideoPort::GetParameter(aParamIndex, apComponentParameterStructure); + } + } + } + +OMX_ERRORTYPE COmxIL3GPDemuxerVideoOutputPort::SetParameter(OMX_INDEXTYPE aParamIndex, + const TAny* apComponentParameterStructure, + TBool& aUpdateProcessingFunction) + { + switch(aParamIndex) + { + case OMX_IndexParamActiveStream: + { + const OMX_PARAM_U32TYPE* u32Type = reinterpret_cast(apComponentParameterStructure); + return iProcessingFunction->SetActiveStream(COmxIL3GPDemuxer::EPortIndexVideoOutput, u32Type->nU32); + } + + default: + { + return COmxILVideoPort::SetParameter(aParamIndex, apComponentParameterStructure, aUpdateProcessingFunction); + } + } + } + +OMX_ERRORTYPE COmxIL3GPDemuxerVideoOutputPort::SetFormatInPortDefinition(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition, + TBool& aUpdateProcessingFunction) + { + const OMX_VIDEO_PORTDEFINITIONTYPE& newVidDef = aPortDefinition.format.video; + OMX_VIDEO_PORTDEFINITIONTYPE& myVidDef = GetParamPortDefinition().format.video; + + if (aPortDefinition.nBufferCountActual > KMaxVideoBuffers) + { + return OMX_ErrorBadParameter; + } + + if(newVidDef.eColorFormat != OMX_COLOR_FormatUnused) + { + return OMX_ErrorBadParameter; + } + + // change to FindInUnsignedKeyOrder if many more formats are added + // TODO this should allow OMX_VIDEO_CodingAutoDetect + if(GetSupportedVideoFormats().Find(newVidDef.eCompressionFormat) == KErrNotFound) + { + return OMX_ErrorBadParameter; + } + + // copy the new port definition + myVidDef = newVidDef; + // ignore parameters which make no sense, either because the output is compressed or because + // we are not a display component + myVidDef.nSliceHeight = 0; + myVidDef.nStride = 0; + myVidDef.pNativeRender = NULL; + myVidDef.pNativeWindow = NULL; + + // ignore the MIME type - the field eCompressionFormat will identify the stream type. + // if we want to support GetParameter() for the MIME type, I think the component needs to + // make a copy of the C string passed in and return a pointer to that. (cMIMEType is a char*). + myVidDef.cMIMEType = NULL; + + aUpdateProcessingFunction = ETrue; + + return OMX_ErrorNone; + } + +TBool COmxIL3GPDemuxerVideoOutputPort::IsTunnelledPortCompatible(const OMX_PARAM_PORTDEFINITIONTYPE& /*aPortDefinition*/) const + { + // This function only gets called on input ports, so panic if this is ever called + User::Panic(K3GPDemuxerVideoPortPanic, KErrGeneral); + return EFalse; // to keep compiler happy + } + +void COmxIL3GPDemuxerVideoOutputPort::FormatDetected(const TSize& aFrameSize, const TVideoFormat& aFormat) + { + GetParamPortDefinition().format.video.nFrameWidth = aFrameSize.iWidth; + GetParamPortDefinition().format.video.nFrameHeight = aFrameSize.iHeight; + GetParamPortDefinition().format.video.eCompressionFormat = aFormat.iCoding; + // TODO deal with H263/AVC profile + } + +OMX_VIDEO_CODINGTYPE COmxIL3GPDemuxerVideoOutputPort::VideoFormat() + { + return GetParamPortDefinition().format.video.eCompressionFormat; + } + +/** Returns the number of buffers configured on this port. */ +TInt COmxIL3GPDemuxerVideoOutputPort::BufferCount() const + { + return GetParamPortDefinition().nBufferCountActual; + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxervideooutputport.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxervideooutputport.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,69 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef COMXIL3GPDEMUXERVIDEOOUTPUTPORT_H +#define COMXIL3GPDEMUXERVIDEOOUTPUTPORT_H + +#include + +class COmxIL3GPDemuxerProcessingFunction; +class TVideoFormat; + +const TInt KMaxVideoBuffers = 10; + +NONSHARABLE_CLASS(COmxIL3GPDemuxerVideoOutputPort) : public COmxILVideoPort + { +public: + static COmxIL3GPDemuxerVideoOutputPort* NewL(const TOmxILCommonPortData& aCommonPortData, + COmxIL3GPDemuxerProcessingFunction& aProcessingFunction); + ~COmxIL3GPDemuxerVideoOutputPort(); + + void FormatDetected(const TSize& aFrameSize, const TVideoFormat& aFormat); + OMX_VIDEO_CODINGTYPE VideoFormat(); + TInt BufferCount() const; + + // from COmxILVideoPort + OMX_ERRORTYPE GetLocalOmxParamIndexes(RArray& aIndexArray) const; + OMX_ERRORTYPE GetLocalOmxConfigIndexes(RArray& aIndexArray) const; + OMX_ERRORTYPE GetParameter(OMX_INDEXTYPE aParamIndex, + TAny* apComponentParameterStructure) const; + OMX_ERRORTYPE SetParameter(OMX_INDEXTYPE aParamIndex, + const TAny* apComponentParameterStructure, + TBool& aUpdateProcessingFunction); + +protected: + OMX_ERRORTYPE SetFormatInPortDefinition(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition, + TBool& aUpdateProcessingFunction); + TBool IsTunnelledPortCompatible(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition) const; + +private: + COmxIL3GPDemuxerVideoOutputPort(COmxIL3GPDemuxerProcessingFunction& aProcessingFunction); + void ConstructL(const TOmxILCommonPortData& aCommonPortData, + const RArray& aSupportedCodings, + const RArray& aSupportedColourFormats); + +private: + COmxIL3GPDemuxerProcessingFunction* iProcessingFunction; // not owned + }; + +#endif //COMXIL3GPDEMUXERVIDEOOUTPUTPORT_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/log.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/log.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,149 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifndef __3GPDEMUXER_LOG_H__ +#define __3GPDEMUXER_LOG_H__ + +#include + +namespace DSD +{ + +#ifdef _DEBUG + +#ifdef _OMXIL_AACDECODER_DEBUG_TRACING_ON + +#define DEBUG_PRINTF(a) {DSD::DebugPrintf(__LINE__, __FILE__, a);} +#define DEBUG_PRINTF2(a, b) {DSD::DebugPrintf(__LINE__, __FILE__, a, b);} +#define DEBUG_PRINTF3(a, b, c) {DSD::DebugPrintf(__LINE__, __FILE__, a, b, c);} +#define DEBUG_PRINTF4(a, b, c, d) {DSD::DebugPrintf(__LINE__, __FILE__, a, b, c, d);} +#define DEBUG_PRINTF5(a, b, c, d, e) {DSD::DebugPrintf(__LINE__, __FILE__, a, b, c, d, e);} + +#define DEBUG_CODE_SECTION(a) TRAP_IGNORE({ a; }) + +class TTruncateOverflowHandler16 : public TDes16Overflow + { + public: + virtual void Overflow( TDes16& aDes ); + }; + +inline void TTruncateOverflowHandler16::Overflow( TDes16& aDes) + { + _LIT(KErrOverflowMsg,"Descriptor Overflow, hence value truncated"); + if( aDes.MaxLength() >= KErrOverflowMsg().Length() + aDes.Length() ) + aDes.Append(KErrOverflowMsg); + } + +class TTruncateOverflowHandler8 : public TDes8Overflow + { + public: + virtual void Overflow( TDes8& aDes ); + }; + +inline void TTruncateOverflowHandler8::Overflow( TDes8& aDes) + { + _LIT(KErrOverflowMsg,"Descriptor Overflow, hence value truncated"); + if( aDes.MaxLength() >= KErrOverflowMsg().Length() + aDes.Length() ) + aDes.Append(KErrOverflowMsg); + } + +// UTF-8 overload of the DebufPrintf method. Should be used by default, +// since it's cheaper both in CPU cycles and stack space. + +inline void DebugPrintf(TInt aLine, char* aFile, TRefByValue aFormat, ...) + { + TTruncateOverflowHandler8 overflowHandler8; + VA_LIST list; + VA_START(list, aFormat); + + TTime now; + now.HomeTime(); + + TBuf8<1024> buffer; + _LIT8(KSwiLogPrefix, "[aacdeco] "); + _LIT8(KSwiLineFileFormat, "TID[%d] : [%s:%d] -- "); + buffer.Append(KSwiLogPrefix); + RThread thread; + TUint threadId = thread.Id(); + thread.Close(); + RProcess proc; + TFileName fName = proc.FileName(); + proc.Close(); + buffer.AppendFormat(KSwiLineFileFormat, threadId, aFile, aLine); + buffer.AppendFormatList(aFormat, list ,&overflowHandler8 ); + buffer.Append(_L8("\r\n")); + + RDebug::RawPrint(buffer); + + VA_END(list); + } + +// Unicode DebufPrintf overload + +inline void DebugPrintf(TInt aLine, char* aFile, TRefByValue aFormat, ...) + { + TTruncateOverflowHandler16 overflowHandler16; + VA_LIST list; + VA_START(list, aFormat); + + TTime now; + now.HomeTime(); + + TBuf8<256> header; + _LIT8(KSwiLogPrefix, "[aacdecoder] "); + _LIT8(KSwiLineFileFormat, "%Ld Line: % 5d, File: %s -- "); + header.Append(KSwiLogPrefix); + header.AppendFormat(KSwiLineFileFormat, now.Int64(), aLine, aFile); + + TBuf<1024> buffer; + buffer.Copy(header); + buffer.AppendFormatList(aFormat, list ,&overflowHandler16); + buffer.Append(_L("\r\n")); + + RDebug::RawPrint(buffer); + + VA_END(list); + } +#else + +#define DEBUG_PRINTF(a) +#define DEBUG_PRINTF2(a, b) +#define DEBUG_PRINTF3(a, b, c) +#define DEBUG_PRINTF4(a, b, c, d) +#define DEBUG_PRINTF5(a, b, c, d, e) + +#define DEBUG_CODE_SECTION(a) + +#endif + +#else + +#define DEBUG_PRINTF(a) +#define DEBUG_PRINTF2(a, b) +#define DEBUG_PRINTF3(a, b, c) +#define DEBUG_PRINTF4(a, b, c, d) +#define DEBUG_PRINTF5(a, b, c, d, e) + +#define DEBUG_CODE_SECTION(a) + +#endif + + +} // namespace DSD + +#endif // __3GPDEMUXER_LOG_H__ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/omxil3gpdemuxer.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/omxil3gpdemuxer.hrh Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifndef OMXIL3GPDEMUXER_HRH_ +#define OMXIL3GPDEMUXER_HRH_ + +#define KUidSymbianOmxIL3gpDemuxerDll 0x10285C31 +#define KUidSymbianOmxIL3gpDemuxer 0x10285C32 + +#endif /*OMXIL3GPDEMUXER_HRH_*/ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/omxil3gpdemuxer.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/omxil3gpdemuxer.rss Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include +#include "omxil3gpdemuxer.hrh" + +RESOURCE REGISTRY_INFO theInfo + { + dll_uid = KUidSymbianOmxIL3gpDemuxerDll; + interfaces = + { + INTERFACE_INFO + { + interface_uid = KUidOmxILSymbianComponentIf; + implementations = + { + IMPLEMENTATION_INFO + { + implementation_uid = KUidSymbianOmxIL3gpDemuxer; + version_no = 1; + display_name = "OMX.SYMBIAN.OTHER.CONTAINER_DEMUXER.3GP"; + default_data = "container_demuxer"; + } + }; + } + }; + } + diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/omxil3gpdemuxerpanic.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/omxil3gpdemuxerpanic.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** + @file + @internalComponent + */ + +#include "omxil3gpdemuxerpanic.h" +#include + +_LIT(KPanicString, "omxil3gpdemuxer"); + +void Panic(TPanicCode aCode) + { + User::Panic(KPanicString, aCode); + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/omxil3gpdemuxerpanic.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/omxil3gpdemuxerpanic.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef OMXIL3GPDEMUXERPANIC_H +#define OMXIL3GPDEMUXERPANIC_H + +enum TPanicCode + { + EProcessThisBufferLNoBufferQueue = 0, + ERemoveBufferInvalidDirection = 1, + ERemoveBufferInvalidPort = 2, + EReceiveQueuedBuffersAppendFailed = 3, + ECreateBufferQueueLZeroBufferCount = 4, + ECheckBufferQueueSizeLZeroBufferCount = 5 + }; + +void Panic(TPanicCode aCode); + +#endif //OMXIL3GPDEMUXERPANIC_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/taudioformat.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/taudioformat.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef TAUDIOFORMAT_H_ +#define TAUDIOFORMAT_H_ + +#include + +class TAudioFormat + { + +public: + + OMX_AUDIO_CODINGTYPE iCoding; + OMX_U32 iFramesPerSample; + OMX_U32 iSampleRate; + OMX_U32 iAverageBitrate; + + }; + +#endif /*TAUDIOFORMAT_H_*/ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpdemuxer/src/tvideoformat.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpdemuxer/src/tvideoformat.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef TVIDEOFORMAT_H_ +#define TVIDEOFORMAT_H_ + +#include + +class TVideoFormat + { +public: + OMX_VIDEO_CODINGTYPE iCoding; + union + { + OMX_VIDEO_H263PROFILETYPE h263; + OMX_VIDEO_AVCPROFILETYPE avc; + OMX_VIDEO_MPEG4PROFILETYPE mpeg4; + } iProfile; + + union + { + OMX_VIDEO_H263LEVELTYPE h263; + OMX_VIDEO_AVCLEVELTYPE avc; + OMX_VIDEO_MPEG4LEVELTYPE mpeg4; + } iLevel; + }; + +#endif /*TVIDEOFORMAT_H_*/ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/group/bld.inf Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +PRJ_PLATFORMS +BASEDEFAULT + +PRJ_EXPORTS +// The export of the IBY is deliberately not guarded by #ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED so that it +// can always be #included by other IBYs/OBYs. However, if NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED is not defined +// then the IBY will effectively be empty and not include anything in the ROM. + +omxil3gpmuxer.iby /epoc32/rom/include/omxil3gpmuxer.iby + +PRJ_MMPFILES +#ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED +omxil3gpmuxer.mmp +#endif // NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/group/omxil3gpmuxer.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/group/omxil3gpmuxer.iby Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifndef OMXIL3GPMUXER_IBY +#define OMXIL3GPMUXER_IBY + +#ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED + +#include <3gplibrary.iby> +#include + +ECOM_PLUGIN(omxil3gpmuxer.dll, omxil3gpmuxer.rsc) + +#endif + +#endif // OMXIL3GPMUXER_IBY diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/group/omxil3gpmuxer.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/group/omxil3gpmuxer.mmp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include "../src/omxil3gpmuxer.hrh" + +TARGET omxil3gpmuxer.dll +TARGETTYPE PLUGIN +UID 0x10009D8D KUidSymbianOmxIL3gpMuxerDll +CAPABILITY All -TCB + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +USERINCLUDE ../src + +SOURCEPATH ../src + +SOURCE comxil3gpmuxer.cpp +SOURCE comxil3gpmuxerprocessingfunction.cpp +SOURCE comxil3gpmuxerconfigmanager.cpp +SOURCE comxil3gpmuxervideoinputport.cpp +SOURCE comxil3gpmuxeraudioinputport.cpp +SOURCE c3gpmuxer.cpp +SOURCE endwaitao.cpp +SOURCE c3gpmuxerwriterthreadobserver.cpp + + +START RESOURCE omxil3gpmuxer.rss +TARGET omxil3gpmuxer.rsc +END + +nostrictdef + +LIBRARY euser.lib +LIBRARY ecom.lib +LIBRARY efsrv.lib +LIBRARY inetprotutil.lib +LIBRARY omxilcomponentcommon.lib +STATICLIBRARY omxilcomponentif.lib +LIBRARY 3gplibrary.lib + +// Uncomment to activate debug tracing in this module +//MACRO _OMXIL_COMMON_DEBUG_TRACING_ON diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/src/c3gpmuxer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/src/c3gpmuxer.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,954 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include "comxil3gpmuxeraudioinputport.h" +#include "comxil3gpmuxervideoinputport.h" +#include "c3gpmuxer.h" +#include "log.h" +#include + +_LIT(K3GPMuxerPanic, "C3GPMuxer"); +const TUint KAudioTimeScale = 44100; +static const TUint KThreadStackSize = 8192; // 8KB +const TInt KMaxBufferSize = 62400 * 2; +const TInt KMicroSecondsPerSecond = 1000000; + + +C3GPMuxer* C3GPMuxer::NewL(MOmxILCallbackNotificationIf& aCallbacks) + { + DEBUG_PRINTF(_L8("C3GPMuxer::NewL")); + C3GPMuxer* self = new (ELeave) C3GPMuxer(aCallbacks); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +C3GPMuxer::C3GPMuxer(MOmxILCallbackNotificationIf& aCallbacks): + CActive(EPriorityStandard), + iCallbacks(aCallbacks) + { + } + +void C3GPMuxer::ConstructL() + { + User::LeaveIfError(iVideoQueue.CreateLocal(KMaxVideoBuffers)); + iPartialFrame.CreateL(KMaxBufferSize); + User::LeaveIfError(iAudioQueue.CreateLocal(KMaxAudioBuffers)); + User::LeaveIfError(iRemoveQueue.CreateLocal(Max(KMaxVideoBuffers, KMaxAudioBuffers))); + User::LeaveIfError(iQueMutex.CreateLocal()); + + iComposer = C3GPCompose::NewL(); + } + +void C3GPMuxer::StartL(TBool aAudioPortEnabled, TBool aVideoPortEnabled) + { + DEBUG_PRINTF(_L8("C3GPMuxer::StartL")); + + iPaused = EFalse; + + if (!iThreadRunning) + { + iAudioPortEnabled = aAudioPortEnabled; + iVideoPortEnabled = aVideoPortEnabled; + + TBuf<40> threadName; + threadName.Format(_L("C3GPMuxerThread@%08X"), this); + + User::LeaveIfError(iThread.Create(threadName, ThreadEntryPoint, KThreadStackSize, NULL, this)); + + // start the thread and wait for it to start the active scheduler + TRequestStatus status; + iThread.Rendezvous(status); + iThread.Resume(); + User::WaitForRequest(status); + User::LeaveIfError(status.Int()); + } + else + { + // self complete + iQueMutex.Wait(); + if (!iRequestOutstanding) + { + TRequestStatus* statusPtr = &iStatus; + iThread.RequestComplete(statusPtr, KErrNone); + } + iQueMutex.Signal(); + } + } + +TInt C3GPMuxer::ThreadEntryPoint(TAny* aPtr) + { + CTrapCleanup* cleanup = CTrapCleanup::New(); + if(!cleanup) + { + return KErrNoMemory; + } + + // Call this objects clock initialisation routine + TRAPD(err, static_cast(aPtr)->RunThreadL()); + delete cleanup; + return err; + } + +void C3GPMuxer::RunThreadL() + { + DEBUG_PRINTF(_L8("C3GPMuxer::RunThreadL")); + CActiveScheduler* sched = new (ELeave) CActiveScheduler; + CleanupStack::PushL(sched); + + CActiveScheduler::Install(sched); + CActiveScheduler::Add(this); + + if (iAudioPortEnabled) + { + iAudioQueue.NotifyDataAvailable(iStatus); + SetActive(); + iRequestOutstanding = ETrue; + } + else if (iVideoPortEnabled) + { + iVideoQueue.NotifyDataAvailable(iStatus); + SetActive(); + iRequestOutstanding = ETrue; + } + + iEndWaitAO = CEndWaitAO::NewL(); + + iThreadRunning = ETrue; + + iThread.Rendezvous(KErrNone); + + CActiveScheduler::Start(); + + HandleError(iComposer->Complete()); + iComposerOpened = EFalse; + + CleanupStack::PopAndDestroy(sched); + } + +C3GPMuxer::~C3GPMuxer() + { + DEBUG_PRINTF(_L8("C3GPMuxer::~C3GPMuxer")); + + if(iThreadRunning) + { + iThreadRunning = EFalse; + TRequestStatus logonStatus; + iThread.Logon(logonStatus); + + iEndWaitAO->Call(); + User::WaitForRequest(logonStatus); + + delete iEndWaitAO; + iEndWaitAO = NULL; + } + + iVideoQueue.Close(); + iPartialFrame.Close(); + iAudioQueue.Close(); + iRemoveQueue.Close(); + + delete iComposer; + + iThread.Close(); + iQueMutex.Close(); + } + +void C3GPMuxer::ProcessThisBufferL(OMX_BUFFERHEADERTYPE* aBufferHeader, TUint32 aPortIndex) + { + DEBUG_PRINTF3(_L8("C3GPMuxer::ProcessThisBufferL : aBufferHeader[%X]; aPortIndex[%u]"), aBufferHeader, aPortIndex); + __ASSERT_ALWAYS(aBufferHeader->nOffset + aBufferHeader->nFilledLen <= aBufferHeader->nAllocLen, User::Invariant()); + + if (aPortIndex == COmxIL3GPMuxer::EPortIndexAudioInput && iAudioPortEnabled) + { + User::LeaveIfError(iAudioQueue.Send(aBufferHeader)); + } + else if (aPortIndex == COmxIL3GPMuxer::EPortIndexVideoInput && iVideoPortEnabled) + { + User::LeaveIfError(iVideoQueue.Send(aBufferHeader)); + } + // FIXME buffer arrived on disabled port?? if we don't consider this an error why bother checking? + } + +void C3GPMuxer::FlushBuffers(TUint32 aPortIndex) + { + DEBUG_PRINTF2(_L8("C3GPMuxer::FlushBuffers : aPortIndex[%u]"), aPortIndex); + + __ASSERT_DEBUG(aPortIndex == OMX_ALL || aPortIndex < COmxIL3GPMuxer::EPortIndexMax, User::Invariant()); + + if (aPortIndex == OMX_ALL || aPortIndex < COmxIL3GPMuxer::EPortIndexMax) + { + iQueMutex.Wait(); + + if (aPortIndex == OMX_ALL) + { + for (TInt portIndex = 0; portIndex < COmxIL3GPMuxer::EPortIndexMax; ++portIndex) + { + DoFlushBuffers(portIndex); + } + } + else + { + DoFlushBuffers(aPortIndex); + } + + iQueMutex.Signal(); + } + } + +void C3GPMuxer::DoFlushBuffers(TUint32 aPortIndex) + { + DEBUG_PRINTF2(_L8("C3GPMuxer::DoFlushBuffers : aPortIndex[%u]"), aPortIndex); + + OMX_BUFFERHEADERTYPE* buffer = NULL; + switch(aPortIndex) + { + case COmxIL3GPMuxer::EPortIndexAudioInput: + { + if (iAudioBuffer) + { + ReturnBuffer(iAudioBuffer, aPortIndex); + } + + while(iAudioQueue.Receive(buffer) != KErrUnderflow) + { + ReturnBuffer(buffer, aPortIndex); + } + break; + } + case COmxIL3GPMuxer::EPortIndexVideoInput: + { + if (iCurrentVideoBuffer) + { + ReturnBuffer(iCurrentVideoBuffer, aPortIndex); + iCurrentVideoBuffer = NULL; + } + if (iNextVideoBuffer) + { + ReturnBuffer(iNextVideoBuffer, aPortIndex); + iNextVideoBuffer = NULL; + } + while(iVideoQueue.Receive(buffer) != KErrUnderflow) + { + ReturnBuffer(buffer, aPortIndex); + } + break; + } + default: + { + User::Panic(K3GPMuxerPanic, KErrArgument); + break; + } + } + } + +TBool C3GPMuxer::RemoveBuffer(OMX_BUFFERHEADERTYPE* aBufferHeader) + { + DEBUG_PRINTF2(_L8("C3GPMuxer::RemoveBuffer : aBufferHeader[%X]"), aBufferHeader); + iQueMutex.Wait(); + TBool found = EFalse; + + // check the current audio/video buffers first + if(aBufferHeader == iAudioBuffer) + { + iAudioBuffer = NULL; + found = ETrue; + } + + if(!found && aBufferHeader == iCurrentVideoBuffer) + { + iCurrentVideoBuffer = NULL; + found = ETrue; + } + if(!found && aBufferHeader == iNextVideoBuffer) + { + iNextVideoBuffer = NULL; + found = ETrue; + } + + if (!found) + { + found = RemoveFromQueue(iAudioQueue, aBufferHeader); + } + + if (!found) + { + found = RemoveFromQueue(iVideoQueue, aBufferHeader); + } + + iQueMutex.Signal(); + + return found; + } + +void C3GPMuxer::SetFilename(const HBufC* aFilename) + { + DEBUG_PRINTF(_L8("C3GPMuxer::SetFilename")); + iFilename = aFilename; + } + +void C3GPMuxer::SetAudioVideoProperties(OMX_U32& aFrameWidth, OMX_U32& aFrameHeight, + OMX_U32& aFramerate, OMX_U32& aBitRate, OMX_U32& /*aAudioFramerate*/) + { + DEBUG_PRINTF(_L8("C3GPMuxer::SetAudioVideoProperties")); + iVideoSize.iWidth = static_cast(aFrameWidth); + iVideoSize.iHeight = static_cast(aFrameHeight); + + iBitRate = aBitRate; + + CalculateVideoTimeScale(aFramerate); + } + +/** +Calculate video timescale and frame duration. +The video timescale is the nearest whole number multiple of the frame rate. +Where the frame rate includes more than 2 decimal places, it is rounded down +to 2 decimal places. This means the calculation is not wholly accurate in those +circumstances, but hopefully it is close enough. +*/ +void C3GPMuxer::CalculateVideoTimeScale(OMX_U32& aFramerate) + { + // Get rid of floating point and round to 2 decimal places + TInt fps = ((static_cast(aFramerate) / (1<<16)) * 100.0) + 0.5; + + iVideoTimeScale = 0; + iDefaultVideoFrameDuration = 1; + + // Find nearest whole number multiple + for (TInt i = 1; i <= 100; ++i) + { + if ((fps * i) % 100 == 0) + { + iVideoTimeScale = fps * i / 100; + iDefaultVideoFrameDuration = i; + break; + } + } + } + +void C3GPMuxer::RunL() + { + DEBUG_PRINTF(_L8("C3GPMuxer::RunL")); + iQueMutex.Wait(); + + iRequestOutstanding = EFalse; + + if (!iPaused) + { + if (iAudioPortEnabled && iVideoPortEnabled) + { + RunAudioVideoL(); + } + else if (iAudioPortEnabled) + { + RunAudioL(); + } + else if (iVideoPortEnabled) + { + RunVideoL(); + } + } + else + { + iStatus = KRequestPending; + } + + SetActive(); + iQueMutex.Signal(); + } + +void C3GPMuxer::RunAudioVideoL() + { + // When opening the composer, both audio and video properties must be passed in + if(!iAudioBuffer) + { + // ignore error, if KErrUnderflow then we go back to waiting on iAudioQueue + iAudioQueue.Receive(iAudioBuffer); + } + else + { + TInt err = KErrNone; + if (!iCurrentVideoBuffer) + { + err = iVideoQueue.Receive(iCurrentVideoBuffer); + + // if KErrUnderflow then we go back to waiting on iVideoQueue + if (err == KErrNone) + { + // both audio and video buffers has been received + if (!iComposerOpened) + { + OpenComposerL(); + iComposerOpened = ETrue; + + iVideoDuration = (iCurrentVideoBuffer->nTimeStamp * iVideoTimeScale) / KMicroSecondsPerSecond; + + ReturnBuffer(iAudioBuffer, COmxIL3GPMuxer::EPortIndexAudioInput); + iAudioBuffer = NULL; + // [SL] FIXME may also need to return iVideoBuffer in nFilledLen = 0 + // (VideoSpecificInfo was entire buffer) + } + + // We need the timestamp of the next buffer to work out the frame duration of the current video buffer + // so wait to receive the next video buffer + } + } + else + { + if(!iNextVideoBuffer) + { + err = iVideoQueue.Receive(iNextVideoBuffer); + } + + // if KErrUnderflow then we go back to waiting on iVideoQueue + if(err == KErrNone) + { + // next video buffer received + + // audio/video frames are added into the composer in the order of timestap + if (iAudioBuffer->nTimeStamp < iCurrentVideoBuffer->nTimeStamp) + { + WriteAudioBuffer(); + iAudioBuffer = NULL; + } + else + { + WriteVideoBufferL(); + iCurrentVideoBuffer = iNextVideoBuffer; + iNextVideoBuffer = NULL; + + if (iCurrentVideoBuffer->nFlags & OMX_BUFFERFLAG_EOS) + { + // this is the last video buffer + WriteVideoBufferL(); + iCurrentVideoBuffer = NULL; + } + } + } + } + } + + if(!iAudioBuffer) + { + iAudioQueue.NotifyDataAvailable(iStatus); + } + else if(!iNextVideoBuffer) + { + iVideoQueue.NotifyDataAvailable(iStatus); + } + else + { + // already have both buffers available + TRequestStatus* statusPtr = &iStatus; + User::RequestComplete(statusPtr, KErrNone); + } + + iRequestOutstanding = ETrue; + } + +void C3GPMuxer::RunAudioL() + { + if(iAudioBuffer == NULL) + { + TInt err = iAudioQueue.Receive(iAudioBuffer); + // KErrUnderflow if RemoveBuffer or FlushBuffers occurs between notify completion and RunL + if(err != KErrNone && err != KErrUnderflow) + { + HandleError(err); + return; + } + } + + if(iAudioBuffer != NULL) + { + if (!iComposerOpened) + { + OpenComposerL(); + iComposerOpened = ETrue; + //return the buffer + ReturnBuffer(iAudioBuffer, COmxIL3GPMuxer::EPortIndexAudioInput); + } + else + { + //write the non header audio buffer. + WriteAudioBuffer(); + } + iAudioBuffer = NULL; + } + + iAudioQueue.NotifyDataAvailable(iStatus); + iRequestOutstanding = ETrue; + } + +void C3GPMuxer::RunVideoL() + { + if (!iCurrentVideoBuffer) + { + // FIXME KErrUnderflow if RemoveBuffer or FlushBuffers occurs between notify completion and RunL + HandleError(iVideoQueue.Receive(iCurrentVideoBuffer)); + + if (!iComposerOpened) + { + OpenComposerL(); + iComposerOpened = ETrue; + } + + iVideoDuration = (iCurrentVideoBuffer->nTimeStamp * iVideoTimeScale) / KMicroSecondsPerSecond; + + // We need the timestamp of the next buffer to work out the frame duration of the current buffer + // so wait to receive the next buffer + } + else + { + // next buffer received + // FIXME KErrUnderflow if RemoveBuffer or FlushBuffers occurs between notify completion and RunL + HandleError(iVideoQueue.Receive(iNextVideoBuffer)); + + WriteVideoBufferL(); + + iCurrentVideoBuffer = iNextVideoBuffer; + iNextVideoBuffer = NULL; + + if (iCurrentVideoBuffer->nFlags & OMX_BUFFERFLAG_EOS) + { + // this is the last buffer + WriteVideoBufferL(); + iCurrentVideoBuffer = NULL; + } + } + + iVideoQueue.NotifyDataAvailable(iStatus); + iRequestOutstanding = ETrue; + } + +void C3GPMuxer::OpenComposerL() + { + DEBUG_PRINTF(_L8("C3GPMuxer::OpenComposer")); + T3GPAudioPropertiesBase* audioProperties = NULL; + TPtr8 audioPtr(NULL,0); + + if (iAudioPortEnabled) + { + // The first buffer is the decoder specific info. + audioPtr.Set(iAudioBuffer->pBuffer + iAudioBuffer->nOffset, + iAudioBuffer->nFilledLen, + iAudioBuffer->nAllocLen - iAudioBuffer->nOffset); + + } + //The following obj need to be declared in the scope of this function and + //also after audioPtr is set. + //Mpeg4Audio is hardcoded for now. + T3GPAudioPropertiesMpeg4Audio audioPropertiesObj(KAudioTimeScale, audioPtr); + + // If audio port is disabled, audioProperties needs to be NULL + if (iAudioPortEnabled) + { + audioProperties=&audioPropertiesObj; + } + + T3GPVideoPropertiesBase* videoProperties = NULL; + TPtr8 videoPtr(NULL,0); + TBool foundVideoFrame = EFalse; + if (iVideoPortEnabled) + { + // get decoder specific info length + TInt offset; + const TUint8* buf = reinterpret_cast(iCurrentVideoBuffer->pBuffer + iCurrentVideoBuffer->nOffset); + TUint32 stitch = 0xFFFFFFFF; + for(offset = 0; offset < iCurrentVideoBuffer->nFilledLen; offset++) + { + stitch <<= 8; + stitch |= buf[offset]; + if(stitch == 0x000001B6) // start of a frame + { + foundVideoFrame = ETrue; + break; + } + } + + if (foundVideoFrame) + { + offset -= 3; + videoPtr.Set(iCurrentVideoBuffer->pBuffer + iCurrentVideoBuffer->nOffset, + offset, iCurrentVideoBuffer->nAllocLen - iCurrentVideoBuffer->nOffset); + iCurrentVideoBuffer->nOffset += offset; + iCurrentVideoBuffer->nFilledLen -= offset; + } + else + { + // We assume that the whole frame is the decoder specific info + videoPtr.Set(iCurrentVideoBuffer->pBuffer + iCurrentVideoBuffer->nOffset, + iCurrentVideoBuffer->nFilledLen, iCurrentVideoBuffer->nAllocLen - iCurrentVideoBuffer->nOffset); + + // Whole buffer has been used. Set remaining length to zero so that when the + // next buffer arrives we don't try to write out the decoder specific info + // as a frame + iCurrentVideoBuffer->nOffset += iCurrentVideoBuffer->nFilledLen; + iCurrentVideoBuffer->nFilledLen = 0; + } + + // FIXME unhandled allocation error - store this on the stack? + videoProperties = new T3GPVideoPropertiesMpeg4Video(iVideoTimeScale, iVideoSize, iBitRate, iBitRate, videoPtr); + } + + HandleError(iComposer->Open(E3GP3GP, videoProperties, audioProperties, *iFilename, E3GPLongClip)); + + delete videoProperties; + } + +void C3GPMuxer::WriteVideoBufferL() + { + DEBUG_PRINTF(_L8("C3GPMuxer::WriteVideoBuffer")); + TUint8* currentBuffer = NULL; + TInt currentBufferLength = 0; + TInt currentBufferMaxLength = 0; + TBool multipleFrameInBuffer = EFalse; + + if (iPartialFrame.Length() > 0) + { + // merge the partial frame from the previous buffer + + if (iPartialFrame.Length()+iCurrentVideoBuffer->nFilledLen > KMaxBufferSize) + { + iPartialFrame.ReAllocL(iPartialFrame.Length()+iCurrentVideoBuffer->nFilledLen); + } + + iPartialFrame.Append(iCurrentVideoBuffer->pBuffer + iCurrentVideoBuffer->nOffset, iCurrentVideoBuffer->nFilledLen); + + currentBuffer = const_cast(iPartialFrame.Ptr()); + currentBufferLength = iPartialFrame.Length(); + currentBufferMaxLength = iPartialFrame.MaxLength(); + + multipleFrameInBuffer = ETrue; + } + else + { + currentBuffer = iCurrentVideoBuffer->pBuffer + iCurrentVideoBuffer->nOffset; + currentBufferLength = iCurrentVideoBuffer->nFilledLen; + currentBufferMaxLength = iCurrentVideoBuffer->nAllocLen - iCurrentVideoBuffer->nOffset; + } + + // Write video frames from buffer. + // Check for non-zero buffer length in case we have been sent an empty buffer + if (currentBufferLength > 0) + { + if(!multipleFrameInBuffer && (iCurrentVideoBuffer->nFlags & OMX_BUFFERFLAG_SYNCFRAME)) + { + // buffer contains one full I frame + TInt nextFrameDuration = CalculateNextFrameDuration(); + TPtr8 videoPtr(currentBuffer, currentBufferLength, currentBufferMaxLength); + HandleError(iComposer->WriteVideoFrame(videoPtr, nextFrameDuration, ETrue)); + } + else if (!multipleFrameInBuffer && (iCurrentVideoBuffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME)) + { + // buffer contains one full frame + + // Evaluate whether it is an I frame + TInt offset = 0; + TUint32 stitch = 0xFFFFFFFF; + TBool isIframe = EFalse; + + for(offset = 0; offset < currentBufferLength; offset++) + { + stitch <<= 8; + stitch |= currentBuffer[offset]; + + if(stitch == 0x000001B6) // start of a frame + { + TUint8 iframebits = currentBuffer[offset+1] >> 6; // get the next 2 bits + if (iframebits == 0) + { + isIframe = ETrue; + } + else + { + isIframe = EFalse; + } + + break; + } + } + + TInt nextFrameDuration = CalculateNextFrameDuration(); + TPtr8 videoPtr(currentBuffer, currentBufferLength, currentBufferMaxLength); + HandleError(iComposer->WriteVideoFrame(videoPtr, nextFrameDuration, isIframe)); + } + else + { + // buffer either contains multiple frames or part of a single frame + // so need to parse the buffer to retrieve the frames + + TInt offset = 0; + TUint32 stitch = 0xFFFFFFFF; + + TBool foundNextFrame = EFalse; + TInt frameLength = 0; + TInt frameOffset = 0; + TBool isIframe = EFalse; + TBool frameWritten = EFalse; + + // retieve and write video frames + for(offset = 0; offset < currentBufferLength; offset++) + { + stitch <<= 8; + stitch |= currentBuffer[offset]; + + frameLength++; + + if(!foundNextFrame && stitch == 0x000001B6) + { + foundNextFrame = ETrue; + + // Evaluate whether it is an I frame + if (offset+1 >= currentBufferLength) + { + break; // reached the end of the buffer + } + + TUint8 iframebits = currentBuffer[offset+1] >> 6; // get the next 2 bits + if (iframebits == 0) + { + isIframe = ETrue; + } + else + { + isIframe = EFalse; + } + } + else if (foundNextFrame && (stitch == 0x000001B0 || stitch == 0x00000120)) + { + // start of next frame (which includes VOS and/or VOL header) + + // write the current frame + TInt nextFrameDuration = CalculateNextFrameDurationPartial(frameWritten); + TPtr8 videoPtr(currentBuffer + frameOffset, frameLength - 4, currentBufferMaxLength - frameOffset); + HandleError(iComposer->WriteVideoFrame(videoPtr, nextFrameDuration, isIframe)); + frameWritten = ETrue; + + frameOffset = offset - 3; // to include the VOS/VOL start code in the next frame + frameLength = 4; + + foundNextFrame = EFalse; + isIframe = EFalse; + } + else if (foundNextFrame && stitch == 0x000001B6) + { + // start of next frame + + // write the current frame + TInt nextFrameDuration = CalculateNextFrameDurationPartial(frameWritten); + TPtr8 videoPtr(currentBuffer + frameOffset, frameLength - 4, currentBufferMaxLength - frameOffset); + HandleError(iComposer->WriteVideoFrame(videoPtr, nextFrameDuration, isIframe)); + frameWritten = ETrue; + + frameOffset = offset - 3; // to include the VOP start code in the next frame + frameLength = 4; + + foundNextFrame = ETrue; + + // Evaluate whether it is an I frame + if (offset+1 >= currentBufferLength) + { + break; // reached the end of the buffer + } + + TUint8 iframebits = currentBuffer[offset+1] >> 6; // get the next 2 bits + if (iframebits == 0) + { + isIframe = ETrue; + } + else + { + isIframe = EFalse; + } + } + } + + if (frameLength > 0) + { + if (iCurrentVideoBuffer->nFlags & OMX_BUFFERFLAG_EOS) + { + // this is the last buffer, so we can assume that the rest of the buffer contains one full frame + TInt nextFrameDuration = CalculateNextFrameDurationPartial(frameWritten); + TPtr8 videoPtr(currentBuffer + frameOffset, frameLength, currentBufferMaxLength - frameOffset); + HandleError(iComposer->WriteVideoFrame(videoPtr, nextFrameDuration, isIframe)); + frameWritten = ETrue; + } + else + { + // the buffer may contain part of a frame + // save it for use later + iPartialFrame.Copy(currentBuffer + frameOffset, frameLength); + } + } + else + { + User::Panic(K3GPMuxerPanic, KErrGeneral); // frameLength should never be 0 + } + } + } + + ReturnBuffer(iCurrentVideoBuffer, COmxIL3GPMuxer::EPortIndexVideoInput); + } + +TInt C3GPMuxer::CalculateNextFrameDuration() + { + TInt64 durationSinceStart = (iCurrentVideoBuffer->nTimeStamp * iVideoTimeScale) / KMicroSecondsPerSecond; + TInt nextFrameDuration = durationSinceStart - iVideoDuration; + if (nextFrameDuration < iDefaultVideoFrameDuration) + { + nextFrameDuration = iDefaultVideoFrameDuration; + } + + iVideoDuration = durationSinceStart; + + return nextFrameDuration; + } + +TInt C3GPMuxer::CalculateNextFrameDurationPartial(TBool aFrameWritten) + { + if (!aFrameWritten) + { + return CalculateNextFrameDuration(); + } + + iVideoDuration += iDefaultVideoFrameDuration; + + return iDefaultVideoFrameDuration; + } + +void C3GPMuxer::WriteAudioBuffer() + { + DEBUG_PRINTF(_L8("C3GPMuxer::WriteAudioBuffer")); + + if (iAudioBuffer->nFilledLen != 0) + { + TPtr8 audioPtr(iAudioBuffer->pBuffer + iAudioBuffer->nOffset, + iAudioBuffer->nFilledLen, iAudioBuffer->nAllocLen - iAudioBuffer->nOffset); + + + //Calculate the audio frame duration in timescale + //nTimeStamp is in microseconds + TUint durationInTimeSlice=KAudioTimeScale*iAudioBuffer->nTimeStamp/KMicroSecondsPerSecond; + TUint duration=durationInTimeSlice-iAudioFrameDuration; + iAudioFrameDuration=durationInTimeSlice; + HandleError(iComposer->WriteAudioFrames(audioPtr, duration)); + + + + } + ReturnBuffer(iAudioBuffer, COmxIL3GPMuxer::EPortIndexAudioInput); + } + +void C3GPMuxer::ReturnBuffer(OMX_BUFFERHEADERTYPE* aBuffer, TUint32 aPortIndex) + { + DEBUG_PRINTF3(_L8("C3GPMuxer::ReturnBuffer : aBuffer[%X]; aPortIndex[%u]"), aBuffer, aPortIndex); + OMX_U32 flags = aBuffer->nFlags; + aBuffer->nFilledLen = 0; + aBuffer->nFlags = 0; + aBuffer->nOffset = 0; + aBuffer->nTimeStamp = 0; + iCallbacks.BufferDoneNotification(aBuffer, aPortIndex, OMX_DirInput); + + if(flags & OMX_BUFFERFLAG_EOS) + { + iCallbacks.EventNotification(OMX_EventBufferFlag, aPortIndex, flags, NULL); + } + } + +void C3GPMuxer::DoCancel() + { + DEBUG_PRINTF(_L8("C3GPMuxer::DoCancel")); + if (iAudioPortEnabled) + { + iAudioQueue.CancelDataAvailable(); + } + + if (iVideoPortEnabled) + { + iVideoQueue.CancelDataAvailable(); + } + } + +TBool C3GPMuxer::RemoveFromQueue(RMsgQueue& aQueue, OMX_BUFFERHEADERTYPE* aBufferHeader) + { + DEBUG_PRINTF3(_L8("C3GPMuxer::RemoveFromQueue : aQueue[%X]; aBufferHeader[%X]"), &aQueue, aBufferHeader); + TBool removed = EFalse; + OMX_BUFFERHEADERTYPE* bufferHeader = NULL; + while(aQueue.Receive(bufferHeader) != KErrUnderflow) + { + if(bufferHeader != aBufferHeader) + { + TInt error = iRemoveQueue.Send(bufferHeader); + __ASSERT_DEBUG(error == KErrNone, User::Panic(K3GPMuxerPanic, error)); + } + else + { + removed = ETrue; + } + } + while(iRemoveQueue.Receive(bufferHeader) != KErrUnderflow) + { + TInt error = aQueue.Send(bufferHeader); + __ASSERT_DEBUG(error == KErrNone, User::Panic(K3GPMuxerPanic, error)); + } + return removed; + } + +void C3GPMuxer::Pause() + { + DEBUG_PRINTF(_L8("C3GPMuxer::Pause")); + iPaused = ETrue; + } + +void C3GPMuxer::HandleError(TInt aError) + { + DEBUG_PRINTF2(_L8("C3GPMuxer::HandleError : aError[%d]"), aError); + OMX_ERRORTYPE omxError = SymbianErrorToOmx(aError); + if (omxError != OMX_ErrorNone) + { + iMuxerInvalid = ETrue; + iCallbacks.ErrorEventNotification(omxError); + } + } + +TBool C3GPMuxer::IsMuxerInvalid() const + { + return iMuxerInvalid; + } + +OMX_ERRORTYPE C3GPMuxer::SymbianErrorToOmx(TInt aError) + { + switch(aError) + { + case KErrNone: + return OMX_ErrorNone; + case KErrNoMemory: + return OMX_ErrorInsufficientResources; + case KErrWrite: + return OMX_ErrorContentPipeOpenFailed; + default: + return OMX_ErrorUndefined; + } + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/src/c3gpmuxer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/src/c3gpmuxer.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef C3GPMUXER_H +#define C3GPMUXER_H + +#include +#include +#include +#include +#include +#include + +#include "comxil3gpmuxer.h" +#include "endwaitao.h" + + + +class MOmxILCallbackNotificationIf; + +NONSHARABLE_CLASS(C3GPMuxer) : public CActive + { + + friend class C3GPMuxerWriterThreadObserver; +public: + static C3GPMuxer* NewL(MOmxILCallbackNotificationIf& aCallbacks); + ~C3GPMuxer(); + + void ProcessThisBufferL(OMX_BUFFERHEADERTYPE* aBufferHeader, TUint32 aPortIndex); + void FlushBuffers(TUint32 aPortIndex); + TBool RemoveBuffer(OMX_BUFFERHEADERTYPE* aBufferHeader); + void SetFilename(const HBufC* aFilename); + void SetAudioVideoProperties(OMX_U32& aFrameWidth, OMX_U32& aFrameHeight, + OMX_U32& aFramerate, OMX_U32& aBitRate, OMX_U32& aAudioFramerate); + void StartL(TBool aAudioPortEnabled, TBool aVideoPortEnabled); + void Pause(); + TBool IsMuxerInvalid() const; + void HandleError(TInt aError); + OMX_ERRORTYPE SymbianErrorToOmx(TInt aError); +protected: + void RunL(); + void RunAudioVideoL(); + void RunAudioL(); + void RunVideoL(); + void DoCancel(); + +private: + C3GPMuxer(MOmxILCallbackNotificationIf& aCallbacks); + void ConstructL(); + + void OpenComposerL(); + void WriteVideoBufferL(); + void WriteAudioBuffer(); + void DoFlushBuffers(TUint32 aPortIndex); + void ReturnBuffer(OMX_BUFFERHEADERTYPE* aBuffer, TUint32 aPortIndex); + static TInt ThreadEntryPoint(TAny* aPtr); + void RunThreadL(); + TBool RemoveFromQueue(RMsgQueue& aQueue, OMX_BUFFERHEADERTYPE* aBufferHeader); + void CalculateVideoTimeScale(OMX_U32& aFramerate); + TInt CalculateNextFrameDuration(); + TInt CalculateNextFrameDurationPartial(TBool aFrameWritten); + +private: + MOmxILCallbackNotificationIf& iCallbacks; + C3GPCompose* iComposer; + const HBufC* iFilename; // Not owned by this class + TSize iVideoSize; + TInt iVideoTimeScale; + TInt iDefaultVideoFrameDuration; + TUint iBitRate; + TBool iAudioPortEnabled; + TBool iVideoPortEnabled; + RMsgQueue iAudioQueue; + RMsgQueue iVideoQueue; + OMX_BUFFERHEADERTYPE* iAudioBuffer; + OMX_BUFFERHEADERTYPE* iCurrentVideoBuffer; + TBool iComposerOpened; + TUint iAudioFrameDuration; + RThread iThread; + RMutex iQueMutex; + TBool iThreadRunning; + CEndWaitAO* iEndWaitAO; + RMsgQueue iRemoveQueue; + TBool iPaused; + TBool iMuxerInvalid; + RBuf8 iPartialFrame; + OMX_BUFFERHEADERTYPE* iNextVideoBuffer; + TInt64 iVideoDuration; + TUint iRemoveQueueLength; + TBool iRemoveQueueNeedsReallocation; + TBool iRequestOutstanding; + }; + +#endif //C3GPMUXER_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/src/c3gpmuxerwriterthreadobserver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/src/c3gpmuxerwriterthreadobserver.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +#include "c3gpmuxerwriterthreadobserver.h" + +_LIT(KMuxerWriterThreadPanic,"MUXER-THREAD-PANIC"); + +C3GPMuxerWriterThreadObserver* C3GPMuxerWriterThreadObserver::NewL(C3GPMuxer* aC3GPMuxer) + { + C3GPMuxerWriterThreadObserver* self = new(ELeave)C3GPMuxerWriterThreadObserver(aC3GPMuxer); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +C3GPMuxerWriterThreadObserver::C3GPMuxerWriterThreadObserver(C3GPMuxer* aC3GPMuxer): +CActive(EPriorityStandard) + { + iWriterThread = aC3GPMuxer; + } + +void C3GPMuxerWriterThreadObserver::ConstructL() + { + CActiveScheduler::Add(this); + } + +void C3GPMuxerWriterThreadObserver::IssueRequest() + { + __ASSERT_ALWAYS(!IsActive(), User::Panic(KMuxerWriterThreadPanic, 0)); + iWriterThread->iThread.Logon(iStatus); + SetActive(); + } + +void C3GPMuxerWriterThreadObserver::RunL() + { + if(KErrDied==iStatus.Int()) + { + iWriterThread->HandleError(KErrDied); + } + } +void C3GPMuxerWriterThreadObserver::DoCancel() + { + //Do Nothing + } +C3GPMuxerWriterThreadObserver::~C3GPMuxerWriterThreadObserver() + { + Cancel(); + } +TInt C3GPMuxerWriterThreadObserver::RunError(TInt) + { + return KErrNone; + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/src/c3gpmuxerwriterthreadobserver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/src/c3gpmuxerwriterthreadobserver.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +/** + @file + @internalComponent + */ +#ifndef C3GPMUXERWRITERTHREADOBSERVER_H_ +#define C3GPMUXERWRITERTHREADOBSERVER_H_ + +#include "c3gpmuxer.h" +#include + +//3GP Muxer writer thread observer class + +class C3GPMuxerWriterThreadObserver : public CActive +{ +public: + + static C3GPMuxerWriterThreadObserver* NewL(C3GPMuxer* aC3GPMuxer); + ~C3GPMuxerWriterThreadObserver(); + void ConstructL(); + void IssueRequest(); + +protected: + C3GPMuxerWriterThreadObserver(C3GPMuxer* aC3GPMuxer); + +// From CActive class + void RunL(); + void DoCancel(); + TInt RunError(TInt aError); +//data members +private: + C3GPMuxer* iWriterThread; +}; + +#endif /*C3GPMUXERWRITERTHREADOBSERVER_H_*/ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxer.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,182 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include + +#include "omxil3gpmuxer.hrh" +#include "comxil3gpmuxer.h" +#include "comxil3gpmuxerprocessingfunction.h" +#include "comxil3gpmuxerconfigmanager.h" +#include "comxil3gpmuxervideoinputport.h" +#include "comxil3gpmuxeraudioinputport.h" +#include "log.h" + +_LIT8(KSymbianOmxIL3gpMuxerName, "OMX.SYMBIAN.OTHER.CONTAINER_MUXER.3GP"); +_LIT8(KSymbianOmxIL3gpMuxerRole, "container_muxer"); + +static const TInt KMinAudioBufferCount = 1; +// at least 2 video buffers must be used since the difference in two buffer timestamps +// is used to calculate the frame duration passed to 3gplibrary +static const TInt KMinVideoBufferCount = 2; + +OMXIL_COMPONENT_ECOM_ENTRYPOINT(KUidSymbianOmxIL3gpMuxer); + +OMX_ERRORTYPE SymbianErrorToOmx(TInt aError); + +// Component Entry Point +OMX_ERRORTYPE OMX_ComponentInit(OMX_HANDLETYPE aComponent) + { + TInt err = COmxIL3GPMuxer::CreateComponent(aComponent); + return SymbianErrorToOmx(err); + } + +TInt COmxIL3GPMuxer::CreateComponent(OMX_HANDLETYPE hComponent) + { + DEBUG_PRINTF(_L8("COmxIL3GPMuxer::CreateComponent")); + COmxIL3GPMuxer* self = new COmxIL3GPMuxer(); + + if (!self) + { + return KErrNoMemory; + } + + TRAPD(err, self->ConstructL(hComponent)); + if(err) + { + delete self; + } + return err; + } + +COmxIL3GPMuxer::COmxIL3GPMuxer() + { + } + +void COmxIL3GPMuxer::ConstructL(OMX_HANDLETYPE hComponent) + { + // STEP 1: Initialize the data received from the IL Core + COmxILComponent::ConstructL(hComponent); + + // STEP 2: Create the call backs holder... + MOmxILCallbackNotificationIf* callbackNotificationIf=CreateCallbackManagerL(COmxILComponent::EOutofContext); + + // STEP 3: Create the 3gpmuxer-specific Processing Function... + COmxIL3GPMuxerProcessingFunction* pProcessingFunction = COmxIL3GPMuxerProcessingFunction::NewL(*callbackNotificationIf); + RegisterProcessingFunction(pProcessingFunction); + + // STEP 4: Create Port manager... + CreatePortManagerL(COmxILComponent::ENonBufferSharingPortManager, + TOmxILSpecVersion(), // OMX Version + 1, // The number of audio ports in this component + 0, // The starting audio port index + 0, // The number of image ports in this component + 0, // The starting image port index + 1, // The number of video ports in this component + 1, // The starting video port index + 0, // The number of other ports in this component + 0 // The starting other port index + ); + + // STEP 5: Create the non-port related configuration manager... + RPointerArray roleList; + CleanupClosePushL(roleList); + roleList.AppendL(&KSymbianOmxIL3gpMuxerRole); + COmxIL3GPMuxerConfigManager* configManager = COmxIL3GPMuxerConfigManager::NewL(KSymbianOmxIL3gpMuxerName, TOmxILSpecVersion(), roleList); + RegisterConfigurationManager(configManager); + CleanupStack::PopAndDestroy(); + + static_cast(pProcessingFunction)->SetConfigManager(*configManager); + + // create the input port and add it to the port manager... + AddAudioInputPortL(); + AddVideoInputPortL(); + + // And finally, let's get everything started + InitComponentL(); + } + +COmxIL3GPMuxer::~COmxIL3GPMuxer() + { + DEBUG_PRINTF(_L8("COmxIL3GPMuxer::~COmxIL3GPMuxer")); + } + +void COmxIL3GPMuxer::AddVideoInputPortL() + { + DEBUG_PRINTF(_L8("COmxIL3GPMuxer::AddVideoInputPortL")); + TOmxILSpecVersion omxVersion; + TOmxILCommonPortData portData( + omxVersion, + EPortIndexVideoInput, + OMX_DirInput, + KMinVideoBufferCount, + 20480, // minimum buffer size, in bytes, TODO autodetect this + OMX_PortDomainVideo, + OMX_TRUE, + 4, // 4-byte alignment + OMX_BufferSupplyUnspecified, + COmxILPort::KBufferMarkPropagationPortNotNeeded + ); + + COmxIL3GPMuxerVideoInputPort* videoInputPort = COmxIL3GPMuxerVideoInputPort::NewL(portData); + CleanupStack::PushL(videoInputPort); + User::LeaveIfError(AddPort(videoInputPort, OMX_DirInput)); + CleanupStack::Pop(); + static_cast(GetProcessingFunction())->SetVideoPort(*videoInputPort); + } + +void COmxIL3GPMuxer::AddAudioInputPortL() + { + DEBUG_PRINTF(_L8("COmxIL3GPMuxer::AddAudioInputPortL")); + TOmxILSpecVersion omxVersion; + TOmxILCommonPortData portData( + omxVersion, + EPortIndexAudioInput, + OMX_DirInput, + KMinAudioBufferCount, + 20480, // minimum buffer size, in bytes, TODO autodetect this + OMX_PortDomainAudio, + OMX_TRUE, + 4, // 4-byte alignment + OMX_BufferSupplyUnspecified, + COmxILPort::KBufferMarkPropagationPortNotNeeded + ); + + COmxIL3GPMuxerAudioInputPort* audioInputPort = COmxIL3GPMuxerAudioInputPort::NewL(portData); + CleanupStack::PushL(audioInputPort); + User::LeaveIfError(AddPort(audioInputPort, OMX_DirInput)); + CleanupStack::Pop(); + static_cast(GetProcessingFunction())->SetAudioPort(*audioInputPort); + } + +OMX_ERRORTYPE SymbianErrorToOmx(TInt aError) + { + switch(aError) + { + case KErrNone: + return OMX_ErrorNone; + case KErrNoMemory: + return OMX_ErrorInsufficientResources; + default: + return OMX_ErrorUndefined; + } + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxer.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef COMXIL3GPDEMUXER_H +#define COMXIL3GPDEMUXER_H + +#include + +class COmxIL3GPMuxerVideoInputPort; +class COmxIL3GPMuxerAudioInputPort; + +NONSHARABLE_CLASS(COmxIL3GPMuxer) : public COmxILComponent + { +public: + enum TPortIndex + { + EPortIndexAudioInput = 0, + EPortIndexVideoInput, + EPortIndexMax // Must be last + }; +public: + static TInt CreateComponent(OMX_HANDLETYPE hComponent); + ~COmxIL3GPMuxer(); + +private: + COmxIL3GPMuxer(); + void ConstructL(OMX_HANDLETYPE hComponent); + +private: + void AddVideoInputPortL(); + void AddAudioInputPortL(); + }; + +#endif //COMXIL3GPDEMUXER_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxeraudioinputport.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxeraudioinputport.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,125 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include "comxil3gpmuxeraudioinputport.h" +#include "log.h" + +// TODO: Possibly add other mime types, for now only AAC handled +_LIT8(KMimeTypeAudioAac, "audio/aac"); + +COmxIL3GPMuxerAudioInputPort* COmxIL3GPMuxerAudioInputPort::NewL(const TOmxILCommonPortData& aCommonPortData) + { + DEBUG_PRINTF(_L8("COmxIL3GPMuxerAudioInputPort::NewL")); + + COmxIL3GPMuxerAudioInputPort* self = new(ELeave) COmxIL3GPMuxerAudioInputPort(); + CleanupStack::PushL(self); + self->ConstructL(aCommonPortData); + CleanupStack::Pop(self); + return self; + } + +void COmxIL3GPMuxerAudioInputPort::ConstructL(const TOmxILCommonPortData& aCommonPortData) + { + RArray supportedCodings; + CleanupClosePushL(supportedCodings); + supportedCodings.AppendL(OMX_AUDIO_CodingAAC); + COmxILAudioPort::ConstructL(aCommonPortData, supportedCodings); + CleanupStack::PopAndDestroy(&supportedCodings); + + // We have to finish with iParamPortDefinition + GetParamPortDefinition().eDomain = OMX_PortDomainAudio; + GetParamPortDefinition().format.audio.pNativeRender = 0; + + // TODO: Possible add in the future other mime types that can be handled by + // this audio port... for now only AAC Check + // COmxILAudioPort::iParamAudioPortFormat.nIndex and use + // COmxILAudioPort::iSupportedAudioFormats[iParamAudioPortFormat.nIndex] + + iMimeTypeBuf.CreateL(KMimeTypeAudioAac(), KMimeTypeAudioAac().Length() + 1); + + TUint8* pTUint = const_cast(iMimeTypeBuf.PtrZ()); + GetParamPortDefinition().format.audio.cMIMEType = reinterpret_cast(pTUint); + + GetParamPortDefinition().format.audio.bFlagErrorConcealment = OMX_FALSE; + GetParamPortDefinition().format.audio.eEncoding = OMX_AUDIO_CodingAAC; + } + +COmxIL3GPMuxerAudioInputPort::COmxIL3GPMuxerAudioInputPort() + { + } + +COmxIL3GPMuxerAudioInputPort::~COmxIL3GPMuxerAudioInputPort() + { + DEBUG_PRINTF(_L8("COmxIL3GPMuxerAudioInputPort::~COmxIL3GPMuxerAudioInputPort")); + iMimeTypeBuf.Close(); + } + +OMX_U32 COmxIL3GPMuxerAudioInputPort::GetAudioFrameRate() const + { + // TODO return nSamplingRate + return 0; + } + +OMX_ERRORTYPE COmxIL3GPMuxerAudioInputPort::GetLocalOmxParamIndexes(RArray& aIndexArray) const + { + return COmxILAudioPort::GetLocalOmxParamIndexes(aIndexArray); + } + +OMX_ERRORTYPE COmxIL3GPMuxerAudioInputPort::GetLocalOmxConfigIndexes(RArray& aIndexArray) const + { + return COmxILAudioPort::GetLocalOmxConfigIndexes(aIndexArray); + } + +OMX_ERRORTYPE COmxIL3GPMuxerAudioInputPort::GetParameter(OMX_INDEXTYPE aParamIndex, TAny* apComponentParameterStructure) const + { + DEBUG_PRINTF2(_L8("COmxIL3GPMuxerAudioInputPort::GetParameter : aParamIndex[%u]"), aParamIndex); + return COmxILAudioPort::GetParameter(aParamIndex, apComponentParameterStructure); + } + +OMX_ERRORTYPE COmxIL3GPMuxerAudioInputPort::SetParameter(OMX_INDEXTYPE aParamIndex, + const TAny* apComponentParameterStructure, + TBool& aUpdateProcessingFunction) + { + DEBUG_PRINTF2(_L8("COmxIL3GPMuxerAudioInputPort::SetParameter : aParamIndex[%u]"), aParamIndex); + return COmxILAudioPort::SetParameter(aParamIndex, apComponentParameterStructure, aUpdateProcessingFunction); + } + +OMX_ERRORTYPE COmxIL3GPMuxerAudioInputPort::SetFormatInPortDefinition( + const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition, + TBool& /*aUpdateProcessingFunction*/) + { + if (aPortDefinition.nBufferCountActual > KMaxAudioBuffers) + { + return OMX_ErrorBadParameter; + } + + GetParamPortDefinition().format.audio = aPortDefinition.format.audio; + + return OMX_ErrorNone; + } + +TBool COmxIL3GPMuxerAudioInputPort::IsTunnelledPortCompatible(const OMX_PARAM_PORTDEFINITIONTYPE& /*aPortDefinition*/) const + { + // TODO (The base class should do this checking) + return ETrue; + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxeraudioinputport.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxeraudioinputport.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef COMXIL3GPMUXERAUDIOINPUTPORT_H +#define COMXIL3GPMUXERAUDIOINPUTPORT_H + +#include + +class COmxIL3GPMuxerProcessingFunction; + +const TInt KMaxAudioBuffers = 20; + +NONSHARABLE_CLASS(COmxIL3GPMuxerAudioInputPort) : public COmxILAudioPort + { +public: + static COmxIL3GPMuxerAudioInputPort* NewL(const TOmxILCommonPortData& aCommonPortData); + + ~COmxIL3GPMuxerAudioInputPort(); + + OMX_U32 GetAudioFrameRate() const; + + // from COmxILAudioPort + OMX_ERRORTYPE GetLocalOmxParamIndexes(RArray& aIndexArray) const; + OMX_ERRORTYPE GetLocalOmxConfigIndexes(RArray& aIndexArray) const; + OMX_ERRORTYPE GetParameter(OMX_INDEXTYPE aParamIndex, + TAny* apComponentParameterStructure) const; + OMX_ERRORTYPE SetParameter(OMX_INDEXTYPE aParamIndex, + const TAny* apComponentParameterStructure, + TBool& aUpdateProcessingFunction); + +protected: + // from COmxILAudioPort + OMX_ERRORTYPE SetFormatInPortDefinition(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition, + TBool& aUpdateProcessingFunction); + TBool IsTunnelledPortCompatible(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition) const; + +private: + COmxIL3GPMuxerAudioInputPort(); + + void ConstructL(const TOmxILCommonPortData& aCommonPortData); + +private: + RBuf8 iMimeTypeBuf; + }; + +#endif /*COMXIL3GPMUXERAUDIOINPUTPORT_H*/ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxerconfigmanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxerconfigmanager.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,152 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include + +#include "comxil3gpmuxerconfigmanager.h" +#include "log.h" + +COmxIL3GPMuxerConfigManager* COmxIL3GPMuxerConfigManager::NewL( + const TDesC8& aComponentName, + const OMX_VERSIONTYPE& aComponentVersion, + const RPointerArray& aComponentRoleList) + { + DEBUG_PRINTF(_L8("COmxIL3GPMuxerConfigManager::NewL")); + COmxIL3GPMuxerConfigManager* self = new(ELeave) COmxIL3GPMuxerConfigManager(); + CleanupStack::PushL(self); + self->ConstructL(aComponentName, aComponentVersion, aComponentRoleList); + CleanupStack::Pop(self); + return self; + } + +COmxIL3GPMuxerConfigManager::COmxIL3GPMuxerConfigManager() + { + // nothing to do + } + +void COmxIL3GPMuxerConfigManager::ConstructL(const TDesC8& aComponentName, + const OMX_VERSIONTYPE& aComponentVersion, + const RPointerArray& aComponentRoleList) + { + COmxILConfigManager::ConstructL(aComponentName, aComponentVersion, aComponentRoleList); + } + +COmxIL3GPMuxerConfigManager::~COmxIL3GPMuxerConfigManager() + { + DEBUG_PRINTF(_L8("COmxIL3GPMuxerConfigManager::~COmxIL3GPMuxerConfigManager")); + delete iUri; + delete iFilename; + } + +OMX_ERRORTYPE COmxIL3GPMuxerConfigManager::GetParameter(OMX_INDEXTYPE aParamIndex, + TAny* apComponentParameterStructure) const + { + DEBUG_PRINTF2(_L8("COmxIL3GPMuxerConfigManager::GetParameter : aParamIndex[%u]"), aParamIndex); + // try the base class first + OMX_ERRORTYPE error = COmxILConfigManager::GetParameter(aParamIndex, apComponentParameterStructure); + if(error != OMX_ErrorUnsupportedIndex) + { + return error; + } + + if(aParamIndex == OMX_IndexParamContentURI) + { + if(!iUri) + { + // content URI has not yet been set + return OMX_ErrorUnsupportedSetting; // TODO check return code + } + OMX_PARAM_CONTENTURITYPE* apContentURI = reinterpret_cast(apComponentParameterStructure); + TPtr8 aDestDes(apContentURI->contentURI, apContentURI->nSize - _FOFF(OMX_PARAM_CONTENTURITYPE, contentURI)); + // using >= as a byte has to be left for the null terminator + if(iUri->Length() >= aDestDes.MaxLength()) + { + // not enough room in supplied struct to copy URI + return OMX_ErrorOverflow; // TODO check return code + } + else + { + aDestDes = *iUri; + aDestDes.Append('\0'); + return OMX_ErrorNone; + } + } + return OMX_ErrorUnsupportedIndex; + } + +OMX_ERRORTYPE COmxIL3GPMuxerConfigManager::SetParameter(OMX_INDEXTYPE aParamIndex, + const TAny* aComponentParameterStructure, + OMX_BOOL aInitTime) + { + DEBUG_PRINTF2(_L8("COmxIL3GPMuxerConfigManager::SetParameter : aParamIndex[%u]"), aParamIndex); + // try the base class first + OMX_ERRORTYPE error = COmxILConfigManager::SetParameter(aParamIndex, aComponentParameterStructure, aInitTime); + if(error != OMX_ErrorUnsupportedIndex) + { + return error; + } + + if(aParamIndex == OMX_IndexParamContentURI) + { + const OMX_PARAM_CONTENTURITYPE* contentUri = reinterpret_cast(aComponentParameterStructure); + TPtrC8 aUriDes(contentUri->contentURI); + + // validate URI by converting to filename + TUriParser8 parser; + if(parser.Parse(aUriDes) != KErrNone) + { + return OMX_ErrorBadParameter; + } + + HBufC* newFilename = NULL; + TInt error; + TRAP(error, newFilename = parser.GetFileNameL()); + if(error != KErrNone) + { + return OMX_ErrorBadParameter; + } + + // retain a copy of the original URI for GetParameter + HBufC8* newUri = HBufC8::New(aUriDes.Length()); + if(!newUri) + { + delete newFilename; + return OMX_ErrorInsufficientResources; + } + *newUri = aUriDes; + + delete iUri; + iUri = newUri; + delete iFilename; + iFilename = newFilename; + + return OMX_ErrorNone; + } + + return OMX_ErrorUnsupportedIndex; + } + +const HBufC* COmxIL3GPMuxerConfigManager::Filename() const + { + return iFilename; + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxerconfigmanager.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxerconfigmanager.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef COMXIL3GPMUXERCONFIGMANAGER_H +#define COMXIL3GPMUXERCONFIGMANAGER_H + +#include + +NONSHARABLE_CLASS(COmxIL3GPMuxerConfigManager) : public COmxILConfigManager + { +public: + static COmxIL3GPMuxerConfigManager* NewL( + const TDesC8& aComponentName, + const OMX_VERSIONTYPE& aComponentVersion, + const RPointerArray& aComponentRoles); + + ~COmxIL3GPMuxerConfigManager(); + + OMX_ERRORTYPE GetParameter(OMX_INDEXTYPE aParamIndex, + TAny* apComponentParameterStructure) const; + + OMX_ERRORTYPE SetParameter(OMX_INDEXTYPE aParamIndex, + const TAny* aComponentParameterStructure, + OMX_BOOL aInitTime = OMX_TRUE); + + /** can return NULL if parameter has not been set. */ + const HBufC* Filename() const; + +private: + COmxIL3GPMuxerConfigManager(); + + void ConstructL(const TDesC8& aComponentName, + const OMX_VERSIONTYPE& aComponentVersion, + const RPointerArray& aComponentRoles); + +private: + HBufC8* iUri; + HBufC* iFilename; + }; + +#endif //COMXIL3GPMUXERCONFIGMANAGER_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxerprocessingfunction.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxerprocessingfunction.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,230 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include "comxil3gpmuxerprocessingfunction.h" +#include "c3gpmuxer.h" +#include +#include "comxil3gpmuxerconfigmanager.h" +#include "comxil3gpmuxervideoinputport.h" +#include "comxil3gpmuxeraudioinputport.h" +#include "log.h" +#include "c3gpmuxerwriterthreadobserver.h" + +COmxIL3GPMuxerProcessingFunction* COmxIL3GPMuxerProcessingFunction::NewL(MOmxILCallbackNotificationIf& aCallbacks) + { + DEBUG_PRINTF(_L8("COmxIL3GPMuxerProcessingFunction::NewL")); + COmxIL3GPMuxerProcessingFunction* self = new (ELeave) COmxIL3GPMuxerProcessingFunction(aCallbacks); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +COmxIL3GPMuxerProcessingFunction::COmxIL3GPMuxerProcessingFunction(MOmxILCallbackNotificationIf& aCallbacks) : + COmxILProcessingFunction(aCallbacks), + iMuxer(NULL) + { + } + +void COmxIL3GPMuxerProcessingFunction::ConstructL() + { + } + +COmxIL3GPMuxerProcessingFunction::~COmxIL3GPMuxerProcessingFunction() + { + DEBUG_PRINTF(_L8("COmxIL3GPMuxerProcessingFunction::~COmxIL3GPMuxerProcessingFunction")); + delete iMuxer; + delete iWriterThreadObserver; + } + +void COmxIL3GPMuxerProcessingFunction::SetConfigManager(COmxIL3GPMuxerConfigManager& aConfigManager) + { + iConfigManager = &aConfigManager; + } + +OMX_ERRORTYPE COmxIL3GPMuxerProcessingFunction::StateTransitionIndication(TStateIndex aNewState) + { + DEBUG_PRINTF2(_L8("COmxIL3GPMuxerProcessingFunction::StateTransitionIndication : aNewState[%u]"), aNewState); + OMX_ERRORTYPE omxError = OMX_ErrorNone; + + switch(aNewState) + { + case EStateExecuting: + { + TRAPD(error, iMuxer->StartL(iAudioPort->IsEnabled(), iVideoPort->IsEnabled())); + if (error != KErrNone) + { + omxError = SymbianErrorToOmx(error); + } + //Creating Writer thread observer + TRAP(error, iWriterThreadObserver = C3GPMuxerWriterThreadObserver::NewL(iMuxer)); + + if (error != KErrNone) + { + omxError = SymbianErrorToOmx(error); + } + iWriterThreadObserver->IssueRequest(); + break; + } + + case ESubStateLoadedToIdle: + { + OMX_U32 frameWidth = 0; + OMX_U32 frameHeight = 0; + OMX_U32 framerate = 0; + OMX_U32 bitRate = 0; + OMX_U32 audioFramerate = 0; + + iVideoPort->GetVideoProperties(frameWidth, frameHeight, framerate, bitRate); + audioFramerate = iAudioPort->GetAudioFrameRate(); + + const HBufC* filename = iConfigManager->Filename(); + if(!filename) + { + // no file name has been set + omxError = OMX_ErrorUnsupportedSetting; + break; + } + + delete iMuxer; + iMuxer = NULL; + + TRAPD(error, iMuxer = C3GPMuxer::NewL(iCallbacks)); + if (error != KErrNone) + { + omxError = SymbianErrorToOmx(error); + break; + } + + iMuxer->SetFilename(filename); + iMuxer->SetAudioVideoProperties(frameWidth, frameHeight, framerate, bitRate, audioFramerate); + + break; + } + + case EStateLoaded: + { + delete iMuxer; + iMuxer = NULL; + break; + } + + case EStatePause: + { + iMuxer->Pause(); + break; + } + + default: + { + break; + } + } + + return omxError; + } + +OMX_ERRORTYPE COmxIL3GPMuxerProcessingFunction::BufferFlushingIndication(TUint32 aPortIndex, OMX_DIRTYPE aDirection) + { + DEBUG_PRINTF3(_L8("COmxIL3GPMuxerProcessingFunction::BufferFlushingIndication : aPortIndex[%u]; aDirection[%u]"), aPortIndex, aDirection); + if (aDirection == OMX_DirInput) + { + iMuxer->FlushBuffers(aPortIndex); + } + else + { + return OMX_ErrorBadParameter; + } + + return OMX_ErrorNone; + } + +OMX_ERRORTYPE COmxIL3GPMuxerProcessingFunction::ParamIndication(OMX_INDEXTYPE /*aParamIndex*/, const TAny* /*apComponentParameterStructure*/) + { + DEBUG_PRINTF(_L8("COmxIL3GPMuxerProcessingFunction::ParamIndication")); + return OMX_ErrorNone; + } + +OMX_ERRORTYPE COmxIL3GPMuxerProcessingFunction::ConfigIndication(OMX_INDEXTYPE /*aConfigIndex*/, const TAny* /*apComponentConfigStructure*/) + { + DEBUG_PRINTF(_L8("COmxIL3GPMuxerProcessingFunction::ConfigIndication")); + return OMX_ErrorNone; + } + +OMX_ERRORTYPE COmxIL3GPMuxerProcessingFunction::BufferIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, + OMX_DIRTYPE aDirection) + { + DEBUG_PRINTF2(_L8("COmxIL3GPMuxerProcessingFunction::BufferIndication : aBufferHeader[%X]"), apBufferHeader); + // Check if the previous buffer processing invalidated the Muxer + if (iMuxer->IsMuxerInvalid()) + { + return OMX_ErrorInvalidState; + } + + TUint32 portIndex; + if (aDirection == OMX_DirInput) + { + portIndex = apBufferHeader->nInputPortIndex; + } + else + { + return OMX_ErrorBadParameter; + } + + TRAPD(err, iMuxer->ProcessThisBufferL(apBufferHeader, portIndex)); + return SymbianErrorToOmx(err); + } + +OMX_BOOL COmxIL3GPMuxerProcessingFunction::BufferRemovalIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, OMX_DIRTYPE /*aDirection*/) + { + DEBUG_PRINTF2(_L8("COmxIL3GPMuxerProcessingFunction::BufferRemovalIndication : aBufferHeader[%X]"), apBufferHeader); + if (iMuxer->RemoveBuffer(apBufferHeader)) + { + return OMX_TRUE; + } + + return OMX_FALSE; + } + +void COmxIL3GPMuxerProcessingFunction::SetVideoPort(COmxIL3GPMuxerVideoInputPort& aVideoPort) + { + iVideoPort = &aVideoPort; + } + +void COmxIL3GPMuxerProcessingFunction::SetAudioPort(COmxIL3GPMuxerAudioInputPort& aAudioPort) + { + iAudioPort = &aAudioPort; + } + +OMX_ERRORTYPE COmxIL3GPMuxerProcessingFunction::SymbianErrorToOmx(TInt aError) + { + switch(aError) + { + case KErrNone: + return OMX_ErrorNone; + case KErrNoMemory: + return OMX_ErrorInsufficientResources; + default: + return OMX_ErrorUndefined; + } + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxerprocessingfunction.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxerprocessingfunction.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef COMXIL3GPMUXERPROCESSINGFUNCTION_H +#define COMXIL3GPMUXERPROCESSINGFUNCTION_H + +#include + +// forward class declarations +class COmxIL3GPMuxerConfigManager; +class COmxIL3GPMuxerVideoInputPort; +class COmxIL3GPMuxerAudioInputPort; +class C3GPMuxer; +class C3GPMuxerWriterThreadObserver; + +NONSHARABLE_CLASS(COmxIL3GPMuxerProcessingFunction) : public COmxILProcessingFunction + { +public: + static COmxIL3GPMuxerProcessingFunction* NewL(MOmxILCallbackNotificationIf& aCallbacks); + ~COmxIL3GPMuxerProcessingFunction(); + + void SetConfigManager(COmxIL3GPMuxerConfigManager& aConfigManager); + void SetVideoPort(COmxIL3GPMuxerVideoInputPort& aVideoPort); + void SetAudioPort(COmxIL3GPMuxerAudioInputPort& aAudioPort); + + // from COmxILProcessingFunction + OMX_ERRORTYPE StateTransitionIndication(TStateIndex aNewState); + OMX_ERRORTYPE BufferFlushingIndication(TUint32 aPortIndex, OMX_DIRTYPE aDirection); + OMX_ERRORTYPE ParamIndication(OMX_INDEXTYPE aParamIndex, const TAny* apComponentParameterStructure); + OMX_ERRORTYPE ConfigIndication(OMX_INDEXTYPE aConfigIndex, const TAny* apComponentConfigStructure); + OMX_ERRORTYPE BufferIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, OMX_DIRTYPE aDirection); + OMX_BOOL BufferRemovalIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, OMX_DIRTYPE aDirection); + +private: + COmxIL3GPMuxerProcessingFunction(MOmxILCallbackNotificationIf& aCallbacks); + void ConstructL(); + + OMX_ERRORTYPE SymbianErrorToOmx(TInt aError); + +private: + C3GPMuxer* iMuxer; + COmxIL3GPMuxerConfigManager* iConfigManager; // not owned + COmxIL3GPMuxerVideoInputPort* iVideoPort; // not owned + COmxIL3GPMuxerAudioInputPort* iAudioPort; // not owned + C3GPMuxerWriterThreadObserver* iWriterThreadObserver; + }; + +#endif //COMXIL3GPMUXERPROCESSINGFUNCTION_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxervideoinputport.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxervideoinputport.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,163 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include "comxil3gpmuxervideoinputport.h" +#include "comxil3gpmuxerprocessingfunction.h" +#include "log.h" + +const TUint KDefaultBitRate = 5000; + + + +COmxIL3GPMuxerVideoInputPort* COmxIL3GPMuxerVideoInputPort::NewL(const TOmxILCommonPortData& aCommonPortData) + + { + DEBUG_PRINTF(_L8("COmxIL3GPMuxerVideoInputPort::NewL")); + // TODO these arrays must left empty, to be removed from the video port constructor + RArray supportedCodings; + RArray supportedColorFormats; + CleanupClosePushL(supportedCodings); + CleanupClosePushL(supportedColorFormats); + + COmxIL3GPMuxerVideoInputPort* self = new(ELeave) COmxIL3GPMuxerVideoInputPort(); + CleanupStack::PushL(self); + self->ConstructL(aCommonPortData, supportedCodings, supportedColorFormats); + CleanupStack::Pop(self); + + CleanupStack::PopAndDestroy(2, &supportedCodings); + + return self; + } + +COmxIL3GPMuxerVideoInputPort::COmxIL3GPMuxerVideoInputPort() + { + GetParamPortDefinition().format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + } + +void COmxIL3GPMuxerVideoInputPort::ConstructL(const TOmxILCommonPortData& aCommonPortData, + const RArray& aSupportedCodings, + const RArray& aSupportedColourFormats) + { + COmxILVideoPort::ConstructL(aCommonPortData, aSupportedCodings, aSupportedColourFormats); + // as there are only four items, do not require a sort order + // if this list gets larger consider using binary search + GetSupportedVideoFormats().AppendL(OMX_VIDEO_CodingUnused); + GetSupportedVideoFormats().AppendL(OMX_VIDEO_CodingAVC); + GetSupportedVideoFormats().AppendL(OMX_VIDEO_CodingH263); + GetSupportedVideoFormats().AppendL(OMX_VIDEO_CodingMPEG4); + + GetSupportedColorFormats().AppendL(OMX_COLOR_FormatUnused); + + GetParamPortDefinition().format.video.nBitrate = KDefaultBitRate; + } + +COmxIL3GPMuxerVideoInputPort::~COmxIL3GPMuxerVideoInputPort() + { + } + +OMX_ERRORTYPE COmxIL3GPMuxerVideoInputPort::GetLocalOmxParamIndexes(RArray& aIndexArray) const + { + OMX_ERRORTYPE omxRetValue = COmxILVideoPort::GetLocalOmxParamIndexes(aIndexArray); + if (omxRetValue != OMX_ErrorNone) + { + return omxRetValue; + } + + return OMX_ErrorNone; + } + +OMX_ERRORTYPE COmxIL3GPMuxerVideoInputPort::GetLocalOmxConfigIndexes(RArray& aIndexArray) const + { + return COmxILVideoPort::GetLocalOmxConfigIndexes(aIndexArray); + } + +OMX_ERRORTYPE COmxIL3GPMuxerVideoInputPort::GetParameter(OMX_INDEXTYPE aParamIndex, + TAny* apComponentParameterStructure) const + { + DEBUG_PRINTF2(_L8("COmxIL3GPMuxerVideoInputPort::GetParameter : aParamIndex[%u]"), aParamIndex); + return COmxILVideoPort::GetParameter(aParamIndex, apComponentParameterStructure); + } + +OMX_ERRORTYPE COmxIL3GPMuxerVideoInputPort::SetParameter(OMX_INDEXTYPE aParamIndex, + const TAny* apComponentParameterStructure, + TBool& aUpdateProcessingFunction) + { + DEBUG_PRINTF2(_L8("COmxIL3GPMuxerVideoInputPort::SetParameter : aParamIndex[%u]"), aParamIndex); + return COmxILVideoPort::SetParameter(aParamIndex, apComponentParameterStructure, aUpdateProcessingFunction); + } + +OMX_ERRORTYPE COmxIL3GPMuxerVideoInputPort::SetFormatInPortDefinition(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition, + TBool& aUpdateProcessingFunction) + { + if (aPortDefinition.nBufferCountActual > KMaxVideoBuffers) + { + return OMX_ErrorBadParameter; + } + + const OMX_VIDEO_PORTDEFINITIONTYPE& newVidDef = aPortDefinition.format.video; + OMX_VIDEO_PORTDEFINITIONTYPE& myVidDef = GetParamPortDefinition().format.video; + + if(newVidDef.eColorFormat != OMX_COLOR_FormatUnused) + { + return OMX_ErrorBadParameter; + } + // change to FindInUnsignedKeyOrder if many more formats are added + // FIXME this should allow OMX_VIDEO_CodingAutoDetect + if(GetSupportedVideoFormats().Find(newVidDef.eCompressionFormat) == KErrNotFound) + { + return OMX_ErrorBadParameter; + } + + // copy the new port definition + myVidDef = newVidDef; + + // ignore parameters which make no sense, either because the output is compressed or because + // we are not a display component + myVidDef.nSliceHeight = 0; + myVidDef.nStride = 0; + myVidDef.pNativeRender = NULL; + myVidDef.pNativeWindow = NULL; + + // ignore the MIME type - the field eCompressionFormat will identify the stream type. + // if we want to support GetParameter() for the MIME type, I think the component needs to + // make a copy of the C string passed in and return a pointer to that. (cMIMEType is a char*). + myVidDef.cMIMEType = NULL; + + aUpdateProcessingFunction = ETrue; + + return OMX_ErrorNone; + } + +TBool COmxIL3GPMuxerVideoInputPort::IsTunnelledPortCompatible(const OMX_PARAM_PORTDEFINITIONTYPE& /*aPortDefinition*/) const + { + // TODO (The base class should do this checking) + return ETrue; + } + +void COmxIL3GPMuxerVideoInputPort::GetVideoProperties(OMX_U32& aFrameWidth, OMX_U32& aFrameHeight, OMX_U32& aFramerate, OMX_U32& aBitRate) + { + aFrameWidth = GetParamPortDefinition().format.video.nFrameWidth; + aFrameHeight = GetParamPortDefinition().format.video.nFrameHeight; + aFramerate = GetParamPortDefinition().format.video.xFramerate; + aBitRate = GetParamPortDefinition().format.video.nBitrate; + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxervideoinputport.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxervideoinputport.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef COMXIL3GPMUXERVIDEOINPUTPORT_H +#define COMXIL3GPMUXERVIDEOINPUTPORT_H + +#include + +class COmxIL3GPMuxerProcessingFunction; + +const TInt KMaxVideoBuffers = 20; + +NONSHARABLE_CLASS(COmxIL3GPMuxerVideoInputPort) : public COmxILVideoPort + { +public: + static COmxIL3GPMuxerVideoInputPort* NewL(const TOmxILCommonPortData& aCommonPortData); + ~COmxIL3GPMuxerVideoInputPort(); + + void GetVideoProperties(OMX_U32& aFrameWidth, OMX_U32& aFrameHeight, OMX_U32& aFramerate, OMX_U32& aBitRate); + + // from COmxILVideoPort + OMX_ERRORTYPE GetLocalOmxParamIndexes(RArray& aIndexArray) const; + OMX_ERRORTYPE GetLocalOmxConfigIndexes(RArray& aIndexArray) const; + OMX_ERRORTYPE GetParameter(OMX_INDEXTYPE aParamIndex, + TAny* apComponentParameterStructure) const; + OMX_ERRORTYPE SetParameter(OMX_INDEXTYPE aParamIndex, + const TAny* apComponentParameterStructure, + TBool& aUpdateProcessingFunction); + +protected: + OMX_ERRORTYPE SetFormatInPortDefinition(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition, + TBool& aUpdateProcessingFunction); + TBool IsTunnelledPortCompatible(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition) const; + +private: + COmxIL3GPMuxerVideoInputPort(); + void ConstructL(const TOmxILCommonPortData& aCommonPortData, + const RArray& aSupportedCodings, + const RArray& aSupportedColourFormats); + }; + +#endif //COMXIL3GPMUXERVIDEOINPUTPORT_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/src/endwaitao.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/src/endwaitao.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include "endwaitao.h" +#include +#include "log.h" + +CEndWaitAO* CEndWaitAO::NewL() + { + DEBUG_PRINTF(_L8("CEndWaitAO::NewL")); + CEndWaitAO* self = new(ELeave) CEndWaitAO(); + return self; + } + +CEndWaitAO::CEndWaitAO(): +CAsyncOneShot(EPriorityHigh) + { + } + +CEndWaitAO::~CEndWaitAO() + { + DEBUG_PRINTF(_L8("CEndWaitAO::~CEndWaitAO")); + Cancel(); + } + +void CEndWaitAO::RunL() + { + DEBUG_PRINTF(_L8("CEndWaitAO::RunL")); + CActiveScheduler::Stop(); + } + +void CEndWaitAO::DoCancel() + { + DEBUG_PRINTF(_L8("CEndWaitAO::DoCancel")); + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrCancel); + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/src/endwaitao.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/src/endwaitao.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifndef ENDWAITAO_H_ +#define ENDWAITAO_H_ + +#include + +class CEndWaitAO : public CAsyncOneShot + { +public: + static CEndWaitAO* NewL(); + ~CEndWaitAO(); + +protected: + void RunL(); + void DoCancel(); + +private: + CEndWaitAO(); + + RThread iSchedulerThread; + }; + +#endif /*ENDWAITAO_H_*/ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/src/log.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/src/log.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,150 @@ +/* +* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifndef __SWI_LOG_H__ +#define __SWI_LOG_H__ + +#include +namespace DSD +{ + +#ifdef _DEBUG + +#ifdef _OMXIL_COMMON_DEBUG_TRACING_ON + + + +class TTruncateOverflowHandler16 : public TDes16Overflow + { + public: + virtual void Overflow( TDes16& aDes ); + }; + +inline void TTruncateOverflowHandler16::Overflow( TDes16& aDes) + { + _LIT(KErrOverflowMsg,"Descriptor Overflow, hence value truncated"); + if( aDes.MaxLength() >= KErrOverflowMsg().Length() + aDes.Length() ) + aDes.Append(KErrOverflowMsg); + } + +class TTruncateOverflowHandler8 : public TDes8Overflow + { + public: + virtual void Overflow( TDes8& aDes ); + }; + +inline void TTruncateOverflowHandler8::Overflow( TDes8& aDes) + { + _LIT(KErrOverflowMsg,"Descriptor Overflow, hence value truncated"); + if( aDes.MaxLength() >= KErrOverflowMsg().Length() + aDes.Length() ) + aDes.Append(KErrOverflowMsg); + } + +#define DEBUG_PRINTF(a) {DSD::DebugPrintf(__LINE__, __FILE__, a);} +#define DEBUG_PRINTF2(a, b) {DSD::DebugPrintf(__LINE__, __FILE__, a, b);} +#define DEBUG_PRINTF3(a, b, c) {DSD::DebugPrintf(__LINE__, __FILE__, a, b, c);} +#define DEBUG_PRINTF4(a, b, c, d) {DSD::DebugPrintf(__LINE__, __FILE__, a, b, c, d);} +#define DEBUG_PRINTF5(a, b, c, d, e) {DSD::DebugPrintf(__LINE__, __FILE__, a, b, c, d, e);} + +#define DEBUG_CODE_SECTION(a) TRAP_IGNORE({ a; }) + +// UTF-8 overload of the DebufPrintf method. Should be used by default, +// since it's cheaper both in CPU cycles and stack space. + +inline void DebugPrintf(TInt aLine, char* aFile, TRefByValue aFormat, ...) + { + TTruncateOverflowHandler8 overflowHandler8; + VA_LIST list; + VA_START(list, aFormat); + + TTime now; + now.HomeTime(); + + TBuf8<1024> buffer; + _LIT8(KSwiLogPrefix, "[3gpmuxer] "); + _LIT8(KSwiLineFileFormat, "TID[%d] : [%s:%d] -- "); + buffer.Append(KSwiLogPrefix); + RThread thread; + TUint threadId = thread.Id(); + thread.Close(); + RProcess proc; + TFileName fName = proc.FileName(); + proc.Close(); + buffer.AppendFormat(KSwiLineFileFormat, threadId, aFile, aLine); + buffer.AppendFormatList(aFormat, list ,&overflowHandler8 ); + buffer.Append(_L8("\r\n")); + + RDebug::RawPrint(buffer); + + VA_END(list); + } + +// Unicode DebufPrintf overload + +inline void DebugPrintf(TInt aLine, char* aFile, TRefByValue aFormat, ...) + { + TTruncateOverflowHandler16 overflowHandler16; + VA_LIST list; + VA_START(list, aFormat); + + TTime now; + now.HomeTime(); + + TBuf8<256> header; + _LIT8(KSwiLogPrefix, "[3gpmuxer] "); + _LIT8(KSwiLineFileFormat, "%Ld Line: % 5d, File: %s -- "); + header.Append(KSwiLogPrefix); + header.AppendFormat(KSwiLineFileFormat, now.Int64(), aLine, aFile); + + TBuf<1024> buffer; + buffer.Copy(header); + buffer.AppendFormatList(aFormat, list ,&overflowHandler16); + buffer.Append(_L("\r\n")); + + RDebug::RawPrint(buffer); + + VA_END(list); + } +#else + +#define DEBUG_PRINTF(a) +#define DEBUG_PRINTF2(a, b) +#define DEBUG_PRINTF3(a, b, c) +#define DEBUG_PRINTF4(a, b, c, d) +#define DEBUG_PRINTF5(a, b, c, d, e) + +#define DEBUG_CODE_SECTION(a) + +#endif + +#else + +#define DEBUG_PRINTF(a) +#define DEBUG_PRINTF2(a, b) +#define DEBUG_PRINTF3(a, b, c) +#define DEBUG_PRINTF4(a, b, c, d) +#define DEBUG_PRINTF5(a, b, c, d, e) + +#define DEBUG_CODE_SECTION(a) + +#endif + + +} // namespace DSD + +#endif // __SWI_LOG_H__ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/src/omxil3gpmuxer.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/src/omxil3gpmuxer.hrh Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifndef OMXIL3GPMUXER_HRH_ +#define OMXIL3GPMUXER_HRH_ + +#define KUidSymbianOmxIL3gpMuxerDll 0x10285C33 +#define KUidSymbianOmxIL3gpMuxer 0x10285C34 + +#endif /*OMXIL3GPMUXER_HRH_*/ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxil3gpmuxer/src/omxil3gpmuxer.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxil3gpmuxer/src/omxil3gpmuxer.rss Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include +#include "omxil3gpmuxer.hrh" + +RESOURCE REGISTRY_INFO theInfo + { + dll_uid = KUidSymbianOmxIL3gpMuxerDll; + interfaces = + { + INTERFACE_INFO + { + interface_uid = KUidOmxILSymbianComponentIf; + implementations = + { + IMPLEMENTATION_INFO + { + implementation_uid = KUidSymbianOmxIL3gpMuxer; + version_no = 1; + display_name = "OMX.SYMBIAN.OTHER.CONTAINER_MUXER.3GP"; + default_data = "container_muxer"; + } + }; + } + }; + } + diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/group/bld.inf Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +PRJ_PLATFORMS +BASEDEFAULT + +PRJ_EXPORTS +// The export of the IBY is deliberately not guarded by #ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED so that it +// can always be #included by other IBYs/OBYs. However, if NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED is not defined +// then the IBY will effectively be empty and not include anything in the ROM. + +omxilclock.iby /epoc32/rom/include/omxilclock.iby + +PRJ_MMPFILES +#ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED +omxilclock.mmp +#endif // NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/group/omxilclock.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/group/omxilclock.iby Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +#ifndef OMXILCLOCK_IBY +#define OMXILCLOCK_IBY + +#ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED +ECOM_PLUGIN(omxilclock.dll, omxilclock.rsc) +#endif + +#endif // OMXILCLOCK_IBY diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/group/omxilclock.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/group/omxilclock.mmp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include "../src/omxilclock.hrh" + +TARGET omxilclock.dll +TARGETTYPE PLUGIN +UID 0x10009D8D KUidSymbianOmxILClockDll +CAPABILITY All -TCB + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +USERINCLUDE ../src + +SOURCEPATH ../src + +SOURCE clocksupervisor.cpp +SOURCE comxilclockcomponent.cpp +SOURCE comxilclockconfigmanager.cpp +SOURCE comxilclockoutputport.cpp +SOURCE comxilclockprocessingfunction.cpp +SOURCE clockpanics.cpp +SOURCE clockthreadnotifier.cpp + +START RESOURCE omxilclock.rss +TARGET omxilclock.rsc +END + +LIBRARY euser.lib efsrv.lib ecom.lib +LIBRARY hal.lib +LIBRARY omxilcomponentcommon.lib +STATICLIBRARY omxilcomponentif.lib + +//MACRO _OMXIL_COMMON_DEBUG_TRACING_ON diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/src/clockpanics.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/src/clockpanics.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include "clockpanics.h" +#include + +_LIT(KClockPanicCategory, "omxilclock"); + +void Panic(TClockPanicCode aCode) + { + User::Panic(KClockPanicCategory, aCode); + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/src/clockpanics.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/src/clockpanics.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +/** + @file + @internalComponent + */ + +#ifndef CLOCKPANICS_H_ +#define CLOCKPANICS_H_ + +enum TClockPanicCode + { + EBufferUnderflow = 0, // ran out of buffers with which to issue notifications + /*ERequestOverflow = 1, // NO LONGER USED. previously, too many media time requests to add to pending queue*/ + EBadAlignment = 2, // unexpected pointer alignment + EMutexUnheld = 3, // the mutex was expected to be held but it was not + ERequestQueueCorrupt = 4, // request queue structure in an inconsistent state + ERequestQueueUnordered = 5, // request queue trigger times not in ascending order + EBufferQueueOverflow = 6, // error adding buffer to queue. this shouldn't happen + // as queue is preallocated with total buffer count + ECompatibilityCheckOnOutput = 7, // IsTunnelledPortCompatible() was called on output port which shouldn't happen + EBufferFlushingInvalidPort = 8, // Invalid port index passed to BufferFlushingIndication() routine + ECallbackManagerBufferError = 9, // The callback manager returned an error during BufferDoneNotification, + // this is not expected since the callee component should handle an error internally + ECallbackManagerEventError = 10, // The callback manager returned an error during EventNotification, + // this is not expected since the client should handle an error internally + + EUndefinedErrorCode = 1000 // received an error code that isn't translated (debug builds only) + }; + +void Panic(TClockPanicCode aCode); + +#endif /*CLOCKPANICS_H_*/ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/src/clocksupervisor.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/src/clocksupervisor.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,1668 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +// NOTE: Assumes OMX_SKIP64BIT is not set when building OMX CORE + +#include +#include // OMX port +#include // OMX version number +#include "clocksupervisor.h" +#include "comxilclockprocessingfunction.h" +#include "clockpanics.h" +#include "omxilclock.hrh" + +#include "log.h" + +////////////// +// File scoped constants +// + +/** The maximum number of simultaneous outstanding requests (across all ports) */ +static const TUint KMaxRequests = 20; +static const TUint KThreadStackSize = 1024; + +/** + * Assumption that timer will always take at least this long to complete. + * How soon an outstanding delay must be before we complete immediately instead of setting a timer. + */ +static const TInt KMinTimerOverhead = 1000; // 1000usecs = 1ms + +// assumption that timers go off at some time rounded to this many microseconds +static const TInt KTimerQuantization = +#ifdef __WINSCW__ + 15000; +#else + 1; +#endif + +// aim to select a counter accurate to ~1ms +#ifdef __WINSCW__ +#define USE_FASTCOUNTER // typically faster than 1ms on emulator, 1ms on hardware +#else +#define USE_NTICKCOUNT // typically 5ms on emulator, 1ms on hardware +#endif + +#if !defined(USE_FASTCOUNTER) && !defined(USE_NTICKCOUNT) +#error Either USE_FASTCOUNTER or USE_NTICKCOUNT must be defined +#endif + +/** + * Structure to map OMX_INDEXTYPE to behaviour required by the Clock component. + */ + +// Indexes for time configs start after OMX_IndexTimeStartUnused = 0x09000000 +// Simply deduct this to index this table + +static const OMX_INDEXTYPE KMinJumpTableIndex = OMX_IndexConfigTimeScale; +static const OMX_INDEXTYPE KMaxJumpTableIndex = OMX_IndexConfigTimeClientStartTime; + +const CClockSupervisor::FunctionPtr CClockSupervisor::iJumpTable[] = + { + /*OMX_IndexConfigTimeScale*/ &CClockSupervisor::HandleGetSetTimeScale ,// requires buffers + /*OMX_IndexConfigTimeClockState*/ &CClockSupervisor::HandleGetSetClockState ,// requires buffers + /*OMX_IndexConfigTimeActiveRefClock*/ &CClockSupervisor::HandleGetSetActiveRefClock , + /*OMX_IndexConfigTimeCurrentMediaTime*/ &CClockSupervisor::HandleQueryCurrentMediaTime , + /*OMX_IndexConfigTimeCurrentWallTime*/ &CClockSupervisor::HandleQueryCurrentWallTime , + /*OMX_IndexConfigTimeCurrentAudioReference*/ &CClockSupervisor::HandleUpdateAudioReference , + /*OMX_IndexConfigTimeCurrentVideoReference*/ &CClockSupervisor::HandleUpdateVideoReference , + /*OMX_IndexConfigTimeMediaTimeRequest*/ &CClockSupervisor::HandleSubmitMediaTimeRequest,// requires buffers + /*OMX_IndexConfigTimeClientStartTime*/ &CClockSupervisor::HandleSetPortClientStartTime, + }; + +#ifdef _DEBUG +#define CHECK_DEBUG() DbgCheck() +#else +#define CHECK_DEBUG() +#endif + + +////////////// + + +/** + * Euclid's algorithm. + * Returns the largest common factor of aX and aY. + */ +static TInt LargestCommonFactor(TInt aX, TInt aY) + { + // based on knowledge that lcf(x,0)=x, lcf(x,y)=lcf(y,x) and lcf(x,y)=lcf(y,x%y) + while(aX != 0) + { + aY %= aX; + if(aY == 0) + { + return aX; + } + aX %= aY; + } + return aY; + } + + +/** + * + * + */ +CClockSupervisor* CClockSupervisor::NewL(COmxILClockProcessingFunction& aProcessingFunction) + { + CClockSupervisor* self = new (ELeave) CClockSupervisor(aProcessingFunction); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + + +/** + * + * + */ +void CClockSupervisor::ConstructL() + { + // calculate tick frequency + // +#ifdef USE_FASTCOUNTER + TInt frequency; // tick frequency in Hz + User::LeaveIfError(HAL::Get(HAL::EFastCounterFrequency, frequency)); + // conversion factor from ticks into microseconds + // using a fraction in integer arithmetic + iMicroConvNum = 1000000; + iMicroConvDen = frequency; + TInt countsUp; + User::LeaveIfError(HAL::Get(HAL::EFastCounterCountsUp, countsUp)); + iSystemClockReversed = !countsUp; +#elif defined(USE_NTICKCOUNT) + User::LeaveIfError(HAL::Get(HAL::ENanoTickPeriod, iMicroConvNum)); // tick period in microseconds + iMicroConvDen = 1; +#else +#error +#endif + + // divide out any common factor to reduce chance of overflow + TInt factor = LargestCommonFactor(iMicroConvNum, iMicroConvDen); + iMicroConvNum /= factor; + iMicroConvDen /= factor; + + // wraparound time in microseconds is 2^32 * iMicroConv + // take the heartbeat interval as half of this (i.e shift left by 31 places) to ensure we wake up often enough to implement the carry properly + TUint64 interval = (static_cast(iMicroConvNum) << 31) / iMicroConvDen; + if (interval > KMaxTInt32) + { + iHeartbeatTimerInterval = KMaxTInt32; + } + else + { + iHeartbeatTimerInterval = interval; + } + + // if denominator is a power of 2, use shift instead + // (shifting is faster than division) + if(iMicroConvDen & (iMicroConvDen - 1) == 0) + { + // PRECONDITION: iMicroConvDen = 2^n, iMicroConvShift = 0 + // POSTCONDITION: iMicroConvDen = 1, iMicroConvShift = n + while(iMicroConvDen >= 2) + { + iMicroConvDen >>= 1; + iMicroConvShift++; + } + } + + // Create the locks + User::LeaveIfError(iQueMutex.CreateLocal()); + + // Create the memory block of empty Time requests that make up the free list. + iRequestBlock = new(ELeave) TMediaRequest [iMaxRequests]; + + // zero the fields for peace of mind + Mem::FillZ(iRequestBlock, (sizeof(TMediaRequest)*iMaxRequests)); + + // Initialise the free list + for(TInt requestIndex = 0; requestIndex < iMaxRequests; requestIndex++) + { + // Add all free items with delta 0 + iFreeRequestQue.Add(iRequestBlock+requestIndex, static_cast(0)); + } + + iStartTimes.ReserveL(KNumPorts); + for(TInt portIndex = 0; portIndex < KNumPorts; portIndex++) + { + iStartTimes.Append(0); + } + + __ASSERT_DEBUG(iMaxRequests == iFreeRequestQue.Count(), Panic(ERequestQueueCorrupt)); + + // Create the timer consumer thread + TBuf<19> threadName; + threadName.Format(_L("OmxILClock@%08X"), this); + + // Timer created on creation of the thread as it is thread relative + User::LeaveIfError(iThread.Create(threadName, ThreadEntryPoint, KThreadStackSize, NULL, this)); + + // High priority thread + iThread.SetPriority(EPriorityRealTime); + // start the thread and wait for it to create the timer + TRequestStatus status; + iThread.Rendezvous(status); + iThread.Resume(); + iThreadStarted = ETrue; + User::WaitForRequest(status); + User::LeaveIfError(status.Int()); + } + + +/** + * + * + */ +CClockSupervisor::CClockSupervisor(COmxILClockProcessingFunction& aProcessingFunction) +: iActiveRefClock(OMX_TIME_RefClockAudio), + iMaxRequests(KMaxRequests), + iProcessingFunction(aProcessingFunction) + { + // compile time assertion that fields requiring atomic access are + // 4-byte aligned + __ASSERT_COMPILE((_FOFF(CClockSupervisor, iWallTicks) & 3) == 0); + + // run time assertion that class itself is allocated on a 4-byte boundary + __ASSERT_ALWAYS((reinterpret_cast(this) & 3) == 0, Panic(EBadAlignment)); + + iMediaClockState.nSize = sizeof(iMediaClockState); + iMediaClockState.nVersion = TOmxILSpecVersion(); + iMediaClockState.eState = OMX_TIME_ClockStateStopped; + + iCancelStatus = KRequestPending; + } + +/** + * + * + */ +CClockSupervisor::~CClockSupervisor() + { + // signal the timing thread and wait for it to terminate + if(iThreadStarted) + { + iThreadRunning = EFalse; + TRequestStatus logonStatus; + iThread.Logon(logonStatus); + // Want the thread to terminate ASAP instead of waiting for a media + // time request completion or a wall time heartbeat. Can't cancel the + // timer without duplicating the handle, and that gives + // KErrPermissionDenied. So we use a second TRequestStatus to wake the + // timing thread before the timer completes. + TRequestStatus* cancelStatus = &iCancelStatus; + iThread.RequestComplete(cancelStatus, KErrCancel); + User::WaitForRequest(logonStatus); + } + + if (iRequestBlock) + { + delete[] iRequestBlock; + iRequestBlock = NULL; + } + + iStartTimes.Close(); + iThread.Close(); + iQueMutex.Close(); + } + + +/** + * Timing thread entry point. + */ +TInt CClockSupervisor::ThreadEntryPoint(TAny* aPtr) + { + CClockSupervisor& supervisor = *static_cast(aPtr); + supervisor.iThreadRunning = ETrue; + CTrapCleanup* cleanup = CTrapCleanup::New(); + if(cleanup == NULL) + { + return KErrNoMemory; + } + + // Delegate to object's clock timing routine + TRAPD(err, supervisor.RunTimingThreadL()); + delete cleanup; + return err; + } + + +/** + * + * + */ +void CClockSupervisor::RunTimingThreadL() + { + // Create the timer (thread relative) + User::LeaveIfError(iTimer.CreateLocal()); + // rendezvous with the creating thread as it must be blocked until the timer is created + iThread.Rendezvous(KErrNone); + + // Start the timer loop to enable us to wake up on heart beat or requests + TimerLoop(); + + iTimer.Close(); + } + +/** + * Services media time requests. + */ +void CClockSupervisor::TimerLoop() + { + // Here we are only interested in setting the timer for a request timeout + // or the heart beat. States are taken care of in ConsumeRequests(). + // On shutdown the flag iThreadRunning is set to EFalse and the timer + // completed with KErrCancel or something other than KRequestPending + // Therefore we no longer try to get another request. + + TInt measuredTimerOverhead = KTimerQuantization; + TRequestStatus timerStatus; + + while(iThreadRunning) + { + // Call our consumer function + TInt timeout = ConsumeRequests(); + + // round down sleep based on overhead and quantization of timers + timeout -= timeout % KTimerQuantization; + timeout -= measuredTimerOverhead; + timeout -= KMinTimerOverhead; + + // limit sleep by the heartbeat interval + if(timeout > iHeartbeatTimerInterval) + { + timeout = iHeartbeatTimerInterval; + } + + // Perhaps timeout not positive from ConsumeRequests(), or due to + // rounding down it is no longer positive. In this case we may spin, so + // be careful when setting KTimerQuantization, KMinTimerOverhead and + // KRequestDeltaLimit + if(timeout <= 0) + { + continue; + } + + iQueMutex.Wait(); + TInt64 actualSleepTime = WallTime(); + iQueMutex.Signal(); + iTimer.HighRes(timerStatus, timeout); + // can't cancel iTimer from another thread, instead we use a second + // TRequestStatus to wake up early, then we can cancel the timer in + // this thread. + User::WaitForRequest(timerStatus, iCancelStatus); + + if(iCancelStatus.Int() != KRequestPending) + { + iTimer.Cancel(); + iCancelStatus = KRequestPending; + } + else + { + // update measuredTimerOverhead + iQueMutex.Wait(); + actualSleepTime = WallTime() - actualSleepTime; + iQueMutex.Signal(); + TInt sleepOverhead = (TInt) (actualSleepTime - timeout); + + /* Dampen adjustments to measuredTimerOverhead + * + * measuredTimerOverhead = max(sleepOverhead, + * avg(measuredTimerOverhead, sleepOverhead)) + * + * i.e. immediate increase, gradual decrease + */ + measuredTimerOverhead = (measuredTimerOverhead + sleepOverhead) >> 1; + if(measuredTimerOverhead < sleepOverhead) + { + measuredTimerOverhead = sleepOverhead; + } + } + } + DEBUG_PRINTF(_L("Clock thread shutting down...")); + } + + +/** + * Update the wall clock with the system ticks + * + */ +void CClockSupervisor::UpdateWallTicks() + { + __ASSERT_DEBUG(iQueMutex.IsHeld(), Panic(EMutexUnheld)); + + TUint32 oldLowPart(I64LOW(iWallTicks)); // save lower 32-bits +#ifdef USE_FASTCOUNTER + // Gets the fast iCounter. + // This is the current value of the machine's high resolution timer. + // If a high resolution timer is not available, it uses the millisecond timer instead. + // The freqency of this iCounter can be determined by reading the HAL attribute EFastCounterFrequency. + TUint32 newLowPart(User::FastCounter()); // set lower 32-bits + if(iSystemClockReversed) + { + newLowPart = -newLowPart; + } +#elif defined(USE_NTICKCOUNT) + TUint32 newLowPart(User::NTickCount()); // set lower 32-bits +#else +#error +#endif + TUint32 newHighPart(I64HIGH(iWallTicks)); // save upper 32-bits + + // note: did not use LockedInc() here because: + // We need a critical section to capture the system time and update the wall clock + // at the same time. + // The wall clock is unsigned. + // LockedInc doesn't stop a preemption directly after the test, only during the inc + if (newLowPart < oldLowPart) + { + newHighPart++; + } + + iWallTicks = MAKE_TUINT64(newHighPart,newLowPart); + } + + +/** + * Returns the current wall time in microseconds. + */ +TInt64 CClockSupervisor::WallTime() + { + __ASSERT_DEBUG(iQueMutex.IsHeld(), Panic(EMutexUnheld)); + + UpdateWallTicks(); + + // if power of two use shift (faster than division) + if (iMicroConvDen == 1) + { + return iWallTicks * iMicroConvNum >> iMicroConvShift; + } + return iWallTicks * iMicroConvNum / iMicroConvDen; + } + +/** + * + * + */ +TBool CClockSupervisor::AllStartTimesReported () + { + return !(static_cast(iMediaClockState.nWaitMask)); + } + +/** + * Called when timer expires or is cancelled. + * + */ +TInt CClockSupervisor::ConsumeRequests() + { + // Events are consumed here only in the Running state. + // Waiting events, State change events, etc. are handled elsewhere. + // These are called broadcast events and have a higher priority + // than the request events requested by the clients. + // This function is called by the TimerLoop only. + + // IMPORTANT: every code path through here must result in a call to UpdateWallTicks to ensure + // that 64-bit time is updated correctly (heartbeat interval makes sure ConsumeRequests is called + // often enough). + + // Our event loop - return if stopped but not for pause (keep heart beat going) + if(OMX_TIME_ClockStateStopped != iMediaClockState.eState) + { + // Acquire the mutex + iQueMutex.Wait(); + + // this can be entered from the timer on heartbeat or on a call to a state change. + // Don't want this to happen on a state change! + if (OMX_TIME_ClockStateWaitingForStartTime == iMediaClockState.eState) + { + // We need to check if all clients have reported their start times + if (!AllStartTimesReported()) + { + // Not all reported as yet... + UpdateWallTicks(); + + // Release the mutex + iQueMutex.Signal(); + + // wait until they have! keep heat beat going in case it takes looooong! + return iHeartbeatTimerInterval; + } + else + { + // depending on scale decide which start time to use + CalculateStartTime(); + + // no need to check error, we are in the waiting state + DoTransitionToRunningState(); + + // Now just go and send the iNext request! + } + } + + /////////////////////////////// + // There is a request pending !!! + // + + // check the timeout period against the wall clock to determine if this is a heart beat + + if(iMtc.iScaleQ16 == 0) + { + // do not pop front of the queue because we are effectively paused + UpdateWallTicks(); + + // Release the mutex + iQueMutex.Signal(); + + return iHeartbeatTimerInterval; + } + + // try to pop the next pending request + TInt64 delta; + TBool present = iPendingRequestQue.FirstDelta(delta); + + // Is there nothing there? + if (!present) + { + // Nothing on the queue + // Here because of heart beat + UpdateWallTicks(); + + // Release the mutex + iQueMutex.Signal(); + + return iHeartbeatTimerInterval; + } + + // update the delta against clock + delta -= WallTime(); + + // Some time to go before head of queue should be serviced? + if (delta > KMinTimerOverhead) + { + // Release the mutex + iQueMutex.Signal(); + + return delta; + } + + // Request timed out, delta expired! + // Fulfill the request + TMediaRequest* request = iPendingRequestQue.RemoveFirst(); + + // Acquire fulfillment buffer for a specific port + OMX_BUFFERHEADERTYPE* buffer = iProcessingFunction.AcquireBuffer(request->iPortIndex); + if(buffer == NULL) + { + // starved of buffers! + DEBUG_PRINTF(_L("ConsumeRequests starved of buffers, transitioning to OMX_StateInvalid")); + iThreadRunning = EFalse; + iQueMutex.Signal(); + iProcessingFunction.InvalidateComponent(); + return 0; + } + OMX_TIME_MEDIATIMETYPE* mT = reinterpret_cast(buffer->pBuffer); + buffer->nOffset = 0; + buffer->nFilledLen = sizeof(OMX_TIME_MEDIATIMETYPE); + + mT->nSize = sizeof(OMX_TIME_MEDIATIMETYPE); + mT->nVersion = TOmxILSpecVersion(); + mT->eUpdateType = OMX_TIME_UpdateRequestFulfillment; + mT->nClientPrivate = reinterpret_cast(request->iClientPrivate); + mT->xScale = iMtc.iScaleQ16; + mT->eState = OMX_TIME_ClockStateRunning; + mT->nMediaTimestamp = request->iMediaTime; + mT->nWallTimeAtMediaTime = request->iTriggerWallTime + request->iOffset; + mT->nOffset = mT->nWallTimeAtMediaTime - WallTime(); // could be waiting on buffer b4 this! + +#ifdef _OMXIL_COMMON_DEBUG_TRACING_ON + DEBUG_PRINTF(_L8("CLOCK::ConsumeRequest*******************************OMX_TIME_UpdateRequestFulfillment***VS2")); + TTime t; + t.HomeTime(); + DEBUG_PRINTF2(_L8("CLOCK::ConsumeRequest : t.HomeTime() = %ld"), t.Int64()); + DEBUG_PRINTF2(_L8("CLOCK::ConsumeRequest : Buffer = 0x%X"), mT->nClientPrivate); + DEBUG_PRINTF2(_L8("CLOCK::ConsumeRequest : mT->nMediaTimestamp = %ld"), mT->nMediaTimestamp); +#endif + + iProcessingFunction.SendBuffer(buffer); + + // clear the delta on this now free request + request->iTriggerWallTime = 0; + + // Add element back to the free pool + iFreeRequestQue.Add(request, 0); + + // Release the mutex + iQueMutex.Signal(); + + // Update delta for next request. + // NOTE: we do not know if scale change or not so when we re-enter here + // we should recalculate the delta above and perform the appropriate action. + return 0; + } + else + { + // clock is stopped - sleep for the heartbeat interval + return iHeartbeatTimerInterval; + } + } + +/** + * + * + */ +OMX_ERRORTYPE CClockSupervisor::ProduceRequest(OMX_INDEXTYPE aIndex, TEntryPoint aEntryPoint, TAny* aPassedStructPtr) + { + // Range checking on parameter/config index + if(aIndex < KMinJumpTableIndex || aIndex > KMaxJumpTableIndex) + { + return OMX_ErrorUnsupportedIndex; + } + // Note also that certain combinations on Get/Set within the supported range are unsupported. + // This is left to the function in the jump table. + + // Acquire the mutex + iQueMutex.Wait(); + + // Index the routing table for the correct handler + FunctionPtr jumpTableFptr = iJumpTable[aIndex-KMinJumpTableIndex]; + OMX_ERRORTYPE ret = (this->*jumpTableFptr)(aEntryPoint, aPassedStructPtr); + + // Release the mutex + iQueMutex.Signal(); + + return ret; + } + + +/** + * According to scale, choose the earliest start time among the set of client + * start times. For forward play this is the minimum, for reverse play this is + * the maximum. + */ +void CClockSupervisor::CalculateStartTime() + { + // The nWaitMask field of the Media clock state is a bit mask specifying the client + // components that the clock component will wait on in the + // OMX_TIME_ClockStateWaitingForStartTime state. Bit masks are defined + // as OMX_CLOCKPORT0 through OMX_CLOCKPORT7. + + // Based on scale locate the minimum or maximum start times of all clients + TInt64 startTime; + + if (iMtc.iScaleQ16 >= 0) + { + startTime = KMaxTInt64; + + // choose minimum + for (TInt portIndex = 0; portIndex < iStartTimes.Count(); portIndex++) + { + if(iStartTimesSet & (1 << portIndex)) + { + startTime = Min(startTime, iStartTimes[portIndex]); + } + } + } + else + { + startTime = KMinTInt64; + + // choose maximum + for (TInt portIndex = 0; portIndex < iStartTimes.Count(); portIndex++) + { + if(iStartTimesSet & (1 << portIndex)) + { + startTime = Max(startTime, iStartTimes[portIndex]); + } + } + } + + // adjust the media time to the new start time + UpdateMediaTime(startTime); + } + + +/** + * Perform actions related to placing the clock into the Stopped state + */ +void CClockSupervisor::DoTransitionToStoppedState() + { + // OMX_TIME_ClockStateStopped: Immediately stop the media clock, clear all + // pending media time requests, clear all client start times, and transition to the + // stopped state. This transition is valid from all other states. + + // We should already have the mutex! + __ASSERT_DEBUG(iQueMutex.IsHeld(), Panic(EMutexUnheld)); + + // clear any current start time + iMediaClockState.nStartTime = 0; + iMediaClockState.nWaitMask = 0; + + // clear client start times + for(TInt index = 0, count = iStartTimes.Count(); index < count; index++) + { + iStartTimes[index] = 0; + } + iStartTimesSet = 0; + + // clear all pending requests, placing them back on the free queue + while (!iPendingRequestQue.IsEmpty()) + { + TMediaRequest* request = iPendingRequestQue.RemoveFirst(); + + // clear the delta on this now free request + request->iTriggerWallTime = 0; + + iFreeRequestQue.Add(request,0); + } + + TInt64 wallTimeNow = WallTime(); + + // if clock was previously running, stop the media time at the present value + if(iMediaClockState.eState == OMX_TIME_ClockStateRunning) + { + TInt64 mediaTimeNow = ((wallTimeNow - iMtc.iWallTimeBase) * iMtc.iScaleQ16 >> 16) + iMtc.iMediaTimeBase; + iMtc.iWallTimeBase = wallTimeNow; + iMtc.iMediaTimeBase = mediaTimeNow; + } + + // Indicate stopped state + iMediaClockState.eState = OMX_TIME_ClockStateStopped; + + // Indicate to clients a state change + OMX_TIME_MEDIATIMETYPE update; + update.nSize = sizeof(OMX_TIME_MEDIATIMETYPE); + update.nVersion = TOmxILSpecVersion(); + update.nClientPrivate = NULL; + update.eUpdateType = OMX_TIME_UpdateClockStateChanged; + update.xScale = iMtc.iScaleQ16; + update.eState = OMX_TIME_ClockStateStopped; + update.nMediaTimestamp = iMtc.iMediaTimeBase; + update.nWallTimeAtMediaTime = wallTimeNow; + update.nOffset = 0; + + BroadcastUpdate(update); + } + + +/** + * Perform actions related to placing the clock into the Running state + */ +void CClockSupervisor::DoTransitionToRunningState() + { + // OMX_TIME_ClockStateRunning: Immediately start the media clock using the given + // start time and offset, and transition to the running state. This transition is valid from + // all other states. + + // We should already have the mutex! + __ASSERT_DEBUG(iQueMutex.IsHeld(), Panic(EMutexUnheld)); + + // if we transistioned from stopped to running then start time will be cleared. + // we only set it on transition from waiting to running + // this is enforced not by a check but by logic flow! + // If this is not the case then start time should have been cleared and we can start now! + + // Indicate running state + iMediaClockState.eState = OMX_TIME_ClockStateRunning; + + // Indicate to clients a state change + OMX_TIME_MEDIATIMETYPE update; + update.nSize = sizeof(OMX_TIME_MEDIATIMETYPE); + update.nVersion = TOmxILSpecVersion(); + update.nClientPrivate = NULL; + update.eUpdateType = OMX_TIME_UpdateClockStateChanged; + update.xScale = iMtc.iScaleQ16; + update.eState = iMediaClockState.eState; + update.nMediaTimestamp = iMtc.iMediaTimeBase; + update.nWallTimeAtMediaTime = iMtc.iWallTimeBase; + update.nOffset = 0; + + BroadcastUpdate(update); + } + +/** + * Perform actions related to placing the clock into the Waiting state + */ +void CClockSupervisor::DoTransitionToWaitingState(OMX_U32 nWaitMask) + { + // OMX_TIME_WaitingForStartTime: Transition immediately to the waiting state, wait + // for all clients specified in nWaitMask to report their start time, start the media clock + // using the minimum of all client start times and transition to + // OMX_TIME_ClockStateRunning. This transition is only valid from the + // OMX_TIME_ClockStateStopped state. + // (*Added*) If in the backwards direction start the media clock using the maximum + // of all client start times. + + // validity of state transition has been checked in HandleGetSetClockState() + + // We should already have the mutex! + __ASSERT_DEBUG(iQueMutex.IsHeld(), Panic(EMutexUnheld)); + + iMediaClockState.eState = OMX_TIME_ClockStateWaitingForStartTime; + + // Start times set in calling function HandleClientStartTime() + + // Remember all clients that need to report their start times + iMediaClockState.nWaitMask = nWaitMask; + + // Indicate to clients a state change + OMX_TIME_MEDIATIMETYPE update; + update.nSize = sizeof(OMX_TIME_MEDIATIMETYPE); + update.nVersion = TOmxILSpecVersion(); + update.nClientPrivate = NULL; + update.eUpdateType = OMX_TIME_UpdateClockStateChanged; + update.xScale = iMtc.iScaleQ16; + update.eState = OMX_TIME_ClockStateWaitingForStartTime; + update.nMediaTimestamp = iMtc.iMediaTimeBase; + update.nWallTimeAtMediaTime = WallTime(); + update.nOffset = 0; + + BroadcastUpdate(update); + } + + + /** + * Update the wall clock with the system ticks + * + */ + OMX_ERRORTYPE CClockSupervisor::HandleSubmitMediaTimeRequest(TEntryPoint aEntry, OMX_PTR aPassedStructPtr) + { + // We should already have the mutex! + __ASSERT_DEBUG(iQueMutex.IsHeld(), Panic(EMutexUnheld)); + + // A client requests the transmission of a particular timestamp via OMX_SetConfig on its + // clock port using the OMX_IndexConfigTimeMediaTimeRequest configuration + // and structure OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE + + // OMX_GetConfig doesn't make any sense for MediaTimeRequest + if(aEntry == EGetConfig) + { + return OMX_ErrorUnsupportedIndex; + } + + TMediaRequest *request = iFreeRequestQue.RemoveFirst(); + if(request == NULL) + { + // too many pending requests! + return OMX_ErrorInsufficientResources; + } + + OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE* rT = static_cast(aPassedStructPtr); + + request->iMediaTime = rT->nMediaTimestamp; + request->iOffset = rT->nOffset; + request->iTriggerWallTime = + ((rT->nMediaTimestamp - iMtc.iMediaTimeBase) * iMtc.iInverseScaleQ16 >> 16) + + iMtc.iWallTimeBase - rT->nOffset; + request->iPortIndex = rT->nPortIndex; + request->iClientPrivate = rT->pClientPrivate; + + TInt64 prevHeadTime(0); + TBool nonEmpty = iPendingRequestQue.FirstDelta(prevHeadTime); + iPendingRequestQue.Add(request, request->iTriggerWallTime); + // Wake the thread immediately if head of queue now will complete sooner + // than it would have previously, or if the queue was empty previously. + // This causes the timing thread to recalculate the sleep time. + if(!nonEmpty || prevHeadTime > request->iTriggerWallTime) + { + TRequestStatus* status = &iCancelStatus; + iThread.RequestComplete(status, KErrCancel); + } + return OMX_ErrorNone; + } + + + /** + * + * + */ + OMX_ERRORTYPE CClockSupervisor::HandleQueryCurrentWallTime(TEntryPoint aEntry, OMX_PTR aPassedStructPtr) + { + // An IL client may query the current wall time via OMX_GetConfig on OMX_IndexConfigTimeCurrentWallTime. + // A client may obtain the current wall time, which is obtained via OMX_GetConfig on + // OMX_IndexConfigTimeCurrentWallTime. + + // OMX_SetConfig doesn't make sense for wall time + if(aEntry == ESetConfig) + { + return OMX_ErrorUnsupportedIndex; + } + + // We should already have the mutex! + __ASSERT_DEBUG(iQueMutex.IsHeld(), Panic(EMutexUnheld)); + + OMX_TIME_CONFIG_TIMESTAMPTYPE& wallTs = *static_cast(aPassedStructPtr); + wallTs.nTimestamp = WallTime(); + return OMX_ErrorNone; + } + + +/** + * Calculates and returns the current media time. + */ +OMX_ERRORTYPE CClockSupervisor::HandleQueryCurrentMediaTime(TEntryPoint aEntry, OMX_PTR aPassedStructPtr) + { + // The clock component can be queried for the current media clock time using + // OMX_GetConfig with the read-only index OMX_IndexConfigTimeCurrentMediaTime and structure + // OMX_TIME_CONFIG_TIMESTAMPTYPE. + + // OMX_SetConfig cannot be used for Media Time (audio or video reference updates are used instead) + if(aEntry == ESetConfig) + { + return OMX_ErrorUnsupportedIndex; + } + + // We should already have the mutex! + __ASSERT_DEBUG(iQueMutex.IsHeld(), Panic(EMutexUnheld)); + + OMX_TIME_CONFIG_TIMESTAMPTYPE* ts = static_cast(aPassedStructPtr); + if(iMediaClockState.eState == OMX_TIME_ClockStateRunning) + { + ts->nTimestamp = ((WallTime() - iMtc.iWallTimeBase) * iMtc.iScaleQ16 >> 16) + iMtc.iMediaTimeBase; + } + else + { + ts->nTimestamp = iMtc.iMediaTimeBase; + } + return OMX_ErrorNone; + } + +/** + * An external component is providing an Audio reference time update. + */ +OMX_ERRORTYPE CClockSupervisor::HandleUpdateAudioReference(TEntryPoint aEntry, OMX_PTR aPassedStructPtr) + { + // The clock component can accept an audio reference clock. + // The reference clock tracks the media time at its associated component + // (i.e., the timestamp of the data currently being processed at that component) + // and provides periodic references to the clock component via OMX_SetConfig + // using OMX_IndexConfigTimeCurrentAudioReference, and structure OMX_TIME_CONFIG_TIMESTAMPTYPE + // + // When the clock component receives a reference, it updates its internally maintained + // media time with the reference. This action synchronizes the clock component with the + // component that is providing the reference clock. + + // OMX_GetConfig not supported on reference time as it will generally be + // some arbitary time in the past + if(aEntry == EGetConfig) + { + return OMX_ErrorUnsupportedIndex; + } + + // We should already have the mutex! + __ASSERT_DEBUG(iQueMutex.IsHeld(), Panic(EMutexUnheld)); + + if(iActiveRefClock == OMX_TIME_RefClockAudio) + { + OMX_TIME_CONFIG_TIMESTAMPTYPE* ts = static_cast(aPassedStructPtr); + UpdateMediaTime(ts->nTimestamp); + } + + return OMX_ErrorNone; + } + +/** + * An external component is providing a Video reference time update. + */ +OMX_ERRORTYPE CClockSupervisor::HandleUpdateVideoReference(TEntryPoint aEntry, OMX_PTR aPassedStructPtr) + { + // The clock component can accept a video reference clock. + // The reference clock tracks the media time at its associated component + // (i.e., the timestamp of the data currently being processed at that component) + // and provides periodic references to the clock component via OMX_SetConfig + // using OMX_IndexConfigTimeCurrentVideoReference, and structure OMX_TIME_CONFIG_TIMESTAMPTYPE + // + // When the clock component receives a reference, it updates its internally maintained + // media time with the reference. This action synchronizes the clock component with the + // component that is providing the reference clock. + + // OMX_GetConfig not supported on reference time as it will generally be + // some arbitary time in the past + if(aEntry == EGetConfig) + { + return OMX_ErrorUnsupportedIndex; + } + + // We should already have the mutex! + __ASSERT_DEBUG(iQueMutex.IsHeld(), Panic(EMutexUnheld)); + + if(iActiveRefClock == OMX_TIME_RefClockVideo) + { + OMX_TIME_CONFIG_TIMESTAMPTYPE* ts = static_cast(aPassedStructPtr); + UpdateMediaTime(ts->nTimestamp); + } + + return OMX_ErrorNone; + } + + /** + * + * + */ + OMX_ERRORTYPE CClockSupervisor::HandleSetPortClientStartTime(TEntryPoint aEntry, OMX_PTR aPassedStructPtr) + { + // We should already have the mutex! + __ASSERT_DEBUG(iQueMutex.IsHeld(), Panic(EMutexUnheld)); + + // When a clock component client receives a buffer with flag OMX_BUFFERFLAG_STARTTIME set, + // it performs an OMX_SetConfig call with OMX_IndexConfigTimeClientStartTime + // on the clock component that is sending the buffer’s timestamp. + // The transmission of the start time informs the clock component that the client’s stream + // is ready for presentation and the timestamp of the first data to be presented. + // + // If the IL client requests a transition to OMX_TIME_ClockStateWaitingForStartTime, it + // designates which clock component clients to wait for. The clock component then waits + // for these clients to send their start times via the + // OMX_IndexConfigTimeClientStartTime configuration. Once all required + // clients have responded, the clock component starts the media clock using the earliest + // client start time. + // + // When a client is sent a start time (i.e., the timestamp of a buffer marked with the + // OMX_BUFFERFLAG_STARTTIME flag ), it sends the start time to the clock component + // via OMX_SetConfig on OMX_IndexConfigTimeClientStartTime. This + // action communicates to the clock component the following information about the client’s + // data stream: + // - The stream is ready. + // - The starting timestamp of the stream + + // TODO Perhaps OMX_GetConfig can be done for client start time, after all + // the start times on each port have been stored. But for now this is not + // supported. + if(aEntry == EGetConfig) + { + return OMX_ErrorUnsupportedIndex; + } + + if(iMediaClockState.eState != OMX_TIME_ClockStateWaitingForStartTime) + { + return OMX_ErrorIncorrectStateOperation; + } + + OMX_TIME_CONFIG_TIMESTAMPTYPE* state = static_cast(aPassedStructPtr); + iMediaClockState.nWaitMask &= ~(1 << state->nPortIndex); // switch off bit + iStartTimesSet |= 1 << state->nPortIndex; // switch on bit + iStartTimes[state->nPortIndex] = state->nTimestamp; + + if(iMediaClockState.nWaitMask == 0) + { + // cancel timer so transition occurs immediately instead of waiting for a heartbeat + TRequestStatus* cancelStatus = &iCancelStatus; + iThread.RequestComplete(cancelStatus, KErrCancel); + } + + return OMX_ErrorNone; + } + +/** + * Sets the current media time to the specified value. + */ +void CClockSupervisor::UpdateMediaTime(TInt64 aMediaTime) + { +#ifdef _OMXIL_COMMON_DEBUG_TRACING_ON + OMX_TIME_CONFIG_TIMESTAMPTYPE ts; + HandleQueryCurrentMediaTime(EGetConfig, &ts); + DEBUG_PRINTF4(_L8("Clock::UpdateMediaTime=[%ld]currentmediaTime=<%d> MediaTime <%ld>"), ts.nTimestamp-aMediaTime,ts.nTimestamp, aMediaTime); +#endif // _OMXIL_COMMON_DEBUG_TRACING_ON + iMtc.iWallTimeBase = WallTime(); + iMtc.iMediaTimeBase = aMediaTime; + iPendingRequestQue.RecalculateAndReorder(iMtc); + + TRequestStatus* status = &iCancelStatus; + iThread.RequestComplete(status, KErrCancel); + } + + /** + * + * + */ + OMX_ERRORTYPE CClockSupervisor::HandleGetSetTimeScale(TEntryPoint aEntry, OMX_PTR aPassedStructPtr) + { + // The IL client queries and sets the media clock’s scale via the + // OMX_IndexConfigTimeScale configuration, passing structure + // OMX_TIME_CONFIG_SCALETYPE + + // We should already have the mutex! + __ASSERT_DEBUG(iQueMutex.IsHeld(), Panic(EMutexUnheld)); + + OMX_TIME_CONFIG_SCALETYPE* sT = static_cast(aPassedStructPtr); + + if (EGetConfig == aEntry) + { + sT->xScale = iMtc.iScaleQ16; + } + else + { // ESetConfig + + if(sT->xScale == iMtc.iScaleQ16) + { + // do not broadcast update if the scale changed to the same value + // IL client causes the scale change but only IL components receive the notification + return OMX_ErrorNone; + } + iMtc.SetScaleQ16(sT->xScale, WallTime()); + + // Reorder before sending notifications + iPendingRequestQue.RecalculateAndReorder(iMtc); + + // Indicate to clients a scale change + // The buffer payload is written here then copied to all clients' buffers + // It should be noted that as this is happening across all ports, time can pass + // making nMediaTimestamp and nWallTimeAtMediaTime inaccurate. Since at present we do + // not recover buffer exhaustion scenarios, it is assumed that the messaging time is short + // thus we do not recalculate the time. + + OMX_TIME_MEDIATIMETYPE update; + update.nSize = sizeof(OMX_TIME_MEDIATIMETYPE); + update.nVersion = TOmxILSpecVersion(); + update.nClientPrivate = NULL; + update.eUpdateType = OMX_TIME_UpdateScaleChanged; + update.xScale = iMtc.iScaleQ16; + update.eState = iMediaClockState.eState; + update.nMediaTimestamp = iMtc.iMediaTimeBase; + update.nWallTimeAtMediaTime = iMtc.iWallTimeBase; + update.nOffset = 0; + + BroadcastUpdate(update); + + // Signal the Timer thread as it may need to fulfill all requests on a direction change, + // of fulfill some requests as we have moved forward in time + TRequestStatus* cancelStatus = &iCancelStatus; + iThread.RequestComplete(cancelStatus, KErrCancel); + //****************************************** + } + return OMX_ErrorNone; + } + + + /** + * + * + */ + OMX_ERRORTYPE CClockSupervisor::HandleGetSetClockState(TEntryPoint aEntry, OMX_PTR aPassedStructPtr) + { + // An OMX_GetConfig execution using index OMX_IndexConfigTimeClockState + // and structure OMX_TIME_CONFIG_CLOCKSTATETYPE queries the current clock state. + // An OMX_SetConfig execution using index OMX_IndexConfigTimeClockState + // and structure OMX_TIME_CONFIG_CLOCKSTATETYPE commands the clock + // component to transition to the given state, effectively providing the IL client a + // mechanism for starting and stopping the media clock. + // + // Upon receiving OMX_SetConfig from the IL client that requests a transition to the + // given state, the clock component will do the following: + // + // - OMX_TIME_ClockStateStopped: Immediately stop the media clock, clear all + // pending media time requests, clear and all client start times, and transition to the + // stopped state. This transition is valid from all other states. + // + // - OMX_TIME_ClockStateRunning: Immediately start the media clock using the given + // start time and offset, and transition to the running state. This transition is valid from + // all other states. + // + // - OMX_TIME_WaitingForStartTime: Transition immediately to the waiting state, wait + // for all clients specified in nWaitMask to report their start time, start the media clock + // using the minimum of all client start times and transition to + // OMX_TIME_ClockStateRunning. This transition is only valid from the + // OMX_TIME_ClockStateStopped state. + + // We should already have the mutex! + __ASSERT_DEBUG(iQueMutex.IsHeld(), Panic(EMutexUnheld)); + + OMX_ERRORTYPE ret = OMX_ErrorNone; + + OMX_TIME_CONFIG_CLOCKSTATETYPE* const &clkState + = static_cast(aPassedStructPtr); + + if (ESetConfig == aEntry) + { + if (iMediaClockState.eState == clkState->eState) + { + // Already in this state! + return OMX_ErrorSameState; + } + if (clkState->eState != OMX_TIME_ClockStateStopped && + clkState->eState != OMX_TIME_ClockStateWaitingForStartTime && + clkState->eState != OMX_TIME_ClockStateRunning) + { + return OMX_ErrorUnsupportedSetting; + } + + // need buffers to notify clock state changes, so require to be in Executing + if(!iProcessingFunction.IsExecuting()) + { + return OMX_ErrorIncorrectStateOperation; + } + + switch (clkState->eState) + { + case OMX_TIME_ClockStateStopped: + { + DoTransitionToStoppedState(); + break; + } + case OMX_TIME_ClockStateWaitingForStartTime: + { + // Can't go into this state from Running state + if (OMX_TIME_ClockStateRunning == iMediaClockState.eState) + { + ret = OMX_ErrorIncorrectStateTransition; + break; + } + // Waiting for no ports makes no sense. Also don't allow wait on ports we don't have. + if (clkState->nWaitMask == 0 || clkState->nWaitMask >= 1 << KNumPorts) + { + ret = OMX_ErrorUnsupportedSetting; + break; + } + DoTransitionToWaitingState(clkState->nWaitMask); + break; + } + case OMX_TIME_ClockStateRunning: + { + // set media time to that passed by the IL client + iMtc.iWallTimeBase = WallTime(); + iMtc.iMediaTimeBase = clkState->nStartTime; + // changed time base so pending trigger wall times may be different + iPendingRequestQue.RecalculateAndReorder(iMtc); + DoTransitionToRunningState(); + // wake the timer thread to reset timer or service pending updates + TRequestStatus* statusPtr = &iCancelStatus; + iThread.RequestComplete(statusPtr, KErrCancel); + + break; + } + // default condition already checked before Executing test + } + } + else + { + clkState->eState = iMediaClockState.eState; + } + + return ret; + } + + /** + * + * + */ + OMX_ERRORTYPE CClockSupervisor::HandleGetSetActiveRefClock(TEntryPoint aEntry, OMX_PTR aPassedStructPtr) + { + // The IL client controls which reference clock the clock component uses (if any) via the + // OMX_IndexConfigTimeActiveRefClock configuration and structure OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE + + // don't need the mutex here as just getting/setting one machine word + + OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE& ref = *static_cast(aPassedStructPtr); + + if (ESetConfig == aEntry) + { + if (ref.eClock != OMX_TIME_RefClockAudio && + ref.eClock != OMX_TIME_RefClockVideo && + ref.eClock != OMX_TIME_RefClockNone) + { + return OMX_ErrorUnsupportedSetting; + } + iActiveRefClock = ref.eClock; + } + else // EGetConfig + { + ref.eClock = iActiveRefClock; + } + return OMX_ErrorNone; + } + +void CClockSupervisor::BroadcastUpdate(const OMX_TIME_MEDIATIMETYPE& aUpdate) + { + // notify state change on all enabled ports + for(TInt portIndex = 0; portIndex < KNumPorts; portIndex++) + { + if(iProcessingFunction.PortEnabled(portIndex)) + { + OMX_BUFFERHEADERTYPE* buffer = iProcessingFunction.AcquireBuffer(portIndex); + if(buffer == NULL) + { + // starved of buffers! + iThreadRunning = EFalse; + iProcessingFunction.InvalidateComponent(); + return; + } + OMX_TIME_MEDIATIMETYPE& mT = *reinterpret_cast(buffer->pBuffer); + mT = aUpdate; + buffer->nOffset = 0; + buffer->nFilledLen = sizeof(OMX_TIME_MEDIATIMETYPE); + iProcessingFunction.SendBuffer(buffer); + } + } + } + +void CClockSupervisor::ReportClockThreadPanic() + { + iThreadRunning = EFalse; + iProcessingFunction.InvalidateComponent(); + } +/** + * Adjusts the media time scale. + * The wall/media time bases are updated so there is no instantaneous change to media time. + * iInverseScaleQ16 is also recalculated. + */ +void TMediaTimeContext::SetScaleQ16(TInt32 aScaleQ16, TInt64 aWallTimeNow) + { + TInt64 mediaTimeNow = ((aWallTimeNow - iWallTimeBase) * iScaleQ16 >> 16) + iMediaTimeBase; + iWallTimeBase = aWallTimeNow; + iMediaTimeBase = mediaTimeNow; + iScaleQ16 = aScaleQ16; + + // calculate inverse scale + // 1.0/scale in Q16 format becomes 2^32/scaleQ16 + // values of -1 and +1 will cause overflow and are clipped + // division by zero also yields KMaxTInt (2^31 - 1) + if(iScaleQ16 == 0 || iScaleQ16 == 1) + { + iInverseScaleQ16 = 0x7FFFFFFF; + } + else if(iScaleQ16 == -1) + { + iInverseScaleQ16 = 0x80000000; + } + else + { + iInverseScaleQ16 = static_cast(0x100000000LL / iScaleQ16); + } + } + + +TRequestDeltaQue::TRequestDeltaQue() + : iHead(0), + iCount(0) + { + // do nothing + } + + void TRequestDeltaQue::Add(TMediaRequest* aElement, TInt64 aDelta) + { + CHECK_DEBUG(); + + __ASSERT_DEBUG(((iHead == NULL && iCount == 0) || (iHead != NULL && iCount > 0)), + Panic(ERequestQueueCorrupt)); + + if (!iHead) + { + iHead = aElement; + aElement->iPrev = aElement; + aElement->iNext = aElement; + } + else // set the new element links + { + TBool front(EFalse); + TMediaRequest* item(NULL); + front = InsertBeforeFoundPosition (aDelta, item); + + if (front) + { + // insert infront BEFORE as we have the lesser delta + // set up the element + aElement->iPrev = item->iPrev; + aElement->iNext = item; + + // set up the item before in the list + item->iPrev->iNext = aElement; + + // set up the item after in the list + item->iPrev = aElement; + + // setup the new head + iHead = aElement; + } + else + { + // insert this element AFTER the item in the list + // set up the element + aElement->iPrev = item; + aElement->iNext = item->iNext; + + // set up the item before in the list + item->iNext = aElement; + + // set up the item after in the list + aElement->iNext->iPrev = aElement; + } + } + iCount++; + +#ifdef _OMXIL_COMMON_DEBUG_TRACING_ON + // print the trigger times in debug mode + DbgPrint(); +#endif + + CHECK_DEBUG(); + } + + TBool TRequestDeltaQue::InsertBeforeFoundPosition(TInt64 aDelta, TMediaRequest*& aItem) const + { + CHECK_DEBUG(); + + __ASSERT_DEBUG(((iHead == NULL && iCount == 0) || (iHead != NULL && iCount > 0)), + Panic(ERequestQueueCorrupt)); + + // search for the position where to insert + // and insert after this + + aItem = iHead->iPrev; // tail + + // start from the end and linearly work backwards + while (aItem->iTriggerWallTime > aDelta && aItem != iHead) + { + aItem = aItem->iPrev; + } + + // indicates that we insert before the item and not after it + if (aItem == iHead && aItem->iTriggerWallTime > aDelta) + { + return ETrue; + } + + // no CHECK_DEBUG required as this method is const + + return EFalse; + } + +/** + * If scale changes, the iTriggerWallTimes must be recalculated. + * + * In addition, because offset is not affected by scale, it is possible for + * the order of the elements to change. This event is assumed to be rare, and + * when it does occur we expect the list to remain 'roughly sorted' requiring + * few exchanges. + * + * So we choose ** bubble sort **. + * + * Time recalculation is merged with the first pass of bubble sort. Times are + * recalculated in the first iteration only. Swaps can occur as necessary in + * all iterations. We expect that in most cases there will only be one pass + * with no swaps. + * + * Note that bubble sort would be worst-case complexity if reversing the list + * due to a time direction change. In such cases future requests complete + * immediately (because they are now in the past). So we do not sort at at all + * in this case. + */ + void TRequestDeltaQue::RecalculateAndReorder(TMediaTimeContext& aMtc) + { + CHECK_DEBUG(); + + __ASSERT_DEBUG(((iHead == NULL && iCount == 0) || (iHead != NULL && iCount > 0)), + Panic(ERequestQueueCorrupt)); + + if(iCount == 0) + { + // nothing to do + return; + } + // note if there is 1 item there is no reorder but we do need to recalculate + + TBool swapped(EFalse); + TBool deltaCalculated(EFalse); + + do + { + // start from end of queue + swapped = EFalse; + TMediaRequest* item(iHead->iPrev); // tail + + if (!deltaCalculated) + { + // calculate the tails new delta + item->iTriggerWallTime = + ((item->iMediaTime - aMtc.iMediaTimeBase) * aMtc.iInverseScaleQ16 >> 16) + + aMtc.iWallTimeBase - item->iOffset; + } + + while (item != iHead) + { + TMediaRequest* swap = item->iPrev; + if (!deltaCalculated) + { + // recalculate the Prev item delta + swap->iTriggerWallTime = + ((swap->iMediaTime - aMtc.iMediaTimeBase) * aMtc.iInverseScaleQ16 >> 16) + + aMtc.iWallTimeBase - swap->iOffset; + } + + if (swap->iTriggerWallTime > item->iTriggerWallTime) + { + // switch (swap, item) for (item, swap) + item->Deque(); + item->AddBefore(swap); + if(swap == iHead) + { + iHead = item; + } + + swapped = ETrue; + } + else + { + // move along list + item = item->iPrev; + } + + } // while + + // after the first pass of the queue, all deltas calculated + deltaCalculated = ETrue; + + } while (swapped); + +#ifdef _OMXIL_COMMON_DEBUG_TRACING_ON + DbgPrint(); +#endif + + CHECK_DEBUG(); + } + + + TMediaRequest* TRequestDeltaQue::RemoveFirst() + { + CHECK_DEBUG(); + + __ASSERT_DEBUG(((iHead == NULL && iCount == 0) || (iHead != NULL && iCount > 0)), + Panic(ERequestQueueCorrupt)); + + TMediaRequest* item = NULL; + + // empty? + if (!iHead) + { + return NULL; + } + else + // only one element? + if (1 == iCount) + { + item = iHead; + iHead = NULL; + } + else + { + item = iHead; + item->iPrev->iNext = item->iNext; + item->iNext->iPrev = item->iPrev; + + // setup the new head + iHead = item->iNext; + } + + iCount--; + + CHECK_DEBUG(); + + return item; + } + + TBool TRequestDeltaQue::FirstDelta(TInt64& aDelta) const + { + CHECK_DEBUG(); + + __ASSERT_DEBUG(((iHead == NULL && iCount == 0) || (iHead != NULL && iCount > 0)), + Panic(ERequestQueueCorrupt)); + + if (!iHead) + { + return EFalse; + } + + aDelta = iHead->iTriggerWallTime; + return ETrue; + } + + TBool TRequestDeltaQue::IsEmpty() const + { + __ASSERT_DEBUG(((iHead == NULL && iCount == 0) || (iHead != NULL && iCount > 0)), + Panic(ERequestQueueCorrupt)); + + return (!iHead); + } + + TUint TRequestDeltaQue::Count() const + { + return iCount; + } + +void TMediaRequest::Deque() + { + iPrev->iNext = iNext; + iNext->iPrev = iPrev; + } + +void TMediaRequest::AddBefore(TMediaRequest* x) + { + x->iPrev->iNext = this; + iPrev = x->iPrev; + iNext = x; + x->iPrev = this; + } + +#ifdef _DEBUG + + /** + * Checks the linked list for consistency. + */ + void TRequestDeltaQue::DbgCheck() const + { + if(iCount == 0) + { + __ASSERT_DEBUG(iHead == NULL, Panic(ERequestQueueCorrupt)); + } + else + { + TMediaRequest* last = iHead; + TInt index = iCount - 1; + while(index-- > 0) + { + TMediaRequest* current = last->iNext; + __ASSERT_DEBUG(current->iPrev == last, Panic(ERequestQueueCorrupt)); + __ASSERT_DEBUG(current->iTriggerWallTime >= last->iTriggerWallTime, Panic(ERequestQueueUnordered)); + last = current; + } + __ASSERT_DEBUG(last->iNext == iHead, Panic(ERequestQueueCorrupt)); + __ASSERT_DEBUG(iHead->iPrev == last, Panic(ERequestQueueCorrupt)); + } + } + +#endif + +#ifdef _OMXIL_COMMON_DEBUG_TRACING_ON + +void TRequestDeltaQue::DbgPrint() const + { + TMediaRequest* x = iHead; + TBuf8<256> msg; + msg.Append(_L8("pending times: ")); + for(TInt index = 0; index < iCount; index++) + { + if(index > 0) + { + msg.Append(_L8(", ")); + } + msg.AppendFormat(_L8("%ld"), x->iTriggerWallTime); + x = x->iNext; + } + DEBUG_PRINTF(msg); + } + +#endif diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/src/clocksupervisor.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/src/clocksupervisor.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,438 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifndef CLOCKSUPERVISOR_H_ +#define CLOCKSUPERVISOR_H_ + +#include +#include + +/** + @file + @internalComponent + */ + +// forward declaration as supervisor calls back to processing function +class COmxILClockProcessingFunction; + +/////////////////////////////////////////////////////////////////////////////// +// List of structures declared in this file: +// +// TMediaRequest +// TEntryPoint +// TIndexToFunctionMapping +// CClockSupervisor +// +/////////////////////////////////////////////////////////////////////////////// +// Storage of Clock requests. +// +// The Media Update storage holds a number of request updates to send to +// clients. +// The updates are entered in a queue based on the delta of the +// 'expected MediaTime minus Offset' giving an absolute time (the delta). +// This difference is then calculated by the queue implementation on insertion +// of the element. +// +// When the clock changes state it notifies the clients by sending them a state +// change notification broadcast. +// The important thing to note here is that there is no seperate queue for +// outgoing notifications. +// As soon as a request timer expires that request is forwarded. +// Broadcast requests are raised and placed first on the queue so are sent +// as and when they occur. +// +// When the scale is a change of direction (i.e. playing in the backwards +// direction), the queue is cleared and the delta's absolute value is taken. +// +// The delta is a TInt which matches the Ticks datatype returned by the system. +// +// We do not expect the phone to be in operation beyond the maximum duration +// held by the 64-bit Wall clock. Behaviour beyond this is undefined. +// +// The reason for choosing a list over an array is mainly access efficiency. +// +// 1) The insertions must be in order so as to be pulled off quickly. +// Updates are pulled off from the front of the queue, so you would have +// to adjust the whole array each time. +// 2) Updates arrive at different times and can expect to be fulfilled prior +// to earlier updates, again the list would need to be adjusted after the +// point of insertion. +// +// Clients are attached via ports and the notifications are sent to them via +// these ports +// +/////////////////////////////////////////////////////////////////////////////// +// Clock functionality is invoked both externally & internally. +// +// Based on the OMX IL 1.1.1 standard, we route these incoming external +// requests to their relevant behaviour. +// +// This Clock component is intended to be created per use case. +// That is for every use case that requires synchronisation. +// This could result in several clocks being created, each with an audio and/or +// video as an input, and each with a high-priority clock thread. +// At most it is considered that there should only be a few of these components +// in existance at any one time, as mobile devices should not really require it. +// However, saying this, it should be factored into the design. +// At this stage it is envisioned that any clock component should reduce its +// timer events to once at just after the 32-bit wraparound when its +// application is not in focus. +// This is due to the time being reported to us in a 32-bit value, whilst our +// Wall clock is 64-bits. +// To avoid any wraparound and losing time by not regulary updating the upper +// word of our wall clock, we need to somehow check the system clock at this +// inteval. This is not a problem during normal operation but can be when the +// application is Paused or goes out of focus. +// +// NOTE: Assumes OMX_SKIP64BIT is not set when building OMX CORE +/////////////////////////////////////////////////////////////////////////////// + + +/** + * + * + */ +class TMediaRequest + { +public: + TInt64 iMediaTime; + TInt64 iOffset; + TInt64 iTriggerWallTime; // == iWallTimeAtMediaTime - iOffset + TInt iPortIndex; + TAny* iClientPrivate; + + inline void Deque(); + inline void AddBefore(TMediaRequest*); + +public: + TMediaRequest *iPrev; + TMediaRequest *iNext; + }; + +/** + * + * + */ +class TMediaTimeContext + { +public: + TMediaTimeContext(): iScaleQ16 (1 << 16), iInverseScaleQ16 (1 << 16) + {/*do nothing*/}; + + void SetScaleQ16(TInt32 aScaleQ16, TInt64 aWallTimeNow); +public: + TInt64 iWallTimeBase; + TInt64 iMediaTimeBase; + + /** + * Scale ranges map to modes of playback. + * A Q16 value relative to a 1X forward advancement of the media clock. + */ + TInt32 iScaleQ16; + + /** + * The reciprocal of iScaleQ16 (i.e. 1 / iScaleQ16), but adjusted for the + * Q16 format. + * + * It therefore has the value 2^32 / iScaleQ16. + * + * If iScaleQ16 == 0, this field takes the value KMaxTInt (2^31 - 1) + * + * If magnitude of iInverseScaleQ16 would be too large for a signed 32-bit + * value, the value is clipped to KMaxTInt or KMinTInt (-2^31 or + * (2^31 - 1)). This can only happen if iScaleQ16 == +/- 1. + */ + TInt32 iInverseScaleQ16; + }; + +/** + * + * + */ +class TRequestDeltaQue + { +public: + TRequestDeltaQue(); + + void Add(TMediaRequest* aElement, TInt64 aDelta); + TMediaRequest* RemoveFirst(); + TBool FirstDelta(TInt64& aDelta) const; + void RecalculateAndReorder(TMediaTimeContext& aMTC); + TBool IsEmpty() const; + TUint Count() const; + +private: + TBool InsertBeforeFoundPosition(TInt64 aDelta, TMediaRequest*& aItem) const; + +#ifdef _DEBUG + void DbgCheck() const; +#endif +#ifdef _OMXIL_COMMON_DEBUG_TRACING_ON + void DbgPrint() const; +#endif + +private: + TMediaRequest* iHead; + TInt iCount; + }; + + +/** + * + * + */ +class CClockSupervisor : public CBase + { +public: +#ifdef STABILITY_TEST_WRAPPER + friend class CStabilityTestWrapper; + friend class CStabilityTestNegativeWrapper; +#endif +friend class CClockThreadNotifier; +public: + static CClockSupervisor* NewL(COmxILClockProcessingFunction& aCallbacks); + ~CClockSupervisor(); + + /** + * Defines how a request arrived at the clock component + */ + enum TEntryPoint + { + EGetConfig, + ESetConfig + }; + + // Producer function + // Invoked via clients of this component, i.e. GetConfig() and SetConfig() + OMX_ERRORTYPE ProduceRequest(OMX_INDEXTYPE aIndex, TEntryPoint aEntryPoint, + TAny* aPassedStructPtr); + + const OMX_TIME_CONFIG_CLOCKSTATETYPE GetMediaClockState() const + { + return iMediaClockState; + } + +private: + CClockSupervisor(COmxILClockProcessingFunction& aProcessingFunction); + void ConstructL(); + +private: + ////////////// + // This section describes the Clock thread related functions + ////////////// + + // The timing thread's entry point + static TInt ThreadEntryPoint(TAny* aPtr); + void RunTimingThreadL(); + +private: + ////////////// + // This section describes the request handler functions + ////////////// + + // From the Audio/Video feeds + OMX_ERRORTYPE HandleUpdateAudioReference(TEntryPoint aEntry, OMX_PTR aPassedStructPtr); + OMX_ERRORTYPE HandleUpdateVideoReference(TEntryPoint aEntry, OMX_PTR aPassedStructPtr); + + // From the OMX component + OMX_ERRORTYPE HandleSetPortClientStartTime(TEntryPoint aEntry, OMX_PTR aPassedStructPtr); + OMX_ERRORTYPE HandleSubmitMediaTimeRequest(TEntryPoint aEntry, OMX_PTR aPassedStructPtr); + + // From the IL client + OMX_ERRORTYPE HandleGetSetTimeScale(TEntryPoint aEntry, OMX_PTR aPassedStructPtr); + OMX_ERRORTYPE HandleGetSetSeekMode(TEntryPoint aEntry, OMX_PTR aPassedStructPtr); + OMX_ERRORTYPE HandleGetSetClockState(TEntryPoint aEntry, OMX_PTR aPassedStructPtr); + OMX_ERRORTYPE HandleGetSetActiveRefClock(TEntryPoint aEntry, OMX_PTR aPassedStructPtr); + + // Called from either IL client or IL components + OMX_ERRORTYPE HandleQueryCurrentWallTime(TEntryPoint aEntry, OMX_PTR aPassedStructPtr); + OMX_ERRORTYPE HandleQueryCurrentMediaTime(TEntryPoint aEntry, OMX_PTR aPassedStructPtr); + +private: + ////////////// + // This section describes the Clock components internal house-keeping + // routines + ////////////// + + // Perform actions related to placing the clock into the Stopped state + void DoTransitionToStoppedState(); + + // Perform actions related to placing the clock into the Running state + void DoTransitionToRunningState(); + + // Perform actions related to placing the clock into the Waiting state + void DoTransitionToWaitingState(OMX_U32 nWaitMask); + + // Update the tick counter, generating higher 32 bits + void UpdateWallTicks(); + + // Consumer function + // Invoked at initialisation and runs in event loop. + TInt ConsumeRequests(); + + // The timer loop to enable us to wake up on heart beat or requests + void TimerLoop(); + + // obtains the most appropriate start time based on scale (direction) + void CalculateStartTime(); + + // reports whether all clients have reported their start times + TBool AllStartTimesReported(); + + TInt64 WallTime(); + + void UpdateMediaTime(TInt64 aMediaTime); + void BroadcastUpdate(const OMX_TIME_MEDIATIMETYPE& aUpdate); + + // reports error when clock thread panics + + void ReportClockThreadPanic(); + +private: + ////////////// + // This section describes the clock's miscellaneous structures + ////////////// + + /** + * State of the clock component's media clock: + */ + OMX_TIME_CONFIG_CLOCKSTATETYPE iMediaClockState; + + /** + * Choice of the clock component's reference clock: + */ + OMX_TIME_REFCLOCKTYPE iActiveRefClock; + + /** + * Array of clients' start times: + */ + RArray iStartTimes; + TUint iStartTimesSet; /* bit mask representing which elements of + the start time array are valid */ + +private: + ////////////// + // This section describes the Clock component's routing structures + ////////////// + + /* + * typedef for function to handle incoming requests + */ + typedef OMX_ERRORTYPE (CClockSupervisor::*FunctionPtr)(TEntryPoint, OMX_PTR); + + /* + * Function jump table. Note that this is declared in class scope so that the table + * definition has access to private methods. + */ + static const FunctionPtr iJumpTable[]; + +private: + ////////////// + // This section describes the Clock component's Timer Control + ////////////// + + /** + * Holds the current Wall Clock. The duration of a 'tick' is platform specific. + * This needs to be 4-byte aligned to allow for atomic access. + */ + OMX_TICKS iWallTicks; + + /** + * Encapsulates the relationship between wall time and media time. + */ + TMediaTimeContext iMtc; + + // conversion factors from wall 'ticks' to microseconds + TInt iMicroConvNum; + TInt iMicroConvDen; + TInt iMicroConvShift; + + // maximum time between calls to WallTime() - avoids 32-bit counter overflow + TInt iHeartbeatTimerInterval; + + // on some platforms User::FastCounter() counts backwards + TBool iSystemClockReversed; + +private: + ////////////// + // This section describes the Clock component's thread and other resources + ////////////// + + /** + * This Clock component object needs to run in a high priority thread as it + * represents the OMX component timings + */ + RThread iThread; + + /** + * Thread access control Mutex, + * used to control updating of the components requests by mutiple threads + */ + RMutex iQueMutex; + + /** + * Event timer to wake up this object to complete fulfillment of a request + * This handle belongs to the High-Pri thread + */ + RTimer iTimer; + + /** + * Flags to control timing thread exit/destroy. + */ + TBool iThreadStarted; + TBool iThreadRunning; + + /** + * Complete this status on the timing thread to interrupt the timer sleep. + * Timer itself can't be cancelled since timer handle is local to timing + * thread. + */ + TRequestStatus iCancelStatus; + +private: + ////////////// + // This section describes the Clock component's request management + // infrastructure + ////////////// + + /** + * Pending Media Time Requests + */ + TRequestDeltaQue iPendingRequestQue; + + /** + * The free queue header. + * Items ared remove from here and placed on the pending queue. + */ + TRequestDeltaQue iFreeRequestQue; + + /** + * memory block where request list nodes are allocated + */ + TMediaRequest* iRequestBlock; + + /** + * Max number of request list nodes allocated + */ + const TUint iMaxRequests; + + COmxILClockProcessingFunction& iProcessingFunction; + }; // class CClockSupervisor + + +#endif // CLOCKSUPERVISOR_H_ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/src/clockthreadnotifier.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/src/clockthreadnotifier.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include "clockthreadnotifier.h" + +_LIT(KClockThreadPanicMsg, "CLOCK-THREAD-NOTIFIER"); + +CClockThreadNotifier* CClockThreadNotifier::NewL(CClockSupervisor* aClockSupervisor) + { + CClockThreadNotifier* self = new(ELeave)CClockThreadNotifier(aClockSupervisor); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +CClockThreadNotifier::CClockThreadNotifier(CClockSupervisor* aClockSupervisor):CActive(CActive::EPriorityStandard) + { + iClockSupervisor = aClockSupervisor; + } +void CClockThreadNotifier::ConstructL() + { + CActiveScheduler::Add(this); + } +void CClockThreadNotifier::RunL() + { + + iClockSupervisor->ReportClockThreadPanic(); + + } +void CClockThreadNotifier::DoCancel() + { + // Do Nothing + } +CClockThreadNotifier::~CClockThreadNotifier() + { + Cancel(); + } +TInt CClockThreadNotifier::RunError(TInt) + { + return KErrNone; + } +void CClockThreadNotifier::IssueRequest() + { + __ASSERT_ALWAYS(!IsActive(), User::Panic(KClockThreadPanicMsg, 0)); + iClockSupervisor->iThread.Logon(iStatus); + SetActive(); + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/src/clockthreadnotifier.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/src/clockthreadnotifier.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +/** + @file + @internalComponent + */ + +#ifndef CLOCKTHREADNOTIFIER_H_ +#define CLOCKTHREADNOTIFIER_H_ + +#include "clocksupervisor.h" +#include + +//Clock thread observer class + +class CClockThreadNotifier : public CActive + { + public: + static CClockThreadNotifier* NewL(CClockSupervisor* aClockSupervisor); + + ~CClockThreadNotifier(); + + void ConstructL(); + void IssueRequest(); + + protected: + CClockThreadNotifier(CClockSupervisor* aClockSupervisor ); + + //from CActive + + protected: + void RunL(); + void DoCancel(); + TInt RunError(TInt aError); + + //data members + private: + CClockSupervisor* iClockSupervisor; + + }; + + + +#endif /* CLOCKTHREADNOTIFIER_H_ */ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/src/comxilclockcomponent.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/src/comxilclockcomponent.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,185 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include +#include +#include + +#include "comxilclockcomponent.h" +#include "comxilclockoutputport.h" +#include "comxilclockprocessingfunction.h" +#include "comxilclockconfigmanager.h" +#include "clockpanics.h" +#include "omxilclock.hrh" + +_LIT8(KSymbianOmxILClockNameDes, KCompNameSymbianOmxILClock); +_LIT8(KSymbianOmxILClockRoleDes, KRoleSymbianOmxILClock); + +OMXIL_COMPONENT_ECOM_ENTRYPOINT(KUidSymbianOmxILClock); + +OMX_ERRORTYPE SymbianErrorToOmx(TInt aError); + +// Component Entry Point +OMX_ERRORTYPE OMX_ComponentInit(OMX_HANDLETYPE aComponent) + { + TInt err = COmxILClockComponent::CreateComponent(aComponent); + return SymbianErrorToOmx(err); + } + +TInt COmxILClockComponent::CreateComponent(OMX_HANDLETYPE hComponent) + { + COmxILClockComponent* self = new COmxILClockComponent(); + + if (!self) + { + return KErrNoMemory; + } + + TRAPD(error, self->ConstructL(hComponent)); + if(error != KErrNone) + { + delete self; + } + return error; + } + +COmxILClockComponent::COmxILClockComponent() + { + // nothing to do + } + +void COmxILClockComponent::ConstructL(OMX_HANDLETYPE hComponent) + { + COmxILComponent::ConstructL(hComponent); + + // use synchronous callback manager since BufferDoneNotifications must be serviced at precise times + MOmxILCallbackNotificationIf* callbackNotificationIf=CreateCallbackManagerL(COmxILComponent::EOutofContext); + + COmxILClockProcessingFunction* pProcessingFunction = COmxILClockProcessingFunction::NewL(*callbackNotificationIf, *this); + RegisterProcessingFunction(pProcessingFunction); + + CreatePortManagerL(COmxILComponent::ENonBufferSharingPortManager, + TOmxILSpecVersion(), // OMX Version + 0, // The number of audio ports in this component + 0, // The starting audio port index + 0, // The number of image ports in this component + 0, // The starting image port index + 0, // The number of video ports in this component + 0, // The starting video port index + KNumPorts, // The number of other ports in this component + 0, // The starting other port index + OMX_FALSE // Process the time port buffer as usual in port manager + ); + + + RPointerArray roleList; + CleanupClosePushL(roleList); + roleList.AppendL(&KSymbianOmxILClockRoleDes); + COmxILClockConfigManager* configManager = COmxILClockConfigManager::NewL(KSymbianOmxILClockNameDes, + TOmxILSpecVersion(), roleList, *(static_cast(pProcessingFunction))); + RegisterConfigurationManager(configManager); + CleanupStack::PopAndDestroy(&roleList); + + for(TInt portIndex = 0; portIndex < KNumPorts; portIndex++) + { + AddPortL(); + } + + InitComponentL(); + } + +COmxILClockComponent::~COmxILClockComponent() + { + iPorts.Reset(); + } + +void COmxILClockComponent::AddPortL() + { + TOmxILSpecVersion omxIlVersion; + TOmxILCommonPortData portData( + omxIlVersion, + iPorts.Count(), // port index + OMX_DirOutput, + 4, // minimum number of buffers + sizeof(OMX_TIME_MEDIATIMETYPE), // minimum buffer size, in bytes + OMX_PortDomainOther, + OMX_FALSE, // do not need contigious buffers + 1, // byte alignment + // Clock being buffer supplier allows it to send notifications to clients without + // waiting for clients to pass their buffers after a state transition + OMX_BufferSupplyOutput, + COmxILPort::KBufferMarkPropagationPortNotNeeded + ); + + RArray supportedOtherFormats; + + CleanupClosePushL(supportedOtherFormats); + supportedOtherFormats.AppendL(OMX_OTHER_FormatTime); + + COmxILClockOutputPort* port = COmxILClockOutputPort::NewL(portData, supportedOtherFormats, + *(static_cast(GetProcessingFunction()))); + CleanupStack::PopAndDestroy(&supportedOtherFormats); + CleanupStack::PushL(port); + User::LeaveIfError(AddPort(port, OMX_DirOutput)); + CleanupStack::Pop(port); + iPorts.AppendL(port); + } + +/** + * Returns true iff the specified port is currently enabled. + */ +TBool COmxILClockComponent::PortEnabled(TInt aPortIndex) const + { + return iPorts[aPortIndex]->IsEnabled(); + } + +/** + * Returns the number of buffers as configured in the port definition. + */ +TInt COmxILClockComponent::PortBufferCount(TInt aPortIndex) const + { + return iPorts[aPortIndex]->BufferCount(); + } + +OMX_ERRORTYPE SymbianErrorToOmx(TInt aError) + { + switch(aError) + { + case KErrNone: + return OMX_ErrorNone; + case KErrNoMemory: + return OMX_ErrorInsufficientResources; + case KErrArgument: + return OMX_ErrorUnsupportedSetting; + case KErrNotSupported: + return OMX_ErrorUnsupportedIndex; + case KErrNotReady: + return OMX_ErrorIncorrectStateOperation; + default: +#ifdef _DEBUG + // Panic in a debug build. It will make people think about how the error should be handled. + Panic(EUndefinedErrorCode); +#endif + return OMX_ErrorUndefined; + } + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/src/comxilclockcomponent.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/src/comxilclockcomponent.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef COMXILCLOCKCOMPONENT_H +#define COMXILCLOCKCOMPONENT_H + +#include + + + +class COmxILClockOutputPort; + +class COmxILClockComponent : public COmxILComponent + { +public: + static TInt CreateComponent(OMX_HANDLETYPE hComponent); + ~COmxILClockComponent(); + + TBool PortEnabled(TInt aPortIndex) const; + TInt PortBufferCount(TInt aPortIndex) const; + +private: + COmxILClockComponent(); + void ConstructL(OMX_HANDLETYPE hComponent); + +private: + void AddPortL(); + +private: + RPointerArray iPorts; + }; + +#endif //COMXILCLOCKOUTPUTPORT_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/src/comxilclockconfigmanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/src/comxilclockconfigmanager.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include "comxilclockconfigmanager.h" +#include "comxilclockprocessingfunction.h" +#include "clocksupervisor.h" + + + +COmxILClockConfigManager* COmxILClockConfigManager::NewL( + const TDesC8& aComponentName, + const OMX_VERSIONTYPE& aComponentVersion, + const RPointerArray& aComponentRoleList, + COmxILClockProcessingFunction& aProcessingFunction) + { + COmxILClockConfigManager* self = new(ELeave) COmxILClockConfigManager(aProcessingFunction); + CleanupStack::PushL(self); + self->ConstructL(aComponentName, aComponentVersion, aComponentRoleList); + CleanupStack::Pop(self); + return self; + } + +COmxILClockConfigManager::COmxILClockConfigManager(COmxILClockProcessingFunction& aProcessingFunction): + iProcessingFunction(&aProcessingFunction) + { + // nothing to do + } + +void COmxILClockConfigManager::ConstructL(const TDesC8& aComponentName, + const OMX_VERSIONTYPE& aComponentVersion, + const RPointerArray& aComponentRoleList) + { + COmxILConfigManager::ConstructL(aComponentName, aComponentVersion, aComponentRoleList); + } + +COmxILClockConfigManager::~COmxILClockConfigManager() + { + } + +OMX_ERRORTYPE COmxILClockConfigManager::GetConfig(OMX_INDEXTYPE aConfigIndex, + TAny* apComponentConfigStructure) const + { + OMX_ERRORTYPE error = iProcessingFunction->ProduceRequest(aConfigIndex, CClockSupervisor::EGetConfig, apComponentConfigStructure); + if(error != OMX_ErrorUnsupportedIndex) + { + return error; + } + + // try base class if PF did not support the index + return COmxILConfigManager::GetConfig(aConfigIndex, apComponentConfigStructure); + } + +OMX_ERRORTYPE COmxILClockConfigManager::SetConfig(OMX_INDEXTYPE aConfigIndex, + const TAny* apComponentConfigStructure) + { + OMX_ERRORTYPE error = iProcessingFunction->ProduceRequest(aConfigIndex, CClockSupervisor::ESetConfig, const_cast(apComponentConfigStructure)); + if(error != OMX_ErrorUnsupportedIndex) + { + return error; + } + + // try base class if PF did not support the index + return COmxILConfigManager::SetConfig(aConfigIndex, apComponentConfigStructure); + } + diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/src/comxilclockconfigmanager.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/src/comxilclockconfigmanager.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef COMXILCLOCKCONFIGMANAGER_H +#define COMXILCLOCKCONFIGMANAGER_H + +#include + + + +// Forward declarations +class COmxILClockProcessingFunction; + +class COmxILClockConfigManager : public COmxILConfigManager + { +public: + static COmxILClockConfigManager* NewL( + const TDesC8& aComponentName, + const OMX_VERSIONTYPE& aComponentVersion, + const RPointerArray& aComponentRoles, + COmxILClockProcessingFunction& aProcessingFunction); + + ~COmxILClockConfigManager(); + + // from COmxILConfigManager + OMX_ERRORTYPE GetConfig(OMX_INDEXTYPE aConfigIndex, + TAny* apComponentConfigStructure) const; + OMX_ERRORTYPE SetConfig(OMX_INDEXTYPE aConfigIndex, + const TAny* apComponentConfigStructure); + +private: + COmxILClockConfigManager(COmxILClockProcessingFunction& aProcessingFunction); + + void ConstructL(const TDesC8& aComponentName, + const OMX_VERSIONTYPE& aComponentVersion, + const RPointerArray& aComponentRoles); + +private: + COmxILClockProcessingFunction* iProcessingFunction; // not owned + }; + +#endif //COMXILCLOCKCONFIGMANAGER_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/src/comxilclockoutputport.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/src/comxilclockoutputport.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,134 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include "comxilclockoutputport.h" +#include "comxilclockprocessingfunction.h" +#include "clockpanics.h" + +COmxILClockOutputPort* COmxILClockOutputPort::NewL(const TOmxILCommonPortData& aCommonPortData, const RArray& aSupportedFormats, COmxILClockProcessingFunction& aProcessingFunction) + { + COmxILClockOutputPort* self = new(ELeave) COmxILClockOutputPort(aProcessingFunction); + CleanupStack::PushL(self); + self->ConstructL(aCommonPortData, aSupportedFormats); + CleanupStack::Pop(self); + return self; + } + +COmxILClockOutputPort::COmxILClockOutputPort(COmxILClockProcessingFunction& aProcessingFunction) : + iProcessingFunction(&aProcessingFunction) + { + } + +void COmxILClockOutputPort::ConstructL(const TOmxILCommonPortData& aCommonPortData, const RArray& aSupportedFormats) + { + COmxILOtherPort::ConstructL(aCommonPortData, aSupportedFormats); + } + +COmxILClockOutputPort::~COmxILClockOutputPort() + { + } + +OMX_ERRORTYPE COmxILClockOutputPort::GetLocalOmxParamIndexes(RArray& aIndexArray) const + { + return COmxILOtherPort::GetLocalOmxParamIndexes(aIndexArray); + } + +OMX_ERRORTYPE COmxILClockOutputPort::GetLocalOmxConfigIndexes(RArray& aIndexArray) const + { + OMX_ERRORTYPE omxRetValue = COmxILOtherPort::GetLocalOmxConfigIndexes(aIndexArray); + if (omxRetValue != OMX_ErrorNone) + { + return omxRetValue; + } + + TInt err = aIndexArray.InsertInOrder(OMX_IndexConfigTimeClientStartTime); + // Note that index duplication is OK. + if (err == KErrNone || err == KErrAlreadyExists) + { + err = aIndexArray.InsertInOrder(OMX_IndexConfigTimeMediaTimeRequest); + } + + if (err != KErrNone && err != KErrAlreadyExists) + { + return OMX_ErrorInsufficientResources; + } + + return OMX_ErrorNone; + } + +OMX_ERRORTYPE COmxILClockOutputPort::GetParameter(OMX_INDEXTYPE aParamIndex, + TAny* apComponentParameterStructure) const + { + return COmxILOtherPort::GetParameter(aParamIndex, apComponentParameterStructure); + } + +OMX_ERRORTYPE COmxILClockOutputPort::SetParameter(OMX_INDEXTYPE aParamIndex, + const TAny* apComponentParameterStructure, + TBool& aUpdateProcessingFunction) + { + return COmxILOtherPort::SetParameter(aParamIndex, apComponentParameterStructure, aUpdateProcessingFunction); + } + +OMX_ERRORTYPE COmxILClockOutputPort::GetConfig(OMX_INDEXTYPE aConfigIndex, + TAny* apComponentConfigStructure) const + { + return COmxILOtherPort::GetConfig(aConfigIndex, apComponentConfigStructure); + } + +OMX_ERRORTYPE COmxILClockOutputPort::SetConfig(OMX_INDEXTYPE aConfigIndex, + const TAny* apComponentConfigStructure, + TBool& aUpdateProcessingFunction) + { + OMX_ERRORTYPE error = iProcessingFunction->ProduceRequest(aConfigIndex, CClockSupervisor::ESetConfig, const_cast(apComponentConfigStructure)); + if(error != OMX_ErrorUnsupportedIndex) + { + return error; + } + + // try base class if PF did not support the index + return COmxILOtherPort::SetConfig(aConfigIndex, apComponentConfigStructure, aUpdateProcessingFunction); + } + +OMX_ERRORTYPE COmxILClockOutputPort::SetFormatInPortDefinition(const OMX_PARAM_PORTDEFINITIONTYPE& /*aPortDefinition*/, + TBool& /*aUpdateProcessingFunction*/) + { + return OMX_ErrorNone; + } + +TBool COmxILClockOutputPort::IsTunnelledPortCompatible(const OMX_PARAM_PORTDEFINITIONTYPE& /*aPortDefinition*/) const + { +#ifdef _DEBUG + // This function only gets called on input ports, but must be implemented because it is pure virtual. + // Panic if this is ever called. + Panic(ECompatibilityCheckOnOutput); +#endif + return ETrue; + } + +/** + * Returns the number of buffers configured in the port definition. + */ +TInt COmxILClockOutputPort::BufferCount() const + { + return GetParamPortDefinition().nBufferCountActual; + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/src/comxilclockoutputport.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/src/comxilclockoutputport.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef COMXILCLOCKOUTPUTPORT_H +#define COMXILCLOCKOUTPUTPORT_H + +#include + + + +class COmxILClockProcessingFunction; + +class COmxILClockOutputPort : public COmxILOtherPort + { +public: + static COmxILClockOutputPort* NewL(const TOmxILCommonPortData& aCommonPortData, const RArray& aSupportedFormats, COmxILClockProcessingFunction& aProcessingFunction); + ~COmxILClockOutputPort(); + + TInt BufferCount() const; + + // from COmxILOtherPort + OMX_ERRORTYPE GetLocalOmxParamIndexes(RArray& aIndexArray) const; + OMX_ERRORTYPE GetLocalOmxConfigIndexes(RArray& aIndexArray) const; + OMX_ERRORTYPE GetParameter(OMX_INDEXTYPE aParamIndex, + TAny* apComponentParameterStructure) const; + OMX_ERRORTYPE SetParameter(OMX_INDEXTYPE aParamIndex, + const TAny* apComponentParameterStructure, + TBool& aUpdateProcessingFunction); + OMX_ERRORTYPE GetConfig(OMX_INDEXTYPE aConfigIndex, + TAny* apComponentConfigStructure) const; + OMX_ERRORTYPE SetConfig(OMX_INDEXTYPE aConfigIndex, + const TAny* apComponentConfigStructure, + TBool& aUpdateProcessingFunction); + +protected: + OMX_ERRORTYPE SetFormatInPortDefinition(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition, + TBool& aUpdateProcessingFunction); + TBool IsTunnelledPortCompatible(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition) const; + +private: + COmxILClockOutputPort(COmxILClockProcessingFunction& aProcessingFunction); + void ConstructL(const TOmxILCommonPortData& aCommonPortData, const RArray& aSupportedFormats); + +private: + COmxILClockProcessingFunction* iProcessingFunction; // not owned + }; + +#endif //COMXILCLOCKOUTPUTPORT_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/src/comxilclockprocessingfunction.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/src/comxilclockprocessingfunction.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,318 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include +#include "comxilclockprocessingfunction.h" +#include "comxilclockcomponent.h" +#include "clocksupervisor.h" +#include +#include "clockpanics.h" +#include "omxilclock.hrh" + +#include + + +OMX_ERRORTYPE SymbianErrorToOmx(TInt aError); + +COmxILClockProcessingFunction* COmxILClockProcessingFunction::NewL(MOmxILCallbackNotificationIf& aCallbacks, + COmxILClockComponent& aComponent) + { + COmxILClockProcessingFunction* self = new (ELeave) COmxILClockProcessingFunction(aCallbacks, aComponent); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +COmxILClockProcessingFunction::COmxILClockProcessingFunction(MOmxILCallbackNotificationIf& aCallbacks, + COmxILClockComponent& aComponent) : + COmxILProcessingFunction(aCallbacks), iComponent(aComponent) + { + } + +void COmxILClockProcessingFunction::ConstructL() + { + iClock = CClockSupervisor::NewL(*this); + iThreadNotifier = CClockThreadNotifier::NewL(iClock); + iThreadNotifier->IssueRequest(); + User::LeaveIfError(iBufferMutex.CreateLocal()); + // create a buffer queue for each port and add it to the iBufferQueues array + for(TInt portIndex = 0; portIndex < KNumPorts; portIndex++) + { + CCirBuf* queue = new(ELeave) CCirBuf(); + CleanupStack::PushL(queue); + iBufferQueues.AppendL(queue); + CleanupStack::Pop(queue); + } + } + +COmxILClockProcessingFunction::~COmxILClockProcessingFunction() + { + delete iClock; + delete iThreadNotifier; + iBufferMutex.Close(); + // empty iBufferQueues and delete any CCirBuf objects + // the CCirBuf objects don't own any buffers they contain, so we don't delete those here + iBufferQueues.ResetAndDestroy(); + } + +OMX_ERRORTYPE COmxILClockProcessingFunction::StateTransitionIndication(TStateIndex aNewState) + { + OMX_ERRORTYPE omxError = OMX_ErrorNone; + + switch(aNewState) + { + case ESubStateLoadedToIdle: + { + // allocate space for the buffer queues now the buffer count on each port is known + for(TInt portIndex = 0; portIndex < KNumPorts; portIndex++) + { + TInt length = iComponent.PortBufferCount(portIndex); + TRAPD(error, iBufferQueues[portIndex]->SetLengthL(length)); + // error not actually a problem if queue was originally longer than we need + if(error != KErrNone && iBufferQueues[portIndex]->Length() < length) + { + omxError = OMX_ErrorInsufficientResources; + break; + } + } + break; + } + + case EStateExecuting: + { + iExecuting = ETrue; + break; + } + + case EStateIdle: + { + iExecuting = EFalse; + break; + } + + case EStatePause: + { + // NOTE we do not change iExecuting + // The value of iExecuting maintains the direction from which + // Paused was entered (i.e. from Idle or Executing). + // This is because we wan't to know whether buffers are available, + // regardless of whether we are paused or not. + // TODO TBD is there an implicit stopping of the clock (e.g. set scale to 0)? + break; + } + default: + { + break; + } + } + + return omxError; + } + +OMX_ERRORTYPE COmxILClockProcessingFunction::BufferFlushingIndication(TUint32 aPortIndex, + OMX_DIRTYPE /*aDirection*/) + { + __ASSERT_DEBUG(aPortIndex == OMX_ALL || aPortIndex < KNumPorts, Panic(EBufferFlushingInvalidPort)); + + if (aPortIndex == OMX_ALL || aPortIndex < KNumPorts) + { + iBufferMutex.Wait(); + + if (aPortIndex == OMX_ALL) + { + for (TInt portIndex = 0; portIndex < KNumPorts; portIndex++) + { + DoBufferFlushingIndication(portIndex); + } + } + else + { + DoBufferFlushingIndication(aPortIndex); + } + + iBufferMutex.Signal(); + } + + return OMX_ErrorNone; + } + +void COmxILClockProcessingFunction::DoBufferFlushingIndication(TUint32 aPortIndex) + { + CCirBuf& queue = *iBufferQueues[aPortIndex]; + + while(queue.Count() > 0) + { + OMX_BUFFERHEADERTYPE* buffer; + // ignore error, we just checked Count() > 0 and we have the mutex, so a buffer + // should definitely be there + queue.Remove(&buffer); + OMX_ERRORTYPE error = iCallbacks.BufferDoneNotification(buffer, aPortIndex, OMX_DirOutput); + // the callback manager should return OMX_ErrorNone + // the callback manager ignores any error code from the callee component since it is the component's responsibility + // to respond to errors generated internally + __ASSERT_DEBUG(error == OMX_ErrorNone, Panic(ECallbackManagerBufferError)); + } + } + +OMX_ERRORTYPE COmxILClockProcessingFunction::ParamIndication(OMX_INDEXTYPE /*aParamIndex*/, + const TAny* /*apComponentParameterStructure*/) + { + return OMX_ErrorNone; + } + +OMX_ERRORTYPE COmxILClockProcessingFunction::ConfigIndication(OMX_INDEXTYPE /*aConfigIndex*/, + const TAny* /*apComponentConfigStructure*/) + { + return OMX_ErrorNone; + } + +OMX_ERRORTYPE COmxILClockProcessingFunction::BufferIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, + OMX_DIRTYPE /*aDirection*/) + { + // add buffer to the appropriate port queue + + CCirBuf& queue = *iBufferQueues[apBufferHeader->nOutputPortIndex]; + TOmxILUtil::ClearBufferContents(apBufferHeader); + apBufferHeader->nOffset = 0; + iBufferMutex.Wait(); + TInt added = queue.Add(&apBufferHeader); + // don't expect 0 (not added) as total number of buffers is known + __ASSERT_DEBUG(added, Panic(EBufferQueueOverflow)); + + iBufferMutex.Signal(); + return OMX_ErrorNone; + } + +/** + * Finds and removes an item from a CCirBuf. + * NOTE items are NOT guaranteed to be in their original position! + * The queue must be protected from concurrent access when calling this + * function. + * + * @param aQueue queue to modify + * @param aRemoveItem item to remove + * @return ETrue if item was found and removed from the queue, EFalse otherwise. + */ +template +static TBool RemoveFromPool(CCirBuf&aQueue, T aRemoveItem) + { + TInt numItems = aQueue.Count(); + for(TInt index = 0; index < numItems; index++) + { + T item; + TInt removed = aQueue.Remove(&item); // ignore error since queue cannot be empty (numItems > 0) + __ASSERT_DEBUG(removed == 1, Panic(EBufferUnderflow)); + if(item == aRemoveItem) + { + return ETrue; + } + else + { + TInt added = aQueue.Add(&item); // ignore error since always space for 1 item as one has just been removed + __ASSERT_DEBUG(added == 1, Panic(EBufferQueueOverflow)); + } + } + return EFalse; + } + +OMX_BOOL COmxILClockProcessingFunction::BufferRemovalIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, + OMX_DIRTYPE /*aDirection*/) + { + CCirBuf& queue = *iBufferQueues[apBufferHeader->nOutputPortIndex]; + iBufferMutex.Wait(); + // note queue may be reordered, but that's OK since these are empty buffers + TBool removed = RemoveFromPool(queue, apBufferHeader); + iBufferMutex.Signal(); + + return removed ? OMX_TRUE : OMX_FALSE; + } + +/** + * Returns a free buffer from the queue for the specified port. + * If no buffer is ready, this method returns NULL + * This method does not block for a buffer to become available. + */ +OMX_BUFFERHEADERTYPE* COmxILClockProcessingFunction::AcquireBuffer(TInt aPortIndex) + { + CCirBuf& queue = *iBufferQueues[aPortIndex]; + iBufferMutex.Wait(); + OMX_BUFFERHEADERTYPE* buffer; + TInt count = queue.Remove(&buffer); + iBufferMutex.Signal(); + if(count > 0) + { + return buffer; + } + else + { + return NULL; + } + } + +/** + * Sends a buffer out on a port. + */ +void COmxILClockProcessingFunction::SendBuffer(OMX_BUFFERHEADERTYPE* aBuffer) + { + OMX_ERRORTYPE error = iCallbacks.BufferDoneNotification(aBuffer, aBuffer->nOutputPortIndex, OMX_DirOutput); + // the callback manager should return OMX_ErrorNone + // the callback manager ignores any error code from the callee component since it is the component's responsibility + // to respond to errors generated internally + __ASSERT_DEBUG(error == OMX_ErrorNone, Panic(ECallbackManagerBufferError)); + } + +OMX_ERRORTYPE COmxILClockProcessingFunction::ProduceRequest(OMX_INDEXTYPE aIdx, CClockSupervisor::TEntryPoint aEntryPoint, TAny* pComponentConfigStructure) + { + return iClock->ProduceRequest(aIdx, aEntryPoint, pComponentConfigStructure); + } + +/** + * Returns true iff the specified port is currently enabled. + */ +TBool COmxILClockProcessingFunction::PortEnabled(TInt aPortIndex) const + { + return iComponent.PortEnabled(aPortIndex); + } + +TBool COmxILClockProcessingFunction::IsExecuting() const + { + return iExecuting; + } + +/** + * Called when CClockSupervisor encounters a fatal error and needs to transition the + * component to OMX_StateInvalid. + */ +void COmxILClockProcessingFunction::InvalidateComponent() + { + OMX_ERRORTYPE error = iCallbacks.ErrorEventNotification(OMX_ErrorInvalidState); + // the callback manager should return OMX_ErrorNone + // the callback manager ignores any error code from the client since it is the client's responsibility to respond + // to errors generated internally + __ASSERT_DEBUG(error == OMX_ErrorNone, Panic(ECallbackManagerEventError)); + // TODO this sends the invalidated event up to the IL client, but does not alter + // the internal state of the component to reflect being invalid. It seems you need + // access to private, non-exported FsmTransition to do that? + } + diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/src/comxilclockprocessingfunction.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/src/comxilclockprocessingfunction.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef COMXILCLOCKPROCESSINGFUNCTION_H +#define COMXILCLOCKPROCESSINGFUNCTION_H + +#include +#include "clocksupervisor.h" +#include "clockthreadnotifier.h" + +class COmxILClockComponent; + +class COmxILClockProcessingFunction : public COmxILProcessingFunction + { +public: + static COmxILClockProcessingFunction* NewL(MOmxILCallbackNotificationIf& aCallbacks, COmxILClockComponent& aComponent); + ~COmxILClockProcessingFunction(); + + OMX_ERRORTYPE ProduceRequest(OMX_INDEXTYPE aIdx, CClockSupervisor::TEntryPoint aEntryPoint, TAny* pComponentConfigStructure); + + // from COmxILProcessingFunction + OMX_ERRORTYPE StateTransitionIndication(TStateIndex aNewState); + OMX_ERRORTYPE BufferFlushingIndication(TUint32 aPortIndex, OMX_DIRTYPE aDirection); + OMX_ERRORTYPE ParamIndication(OMX_INDEXTYPE aParamIndex, const TAny* apComponentParameterStructure); + OMX_ERRORTYPE ConfigIndication(OMX_INDEXTYPE aConfigIndex, const TAny* apComponentConfigStructure); + OMX_ERRORTYPE BufferIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, OMX_DIRTYPE aDirection); + OMX_BOOL BufferRemovalIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, OMX_DIRTYPE aDirection); + + // used by CClockSupervisor + OMX_BUFFERHEADERTYPE* AcquireBuffer(TInt aPortIndex); + void SendBuffer(OMX_BUFFERHEADERTYPE* aBuffer); + TBool PortEnabled(TInt aPortIndex) const; + TBool IsExecuting() const; + void InvalidateComponent(); + + +private: + COmxILClockProcessingFunction(MOmxILCallbackNotificationIf& aCallbacks, COmxILClockComponent& aComponent); + void ConstructL(); + void DoBufferFlushingIndication(TUint32 aPortIndex); + +private: + CClockSupervisor* iClock; + CClockThreadNotifier* iThreadNotifier; + COmxILClockComponent& iComponent; + RPointerArray > iBufferQueues; + RMutex iBufferMutex; + TBool iExecuting; + }; + +#endif //COMXILCLOCKPROCESSINGFUNCTION_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/src/log.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/src/log.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,149 @@ +/* +* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifndef __SWI_LOG_H__ +#define __SWI_LOG_H__ + +#include + +class TTruncateOverflowHandler16 : public TDes16Overflow + { + public: + virtual void Overflow( TDes16& aDes ); + }; + +inline void TTruncateOverflowHandler16::Overflow( TDes16& aDes) + { + _LIT(KErrOverflowMsg,"Descriptor Overflow, hence value truncated"); + if( aDes.MaxLength() >= KErrOverflowMsg().Length() + aDes.Length() ) + aDes.Append(KErrOverflowMsg); + } + +class TTruncateOverflowHandler8 : public TDes8Overflow + { + public: + virtual void Overflow( TDes8& aDes ); + }; + +inline void TTruncateOverflowHandler8::Overflow( TDes8& aDes) + { + _LIT(KErrOverflowMsg,"Descriptor Overflow, hence value truncated"); + if( aDes.MaxLength() >= KErrOverflowMsg().Length() + aDes.Length() ) + aDes.Append(KErrOverflowMsg); + } + +namespace DSD +{ + +#ifdef _DEBUG + +#ifdef _OMXIL_COMMON_DEBUG_TRACING_ON + +#define DEBUG_PRINTF(a) {DSD::DebugPrintf(__LINE__, __FILE__, a);} +#define DEBUG_PRINTF2(a, b) {DSD::DebugPrintf(__LINE__, __FILE__, a, b);} +#define DEBUG_PRINTF3(a, b, c) {DSD::DebugPrintf(__LINE__, __FILE__, a, b, c);} +#define DEBUG_PRINTF4(a, b, c, d) {DSD::DebugPrintf(__LINE__, __FILE__, a, b, c, d);} +#define DEBUG_PRINTF5(a, b, c, d, e) {DSD::DebugPrintf(__LINE__, __FILE__, a, b, c, d, e);} + +#define DEBUG_CODE_SECTION(a) TRAP_IGNORE({ a; }) + +// UTF-8 overload of the DebufPrintf method. Should be used by default, +// since it's cheaper both in CPU cycles and stack space. + +inline void DebugPrintf(TInt aLine, char* aFile, TRefByValue aFormat, ...) + { + TTruncateOverflowHandler8 overflowHandler8; + VA_LIST list; + VA_START(list, aFormat); + + TTime now; + now.HomeTime(); + + TBuf8<1024> buffer; + _LIT8(KSwiLogPrefix, "[ilclock] "); + _LIT8(KSwiLineFileFormat, "TID[%d] : [%s:%d] -- "); + buffer.Append(KSwiLogPrefix); + RThread thread; + TUint threadId = thread.Id(); + thread.Close(); + RProcess proc; + TFileName fName = proc.FileName(); + proc.Close(); + buffer.AppendFormat(KSwiLineFileFormat, threadId, aFile, aLine); + buffer.AppendFormatList(aFormat, list ,&overflowHandler8 ); + buffer.Append(_L8("\r\n")); + + RDebug::RawPrint(buffer); + + VA_END(list); + } + +// Unicode DebufPrintf overload + +inline void DebugPrintf(TInt aLine, char* aFile, TRefByValue aFormat, ...) + { + TTruncateOverflowHandler16 overflowHandler16; + VA_LIST list; + VA_START(list, aFormat); + + TTime now; + now.HomeTime(); + + TBuf8<256> header; + _LIT8(KSwiLogPrefix, "[ilclock] "); + _LIT8(KSwiLineFileFormat, "%Ld Line: % 5d, File: %s -- "); + header.Append(KSwiLogPrefix); + header.AppendFormat(KSwiLineFileFormat, now.Int64(), aLine, aFile); + + TBuf<1024> buffer; + buffer.Copy(header); + buffer.AppendFormatList(aFormat, list ,&overflowHandler16); + buffer.Append(_L("\r\n")); + + RDebug::RawPrint(buffer); + + VA_END(list); + } +#else + +#define DEBUG_PRINTF(a) +#define DEBUG_PRINTF2(a, b) +#define DEBUG_PRINTF3(a, b, c) +#define DEBUG_PRINTF4(a, b, c, d) +#define DEBUG_PRINTF5(a, b, c, d, e) + +#define DEBUG_CODE_SECTION(a) + +#endif + +#else + +#define DEBUG_PRINTF(a) +#define DEBUG_PRINTF2(a, b) +#define DEBUG_PRINTF3(a, b, c) +#define DEBUG_PRINTF4(a, b, c, d) +#define DEBUG_PRINTF5(a, b, c, d, e) + +#define DEBUG_CODE_SECTION(a) + +#endif + + +} // namespace DSD + +#endif // __SWI_LOG_H__ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/src/omxilclock.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/src/omxilclock.hrh Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#ifndef OMXILCLOCK_HRH_ +#define OMXILCLOCK_HRH_ + +#define KUidSymbianOmxILClockDll 0x10286597 +#define KUidSymbianOmxILClock 0x10286598 + +#define KCompNameSymbianOmxILClock "OMX.SYMBIAN.OTHER.CLOCK" +#define KRoleSymbianOmxILClock "clock.binary" + +// No theoretical limit on number of ports, but OpenMAX defines the wait mask OMX_CLOCKPORT0 through +// OMX_CLOCKPORT7 so we assume this number +#define KNumPorts 8 + +#endif /*OMXILCLOCK_HRH_*/ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilclock/src/omxilclock.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilclock/src/omxilclock.rss Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include +#include "omxilclock.hrh" + +RESOURCE REGISTRY_INFO theInfo + { + dll_uid = KUidSymbianOmxILClockDll; + interfaces = + { + INTERFACE_INFO + { + interface_uid = KUidOmxILSymbianComponentIf; + implementations = + { + IMPLEMENTATION_INFO + { + implementation_uid = KUidSymbianOmxILClock; + version_no = 1; + display_name = KCompNameSymbianOmxILClock; + default_data = KRoleSymbianOmxILClock; + } + }; + } + }; + } + diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/group/bld.inf Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +PRJ_PLATFORMS +BASEDEFAULT + +PRJ_EXPORTS +// The export of the IBY is deliberately not guarded by #ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED so that it +// can always be #included by other IBYs/OBYs. However, if NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED is not defined +// then the IBY will effectively be empty and not include anything in the ROM. + +omxilgraphicsink.iby /epoc32/rom/include/omxilgraphicsink.iby + +PRJ_MMPFILES +#ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED +omxilgraphicsink.mmp +#endif // NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/group/omxilgraphicsink.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/group/omxilgraphicsink.iby Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +#ifndef OMXILGRAPHICSSINK_IBY +#define OMXILGRAPHICSSINK_IBY + +#ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED +#ifdef SYMBIAN_GRAPHICS_USE_GCE + +ECOM_PLUGIN(omxilgraphicsink.dll, omxilgraphicsink.rsc) + +#endif // SYMBIAN_GRAPHICS_USE_GCE +#endif // NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED + +#endif // OMXILGRAPHICSSINK_IBY diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/group/omxilgraphicsink.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/group/omxilgraphicsink.mmp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include "../src/omxilgraphicsink.hrh" + +TARGET omxilgraphicsink.dll +CAPABILITY ALL -TCB +TARGETTYPE PLUGIN +UID 0x10009D8D KUidSymbianOmxILGraphicSinkDll +VENDORID 0x70000001 + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +USERINCLUDE ../src +SOURCEPATH ../src + +SOURCE omxilgraphicsinkpanics.cpp +SOURCE omxilgraphicsink.cpp +SOURCE omxilgraphicsinkvpb0port.cpp +SOURCE omxilgraphicsinkprocessingfunction.cpp + +RESOURCE omxilgraphicsink.rss +LIBRARY euser.lib +LIBRARY ecom.lib +LIBRARY omxilcomponentcommon.lib +LIBRARY surfaceupdateclient.lib +LIBRARY gdi.lib +LIBRARY ws32.lib +LIBRARY surfacemanager.lib +LIBRARY hal.lib +STATICLIBRARY omxilcomponentif.lib + +//MACRO ILCOMPONENTCONFORMANCE + +SMPSAFE diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/src/log.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/src/log.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,149 @@ +/* +* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifndef __SWI_LOG_H__ +#define __SWI_LOG_H__ + +#include + +class TTruncateOverflowHandler16 : public TDes16Overflow + { + public: + virtual void Overflow( TDes16& aDes ); + }; + +inline void TTruncateOverflowHandler16::Overflow( TDes16& aDes) + { + _LIT(KErrOverflowMsg,"Descriptor Overflow, hence value truncated"); + if( aDes.MaxLength() >= KErrOverflowMsg().Length() + aDes.Length() ) + aDes.Append(KErrOverflowMsg); + } + +class TTruncateOverflowHandler8 : public TDes8Overflow + { + public: + virtual void Overflow( TDes8& aDes ); + }; + +inline void TTruncateOverflowHandler8::Overflow( TDes8& aDes) + { + _LIT(KErrOverflowMsg,"Descriptor Overflow, hence value truncated"); + if( aDes.MaxLength() >= KErrOverflowMsg().Length() + aDes.Length() ) + aDes.Append(KErrOverflowMsg); + } + +namespace DSD +{ + +#ifdef _DEBUG + +#ifdef _OMXIL_COMMON_DEBUG_TRACING_ON + +#define DEBUG_PRINTF(a) {DSD::DebugPrintf(__LINE__, __FILE__, a);} +#define DEBUG_PRINTF2(a, b) {DSD::DebugPrintf(__LINE__, __FILE__, a, b);} +#define DEBUG_PRINTF3(a, b, c) {DSD::DebugPrintf(__LINE__, __FILE__, a, b, c);} +#define DEBUG_PRINTF4(a, b, c, d) {DSD::DebugPrintf(__LINE__, __FILE__, a, b, c, d);} +#define DEBUG_PRINTF5(a, b, c, d, e) {DSD::DebugPrintf(__LINE__, __FILE__, a, b, c, d, e);} + +#define DEBUG_CODE_SECTION(a) TRAP_IGNORE({ a; }) + +// UTF-8 overload of the DebufPrintf method. Should be used by default, +// since it's cheaper both in CPU cycles and stack space. + +inline void DebugPrintf(TInt aLine, char* aFile, TRefByValue aFormat, ...) + { + TTruncateOverflowHandler8 overflowHandler8; + VA_LIST list; + VA_START(list, aFormat); + + TTime now; + now.HomeTime(); + + TBuf8<1024> buffer; + _LIT8(KSwiLogPrefix, "[vidsch] "); + _LIT8(KSwiLineFileFormat, "TID[%d] : [%s:%d] -- "); + buffer.Append(KSwiLogPrefix); + RThread thread; + TUint threadId = thread.Id(); + thread.Close(); + RProcess proc; + TFileName fName = proc.FileName(); + proc.Close(); + buffer.AppendFormat(KSwiLineFileFormat, threadId, aFile, aLine); + buffer.AppendFormatList(aFormat, list ,&overflowHandler8 ); + buffer.Append(_L8("\r\n")); + + RDebug::RawPrint(buffer); + + VA_END(list); + } + +// Unicode DebufPrintf overload + +inline void DebugPrintf(TInt aLine, char* aFile, TRefByValue aFormat, ...) + { + TTruncateOverflowHandler16 overflowHandler16; + VA_LIST list; + VA_START(list, aFormat); + + TTime now; + now.HomeTime(); + + TBuf8<256> header; + _LIT8(KSwiLogPrefix, "[vidsch] "); + _LIT8(KSwiLineFileFormat, "%Ld Line: % 5d, File: %s -- "); + header.Append(KSwiLogPrefix); + header.AppendFormat(KSwiLineFileFormat, now.Int64(), aLine, aFile); + + TBuf<1024> buffer; + buffer.Copy(header); + buffer.AppendFormatList(aFormat, list ,&overflowHandler16); + buffer.Append(_L("\r\n")); + + RDebug::RawPrint(buffer); + + VA_END(list); + } +#else + +#define DEBUG_PRINTF(a) +#define DEBUG_PRINTF2(a, b) +#define DEBUG_PRINTF3(a, b, c) +#define DEBUG_PRINTF4(a, b, c, d) +#define DEBUG_PRINTF5(a, b, c, d, e) + +#define DEBUG_CODE_SECTION(a) + +#endif + +#else + +#define DEBUG_PRINTF(a) +#define DEBUG_PRINTF2(a, b) +#define DEBUG_PRINTF3(a, b, c) +#define DEBUG_PRINTF4(a, b, c, d) +#define DEBUG_PRINTF5(a, b, c, d, e) + +#define DEBUG_CODE_SECTION(a) + +#endif + + +} // namespace DSD + +#endif // __SWI_LOG_H__ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/src/mmfbuffershared.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/src/mmfbuffershared.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,70 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** + @file + @internalComponent +*/ + +#ifndef MMFBUFFERSHARED_H +#define MMFBUFFERSHARED_H + +#include + +const TInt KMinBuffers = 1; +const TInt KMinBufferSize = 4000; + +/** + * The T class holds the filled buffer information for each buffer. + */ +class TFilledBufferHeaderV2 + { +public: + /** Amount of buffer filled with actual data */ + TUint iFilledLength; + /** Any timestamp associated with the buffer */ + TInt64 iTimeStamp; + /** Combination of OMX_BUFFERFLAG_*, specified at page 68 in the OpenMAX spec. */ + TUint iFlags; + /** offset **/ + TUint32 iOffset; + }; + +/** Shared chunk buffers information. It can be set by the user. */ +class TMMSharedChunkBufConfig + { +public: + /** The number of buffers. */ + TInt iNumBuffers; + /** The size of each buffer in bytes. */ + TInt iBufferSizeInBytes; + }; + +struct TBufSrcComponentHandles + { + /** The descriptor containing the name of the global chunk to be opened */ + TName iChunkName; + /** The descriptor containing the name of the global message queue + for the available buffer notification */ + TName iBufferAvailMsgQueue; + /** The descriptor containing the name of the global message queue + for the filled buffer */ + TName iBufferFilledMsgQueue; + }; + +#endif // MMFBUFFERSHARED_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/src/omxilgraphicsink.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/src/omxilgraphicsink.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,221 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +/** + @file + @internalComponent +*/ + +#include +#include + +#include "omxilgraphicsink.h" +#include "omxilgraphicsinkvpb0port.h" +#include "omxilgraphicsinkprocessingfunction.h" +#include "omxilgraphicsink.hrh" +#include +#include "log.h" + +_LIT8(KSymbianOMXGraphicSinkComponentName, KCompNameSymbianOMXGraphicSink); +_LIT8(KSymbianOMXGraphicSinkRole, KRoleSymbianOMXGraphicSink); + +const TUint8 COmxILGraphicSink::iComponentVersionMajor; +const TUint8 COmxILGraphicSink::iComponentVersionMinor; +const TUint8 COmxILGraphicSink::iComponentVersionRevision; +const TUint8 COmxILGraphicSink::iComponentVersionStep; + +OMXIL_COMPONENT_ECOM_ENTRYPOINT(KUidSymbianOmxILGraphicSink); + +/** +Component Entry Point +@param aComponent The handle of the component to be initialised. +@return KErrNone if successful; + KErrNoMemory if the driver failed to allocate memory for the new component; + otherwise one of the other system-wide error codes. +*/ +OMX_ERRORTYPE OMX_ComponentInit(OMX_HANDLETYPE aComponent) + { + TInt err = COmxILGraphicSink::CreateComponent(aComponent); + if (err == KErrNone) + { + return OMX_ErrorNone; + } + else + { + // return some problem + return err == KErrNoMemory ? OMX_ErrorInsufficientResources : OMX_ErrorUndefined; + + } + } + +/** +This function creates a new Graphic sink component. +@param aComponent The handle of the component to be created. +@return KErrNone if successful; + KErrNoMemory if the driver failed to allocate memory for the new component; + otherwise one of the other system-wide error codes. +*/ +TInt COmxILGraphicSink::CreateComponent(OMX_HANDLETYPE aComponent) + { + DEBUG_PRINTF(_L8("COmxILGraphicSink::CreateComponent")); + + COmxILGraphicSink* self = new COmxILGraphicSink(); + + if (!self) + { + return KErrNoMemory; + } + + TRAPD(err, self->ConstructL(aComponent)); + + if(err != KErrNone) + { + delete self; + } + + return err; + + } + +/** +Constructor of the class. +*/ +COmxILGraphicSink::COmxILGraphicSink() + { + DEBUG_PRINTF(_L8("COmxILGraphicSink::COmxILGraphicSink +")); + } + +/** +Destructor of the class. +*/ +COmxILGraphicSink::~COmxILGraphicSink() + { + DEBUG_PRINTF(_L8("COmxILGraphicSink::~COmxILGraphicSink +")); + } + +/** +Second phase construction for the component. +@param aHandle The handle of the component to be created. +*/ +void COmxILGraphicSink::ConstructL(OMX_HANDLETYPE aHandle) + { + DEBUG_PRINTF(_L8("COmxILGraphicSink::ConstructL")); + // Initialize the data received from IL Core + COmxILComponent::ConstructL(aHandle); + + // STEP 2: Create the call backs manager... + MOmxILCallbackNotificationIf* callbackNotificationIf=CreateCallbackManagerL(COmxILComponent::EOutofContext); + + // STEP 3: Create the Graphic Sink Processing Function... + COmxILGraphicSinkProcessingFunction* pGraphicSinkProcessingFunction = COmxILGraphicSinkProcessingFunction::NewL(*callbackNotificationIf); + RegisterProcessingFunction(pGraphicSinkProcessingFunction); + + // STEP 4: Create Port manager... + CreatePortManagerL(COmxILComponent::ENonBufferSharingPortManager, + TOmxILSpecVersion(), // OMX Version + 0, // The number of audio ports in this component + 0, // The starting audio port index + 0, // The number of image ports in this component + 0, // The starting image port index + 1, // The number of video ports in this component + 0, // The starting video port index + 0, // The number of other ports in this component + 0 // The starting other port index + ); + + COmxILGraphicSinkVPB0Port* pb0Port = ConstructVPB0PortL(); + CleanupStack::PushL(pb0Port); + User::LeaveIfError(AddPort(pb0Port, OMX_DirInput)); + CleanupStack::Pop(pb0Port); + SetPortToPF(pb0Port); + + // STEP 5: Create the non-port related configuration manager... + RPointerArray componentRoles; + CleanupClosePushL(componentRoles); + componentRoles.AppendL(&KSymbianOMXGraphicSinkRole); + COmxILConfigManager* pConfigManager = COmxILConfigManager::NewL( + KSymbianOMXGraphicSinkComponentName, + TOmxILVersion(iComponentVersionMajor, + iComponentVersionMinor, + iComponentVersionRevision, + iComponentVersionStep), + componentRoles); + + CleanupStack::PopAndDestroy(&componentRoles); + RegisterConfigurationManager(pConfigManager); + + // And finally, let's get everything started + InitComponentL(); + } + +/** +Create the input port VPB0Port for Graphic sink. +@return A pointer to the VPB0Port to be created. +*/ +COmxILGraphicSinkVPB0Port* COmxILGraphicSink::ConstructVPB0PortL() + { + DEBUG_PRINTF(_L8("COmxILGraphicSink::ConstructVPB0PortL +")); + + OMX_U32 thisPortIndex = 0; + const TUint32 KBufferCountMin = 2; // OMX_U32 + const TUint32 KBufferSizeMin = 1024; // OMX_U32 +#ifndef ILCOMPONENTCONFORMANCE + const TUint32 KBufferAlignment = 2; // OMX_U32 + const OMX_BOOL KBuffersContiguous = OMX_TRUE; +#else + // conformance suite currently doesn't support allocating contiguous or + // beyond byte aligned buffers + const TUint32 KBufferAlignment = 0; // OMX_U32 + const OMX_BOOL KBuffersContiguous = OMX_FALSE; +#endif + // These arrays must left empty, to be removed from the video port constructor + RArray supportedVideoFormats; + RArray supportedColorFormats; + CleanupClosePushL(supportedVideoFormats); + CleanupClosePushL(supportedColorFormats); + + COmxILGraphicSinkVPB0Port* vpb0Port = COmxILGraphicSinkVPB0Port::NewL( + TOmxILCommonPortData( + TOmxILSpecVersion(),// OMX specification version information + thisPortIndex, // Port number the structure applies to + OMX_DirInput, // Direction of this port + KBufferCountMin, // The minimum number of buffers this port requires + KBufferSizeMin, // Minimum size, in bytes, for buffers to be used for this port + OMX_PortDomainVideo,// Domain of the port + KBuffersContiguous, // Buffers contiguous requirement (true or false) + KBufferAlignment, // Buffer aligment requirements + OMX_BufferSupplyInput, // supplier preference when tunneling between two ports + COmxILPort::KBufferMarkPropagationPortNotNeeded + ), + supportedVideoFormats, // Supported video formats + supportedColorFormats, // Supported color formats + *((COmxILGraphicSinkProcessingFunction *)(GetProcessingFunction())) + ); + + CleanupStack::PopAndDestroy(2, &supportedVideoFormats); + + return vpb0Port; + } + +/* +Set the graphic sink port to the graphic sink processing function, +so the processing function can access the port definition later. + */ +void COmxILGraphicSink::SetPortToPF(COmxILGraphicSinkVPB0Port* aPort) + { + ((COmxILGraphicSinkProcessingFunction *)(GetProcessingFunction()))->iGraphicSinkPort = aPort; + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/src/omxilgraphicsink.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/src/omxilgraphicsink.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +/** + @file + @internalComponent +*/ + +#ifndef OMXILGRAPHICSINK_H +#define OMXILGRAPHICSINK_H + +#include + +class COmxILGraphicSinkVPB0Port; +class COmxILGraphicSinkProcessingFunction; + +/** +OpenMAX IL based graphics sink component class +*/ +class COmxILGraphicSink : public COmxILComponent + { +public: + /** The major version number of component. */ + static const TUint8 iComponentVersionMajor = OMX_VERSION_MAJOR; + /** The minor version number of component. */ + static const TUint8 iComponentVersionMinor = OMX_VERSION_MINOR; + /** The revision version number of component. */ + static const TUint8 iComponentVersionRevision = OMX_VERSION_REVISION; + /** The step version number of component. */ + static const TUint8 iComponentVersionStep = OMX_VERSION_STEP; + +public: + static TInt CreateComponent(OMX_HANDLETYPE aComponent); + ~COmxILGraphicSink(); + +private: + COmxILGraphicSink(); + void ConstructL(OMX_HANDLETYPE aHandle); + + COmxILGraphicSinkVPB0Port* ConstructVPB0PortL(); + void SetPortToPF(COmxILGraphicSinkVPB0Port* aPort); + }; + +#endif // OMXILGRAPHICSINK_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/src/omxilgraphicsink.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/src/omxilgraphicsink.hrh Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +/** + @file + @internalComponent +*/ + +#ifndef OMXILGRAPHICSINK_HRH +#define OMXILGRAPHICSINK_HRH + +#define KUidSymbianOmxILGraphicSinkDll 0x10285E6D +#define KUidSymbianOmxILGraphicSink 0x10285E6E + +#define KCompNameSymbianOMXGraphicSink "OMX.SYMBIAN.VIDEO.GRAPHICSINK" +#define KRoleSymbianOMXGraphicSink "iv_renderer" + +#endif // OMXILGRAPHICSINK_HRH + diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/src/omxilgraphicsink.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/src/omxilgraphicsink.rss Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +/** + @file + @internalComponent +*/ + +#include +#include +#include "omxilgraphicsink.hrh" + +RESOURCE REGISTRY_INFO theInfo + { + dll_uid = KUidSymbianOmxILGraphicSinkDll; + interfaces = + { + INTERFACE_INFO + { + interface_uid = KUidOmxILSymbianComponentIf; + implementations = + { + IMPLEMENTATION_INFO + { + implementation_uid = KUidSymbianOmxILGraphicSink; + version_no = 1; + display_name = KCompNameSymbianOMXGraphicSink; + default_data = KRoleSymbianOMXGraphicSink; + // opaque_data = "0x1027379eVORB P16"; + } + }; + } + }; + } + diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkextensionsindexes.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkextensionsindexes.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef OMXILGRAPHICSINKEXTENSIONSINDEXES_H_ +#define OMXILGRAPHICSINKEXTENSIONSINDEXES_H_ + +/* + * Index for the surface configuration extension + */ +#define OMX_NokiaIndexParamGraphicSurfaceConfig 0x7F000011 +#define OMX_SymbianIndexConfigSharedChunkMetadata 0x7F000012 + +#endif //OMXILGRAPHICSINKEXTENSIONSINDEXES_H_ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkpanics.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkpanics.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include "omxilgraphicsinkpanics.h" +#include + +_LIT(KGraphicSinkPanicCategory, "omxilgraphicsink"); + +/** +Raises a panic. +@param The panic to be raised. +*/ +void Panic(TGraphicSinkPanicCode aCode) + { + User::Panic(KGraphicSinkPanicCategory, aCode); + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkpanics.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkpanics.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +/** + @file + @internalComponent + */ + +#ifndef OMXILGRAPHICSINKPANICS_H_ +#define OMXILGRAPHICSINKPANICS_H_ + +enum TGraphicSinkPanicCode + { + EUndefinedPixelFormat = 0 // pixel format not handled + }; + +void Panic(TGraphicSinkPanicCode aCode); + +#endif /*OMXILGRAPHICSINKPANICS_H_*/ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkprocessingfunction.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkprocessingfunction.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,1349 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +/** + @file + @internalComponent +*/ + +#include "log.h" + +#include "omxilgraphicsinkprocessingfunction.h" +#include "omxilgraphicsinktrace.h" +#include "omxilgraphicsinkpanics.h" +#include "omxilgraphicsinkvpb0port.h" +#include +#include +#include "omxilgraphicsinkextensionsindexes.h" +#include +#include + +// Constant numbers +#ifndef __WINSCW__ +const TInt KRefGfxAlignment = RSurfaceManager::EPageAligned; +#else +const TInt KRefGfxAlignment = 2; +#endif +static const TBool KRefGfxContiguous = ETrue; +static const TInt KSurfaceUpdateNumOfMessageSlots = 4; +static const TUint32 KNullTickCount = 0xFFFFFFFF; + + +/** +Create a new processing function object. + +@param aCallbacks The callback manager interface for processing function. + +@return A pointer to the processing function object to be created. +*/ +COmxILGraphicSinkProcessingFunction* +COmxILGraphicSinkProcessingFunction::NewL(MOmxILCallbackNotificationIf& aCallbacks) + { + COmxILGraphicSinkProcessingFunction* self = + new (ELeave)COmxILGraphicSinkProcessingFunction(aCallbacks); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +/** +Second phase construction for the processing function. Loads the device driver for surface manager and initializes the surface attributes. +*/ +void +COmxILGraphicSinkProcessingFunction::ConstructL() + { + iTransitionToPauseWait = new(ELeave) CActiveSchedulerWait(); + User::LeaveIfError(iTransitionToPauseWaitSemaphore.CreateLocal(0)); + + //record the ID of the creator thread for later use + iOwnerThreadId = RThread().Id(); + + iGraphicSurfaceAccess = CGraphicSurfaceAccess::NewL(*this); + iPFHelper = CPFHelper::NewL(*this, *iGraphicSurfaceAccess); + + User::LeaveIfError(iBufferMutex.CreateLocal()); + InitSurfaceAttributes(); + iState = OMX_StateLoaded; + } + +/** +Constructor of the class. + +@param aCallbacks The callback manager interface for processing function. +*/ +COmxILGraphicSinkProcessingFunction::COmxILGraphicSinkProcessingFunction( + MOmxILCallbackNotificationIf& aCallbacks) + : + COmxILProcessingFunction(aCallbacks) + { + HAL::Get(HALData::EFastCounterFrequency,iFastCounterFrequency); + } + +/** +Destructor of the class. +*/ +COmxILGraphicSinkProcessingFunction::~COmxILGraphicSinkProcessingFunction() + { + delete iTransitionToPauseWait; + iTransitionToPauseWaitSemaphore.Close(); + + // Check in case the driver has not been closed. That would happen in + // an scenario where the component is deleted while being in + // OMX_StateExecuting state. + if(iPFHelper && + (iState == OMX_StateInvalid || + iState == OMX_StateExecuting || + iState == OMX_StatePause)) + { + // Ignore error if the following call fails + iPFHelper->StopSync(); + } + + delete iPFHelper; + delete iGraphicSurfaceAccess; + + iSurfaceManager.Close(); + + // Buffer headers are not owned by the processing function + iBuffersToEmpty.Close(); + + iBufferMutex.Close(); + } + +/** +This method provides the state change information within the processing function so that appropriate action can be taken. +This state change information is provided by the FSM on behalf of the IL Client. + +@param aNewState The new state of FSM. + +@return OMX_ErrorNone if successful + OMX_ErrorInsufficientResources if fail to start GraphicSink frame acceptor + OMX_ErrorIncorrectStateTransition if unsupported state + Any other OpenMAX IL wide error code +*/ +OMX_ERRORTYPE +COmxILGraphicSinkProcessingFunction::StateTransitionIndication(TStateIndex aNewState) + { + switch(aNewState) + { + case EStateExecuting: + { + return iPFHelper->ExecuteAsync(); + } + case EStateInvalid: + { + return iPFHelper->StopAsync(); + } + case EStatePause: + { + // must be done immediately + OMX_ERRORTYPE omxErr = iPFHelper->Pause(); + if(omxErr == OMX_ErrorNone) + { + WaitForTransitionToPauseToFinish(); + } + return omxErr; + } + case EStateIdle: + { + iBufferMutex.Wait(); + iBuffersToEmpty.Reset(); + iBufferMutex.Signal(); + iState = OMX_StateIdle; + return OMX_ErrorNone; + } + case EStateLoaded: + case EStateWaitForResources: + { + return iPFHelper->StopAsync(); + } + case ESubStateLoadedToIdle: + { + // Open a channel to the surface manager logical device driver. + TInt err = iSurfaceManager.Open(); + if ( err != KErrNone) + { + return OMX_ErrorHardware; + } + + if (iPFHelper->OpenDevice() != KErrNone) + { + return OMX_ErrorInsufficientResources; + } + /* + if (iGraphicSinkPort->ValidateStride() != OMX_ErrorNone) + { + return OMX_ErrorUnsupportedSetting; + } + return OMX_ErrorNone; + */ + return iGraphicSinkPort->ValidateStride(); + } + case ESubStateIdleToLoaded: + { + return iPFHelper->CloseDevice(); + } + case ESubStateExecutingToIdle: + { + // must be done immediately + return iPFHelper->StopAsync(); + } + case ESubStatePauseToIdle: + { + // Ignore these transitions... + return OMX_ErrorNone; + } + default: + { + return OMX_ErrorIncorrectStateTransition; + } + }; + } + +/** +Flushes all the buffers retained by the processing function and sends it to either IL Client or the Tunelled component, as the case may be. + +@param aPortIndex Port index used to flush buffers from a given port of the component. +@param aDirection This describes the direction of the port. + +@return OMX_ErrorNone if successful; + Any other OpenMAX IL wide error code; +*/ +OMX_ERRORTYPE +COmxILGraphicSinkProcessingFunction::BufferFlushingIndication( + TUint32 aPortIndex, + OMX_DIRTYPE aDirection) + { + iBufferMutex.Wait(); + if ((aPortIndex == OMX_ALL && aDirection == OMX_DirMax) || + (aPortIndex == 0 && aDirection == OMX_DirInput)) + { + // Send BufferDone notifications for each buffer... + if(iBufferOnScreen) + { + iCallbacks.BufferDoneNotification(iBufferOnScreen, 0, OMX_DirInput); + iBufferOnScreen = NULL; + } + const TUint bufferCount = iBuffersToEmpty.Count(); + OMX_BUFFERHEADERTYPE* pBufferHeader = 0; + for (TUint i=0; inTickCount = KNullTickCount; + iCallbacks. + BufferDoneNotification( + pBufferHeader, + pBufferHeader->nInputPortIndex, + OMX_DirInput + ); + } + // Empty buffer lists... + iBuffersToEmpty.Reset(); + + iBufferMutex.Signal(); + return OMX_ErrorNone; + } + else + { + iBufferMutex.Signal(); + return OMX_ErrorBadParameter; + } + } + +/** +Update the structure corresponding to the given index which belongs to the static parameters list. + +@param aParamIndex The index representing the desired structure to be updated. +@param aComponentParameterStructure A pointer to structure which has the desired settings that will be used to update the Processing function. + +@return OMX_ErrorNone if successful; + OMX_ErrorUnsupportedIndex if unsupported index; + OMX_ErrorUnsupportedSetting if pixel format is EUidPixelFormatUnknown; + Any other OpenMAX IL wide error code; +*/ +OMX_ERRORTYPE +COmxILGraphicSinkProcessingFunction::ParamIndication( + OMX_INDEXTYPE aParamIndex, + const TAny* apComponentParameterStructure) + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkProcessingFunction::PortParamIndication")); + + switch(aParamIndex) + { + case OMX_IndexParamPortDefinition: + { + const OMX_PARAM_PORTDEFINITIONTYPE* portDefinition = static_cast(apComponentParameterStructure); + + // + // All the fields in SurfaceAttribute structure should be updated. + // + iGraphicSurfaceSettings.iSurfaceAttributes.iSize.iWidth = portDefinition->format.video.nFrameWidth; + iGraphicSurfaceSettings.iSurfaceAttributes.iSize.iHeight = portDefinition->format.video.nFrameHeight; + + // Need to convert OMX Color Format to TUidPixelFormat. + TUidPixelFormat pixelFormat = ConvertPixelFormat(portDefinition->format.video.eColorFormat); + if(pixelFormat == EUidPixelFormatUnknown) + { + return OMX_ErrorUnsupportedSetting; + } + else + { + iGraphicSurfaceSettings.iSurfaceAttributes.iPixelFormat = pixelFormat; + } + + iGraphicSurfaceSettings.iSurfaceAttributes.iBuffers = portDefinition->nBufferCountActual; + iGraphicSurfaceSettings.iSurfaceAttributes.iStride = portDefinition->format.video.nStride; + break; + } + case OMX_IndexParamVideoPortFormat: + { + const OMX_VIDEO_PARAM_PORTFORMATTYPE* videoPortFormat = static_cast(apComponentParameterStructure); + + // only OMX_COLOR_FORMATTYPE eColorFormat to be used for SurfaceAttributes.iPixelFormat + TUidPixelFormat pixelFormat = ConvertPixelFormat(videoPortFormat->eColorFormat); + if(pixelFormat == EUidPixelFormatUnknown) + { + return OMX_ErrorUnsupportedSetting; + } + else + { + iGraphicSurfaceSettings.iSurfaceAttributes.iPixelFormat = pixelFormat; + } + break; + } + default: + { + return OMX_ErrorUnsupportedIndex; + } + } + return OMX_ErrorNone; + } + +/** +Update the structure corresponding to the given index which belongs to the dynamic configuration list. + +@param aConfigIndex The index representing the desired structure to be updated. +@param aComponentConfigStructure A pointer to structure which has the desired settings that will be used to update the Processing function. + +@return OMX_ErrorNone if successful; + OMX_ErrorUnsupportedIndex if unsupported index; + OMX_ErrorUnsupportedSetting if SurfaceConfiguration returns error; + Any other OpenMAX IL wide error code; +*/ +OMX_ERRORTYPE +COmxILGraphicSinkProcessingFunction::ConfigIndication(OMX_INDEXTYPE aConfigIndex, + const TAny* apComponentConfigStructure) + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkProcessingFunction::ConfigIndication")); + + TInt err = KErrNone; + + switch(aConfigIndex) + { + case OMX_SymbianIndexConfigSharedChunkMetadata: + { + const OMX_SYMBIAN_CONFIG_SHAREDCHUNKMETADATATYPE* + pSharedChunkMetadata + = static_cast< + const OMX_SYMBIAN_CONFIG_SHAREDCHUNKMETADATATYPE*>( + apComponentConfigStructure); + + iGraphicSurfaceAccess->iSharedChunkHandleId = pSharedChunkMetadata->nHandleId; + iGraphicSurfaceAccess->iSharedChunkThreadId = pSharedChunkMetadata->nOwnerThreadId; + + iGraphicSurfaceAccess->iIsLocalChunk = EFalse; + break; + } + case OMX_IndexConfigCommonScale: + { + const OMX_CONFIG_SCALEFACTORTYPE* scaleFactor = static_cast(apComponentConfigStructure); + + err = iGraphicSurfaceSettings.iSurfaceConfig.SetExtent(TRect(TSize(scaleFactor->xWidth, scaleFactor->xHeight))); + if(err != KErrNone) + { + return OMX_ErrorUnsupportedSetting; + } + + break; + } + case OMX_IndexConfigCommonOutputSize: + { + const OMX_FRAMESIZETYPE* frameSize = static_cast(apComponentConfigStructure); + + err = iGraphicSurfaceSettings.iSurfaceConfig.SetExtent(TRect(TSize(frameSize->nWidth, frameSize->nHeight))); + if(err != KErrNone) + { + return OMX_ErrorUnsupportedSetting; + } + + break; + } + case OMX_IndexConfigCommonInputCrop: + case OMX_IndexConfigCommonOutputCrop: + case OMX_IndexConfigCommonExclusionRect: + { + const OMX_CONFIG_RECTTYPE* rec = static_cast(apComponentConfigStructure); + + err = iGraphicSurfaceSettings.iSurfaceConfig.SetExtent(TRect(TPoint(rec->nTop, rec->nLeft), TSize(rec->nWidth, rec->nHeight))); + if(err != KErrNone) + { + return OMX_ErrorUnsupportedSetting; + } + + break; + } + default: + { + return OMX_ErrorUnsupportedIndex; + } + } + + return OMX_ErrorNone; + } + +void COmxILGraphicSinkProcessingFunction::SetSharedChunkBufConfig(TMMSharedChunkBufConfig aSharedChunkBufConfig) + { + iGraphicSurfaceAccess->iSharedChunkBufConfig = aSharedChunkBufConfig; + } + +void COmxILGraphicSinkProcessingFunction::GetSharedChunkMetadata( + OMX_U32& aHandleId, + OMX_U64& aThreadId) const + { + aHandleId = iGraphicSurfaceAccess->iSharedChunkHandleId; + aThreadId = iGraphicSurfaceAccess->iSharedChunkThreadId; + } + +/** +This method is invoked whenever the component is requested to emtpy/display the contents of the buffers passed as function arguments. + +@param apBufferHeader A pointer to buffer header. +@param aDirection provides the direction either input or output. This can be used as a further check whether buffers received are valid or not. + +@return OMX_ErrorNone if successful; + Any other OpenMAX IL wide error code; +*/ +OMX_ERRORTYPE +COmxILGraphicSinkProcessingFunction::BufferIndication( + OMX_BUFFERHEADERTYPE* apBufferHeader, + OMX_DIRTYPE aDirection) + { + if (aDirection != OMX_DirInput) + { + return OMX_ErrorBadParameter; + } + //The nTickCount is just internal here, stored temporarily. So it is count not time period. + apBufferHeader->nTickCount = User::FastCounter(); + iBufferMutex.Wait(); + OMX_ERRORTYPE ret = OMX_ErrorNone; + if (iBuffersToEmpty.Append(apBufferHeader) != KErrNone) + { + apBufferHeader->nTickCount = KNullTickCount; + ret = OMX_ErrorInsufficientResources; + } + else if (iState != OMX_StateExecuting) + { + // If Component not in an executing state delay processing buffer + ret = OMX_ErrorNone; + } + else if (iPFHelper->BufferIndication() != KErrNone) + { + apBufferHeader->nTickCount = KNullTickCount; + ret = OMX_ErrorInsufficientResources; + } + iBufferMutex.Signal(); + return ret; + } + +/** +This method is used to check whether the required buffer is held by the processing function or not. + +@param apBufferHeader A pointer to buffer header being searched. +@param aDirection provides the direction either input or output. This can be used as a further check whether buffers received are valid or not. + +@return OMX_TRUE if find the buffer; + OMX_FALSE if fail to find the buffer; +*/ +OMX_BOOL +COmxILGraphicSinkProcessingFunction::BufferRemovalIndication( + OMX_BUFFERHEADERTYPE* apBufferHeader, + OMX_DIRTYPE /* aDirection */) + { + TBool headerDeletionResult = ETrue; + + TInt headerIndexInArray = KErrNotFound; + iBufferMutex.Wait(); + if (KErrNotFound != + (headerIndexInArray = + iBuffersToEmpty.Find(apBufferHeader))) + { + iBuffersToEmpty.Remove(headerIndexInArray); + } + else if(iBufferOnScreen == apBufferHeader) + { + iBufferOnScreen = NULL; + } + else + { + headerDeletionResult = EFalse; + } + iBufferMutex.Signal(); + return (headerDeletionResult ? OMX_TRUE : OMX_FALSE); + } + +/** +This method creates COmxILMMBuffer class object. Also creates surface and allocates the chunks based on the number of buffers, +maps the surface in the given process. It also allocates the resources like creating the message queue and other necessary C +class objects. This method gets called when the component acts as buffer supplier. + +@param aPortSpecificBuffer gives the starting address of the specific buffer. +@param aPortPrivate gives the private data which is COmxILMMBuffer pointer in this case. + +@leave OMX_ErrorNone if successful; +@leave OMX_ErrorInsufficientResources if function returns KErrNoMemory; +@leave OMX_ErrorBadParameter if function returns errors except KErrNoMemory; +@leave Any other OpenMAX IL wide error code; +*/ +void COmxILGraphicSinkProcessingFunction::CreateBufferL(OMX_U8*& aPortSpecificBuffer, OMX_PTR& aPortPrivate, OMX_U32 aBufferCountActual) + { + iGraphicSurfaceAccess->CreateBufferL(aPortSpecificBuffer, aPortPrivate, aBufferCountActual); + } + +/** +Destroy MM buffer, close surface, and deallocate other resources like message queue and C class objects. This is called when component +acts as buffer supplier. +@param apPortPrivate gives the private data which is COmxILMMBuffer pointer in this case. +*/ +void COmxILGraphicSinkProcessingFunction::DestroyBuffer(OMX_PTR /*apPortPrivate*/) + { + if( iGraphicSurfaceAccess ) + { + iGraphicSurfaceAccess->iBufferIdGenerator--; + // to reset surface id in case client requests different settings. + if(iGraphicSurfaceAccess->iBufferIdGenerator == 0) + { + iGraphicSurfaceAccess->ResetSurfaceId(); + iGraphicSurfaceAccess->CloseChunk(); + } + } + } + +/** +Creates the surface by utilizing the buffers passed via application private data. It then maps the surface in the given process. +It also allocates the resources like creating the message queue and other necessary C class objects. This method gets called when +the component acts as non buffer supplier. + +@param aSizeBytes The size of buffer. +@param apBuffer gives the starting address of the specific buffer. +@param aAppPrivate provides the private data which is COmxILMMBuffer pointer in this case and holds details of buffers already allocated. +@param aBufferCountActual The actual number of buffers. + +@leave OMX_ErrorNone if successful; +@leave OMX_ErrorInsufficientResources if aPortPrivate is null or functions return KErrNoMemory; +@leave OMX_ErrorBadParameter if functions return errors except KErrNoMemory; +@leave Any other OpenMAX IL wide error code; +*/ +void COmxILGraphicSinkProcessingFunction::InitBufferL(OMX_U32 aSizeBytes, OMX_U8* apBuffer, OMX_U32 aBufferCountActual) + { + iGraphicSurfaceAccess->InitBufferL(aSizeBytes, apBuffer, aBufferCountActual); + } + +/** +Deallocate resources like message queue and C class objects. This is called when component acts as non buffer supplier. +*/ +void COmxILGraphicSinkProcessingFunction::DeInitBuffer() + { + // to reset surface id in case client requests different settings. + if(iGraphicSurfaceAccess) + { + iGraphicSurfaceAccess->ResetSurfaceId(); + iGraphicSurfaceAccess->CloseChunk(); + } + } + +/** +Initialise surface attribute structure. +*/ +void COmxILGraphicSinkProcessingFunction::InitSurfaceAttributes() + { + RSurfaceManager::TSurfaceCreationAttributes* attr = &iGraphicSurfaceSettings.iSurfaceAttributes; + + attr->iAlignment = KRefGfxAlignment; + attr->iContiguous = KRefGfxContiguous; + attr->iCacheAttrib = RSurfaceManager::ENotCached; + attr->iMappable = ETrue; + } + +TUidPixelFormat COmxILGraphicSinkProcessingFunction::ConvertPixelFormat(OMX_COLOR_FORMATTYPE aColorFormat) + { + switch(aColorFormat) + { + // OMX "Planar" formats not currently supported by GraphicSink since data comes in more than one buffer. + // "PackedPlanar" formats can be added easily provided the GCE backend supports them. + + case OMX_COLOR_Format16bitRGB565: + return EUidPixelFormatRGB_565; + + case OMX_COLOR_Format32bitARGB8888: + return EUidPixelFormatARGB_8888; + + case OMX_COLOR_FormatYCrYCb: + return EUidPixelFormatYUV_422Reversed; + + case OMX_COLOR_FormatCbYCrY: + return EUidPixelFormatYUV_422Interleaved; + + // Need to map color format to Symbian pixel format. + default: + { + return EUidPixelFormatUnknown; + } + } + } + +void COmxILGraphicSinkProcessingFunction::WaitForTransitionToPauseToFinish() + { + if(RThread().Id() == iOwnerThreadId) + { + //if the owner thread is the same thread as the one created the active objects in this processing function + //then we can wait by using CActiveSchedulerWait + DEBUG_PRINTF(_L8("GraphicSinkProcessingFunction::WaitForTransitionToPauseToFinish - blocking transition to pause with active scheduler wait now")); + iTransitionToPauseWait->Start(); + } + else + { + //if this is a thread different from the creator thread then semaphore is needed to block this thread until the transition + //to paused state completes + DEBUG_PRINTF(_L8("GraphicSinkProcessingFunction::WaitForTransitionToPauseToFinish - blocking thread with semaphore now")); + iTransitionToPauseWaitSemaphore.Wait(); + } + } + +void COmxILGraphicSinkProcessingFunction::TransitionToPauseFinished() + { + if(iTransitionToPauseWait->IsStarted()) + { + DEBUG_PRINTF(_L8("GraphicSinkProcessingFunction::TransitionToPauseFinished - unblocking transition to pause (active scheduler wait) now")); + iTransitionToPauseWait->AsyncStop(); + } + else + { + DEBUG_PRINTF(_L8("GraphicSinkProcessingFunction::TransitionToPauseFinished - unblocking transition to pause (semaphore) now")); + iTransitionToPauseWaitSemaphore.Signal(); + } + } + +COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess* COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::NewL(COmxILGraphicSinkProcessingFunction& aParent) + { + return new (ELeave) CGraphicSurfaceAccess(aParent); + } + +COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::CGraphicSurfaceAccess(COmxILGraphicSinkProcessingFunction& aParent) +: CActive(EPriorityStandard), + iIsLocalChunk(ETrue), + iParent(aParent) + { + CActiveScheduler::Add(this); + iSurfaceId = TSurfaceId::CreateNullId(); + iOffsetArray.Reset(); + } + +void COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::CloseChunk() + { + if(iChunk.Handle()) + { + iChunk.Close(); + } + } + +COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::~CGraphicSurfaceAccess() + { + Cancel(); + + CloseChunk(); + + if (!iSurfaceId.IsNull()) + { + iParent.SurfaceManager().CloseSurface(iSurfaceId); // ignore the error + } + #ifdef ILCOMPONENTCONFORMANCE + iArrayOffsets.Close(); + #endif + + iOffsetArray.Close(); + iSurfaceUpdateSession.Close(); + + } + +void COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::RunL() + { + // The buffer is not on the list implies that they have already been flushed/spotted + // via BufferFlushingIndication/BufferRemovalIndication + iParent.iBufferMutex.Wait(); + TInt index = iParent.BuffersToEmpty().Find(iCurrentBuffer); + if (KErrNotFound != index) + { + switch(iStatus.Int()) + { + case KErrNone: + { + // Consumed all data completely and setting nFilledLen to zero. + iCurrentBuffer->nFilledLen = 0; + break; + } + case KErrCancel: + default: + { + // Leave actual value of iCurrentBuffer->nFilledLen + DEBUG_PRINTF2(_L8("COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::RunL() err = %d"), iStatus.Int()); + } + }; + + if(iStatus.Int() != KErrNone) + { + iCurrentBuffer->nTickCount = KNullTickCount; + } + else + { + TUint32 currentTickCount = User::FastCounter(); + + // On some hardware boards, tick count decrements as time increases so + // need to check which way the counter is going + if (currentTickCount >= iCurrentBuffer->nTickCount) + { + iCurrentBuffer->nTickCount = (currentTickCount - iCurrentBuffer->nTickCount) / iParent.GetFastCounterFrequency(); + } + else + { + iCurrentBuffer->nTickCount = (iCurrentBuffer->nTickCount - currentTickCount) / iParent.GetFastCounterFrequency(); + } + } + + + if(iCurrentBuffer->nFlags & OMX_BUFFERFLAG_EOS) + { + iParent.GetCallbacks().EventNotification(OMX_EventBufferFlag, iCurrentBuffer->nInputPortIndex, iCurrentBuffer->nFlags, NULL); + } + + iCurrentBuffer->nFilledLen = 0; + iCurrentBuffer->nFlags = 0; + iCurrentBuffer->nOffset = 0; + iCurrentBuffer->nTimeStamp = 0; + + // now sending back to framework.. + if(iParent.iBufferOnScreen) + { + // Add error handling? + iParent.GetCallbacks().BufferDoneNotification(iParent.iBufferOnScreen, iParent.iBufferOnScreen->nInputPortIndex,OMX_DirInput); + } + iParent.iBufferOnScreen = iCurrentBuffer; + + iParent.BuffersToEmpty().Remove(index); + iCurrentBuffer = NULL; + + // check if any more buffers to be consumed.. + if (ProcessNextBuffer() != KErrNone) + { + iParent.GetCallbacks().ErrorEventNotification(OMX_ErrorInsufficientResources); + } + } + iParent.iBufferMutex.Signal(); + } + +void COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::CreateBufferL(OMX_U8*& aPortSpecificBuffer, OMX_PTR& aPortPrivate, OMX_U32 aBufferCountActual) + { + if(iSurfaceId.IsNull()) + { + // race condition on nBufferCountActual + if(aBufferCountActual != iParent.GraphicSurfaceSettings().iSurfaceAttributes.iBuffers) + { + iParent.GraphicSurfaceSettings().iSurfaceAttributes.iBuffers = aBufferCountActual; + } + + User::LeaveIfError(iParent.SurfaceManager().CreateSurface(iParent.GraphicSurfaceSettings().iSurfaceAttributesBuf, iSurfaceId)); + + RChunk chunk; + CleanupClosePushL(chunk); + User::LeaveIfError(iParent.SurfaceManager().MapSurface(iSurfaceId, chunk)); + + //We need to change the chunk handle to be shared by the whole process. + RThread thread; + CleanupClosePushL(thread); + iChunk.SetHandle(chunk.Handle()); + User::LeaveIfError(iChunk.Duplicate(thread)); + CleanupStack::PopAndDestroy(2, &chunk); + + // for SetConfig(OMX_SYMBIAN_CONFIG_SHARED_CHUNK_METADATA) + iSharedChunkHandleId = iChunk.Handle(); + iSharedChunkThreadId = RThread().Id().Id(); + + switch(iParent.iGraphicSurfaceSettings.iSurfaceAttributes.iPixelFormat) + { + case EUidPixelFormatYUV_422Reversed: + { + // fill buffer 0 with black + TUint32* data = reinterpret_cast(iChunk.Base()); + TInt numPixelPairs = iParent.GraphicSurfaceSettings().iSurfaceAttributes.iStride * iParent.GraphicSurfaceSettings().iSurfaceAttributes.iSize.iHeight / 4; + for(TInt offset = 0; offset < numPixelPairs; offset++) + { + data[offset] = 0x80108010; + } + } + break; + case EUidPixelFormatYUV_422Interleaved: + { + // fill buffer 0 with black + TUint32* data = reinterpret_cast(iChunk.Base()); + TInt numPixelPairs = iParent.GraphicSurfaceSettings().iSurfaceAttributes.iStride * iParent.GraphicSurfaceSettings().iSurfaceAttributes.iSize.iHeight / 4; + for(TInt offset = 0; offset < numPixelPairs; offset++) + { + data[offset] = 0x10801080; + } + } + break; + case EUidPixelFormatRGB_565: + case EUidPixelFormatARGB_8888: + Mem::FillZ(iChunk.Base(), iParent.GraphicSurfaceSettings().iSurfaceAttributes.iStride * iParent.GraphicSurfaceSettings().iSurfaceAttributes.iSize.iHeight); + break; + default: +#ifdef _DEBUG + // Panic in a debug build. It will make people think about how the error should be handled. + Panic(EUndefinedPixelFormat); +#endif + break; + } + + // Now, GFX needs to make sure that TSurfaceConfiguration has valid surface id + // so that IL Client can use RSurfaceManager::SetBackroundSurface() + User::LeaveIfError(iParent.GraphicSurfaceSettings().iSurfaceConfig.SetSurfaceId(iSurfaceId)); + iParent.iCallbacks.EventNotification(OMX_EventPortSettingsChanged, OMX_NokiaIndexParamGraphicSurfaceConfig, 0, NULL); + + chunk.Close(); + #ifdef ILCOMPONENTCONFORMANCE + iIsBufferSupplier = ETrue; + #endif + } + + ASSERT(iChunk.Handle()); + + + RSurfaceManager::TInfoBuf surfaceInfoBuf; + RSurfaceManager::TSurfaceInfoV01& surfaceInfo (surfaceInfoBuf()); + User::LeaveIfError(iParent.SurfaceManager().SurfaceInfo(iSurfaceId, surfaceInfoBuf)); + for (TInt i = 0 ; i < surfaceInfo.iBuffers ; i++) + { + TInt offset = 0; + User::LeaveIfError(iParent.SurfaceManager().GetBufferOffset(iSurfaceId, i, offset)); + + if(iBufferIdGenerator == 0) + { + iOffsetArray.AppendL(offset); + } + } + + aPortSpecificBuffer = iChunk.Base() + iOffsetArray[iBufferIdGenerator]; + aPortPrivate = NULL; + + iBufferIdGenerator++; + } + + +#ifndef ILCOMPONENTCONFORMANCE +void COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::InitBufferL(OMX_U32 aSizeBytes, OMX_U8* apBuffer, OMX_U32 aBufferCountActual) +{ + // open chunk at the beginning + if(iChunk.Handle() == NULL) + { + // only support chunk extension otherwise error + if(iSharedChunkThreadId == NULL || iSharedChunkHandleId == NULL) + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::InitBufferL handles not valie")); + User::Leave(KErrBadHandle); + } + + // race condition on nBufferCountActual + if(aBufferCountActual != iParent.GraphicSurfaceSettings().iSurfaceAttributes.iBuffers) + { + iParent.GraphicSurfaceSettings().iSurfaceAttributes.iBuffers = aBufferCountActual; + } + + DEBUG_PRINTF2(_L8("COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::InitBufferL iSharedChunkThreadId = %Lu"), iSharedChunkThreadId); + DEBUG_PRINTF2(_L8("COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::InitBufferL iSharedChunkHandleId = %Lu"), iSharedChunkHandleId); + + RThread chunkOwnerThread; + User::LeaveIfError(chunkOwnerThread.Open(TThreadId(iSharedChunkThreadId))); + CleanupClosePushL(chunkOwnerThread); + + iChunk.SetHandle(iSharedChunkHandleId); + User::LeaveIfError(iChunk.Duplicate(chunkOwnerThread)); + CleanupStack::PopAndDestroy(&chunkOwnerThread); + } + + // differ creating surface id with chunk at last call + if(iSurfaceId.IsNull() && (((aBufferCountActual - 1) == iOffsetArray.Count()))) + { + // Buffer size must be > 0! + if( aSizeBytes == 0 ) + { + User::Leave( KErrArgument ); + } + + // Update surface attributes using the buffer size supplied by the client. + // The supplied buffer size is used to create the graphics surface and must + // therefore be large enough to accommodate any meta-data too. + iParent.GraphicSurfaceSettings().iSurfaceAttributes.iOffsetBetweenBuffers = aSizeBytes; + + TInt err = KErrGeneral; + // create surface id with chunk + err = iParent.SurfaceManager().CreateSurface(iParent.GraphicSurfaceSettings().iSurfaceAttributesBuf, iSurfaceId, iChunk); + if(err != KErrNone) + { + DEBUG_PRINTF2(_L8("COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::InitBufferL createsurface err = %d"), err); + User::Leave(err); + } + + // Now, GFX needs to make sure that TSurfaceConfiguration has valid surface id + err = iParent.GraphicSurfaceSettings().iSurfaceConfig.SetSurfaceId(iSurfaceId); + if(err != KErrNone) + { + DEBUG_PRINTF2(_L8("COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::InitBufferL SetSurfaceId err = %d"), err); + User::Leave(err); + } + + RSurfaceManager::TInfoBuf surfaceInfoBuf; + RSurfaceManager::TSurfaceInfoV01& surfaceInfo (surfaceInfoBuf()); + surfaceInfo.iSize = iParent.GraphicSurfaceSettings().iSurfaceAttributes.iSize; + surfaceInfo.iBuffers = iParent.GraphicSurfaceSettings().iSurfaceAttributes.iBuffers; + surfaceInfo.iPixelFormat = iParent.GraphicSurfaceSettings().iSurfaceAttributes.iPixelFormat; + surfaceInfo.iStride = iParent.GraphicSurfaceSettings().iSurfaceAttributes.iStride; + surfaceInfo.iContiguous = iParent.GraphicSurfaceSettings().iSurfaceAttributes.iContiguous; + surfaceInfo.iCacheAttrib = iParent.GraphicSurfaceSettings().iSurfaceAttributes.iCacheAttrib; + surfaceInfo.iMappable = iParent.GraphicSurfaceSettings().iSurfaceAttributes.iMappable; + + err = iParent.SurfaceManager().SurfaceInfo(iSurfaceId, surfaceInfoBuf); + if(err != KErrNone) + { + DEBUG_PRINTF2(_L8("COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::InitBufferL SurfaceInfo err = %d"), err); + User::Leave(err); + } + + // everything is fine and now ready to rock and roll... + iParent.iCallbacks.EventNotification(OMX_EventPortSettingsChanged, OMX_NokiaIndexParamGraphicSurfaceConfig, 0, NULL); + } + + // save offsets + TInt offset = apBuffer - iChunk.Base(); + iOffsetArray.AppendL(offset); + } + +#else + +void COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::InitBufferL(OMX_U32 /*aSizeBytes*/, OMX_U8* /*apBuffer*/, OMX_U32 aBufferCountActual) + { + if(iSurfaceId.IsNull()) + { + User::LeaveIfError(iParent.SurfaceManager().CreateSurface(iParent.GraphicSurfaceSettings().iSurfaceAttributesBuf, iSurfaceId)); + + RChunk chunk; + User::LeaveIfError(iParent.SurfaceManager().MapSurface(iSurfaceId, chunk)); + CleanupClosePushL(chunk); + + //We need to change the chunk handle to be shared by the whole process. + RThread thread; + CleanupClosePushL(thread); + iChunk.SetHandle(chunk.Handle()); + User::LeaveIfError(iChunk.Duplicate(thread)); + CleanupStack::PopAndDestroy(2, &chunk); + + // Now, GFX needs to make sure that TSurfaceConfiguration has valid surface id + // so that IL Client can use RSurfaceManager::SetBackroundSurface() + User::LeaveIfError(iParent.GraphicSurfaceSettings().iSurfaceConfig.SetSurfaceId(iSurfaceId)); + iParent.iCallbacks.EventNotification(OMX_EventPortSettingsChanged, OMX_NokiaIndexParamGraphicSurfaceConfig, 0, NULL); + + iIsBufferSupplier = EFalse; + + for(TInt i = 0 ; i < aBufferCountActual ; i++) + { + TInt offset = 0; + User::LeaveIfError(iParent.SurfaceManager().GetBufferOffset(iSurfaceId, i, offset)); + iArrayOffsets.AppendL(offset); + } + } + + } +#endif //ILCOMPONENTCONFORMANCE + +TInt COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::ProcessNextBuffer() + { + __ASSERT_DEBUG(iParent.iBufferMutex.IsHeld(), User::Invariant()); + + TInt err = KErrNone; + + if ((iParent.BuffersToEmpty().Count()>0) && !IsActive() && iParent.State() == OMX_StateExecuting) + { + iCurrentBuffer = iParent.BuffersToEmpty()[0]; + TInt bufferId = KErrNotFound; + + if (iCurrentBuffer->nFilledLen == 0) + { + // Nothing in the buffer so no need to display it. The buffer might have a flag + // that needs processing though. Self complete to keep the state machine running. + iStatus = KRequestPending; + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + return KErrNone; + } + +#ifdef ILCOMPONENTCONFORMANCE + if (iIsBufferSupplier) + { +#endif + TInt offset = iCurrentBuffer->pBuffer - iChunk.Base(); + bufferId = iOffsetArray.Find(offset); +#ifdef ILCOMPONENTCONFORMANCE + } + else + { + // Copy data from IL Conformance Suite in to Chunk address at specific address. + TPtr8 ptr(iChunk.Base(),iCurrentBuffer->nFilledLen ,iCurrentBuffer->nAllocLen); + ptr.Copy(iCurrentBuffer->pBuffer + iCurrentBuffer->nOffset, iCurrentBuffer->nFilledLen); + // isn't nOffset likely going to be 0? better to map buffer pointer to buffer id directly + bufferId = iArrayOffsets.Find(iCurrentBuffer->nOffset); + // nOffset is not ideal for identifying buffer area since it's likely each buffer header + // will have a unique pBuffer and nOffset == 0. We could calculate buffer ID by finding + // the buffer header on the buffer header array in the port, but this isn't how bufferID + // is calculated in the rest of the code. (we could just store the buffer ID on the + // pInputPortPrivate but we have a habit of trying to export GS specific info into COmxILMMBuffer) + __ASSERT_ALWAYS(bufferId == 0, User::Invariant()); + } +#endif + + if(KErrNotFound == bufferId) + { + // An error here means that the buffer will not be displayed and RunL() will not be + // invoked. However the buffer might have a flag that needs processing. Self complete + // to keep the state machine running. + iStatus = KRequestPending; + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNotFound); + return KErrNotFound; + } + + // due to COmxMMILBuffer dependency. to be removed + if (iIsLocalChunk) + { + // copy data into local chunk + TPtr8 ptr(iCurrentBuffer->pBuffer,iCurrentBuffer->nFilledLen ,iCurrentBuffer->nAllocLen); + ptr.Copy(iChunk.Base() + offset, iCurrentBuffer->nFilledLen); + } + + iSurfaceUpdateSession.NotifyWhenDisplayed(iStatus, iTimeStamp); + SetActive(); + + err = iSurfaceUpdateSession.SubmitUpdate(KAllScreens, iSurfaceId, bufferId); + if(err) + { + // An error here means that the buffer will not be displayed and RunL() will not be + // invoked. However the buffer might have a flag that needs processing. Self complete + // to keep the state machine running. + iStatus = KRequestPending; + SetActive(); + TRequestStatus* status = &iStatus; + User::RequestComplete(status, err); + } + } + + return err; + } + +void COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::DoCancel() + { + if (iSurfaceUpdateSession.Handle() != KNullHandle) + { + iSurfaceUpdateSession.CancelAllUpdateNotifications(); + } + + iCurrentBuffer = NULL; + } + +TInt COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::OpenDevice() + { + TInt err = iSurfaceUpdateSession.Connect(KSurfaceUpdateNumOfMessageSlots); + + if (err == KErrNotFound || err != KErrNone) + { +#ifdef __WINSCW__ + DEBUG_PRINTF(_L8("Make sure SYMBIAN_GRAPHICS_USE_GCE ON is specified in epoc.ini")); +#else + DEBUG_PRINTF(_L8("Make sure SYMBIAN_GRAPHICS_USE_GCE is defined in ROM build")); +#endif + } + + return err; + } + +void COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::CloseDevice() + { + iSurfaceUpdateSession.CancelAllUpdateNotifications(); + + if (!iSurfaceId.IsNull()) + { + iParent.SurfaceManager().CloseSurface(iSurfaceId); // ignore the error + } + + iSurfaceUpdateSession.Close(); + // RSurface::Open() happened in context of caller. + iParent.SurfaceManager().Close(); + + iOffsetArray.Reset(); + } + +TInt COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::Execute() + { + iParent.SetState(OMX_StateExecuting); + iFirstFrameDisplayed = EFalse; + TInt r = ProcessNextBuffer(); + return r; + } + +TInt COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::Pause() + { + iParent.SetState(OMX_StatePause); + iFirstFrameDisplayed = EFalse; + Cancel(); + iParent.TransitionToPauseFinished(); + return KErrNone; + } + +TInt COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::Stop() + { + if(iParent.State() == OMX_StateExecuting || iParent.State() == OMX_StatePause) + { + // Cancel and flush the device driver + Cancel(); + iParent.SetState(OMX_StateIdle); + iFirstFrameDisplayed = EFalse; + } + return KErrNone; + } + +void COmxILGraphicSinkProcessingFunction::CGraphicSurfaceAccess::ResetSurfaceId() + { + iSurfaceId = TSurfaceId::CreateNullId(); + } + +COmxILGraphicSinkProcessingFunction::CPFHelper* COmxILGraphicSinkProcessingFunction::CPFHelper::NewL(COmxILGraphicSinkProcessingFunction& aParent, CGraphicSurfaceAccess& aGraphicSurfaceAccess) + { + CPFHelper* self = new (ELeave) CPFHelper(aParent, aGraphicSurfaceAccess); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +COmxILGraphicSinkProcessingFunction::CPFHelper::CPFHelper(COmxILGraphicSinkProcessingFunction& aParent, CGraphicSurfaceAccess& aSurfaceAccess) +: CActive(EPriorityUserInput), + iParent(aParent), + iGraphicSurfaceAccess(aSurfaceAccess) + { + CActiveScheduler::Add(this); + } + +void COmxILGraphicSinkProcessingFunction::CPFHelper::ConstructL() + { + User::LeaveIfError(iMsgQueue.CreateLocal(KMaxMsgQueueEntries)); + SetActive(); + iMsgQueue.NotifyDataAvailable(iStatus); + } + +COmxILGraphicSinkProcessingFunction::CPFHelper::~CPFHelper() + { + Cancel(); + iMsgQueue.Close(); + } + +void COmxILGraphicSinkProcessingFunction::CPFHelper::RunL() + { + iParent.iBufferMutex.Wait(); + if (ProcessQueue() != KErrNone) + { + iParent.GetCallbacks().ErrorEventNotification(OMX_ErrorInsufficientResources); + } + + // setup for next callbacks + SetActive(); + iMsgQueue.NotifyDataAvailable(iStatus); + iParent.iBufferMutex.Signal(); + } + +void COmxILGraphicSinkProcessingFunction::CPFHelper::DoCancel() + { + if (iMsgQueue.Handle()) + { + ProcessQueue(); // Ignore the error? + iMsgQueue.CancelDataAvailable(); + } + } + +TInt COmxILGraphicSinkProcessingFunction::CPFHelper::ProcessQueue() + { + TMessageType msg; + TInt err = iMsgQueue.Receive(msg); + while (err == KErrNone) + { + switch (msg) + { + case EOpenDevice: + { + err = iGraphicSurfaceAccess.OpenDevice(); + break; + } + case ECloseDevice: + { + iGraphicSurfaceAccess.CloseDevice(); + break; + } + + case EExecuteCommand: + { + err = iGraphicSurfaceAccess.Execute(); + break; + } + + case EStopCommand: + { + err = iGraphicSurfaceAccess.Stop(); + break; + } + + case EPauseCommand: + { + err = iGraphicSurfaceAccess.Pause(); + break; + } + + case EBufferIndication: + { + // Add buffer to list waiting to process. + // While we could send zero length buffers straight back, this would cause a + // problem if that buffer has a flag on it that needs processing. So we still + // pass them on and the graphics surface access code will not display them. + if (iParent.State() == OMX_StateExecuting || iParent.State() == OMX_StatePause) + { + err = iGraphicSurfaceAccess.ProcessNextBuffer(); + } + break; + } + default: + { + DEBUG_PRINTF2(_L8("\nMsqQue >> %d"),msg); + break; + } + } + + if (err) + { + break; + } + + err = iMsgQueue.Receive(msg); + } + + if ( err == KErrUnderflow) + { + err = KErrNone; + } + + return err; + } + +OMX_ERRORTYPE COmxILGraphicSinkProcessingFunction::CPFHelper::OpenDevice() + { + TMessageType message; + message = EOpenDevice; + return ConvertError(iMsgQueue.Send(message)); + } + +OMX_ERRORTYPE COmxILGraphicSinkProcessingFunction::CPFHelper::CloseDevice() + { + TMessageType message; + message = ECloseDevice; + return ConvertError(iMsgQueue.Send(message)); + } + +OMX_ERRORTYPE COmxILGraphicSinkProcessingFunction::CPFHelper::ExecuteAsync() + { + TMessageType message; + message = EExecuteCommand; + return ConvertError(iMsgQueue.Send(message)); + } + +OMX_ERRORTYPE COmxILGraphicSinkProcessingFunction::CPFHelper::StopAsync() + { + TMessageType message; + message = EStopCommand; + return ConvertError(iMsgQueue.Send(message)); + } + +OMX_ERRORTYPE COmxILGraphicSinkProcessingFunction::CPFHelper::StopSync() + { + // Cancel to process the existing queue before handling this command + if (IsActive()) + { + Cancel(); + } + + TInt err = iGraphicSurfaceAccess.Stop(); + + // setup for next callbacks + SetActive(); + iMsgQueue.NotifyDataAvailable(iStatus); + + return ConvertError(err); + } + +OMX_ERRORTYPE COmxILGraphicSinkProcessingFunction::CPFHelper::Pause() + { + TMessageType message; + message = EPauseCommand; + return ConvertError(iMsgQueue.Send(message)); + } + +OMX_ERRORTYPE COmxILGraphicSinkProcessingFunction::CPFHelper::BufferIndication() + { + TMessageType message; + message = EBufferIndication; + return ConvertError(iMsgQueue.Send(message)); + } + +OMX_ERRORTYPE COmxILGraphicSinkProcessingFunction::CPFHelper::ConvertError(TInt aError) + { + if(aError == KErrNone) + { + return OMX_ErrorNone; + } + else if(aError == KErrOverflow) + { + return OMX_ErrorInsufficientResources; + } + + // default + return OMX_ErrorUndefined; + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkprocessingfunction.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkprocessingfunction.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,246 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +/** + @file + @internalComponent +*/ + +#ifndef OMXILGRAPHICSINKPROCESSINGFUNCTION_H +#define OMXILGRAPHICSINKPROCESSINGFUNCTION_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "mmfbuffershared.h" + + +class COmxILGraphicSinkVPB0Port; +/** +The class for GraphicSink processing functions. This provides the main processing engine behind the graphic sink. +*/ +class COmxILGraphicSinkProcessingFunction : + public COmxILProcessingFunction + { +private: + class TGraphicSurfaceSettings + { + public: + TGraphicSurfaceSettings() : iSurfaceAttributes(iSurfaceAttributesBuf()) {}; + + public: + // Surface configuration + TSurfaceConfiguration iSurfaceConfig; + // A package for surface attribute. + RSurfaceManager::TSurfaceCreationAttributesBuf iSurfaceAttributesBuf; + // A surface attribute. + RSurfaceManager::TSurfaceCreationAttributes& iSurfaceAttributes; + } iGraphicSurfaceSettings; + +public: + static COmxILGraphicSinkProcessingFunction* NewL( + MOmxILCallbackNotificationIf& aCallbacks); + + ~COmxILGraphicSinkProcessingFunction(); + + OMX_ERRORTYPE StateTransitionIndication(TStateIndex aNewState); + + OMX_ERRORTYPE BufferFlushingIndication(TUint32 aPortIndex, + OMX_DIRTYPE aDirection); + + OMX_ERRORTYPE ParamIndication(OMX_INDEXTYPE aParamIndex, + const TAny* apComponentParameterStructure); + + OMX_ERRORTYPE ConfigIndication(OMX_INDEXTYPE aConfigIndex, + const TAny* apComponentConfigStructure); + + OMX_ERRORTYPE BufferIndication( + OMX_BUFFERHEADERTYPE* apBufferHeader, + OMX_DIRTYPE aDirection); + + OMX_BOOL BufferRemovalIndication( + OMX_BUFFERHEADERTYPE* apBufferHeader, + OMX_DIRTYPE aDirection); + + void CreateBufferL(OMX_U8*& aPortSpecificBuffer, OMX_PTR& aPortPrivate, OMX_U32 aBufferCountActual); + void DestroyBuffer(OMX_PTR apPortPrivate); + void InitBufferL(OMX_U32 aSizeBytes, OMX_U8* apBuffer, OMX_U32 aBufferCountActual); + void DeInitBuffer(); + void WaitForTransitionToPauseToFinish(); + void TransitionToPauseFinished(); + + TUidPixelFormat ConvertPixelFormat(OMX_COLOR_FORMATTYPE aColorFormat); + + // Access private member (read and write) + inline MOmxILCallbackNotificationIf& GetCallbacks(); + inline TSurfaceConfiguration& GetSurfaceConfiguration(); + inline RPointerArray& BuffersToEmpty(); + inline TGraphicSurfaceSettings& GraphicSurfaceSettings(); + inline OMX_STATETYPE State(); + inline void SetState(OMX_STATETYPE aState); + inline RSurfaceManager& SurfaceManager(); + inline TInt GetFastCounterFrequency(); + + void SetSharedChunkBufConfig(TMMSharedChunkBufConfig aSharedChunkBufConfig); + void GetSharedChunkMetadata(OMX_U32& aHandleId, OMX_U64& aThreadId) const; + +public: + //Not own, just points to related graphic sink port, so set it to public data member. + COmxILGraphicSinkVPB0Port* iGraphicSinkPort; +private: + COmxILGraphicSinkProcessingFunction(MOmxILCallbackNotificationIf& aCallbacks); + void ConstructL(); + + void InitSurfaceAttributes(); + +private: + RPointerArray iBuffersToEmpty; + OMX_BUFFERHEADERTYPE* iBufferOnScreen; + RMutex iBufferMutex; + OMX_STATETYPE iState; + TInt iFastCounterFrequency; + // A surface manager. + RSurfaceManager iSurfaceManager; + TThreadId iOwnerThreadId; + CActiveSchedulerWait* iTransitionToPauseWait; + RSemaphore iTransitionToPauseWaitSemaphore; + + /** + * Mediates access to the RSurfaceUpdateSession. + */ + class CGraphicSurfaceAccess : public CActive + { + public: + static CGraphicSurfaceAccess* NewL(COmxILGraphicSinkProcessingFunction& aParent); + ~CGraphicSurfaceAccess(); + + // from CActive + void RunL(); + void DoCancel(); + + TInt OpenDevice(); + void CloseDevice(); + TInt Execute(); + TInt Pause(); + TInt Stop(); + + void CreateBufferL(OMX_U8*& aPortSpecificBuffer, OMX_PTR& aPortPrivate, OMX_U32 aBufferCountActual); + void InitBufferL(OMX_U32 aSizeBytes, OMX_U8* apBuffer, OMX_U32 aBufferCountActual); + + TInt ProcessNextBuffer(); + + void ResetSurfaceId(); + void CloseChunk(); + + public: + TInt iSharedChunkHandleId; + TUint64 iSharedChunkThreadId; + TMMSharedChunkBufConfig iSharedChunkBufConfig; + TBool iIsLocalChunk; + + private: + CGraphicSurfaceAccess(COmxILGraphicSinkProcessingFunction& aParent); + + public: + TInt iBufferIdGenerator; + + private: + OMX_BUFFERHEADERTYPE* iCurrentBuffer; + COmxILGraphicSinkProcessingFunction& iParent; + + // Memory chunk + RChunk iChunk; + + #ifdef ILCOMPONENTCONFORMANCE + // These are added for the ILComponentConformance Suite + // Handles copy of data in case of Non-buffer supplier, while running IL Component conformance suite + TBool iIsBufferSupplier; + // Conformance suite does not handle chunks therefore offsets from base chunk address are held in this array + RArray iArrayOffsets; + #endif + + // Surface Id + TSurfaceId iSurfaceId; + // A surface update session. + RSurfaceUpdateSession iSurfaceUpdateSession; + // Time stamp of the display notification event + TTimeStamp iTimeStamp; + // An indicator for first frame displayed + TBool iFirstFrameDisplayed; + + RArray iOffsetArray; + + } *iGraphicSurfaceAccess; + + /** + * Serializes operations into the 'main' thread hosting the Active Scheduler. + */ + class CPFHelper : public CActive + { + public: + static CPFHelper* NewL(COmxILGraphicSinkProcessingFunction& aParent, CGraphicSurfaceAccess& aGraphicSurfaceAccess); + ~CPFHelper(); + + // from CActive + void RunL(); + void DoCancel(); + + OMX_ERRORTYPE OpenDevice(); + OMX_ERRORTYPE CloseDevice(); + OMX_ERRORTYPE ExecuteAsync(); + OMX_ERRORTYPE StopAsync(); + OMX_ERRORTYPE StopSync(); + OMX_ERRORTYPE Pause(); + OMX_ERRORTYPE BufferIndication(); + + enum TMessageType + { + EOpenDevice, + ECloseDevice, + EExecuteCommand, + EStopCommand, + EPauseCommand, + EBufferIndication + }; + + RMsgQueue iMsgQueue; + + private: + CPFHelper(COmxILGraphicSinkProcessingFunction& aParent, CGraphicSurfaceAccess& aGraphicSurfaceAccess); + void ConstructL(); + + TInt ProcessQueue(); + + OMX_ERRORTYPE ConvertError(TInt aError); + + private: + static const TInt KMaxMsgQueueEntries = 25; + + COmxILGraphicSinkProcessingFunction& iParent; + CGraphicSurfaceAccess& iGraphicSurfaceAccess; + } *iPFHelper; + }; + +#include "omxilgraphicsinkprocessingfunction.inl" + +#endif // OMXILGRAPHICSINKPROCESSINGFUNCTION_H + diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkprocessingfunction.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkprocessingfunction.inl Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +/** + @file + @internalComponent +*/ + +inline MOmxILCallbackNotificationIf& COmxILGraphicSinkProcessingFunction::GetCallbacks() + { + return iCallbacks; + } + +inline TSurfaceConfiguration& COmxILGraphicSinkProcessingFunction::GetSurfaceConfiguration() + { + return iGraphicSurfaceSettings.iSurfaceConfig; + } + +inline RPointerArray& COmxILGraphicSinkProcessingFunction::BuffersToEmpty() + { + return iBuffersToEmpty; + } + +inline COmxILGraphicSinkProcessingFunction::TGraphicSurfaceSettings& COmxILGraphicSinkProcessingFunction::GraphicSurfaceSettings() + { + return iGraphicSurfaceSettings; + } + +inline OMX_STATETYPE COmxILGraphicSinkProcessingFunction::State() + { + return iState; + } + +inline void COmxILGraphicSinkProcessingFunction::SetState(OMX_STATETYPE aState) + { + iState = aState; + } + + +inline TInt COmxILGraphicSinkProcessingFunction::GetFastCounterFrequency() + { + return iFastCounterFrequency; + } + +inline RSurfaceManager& COmxILGraphicSinkProcessingFunction::SurfaceManager() + { + return iSurfaceManager; + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinktrace.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinktrace.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +/** + @file + @internalComponent +*/ + +#ifndef OMXILGRAPHICSINKTRACE_H__ +#define OMXILGRAPHICSINKTRACE_H__ + +#ifdef SYMBIAN_MULTIMEDIA_TURN_TIMING_TRACING_ON + +#include + +/* + * Simple logging macro + * + * identifier - select from enum TTestTraceIdentifier + * + * */ +#define GRAPHICSINK_PERFORMANCE_TIMESTAMP_TRACE(identifier) TUTrace::PrintfPrimary(KTestTraceFilterId, 0, 0, "VPT %x", identifier) + +#else + +#define GRAPHICSINK_PERFORMANCE_TIMESTAMP_TRACE(identifier) + +#endif + +#endif // OMXILGRAPHICSINKTRACE_H__ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkvpb0port.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkvpb0port.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,859 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +/** + @file + @internalComponent +*/ + +#include +#include "omxilgraphicsinkvpb0port.h" +#include +#include +#include +#include "log.h" + +#include "omxilgraphicsinkextensionsindexes.h" + +// Port definition mime type. Mime type is not relevant for uncompressed video frames +_LIT8(KMimeType, ""); + +// Constant numbers +static const TUint32 KRefGfxFramerate = 0; // mandatory +static const TUint32 KRefGfxMinBufferSize = 1024; + +/** +Create a new VPB0 port. + +@param aCommonPortData The common information of the new VPB0 port. + aSupportedVideoFormats The list of the supported video formats. + aSupportedColorFormats The list of the supported color formats. + aGraphicSinkPF The processing function for the VPB0 port. + +@return A pointer of the VPB0Port to be created. +*/ +COmxILGraphicSinkVPB0Port* COmxILGraphicSinkVPB0Port::NewL( + const TOmxILCommonPortData& aCommonPortData, + const RArray& aSupportedVideoFormats, + const RArray& aSupportedColorFormats, + COmxILGraphicSinkProcessingFunction& aGraphicSinkPF) + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkVPB0Port::NewL +")); + COmxILGraphicSinkVPB0Port* self = new (ELeave)COmxILGraphicSinkVPB0Port( + aGraphicSinkPF); + CleanupStack::PushL(self); + self->ConstructL(aCommonPortData, aSupportedVideoFormats, aSupportedColorFormats); + CleanupStack::Pop(self); + return self; + } + +/** +Second phase construction for the class COmxILGraphicSinkVPB0Port. Initializes the param structures and config structures for GraphicSink port. +Also appends the supported color and video formats to the respective arrays. +*/ +void COmxILGraphicSinkVPB0Port::ConstructL(const TOmxILCommonPortData& aCommonPortData, + const RArray& aSupportedVideoFormats, + const RArray& aSupportedColorFormats) + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkVPB0Port::ConstructL +")); + COmxILVideoPort::ConstructL(aCommonPortData, aSupportedVideoFormats, aSupportedColorFormats); + GetParamPortDefinition().eDomain = OMX_PortDomainVideo; + + iMimeTypeBuf.CreateL(KMimeType(), KMimeType().Length() + 1); + TUint8* pTUint = const_cast(iMimeTypeBuf.PtrZ()); + GetParamPortDefinition().format.video.cMIMEType = reinterpret_cast(pTUint); + GetParamPortDefinition().format.video.pNativeRender = NULL; + GetParamPortDefinition().format.video.pNativeWindow = NULL; + + GetParamPortDefinition().nBufferSize = KRefGfxMinBufferSize; + + GetSupportedVideoFormats().AppendL(OMX_VIDEO_CodingUnused); + GetSupportedColorFormats().AppendL(OMX_COLOR_FormatCbYCrY); + GetSupportedColorFormats().AppendL(OMX_COLOR_FormatYCrYCb); + GetSupportedColorFormats().AppendL(OMX_COLOR_Format16bitRGB565); + GetSupportedColorFormats().AppendL(OMX_COLOR_Format32bitARGB8888); + + InitParamsAndConfigs(); + + iSharedChunkMetadataExtensionIndex = OMX_IndexComponentStartUnused; + } + +/** +Constructor of the class. + +@param aCommonPortData The common information of the new VPB0 port. + aSupportedVideoFormats The list of the supported video formats. + aSupportedColorFormats The list of the supported color formats. + aGraphicSinkPF The processing function for the VPB0 port. +*/ +COmxILGraphicSinkVPB0Port::COmxILGraphicSinkVPB0Port( + COmxILGraphicSinkProcessingFunction& aGraphicSinkPF) + : iGraphicSinkPF(aGraphicSinkPF) + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkVPB0Port::COmxILGraphicSinkVPB0Port +")); + } + +/** +Destructor of the class. +*/ +COmxILGraphicSinkVPB0Port::~COmxILGraphicSinkVPB0Port() + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkVPB0Port::~COmxILGraphicSinkVPB0Port +")); + + CleanUpPort(); + iMimeTypeBuf.Close(); + } + +/** +Sets the format field available as part of OMX_PARAM_PORTDEFINITIONTYPE. + +@param aPortDefinition structure containing the format field to be updated. + aUpdateProcessingFunction indicates whether or not processing function needs to be updated. + +@return OMX_ErrorNone if successful; + OMX_ErrorBadParameter if both compression format and color format are unused at the same time, or nStride is invalid; + OMX_ErrorUnsupportedSetting if unsupported compression format and color format, or bitrate is non-zero; +*/ +OMX_ERRORTYPE COmxILGraphicSinkVPB0Port::SetFormatInPortDefinition(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition,TBool& aUpdateProcessingFunction) + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkVPB0Port::SetFormatInPortDefinition +")); + + // Check settings in input OMX_PARAM_PORTDEFINITIONTYPE. + if (!UpdateColorFormat(GetParamPortDefinition().format.video.eColorFormat, aPortDefinition.format.video.eColorFormat, aUpdateProcessingFunction)) + { + return OMX_ErrorUnsupportedSetting; + } + + if (!UpdateCodingType(GetParamPortDefinition().format.video.eCompressionFormat, aPortDefinition.format.video.eCompressionFormat, aUpdateProcessingFunction)) + { + return OMX_ErrorUnsupportedSetting; + } + + if(GetParamPortDefinition().format.video.nStride != aPortDefinition.format.video.nStride) + { + // nStride shall not be 0x0 + if(0x0 == aPortDefinition.format.video.nStride) + { + return OMX_ErrorBadParameter; + } + + GetParamPortDefinition().format.video.nStride = aPortDefinition.format.video.nStride; + aUpdateProcessingFunction = ETrue; + } + + if (GetParamPortDefinition().format.video.nFrameWidth != aPortDefinition.format.video.nFrameWidth || + GetParamPortDefinition().format.video.nFrameHeight != aPortDefinition.format.video.nFrameHeight || + GetParamPortDefinition().format.video.nBitrate != aPortDefinition.format.video.nBitrate) + { + GetParamPortDefinition().format.video.nFrameWidth = aPortDefinition.format.video.nFrameWidth; + GetParamPortDefinition().format.video.nFrameHeight = aPortDefinition.format.video.nFrameHeight; + // nSliceHeight is a RO attribute. Policy is to set it to the frame height + GetParamPortDefinition().format.video.nSliceHeight = aPortDefinition.format.video.nFrameHeight; + GetParamPortDefinition().format.video.nBitrate = aPortDefinition.format.video.nBitrate; + aUpdateProcessingFunction = ETrue; + } + return OMX_ErrorNone; + } + +/** +Insert new indices belonging to the static parameter category. + +@param aIndexArray The array of indices for insert. + +@return OMX_ErrorNone if successful; + OMX_ErrorInsufficientResources if fail to insert indexes; +*/ +OMX_ERRORTYPE COmxILGraphicSinkVPB0Port::GetLocalOmxParamIndexes(RArray& aIndexArray) const + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkVPB0Port::GetLocalOmxParamIndexes +")); + + // Always collect param indexes from parents + OMX_ERRORTYPE omxRetValue = COmxILVideoPort::GetLocalOmxParamIndexes(aIndexArray); + + if(OMX_ErrorNone != omxRetValue) + { + return omxRetValue; + } + + TInt err = aIndexArray.InsertInOrder(OMX_NokiaIndexParamGraphicSurfaceConfig); + + // Note that index duplication is OK. + if (KErrNone != err && KErrAlreadyExists != err) + { + return OMX_ErrorInsufficientResources; + } + + return OMX_ErrorNone; + } + +/** +Insert new indices belonging to the dynamic configuration category. + +@param aIndexArray The array of indices for insert. + +@return OMX_ErrorNone if successful; + OMX_ErrorInsufficientResources if fail to insert indexes; +*/ +OMX_ERRORTYPE COmxILGraphicSinkVPB0Port::GetLocalOmxConfigIndexes(RArray& aIndexArray) const + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkVPB0Port::GetLocalOmxConfigIndexes +")); + + // Always collect local indexes from parent + OMX_ERRORTYPE omxRetValue = COmxILVideoPort::GetLocalOmxConfigIndexes(aIndexArray); + if (omxRetValue != OMX_ErrorNone) + { + return omxRetValue; + } + + TInt err = aIndexArray.InsertInOrder(OMX_IndexConfigCommonScale); + // Note that index duplication is OK. + if (err == KErrNone || err == KErrAlreadyExists) + { + err = aIndexArray.InsertInOrder(OMX_IndexConfigCommonOutputSize); + } + + if (err == KErrNone || err == KErrAlreadyExists) + { + err = aIndexArray.InsertInOrder(OMX_IndexConfigCommonInputCrop); + } + + if (err == KErrNone || err == KErrAlreadyExists) + { + err = aIndexArray.InsertInOrder(OMX_IndexConfigCommonOutputCrop); + } + + if (err == KErrNone || err == KErrAlreadyExists) + { + err = aIndexArray.InsertInOrder(OMX_IndexConfigCommonExclusionRect); + } + + if (err == KErrNone || err == KErrAlreadyExists) + { + err = aIndexArray.InsertInOrder(OMX_SymbianIndexConfigSharedChunkMetadata); + } + + if (err != KErrNone && err != KErrAlreadyExists) + { + return OMX_ErrorInsufficientResources; + } + + return OMX_ErrorNone; + } + +/** +This method provides the current values for the parameters present in the structure represented by the given index. + +@param aParamIndex The specific param index for which the current parameter values are required. + apComponentParameterStructure The pointer to the structure which will be updated to provide the current parameter values. + +@return OMX_ErrorNone if successful; + OMX_ErrorNoMore if no more formats; + OMX_ErrorUnsupportedSetting if unsupported setting is passed; +*/ +OMX_ERRORTYPE COmxILGraphicSinkVPB0Port::GetParameter(OMX_INDEXTYPE aParamIndex,TAny* apComponentParameterStructure) const + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkVPB0Port::GetParameter +")); + switch(aParamIndex) + { + case OMX_NokiaIndexParamGraphicSurfaceConfig: + { + OMX_SYMBIAN_VIDEO_PARAM_SURFACECONFIGURATION* videoSurface = static_cast(apComponentParameterStructure); + *videoSurface = iParamVideoSurfaceConfiguration; + break; + } + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE* compvideoPortFormat = static_cast(apComponentParameterStructure); + + // framerate should be always zero for GFX otherwise unsupported value + if(KRefGfxFramerate != compvideoPortFormat->xFramerate) + { + return OMX_ErrorUnsupportedSetting; + } + + return COmxILVideoPort::GetParameter(aParamIndex,apComponentParameterStructure); + } + default: + { + // Try the parent's indexes + return COmxILVideoPort::GetParameter(aParamIndex,apComponentParameterStructure); + } + }; + + return OMX_ErrorNone; + } + +/** +This method sets the values of the parameters present in the structure represented by the given index. + +@param aParamIndex The specific param index for which the parameter values have to be set. + apComponentParameterStructure The pointer to the structure which will provide the desired parameter values to be set. + aUpdateProcessingFunction informs whether the processing fucntion needs to be updated. + +@return OMX_ErrorNone if successful; + OMX_ErrorUnsupportedSetting if non-zero framerate value; + OMX_ErrorUnsupportedIndex if request OMX_NokiaIndexParamGraphicSurfaceConfig index; +*/ +OMX_ERRORTYPE COmxILGraphicSinkVPB0Port::SetParameter(OMX_INDEXTYPE aParamIndex,const TAny* apComponentParameterStructure, TBool& aUpdateProcessingFunction) + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkVPB0Port::SetParameter +")); + + OMX_ERRORTYPE error = OMX_ErrorNone; + switch(aParamIndex) + { + case OMX_IndexParamVideoPortFormat: + { + const OMX_VIDEO_PARAM_PORTFORMATTYPE *componentParameterStructure = static_cast(apComponentParameterStructure); + + if (GetParamPortDefinition().format.video.xFramerate != componentParameterStructure->xFramerate) + { + if (0 != componentParameterStructure->xFramerate) + { + // Known Frame rate is not supported. framerate should be always zero + return OMX_ErrorUnsupportedSetting; + } + } + + error = COmxILVideoPort::SetParameter(aParamIndex, apComponentParameterStructure, aUpdateProcessingFunction); + if(error != OMX_ErrorNone) + { + return error; + } + + if(aUpdateProcessingFunction) + { + // eColorFormat and/or eCompressionFormat and/or xFramerate is/are changed by OMX_IndexParamVideoPortFormat + // Hence change same varibles associated to index OMX_IndexParamPortDefinition. + // Update their value in OMX_PARAM_PORTDEFINITIONTYPE. + UpdateParamInPortDefinitionStruct(); + return OMX_ErrorNone; + } + + break; + } + case OMX_NokiaIndexParamGraphicSurfaceConfig: + { + // IL Client can only query OMX_GetParameter with this index but can not set any value on TSurfaceConfiguration + // GFX simply returns OMX_ErrorUnsupportedIndex for the attempt on OMX_GetParameter with this index. + return OMX_ErrorUnsupportedIndex; + } + default: + { + // Try the parent's indexes + return COmxILVideoPort::SetParameter(aParamIndex, apComponentParameterStructure, aUpdateProcessingFunction); + } + }; + return error; + } + +/** +This method provides the current values for the configurations present in the structure represented by the given index. + +@param aConfigIndex The specific configuration index for which the current configuration values are required. + apComponentConfigStructure The pointer to the structure which will be updated to provide the current configuration values. + +@return OMX_ErrorNone if successful; + OMX_ErrorUnsupportedIndex if request non-inserted config index; +*/ +OMX_ERRORTYPE COmxILGraphicSinkVPB0Port::GetConfig(OMX_INDEXTYPE aConfigIndex,TAny* apComponentParameterStructure) const + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkVPB0Port::GetConfig +")); + switch(aConfigIndex) + { + case OMX_SymbianIndexConfigSharedChunkMetadata: + { + OMX_SYMBIAN_CONFIG_SHAREDCHUNKMETADATATYPE* + pSharedChunkMetadata + = static_cast< + OMX_SYMBIAN_CONFIG_SHAREDCHUNKMETADATATYPE*>(apComponentParameterStructure); + + iGraphicSinkPF.GetSharedChunkMetadata( + pSharedChunkMetadata->nHandleId, + pSharedChunkMetadata->nOwnerThreadId); + } + break; + case OMX_IndexConfigCommonScale: + { + OMX_CONFIG_SCALEFACTORTYPE* scaleFactor = static_cast(apComponentParameterStructure); + *scaleFactor = iConfigScaleFactor; + break; + } + case OMX_IndexConfigCommonOutputSize: + { + OMX_FRAMESIZETYPE* frameSize = static_cast(apComponentParameterStructure); + *frameSize = iConfigFrameSize; + break; + } + case OMX_IndexConfigCommonInputCrop: + case OMX_IndexConfigCommonOutputCrop: + case OMX_IndexConfigCommonExclusionRect: + { + OMX_CONFIG_RECTTYPE* rec = static_cast(apComponentParameterStructure); + *rec = iConfigRec; + break; + } + default: + { + // Try the parent's indexes + return COmxILVideoPort::GetConfig(aConfigIndex,apComponentParameterStructure); + } + }; + + return OMX_ErrorNone; + } + +/** +This method sets the values of the configurations present in the structure represented by the given index. + +@param aConfigIndex The specific configuration index for which the configuration values have to be set. + apComponentConfigStructure The pointer to the structure which will be provide the desired configuration values to be set. + aUpdateProcessingFunction informs whether the processing fucntion needs to be updated. + +@return OMX_ErrorNone if successful; + OMX_ErrorUnsupportedIndex if request OMX_NokiaIndexParamGraphicSurfaceConfig index; +*/ +OMX_ERRORTYPE COmxILGraphicSinkVPB0Port::SetConfig(OMX_INDEXTYPE aConfigIndex,const TAny* apComponentParameterStructure, TBool& aUpdateProcessingFunction) + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkVPB0Port::SetConfig +")); + switch(aConfigIndex) + { + case OMX_SymbianIndexConfigSharedChunkMetadata: + { + aUpdateProcessingFunction = ETrue; + break; + } + case OMX_IndexConfigCommonScale: + { + const OMX_CONFIG_SCALEFACTORTYPE* scaleFactor = static_cast(apComponentParameterStructure); + + if(iConfigScaleFactor.xWidth != scaleFactor->xWidth) + { + iConfigScaleFactor.xWidth = scaleFactor->xWidth; + aUpdateProcessingFunction = ETrue; + } + if(iConfigScaleFactor.xHeight != scaleFactor->xHeight) + { + iConfigScaleFactor.xHeight = scaleFactor->xHeight; + aUpdateProcessingFunction = ETrue; + } + break; + } + case OMX_IndexConfigCommonOutputSize: + { + const OMX_FRAMESIZETYPE* frameSize = static_cast(apComponentParameterStructure); + + if(iConfigFrameSize.nWidth != frameSize->nWidth) + { + iConfigFrameSize.nWidth = frameSize->nWidth; + aUpdateProcessingFunction = ETrue; + } + if(iConfigFrameSize.nHeight != frameSize->nHeight) + { + iConfigFrameSize.nHeight = frameSize->nHeight; + aUpdateProcessingFunction = ETrue; + } + break; + } + case OMX_IndexConfigCommonInputCrop: + case OMX_IndexConfigCommonOutputCrop: + case OMX_IndexConfigCommonExclusionRect: + { + const OMX_CONFIG_RECTTYPE* rec = static_cast(apComponentParameterStructure); + + if(iConfigRec.nTop != rec->nTop) + { + iConfigRec.nTop = rec->nTop; + aUpdateProcessingFunction = ETrue; + } + if(iConfigRec.nLeft != rec->nLeft) + { + iConfigRec.nLeft = rec->nLeft; + aUpdateProcessingFunction = ETrue; + } + if(iConfigRec.nWidth != rec->nWidth) + { + iConfigRec.nWidth = rec->nWidth; + aUpdateProcessingFunction = ETrue; + } + if(iConfigRec.nHeight != rec->nHeight) + { + iConfigRec.nHeight = rec->nHeight; + aUpdateProcessingFunction = ETrue; + } + break; + } + default: + { + // Try the parent's indexes + return COmxILVideoPort::SetConfig(aConfigIndex, apComponentParameterStructure, aUpdateProcessingFunction); + } + }; + + return OMX_ErrorNone; + } + +/** +This method provides the index type represented by the given parameter name. + +@param aParameterName The name of extention parameter to be retrieved. + apIndexType The pointer which will retrieve the required index. + +@return OMX_ErrorNone if successful; + OMX_ErrorUnsupportedIndex if unsupported parameter name is passed; +*/ +OMX_ERRORTYPE COmxILGraphicSinkVPB0Port::GetExtensionIndex(OMX_STRING aParameterName, OMX_INDEXTYPE* apIndexType) const + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkVPB0Port::GetExtensionIndex")); + + TPtrC8 requestedParameterNamePtr(const_cast(reinterpret_cast(aParameterName))); + + // OMX_NokiaIndexParamGraphicSurfaceConfig + TPtrC8 parameterNamePtr(reinterpret_cast(sOmxSymbianGfxSurfaceConfig)); + if (requestedParameterNamePtr == parameterNamePtr) + { + *apIndexType = static_cast(OMX_NokiaIndexParamGraphicSurfaceConfig); + return OMX_ErrorNone; + } + + // OMX_SymbianIndexConfigSharedChunkMetadata + TPtrC8 parameterNamePtr2(reinterpret_cast(OMX_SYMBIAN_INDEX_CONFIG_SHAREDCHUNKMETADATA_NAME)); + if(requestedParameterNamePtr == parameterNamePtr2) + { + *apIndexType = static_cast(OMX_SymbianIndexConfigSharedChunkMetadata); + return OMX_ErrorNone; + } + + *apIndexType = OMX_IndexMax; + + return OMX_ErrorUnsupportedIndex; + } + +/** +Check whether or not the tunnelled ports are compatible. + +@param aPortDefinition The port definition parameters to be checked for compatibility. + +@return EFalse if tunnelled ports' parameters are incompatible; + ETrue otherwise; +*/ +TBool COmxILGraphicSinkVPB0Port::IsTunnelledPortCompatible(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition) const + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkVPB0Port::IsTunnelledPortCompatible +")); + + if(aPortDefinition.eDomain != GetParamPortDefinition().eDomain) + { + return EFalse; + } + + if(OMX_VIDEO_CodingUnused != aPortDefinition.format.video.eCompressionFormat) + { + return EFalse; + } + + if (GetParamPortDefinition().format.video.eColorFormat != aPortDefinition.format.video.eColorFormat) + { + return EFalse; + } + + if (GetParamPortDefinition().format.video.nFrameWidth != aPortDefinition.format.video.nFrameWidth) + { + return EFalse; + } + + if (GetParamPortDefinition().format.video.nFrameHeight != aPortDefinition.format.video.nFrameHeight) + { + return EFalse; + } + + if (GetParamPortDefinition().format.video.nStride != aPortDefinition.format.video.nStride) + { + return EFalse; + } + + return ETrue; + } + +/** +Allocates buffer, creates surface and updates the surface configuration. + +@param aSizeBytes The size of buffer. + apPortSpecificBuffer The address of buffer. + apPortPrivate The pointer of COmxILMMBuffer. + apAppPrivate Not used (default = 0). + +@return OMX_ErrorNone if successful; + OMX_ErrorInsufficientResources if failed to allocate buffer or update the surface configuration; + OMX_ErrorBadParameter if illegal parameters are passed; + +@see COmxILGraphicSinkProcessingFunction. +*/ +OMX_ERRORTYPE COmxILGraphicSinkVPB0Port::DoBufferAllocation(OMX_U32 /*aSizeBytes*/, OMX_U8*& apPortSpecificBuffer, OMX_PTR& apPortPrivate, OMX_PTR& /*apPlatformPrivate*/, OMX_PTR /* apAppPrivate */) + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkVPB0Port::DoBufferAllocation +")); + + // Create buffers allocated to be used for other components. + TRAPD(error, iGraphicSinkPF.CreateBufferL(apPortSpecificBuffer, apPortPrivate, GetParamPortDefinition().nBufferCountActual)); + switch(error) + { + case KErrNone: + break; + case KErrNoMemory: + return OMX_ErrorInsufficientResources; + default: + return OMX_ErrorBadParameter; + }; + + return OMX_ErrorNone; + } + +/** +Utilizes buffer given from allocator component to create surface, and updates the surface configuration. + +@param aSizeBytes The size of buffer. + apPortSpecificBuffer The address of buffer. + apPortPrivate The pointer of COmxILMMBuffer. + apAppPrivate Not used (default = 0). + +@return OMX_ErrorNone if successful; + OMX_ErrorInsufficientResources if failed to utilize buffer or update the surface configuration; + OMX_ErrorBadParameter if illegal parameters are passed; + +@see COmxILGraphicSinkProcessingFunction. +*/ +OMX_ERRORTYPE COmxILGraphicSinkVPB0Port::DoBufferWrapping(OMX_U32 aSizeBytes, OMX_U8* apBuffer, OMX_PTR& /*apPortPrivate*/, OMX_PTR& /*apPlatformPrivate*/, OMX_PTR /*apAppPrivate*/) + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkVPB0Port::DoBufferWrapping +")); + + // Init buffers given from allocator component. + TRAPD(error, iGraphicSinkPF.InitBufferL(aSizeBytes, apBuffer, GetParamPortDefinition().nBufferCountActual)); + switch(error) + { + case KErrNone: + break; + case KErrNoMemory: + return OMX_ErrorInsufficientResources; + default: + return OMX_ErrorBadParameter; + }; + + return OMX_ErrorNone; + } + +/** +Deallocate buffer and deallocates local resources in the processing function. + +@param apPortSpecificBuffer Not used. + apPortPrivate Not used. + apAppPrivate Not used (default = 0). +*/ +void COmxILGraphicSinkVPB0Port::DoBufferDeallocation(OMX_PTR /*apPortSpecificBuffer*/, OMX_PTR apPortPrivate, OMX_PTR /*apPlatformPrivate*/, OMX_PTR /* apAppPrivate */) + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkVPB0Port::DoBufferDeallocation")); + iGraphicSinkPF.DestroyBuffer(apPortPrivate); + } + +/** +Deinitialise buffer and deallocates local resources in the processing function. + +@param apPortSpecificBuffer Not used. + apPortPrivate Not used. + apAppPrivate Not used (default = 0). +*/ +void COmxILGraphicSinkVPB0Port::DoBufferUnwrapping(OMX_PTR /* apPortSpecificBuffer */, OMX_PTR /* apPortPrivate */, OMX_PTR /*apPlatformPrivate*/, OMX_PTR /* apAppPrivate */) + { + DEBUG_PRINTF(_L8("COmxILGraphicSinkVPB0Port::DoBufferUnwrapping")); + iGraphicSinkPF.DeInitBuffer(); + } + + +/** +Update ParamInPortDefinition struct. +*/ +void COmxILGraphicSinkVPB0Port::UpdateParamInPortDefinitionStruct() + { + // OMX_PARAM_PORTDEFINITION structure needs to be updated with respect to the changes from other OMX_PARAM structures. + GetParamPortDefinition().format.video.eColorFormat = GetParamVideoPortFormat().eColorFormat; + GetParamPortDefinition().format.video.xFramerate = GetParamVideoPortFormat().xFramerate; + GetParamPortDefinition().format.video.eCompressionFormat = GetParamVideoPortFormat().eCompressionFormat; + } + +/** +Initialise all param and config structures for GraphicSink port. +*/ +void COmxILGraphicSinkVPB0Port::InitParamsAndConfigs() + { + // init OMX_SYMBIAN_VIDEO_CONFIG_SURFACECONFIGRATION here + iParamVideoSurfaceConfiguration.nSize = sizeof(OMX_SYMBIAN_VIDEO_PARAM_SURFACECONFIGURATION); + iParamVideoSurfaceConfiguration.nVersion = TOmxILSpecVersion(); + iParamVideoSurfaceConfiguration.nPortIndex = GetParamPortDefinition().nPortIndex; + iParamVideoSurfaceConfiguration.pSurfaceConfig = &iGraphicSinkPF.GetSurfaceConfiguration(); + + // init OMX_CONFIG_SCALEFACTORTYPE + iConfigScaleFactor.nSize = sizeof(OMX_CONFIG_SCALEFACTORTYPE); + iConfigScaleFactor.nVersion = TOmxILSpecVersion(); + iConfigScaleFactor.nPortIndex = GetParamPortDefinition().nPortIndex; + + // init OMX_FRAMESIZETYPE + iConfigFrameSize.nSize = sizeof(OMX_FRAMESIZETYPE); + iConfigFrameSize.nVersion = TOmxILSpecVersion(); + iConfigFrameSize.nPortIndex = GetParamPortDefinition().nPortIndex; + + // init OMX_CONFIG_RECTTYPE + iConfigRec.nSize = sizeof(OMX_CONFIG_RECTTYPE); + iConfigRec.nVersion = TOmxILSpecVersion(); + iConfigRec.nPortIndex = GetParamPortDefinition().nPortIndex; + iConfigRec.nTop = 0; + iConfigRec.nLeft = 0; + + iSharedChunkBufConfig.iNumBuffers = GetParamPortDefinition().nBufferCountActual; + iSharedChunkBufConfig.iBufferSizeInBytes = GetParamPortDefinition().nBufferSize; + iGraphicSinkPF.SetSharedChunkBufConfig(iSharedChunkBufConfig); + } + +TInt BytesPerPixel(OMX_COLOR_FORMATTYPE aPixelFormat) + { + switch (aPixelFormat) + { + //fall through + + //case EUidPixelFormatRGB_565: + case OMX_COLOR_Format16bitRGB565: + //case EUidPixelFormatBGR_565: + case OMX_COLOR_Format16bitBGR565: + //case EUidPixelFormatARGB_1555: + case OMX_COLOR_Format16bitARGB1555: + //case EUidPixelFormatXRGB_1555: + //case EUidPixelFormatARGB_4444: + case OMX_COLOR_Format16bitARGB4444: + //case EUidPixelFormatARGB_8332: + case OMX_COLOR_Format8bitRGB332: + //case EUidPixelFormatBGRX_5551: + //case EUidPixelFormatBGRA_5551: + //case EUidPixelFormatBGRA_4444: + //case EUidPixelFormatBGRX_4444: + //case EUidPixelFormatAP_88: + //case EUidPixelFormatXRGB_4444: + //case EUidPixelFormatXBGR_4444: + //case EUidPixelFormatYUV_422Interleaved: + //case EUidPixelFormatYUV_422Planar: + case OMX_COLOR_FormatYUV422Planar: + //case EUidPixelFormatYUV_422Reversed: + case OMX_COLOR_FormatYCrYCb: + //case EUidPixelFormatYUV_422SemiPlanar: + case OMX_COLOR_FormatYUV422SemiPlanar: + //case EUidPixelFormatYUV_422InterleavedReversed: + //case EUidPixelFormatYYUV_422Interleaved: + case OMX_COLOR_FormatCbYCrY: + case OMX_COLOR_FormatYCbYCr: + case OMX_COLOR_FormatRawBayer10bit: + { + return 2; + } + + //fall through + //case EUidPixelFormatXRGB_8888: + //case EUidPixelFormatBGRX_8888: + //case EUidPixelFormatXBGR_8888: + //case EUidPixelFormatBGRA_8888: + case OMX_COLOR_Format32bitBGRA8888: + //case EUidPixelFormatARGB_8888: + case OMX_COLOR_Format32bitARGB8888: + //case EUidPixelFormatABGR_8888: + //case EUidPixelFormatARGB_8888_PRE: + //case EUidPixelFormatABGR_8888_PRE: + //case EUidPixelFormatBGRA_8888_PRE: + //case EUidPixelFormatARGB_2101010: + //case EUidPixelFormatABGR_2101010: + { + return 4; + } + + //fall through + //case EUidPixelFormatBGR_888: + case OMX_COLOR_Format24bitBGR888: + //case EUidPixelFormatRGB_888: + case OMX_COLOR_Format24bitRGB888: + { + return 3; + } + + default: + return 0; + } + } + +/** +Check the nStride value is valid. +*/ +OMX_ERRORTYPE COmxILGraphicSinkVPB0Port::ValidateStride() + { + if (GetParamPortDefinition().format.video.nStride < GetParamPortDefinition().format.video.nFrameWidth * BytesPerPixel(GetParamPortDefinition().format.video.eColorFormat)) + { + return OMX_ErrorBadParameter; + } + return OMX_ErrorNone; + } + +OMX_ERRORTYPE COmxILGraphicSinkVPB0Port::DoOmxUseBuffer( + OMX_HANDLETYPE aTunnelledComponent, + OMX_BUFFERHEADERTYPE** appBufferHdr, + OMX_U32 aTunnelledPortIndex, + OMX_PTR apPortPrivate, + OMX_PTR /* apPlatformPrivate */, + OMX_U32 aSizeBytes, + OMX_U8* apBuffer) + { + + // Find out if the tunnelled port has support for the + // OMX.SYMBIAN.INDEX.CONFIG.SHAREDCHUNKMETADATA extension + if (OMX_IndexComponentStartUnused == iSharedChunkMetadataExtensionIndex) + { + if (OMX_ErrorNone == OMX_GetExtensionIndex( + aTunnelledComponent, + const_cast(OMX_SYMBIAN_INDEX_CONFIG_SHAREDCHUNKMETADATA_NAME), + &iSharedChunkMetadataExtensionIndex)) + { + // Communicate the shared chunk metadata to the tunnelled + // component + OMX_SYMBIAN_CONFIG_SHAREDCHUNKMETADATATYPE configSharedChunkMetadata; + configSharedChunkMetadata.nSize = sizeof(OMX_SYMBIAN_CONFIG_SHAREDCHUNKMETADATATYPE); + configSharedChunkMetadata.nVersion = TOmxILSpecVersion(); + configSharedChunkMetadata.nPortIndex = GetParamPortDefinition().nPortIndex; + iGraphicSinkPF.GetSharedChunkMetadata( + configSharedChunkMetadata.nHandleId, + configSharedChunkMetadata.nOwnerThreadId); + + // Ignore any error returned by the tunnelled component + (void) OMX_SetConfig(aTunnelledComponent, + iSharedChunkMetadataExtensionIndex, + &configSharedChunkMetadata); + } + else + { + // No support in the tunnelled component. + iSharedChunkMetadataExtensionIndex = OMX_IndexMax; + } + } + + return OMX_UseBuffer( + aTunnelledComponent, + appBufferHdr, + aTunnelledPortIndex, + apPortPrivate, + aSizeBytes, + apBuffer); + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkvpb0port.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkvpb0port.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,101 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +/** + @file + @internalComponent +*/ + +#ifndef OMXILGRAPHICSINKVPB0PORT_H +#define OMXILGRAPHICSINKVPB0PORT_H + +#include +#include "omxilgraphicsinkprocessingfunction.h" +#include +#include +#include "mmfbuffershared.h" + +/** +Class COmxILGraphicSinkVPB0Port represents the input port 0 for the OpenMAX IL based graphics sink component. +*/ +class COmxILGraphicSinkVPB0Port : public COmxILVideoPort + { +public: + + static COmxILGraphicSinkVPB0Port* NewL( + const TOmxILCommonPortData& aCommonPortData, + const RArray& aSupportedVideoFormats, + const RArray& aSupportedColorFormats, + COmxILGraphicSinkProcessingFunction& aGraphicSinkPF); + + ~COmxILGraphicSinkVPB0Port(); + + OMX_ERRORTYPE GetLocalOmxParamIndexes(RArray& aIndexArray) const; + OMX_ERRORTYPE GetLocalOmxConfigIndexes(RArray& aIndexArray) const; + + OMX_ERRORTYPE GetParameter(OMX_INDEXTYPE aParamIndex, TAny* apComponentParameterStructure) const; + OMX_ERRORTYPE SetParameter(OMX_INDEXTYPE aParamIndex, const TAny* apComponentParameterStructure, TBool& aUpdateProcessingFunction); + + OMX_ERRORTYPE GetConfig(OMX_INDEXTYPE aConfigIndex, TAny* apComponentConfigStructure) const; + OMX_ERRORTYPE SetConfig(OMX_INDEXTYPE aConfigIndex, const TAny* apComponentConfigStructure, TBool& aUpdateProcessingFunction); + + OMX_ERRORTYPE GetExtensionIndex(OMX_STRING aParameterName, OMX_INDEXTYPE* apIndexType) const; + OMX_ERRORTYPE ValidateStride(); + +private: + + COmxILGraphicSinkVPB0Port( + COmxILGraphicSinkProcessingFunction& aGraphicSinkPF); + + void ConstructL(const TOmxILCommonPortData& aCommonPortData, + const RArray& aSupportedVideoFormats, + const RArray& aSupportedColorFormats); + + OMX_ERRORTYPE SetFormatInPortDefinition(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition, TBool& aUpdateProcessingFunction); + + TBool IsTunnelledPortCompatible(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition) const; + + OMX_ERRORTYPE DoBufferAllocation(OMX_U32 aSizeBytes, OMX_U8*& apPortSpecificBuffer, OMX_PTR& apPortPrivate, OMX_PTR& apPlatformPrivate, OMX_PTR apAppPrivate = 0); + void DoBufferDeallocation(OMX_PTR apPortSpecificBuffer, OMX_PTR apPortPrivate, OMX_PTR apPlatformPrivate, OMX_PTR apAppPrivate = 0); + OMX_ERRORTYPE DoBufferWrapping(OMX_U32 aSizeBytes, OMX_U8* apBuffer, OMX_PTR& apPortPrivate, OMX_PTR& apPlatformPrivate, OMX_PTR apAppPrivate = 0); + void DoBufferUnwrapping(OMX_PTR apPortSpecificBuffer, OMX_PTR apPortPrivate, OMX_PTR apPlatformPrivate, OMX_PTR apAppPrivate = 0); + OMX_ERRORTYPE DoOmxUseBuffer(OMX_HANDLETYPE aTunnelledComponent, OMX_BUFFERHEADERTYPE** appBufferHdr, OMX_U32 aTunnelledPortIndex, OMX_PTR apPortPrivate, OMX_PTR apPlatformPrivate, OMX_U32 aSizeBytes, OMX_U8* apBuffer); + + void InitParamsAndConfigs(); + void UpdateParamInPortDefinitionStruct(); + +private: + /** The reference of GraphicSink ProcessingFunction. */ + COmxILGraphicSinkProcessingFunction& iGraphicSinkPF; + /** The type of Mime. */ + RBuf8 iMimeTypeBuf; + + // The scaling size of video or image data. + OMX_CONFIG_SCALEFACTORTYPE iConfigScaleFactor; + // The size of frame. + OMX_FRAMESIZETYPE iConfigFrameSize; + // The size of rectangle. + OMX_CONFIG_RECTTYPE iConfigRec; + + // Extension to provide a structure for Surface Configuration. + OMX_SYMBIAN_VIDEO_PARAM_SURFACECONFIGURATION iParamVideoSurfaceConfiguration; + + TMMSharedChunkBufConfig iSharedChunkBufConfig; + OMX_INDEXTYPE iSharedChunkMetadataExtensionIndex; + }; + +#endif // OMXILGRAPHICSINKVPB0PORT_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/group/bld.inf Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +PRJ_TESTEXPORTS +// The export of the IBY is deliberately not guarded by #ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED so that it +// can always be #included by other IBYs/OBYs. However, if NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED is not defined +// then the IBY will effectively be empty and not include anything in the ROM. + +tsu_omxilgraphicsink.iby /epoc32/rom/include/tsu_omxilgraphicsink.iby + +#ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED +../scripts/tsu_omxilgraphicsink_01.script c:/omxil/tsu_omxilgraphicsink_01.script +../scripts/tsu_omxilgraphicsink_02.script c:/omxil/tsu_omxilgraphicsink_02.script +../scripts/tsu_omxilgraphicsink_03.script c:/omxil/tsu_omxilgraphicsink_03.script +../scripts/tsu_omxilgraphicsink_04.script c:/omxil/tsu_omxilgraphicsink_04.script +../scripts/tsu_omxilgraphicsink_05.script c:/omxil/tsu_omxilgraphicsink_05.script +../scripts/tsu_omxilgraphicsink_06.script c:/omxil/tsu_omxilgraphicsink_06.script +../scripts/tsu_omxilgraphicsink_07.script c:/omxil/tsu_omxilgraphicsink_07.script +../scripts/tsu_omxilgraphicsink_08.script c:/omxil/tsu_omxilgraphicsink_08.script +../scripts/tsu_omxilgraphicsink_09.script c:/omxil/tsu_omxilgraphicsink_09.script +../scripts/tsu_omxilgraphicsink_10.script c:/omxil/tsu_omxilgraphicsink_10.script +../scripts/tsu_omxilgraphicsink.ini z:/omxil/configs/tsu_omxilgraphicsink.ini + + +PRJ_TESTMMPFILES +tsu_omxilgraphicsink.mmp + +#endif // NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/group/tsu_omxilgraphicsink.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/group/tsu_omxilgraphicsink.iby Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifndef TSU_OMXILGRAPHICSINK_IBY +#define TSU_OMXILGRAPHICSINK_IBY + +#ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED + +// debug build +file=ABI_DIR\BUILD_DIR\tsu_omxilgraphicsink.exe System\Libs\tsu_omxilgraphicsink.exe + +data=EPOCROOT##epoc32\data\c\omxil\tsu_omxilgraphicsink_01.script tsu_omxilgraphicsink_01.script +data=EPOCROOT##epoc32\data\c\omxil\tsu_omxilgraphicsink_02.script tsu_omxilgraphicsink_02.script +data=EPOCROOT##epoc32\data\c\omxil\tsu_omxilgraphicsink_03.script tsu_omxilgraphicsink_03.script +data=EPOCROOT##epoc32\data\c\omxil\tsu_omxilgraphicsink_04.script tsu_omxilgraphicsink_04.script +data=EPOCROOT##epoc32\data\c\omxil\tsu_omxilgraphicsink_05.script tsu_omxilgraphicsink_05.script +data=EPOCROOT##epoc32\data\c\omxil\tsu_omxilgraphicsink_06.script tsu_omxilgraphicsink_06.script +data=EPOCROOT##epoc32\data\c\omxil\tsu_omxilgraphicsink_07.script tsu_omxilgraphicsink_07.script +data=EPOCROOT##epoc32\data\c\omxil\tsu_omxilgraphicsink_08.script tsu_omxilgraphicsink_08.script +data=EPOCROOT##epoc32\data\c\omxil\tsu_omxilgraphicsink_09.script tsu_omxilgraphicsink_09.script +data=EPOCROOT##epoc32\data\c\omxil\tsu_omxilgraphicsink_10.script tsu_omxilgraphicsink_10.script +data=EPOCROOT##epoc32\data\z\omxil\configs\tsu_omxilgraphicsink.ini omxil\configs\tsu_omxilgraphicsink.ini + +#endif // NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED + +#endif //TSU_OMXILGRAPHICSINK_IBY diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/group/tsu_omxilgraphicsink.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/group/tsu_omxilgraphicsink.mmp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +TARGET tsu_omxilgraphicsink.exe +TARGETTYPE exe +UID 0x1000008d 0x20031C8F // Same UID as legacy tests +VENDORID 0x70000001 + +CAPABILITY ALL -TCB + +USERINCLUDE ../src +SOURCEPATH ../src +SOURCE omxilgraphicsinksuiteserver.cpp +SOURCE omxilgraphicsinktestbase.cpp +SOURCE omxilmmbuffer.cpp +SOURCE graphicsinktestbase.cpp +SOURCE graphicsinkteststeps.cpp + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +LIBRARY euser.lib +LIBRARY testexecuteutils.lib +LIBRARY testexecutelogclient.lib +LIBRARY ecom.lib +LIBRARY efsrv.lib +LIBRARY omxilcomponentcommon.lib +LIBRARY surfaceupdateclient.lib +LIBRARY omxilcoreclient.lib +LIBRARY ws32.lib +LIBRARY gdi.lib +LIBRARY surfacemanager.lib diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink.ini --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink.ini Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,45 @@ +[AllocateBufferStateOne] +RTestCase=9 +RTestStep=1 + +[AllocateBufferStateTwo] +RTestCase=9 +RTestStep=2 + +[AllocateBufferStateThree] +RTestCase=9 +RTestStep=3 + +[AllocateBufferStateFour] +RTestCase=9 +RTestStep=4 + +[DoBufferDoneOne] +RTestCase=10 +RTestStep=1 +REmptyBufferLimit=1 + +[DoBufferDoneTwo] +RTestCase=10 +RTestStep=2 +REmptyBufferLimit=1 + +[DoBufferDoneThree] +RTestCase=10 +RTestStep=3 +REmptyBufferLimit=1 + +[DoBufferDoneFour] +RTestCase=10 +RTestStep=4 +REmptyBufferLimit=0 + +[DoBufferDoneFive] +RTestCase=10 +RTestStep=5 +REmptyBufferLimit=1 + +[DoBufferDoneSix] +RTestCase=10 +RTestStep=6 +REmptyBufferLimit=2 \ No newline at end of file diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_01.script --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_01.script Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,164 @@ +// +// Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +LOAD_SUITE tsu_omxilgraphicsink + +START_TESTCASE MMVIDEO-OMX-GS-001-01-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-001-01-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Confirm OMX_GraphicSink component is initialized with the correct parameters and is initialized to the correct state +//! @SYMTestExpectedResults The component is initialized correctly and in the right state +//! @SYMTestActions Create a OMX_GraphicSink component and check initial state OMX_StateLoaded +//! Confirm OMX component name using GetComponentVersion +//! Check default values for OMX_PARAM_PORTDEFINITIONTYPE +//! Check default values for OMX_VIDEO_PARAM_PORTFORMATTYPE +//! Send command to all suppported states using SendCommand +//! Check state is unaltered with GetState +//! COmxILGraphicSink::CreateComponent +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkVPB0Port::GetParameter +//! COmxILGraphicSinkVPB0Port::SetParameter +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-001-01-HP +END_TESTCASE MMVIDEO-OMX-GS-001-01-HP + +START_TESTCASE MMVIDEO-OMX-GS-001-02-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-001-02-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Test default parameters assigned and exported into a struct using the correct index type +//! Then change Framerate value using the same structs and confirm the value is updated +//! @SYMTestExpectedResults Framerate is updated in in OMX_VIDEO_PARAM_PORTFORMATTYPE and OMX_PARAM_PORTDEFINITIONTYPE +//! @SYMTestActions Using OMX_PARAM_PORTDEFINITIONTYPE set xFramerate OMX_ErrorUnsupportedSetting +//! Confirm xFramerate value using OMX_PARAM_PORTDEFINITIONTYPE +//! Confirm xFramerate value using OMX_VIDEO_PARAM_PORTFORMATTYPE +//! Using OMX_VIDEO_PARAM_PORTFORMATTYPE set xFramerate OMX_ErrorUnsupportedSetting +//! Confirm xFramerate value using OMX_VIDEO_PARAM_PORTFORMATTYPE -GetParameter +//! Confirm xFramerate value using OMX_PARAM_PORTDEFINITIONTYPE -GetParameter +//! COmxILGraphicSinkVPB0Port::GetParameter +//! COmxILGraphicSinkVPB0Port::SetParameter +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-001-02-HP +END_TESTCASE MMVIDEO-OMX-GS-001-02-HP + +START_TESTCASE MMVIDEO-OMX-GS-001-03-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-001-03-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Test default parameters assigned and exported into a struct using the correct index type +//! Then change Framesize value using the same structs and confirm the value is updated +//! @SYMTestExpectedResults Framesize is changed in the graphicsink component +//! @SYMTestActions Declare and populate data structure OMX_PARAM_PORTDEFINITIONTYPE +//! Attempt to set nFrameHeight & nFrameWidth -SetParameter +//! Confirm values are updated in component +//! Repeat multiple time with increases frame sizes +//! COmxILGraphicSinkVPB0Port::GetParameter +//! COmxILGraphicSinkVPB0Port::SetParameter +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-001-03-HP +END_TESTCASE MMVIDEO-OMX-GS-001-03-HP + +START_TESTCASE MMVIDEO-OMX-GS-001-04-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-001-04-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Test default parameters assigned and exported into a struct using the correct index type +//! Then change colour format using the same structs and confirm the value is updated +//! @SYMTestExpectedResults Colour format is never changed from the default value +//! @SYMTestActions Using OMX_PARAM_PORTDEFINITIONTYPE set eColorFormat to OMX_COLOR_FormatCbYCrY +//! Confirm eColorFormat value using OMX_VIDEO_PARAM_PORTFORMATTYPE & OMX_PARAM_PORTDEFINITIONTYPE +//! Set negative values for eColorFormat & eCompressionFormat using OMX_PARAM_PORTDEFINITIONTYPE +//! Using OMX_VIDEO_PARAM_PORTFORMATTYPE set eColorFormat to OMX_COLOR_FormatCbYCrY +//! Confirm eColorFormat value using OMX_VIDEO_PARAM_PORTFORMATTYPE & OMX_PARAM_PORTDEFINITIONTYPE +//! Set negative values for eColorFormat & eCompressionFormat using OMX_VIDEO_PARAM_PORTFORMATTYPE +//! COmxILGraphicSinkVPB0Port::GetParameter +//! COmxILGraphicSinkVPB0Port::SetParameter +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-001-04-HP +END_TESTCASE MMVIDEO-OMX-GS-001-04-HP + +START_TESTCASE MMVIDEO-OMX-GS-001-05-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-001-05-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Test default parameters assigned and exported into a struct using the correct index type +//! Then change buffer count using the same structs and confirm the value is updated +//! @SYMTestExpectedResults nBufferCountActual value is updated in component +//! @SYMTestActions Using OMX_PARAM_PORTDEFINITIONTYPE confirm nBufferCountMin and nBufferCountActual values +//! Set nBufferCountActual to below nBufferCountMin and confirm OMX_ErrorBadParameter +//! Incrementally increase nBufferCountActual and set in component +//! COmxILGraphicSinkVPB0Port::GetParameter +//! COmxILGraphicSinkVPB0Port::SetParameter +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-001-05-HP +END_TESTCASE MMVIDEO-OMX-GS-001-05-HP + +START_TESTCASE MMVIDEO-OMX-GS-001-06-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-001-06-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Test stride dependant values in supported struct types using the correct index type +//! @SYMTestExpectedResults Stride value is updated and correct in component +//! @SYMTestActions Using OMX_PARAM_PORTDEFINITIONTYPE confirm stride dependant values +//! Set nFrameWidth & eColorFormat and calculated correct stride +//! Incrementally increase nFrameWidth and set in component +//! COmxILGraphicSinkVPB0Port::GetParameter +//! COmxILGraphicSinkVPB0Port::SetParameter +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-001-06-HP +END_TESTCASE MMVIDEO-OMX-GS-001-06-HP + +START_TESTCASE MMVIDEO-OMX-GS-001-07-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-001-07-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Attempt to set the parameter of the graphics sink component +//! @SYMTestExpectedResults Set command should return appropiate error and value is updated +//! @SYMTestActions Using OMX_PARAM_PORTDEFINITIONTYPE change values +//! Attempt to set the following values nBufferCountMin, nBufferSize, nBufferAlignment +//! nSliceHeight, bEnabled, bPopulated, bBuffersContiguous and eDomain +//! COmxILGraphicSinkVPB0Port::GetParameter +//! COmxILGraphicSinkVPB0Port::SetParameter +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-001-07-HP +END_TESTCASE MMVIDEO-OMX-GS-001-07-HP + +START_TESTCASE MMVIDEO-OMX-GS-001-08-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-001-08-HP + + + +//! @SYMTestType UT +//! @SYMTestCaseDesc Attempt to set unsupported colour format types +//! @SYMTestExpectedResults OMX_ErrorBadParameter and OMX_ErrorUnsupported setting should be returned +//! @SYMTestActions Using OMX_PARAM_PORTDEFINITIONTYPE and OMX_VIDEO_PARAM_PORTFORMATTYPE +//! Set unsupported OMX_COLOR_FORMATTYPE and Set unsupported OMX_VIDEO_CODINGTYPE +//! Both structs should return OMX_ErrorUnsupportedSetting when SetParmater called +//! Use combination of unsupported colour formats to invoke OMX_ErrorBadParameter +//! COmxILGraphicSinkVPB0Port::GetParameter +//! COmxILGraphicSinkVPB0Port::SetParameter +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-001-08-HP +END_TESTCASE MMVIDEO-OMX-GS-001-08-HP + +START_TESTCASE MMVIDEO-OMX-GS-001-09-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-001-09-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Get BytesPerPixel for all color formats +//! @SYMTestExpectedResults A valid bytes per pixil TInt value is returned +//! @SYMTestActions Call COmxILMMBuffer::BytesPerPixel with OMX_COLOR_FORMATTYPE +//! Call COmxILMMBuffer::BytesPerPixel with TUidPixelFormat +//! COmxILMMBuffer::BytesPerPixel(TUidPixelFormat aPixelForamt) +//! COmxILMMBuffer::BytesPerPixel(OMX_COLOR_FORMATTYPE aPixelForamt) +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-001-09-HP +END_TESTCASE MMVIDEO-OMX-GS-001-09-HP + +// START_TESTCASE MMVIDEO-OMX-GS-001-00-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-001-00-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Allocate test for Graphic Sink component +//! @SYMTestExpectedResults OOM testing should return correct errors +//! @SYMTestActions Allocate testing of the Graphic SInk OMX component +//! COmxILGraphicSink::CreateComponent +// Fails due to "OmxILPort: 1" Panic - under investigation. Test disabled as this failure sometimes interferes with subsequent test steps. +// RUN_TEST_STEP !OOM 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-001-00-HP +// END_TESTCASE MMVIDEO-OMX-GS-001-00-HP diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_02.script --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_02.script Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,76 @@ +// +// Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +LOAD_SUITE tsu_omxilgraphicsink + +START_TESTCASE MMVIDEO-OMX-GS-002-01-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-002-01-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc HEAP test State Loaded to Idle transition test using AllocateBuffer +//! @SYMTestExpectedResults HEAP mark reports no memory leaks +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Repeat test once, using __MM_HEAP_MARK and __MM_HEAP_MARK to test HEAP size +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-002-01-HP +END_TESTCASE MMVIDEO-OMX-GS-002-01-HP + +START_TESTCASE MMVIDEO-OMX-GS-002-02-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-002-02-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Stress test State Loaded to Idle transition test using AllocateBuffer +//! @SYMTestExpectedResults State is changed and callback is invoked +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Repeat test multiple times +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-002-02-HP +END_TESTCASE MMVIDEO-OMX-GS-002-02-HP + +START_TESTCASE MMVIDEO-OMX-GS-002-03-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-002-03-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc State Loaded to Idle transition test using AllocateBuffer +//! Changing the required number of buffers nBufferCountActual +//! @SYMTestExpectedResults State is changed and callback is invoked +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Repeat & incrementally increase the number of required buffers +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-002-03-HP +END_TESTCASE MMVIDEO-OMX-GS-002-03-HP + +START_TESTCASE MMVIDEO-OMX-GS-002-04-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-002-04-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Negative allocate buffer test +//! @SYMTestExpectedResults Allocate buffer returns OMX_ErrorIncorrectStateOperation +//! @SYMTestActions Attempt to Allocate required number of buffer without using the send command +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-002-04-HP +END_TESTCASE MMVIDEO-OMX-GS-002-04-HP diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_03.script --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_03.script Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,76 @@ +// +// Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +LOAD_SUITE tsu_omxilgraphicsink + +START_TESTCASE MMVIDEO-OMX-GS-003-01-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-003-01-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc HEAP test State Loaded to Idle transition test using UseBuffer +//! @SYMTestExpectedResults HEAP mark reports no memory leaks +//! @SYMTestActions Send command OMX_StateIdle and use required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Repeat test once, using __MM_HEAP_MARK and __MM_HEAP_MARK to test HEAP size +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-003-01-HP +END_TESTCASE MMVIDEO-OMX-GS-003-01-HP + +START_TESTCASE MMVIDEO-OMX-GS-003-02-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-003-02-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Stress test State Loaded to Idle transition test using UseBuffer +//! @SYMTestExpectedResults State is changed and callback is invoked +//! @SYMTestActions Send command OMX_StateIdle and use required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Repeat test multiple times +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-003-02-HP +END_TESTCASE MMVIDEO-OMX-GS-003-02-HP + +START_TESTCASE MMVIDEO-OMX-GS-003-03-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-003-03-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc State Loaded to Idle transition test using UseBuffer +//! Changing the required number of buffers nBufferCountActual +//! @SYMTestExpectedResults State is changed and callback is invoked +//! @SYMTestActions Send command OMX_StateIdle and Use required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Repeat & incrementally increase the number of required buffers +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-003-03-HP +END_TESTCASE MMVIDEO-OMX-GS-003-03-HP + +START_TESTCASE MMVIDEO-OMX-GS-003-04-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-003-04-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Negative use buffer test +//! @SYMTestExpectedResults Use buffer returns OMX_ErrorIncorrectStateOperation +//! @SYMTestActions Attempt to use required number of buffer without using the send command +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-003-04-HP +END_TESTCASE MMVIDEO-OMX-GS-003-04-HP diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_04.script --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_04.script Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,129 @@ +// +// Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +LOAD_SUITE tsu_omxilgraphicsink + +START_TESTCASE MMVIDEO-OMX-GS-004-01-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-004-01-HP +//! @SYMTestCaseDesc HEAP test State Loaded to Idle to Executing using AllocateBuffer +//! @SYMTestExpectedResults HEAP mark reports no memory leaks +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffers +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateExecuting and then send command OMX_StateIdle +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Repeat test once, using __MM_HEAP_MARK and __MM_HEAP_MARK to test HEAP size +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-004-01-HP + +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-009-00-HP c:\omxil\configs\tsu_omxilgraphicsink.ini AllocateBufferStateOne + +END_TESTCASE MMVIDEO-OMX-GS-004-01-HP + +START_TESTCASE MMVIDEO-OMX-GS-004-02-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-004-02-HP +//! @SYMTestCaseDesc Stress test State Loaded to Idle to Executing using AllocateBuffer +//! @SYMTestExpectedResults State is changed and callback is invoked +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffers +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateExecuting and then send command OMX_StateIdle +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Repeat test multiple times +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-004-02-HP + +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-009-00-HP c:\omxil\configs\tsu_omxilgraphicsink.ini AllocateBufferStateTwo + +END_TESTCASE MMVIDEO-OMX-GS-004-02-HP + +START_TESTCASE MMVIDEO-OMX-GS-004-03-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-004-03-HP +//! @SYMTestCaseDesc Stress test State Loaded to Idle to Executing using AllocateBuffer +//! @SYMTestExpectedResults State is changed and callback is invoked +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffers +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateExecuting and then send command OMX_StateIdle +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Increase buffer count incrementally and repeat test multiple times +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-004-03-HP + +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-009-00-HP c:\omxil\configs\tsu_omxilgraphicsink.ini AllocateBufferStateThree + +END_TESTCASE MMVIDEO-OMX-GS-004-03-HP + +START_TESTCASE MMVIDEO-OMX-GS-004-04-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-004-04-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Stress test State Loaded to Idle to Executing using AllocateBuffer +//! @SYMTestExpectedResults State is changed and callback is invoked +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffers +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateExecuting and then send command OMX_StateIdle +//! Repeat Idle to Executing to Idle 20 times +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Repeat test multiple times +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-004-04-HP +END_TESTCASE MMVIDEO-OMX-GS-004-04-HP + +// START_TESTCASE MMVIDEO-OMX-GS-004-05-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-004-05-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Stress test State Loaded to Idle to Executing using AllocateBuffer +//! @SYMTestExpectedResults State is changed and callback is invoked +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffers +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateExecuting and then send command OMX_StateIdle +//! Repeat Idle to Executing to Idle 20 times +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Increase buffer count incrementally and repeat test multiple times +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +// Fails due to OOM - under investigation. Test disabled as this failure sometimes interferes with subsequent test steps. +// RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-004-05-HP +// END_TESTCASE MMVIDEO-OMX-GS-004-05-HP + +START_TESTCASE MMVIDEO-OMX-GS-004-06-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-004-06-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Move from executing to idle without waiting for DoFillBufferDone callback +//! @SYMTestExpectedResults OpenMAX shuts down without error +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffers +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateExecuting and then send command OMX_StateIdle +//! Fill buffer with data and call EmptyThisBuffer +//! Within same method call Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateLoaded and call FreeHandle +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-004-06-HP +END_TESTCASE MMVIDEO-OMX-GS-004-06-HP diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_05.script --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_05.script Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,118 @@ +// +// Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +LOAD_SUITE tsu_omxilgraphicsink + +START_TESTCASE MMVIDEO-OMX-GS-005-01-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-005-01-HP +//! @SYMTestCaseDesc HEAP test Empty this buffer using Allocate Buffer +//! @SYMTestExpectedResults HEAP mark reports no memory leaks +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffers +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateExecuting and wait for callback to return OMX_EventCmdComplete +//! Fill Allocated buffer with colour using filled CCameraBuffer* +//! Call Empty this buffer and wait for DoEmptyBufferDone callback +//! Call Empty this buffer for next buffer and repeat multiple times +//! Send command OMX_StateIdle and wait for callback +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Repeat test once, using __MM_HEAP_MARK and __MM_HEAP_MARK to test HEAP size +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-005-01-HP +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-010-00-HP z:\omxil\configs\tsu_omxilgraphicsink.ini DoBufferDoneOne +END_TESTCASE MMVIDEO-OMX-GS-005-01-HP + +START_TESTCASE MMVIDEO-OMX-GS-005-02-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-005-02-HP +//! @SYMTestCaseDesc Empty this buffer using Allocate Buffer +//! @SYMTestExpectedResults State is changed and callbacks are invoked +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffers +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateExecuting and wait for callback to return OMX_EventCmdComplete +//! Fill Allocated buffer with colour using filled CCameraBuffer* +//! Call Empty this buffer and wait for DoEmptyBufferDone callback +//! Send command OMX_StateIdle and wait for callback +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Repeat test multiple times +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-005-02-HP +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-010-00-HP z:\omxil\configs\tsu_omxilgraphicsink.ini DoBufferDoneTwo +END_TESTCASE MMVIDEO-OMX-GS-005-02-HP + +START_TESTCASE MMVIDEO-OMX-GS-005-03-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-005-03-HP +//! @SYMTestCaseDesc Empty this buffer using Allocate Buffer +//! @SYMTestExpectedResults State is changed and callbacks are invoked +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffers +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateExecuting and wait for callback to return OMX_EventCmdComplete +//! Fill Allocated buffer with colour using filled CCameraBuffer* +//! Call Empty this buffer and wait for DoEmptyBufferDone callback +//! Call Empty this buffer for next buffer and repeat multiple times +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Increase buffer count incrementally and repeat test multiple times +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +// Fails due to OOM - under investigation. Test disabled as this failure sometimes interferes with subsequent test steps. +// RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-005-03-HP +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-010-00-HP z:\omxil\configs\tsu_omxilgraphicsink.ini DoBufferDoneThree +END_TESTCASE MMVIDEO-OMX-GS-005-03-HP + +START_TESTCASE MMVIDEO-OMX-GS-005-04-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-005-04-HP +//! @SYMTestCaseDesc Empty this buffer using Allocate Buffer +//! @SYMTestExpectedResults State is changed and callbacks are invoked +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffers +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateExecuting and wait for callback to return OMX_EventCmdComplete +//! Fill Allocated buffer with colour using filled CCameraBuffer* +//! Call Empty this buffer and wait for DoEmptyBufferDone callback +//! Call Empty this buffer for next buffer and repeat multiple times +//! Repeat test multiple times +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-005-04-HP +END_TESTCASE MMVIDEO-OMX-GS-005-04-HP + +START_TESTCASE MMVIDEO-OMX-GS-005-05-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-005-05-HP +//! @SYMTestCaseDesc Empty this buffer using Allocate Buffer +//! @SYMTestExpectedResults State is changed and callbacks are invoked +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffers +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateExecuting and wait for callback to return OMX_EventCmdComplete +//! Fill Allocated buffer with colour using filled CCameraBuffer* +//! Call Empty this buffer and wait for DoEmptyBufferDone callback +//! Call Empty this buffer for next buffer and repeat multiple times +//! Send command OMX_StateIdle and wait for callback +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-005-05-HP +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-010-00-HP z:\omxil\configs\tsu_omxilgraphicsink.ini DoBufferDoneFour +END_TESTCASE MMVIDEO-OMX-GS-005-05-HP diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_06.script --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_06.script Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,49 @@ +// +// Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +LOAD_SUITE tsu_omxilgraphicsink + + +START_TESTCASE MMVIDEO-OMX-GS-006-01-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-006-01-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Stress Test Set buffer count actual +//! @SYMTestExpectedResults Buffer count changes are excepted and state is changed +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffers +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateLoaded and Free required number of buffer +//! Incrementally increase number of buffers and repeat test +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-006-01-HP +END_TESTCASE MMVIDEO-OMX-GS-006-01-HP + +START_TESTCASE MMVIDEO-OMX-GS-006-02-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-006-02-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Stress Test Set buffer count actual +//! @SYMTestExpectedResults Buffer count changes are excepted and state is changed +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffers +//! Attempt to allocate an aditional buffer +//! AllocateBuffer returned correct error: OMX_ErrorIncorrectStateOperation +//! Confirm state remains OMX_StateIdle using Get State +//! FreeBuffer without calling SendCommand to OMX_StateLoaded +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-006-02-HP +END_TESTCASE MMVIDEO-OMX-GS-006-02-HP diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_07.script --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_07.script Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,114 @@ +// +// Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +LOAD_SUITE tsu_omxilgraphicsink + + +START_TESTCASE MMVIDEO-OMX-GS-007-01-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-007-01-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Pause test +//! @SYMTestExpectedResults State is changed and callbacks are invoked +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffers +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateExecuting and wait for callback to return OMX_EventCmdComplete +//! Fill Allocated buffer with colour using filled CCameraBuffer* +//! Call Empty this buffer and wait for DoEmptyBufferDone callback +//! Call Empty this buffer for next buffer and repeat multiple times +//! Send command OMX_StatePause and wait for callback to return OMX_EventCmdComplete after a certain amount buffers emptied +//! Send command OMX_StateExecuting and wait for callback +//! Repeat this loop five times +//! Send command OMX_StateIdle and wait for callback +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-007-01-HP +END_TESTCASE MMVIDEO-OMX-GS-007-01-HP + +START_TESTCASE MMVIDEO-OMX-GS-007-02-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-007-02-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Pause test +//! @SYMTestExpectedResults State is changed and callbacks are invoked +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffers +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateExecuting and wait for callback to return OMX_EventCmdComplete +//! Fill Allocated buffer with colour using filled CCameraBuffer* +//! Call Empty this buffer and wait for DoEmptyBufferDone callback +//! Call Empty this buffer for next buffer and repeat multiple times +//! Send command OMX_StatePause and wait for callback to return OMX_EventCmdComplete after a certain amount buffers emptied +//! Send command OMX_StateIdle and wait for callback +//! Send command OMX_StateExecuting and wait for callback +//! Repeat this loop five times +//! Send command OMX_StateIdle and wait for callback +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-007-02-HP +END_TESTCASE MMVIDEO-OMX-GS-007-02-HP + +START_TESTCASE MMVIDEO-OMX-GS-007-03-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-007-03-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Pause test +//! @SYMTestExpectedResults State is changed and callbacks are invoked +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffers +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateExecuting and wait for callback to return OMX_EventCmdComplete +//! Fill Allocated buffer with colour using filled CCameraBuffer* +//! Call Empty this buffer and wait for DoEmptyBufferDone callback +//! Call Empty this buffer for next buffer and repeat multiple times +//! Send command OMX_StateIdle and wait for callback to return OMX_EventCmdComplete after a certain amount buffers emptied +//! Send command OMX_StatePause and wait for callback +//! Send command OMX_StateExecuting and wait for callback +//! Repeat this loop five times +//! Send command OMX_StateIdle and wait for callback +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-007-03-HP +END_TESTCASE MMVIDEO-OMX-GS-007-03-HP + +START_TESTCASE MMVIDEO-OMX-GS-007-04-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-007-04-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Pause test +//! @SYMTestExpectedResults State is changed and callbacks are invoked +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffers +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateExecuting and wait for callback to return OMX_EventCmdComplete +//! Fill Allocated buffer with colour using filled CCameraBuffer* +//! Call Empty this buffer and wait for DoEmptyBufferDone callback +//! Call Empty this buffer for next buffer and repeat multiple times +//! Send command OMX_StatePause and wait for callback to return OMX_EventCmdComplete after a certain amount buffers emptied +//! Send command OMX_StateIdle and wait for callback +//! Send command OMX_StatePause and wait for callback +//! Send command OMX_StateExecuting and wait for callback +//! Repeat this loop five times +//! Send command OMX_StateIdle and wait for callback +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-007-04-HP +END_TESTCASE MMVIDEO-OMX-GS-007-04-HP diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_08.script --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_08.script Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,35 @@ +// +// Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +LOAD_SUITE tsu_omxilgraphicsink + +START_TESTCASE MMVIDEO-OMX-GS-008-01-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-008-01-HP +//! @SYMTestType UT +//! @SYMTestCaseDesc Test default parameters assigned and exported into a struct using the correct index type +//! Then change ScaleFactor value using the same structs and confirm the value is updated +//! Then change OutputSize value using the same structs and confirm the value is updated +//! Then change InputCrop value using the same structs and confirm the value is updated +//! Then change ExclusionRect value using the same structs and confirm the value is updated +//! @SYMTestExpectedResults Parameters are changed in the graphicsink component +//! @SYMTestActions Declare and populate data structure OMX_CONFIG_SCALEFACTORTYPE +//! Attempt to set xWidth & xHeight -SetParameter +//! Confirm values are updated in component +//! Repeat multiple time with the above mentioned parameters +//! COmxILGraphicSinkVPB0Port::GetParameter +//! COmxILGraphicSinkVPB0Port::SetParameter +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-008-01-HP +END_TESTCASE MMVIDEO-OMX-GS-008-01-HP diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_09.script --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_09.script Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,35 @@ +// +// Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +LOAD_SUITE tsu_omxilgraphicsink + +START_TESTCASE MMVIDEO-OMX-GS-009-04-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-009-04-HP +//! @SYMTestCaseDesc Stress test Wait for Resources to Executing using AllocateBuffer +//! @SYMTestExpectedResults State is changed and callback is invoked +//! @SYMTestActions Send command OMX_StateWaitForResources and Allocate required number of buffers +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateIdle and Allocate required number of buffers +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateExecuting and then send command OMX_StateIdle +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! Repeat test multiple times +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-009-00-HP z:\omxil\configs\tsu_omxilgraphicsink.ini AllocateBufferStateFour +END_TESTCASE MMVIDEO-OMX-GS-009-04-HP diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_10.script --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_10.script Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,38 @@ +// +// Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +LOAD_SUITE tsu_omxilgraphicsink + +START_TESTCASE MMVIDEO-OMX-GS-010-05-HP +//! @SYMTestCaseID MMVIDEO-OMX-GS-010-05-HP +//! @SYMTestCaseDesc Return to OMX_StateLoaded from Empty this buffer asynchronously +//! @SYMTestExpectedResults State returns to OMX_StateLoaded without error or memory leak +//! @SYMTestActions Send command OMX_StateIdle and Allocate required number of buffers +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateExecuting and wait for callback to return OMX_EventCmdComplete +//! Fill Allocated buffer with colour using filled CCameraBuffer* +//! Call Empty this buffer and wait for DoEmptyBufferDone callback +//! Send command OMX_StateIdle prior to Empty this buffer done callback +//! Or in second Empty this buffer done callback +//! Wait for callback to return OMX_EventCmdComplete +//! Send command OMX_StateLoaded and Free required number of buffer +//! Wait for callback to return OMX_EventCmdComplete +//! COmxILGraphicSinkProcessingFunction::StateTransitionIndication +//! COmxILGraphicSinkProcessingFunction::CreateBufferL +//! COmxILGraphicSinkProcessingFunction::DestroyBuffer +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-010-00-HP z:\omxil\configs\tsu_omxilgraphicsink.ini DoBufferDoneFive +RUN_TEST_STEP 100 tsu_omxilgraphicsink MMVIDEO-OMX-GS-010-00-HP z:\omxil\configs\tsu_omxilgraphicsink.ini DoBufferDoneSix +END_TESTCASE MMVIDEO-OMX-GS-010-05-HP diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/src/graphicsinktestbase.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/src/graphicsinktestbase.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,1882 @@ +/* +* Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include "graphicsinktestbase.h" +#include +#include +#include + +const TInt MAXNUMOFBUFFERS = 30; // Due to the size of buffers we limit the max number of buffers + +/* + * There are known issues due to limitations in the OMX core with tests that repeatedly load + * and unload buffers. If left to run until the timer runs out they inevitably end up failing + * and causing problems for subsequent test steps due to iffy clean-up. This constant is therefore + * used to limit the amount of test iterations to a "safe" number. + */ +const TInt KMaxTestIterations = 25; + +CGraphicsSinkTestBase::CGraphicsSinkTestBase() + { + iTestIteration = 0; + iTestTimedOut = EFalse; + iWaitForResources = EFalse; + iExecuteToIdleCount = 0; + iDoEmptyBufferDoneLimit = 20; + iExecutingToIdle = ETrue; + iDoEmptyBufferDoneCount = 0; + iIdleToExecuteCount = 0; + iPauseStateCount = 0; + } + +CGraphicsSinkTestBase::~CGraphicsSinkTestBase() + { + + } + +void CGraphicsSinkTestBase::WaitForEvent(OMX_EVENTTYPE aEvent) + { + INFO_PRINTF2(_L("Wait for event %d cmd"),aEvent); + iEventToWaitFor = aEvent; + CActiveScheduler::Start(); + } + +void CGraphicsSinkTestBase::DoFillBufferDone(OMX_HANDLETYPE /*aComponent*/,OMX_BUFFERHEADERTYPE* /*aBufferHeader*/) + { + // Should never be called as graphic sink does not support this + INFO_PRINTF1(_L("CGraphicsSinkTestBase::DoFillBufferDone")); + } + +void CGraphicsSinkTestBase::DoEmptyBufferDone(OMX_HANDLETYPE aComponent,OMX_BUFFERHEADERTYPE* aBufferHeader) + { + // INFO_PRINTF3(_L("CGraphicsSinkTestBase::DoEmptyBufferDone: Count %d Limit %d"), iDoEmptyBufferDoneCount,iDoEmptyBufferDoneLimit); + + //INFO_PRINTF2(_L("CGraphicsSinkTestBase::DoEmptyBufferDone: Received pBuffer 0x%08x"), aBufferHeader->pBuffer ); + + TInt error = iInputBufferHeaders.Append(aBufferHeader); + if (error != KErrNone) + { + ERR_PRINTF1(_L("OOM ERROR")); + CActiveScheduler::Stop(); + return SetTestStepError(error); + } + + if (iIgnoreNextBufferDone) + { + iIgnoreNextBufferDone = EFalse; + return; + } + + if (iInputBufferHeaders.Count() == 0) + { + ERR_PRINTF1(_L("iInputBufferHeaders count has dropped to 0")); + CActiveScheduler::Stop(); + return SetTestStepResult(EFail); + } + + iDoEmptyBufferDoneCount++; + + OMX_COMPONENTTYPE* comp = static_cast(aComponent); + + if (iTestCase == 10) + { + if ((iDoEmptyBufferDoneCount < iDoEmptyBufferDoneLimit || iDoEmptyBufferDoneLimit == 0) && !iTestTimedOut) + { + iInputBufferHeader = iInputBufferHeaders[0]; + iInputBufferHeaders.Remove(0); + + iInputBufferHeader->nFilledLen = iOmxParamPortInput.format.video.nFrameWidth * + COmxILMMBuffer::BytesPerPixel(iOmxParamPortInput.format.video.eColorFormat) * + iOmxParamPortInput.format.video.nFrameHeight; + + iInputBufferHeader->nFlags = OMX_BUFFERFLAG_SYNCFRAME; + + iOmxErrorType = comp->EmptyThisBuffer(comp,iInputBufferHeader); + if (OMX_ErrorNone != iOmxErrorType) + { + ERR_PRINTF1(_L("EmptyThisBuffer returned an error")); + PrintOmxError(iOmxErrorType); + return SetTestStepError(iOmxErrorType); + } + + if (iTestStep == 6) + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateIdle,0); + } + } + else + { + iDoEmptyBufferDoneCount = 0; + iIgnoreNextBufferDone = ETrue; + if (iTestStep != 5 && iTestStep != 6) + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateIdle,0); + } + } + } + else + { + if (TestStepName() == (_L("MMVIDEO-OMX-GS-005-05-HP"))) + { + iDoEmptyBufferDoneCount = 0; + } + + if (iDoEmptyBufferDoneCount < iDoEmptyBufferDoneLimit && !iTestTimedOut) + { + //INFO_PRINTF2(_L("CGraphicsSinkTestBase::DoEmptyBufferDone: Sending pBuffer 0x%08x"), iInputBufferHeaders[0]->pBuffer ); + + iInputBufferHeader = iInputBufferHeaders[0]; + iInputBufferHeaders.Remove(0); + + TInt bytesperpixel = COmxILMMBuffer::BytesPerPixel(iOmxParamPortInput.format.video.eColorFormat); + iInputBufferHeader->nFilledLen = iOmxParamPortInput.format.video.nFrameWidth * bytesperpixel * + iOmxParamPortInput.format.video.nFrameHeight; + iInputBufferHeader->nOffset = aBufferHeader->nOffset; + iInputBufferHeader->nFlags = OMX_BUFFERFLAG_SYNCFRAME; + + iOmxErrorType = comp->EmptyThisBuffer(comp,iInputBufferHeader); + if (OMX_ErrorNone != iOmxErrorType) + { + ERR_PRINTF1(_L("EmptyThisBuffer returned an error")); + PrintOmxError(iOmxErrorType); + return SetTestStepError(iOmxErrorType); + } + } + else + { + iDoEmptyBufferDoneCount = 0; + iIgnoreNextBufferDone = ETrue; + if (TestStepName() != (_L("MMVIDEO-OMX-GS-004-06-HP"))) + { + if (iExecutingToIdle) + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateIdle,0); + } + else + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StatePause,0); + } + } + } + } + } + + +TVerdict CGraphicsSinkTestBase::DoGSCompAllocTestL() + { + TVerdict result = EPass; + + // Create a callback handler, graphic sink handle and destroy it + iError = OMX_Init(); + if(iError != OMX_ErrorNone) + { + iError = OMX_Deinit(); + User::Leave(KErrNoMemory); + } + + delete iCallbackHandler; + iCallbackHandler = NULL; + TRAPD(error, iCallbackHandler = CCallbackHandler::NewL(*this)); + + if (!error) + { + OMX_CALLBACKTYPE* omxCallbacks = *iCallbackHandler; + OMX_PTR appData = iCallbackHandler; + OMX_HANDLETYPE graphicsSinkHandle = NULL; + OMX_STRING graphicsSinkComponentName = "OMX.SYMBIAN.VIDEO.GRAPHICSINK"; + + iError = OMX_GetHandle( + &graphicsSinkHandle, + graphicsSinkComponentName, + appData, + omxCallbacks); + + if (iError == OMX_ErrorNone) + { + iGraphicSinkCompHandle = (OMX_COMPONENTTYPE*)graphicsSinkHandle; + OMX_FreeHandle(iGraphicSinkCompHandle); + delete iCallbackHandler; + iCallbackHandler = NULL; + iError = OMX_Deinit(); + if(iError != OMX_ErrorNone) + { + User::Leave(KErrGeneral); + } + } + else + { + result = EFail; + PrintOmxError(iError); + ERR_PRINTF2(_L("Unexpected %d return OMX_GetHandle"), iError); + delete iCallbackHandler; + iCallbackHandler = NULL; + iError = OMX_Deinit(); + User::Leave(KErrNoMemory); + } + } + else + { + ERR_PRINTF2(_L("Unexpected %d return CCallbackHandler::NewL()"), iError); + result = EFail; + iError = OMX_Deinit(); + User::Leave(KErrNoMemory); + } + + return result; + } + + +void CGraphicsSinkTestBase::DoEventHandler(OMX_HANDLETYPE aComponent, OMX_EVENTTYPE aEvent, + TUint aData1, TUint aData2, TAny* aExtra) + { +/* OMX_COMPONENTTYPE* comp = static_cast(aComponent); + if (comp == iCameraSourceCompHandle && + aEvent == OMX_EventCmdComplete && + aData1 == OMX_CommandPortDisable && + (aData2 == KCameraVCPortIndex || aData2 == KCameraClockPortIndex)) + { + return; + } +*/ + OMX_ERRORTYPE errorEvent = static_cast( aData1 ); + + switch (aEvent) + { + case OMX_EventError: + { + if(TestStepName() == (_L("MMVIDEO-OMX-GS-001-01-HP"))) + { + ErrorEventTask_001(errorEvent); + } + else + { + switch (errorEvent) + { + case OMX_ErrorFormatNotDetected: + { + // INFO_PRINTF1(_L("DoEventHandler: OMX_EventError [OMX_ErrorFormatNotDetected]")); + PrintOmxError(OMX_ErrorFormatNotDetected); + CActiveScheduler::Stop(); + return SetTestStepError(KErrGeneral); + } + case OMX_ErrorIncorrectStateOperation: + { + // INFO_PRINTF1(_L("DoEventHandler: OMX_EventError [OMX_ErrorIncorrectStateOperation]")); + if(TestStepName() == (_L("MMVIDEO-OMX-GS-002-04-HP"))) + { + CActiveScheduler::Stop(); + return SetTestStepResult(EPass); + } + CActiveScheduler::Stop(); + return SetTestStepError(PrintOmxError(OMX_ErrorIncorrectStateOperation)); + } + case OMX_ErrorInvalidState: + { + // INFO_PRINTF1(_L("DoEventHandler: OMX_EventError [OMX_ErrorInvalidState]")); + CActiveScheduler::Stop(); + PrintOmxError(OMX_ErrorInvalidState); + return SetTestStepError(KErrGeneral); + } + case OMX_ErrorPortUnpopulated: + { + // INFO_PRINTF1(_L("DoEventHandler: OMX_EventError [OMX_ErrorPortUnpopulated]")); + if (TestStepName() == (_L("MMVIDEO-OMX-GS-006-02-HP"))) + { + if (--iInputBufferHeadersCount == 0) + CActiveScheduler::Stop(); + return SetTestStepResult(EPass); + } + } + default: + { + INFO_PRINTF2(_L("DoEventHandler: OMX_EventError [%d]"), aData1); + CActiveScheduler::Stop(); + return SetTestStepError(KErrGeneral); + } + } + } + } + case OMX_EventBufferFlag: + { + break; + } + case OMX_EventCmdComplete: + { + InitiateNextStateTransition(aComponent, aData1, aData2, aExtra); + break; + } + case OMX_EventPortSettingsChanged: + { + if(iEventToWaitFor == aEvent) + { + iEventToWaitFor = OMX_EventMax; + CActiveScheduler::Stop(); + return SetTestStepResult(EPass); + } + else + { + UpdateSettingChanged(aComponent, aData1, aData2, aExtra); + } + break; + } + + /* case OMX_EventNokiaFirstFrameDisplayed: + { + break; + }*/ + + default: + { + INFO_PRINTF2(_L("DoEventHandler: OMX Event [%d]"), aEvent); + CActiveScheduler::Stop(); + return SetTestStepError(KErrGeneral); + } + } + } + +void CGraphicsSinkTestBase::InitiateNextStateTransition(OMX_HANDLETYPE /*aComponent*/, TUint /*aData1*/, + TUint aData2, TAny* /*aExtra*/) + { + switch(aData2) + { + case OMX_StateLoaded: + { + if(TestStepName() == (_L("MMVIDEO-OMX-GS-002-01-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-002-02-HP")) + || TestStepName() == (_L("MMVIDEO-OMX-GS-002-03-HP"))) + { + LoadedStateTask_002(); + } + else + { + if(TestStepName() == (_L("MMVIDEO-OMX-GS-003-01-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-003-02-HP")) + || TestStepName() == (_L("MMVIDEO-OMX-GS-003-03-HP"))) + { + LoadedStateTask_003(); + } + else + { + if(TestStepName() == (_L("MMVIDEO-OMX-GS-004-01-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-004-02-HP")) + || TestStepName() == (_L("MMVIDEO-OMX-GS-004-03-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-004-04-HP")) + || TestStepName() == (_L("MMVIDEO-OMX-GS-004-05-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-004-06-HP"))) + { + LoadedStateTask_004(); + } + else + { + if(TestStepName() == (_L("MMVIDEO-OMX-GS-005-01-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-005-02-HP")) + || TestStepName() == (_L("MMVIDEO-OMX-GS-005-03-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-005-04-HP")) + || TestStepName() == (_L("MMVIDEO-OMX-GS-005-05-HP"))) + { + LoadedStateTask_005(); + } + else + { + if (TestStepName() == (_L("MMVIDEO-OMX-GS-006-01-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-006-02-HP"))) + { + LoadedStateTask_006(); + } + else + { + if(TestStepName() == (_L("MMVIDEO-OMX-GS-007-01-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-007-02-HP")) || + TestStepName() == (_L("MMVIDEO-OMX-GS-007-03-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-007-04-HP"))) + { + LoadedStateTask_007(); + } + else + { + if (iTestCase == 9) + { + LoadedStateTransitionTask(); + } + else + { + if (iTestCase == 10) + { + LoadedStateBufferTask(); + } + else + { + INFO_PRINTF1(_L("CGraphicsSinkTestBase::DoEventHandler State set to OMX_StateLoaded")); + } + } + } + } + } + } + } + } + break; + } + case OMX_StateWaitForResources: + { + if (iTestCase == 9) + { + WaitForResourcesTransitionTask(); + } + else + { + INFO_PRINTF1(_L("CGraphicsSinkTestBase::DoEventHandler State set to OMX_StateWaitForResources")); + } + break; + } + case OMX_StateIdle: + { + if(TestStepName() == (_L("MMVIDEO-OMX-GS-002-01-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-002-02-HP")) + || TestStepName() == (_L("MMVIDEO-OMX-GS-002-03-HP"))) + { + IdleStateTask_002(); + } + else + { + if(TestStepName() == (_L("MMVIDEO-OMX-GS-003-01-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-003-02-HP")) + || TestStepName() == (_L("MMVIDEO-OMX-GS-003-03-HP"))) + { + IdleStateTask_003(); + } + else + { + if(TestStepName() == (_L("MMVIDEO-OMX-GS-004-01-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-004-02-HP")) + || TestStepName() == (_L("MMVIDEO-OMX-GS-004-03-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-004-04-HP")) + || TestStepName() == (_L("MMVIDEO-OMX-GS-004-05-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-004-06-HP"))) + { + IdleStateTask_004(); + } + else + { + if(TestStepName() == (_L("MMVIDEO-OMX-GS-005-01-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-005-02-HP")) + || TestStepName() == (_L("MMVIDEO-OMX-GS-005-03-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-005-04-HP")) + || TestStepName() == (_L("MMVIDEO-OMX-GS-005-05-HP"))) + { + IdleStateTask_005(); + } + else + { + if (TestStepName() == (_L("MMVIDEO-OMX-GS-006-01-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-006-02-HP"))) + { + IdleStateTask_006(); + } + else + { + if(TestStepName() == (_L("MMVIDEO-OMX-GS-007-01-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-007-02-HP")) || + TestStepName() == (_L("MMVIDEO-OMX-GS-007-03-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-007-04-HP"))) + { + IdleStateTask_007(); + } + else + { + if (iTestCase == 9) + { + IdleStateTransitionTask(); + } + else + { + if (iTestCase == 10) + { + IdleStateBufferTask(); + } + else + { + INFO_PRINTF1(_L("CGraphicsSinkTestBase::DoEventHandler State set to OMX_StateIdle")); + } + } + } + } + } + } + } + } + break; + } + case OMX_StateExecuting: + { + if(TestStepName() == (_L("MMVIDEO-OMX-GS-004-01-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-004-02-HP")) + || TestStepName() == (_L("MMVIDEO-OMX-GS-004-03-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-004-04-HP")) + || TestStepName() == (_L("MMVIDEO-OMX-GS-004-05-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-004-06-HP"))) + { + ExecutingStateTask_004(); + } + else + { + if(TestStepName() == (_L("MMVIDEO-OMX-GS-005-01-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-005-02-HP")) + || TestStepName() == (_L("MMVIDEO-OMX-GS-005-03-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-005-04-HP")) + || TestStepName() == (_L("MMVIDEO-OMX-GS-005-05-HP"))) + { + ExecutingStateTask_005(); + } + else + { + if (TestStepName() == (_L("MMVIDEO-OMX-GS-007-01-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-007-02-HP")) + || TestStepName() == (_L("MMVIDEO-OMX-GS-007-03-HP"))) + { + ExecutingStateTask_007(); + } + else + { + if (iTestCase == 9) + { + ExecutingStateTransitionTask(); + } + else + { + if (iTestCase == 10) + { + ExecutingStateBufferTask(); + } + else + { + switch(iPreviousState) + { + case OMX_StateIdle: + { + iPreviousState = OMX_StateExecuting; + EmptyThisBufferTask(); + break; + } + case OMX_StatePause: + { + iPreviousState = OMX_StateExecuting; + EmptyThisBufferTask(); + break; + } + } + } + } + } + } + } + break; + } + case OMX_StatePause: + { + if(TestStepName() == (_L("MMVIDEO-OMX-GS-007-01-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-007-02-HP")) || + TestStepName() == (_L("MMVIDEO-OMX-GS-007-03-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-007-04-HP"))) + { + PauseStateTask_007(); + } + else + { + INFO_PRINTF1(_L("CGraphicsSinkTestBase::DoEventHandler State set to OMX_StatePause")); + } + break; + } + case OMX_StateInvalid: + { + if(TestStepName() == (_L("MMVIDEO-OMX-GS-001-01-HP"))) + { + INFO_PRINTF1(_L("CGraphicsSinkTestBase::GSTest001: Loaded to Invalid")); + // Not really intended for loaded to invalid test but booleon needed + iExecutingToIdle = EFalse; + } + else + { + INFO_PRINTF1(_L("CGraphicsSinkTestBase::DoEventHandler State set to OMX_StateInvalid")); + } + break; + } + } + } + +void CGraphicsSinkTestBase::UpdateSettingChanged(OMX_HANDLETYPE /*aComponent*/,TUint aData1,TUint /*aData2*/,TAny* /*aExtra*/) + { + TInt err = KErrGeneral; + + if(aData1 == iSurfaceConfigExt || + aData1 == OMX_IndexConfigCommonScale || + aData1 == OMX_IndexConfigCommonOutputSize || + aData1 == OMX_IndexConfigCommonInputCrop || + aData1 == OMX_IndexConfigCommonOutputCrop || + aData1 == OMX_IndexConfigCommonExclusionRect) + { + // port setting has been changed with Configs + TSurfaceId surfaceId; + (*iSurfaceConfig).GetSurfaceId(surfaceId); + // INFO_PRINTF2(_L("Surface Id:%d"),surfaceId); + err = iWindow->SetBackgroundSurface(*iSurfaceConfig, ETrue); + if(KErrNone != err) + { + ERR_PRINTF2(_L("SetSurfaceId fails with error: %d"),err); + SetTestStepError(KErrGeneral); + return SetTestStepResult(EFail); + } + // SetBackgroundSurface OK + } + } + + +void CGraphicsSinkTestBase::CloseTestStep() + { + delete iCamOutputBuffer; + + FreeBuffer( iGraphicSinkCompHandle, 0, iInputBufferHeaders, OMX_ErrorNone ); + iInputBufferHeaders.Reset(); + + COmxGsTestBase::CloseTest(); + } + +void CGraphicsSinkTestBase::EmptyThisBufferTask() + { + // INFO_PRINTF2(_L("CGraphicsSinkTestBase::EmptyThisBufferTask: Empty this buffer task Count %d"),iDoEmptyBufferDoneCount); + + TInt bytesperpixel = COmxILMMBuffer::BytesPerPixel(iOmxParamPortInput.format.video.eColorFormat); + // CGraphicsSinkTestBase::EmptyThisBufferTask: Fill COmxILMMBuffer* with colour + FillCCamBuffer(iChunk, iOmxParamPortInput.format.video.nFrameWidth,iOmxParamPortInput.format.video.nFrameHeight,bytesperpixel,iOmxParamPortInput.nBufferCountActual); + + //INFO_PRINTF2(_L("CGraphicsSinkTestBase::EmptyThisBufferTask: Sending pBuffer 0x%08x"), iInputBufferHeaders[0]->pBuffer ); + + iInputBufferHeader = iInputBufferHeaders[0]; + iInputBufferHeader->nFilledLen = iOmxParamPortInput.format.video.nFrameWidth * + COmxILMMBuffer::BytesPerPixel(iOmxParamPortInput.format.video.eColorFormat) * + iOmxParamPortInput.format.video.nFrameHeight; + iInputBufferHeaders.Remove(0); + iOmxErrorType = iGraphicSinkCompHandle->EmptyThisBuffer(iGraphicSinkCompHandle,iInputBufferHeader); + + + if (OMX_ErrorNone != iOmxErrorType) + { + ERR_PRINTF1(_L("EmptyThisBuffer returned an error")); + return SetTestStepError(KErrGeneral); + } + + if (TestStepName() == (_L("MMVIDEO-OMX-GS-004-06-HP"))) + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateIdle, 0); + } + else + { + if( iIgnoreNextBufferDone ){ + iIgnoreNextBufferDone = EFalse; + return; + } + // else... + + //INFO_PRINTF2(_L("CGraphicsSinkTestBase::EmptyThisBufferTask: Sending pBuffer 0x%08x"), iInputBufferHeaders[0]->pBuffer ); + + iInputBufferHeader = iInputBufferHeaders[0]; + iInputBufferHeaders.Remove(0); + iInputBufferHeader->nFilledLen = iOmxParamPortInput.format.video.nFrameWidth * + COmxILMMBuffer::BytesPerPixel(iOmxParamPortInput.format.video.eColorFormat) * + iOmxParamPortInput.format.video.nFrameHeight; + iInputBufferHeader->nFlags = OMX_BUFFERFLAG_SYNCFRAME; + iOmxErrorType = iGraphicSinkCompHandle->EmptyThisBuffer(iGraphicSinkCompHandle,iInputBufferHeader); + if (OMX_ErrorNone != iOmxErrorType) + { + ERR_PRINTF1(_L("EmptyThisBuffer returned an error")); + return SetTestStepError(KErrGeneral); + } + } + } + +void CGraphicsSinkTestBase::DoROmxGsTestSetup() + { + TRAPD(err,CreateWindowL()); + if(err != KErrNone) + { + ERR_PRINTF2(_L("CreateWindow Failed %d"),err); + return SetTestStepError(err); + } + + OMX_INDEXTYPE videoSurfaceConfigIndex = OMX_IndexMax; + + iError = iGraphicSinkCompHandle->GetExtensionIndex(iGraphicSinkCompHandle, const_cast(sOmxSymbianGfxSurfaceConfig), &videoSurfaceConfigIndex); + if(OMX_ErrorNone != iError) + { + ERR_PRINTF1(_L("OMX_GetExtensionIndex Failed")); + PrintOmxError(iError); + return SetTestStepError(KErrGeneral); + } + + OMX_SYMBIAN_VIDEO_PARAM_SURFACECONFIGURATION surfaceConfig; + surfaceConfig.nSize = sizeof(OMX_SYMBIAN_VIDEO_PARAM_SURFACECONFIGURATION); + surfaceConfig.nVersion = TOmxILSpecVersion(); + surfaceConfig.nPortIndex = 0; + + GetParameter(iGraphicSinkCompHandle, videoSurfaceConfigIndex, &surfaceConfig); + if(NULL == surfaceConfig.pSurfaceConfig) + { + ERR_PRINTF1(_L("GetParameter Failed 01")); + return SetTestStepError(KErrGeneral); + } + + iSurfaceConfig = reinterpret_cast(surfaceConfig.pSurfaceConfig); + // INFO_PRINTF2(_L("SurfaceConfig : %x"), iSurfaceConfig); + TSurfaceId surfaceId; + (*iSurfaceConfig).GetSurfaceId(surfaceId); + // INFO_PRINTF2(_L("Surface Id:%d: "),surfaceId); + + // Get default OMX_PARAM_PORTDEFINITIONTYPE paramaters + iOmxParamPortInput.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + iOmxParamPortInput.nVersion = TOmxILSpecVersion(); + iOmxParamPortInput.nPortIndex = 0; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&iOmxParamPortInput); + + // Set the color format to the supported type OMX_COLOR_FormatCbYCrY + // initial settings + iOmxParamPortInput.format.video.eColorFormat = OMX_COLOR_FormatCbYCrY; + iOmxParamPortInput.format.video.nFrameWidth = 320; + iOmxParamPortInput.format.video.nFrameHeight = 240; + iOmxParamPortInput.format.video.nStride = 320*2; + iOmxParamPortInput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&iOmxParamPortInput); + } + +void CGraphicsSinkTestBase::DeleteCCameraBuf() + { + // Clean up from AllocateCCameraBuf + if (iCamOutputBuffer) + { + delete iCamOutputBuffer; + iCamOutputBuffer = NULL; + + iTestChunk.Close(); + iSurfaceUpdateSession.CancelAllUpdateNotifications(); + iSurfaceUpdateSession.Close(); + iSurfaceManager.CloseSurface(iSurfaceId); + iSurfaceId = TSurfaceId::CreateNullId(); + iSurfaceManager.Close(); + } + } + +void CGraphicsSinkTestBase::AllocateCCameraBuf() + { + // Setting paramters for surface manager + iOmxParamPortInput.format.video.eColorFormat = OMX_COLOR_FormatCbYCrY; + iOmxParamPortInput.format.video.xFramerate = 0; + iOmxParamPortInput.format.video.nFrameHeight = 320; + iOmxParamPortInput.format.video.nFrameWidth = 240; + iOmxParamPortInput.format.video.nStride = iOmxParamPortInput.format.video.nFrameWidth * COmxILMMBuffer::BytesPerPixel(iOmxParamPortInput.format.video.eColorFormat); + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&iOmxParamPortInput); + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&iOmxParamPortInput); + + // Create surface manager + RSurfaceManager::TSurfaceCreationAttributesBuf bf; + RSurfaceManager::TSurfaceCreationAttributes& b = bf(); + + b.iSize.iWidth = iOmxParamPortInput.format.video.nFrameWidth; + b.iSize.iHeight = iOmxParamPortInput.format.video.nFrameHeight; + b.iBuffers = iOmxParamPortInput.nBufferCountActual; + b.iPixelFormat = EUidPixelFormatRGB_565; // Look for conversion method + b.iStride = iOmxParamPortInput.format.video.nStride; + b.iOffsetToFirstBuffer = 0; + b.iOffsetBetweenBuffers = 0; // let surfacemanager choose. +#ifndef __WINSCW__ + b.iAlignment = RSurfaceManager::EPageAligned; +#else + b.iAlignment = 2; //TBC //working algn = 2z +#endif + b.iContiguous = ETrue; + b.iMappable = ETrue; + + TInt grapherr = InitialiseSurfaceManager(); + if(grapherr != KErrNone && grapherr != KErrAlreadyExists) + { + ERR_PRINTF1(_L("CGraphicsSurfaceSink::NewL FAILED")); + return SetTestStepError(grapherr); + } + + TRAPD(error, iCamOutputBuffer = COmxILMMBuffer::NewL(iTestChunk)); + if(error != KErrNone) + { + ERR_PRINTF1(_L("COmxILMMBuffer::NewL FAILED")); + return SetTestStepError(error); + } + + TInt ret = CreateAndMapSurface(bf, iCamOutputBuffer->SurfaceId()); + if(ret != KErrNone) + { + ERR_PRINTF2(_L("CreateAndMapSurfaceL FAILED: %d"), ret); + return SetTestStepError(ret); + } + //INFO_PRINTF2(_L("CGraphicsSinkTestBase::UseBufferTask: Chunk size: %d"),iCamOutputBuffer->Chunk().Size()); + + RSurfaceManager::TInfoBuf surfacebuf; + ret = iSurfaceManager.SurfaceInfo(iCamOutputBuffer->SurfaceId(), surfacebuf); + if(ret != KErrNone) + { + ERR_PRINTF1(_L("RSurfaceManager::SurfaceInfo FAILED")); + return SetTestStepError(ret); + } + + // INFO_PRINTF2(_L("Surface Id:%d "),iCamOutputBuffer->SurfaceId()); + iCamOutputBuffer->SurfaceInfoV01() = surfacebuf(); + // INFO_PRINTF2(_L("Handle of RChunk graph: %d"),iCamOutputBuffer->Chunk().Handle()); + + TInt numberofbuffer = b.iBuffers; + for(TInt i = 0 ; i < numberofbuffer; i++ ) + { + TInt offset; + iSurfaceManager.GetBufferOffset(iCamOutputBuffer->SurfaceId(),i,offset); + + //INFO_PRINTF3(_L("CGraphicsSinkTestBase::AllocateCCameraBuf() offset no %d = %d"), i , offset); + + iCamOutputBuffer->OffsetInfoArray().Append(offset); + } + + } + +void CGraphicsSinkTestBase::AllocateBufferTask() + { + TInt bytesperpixel = COmxILMMBuffer::BytesPerPixel(iOmxParamPortInput.format.video.eColorFormat); + TInt size = bytesperpixel * iOmxParamPortInput.format.video.nFrameWidth * iOmxParamPortInput.format.video.nFrameHeight; + + // Assume that allocate buffer is only called in state loaded + iPreviousState = OMX_StateLoaded; + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateIdle,0); + AllocateBuffer(iGraphicSinkCompHandle,&iInputBufferHeader,0,NULL,size,&iInputBufferHeaders,iOmxParamPortInput.nBufferCountActual); + // This also confirms that the buffer count is correct, as is shouldnt be zero + if (iInputBufferHeaders.Count() == 0) + { + ERR_PRINTF2(_L("CGraphicsSinkTestBase::AllocateBufferTask: iInputBufferHeaders Count %d"),iInputBufferHeaders.Count()); + CActiveScheduler::Stop(); + return SetTestStepError(KErrGeneral); + } + iInputBufferHeadersCount = iInputBufferHeaders.Count(); + // Create COmxILMMBuffer* + // INFO_PRINTF2(_L("CGraphicsSinkTestBase::AllocateBufferTask: reinterpret_cast COmxILMMBuffer* %d"),iInputBufferHeaders[0]->pInputPortPrivate); + + + // duplicate chunk given from component by getconfig + OMX_INDEXTYPE sharedChunkMetadataExtensionIndex; + // due to chunk extension support in gfx + if (OMX_ErrorNone == OMX_GetExtensionIndex( + iGraphicSinkCompHandle, + OMX_SYMBIAN_INDEX_CONFIG_SHAREDCHUNKMETADATA_NAME, + &sharedChunkMetadataExtensionIndex)) + { + // Communicate the shared chunk metadata to the tunnelled + // component + OMX_SYMBIAN_CONFIG_SHAREDCHUNKMETADATATYPE configSharedChunkMetadata; + configSharedChunkMetadata.nSize = sizeof(OMX_SYMBIAN_CONFIG_SHAREDCHUNKMETADATATYPE); + configSharedChunkMetadata.nVersion = TOmxILSpecVersion(); + configSharedChunkMetadata.nPortIndex = 0; + + (void) OMX_GetConfig(iGraphicSinkCompHandle, + sharedChunkMetadataExtensionIndex, + &configSharedChunkMetadata); + + + //map the chunk into this process + RThread chunkOwnerThread; + User::LeaveIfError(chunkOwnerThread.Open(TThreadId(configSharedChunkMetadata.nOwnerThreadId))); + CleanupClosePushL(chunkOwnerThread); + + iChunk.SetHandle(configSharedChunkMetadata.nHandleId); + User::LeaveIfError(iChunk.Duplicate(chunkOwnerThread)); + CleanupStack::PopAndDestroy(&chunkOwnerThread); + + } + else + { + ERR_PRINTF1(_L("Failed to fetch shared chunk metadata from gfx sink.")); + CActiveScheduler::Stop(); + return SetTestStepError( KErrGeneral ); + } + + } + +void CGraphicsSinkTestBase::UseBufferTask() + { + TInt size = 0; + if( iCamOutputBuffer->OffsetInfoArray().Count() < 2 ){ + iSurfaceManager.GetBufferOffset( iCamOutputBuffer->SurfaceId(), 0, size ); + } + else{ + size = iCamOutputBuffer->OffsetInfoArray()[1] - iCamOutputBuffer->OffsetInfoArray()[0]; + } + + // Assume that use buffer is only called in state loaded + iPreviousState = OMX_StateLoaded; + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateIdle,0); + + // due to chunk extension support in gfx + OMX_INDEXTYPE sharedChunkMetadataExtensionIndex; + if (OMX_ErrorNone == OMX_GetExtensionIndex( + iGraphicSinkCompHandle, + OMX_SYMBIAN_INDEX_CONFIG_SHAREDCHUNKMETADATA_NAME, + &sharedChunkMetadataExtensionIndex)) + { + // Communicate the shared chunk metadata to the tunnelled + // component + OMX_SYMBIAN_CONFIG_SHAREDCHUNKMETADATATYPE configSharedChunkMetadata; + configSharedChunkMetadata.nSize = sizeof(OMX_SYMBIAN_CONFIG_SHAREDCHUNKMETADATATYPE); + configSharedChunkMetadata.nVersion = TOmxILSpecVersion(); + configSharedChunkMetadata.nPortIndex = 0; + configSharedChunkMetadata.nHandleId = iCamOutputBuffer->Chunk().Handle(); + configSharedChunkMetadata.nOwnerThreadId = RThread().Id().Id(); + + iError = OMX_SetConfig(iGraphicSinkCompHandle, + sharedChunkMetadataExtensionIndex, + &configSharedChunkMetadata); + + if (OMX_ErrorNone != iError) + { + ERR_PRINTF1(_L("CGraphicsSinkTestBase::UseBufferTask: Set shared chunk config error!")); + return SetTestStepError(PrintOmxError(iError)); + } + } + + + for (TInt i = 0 ; i < iOmxParamPortInput.nBufferCountActual; i++) + { + //INFO_PRINTF4(_L("CGraphicsSinkTestBase::UseBufferTask: size = %d, chunk base = 0x%08x, offset = %d.") , size, iCamOutputBuffer->Chunk().Base(), iCamOutputBuffer->OffsetInfoArray()[i] ); + iError = iGraphicSinkCompHandle->UseBuffer(iGraphicSinkCompHandle, + &iOutputBufferHeader, + 0, // input port + NULL, /*iCamOutputBuffer,*/ // pAppPrivate + size, // update + iCamOutputBuffer->Chunk().Base() + iCamOutputBuffer->OffsetInfoArray()[i] /* // change made due to OMXILBufferClass */); // + if (OMX_ErrorNone != iError) + { + ERR_PRINTF1(_L("CGraphicsSinkTestBase::UseBufferTask: UseBuffer Error")); + return SetTestStepError(PrintOmxError(iError)); + } + // INFO_PRINTF2(_L("surface ID y : %d"), iCamOutputBuffer->SurfaceId()); + // INFO_PRINTF2(_L("Buffer offset : %d"), iCamOutputBuffer->iBufferOffset); + if (iOutputBufferHeaders.Append(iOutputBufferHeader) != KErrNone) + { + ERR_PRINTF1(_L("OOM ERROR")); + return SetTestStepError(KErrGeneral); + } + } + } + +void CGraphicsSinkTestBase::AllocateBufferTaskStress() + { + // Color format should be default value: OMX_COLOR_Format16bitRGB565 + TInt bytesperpixel = COmxILMMBuffer::BytesPerPixel(iOmxParamPortInput.format.video.eColorFormat); + TInt size = bytesperpixel * iOmxParamPortInput.format.video.nFrameWidth * iOmxParamPortInput.format.video.nFrameHeight; + + // Assume that allocate buffer is only called in state loaded + iPreviousState = OMX_StateLoaded; + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateIdle,0); + + for(TInt i = 0 ; i < iOmxParamPortInput.nBufferCountActual; i++ ) + { + iOmxErrorType = iGraphicSinkCompHandle->AllocateBuffer(iGraphicSinkCompHandle,&iInputBufferHeader,0,NULL,size); + if (iOmxErrorType != OMX_ErrorNone) + { + if (iOmxErrorType == OMX_ErrorInsufficientResources) + { + INFO_PRINTF2(_L("CGraphicsSinkTestBase::AllocateBufferTaskStress: AllocateBuffer returned InsufficientResources & nBufferCountActual was set to %d"),iOmxParamPortInput.nBufferCountActual); + CActiveScheduler::Stop(); + return SetTestStepResult(EPass); + } + else + { + CActiveScheduler::Stop(); + return SetTestStepError(PrintOmxError(iOmxErrorType)); + } + } + + // Used for tracking + TRAPD(err,iInputBufferHeaders.AppendL(iInputBufferHeader)); + if(err != KErrNone) + { + ERR_PRINTF2(_L("AppendL Buffer Failed %d"),err); + CActiveScheduler::Stop(); + return SetTestStepError(err); + } + } + + // This also confirms that the buffer count is correct, as is shouldnt be zero + if (iInputBufferHeaders.Count() == 0) + { + ERR_PRINTF2(_L("CGraphicsSinkTestBase::AllocateBufferTaskStress: iInputBufferHeaders Count %d"),iInputBufferHeaders.Count()); + CActiveScheduler::Stop(); + return SetTestStepError(KErrGeneral); + } + + // Create COmxILMMBuffer* + // INFO_PRINTF2(_L("CGraphicsSinkTestBase::AllocateBufferTaskStress: reinterpret_cast COmxILMMBuffer* %d"),iInputBufferHeaders[0]->pInputPortPrivate); + //iCamBuf = static_cast(iInputBufferHeaders[0]->pInputPortPrivate); + // duplicate chunk given from component by getconfig + OMX_INDEXTYPE sharedChunkMetadataExtensionIndex; + // due to chunk extension support in gfx + if (OMX_ErrorNone == OMX_GetExtensionIndex( + iGraphicSinkCompHandle, + OMX_SYMBIAN_INDEX_CONFIG_SHAREDCHUNKMETADATA_NAME, + &sharedChunkMetadataExtensionIndex)) + { + // Communicate the shared chunk metadata to the tunnelled + // component + OMX_SYMBIAN_CONFIG_SHAREDCHUNKMETADATATYPE configSharedChunkMetadata; + configSharedChunkMetadata.nSize = sizeof(OMX_SYMBIAN_CONFIG_SHAREDCHUNKMETADATATYPE); + configSharedChunkMetadata.nVersion = TOmxILSpecVersion(); + configSharedChunkMetadata.nPortIndex = 0; + + (void) OMX_GetConfig(iGraphicSinkCompHandle, + sharedChunkMetadataExtensionIndex, + &configSharedChunkMetadata); + + + //map the chunk into this process + RThread chunkOwnerThread; + User::LeaveIfError(chunkOwnerThread.Open(TThreadId(configSharedChunkMetadata.nOwnerThreadId))); + CleanupClosePushL(chunkOwnerThread); + + iChunk.SetHandle(configSharedChunkMetadata.nHandleId); + User::LeaveIfError(iChunk.Duplicate(chunkOwnerThread)); + CleanupStack::PopAndDestroy(&chunkOwnerThread); + + } + else + { + ERR_PRINTF1(_L("Failed to fetch shared chunk metadata from gfx sink.")); + CActiveScheduler::Stop(); + return SetTestStepError( KErrGeneral ); + } + } + +void CGraphicsSinkTestBase::FreeBufferTask(RPointerArray* aBufferHeaders, + OMX_U32 aPortIndex,TBool aSendCommand) + { + if (aSendCommand) + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateLoaded,0); + } + + FreeBuffer(iGraphicSinkCompHandle,aPortIndex,*aBufferHeaders); + aBufferHeaders->Reset(); + } + +void CGraphicsSinkTestBase::FreeBufferTaskAlt(RPointerArray aBufferHeaders, + OMX_U32 aPortIndex,TBool aSendCommand) + { + if (aSendCommand) + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateLoaded,0); + } + + FreeBuffer(iGraphicSinkCompHandle,aPortIndex,aBufferHeaders); + } + +void CGraphicsSinkTestBase::FillCCamBuffer(const RChunk& aCamBuf, OMX_U32 aFrameWidth, + OMX_U32 aFrameHeight, TInt aBytePerPixel, TInt aNumOfActualBuffer) + { + // FillThisBuffer + TRgb red_col(255,0,0); + TRgb blue_col(0,255,0); + TRgb green_col(0,0,255); + TRgb black_col(0,0,0); + TUint32 red_color = red_col.Color64K(); + TUint32 blue_color = blue_col.Color64K(); + TUint32 green_color = green_col.Color64K(); + TUint32 black_color = black_col.Color64K(); + TUint32 col[] = {red_color, blue_color, green_color, black_color}; + + TInt stride = aFrameWidth * aBytePerPixel; + TInt colIndex = 0; + for(TInt index=0; indexChunk().Base() + aCamBuf->BufferOffset(); + TUint8* surfacePtr = aCamBuf.Base() + (iOmxParamPortInput.nBufferSize * index); + TUint8* linePtr = surfacePtr; + + TUint16* ptr = reinterpret_cast(surfacePtr); + + // Fill first line + for (TInt xx = 0; xx < aFrameWidth; xx++) + { + colIndex = Math::Random() % 4; + ptr[xx] = (TUint16)col[colIndex]; + //ptr[xx] = (TUint16)col[colIndex%4]; + colIndex++; + } + + // Now copy that to the other lines + for (TInt yy = 1; yy < aFrameHeight; yy++) + { + linePtr += stride; + Mem::Move(linePtr, surfacePtr, stride); + } + } + } + +void CGraphicsSinkTestBase::CreateOmxParamPortDefinitionType(OMX_PARAM_PORTDEFINITIONTYPE* aOmxParamPortType) + { + aOmxParamPortType->nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + aOmxParamPortType->nVersion = TOmxILSpecVersion(); + aOmxParamPortType->nPortIndex = 0; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,aOmxParamPortType,OMX_ErrorNone); + // initial settings + aOmxParamPortType->format.video.nFrameWidth = 320; + aOmxParamPortType->format.video.nFrameHeight = 240; + aOmxParamPortType->format.video.eColorFormat = OMX_COLOR_FormatCbYCrY; + aOmxParamPortType->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + aOmxParamPortType->format.video.xFramerate = 0; + aOmxParamPortType->format.video.nStride = 320*2; + aOmxParamPortType->format.video.nSliceHeight = 10; + aOmxParamPortType->format.video.nBitrate = 96000; + } + +void CGraphicsSinkTestBase::CreateOmxVideoParamPortFormatType(OMX_VIDEO_PARAM_PORTFORMATTYPE* aOmxVideoParamPortType) + { + aOmxVideoParamPortType->nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE); + aOmxVideoParamPortType->nVersion = TOmxILSpecVersion(); + aOmxVideoParamPortType->nPortIndex = 0; + aOmxVideoParamPortType->nIndex = 0; + // The following 2 values should be over written by the correct ones for this index + aOmxVideoParamPortType->eCompressionFormat = OMX_VIDEO_CodingUnused; + aOmxVideoParamPortType->eColorFormat = OMX_COLOR_FormatCrYCbY; + aOmxVideoParamPortType->xFramerate = 0; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,aOmxVideoParamPortType,OMX_ErrorNone); + } + +void CGraphicsSinkTestBase::CompareU32Param(OMX_U32 aSetParamType, OMX_U32 aGetParamType) + { + if (aSetParamType != aGetParamType) + { + ERR_PRINTF3(_L("Comparison failed: Set value: %d Get value: %d"),aSetParamType,aGetParamType); + return SetTestStepError(KErrGeneral); + } + } + +void CGraphicsSinkTestBase::CompareCFTParam(OMX_COLOR_FORMATTYPE aInputParamType, OMX_COLOR_FORMATTYPE aOutputParamType, OMX_INDEXTYPE aIndexType) + { + if (aInputParamType != aOutputParamType) + { + ERR_PRINTF3(_L("Comparison failed: set value: %d Index : %X"),aInputParamType,aIndexType); + ERR_PRINTF3(_L("Comparison failed: get value: %d Index : %X"),aOutputParamType,aIndexType); + return SetTestStepError(KErrGeneral); + } + } + +void CGraphicsSinkTestBase::CompareVCTParam(OMX_VIDEO_CODINGTYPE aInputParamType, OMX_VIDEO_CODINGTYPE aOutputParamType, OMX_INDEXTYPE aIndexType) + { + if (aInputParamType != aOutputParamType) + { + ERR_PRINTF3(_L("Comparison failed: set value: %d Index : %X"),aInputParamType,aIndexType); + ERR_PRINTF3(_L("Comparison failed: get value: %d Index : %X"),aOutputParamType,aIndexType); + return SetTestStepError(KErrGeneral); + } + } + +void CGraphicsSinkTestBase::CompareBoolParam(OMX_BOOL aInputParamType, OMX_BOOL aOutputParamType, OMX_INDEXTYPE aIndexType) + { + if (aInputParamType != aOutputParamType) + { + ERR_PRINTF3(_L("Comparison failed: set value: %d Index : %X"),aInputParamType,aIndexType); + ERR_PRINTF3(_L("Comparison failed: get value: %d Index : %X"),aOutputParamType,aIndexType); + return SetTestStepError(KErrGeneral); + } + } + +TInt CGraphicsSinkTestBase::PostKickOffTestL(TInt aTimerId) + { + if (aTimerId == 1) + { + iTestTimedOut = ETrue; + return KErrNone; + } + else + { + if (iPreviousState == OMX_StatePause && (TestStepName() == (_L("MMVIDEO-OMX-GS-007-01-HP")) || + TestStepName() == (_L("MMVIDEO-OMX-GS-007-03-HP")))) + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateExecuting,0); + return KErrNone; + } + else + { + if (iPreviousState == OMX_StatePause && (TestStepName() == (_L("MMVIDEO-OMX-GS-007-02-HP")) || + TestStepName() == (_L("MMVIDEO-OMX-GS-007-04-HP")))) + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateIdle,0); + return KErrNone; + } + } + } + return KErrNone; + } + +void CGraphicsSinkTestBase::ErrorEventTask_001(OMX_ERRORTYPE aOmxError) + { + // INFO_PRINTF2(_L("GSTest001: EventError iteration: %d"), iTestIteration); + if (iTestIteration == 0) + { + if (aOmxError == OMX_ErrorIncorrectStateTransition) + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StatePause,0,OMX_ErrorNone); + } + else + { + ERR_PRINTF1(_L("CGraphicsSinkTestBase::ErrorEventTask_001: Invoked incorrect error event")); + CActiveScheduler::Stop(); + return SetTestStepError(KErrGeneral); + } + } + if (iTestIteration == 1) + { + if (aOmxError == OMX_ErrorIncorrectStateTransition) + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateLoaded,0,OMX_ErrorNone); + } + else + { + ERR_PRINTF1(_L("CGraphicsSinkTestBase::ErrorEventTask_001: Invoked incorrect error event")); + CActiveScheduler::Stop(); + return SetTestStepError(KErrGeneral); + } + } + if (iTestIteration == 2) + { + if (aOmxError == OMX_ErrorSameState) + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateInvalid,0,OMX_ErrorNone); + } + else + { + ERR_PRINTF1(_L("CGraphicsSinkTestBase::ErrorEventTask_001: Invoked incorrect error event")); + CActiveScheduler::Stop(); + return SetTestStepError(KErrGeneral); + } + } + if (iTestIteration == 3) + { + if (iExecutingToIdle == EFalse && aOmxError == OMX_ErrorInvalidState) + { + // INFO_PRINTF1(_L("CGraphicsSinkTestBase::ErrorEventTask_001: Invoked correct error event")); + CActiveScheduler::Stop(); + return SetTestStepResult(EPass); + } + else + { + ERR_PRINTF1(_L("CGraphicsSinkTestBase::ErrorEventTask_001: Invoked incorrect error event")); + CActiveScheduler::Stop(); + return SetTestStepResult(EPass); + } + } + iTestIteration++; + } + + +void CGraphicsSinkTestBase::LoadedStateTask_002() + { + iPreviousState = OMX_StateLoaded; + // INFO_PRINTF2(_L("GSTest002: Test complete iteration: %d"), iTestIteration); + iTestIteration++; + + if(TestStepName() == (_L("MMVIDEO-OMX-GS-002-01-HP"))) + { + if (iTestIteration == 1) + { + INFO_PRINTF1(_L("CGraphicsSinkTestBase::LoadedStateTask_002: __MM_HEAP_MARK")); + __UHEAP_MARK; + } + else + { + INFO_PRINTF1(_L("CGraphicsSinkTestBase::LoadedStateTask_002: __MM_HEAP_MARKEND")); + __UHEAP_MARKEND; + iTestTimedOut = ETrue; + } + } + + if(TestStepName() == (_L("MMVIDEO-OMX-GS-002-03-HP"))) + { + // Only increase the buffer count every 5 times + iOmxParamPortInput.nBufferCountActual = iOmxParamPortInput.nBufferCountMin + iTestIteration/5; + // INFO_PRINTF2(_L("CGraphicsSinkTestBase::LoadedStateTask_002: Setting nBufferCountActual: %d"), iOmxParamPortInput.nBufferCountActual); + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&iOmxParamPortInput); + } + + if(iTestIteration < KMaxTestIterations && !iTestTimedOut) + { + AllocateBufferTask(); + } + else + { + CActiveScheduler::Stop(); + return SetTestStepResult(EPass); + } + } + +void CGraphicsSinkTestBase::IdleStateTask_002() + { + iPreviousState = OMX_StateIdle; + FreeBufferTask(&iInputBufferHeaders,0); + } + +void CGraphicsSinkTestBase::LoadedStateTask_003() + { + iPreviousState = OMX_StateLoaded; + // INFO_PRINTF2(_L("GSTest003: Test complete iteration: %d"), iTestIteration); + iTestIteration++; + + if(TestStepName() == (_L("MMVIDEO-OMX-GS-003-01-HP"))) + { + if (iTestIteration == 1) + { + INFO_PRINTF1(_L("CGraphicsSinkTestBase::LoadedStateTask_003: __MM_HEAP_MARK")); + __UHEAP_MARK; + } + else + { + INFO_PRINTF1(_L("CGraphicsSinkTestBase::LoadedStateTask_003: __MM_HEAP_MARKEND")); + DeleteCCameraBuf(); + __UHEAP_MARKEND; + iTestTimedOut = ETrue; + } + } + + if(TestStepName() == (_L("MMVIDEO-OMX-GS-003-03-HP"))) + { + // Only increase the buffer count every 5 times + iOmxParamPortInput.nBufferCountActual = iOmxParamPortInput.nBufferCountMin + iTestIteration/5; + // INFO_PRINTF2(_L("CGraphicsSinkTestBase::LoadedStateTask_003: Setting nBufferCountActual: %d"), iOmxParamPortOutput.nBufferCountActual); + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&iOmxParamPortInput); + } + + if(!iTestTimedOut) + { + DeleteCCameraBuf(); + AllocateCCameraBuf(); + UseBufferTask(); + } + else + { + CActiveScheduler::Stop(); + return SetTestStepResult(EPass); + } + } + +void CGraphicsSinkTestBase::IdleStateTask_003() + { + iPreviousState = OMX_StateIdle; + FreeBufferTask(&iOutputBufferHeaders,0); + } + +void CGraphicsSinkTestBase::LoadedStateTask_004() + { + // INFO_PRINTF2(_L("GSTest004: Test complete iteration: %d"), iTestIteration); + iTestIteration++; + + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + iPreviousState = OMX_StateLoaded; + if(TestStepName() == (_L("MMVIDEO-OMX-GS-004-01-HP"))) + { + if (iTestIteration == 1) + { + INFO_PRINTF1(_L("CGraphicsSinkTestBase::LoadedStateTask_004: __MM_HEAP_MARK")); + __UHEAP_MARK; + } + else + { + INFO_PRINTF1(_L("CGraphicsSinkTestBase::LoadedStateTask_004: __MM_HEAP_MARKEND")); + __UHEAP_MARKEND; + iTestTimedOut = ETrue; + } + } + + if(TestStepName() == (_L("MMVIDEO-OMX-GS-004-03-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-004-05-HP"))) + { + iOmxParamPortInput.nBufferCountActual = 5 + iTestIteration/5; + INFO_PRINTF2(_L("CGraphicsSinkTestBase::LoadedStateTask_004: Setting nBufferCountActual: %d"), iOmxParamPortInput.nBufferCountActual); + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&iOmxParamPortInput); + } + + if(iTestIteration < KMaxTestIterations && !iTestTimedOut) + { + AllocateBufferTask(); + } + else + { + CActiveScheduler::Stop(); + return SetTestStepResult(EPass); + } + } + +void CGraphicsSinkTestBase::IdleStateTask_004() + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateIdle); + if(iPreviousState == OMX_StateLoaded) + { + iPreviousState = OMX_StateIdle; + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateExecuting,0); + } + else if(iPreviousState == OMX_StateExecuting) + { + // INFO_PRINTF2(_L("CGraphicsSinkTestBase::IdleStateTask_004: Executing to Idle task Count %d"),iExecuteToIdleCount); + iExecuteToIdleCount++; + iPreviousState = OMX_StateIdle; + + if (TestStepName() == (_L("MMVIDEO-OMX-GS-004-01-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-004-02-HP")) + || TestStepName() == (_L("MMVIDEO-OMX-GS-004-03-HP"))) + { + FreeBufferTask(&iInputBufferHeaders,0); + } + + if (TestStepName() == (_L("MMVIDEO-OMX-GS-004-04-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-004-05-HP")) + || TestStepName() == (_L("MMVIDEO-OMX-GS-004-06-HP"))) + { + if (iExecuteToIdleCount < 20) + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateExecuting,0); + } + else + { + FreeBufferTask(&iInputBufferHeaders,0); + } + } + } + } + +void CGraphicsSinkTestBase::ExecutingStateTask_004() + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateExecuting); + iPreviousState = OMX_StateExecuting; + + if (TestStepName() == (_L("MMVIDEO-OMX-GS-004-06-HP"))) + { + iExecuteToIdleCount = 20; + iTestTimedOut = ETrue; + EmptyThisBufferTask(); + } + else + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateIdle, 0); + } + } + +void CGraphicsSinkTestBase::LoadedStateTask_005() + { + // INFO_PRINTF2(_L("GSTest005: Test complete iteration: %d"), iTestIteration); + iTestIteration++; + + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + iPreviousState = OMX_StateLoaded; + if(TestStepName() == (_L("MMVIDEO-OMX-GS-005-01-HP"))) + { + if (iTestIteration == 1) + { + INFO_PRINTF1(_L("CGraphicsSinkTestBase::LoadedStateTask_005: __MM_HEAP_MARK")); + __UHEAP_MARK; + } + else + { + INFO_PRINTF1(_L("CGraphicsSinkTestBase::LoadedStateTask_005: __MM_HEAP_MARKEND")); + __UHEAP_MARKEND; + iTestTimedOut = ETrue; + } + } + + if(TestStepName() == (_L("MMVIDEO-OMX-GS-005-03-HP"))) + { + iOmxParamPortInput.nBufferCountActual = Min(5 + iTestIteration, 100); // let's cap the amount of buffers :-) + // INFO_PRINTF2(_L("CGraphicsSinkTestBase::LoadedStateTask_005: Setting nBufferCountActual: %d"), iOmxParamPortInput.nBufferCountActual); + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&iOmxParamPortInput); + } + + if(iTestIteration < KMaxTestIterations && !iTestTimedOut) + { + AllocateBufferTask(); + } + else + { + + CActiveScheduler::Stop(); + return SetTestStepResult(EPass); + } + } + +void CGraphicsSinkTestBase::IdleStateTask_005() + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateIdle); + if(iPreviousState == OMX_StateLoaded) + { + iPreviousState = OMX_StateIdle; + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateExecuting,0); + } + if(iPreviousState == OMX_StateExecuting) + { + iPreviousState = OMX_StateIdle; + if (TestStepName() == (_L("MMVIDEO-OMX-GS-005-04-HP")) && !iTestTimedOut) + { + // INFO_PRINTF2(_L("CGraphicsSinkTestBase::IdleStateTask_005: Test complete iteration: %d"), iTestIteration); + iTestIteration++; + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateExecuting,0); + } + else + { + FreeBufferTask(&iInputBufferHeaders,0); + } + } + } + +void CGraphicsSinkTestBase::ExecutingStateTask_005() + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateExecuting); + iPreviousState = OMX_StateExecuting; + EmptyThisBufferTask(); + } + +void CGraphicsSinkTestBase::LoadedStateTask_006() + { + // INFO_PRINTF2(_L("GSTest006: Test complete iteration: %d"), iTestIteration); + iTestIteration++; + + iPreviousState = OMX_StateLoaded; + if(TestStepName() == (_L("MMVIDEO-OMX-GS-006-01-HP")) && !iTestTimedOut) + { + iOmxParamPortInput.nBufferCountActual = iOmxParamPortInput.nBufferCountActual + 1; + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&iOmxParamPortInput); + AllocateBufferTaskStress(); + } + else + { + CActiveScheduler::Stop(); + return SetTestStepResult(EPass); + } + } + +void CGraphicsSinkTestBase::IdleStateTask_006() + { + iPreviousState = OMX_StateIdle; + if(TestStepName() == (_L("MMVIDEO-OMX-GS-006-01-HP"))) + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateLoaded,0); + + FreeBuffer(iGraphicSinkCompHandle,0,iInputBufferHeaders); + iInputBufferHeaders.Reset(); + } + if(TestStepName() == (_L("MMVIDEO-OMX-GS-006-02-HP"))) + { + // Allocate to many buffers + TInt bytesperpixel = COmxILMMBuffer::BytesPerPixel(iOmxParamPortInput.format.video.eColorFormat); + TInt size = bytesperpixel * iOmxParamPortInput.format.video.nFrameWidth * iOmxParamPortInput.format.video.nFrameHeight; + + iOmxErrorType = iGraphicSinkCompHandle->AllocateBuffer(iGraphicSinkCompHandle,&iInputBufferHeader,0,NULL,size); + if (OMX_ErrorIncorrectStateOperation != iOmxErrorType) + { + ERR_PRINTF1(_L("AllocateBuffer failed to return error")); + CActiveScheduler::Stop(); + return SetTestStepError(PrintOmxError(iOmxErrorType)); + } + + // Confirm state remains OMX_StateIdle + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateIdle); + + // FreeBuffer without calling SendCommand to OMX_StateLoaded + FreeBuffer(iGraphicSinkCompHandle, 0, iInputBufferHeaders); + iInputBufferHeaders.Reset(); + } + } + +void CGraphicsSinkTestBase::LoadedStateTask_007() + { + switch (iPreviousState) + { + case OMX_StateIdle: + { + iPreviousState = OMX_StateLoaded; + CActiveScheduler::Stop(); + return SetTestStepResult(EPass); + } + case OMX_StateWaitForResources: + { + // State is OMX_StateIdle from OMX_StateWaitForResources + break; + } + } + } + +void CGraphicsSinkTestBase::IdleStateTask_007() + { + switch (iPreviousState) + { + case OMX_StateLoaded: + { + iPreviousState = OMX_StateIdle; + if (TestStepName() == (_L("MMVIDEO-OMX-GS-007-03-HP")) || TestStepName() == (_L("MMVIDEO-OMX-GS-007-04-HP"))) + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StatePause,0); + } + else + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateExecuting,0); + } + break; + } + case OMX_StateExecuting: + { + iPreviousState = OMX_StateIdle; + if (TestStepName() == (_L("MMVIDEO-OMX-GS-007-03-HP")) && !iTestTimedOut) + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StatePause,0); + } + else + { + // INFO_PRINTF2(_L("CGraphicsSinkTestBase::IdleStateTask_007:: Executing to Idle task Count %d"),iExecuteToIdleCount); + iExecuteToIdleCount++; + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateLoaded,0); + + FreeBuffer(iGraphicSinkCompHandle,0,iInputBufferHeaders); + iInputBufferHeaders.Reset(); + } + break; + } + case OMX_StatePause: + { + iPreviousState = OMX_StateIdle; + if (TestStepName() == (_L("MMVIDEO-OMX-GS-007-04-HP")) && !iTestTimedOut) + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StatePause,0); + } + else + { + if (iTestTimedOut) + { + // INFO_PRINTF2(_L("CGraphicsSinkTestBase::IdleStateTask_007:: Executing to Idle task Count %d"),iExecuteToIdleCount); + iExecuteToIdleCount++; + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateLoaded,0); + + FreeBuffer(iGraphicSinkCompHandle,0,iInputBufferHeaders); + iInputBufferHeaders.Reset(); + } + else + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateExecuting,0); + } + } + } + } + } + +void CGraphicsSinkTestBase::PauseStateTask_007() + { + iPreviousState = OMX_StatePause; + // INFO_PRINTF2(_L("CGraphicsSinkTestBase::PauseStateTask_007:: Pause state task count %d"),iPauseStateCount); + if(++iPauseStateCount == 5) + { + iTestTimedOut = ETrue; + } + + if(iTestShutdown) + { + delete iTestShutdown; + } + + TRAPD(err, iTestShutdown = COmxGsTestShutdown::NewL(this,2)); + if(err) + { + ERR_PRINTF1(_L("OOM ERROR")); + CActiveScheduler::Stop(); + return SetTestStepError(err); + } + iInterval = KTSU_OMX_GS_PAUSE; + iTestShutdown->Start(iInterval,KErrGeneral, EPass); + } + +void CGraphicsSinkTestBase::ExecutingStateTask_007() + { + iPreviousState = OMX_StateExecuting; + // INFO_PRINTF2(_L("CGraphicsSinkTestBase::ExecutingStateTask_007 Idle to Executing task Count %d"),iIdleToExecuteCount); + iIdleToExecuteCount++; + + if (TestStepName() == (_L("MMVIDEO-OMX-GS-007-03-HP")) || iTestTimedOut) + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateIdle,0); + } + else + { + EmptyThisBufferTask(); + } + } + +void CGraphicsSinkTestBase::StartStateTransitionTask() + { + GetState(iGraphicSinkCompHandle,&iState,OMX_StateLoaded); + iGphxPrevState = iState; + + if (iTestStep == 4) + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateWaitForResources,0); + } + else + { + AllocateBufferTask(); + } + } + +void CGraphicsSinkTestBase::WaitForResourcesTransitionTask() + { + GetState(iGraphicSinkCompHandle,&iState,OMX_StateWaitForResources); + iGphxPrevState = iState; + + if (iTestStep == 4) + { + iWaitForResources = ETrue; + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateLoaded,0); + } + } + +void CGraphicsSinkTestBase::LoadedStateTransitionTask() + { + //INFO_PRINTF3(_L("GSTest00%d: Test complete iteration: %d"), iTestCase, iTestIteration); + iTestIteration++; + GetState(iGraphicSinkCompHandle,&iState,OMX_StateLoaded); + + iGphxPrevState = iState; + if(iTestStep == 1) + { + if (iTestIteration == 1) + { + INFO_PRINTF3(_L("LoadedStateTransitionTask_00%d_0%d: __MM_HEAP_MARK"), iTestCase,iTestStep); + __UHEAP_MARK; + } + else + { + INFO_PRINTF3(_L("LoadedStateTransitionTask_00%d_0%d: __MM_HEAP_MARKEND"), iTestCase,iTestStep); + __UHEAP_MARKEND; + iTestTimedOut = ETrue; + } + } + + if(iTestStep == 3) + { + if ((iOmxParamPortInput.nBufferCountMin + iTestIteration/10) <= MAXNUMOFBUFFERS) + { + iOmxParamPortInput.nBufferCountActual = iOmxParamPortInput.nBufferCountMin + iTestIteration/10; + //INFO_PRINTF3(_L("GSTest00%d: Setting INPUT nBufferCountActual: %d"),iTestCase,iOmxParamPortInput.nBufferCountActual); + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&iOmxParamPortInput); + } + } + + if(iTestIteration < KMaxTestIterations && !iTestTimedOut) + { + if (iTestStep == 4 && iWaitForResources) + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateWaitForResources,0); + } + else + { + iWaitForResources = EFalse; + AllocateBufferTask(); + } + } + else + { + CActiveScheduler::Stop(); + } + } + +void CGraphicsSinkTestBase::IdleStateTransitionTask() + { + GetState(iGraphicSinkCompHandle,&iState,OMX_StateIdle); + if(iGphxPrevState == OMX_StateLoaded) + { + iGphxPrevState = iState; + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateExecuting,0); + } + else if(iGphxPrevState == OMX_StateExecuting) + { + iGphxPrevState = iState; + FreeBufferTaskAlt(iInputBufferHeaders,0); + iInputBufferHeaders.Reset(); + } + } + +void CGraphicsSinkTestBase::ExecutingStateTransitionTask() + { + GetState(iGraphicSinkCompHandle,&iState,OMX_StateExecuting); + iGphxPrevState = iState; + + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateIdle,0); + } + +void CGraphicsSinkTestBase::StartBufferDoneTask() + { + GetState(iGraphicSinkCompHandle,&iState,OMX_StateLoaded); + iGphxPrevState = iState; + + AllocateBufferTask(); + } + +void CGraphicsSinkTestBase::LoadedStateBufferTask() + { + // INFO_PRINTF3(_L("GSTest00%d: Test complete iteration: %d"), iTestCase, iTestIteration); + iTestIteration++; + GetState(iGraphicSinkCompHandle,&iState,OMX_StateLoaded); + iGphxPrevState = iState; + if(iTestStep == 1 || iTestStep == 5|| iTestStep == 6) + { + if (iTestIteration == 1) + { + INFO_PRINTF3(_L("LoadedStateTransitionTask_00%d_0%d: __MM_HEAP_MARK"), iTestCase,iTestStep); + __UHEAP_MARK; + } + else + { + INFO_PRINTF3(_L("LoadedStateTransitionTask_00%d_0%d: __MM_HEAP_MARKEND"), iTestCase,iTestStep); + __UHEAP_MARKEND; + iTestTimedOut = ETrue; + } + } + + if(iTestStep == 3) + { + OMX_U32 setbuffercount = iOmxParamPortInput.nBufferCountMin + iTestIteration/10; + if (setbuffercount <= MAXNUMOFBUFFERS && setbuffercount != iOmxParamPortInput.nBufferCountActual) + { + iOmxParamPortInput.nBufferCountActual = iOmxParamPortInput.nBufferCountMin + iTestIteration/10; + iDoEmptyBufferDoneLimit = iOmxParamPortInput.nBufferCountActual; + INFO_PRINTF4(_L("GSTest00%d: Setting INPUT nBufferCountActual: %d DoEmptyBufferDoneLimit: %d") + ,iTestCase,iOmxParamPortInput.nBufferCountActual,iDoEmptyBufferDoneLimit); + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&iOmxParamPortInput); + } + } + + if(iTestIteration < KMaxTestIterations && !iTestTimedOut) + { + iWaitForResources = EFalse; + AllocateBufferTask(); + } + else + { + CActiveScheduler::Stop(); // End the test + } + } + +void CGraphicsSinkTestBase::IdleStateBufferTask() + { + GetState(iGraphicSinkCompHandle,&iState,OMX_StateIdle); + if(iGphxPrevState == OMX_StateLoaded) + { + iGphxPrevState = iState; + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateExecuting,0); + } + else if(iGphxPrevState == OMX_StateExecuting) + { + iGphxPrevState = iState; + FreeBufferTaskAlt(iInputBufferHeaders,0); + iInputBufferHeaders.Reset(); + } + } + +void CGraphicsSinkTestBase::ExecutingStateBufferTask() + { + GetState(iGraphicSinkCompHandle,&iState,OMX_StateExecuting); + iGphxPrevState = iState; + + EmptyThisBufferTask(); + if (iTestStep == 5) + { + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateIdle,0); + } + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/src/graphicsinktestbase.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/src/graphicsinktestbase.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,171 @@ +/* +* Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** + * @file + * @internalTechnology + */ + +#ifndef GRAPHICSINKTESTBASE_H +#define GRAPHICSINKTESTBASE_H + +#include +#include +#include +#include + +#include "omxilgraphicsinktestbase.h" + +const TInt KTSU_OMX_GS_PAUSE = 2000000;// 2 second timer for test shutdown + +class CGraphicsSinkTestBase : public COmxGsTestBase + { +public: + CGraphicsSinkTestBase(); + ~CGraphicsSinkTestBase(); + +public: + void CloseTestStep(); + // Functions to act on callbackhandler functions + void DoFillBufferDone(OMX_HANDLETYPE aComponent, + OMX_BUFFERHEADERTYPE* aBufferHeader); + + void DoEmptyBufferDone(OMX_HANDLETYPE aComponent, + OMX_BUFFERHEADERTYPE* aBufferHeader); + + void DoEventHandler(OMX_HANDLETYPE aComponent,OMX_EVENTTYPE aEvent, + TUint aData1,TUint aData2,TAny* aExtra); + // End of callbackhandler functions + + void InitiateNextStateTransition(OMX_HANDLETYPE aComponent, TUint aData1, + TUint aData2, TAny* aExtra); + + void UpdateSettingChanged(OMX_HANDLETYPE aComponent, TUint aData1, + TUint aData2, TAny* aExtra); + + +protected: + + void ErrorEventTask_001( + OMX_ERRORTYPE aOmxError); + + TVerdict DoGSCompAllocTestL(); + + void LoadedStateTask_002(); + void IdleStateTask_002(); + + void LoadedStateTask_003(); + void IdleStateTask_003(); + + void LoadedStateTask_004(); + void IdleStateTask_004(); + void ExecutingStateTask_004(); + + void LoadedStateTask_005(); + void IdleStateTask_005(); + void ExecutingStateTask_005(); + + void LoadedStateTask_006(); + void IdleStateTask_006(); + + void LoadedStateTask_007(); + void IdleStateTask_007(); + void PauseStateTask_007(); + void ExecutingStateTask_007(); + + void StartStateTransitionTask(); + void WaitForResourcesTransitionTask(); + void LoadedStateTransitionTask(); + void IdleStateTransitionTask(); + void ExecutingStateTransitionTask(); + + void StartBufferDoneTask(); + void LoadedStateBufferTask(); + void IdleStateBufferTask(); + void ExecutingStateBufferTask(); + + void DoROmxGsTestSetup(); + void AllocateCCameraBuf(); + void DeleteCCameraBuf(); + void AllocateBufferTask(); + void AllocateBufferTaskStress(); + void UseBufferTask(); + void FreeBufferTask(RPointerArray* aBufferHeaders, + OMX_U32 aPortIndex,TBool aSendCommand = ETrue); + void FreeBufferTaskAlt(RPointerArray aBufferHeaders, + OMX_U32 aPortIndex,TBool aSendCommand = ETrue); + void EmptyThisBufferTask(); + void FillCCamBuffer( + const RChunk& aCamBuf, + OMX_U32 aFrameWidth, + OMX_U32 aFrameHeight, + TInt aBytePerPixel, + TInt aNumOfActualBuffer); + void CreateOmxParamPortDefinitionType(OMX_PARAM_PORTDEFINITIONTYPE* aOmxParamPortType); + void CreateOmxVideoParamPortFormatType(OMX_VIDEO_PARAM_PORTFORMATTYPE* aOmxVideoParamPortType); + + TInt PostKickOffTestL(TInt aTimerId); + // General functions used to test the outcome of Get and Set tests. + void CompareVCTParam(OMX_VIDEO_CODINGTYPE aInputParamType, OMX_VIDEO_CODINGTYPE aOutputParamType, OMX_INDEXTYPE aIndexType); + void CompareU32Param(OMX_U32 aInputParamType, OMX_U32 aOutputParamType); + void CompareCFTParam(OMX_COLOR_FORMATTYPE aInputParamType, OMX_COLOR_FORMATTYPE aOutputParamType, OMX_INDEXTYPE aIndexType); + void CompareBoolParam(OMX_BOOL aInputParamType, OMX_BOOL aOutputParamType, OMX_INDEXTYPE aIndexType); + + void WaitForEvent(OMX_EVENTTYPE aEvent); + +protected: + //COmxILMMBuffer* iCamBuf; + RChunk iChunk; // to replace with COmxILMMBuffer + COmxILMMBuffer* iCamOutputBuffer; + + OMX_BUFFERHEADERTYPE* iInputBufferHeader; + OMX_BUFFERHEADERTYPE* iOutputBufferHeader; + RPointerArray iInputBufferHeaders; + RPointerArray iOutputBufferHeaders; + + OMX_PARAM_PORTDEFINITIONTYPE iOmxParamPortInput; + + OMX_STATETYPE iOmxStateType; + OMX_ERRORTYPE iOmxErrorType; + + TUint iPreviousState; + TInt iDoEmptyBufferDoneCount; + TInt iDoEmptyBufferDoneLimit; + TInt iColSwitch; + TInt iExecuteToIdleCount; + TInt iIdleToLoadedCount; + TInt iPauseStateCount; + TInt iIdleToExecuteCount; + TBool iExecutingToIdle; + + TSurfaceConfiguration* iSurfaceConfig; + + TInt iTestIteration; + volatile TBool iTestTimedOut; + volatile TBool iWaitForResources; + TInt iInputBufferHeadersCount; + + OMX_EVENTTYPE iEventToWaitFor; + + TInt iTestCase; + TInt iTestStep; + + TBool iIgnoreNextBufferDone; + }; + +#endif //GRAPHICSINKTESTBASE_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/src/graphicsinkteststeps.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/src/graphicsinkteststeps.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,2187 @@ +/* +* Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** + * @file + * @internalTechnology + */ + +#include "graphicsinkteststeps.h" +#include +#include + +COmxGsTest0001Step01::~COmxGsTest0001Step01() +/** + * Destructor + */ + { + } + +COmxGsTest0001Step01::COmxGsTest0001Step01() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0001Step01); + } + +TVerdict COmxGsTest0001Step01::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + + // Check GetComponentVersion + const TInt maxComponentNameSize = 128; + + char componentNameArray[maxComponentNameSize]; + OMX_VERSIONTYPE componentVersion; + OMX_VERSIONTYPE specVersion; + OMX_UUIDTYPE componentUUID; + + // Obtain the component's version + iOmxErrorType = iGraphicSinkCompHandle->GetComponentVersion(iGraphicSinkCompHandle, + componentNameArray,&componentVersion,&specVersion,&componentUUID); + if (iOmxErrorType != OMX_ErrorNone) + { + SetTestStepError(KErrGeneral); + SetTestStepResult(EFail); + return TestStepResult(); + } + + // Translate component name + TBuf8 componentNameBuf8; + componentNameBuf8 = const_cast(reinterpret_cast(componentNameArray)); + TBuf componentNameBuf16; + // INFO_PRINTF2(_L("Component Name length: %d"), componentNameBuf8.Length()); + componentNameBuf16.Copy(componentNameBuf8); + componentNameBuf16.PtrZ(); + const TBuf componentNameConst = _L("OMX.SYMBIAN.VIDEO.GRAPHICSINK"); + + INFO_PRINTF2(_L("Component Name: %S"), &componentNameBuf16); + INFO_PRINTF2(_L("Component Version Major: %d"), componentVersion.s.nVersionMajor); + INFO_PRINTF2(_L("Component Version Minor: %d"), componentVersion.s.nVersionMinor); + INFO_PRINTF2(_L("Component Version Revision: %d"), componentVersion.s.nRevision); + INFO_PRINTF2(_L("Component Version Step: %d"), componentVersion.s.nStep); + INFO_PRINTF2(_L("OMX Version Major: %d"), specVersion.s.nVersionMajor); + INFO_PRINTF2(_L("OMX Version Minor: %d"), specVersion.s.nVersionMinor); + INFO_PRINTF2(_L("OMX Version Revision: %d"), specVersion.s.nRevision); + INFO_PRINTF2(_L("OMX Version Step: %d"), specVersion.s.nStep); + INFO_PRINTF2(_L("Component UUID: %X"), componentUUID); + + // Quick check to confirm component name + if (componentNameConst != componentNameBuf16) + { + ERR_PRINTF1(_L("Incorrect component name retuned")); + SetTestStepError(KErrGeneral); + SetTestStepResult(EFail); + return TestStepResult(); + } + + // Simple GetParam test to display data change when using GetParam + OMX_PARAM_PORTDEFINITIONTYPE omxParamPortDefType; + // Confirm error when required paramaters not set + omxParamPortDefType.nPortIndex = 5; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortDefType,OMX_ErrorBadPortIndex); + + // Set required paramaters and test GetParameter + omxParamPortDefType.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + omxParamPortDefType.nVersion = TOmxILSpecVersion(); + omxParamPortDefType.nPortIndex = 0; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortDefType); + + INFO_PRINTF2(_L("PORTDEFINITIONTYPE nBufferCountActual: %X"), omxParamPortDefType.nBufferCountActual); + INFO_PRINTF2(_L("PORTDEFINITIONTYPE nBufferCountMin: %X"), omxParamPortDefType.nBufferCountMin); + INFO_PRINTF2(_L("PORTDEFINITIONTYPE nBufferSize: %X"), omxParamPortDefType.nBufferSize); + INFO_PRINTF2(_L("PORTDEFINITIONTYPE eCompressionFormat: %X"), omxParamPortDefType.format.video.eCompressionFormat); + INFO_PRINTF2(_L("PORTDEFINITIONTYPE eColorFormat: %X"), omxParamPortDefType.format.video.eColorFormat); + INFO_PRINTF2(_L("PORTDEFINITIONTYPE xFramerate: %X"), omxParamPortDefType.format.video.xFramerate); + + omxParamPortDefType.format.video.eCompressionFormat = OMX_VIDEO_CodingAutoDetect; + omxParamPortDefType.format.video.eColorFormat = OMX_COLOR_FormatCbYCrY; + + // Attempt to set bad paramaters + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortDefType, OMX_ErrorUnsupportedSetting); + + // Obtain the new port def params for OMX_VIDEO_PARAM_PORTFORMATTYPE + OMX_VIDEO_PARAM_PORTFORMATTYPE omxVideoParamPortForType; + + omxVideoParamPortForType.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE); + omxVideoParamPortForType.nVersion = TOmxILSpecVersion(); + omxVideoParamPortForType.nPortIndex = 0; + omxVideoParamPortForType.nIndex = 0; + omxVideoParamPortForType.eCompressionFormat = OMX_VIDEO_CodingUnused; + omxVideoParamPortForType.eColorFormat = OMX_COLOR_FormatCrYCbY; + omxVideoParamPortForType.xFramerate = 0; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamPortForType); + + INFO_PRINTF2(_L("PORTFORMATTYPE nIndex: %X"), omxVideoParamPortForType.nIndex); + INFO_PRINTF2(_L("PORTFORMATTYPE nPortIndex: %X"), omxVideoParamPortForType.nPortIndex); + INFO_PRINTF2(_L("PORTFORMATTYPE nSize: %X"), omxVideoParamPortForType.nSize); + INFO_PRINTF2(_L("PORTFORMATTYPE nVersion: %X"), omxVideoParamPortForType.nVersion); + INFO_PRINTF2(_L("PORTFORMATTYPE eCompressionFormat: %X"), omxVideoParamPortForType.eCompressionFormat); + INFO_PRINTF2(_L("PORTFORMATTYPE eColorFormat: %X"), omxVideoParamPortForType.eColorFormat); + INFO_PRINTF2(_L("PORTFORMATTYPE xFramerate: %X"), omxVideoParamPortForType.xFramerate); + + omxParamPortDefType.format.video.eCompressionFormat = OMX_VIDEO_CodingAutoDetect; + omxParamPortDefType.format.video.eColorFormat = OMX_COLOR_FormatCbYCrY; + + // Attempt to set bad paramaters + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamPortForType,OMX_ErrorUnsupportedSetting); + + // Obtain the new port def params for OMX_VIDEO_PARAM_PORTFORMATTYPE + OMX_VIDEO_PARAM_PORTFORMATTYPE omxVideoParamPortForType2; + + omxVideoParamPortForType2.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE); + omxVideoParamPortForType2.nVersion = TOmxILSpecVersion(); + omxVideoParamPortForType2.nPortIndex = 0; + omxVideoParamPortForType2.nIndex = 1; + omxVideoParamPortForType2.eCompressionFormat = OMX_VIDEO_CodingUnused; + omxVideoParamPortForType2.eColorFormat = OMX_COLOR_FormatCrYCbY; + omxVideoParamPortForType2.xFramerate = 0; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamPortForType2); + + INFO_PRINTF2(_L("PORTFORMATTYPE nIndex: %X"), omxVideoParamPortForType2.nIndex); + INFO_PRINTF2(_L("PORTFORMATTYPE nPortIndex: %X"), omxVideoParamPortForType2.nPortIndex); + INFO_PRINTF2(_L("PORTFORMATTYPE nSize: %X"), omxVideoParamPortForType2.nSize); + INFO_PRINTF2(_L("PORTFORMATTYPE nVersion: %X"), omxVideoParamPortForType2.nVersion); + INFO_PRINTF2(_L("PORTFORMATTYPE eCompressionFormat: %X"), omxVideoParamPortForType2.eCompressionFormat); + INFO_PRINTF2(_L("PORTFORMATTYPE eColorFormat: %X"), omxVideoParamPortForType2.eColorFormat); + INFO_PRINTF2(_L("PORTFORMATTYPE xFramerate: %X"), omxVideoParamPortForType2.xFramerate); + + omxVideoParamPortForType2.eCompressionFormat = OMX_VIDEO_CodingUnused; + omxVideoParamPortForType2.eColorFormat = OMX_COLOR_Format12bitRGB444; + + // Attempt to set bad paramaters + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamPortForType2,OMX_ErrorUnsupportedSetting); + + OMX_INDEXTYPE videosurfaceconfigindex = OMX_IndexMax; + const char tempconfig [] = "OMX.BRIAN.INDEX.PARAM.VIDEO.GFX.SURFACECONFIG"; + iError = iGraphicSinkCompHandle->GetExtensionIndex(iGraphicSinkCompHandle, const_cast(tempconfig), &videosurfaceconfigindex); + if(OMX_ErrorUnsupportedIndex != iError) + { + INFO_PRINTF1(_L("OMX_GetExtensionIndex Failed")); + SetTestStepError(PrintOmxError(iError)); + SetTestStepResult(EFail); + return TestStepResult(); + } + + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateExecuting,0,OMX_ErrorNone); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0001Step00::~COmxGsTest0001Step00() +/** + * Destructor + */ + { + } + +COmxGsTest0001Step00::COmxGsTest0001Step00() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0001Step00); + } + +TVerdict COmxGsTest0001Step00::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + TInt err; + TVerdict result = EFail; + + TRAP(err, result = DoGSCompAllocTestL()); + + if ((err != KErrNoMemory )) + { + INFO_PRINTF1(_L("Alloc testing completed successfully")); + result = EPass; + } + + SetTestStepError(err); + SetTestStepResult(result); + return TestStepResult(); + } + +COmxGsTest0001Step02::~COmxGsTest0001Step02() +/** + * Destructor + */ + { + } + +COmxGsTest0001Step02::COmxGsTest0001Step02() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0001Step02); + } + + +TVerdict COmxGsTest0001Step02::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + + // Set Framerate and confirm OMX error + // Declare the structs for Parameter tests + OMX_PARAM_PORTDEFINITIONTYPE omxParamPortInput; + OMX_PARAM_PORTDEFINITIONTYPE omxParamPortOutput; + OMX_VIDEO_PARAM_PORTFORMATTYPE omxVideoParamInput; + OMX_VIDEO_PARAM_PORTFORMATTYPE omxVideoParamOutput; + // framerate is always 0 for gfx component. + const OMX_U32 setParam = 0; + + /* + * Set the Framerate with the OMX_PARAM_PORTDEFINITIONTYPE struct + * Then compares it against other structs to ensure Framerate is updated + */ + omxParamPortInput.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + omxParamPortInput.nVersion = TOmxILSpecVersion(); + omxParamPortInput.nPortIndex = 0; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortInput,OMX_ErrorNone); + + // initial settings + omxParamPortInput.format.video.nFrameWidth = 320; + omxParamPortInput.format.video.nFrameHeight = 240; + omxParamPortInput.format.video.nStride = 320*2; + omxParamPortInput.format.video.eColorFormat = OMX_COLOR_FormatCbYCrY; + omxParamPortInput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + + // for test + omxParamPortInput.format.video.xFramerate = 35; + + // Test Framerate in the OMX_PARAM_PORTDEFINITIONTYPE struct + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortInput); + + omxParamPortOutput.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + omxParamPortOutput.nVersion = TOmxILSpecVersion(); + omxParamPortOutput.nPortIndex = 0; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortOutput,OMX_ErrorNone); + CompareU32Param(setParam, omxParamPortOutput.format.video.xFramerate); + + // Test Framerate in the OMX_VIDEO_PARAM_PORTFORMATTYPE struct + omxVideoParamOutput.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE); + omxVideoParamOutput.nVersion = TOmxILSpecVersion(); + omxVideoParamOutput.nPortIndex = 0; + omxVideoParamOutput.nIndex = 0; + omxVideoParamOutput.eCompressionFormat = OMX_VIDEO_CodingUnused; + omxVideoParamOutput.eColorFormat = OMX_COLOR_FormatCrYCbY; + omxVideoParamOutput.xFramerate = 0; + // by using getparameter with OMX_VIDEO_PARAM_PORTFORMATTYPE, test client specifies all fields including framerate. + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamOutput,OMX_ErrorNone); + CompareU32Param(setParam, omxVideoParamOutput.xFramerate); + omxVideoParamOutput.xFramerate = 45; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamOutput,OMX_ErrorUnsupportedSetting); + omxVideoParamOutput.xFramerate = 0; + + /* + * Set the Framerate with the OMX_VIDEO_PARAM_PORTFORMATTYPE struct + * Then compares it against other structs to ensure Framerate is updated + */ + omxVideoParamInput.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE); + omxVideoParamInput.nVersion = TOmxILSpecVersion(); + omxVideoParamInput.nPortIndex = 0; + omxVideoParamInput.nIndex = 0; + omxVideoParamInput.eCompressionFormat = OMX_VIDEO_CodingUnused; + omxVideoParamInput.eColorFormat = OMX_COLOR_FormatCrYCbY; + omxVideoParamInput.xFramerate = 0; + // by using getparameter with OMX_VIDEO_PARAM_PORTFORMATTYPE, test client specifies all fields including framerate. + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamInput,OMX_ErrorNone); + omxVideoParamInput.xFramerate = 45; + // Test Framerate in the OMX_VIDEO_PARAM_PORTFORMATTYPE struct + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamInput,OMX_ErrorUnsupportedSetting); + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamOutput,OMX_ErrorNone); + CompareU32Param(setParam, omxVideoParamOutput.xFramerate); + + // Test Framerate in the OMX_PARAM_PORTDEFINITIONTYPE struct + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortOutput,OMX_ErrorNone); + CompareU32Param(setParam, omxParamPortOutput.format.video.xFramerate); + + // Negative SetParamater test with OMX_SymbianIndexParamVideoGFXSurfaceConfig + iError = OMX_SetParameter(iGraphicSinkCompHandle, iSurfaceConfigExt,&omxVideoParamInput); + // TBD is OMX_ErrorUnsupportedIndex really the correct error code? + if (OMX_ErrorUnsupportedIndex != iError) + { + SetTestStepError(PrintOmxError(iError)); + SetTestStepResult(EFail); + return TestStepResult(); + } + + SetTestStepResult(EPass); + return TestStepResult(); + } + +COmxGsTest0001Step03::~COmxGsTest0001Step03() +/** + * Destructor + */ + { + } + +COmxGsTest0001Step03::COmxGsTest0001Step03() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0001Step03); + } + +TVerdict COmxGsTest0001Step03::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + + // Set Framesize and confirm + // Declare the structs for Parameter tests + OMX_PARAM_PORTDEFINITIONTYPE omxParamPortInput; + OMX_PARAM_PORTDEFINITIONTYPE omxParamPortOutput; + OMX_U32 setParamHeight; + OMX_U32 setParamWidth; + + for (TInt i = 1; i <= 50; i++) + { + /* + * Set the Framsize with the OMX_PARAM_PORTDEFINITIONTYPE struct + * Then compares it against other structs to ensure Framerate is updated + */ + omxParamPortInput.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + omxParamPortInput.nVersion = TOmxILSpecVersion(); + omxParamPortInput.nPortIndex = 0; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortInput,OMX_ErrorNone); + + omxParamPortInput.format.video.nFrameHeight = 10 * i; + omxParamPortInput.format.video.nFrameWidth = 10 * i; + + omxParamPortInput.format.video.eColorFormat = OMX_COLOR_FormatCbYCrY; + TInt bytesPerPixel = COmxILMMBuffer::BytesPerPixel(omxParamPortInput.format.video.eColorFormat); + TInt stride = bytesPerPixel * omxParamPortInput.format.video.nFrameWidth; + omxParamPortInput.format.video.nStride = stride; + + setParamHeight = omxParamPortInput.format.video.nFrameHeight; + setParamWidth = omxParamPortInput.format.video.nFrameWidth; + // Test Framsize in the OMX_PARAM_PORTDEFINITIONTYPE struct + + // INFO_PRINTF4(_L("i: %d, width: %d, height: %d"),i, omxParamPortInput.format.video.nFrameWidth, omxParamPortInput.format.video.nFrameHeight); + + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortInput,OMX_ErrorNone); + + omxParamPortOutput.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + omxParamPortOutput.nVersion = TOmxILSpecVersion(); + omxParamPortOutput.nPortIndex = 0; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortOutput,OMX_ErrorNone); + CompareU32Param(setParamHeight, omxParamPortInput.format.video.nFrameHeight); + CompareU32Param(setParamWidth, omxParamPortInput.format.video.nFrameWidth); + CompareU32Param(setParamHeight, omxParamPortOutput.format.video.nFrameHeight); + CompareU32Param(setParamWidth, omxParamPortOutput.format.video.nFrameWidth); + } + + SetTestStepResult(EPass); + + return TestStepResult(); + } + +COmxGsTest0001Step04::~COmxGsTest0001Step04() +/** + * Destructor + */ + { + } + +COmxGsTest0001Step04::COmxGsTest0001Step04() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0001Step04); + } + +TVerdict COmxGsTest0001Step04::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + + // Set FrameFormat and confirm + // Declare the structs for Parameter tests + OMX_PARAM_PORTDEFINITIONTYPE omxParamPortInput; + OMX_PARAM_PORTDEFINITIONTYPE omxParamPortOutput; + OMX_VIDEO_PARAM_PORTFORMATTYPE omxVideoParamInput; + OMX_VIDEO_PARAM_PORTFORMATTYPE omxVideoParamOutput; + OMX_COLOR_FORMATTYPE setColorFormat; + + /* + * Set the Frameformat with the OMX_PARAM_PORTDEFINITIONTYPE struct + * Then compares it against other structs to ensure Framerate is updated + */ + omxParamPortInput.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + omxParamPortInput.nVersion = TOmxILSpecVersion(); + omxParamPortInput.nPortIndex = 0; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortInput,OMX_ErrorNone); + + + // initial settings + omxParamPortInput.format.video.nFrameWidth = 320; + omxParamPortInput.format.video.nFrameHeight = 240; + omxParamPortInput.format.video.nStride = 320*2; + omxParamPortInput.format.video.eColorFormat = OMX_COLOR_FormatCbYCrY; + omxParamPortInput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + + // Store default value should be OMX_COLOR_FormatCbYCrY + setColorFormat = omxParamPortInput.format.video.eColorFormat; + // Test Framerate in the OMX_PARAM_PORTDEFINITIONTYPE struct + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortInput,OMX_ErrorNone); + + omxParamPortOutput.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + omxParamPortOutput.nVersion = TOmxILSpecVersion(); + omxParamPortOutput.nPortIndex = 0; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortOutput,OMX_ErrorNone); + CompareCFTParam(setColorFormat, omxParamPortInput.format.video.eColorFormat,OMX_IndexParamPortDefinition); + CompareCFTParam(setColorFormat, omxParamPortOutput.format.video.eColorFormat,OMX_IndexParamPortDefinition); + + // Test Framerate in the OMX_VIDEO_PARAM_PORTFORMATTYPE struct + omxVideoParamOutput.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE); + omxVideoParamOutput.nVersion = TOmxILSpecVersion(); + omxVideoParamOutput.nPortIndex = 0; + omxVideoParamOutput.nIndex = 0; + // The following 2 values should be over written by the correct ones for this index + omxVideoParamOutput.eCompressionFormat = OMX_VIDEO_CodingUnused; + omxVideoParamOutput.eColorFormat = OMX_COLOR_FormatCrYCbY; + omxVideoParamOutput.xFramerate = 0; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamOutput,OMX_ErrorNone); + CompareCFTParam(setColorFormat, omxVideoParamOutput.eColorFormat,OMX_IndexParamVideoPortFormat); + + // Negative GetParameter test for OMX_VIDEO_PARAM_PORTFORMATTYPE + omxVideoParamOutput.nIndex = 10; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamOutput,OMX_ErrorNoMore); + omxVideoParamOutput.nIndex = 0; + + // Because we only have one valid color format, set color format to unused before next test + omxParamPortInput.format.video.eColorFormat = OMX_COLOR_FormatUnused; + + //should expect OMX_ErrorUnsupportedSetting when to try changing unsupported pixelformats. + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortInput,OMX_ErrorUnsupportedSetting); + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortOutput,OMX_ErrorNone); + CompareCFTParam(setColorFormat, omxParamPortOutput.format.video.eColorFormat,OMX_IndexParamPortDefinition); + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamOutput,OMX_ErrorNone); + CompareCFTParam(setColorFormat, omxVideoParamOutput.eColorFormat,OMX_IndexParamVideoPortFormat); + + /* + * Set the Frameformat with the OMX_VIDEO_PARAM_PORTFORMATTYPE struct + * Then compares it against other structs to ensure Framerate is updated + */ + // by using getparameter with OMX_VIDEO_PARAM_PORTFORMATTYPE, test client specifies all fields including framerate. + omxVideoParamInput.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE); + omxVideoParamInput.nVersion = TOmxILSpecVersion(); + omxVideoParamInput.nPortIndex = 0; + omxVideoParamInput.nIndex = 0; + // The following 2 values should be over written by the correct ones for this index + omxVideoParamInput.eCompressionFormat = OMX_VIDEO_CodingUnused; + omxVideoParamInput.eColorFormat = OMX_COLOR_FormatCrYCbY; + omxVideoParamInput.xFramerate = 0; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamInput,OMX_ErrorNone); + setColorFormat = omxVideoParamInput.eColorFormat; + + // Test Framerate in the OMX_VIDEO_PARAM_PORTFORMATTYPE struct + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamInput,OMX_ErrorNone); + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamOutput,OMX_ErrorNone); + CompareCFTParam(setColorFormat, omxVideoParamInput.eColorFormat,OMX_IndexParamVideoPortFormat); + CompareCFTParam(setColorFormat, omxVideoParamOutput.eColorFormat,OMX_IndexParamVideoPortFormat); + + // Test Framerate in the OMX_PARAM_PORTDEFINITIONTYPE struct + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortOutput,OMX_ErrorNone); + CompareCFTParam(setColorFormat, omxParamPortOutput.format.video.eColorFormat,OMX_IndexParamPortDefinition); + // Because we only have one valid color format, set color format to unused before next test + omxVideoParamInput.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + omxVideoParamInput.eColorFormat = OMX_COLOR_FormatUnused; + // Should expect OMX_ErrorUnsupportedSetting when to try changing unsupported pixelformats. + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamInput,OMX_ErrorUnsupportedSetting); + // The failed set paramater should not change the colour value in the component + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamOutput,OMX_ErrorNone); + CompareCFTParam(setColorFormat, omxVideoParamOutput.eColorFormat,OMX_IndexParamVideoPortFormat); + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortOutput,OMX_ErrorNone); + CompareCFTParam(setColorFormat, omxParamPortOutput.format.video.eColorFormat,OMX_IndexParamPortDefinition); + + SetTestStepResult(EPass); + return TestStepResult(); + } + +COmxGsTest0001Step05::~COmxGsTest0001Step05() +/** + * Destructor + */ + { + } + +COmxGsTest0001Step05::COmxGsTest0001Step05() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0001Step05); + } + +TVerdict COmxGsTest0001Step05::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + + // Declare the structs for Parameter tests + OMX_PARAM_PORTDEFINITIONTYPE omxParamPortInput; + OMX_PARAM_PORTDEFINITIONTYPE omxParamPortOutput; + OMX_U32 setParam; + + /* + * Set the Frameformat with the OMX_PARAM_PORTDEFINITIONTYPE struct + * Then compares it against other structs to ensure Framerate is updated + */ + omxParamPortInput.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + omxParamPortInput.nVersion = TOmxILSpecVersion(); + omxParamPortInput.nPortIndex = 0; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortInput,OMX_ErrorNone); + + omxParamPortOutput.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + omxParamPortOutput.nVersion = TOmxILSpecVersion(); + omxParamPortOutput.nPortIndex = 0; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortOutput,OMX_ErrorNone); + + // Confirm default values of buffer count + if (omxParamPortInput.nBufferCountMin <= 0) + { + ERR_PRINTF2(_L("Default buffer count minimun is not set correctly: %d"),omxParamPortInput.nBufferCountMin); + SetTestStepError(KErrGeneral); + SetTestStepResult(EFail); + return TestStepResult(); + } + + if (omxParamPortInput.nBufferCountActual == 0) + { + ERR_PRINTF1(_L("Default Buffer count min is set to 0")); + SetTestStepError(KErrGeneral); + SetTestStepResult(EFail); + return TestStepResult(); + } + + if (omxParamPortInput.nBufferCountActual < omxParamPortInput.nBufferCountMin) + { + ERR_PRINTF2(_L("Default buffer count minimun is not set correctly: %d"),omxParamPortInput.nBufferCountMin); + SetTestStepError(KErrGeneral); + SetTestStepResult(EFail); + return TestStepResult(); + } + + // Set nBufferCountActual to below nBufferCountMin + omxParamPortInput.nBufferCountActual = omxParamPortInput.nBufferCountMin - 1; + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortInput,OMX_ErrorBadParameter); + + for (TInt i = 0; i < 5; i++) + { + // INFO_PRINTF2(_L("COmxGsTest0001Step05::doTestStepL() Increase nBufferCountActual by %d"),i); + omxParamPortInput.nBufferCountActual = omxParamPortInput.nBufferCountMin + i; + setParam = omxParamPortInput.nBufferCountActual; + + // initial settings + omxParamPortInput.format.video.nFrameWidth = 320; + omxParamPortInput.format.video.nFrameHeight = 240; + omxParamPortInput.format.video.nStride = 320*2; + omxParamPortInput.format.video.eColorFormat = OMX_COLOR_FormatCbYCrY; + omxParamPortInput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortInput,OMX_ErrorNone); + + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortOutput,OMX_ErrorNone); + CompareU32Param(setParam, omxParamPortInput.nBufferCountActual); + CompareU32Param(setParam, omxParamPortOutput.nBufferCountActual); + } + + SetTestStepResult(EPass); + return TestStepResult(); + } + +COmxGsTest0001Step06::~COmxGsTest0001Step06() +/** + * Destructor + */ + { + } + +COmxGsTest0001Step06::COmxGsTest0001Step06() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0001Step06); + } + +TVerdict COmxGsTest0001Step06::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + + // Declare the structs for Parameter tests + OMX_PARAM_PORTDEFINITIONTYPE omxParamPortInput; + OMX_PARAM_PORTDEFINITIONTYPE omxParamPortOutput; + + /* + * OMX_PARAM_PORTDEFINITIONTYPE::nBufferAlignment + */ + omxParamPortInput.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + omxParamPortInput.nVersion = TOmxILSpecVersion(); + omxParamPortInput.nPortIndex = 0; + omxParamPortOutput.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + omxParamPortOutput.nVersion = TOmxILSpecVersion(); + omxParamPortOutput.nPortIndex = 0; + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortInput,OMX_ErrorNone); + + // Set values using OMX_PARAM_PORTDEFINITIONTYPE and confirm stride + // stride shouldn't be equal to zero. so i=1 . + for (TInt i = 1; i < 50; i++) + { + // initial settings + omxParamPortInput.format.video.nFrameHeight = 240; + omxParamPortInput.format.video.eColorFormat = OMX_COLOR_FormatCbYCrY; + omxParamPortInput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + + // test starts + omxParamPortInput.format.video.nFrameWidth = 10 * i; + TInt bytesPerPixel = COmxILMMBuffer::BytesPerPixel(omxParamPortInput.format.video.eColorFormat); + TInt stride = bytesPerPixel * omxParamPortInput.format.video.nFrameWidth; + // The code needs to calculate the stride + omxParamPortInput.format.video.nStride = stride; + + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortInput,OMX_ErrorNone); + + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortOutput,OMX_ErrorNone); + + if (omxParamPortOutput.format.video.nStride < stride) + { + ERR_PRINTF2(_L("Stride value was not correct: %d"), omxParamPortOutput.format.video.nStride); + SetTestStepError(KErrGeneral); + SetTestStepResult(EFail); + return TestStepResult(); + } + } + + SetTestStepResult(EPass); + return TestStepResult(); + } + +COmxGsTest0001Step07::~COmxGsTest0001Step07() +/** + * Destructor + */ + { + } + +COmxGsTest0001Step07::COmxGsTest0001Step07() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0001Step07); + } + +TVerdict COmxGsTest0001Step07::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + + // Declare the structs for Parameter tests + OMX_PARAM_PORTDEFINITIONTYPE omxParamPortTypeInput; + CreateOmxParamPortDefinitionType(&omxParamPortTypeInput); + OMX_PARAM_PORTDEFINITIONTYPE omxParamPortDefinition; + CreateOmxParamPortDefinitionType(&omxParamPortDefinition); + + // The following tests attempt to set the parameter of the graphics sink component. + // In each case we call set, which is expected to pass through + // the component and return OMX_ErrorNone. After Get is called we perform a chack that the + // structs is updated. + + // aren't they all read-only fields? + + /* + omxParamPortTypeInput.nBufferCountMin = omxParamPortTypeInput.nBufferCountMin - 1; + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortTypeInput); + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortTypeInput); + CompareU32Param(omxParamPortDefinition.nBufferCountMin, omxParamPortTypeInput.nBufferCountMin ); + + // nBufferSize is read-only value + omxParamPortTypeInput.nBufferSize = omxParamPortDefinition.nBufferSize + omxParamPortDefinition.nBufferSize; + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortTypeInput); + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortTypeInput); + CompareU32Param(omxParamPortDefinition.nBufferSize,omxParamPortTypeInput.nBufferSize); + + omxParamPortTypeInput.nBufferAlignment = 4; + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortTypeInput,OMX_ErrorNone); + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortTypeInput,OMX_ErrorNone); + CompareU32Param(omxParamPortDefinition.nBufferAlignment,omxParamPortTypeInput.nBufferAlignment); + + // nSliceHeight is read-only value + omxParamPortTypeInput.format.video.nSliceHeight = 20; + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortTypeInput,OMX_ErrorNone); + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortTypeInput,OMX_ErrorNone); + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortDefinition,OMX_ErrorNone); + CompareU32Param(omxParamPortDefinition.format.video.nSliceHeight,omxParamPortTypeInput.format.video.nSliceHeight); + + // bEnabled is read-only value + omxParamPortTypeInput.bEnabled = OMX_FALSE; + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortTypeInput); + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortTypeInput,OMX_ErrorNone); + CompareBoolParam(omxParamPortTypeInput.bEnabled, omxParamPortDefinition.bEnabled,OMX_IndexParamPortDefinition); + + // bPopulated is read-only value + omxParamPortTypeInput.bPopulated = OMX_TRUE; + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortTypeInput); + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortTypeInput,OMX_ErrorNone); + CompareBoolParam(omxParamPortTypeInput.bPopulated, omxParamPortDefinition.bPopulated,OMX_IndexParamPortDefinition); + + // bBuffersContiguous is read-only value + omxParamPortTypeInput.bBuffersContiguous = OMX_FALSE; + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortTypeInput,OMX_ErrorNone); + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortTypeInput,OMX_ErrorNone); + CompareBoolParam(omxParamPortTypeInput.bBuffersContiguous, omxParamPortDefinition.bBuffersContiguous,OMX_IndexParamPortDefinition); + + // eDomain is read-only value + omxParamPortTypeInput.eDomain = OMX_PortDomainOther; + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortTypeInput,OMX_ErrorNone); + GetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortTypeInput,OMX_ErrorNone); + CompareU32Param(omxParamPortTypeInput.eDomain, omxParamPortDefinition.eDomain); + */ + + SetTestStepResult(EPass); + return TestStepResult(); + } + +COmxGsTest0001Step08::~COmxGsTest0001Step08() +/** + * Destructor + */ + { + } + +COmxGsTest0001Step08::COmxGsTest0001Step08() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0001Step08); + } + +TVerdict COmxGsTest0001Step08::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + OMX_PARAM_PORTDEFINITIONTYPE omxParamPortInput; + OMX_VIDEO_PARAM_PORTFORMATTYPE omxVideoParamInput; + CreateOmxParamPortDefinitionType(&omxParamPortInput); + CreateOmxVideoParamPortFormatType(&omxVideoParamInput); + + OMX_COLOR_FORMATTYPE defaultColorFormat = omxParamPortInput.format.video.eColorFormat; + if (omxVideoParamInput.eColorFormat != omxParamPortInput.format.video.eColorFormat) + { + SetTestStepError(KErrGeneral); + return TestStepResult(); + } + + // Traverse the array of colour format to confirm support. + // The enumeration OMX_COLOR_FORMATTYPE starts at 1 and currently finishes at 43 + for (TInt i = 1; i < 44; i++) + { + //INFO_PRINTF2(_L("COmxGsTest0001Step08::doTestStepL(): Set OMX_COLOR_FORMATTYPE(%d)"),i); + omxParamPortInput.format.video.eColorFormat = OMX_COLOR_FORMATTYPE(i); + omxVideoParamInput.eColorFormat = OMX_COLOR_FORMATTYPE(i); + omxVideoParamInput.eCompressionFormat = OMX_VIDEO_CodingUnused; + + // initial settings + omxParamPortInput.format.video.nFrameWidth = 320; + omxParamPortInput.format.video.nFrameHeight = 240; + omxParamPortInput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + + + TInt check = OMX_COLOR_FORMATTYPE(i); + if(check == OMX_COLOR_Format16bitRGB565 || + check == OMX_COLOR_FormatYCrYCb || + check == OMX_COLOR_FormatCbYCrY || + check == OMX_COLOR_Format32bitARGB8888) + { + TInt bytesPerPixel = COmxILMMBuffer::BytesPerPixel(omxParamPortInput.format.video.eColorFormat); + TInt stride = bytesPerPixel * omxParamPortInput.format.video.nFrameWidth; + omxParamPortInput.format.video.nStride = stride; + + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortInput); + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamInput); + } + else + { + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortInput,OMX_ErrorUnsupportedSetting); + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamInput,OMX_ErrorUnsupportedSetting); + } + + omxParamPortInput.format.video.eColorFormat = defaultColorFormat; + omxVideoParamInput.eColorFormat = defaultColorFormat; + } + + // Set CompressionFormat and confirm + OMX_VIDEO_CODINGTYPE defaultCompressionFormat = omxParamPortInput.format.video.eCompressionFormat; + if (omxVideoParamInput.eCompressionFormat != omxParamPortInput.format.video.eCompressionFormat) + { + SetTestStepError(KErrGeneral); + return TestStepResult(); + } + + for (TInt i = 1; i < 9; i++) + { + //INFO_PRINTF2(_L("COmxGsTest0001Step08::doTestStepL(): Set OMX_VIDEO_CODINGTYPE(%d)"),i); + omxParamPortInput.format.video.eCompressionFormat = OMX_VIDEO_CODINGTYPE(i); + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortInput,OMX_ErrorUnsupportedSetting); + omxParamPortInput.format.video.eCompressionFormat = defaultCompressionFormat; + + omxVideoParamInput.eCompressionFormat = OMX_VIDEO_CODINGTYPE(i); + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamInput,OMX_ErrorUnsupportedSetting); + omxVideoParamInput.eCompressionFormat = defaultCompressionFormat; + } + + //INFO_PRINTF1(_L("COmxGsTest0001Step08::doTestStepL(): Set ColorFormat and CompressionFormat")); + for (TInt i = 0; i < 47; i++) + { + //INFO_PRINTF2(_L("COmxGsTest0001Step08::doTestStepL(): Set OMX_COLOR_FORMATTYPE(%d) using OMX_PARAM_PORTDEFINITIONTYPE"),i); + omxParamPortInput.format.video.eColorFormat = OMX_COLOR_FORMATTYPE(i); + for (TInt j = 0; j < 9; j++) + { + //INFO_PRINTF2(_L("COmxGsTest0001Step08::doTestStepL(): Set OMX_VIDEO_CODINGTYPE(%d) using OMX_PARAM_PORTDEFINITIONTYPE"),j); + omxParamPortInput.format.video.eCompressionFormat = OMX_VIDEO_CODINGTYPE(j); + + if ((i == OMX_COLOR_Format16bitRGB565 || i == OMX_COLOR_FormatYCrYCb || i == OMX_COLOR_FormatCbYCrY || i == OMX_COLOR_Format32bitARGB8888) && j == 0) + { + TInt bytesPerPixel = COmxILMMBuffer::BytesPerPixel(omxParamPortInput.format.video.eColorFormat); + TInt stride = bytesPerPixel * omxParamPortInput.format.video.nFrameWidth; + omxParamPortInput.format.video.nStride = stride; + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortInput); + } + else + { + if ((i == 0 && j != 0) || (i != 0 && j == 0)) // If OMX_COLOR_FORMATTYPE set to OMX_VIDEO_CodingUnused error is OMX_ErrorUnsupportedSetting + { + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortInput,OMX_ErrorUnsupportedSetting); + } + else + { + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortInput,OMX_ErrorUnsupportedSetting); + } + } + } + + INFO_PRINTF2(_L("COmxGsTest0001Step08::doTestStepL(): Set OMX_COLOR_FORMATTYPE(%d) using OMX_VIDEO_PARAM_PORTFORMATTYPE"),i); + omxVideoParamInput.eColorFormat = OMX_COLOR_FORMATTYPE(i); + for (TInt j = 0; j < 9; j++) + { + //INFO_PRINTF2(_L("COmxGsTest0001Step08::doTestStepL(): Set OMX_VIDEO_CODINGTYPE(%d) using OMX_VIDEO_PARAM_PORTFORMATTYPE"),j); + omxVideoParamInput.eCompressionFormat = OMX_VIDEO_CODINGTYPE(j); + // OMX_COLOR_Format16bitRGB565,OMX_COLOR_FormatYCrYCb, OMX_COLOR_FormatCbYCrY + if ((i == OMX_COLOR_Format16bitRGB565 || i == OMX_COLOR_FormatYCrYCb || i == OMX_COLOR_FormatCbYCrY || i == OMX_COLOR_Format32bitARGB8888) && j == 0) + { + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamInput); + } + else + { + if ((i == 0 && j != 0) || (i != 0 && j == 0)) // If OMX_COLOR_FORMATTYPE set to OMX_VIDEO_CodingUnused error is OMX_ErrorUnsupportedSetting + { + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamInput,OMX_ErrorUnsupportedSetting); + } + else + { + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamInput,OMX_ErrorUnsupportedSetting); + } + } + } + + // Set values back to default + omxParamPortInput.format.video.eColorFormat = OMX_COLOR_FormatCbYCrY; + omxVideoParamInput.eColorFormat = OMX_COLOR_FormatCbYCrY; + omxParamPortInput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + omxVideoParamInput.eCompressionFormat = OMX_VIDEO_CodingUnused; + } + + // Set color format and compression format to Unused + omxParamPortInput.format.video.eColorFormat = OMX_COLOR_FormatUnused; + omxVideoParamInput.eColorFormat = OMX_COLOR_FormatUnused; + omxParamPortInput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + omxVideoParamInput.eCompressionFormat = OMX_VIDEO_CodingUnused; + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamPortDefinition,&omxParamPortInput,OMX_ErrorUnsupportedSetting); + SetParameter(iGraphicSinkCompHandle,OMX_IndexParamVideoPortFormat,&omxVideoParamInput,OMX_ErrorUnsupportedSetting); + + SetTestStepResult(EPass); + return TestStepResult(); + } + +COmxGsTest0001Step09::~COmxGsTest0001Step09() +/** + * Destructor + */ + { + } + +COmxGsTest0001Step09::COmxGsTest0001Step09() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0001Step09); + } + +TVerdict COmxGsTest0001Step09::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + // COmxILMMBuffer::BytesPerPixel(OMX_COLOR_FORMATTYPE) + for (TInt i = 0; i < 47; i++) + { + TInt bytesPerPixel = 15; + bytesPerPixel = COmxILMMBuffer::BytesPerPixel(OMX_COLOR_FORMATTYPE(i)); + if (bytesPerPixel == 15) + { + SetTestStepError(KErrGeneral); + return TestStepResult(); + } + } + + // COmxILMMBuffer::BytesPerPixel(TUidPixelFormat) + for (TInt i = 0; i < 50; i++) + { + TInt bytesPerPixel = 15; + bytesPerPixel = COmxILMMBuffer::BytesPerPixel(TUidPixelFormat(i)); + if (bytesPerPixel == 15) + { + SetTestStepError(KErrGeneral); + return TestStepResult(); + } + } + + SetTestStepResult(EPass); + return TestStepResult(); + } + + +COmxGsTest0002Step01::~COmxGsTest0002Step01() +/** + * Destructor + */ + { + } + +COmxGsTest0002Step01::COmxGsTest0002Step01() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0002Step01); + } + +TVerdict COmxGsTest0002Step01::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + CGraphicsSinkTestBase::DoROmxGsTestSetup(); + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0002Step02::~COmxGsTest0002Step02() +/** + * Destructor + */ + { + } + +COmxGsTest0002Step02::COmxGsTest0002Step02() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0002Step02); + } + +TVerdict COmxGsTest0002Step02::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + CGraphicsSinkTestBase::DoROmxGsTestSetup(); + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0002Step03::~COmxGsTest0002Step03() +/** + * Destructor + */ + { + } + +COmxGsTest0002Step03::COmxGsTest0002Step03() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0002Step03); + } + +TVerdict COmxGsTest0002Step03::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + DoROmxGsTestSetup(); + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0002Step04::~COmxGsTest0002Step04() +/** + * Destructor + */ + { + } + +COmxGsTest0002Step04::COmxGsTest0002Step04() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0002Step04); + } + +TVerdict COmxGsTest0002Step04::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + DoROmxGsTestSetup(); + + // Needed by Allocate buffer + TInt bytesPerPixel = COmxILMMBuffer::BytesPerPixel(iOmxParamPortInput.format.video.eColorFormat); + TInt bufferSize = bytesPerPixel * iOmxParamPortInput.format.video.nFrameWidth * iOmxParamPortInput.format.video.nFrameHeight; + + AllocateBuffer(iGraphicSinkCompHandle,&iInputBufferHeader,0,NULL,bufferSize,&iInputBufferHeaders,1,OMX_ErrorIncorrectStateOperation); + iInputBufferHeaders.Reset(); + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + SetTestStepResult(EPass); + return TestStepResult(); + } + +COmxGsTest0003Step01::~COmxGsTest0003Step01() +/** + * Destructor + */ + { + } + +COmxGsTest0003Step01::COmxGsTest0003Step01() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0003Step01); + } + +TVerdict COmxGsTest0003Step01::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + DoROmxGsTestSetup(); + AllocateCCameraBuf(); + UseBufferTask(); + if( iError == OMX_ErrorNone ){ + StartTimer(); + } + return TestStepResult(); + } + +COmxGsTest0003Step02::~COmxGsTest0003Step02() +/** + * Destructor + */ + { + } + +COmxGsTest0003Step02::COmxGsTest0003Step02() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0003Step02); + } + +TVerdict COmxGsTest0003Step02::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + DoROmxGsTestSetup(); + AllocateCCameraBuf(); + UseBufferTask(); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0003Step03::~COmxGsTest0003Step03() +/** + * Destructor + */ + { + } + +COmxGsTest0003Step03::COmxGsTest0003Step03() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0003Step03); + } + +TVerdict COmxGsTest0003Step03::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + DoROmxGsTestSetup(); + AllocateCCameraBuf(); + UseBufferTask(); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0003Step04::~COmxGsTest0003Step04() +/** + * Destructor + */ + { + } + +COmxGsTest0003Step04::COmxGsTest0003Step04() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0003Step04); + } + + +TVerdict COmxGsTest0003Step04::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + DoROmxGsTestSetup(); + + TInt bytesperpixel = COmxILMMBuffer::BytesPerPixel(iOmxParamPortInput.format.video.eColorFormat); + // Not a true declaration, just used to test UseBuffer + iTestChunk.CreateLocal(1024,1024); + + + // Create local buffer then create iCamBuf from it. Used for coverage + COmxILMMBuffer* cameraBuffer = NULL; + TRAPD(err, cameraBuffer = COmxILMMBuffer::NewL(iTestChunk)); + if(err) + { + ERR_PRINTF1(_L("OOM ERROR")); + SetTestStepError(err); + return TestStepResult(); + } + + /* + TRAP(err, iCamBuf = COmxILMMBuffer::CreateL(*cameraBuffer)); + delete cameraBuffer; + if(err != KErrNone) + { + ERR_PRINTF1(_L("Failed to produce COmxILMMBuffer using COmxILMMBuffer::CreateL()")); + SetTestStepError(err); + return TestStepResult(); + } + */ + + + OMX_INDEXTYPE sharedChunkMetadataExtensionIndex; + // due to chunk extension support in gfx + if (OMX_ErrorNone == OMX_GetExtensionIndex( + iGraphicSinkCompHandle, + OMX_SYMBIAN_INDEX_CONFIG_SHAREDCHUNKMETADATA_NAME, + &sharedChunkMetadataExtensionIndex)) + { + // Communicate the shared chunk metadata to the tunnelled + // component + OMX_SYMBIAN_CONFIG_SHAREDCHUNKMETADATATYPE configSharedChunkMetadata; + configSharedChunkMetadata.nSize = sizeof(OMX_SYMBIAN_CONFIG_SHAREDCHUNKMETADATATYPE); + configSharedChunkMetadata.nVersion = TOmxILSpecVersion(); + configSharedChunkMetadata.nPortIndex = 0; + configSharedChunkMetadata.nHandleId = iTestChunk.Handle(); + configSharedChunkMetadata.nOwnerThreadId = RThread().Id().Id(); + + (void) OMX_SetConfig(iGraphicSinkCompHandle, + sharedChunkMetadataExtensionIndex, + &configSharedChunkMetadata); + } + else + { + ERR_PRINTF1(_L("Failed to set shared chunk meta-data config.")); + SetTestStepError(err); + return TestStepResult(); + } + + + iPreviousState = OMX_StateLoaded; + + // UseBuffer with illegal pointer to the memory buffer area to be used + iOmxErrorType = iGraphicSinkCompHandle->UseBuffer(iGraphicSinkCompHandle,&iOutputBufferHeader,0,cameraBuffer,cameraBuffer->Chunk().Size(),0); + if (OMX_ErrorBadParameter != iOmxErrorType) + { + ERR_PRINTF1(_L("UseBuffer un-expectantly did not return an error")); + SetTestStepError(PrintOmxError(iOmxErrorType)); + return TestStepResult(); + } + + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + // UseBuffer with illegal buffer size in bytes + iOmxErrorType = iGraphicSinkCompHandle->UseBuffer(iGraphicSinkCompHandle, + //&iOutputBufferHeader,0,iCamBuf,0,iCamBuf->Chunk().Base()); + &iOutputBufferHeader,0,NULL,0,iTestChunk.Base()); + if (OMX_ErrorBadParameter != iOmxErrorType) + { + ERR_PRINTF1(_L("UseBuffer un-expectantly did not return an error")); + SetTestStepError(PrintOmxError(iOmxErrorType)); + return TestStepResult(); + } + + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + // UseBuffer with illegal pointer to memory buffer and size + iOmxErrorType = iGraphicSinkCompHandle->UseBuffer(iGraphicSinkCompHandle, + //&iOutputBufferHeader,0,iCamBuf,0,0); + &iOutputBufferHeader,0,NULL,0,NULL); + if (OMX_ErrorBadParameter != iOmxErrorType) + { + ERR_PRINTF1(_L("UseBuffer un-expectantly did not return an error")); + SetTestStepError(PrintOmxError(iOmxErrorType)); + return TestStepResult(); + } + + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + // UseBuffer without calling SendCommand + iOmxErrorType = iGraphicSinkCompHandle->UseBuffer(iGraphicSinkCompHandle, + //&iOutputBufferHeader,0,iCamBuf,iCamBuf->Chunk().Size(),iCamBuf->Chunk().Base()); + &iOutputBufferHeader,0,NULL,iTestChunk.Size(),iTestChunk.Base()); + if (OMX_ErrorIncorrectStateOperation != iOmxErrorType) + { + ERR_PRINTF1(_L("UseBuffer un-expectantly did not return an error")); + SetTestStepError(PrintOmxError(iOmxErrorType)); + return TestStepResult(); + } + + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + // UseBuffer with correct parameters + SendCommand(iGraphicSinkCompHandle,OMX_CommandStateSet,OMX_StateIdle,0); +/* + // change made due to OMXILBufferClass + iCamBuf->OffsetInfoArray().Append(0); + + iOmxErrorType = iGraphicSinkCompHandle->UseBuffer(iGraphicSinkCompHandle,&iInputBufferHeader, + 0,iCamBuf,iCamBuf->Chunk().Size(),iCamBuf->Chunk().Base() + iCamBuf->OffsetInfoArray()[0]); + // Confirm UseBuffer returns OMX_ErrorBadParameter + if (OMX_ErrorBadParameter != iOmxErrorType) + { + ERR_PRINTF1(_L("UseBuffer returned incorrect error")); + SetTestStepError(PrintOmxError(iOmxErrorType)); + return TestStepResult(); + } + + // Confirm state unaltered + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); +*/ + + delete cameraBuffer; + + //iTestChunk.Close(); + SetTestStepResult(EPass); + return TestStepResult(); + } + +COmxGsTest0004Step01::~COmxGsTest0004Step01() +/** + * Destructor + */ + { + } + +COmxGsTest0004Step01::COmxGsTest0004Step01() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0004Step01); + } + +TVerdict COmxGsTest0004Step01::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + DoROmxGsTestSetup(); + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0004Step02::~COmxGsTest0004Step02() +/** + * Destructor + */ + { + } + +COmxGsTest0004Step02::COmxGsTest0004Step02() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0004Step02); + } + + +TVerdict COmxGsTest0004Step02::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + DoROmxGsTestSetup(); + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0004Step03::~COmxGsTest0004Step03() +/** + * Destructor + */ + { + } + +COmxGsTest0004Step03::COmxGsTest0004Step03() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0004Step03); + } + +TVerdict COmxGsTest0004Step03::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + DoROmxGsTestSetup(); + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0004Step04::~COmxGsTest0004Step04() +/** + * Destructor + */ + { + } + +COmxGsTest0004Step04::COmxGsTest0004Step04() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0004Step04); + } + +TVerdict COmxGsTest0004Step04::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + DoROmxGsTestSetup(); + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0004Step05::~COmxGsTest0004Step05() +/** + * Destructor + */ + { + } + +COmxGsTest0004Step05::COmxGsTest0004Step05() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0004Step05); + } + +TVerdict COmxGsTest0004Step05::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + DoROmxGsTestSetup(); + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + + +COmxGsTest0004Step06::~COmxGsTest0004Step06() +/** + * Destructor + */ + { + } + +COmxGsTest0004Step06::COmxGsTest0004Step06() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0004Step06); + } + +TVerdict COmxGsTest0004Step06::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + DoROmxGsTestSetup(); + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0005Step01::~COmxGsTest0005Step01() +/** + * Destructor + */ + { + } + +COmxGsTest0005Step01::COmxGsTest0005Step01() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0005Step01); + } + +TVerdict COmxGsTest0005Step01::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + DoROmxGsTestSetup(); + iDoEmptyBufferDoneLimit = 10; + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0005Step02::~COmxGsTest0005Step02() +/** + * Destructor + */ + { + } + +COmxGsTest0005Step02::COmxGsTest0005Step02() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0005Step02); + } + +TVerdict COmxGsTest0005Step02::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + DoROmxGsTestSetup(); + iDoEmptyBufferDoneLimit = 10; + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0005Step03::~COmxGsTest0005Step03() +/** + * Destructor + */ + { + } + +COmxGsTest0005Step03::COmxGsTest0005Step03() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0005Step03); + } + +TVerdict COmxGsTest0005Step03::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + DoROmxGsTestSetup(); + iDoEmptyBufferDoneLimit = 10; + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + + +COmxGsTest0005Step04::~COmxGsTest0005Step04() +/** + * Destructor + */ + { + } + +COmxGsTest0005Step04::COmxGsTest0005Step04() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0005Step04); + } + +TVerdict COmxGsTest0005Step04::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + DoROmxGsTestSetup(); + iDoEmptyBufferDoneLimit = 10; + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0005Step05::~COmxGsTest0005Step05() +/** + * Destructor + */ + { + } + +COmxGsTest0005Step05::COmxGsTest0005Step05() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0005Step05); + } + +TVerdict COmxGsTest0005Step05::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + DoROmxGsTestSetup(); + iDoEmptyBufferDoneLimit = 10; + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0006Step01::~COmxGsTest0006Step01() +/** + * Destructor + */ + { + } + +COmxGsTest0006Step01::COmxGsTest0006Step01() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0006Step01); + } + +TVerdict COmxGsTest0006Step01::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + DoROmxGsTestSetup(); + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0006Step02::~COmxGsTest0006Step02() +/** + * Destructor + */ + { + } + +COmxGsTest0006Step02::COmxGsTest0006Step02() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0006Step02); + } + +TVerdict COmxGsTest0006Step02::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + DoROmxGsTestSetup(); + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0007Step01::~COmxGsTest0007Step01() +/** + * Destructor + */ + { + } + +COmxGsTest0007Step01::COmxGsTest0007Step01() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0007Step01); + } + + +TVerdict COmxGsTest0007Step01::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + iDoEmptyBufferDoneLimit = 8; + iExecutingToIdle = EFalse; + + DoROmxGsTestSetup(); + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0007Step02::~COmxGsTest0007Step02() +/** + * Destructor + */ + { + } + +COmxGsTest0007Step02::COmxGsTest0007Step02() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0007Step02); + } + +TVerdict COmxGsTest0007Step02::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + iDoEmptyBufferDoneLimit = 8; + iExecutingToIdle = EFalse; + + DoROmxGsTestSetup(); + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + + +COmxGsTest0007Step03::~COmxGsTest0007Step03() +/** + * Destructor + */ + { + } + +COmxGsTest0007Step03::COmxGsTest0007Step03() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0007Step03); + } + +TVerdict COmxGsTest0007Step03::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + iDoEmptyBufferDoneLimit = 8; + iExecutingToIdle = EFalse; + + DoROmxGsTestSetup(); + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0007Step04::~COmxGsTest0007Step04() +/** + * Destructor + */ + { + } + +COmxGsTest0007Step04::COmxGsTest0007Step04() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0007Step04); + } + +TVerdict COmxGsTest0007Step04::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + GetState(iGraphicSinkCompHandle,&iOmxStateType,OMX_StateLoaded); + iDoEmptyBufferDoneLimit = 8; + iExecutingToIdle = EFalse; + + DoROmxGsTestSetup(); + AllocateBufferTask(); + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0008Step01::~COmxGsTest0008Step01() +/** + * Destructor + */ + { + } + +COmxGsTest0008Step01::COmxGsTest0008Step01() +/** + * Constructor + */ + { + SetTestStepName(KOmxGsTest0008Step01); + } + +TVerdict COmxGsTest0008Step01::doTestStepL() +/** + * @return - TVerdict code + * Override of base class pure virtual + * Our implementation only gets called if the base class doTestStepPreambleL() did + * not leave. That being the case, the current test result value will be EPass. + */ + { + // Use set and get config for all different relevant dynamic configurations including negative tests + OMX_FRAMESIZETYPE setFrameSize; + OMX_CONFIG_SCALEFACTORTYPE setScaleFactor; + OMX_CONFIG_RECTTYPE setRecType; + + OMX_FRAMESIZETYPE getFrameSize; + OMX_CONFIG_SCALEFACTORTYPE getScaleFactor; + OMX_CONFIG_RECTTYPE getRecType; + + + //Testing OMX_IndexConfigCommonScale + setScaleFactor.nSize = sizeof(OMX_CONFIG_SCALEFACTORTYPE); + setScaleFactor.nVersion = TOmxILSpecVersion(); + setScaleFactor.nPortIndex = 0; + GetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonScale,&setScaleFactor); + setScaleFactor.xWidth = 0x10000; + setScaleFactor.xHeight = 0x10000; + SetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonScale,&setScaleFactor); + getScaleFactor.nSize = sizeof(OMX_CONFIG_SCALEFACTORTYPE); + getScaleFactor.nVersion = TOmxILSpecVersion(); + getScaleFactor.nPortIndex = 0; + GetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonScale,&getScaleFactor); + if(setScaleFactor.xWidth != getScaleFactor.xWidth || setScaleFactor.xHeight != getScaleFactor.xHeight) + { + ERR_PRINTF1(_L("COmxGsTest0008Step01::doTestStepL(): OMX_IndexConfigCommonScale 1 error")); + SetTestStepError(KErrGeneral); + return TestStepResult(); + } + + //Code coverage negative testing + setScaleFactor.nPortIndex = 1; + GetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonScale,&setScaleFactor,OMX_ErrorBadPortIndex); + SetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonScale,&setScaleFactor,OMX_ErrorBadPortIndex); + + + //Testing OMX_IndexConfigCommonScale + setScaleFactor.nSize = sizeof(OMX_CONFIG_SCALEFACTORTYPE); + setScaleFactor.nVersion = TOmxILSpecVersion(); + setScaleFactor.nPortIndex = 0; + GetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonScale,&setScaleFactor); + setScaleFactor.xWidth = 0x20000; + setScaleFactor.xHeight = 0x20000; + SetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonScale,&setScaleFactor); + SetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonScale,&setScaleFactor); + getScaleFactor.nSize = sizeof(OMX_CONFIG_SCALEFACTORTYPE); + getScaleFactor.nVersion = TOmxILSpecVersion(); + getScaleFactor.nPortIndex = 0; + GetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonScale,&getScaleFactor); + if(setScaleFactor.xWidth != getScaleFactor.xWidth || setScaleFactor.xHeight != getScaleFactor.xHeight) + { + ERR_PRINTF1(_L("COmxGsTest0008Step01::doTestStepL(): OMX_IndexConfigCommonScale 2 error")); + SetTestStepError(KErrGeneral); + return TestStepResult(); + } + + //Testing OMX_IndexConfigCommonOutputSize + setFrameSize.nSize = sizeof(OMX_FRAMESIZETYPE); + setFrameSize.nVersion = TOmxILSpecVersion(); + setFrameSize.nPortIndex = 0; + GetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonOutputSize,&setFrameSize); + setFrameSize.nWidth = 320; + setFrameSize.nHeight = 240; + SetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonOutputSize,&setFrameSize); + getFrameSize.nSize = sizeof(OMX_FRAMESIZETYPE); + getFrameSize.nVersion = TOmxILSpecVersion(); + getFrameSize.nPortIndex = 0; + GetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonOutputSize,&getFrameSize); + if(setFrameSize.nWidth != getFrameSize.nWidth || setFrameSize.nHeight != getFrameSize.nHeight) + { + ERR_PRINTF1(_L("COmxGsTest0008Step01::doTestStepL(): OMX_IndexConfigCommonOutputSize 1 error")); + SetTestStepError(KErrGeneral); + return TestStepResult(); + } + + //Code coverage negative testing + setFrameSize.nPortIndex = 1; + GetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonOutputSize,&setFrameSize,OMX_ErrorBadPortIndex); + SetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonOutputSize,&setFrameSize,OMX_ErrorBadPortIndex); + + + //Testing OMX_IndexConfigCommonOutputSize + setFrameSize.nSize = sizeof(OMX_FRAMESIZETYPE); + setFrameSize.nVersion = TOmxILSpecVersion(); + setFrameSize.nPortIndex = 0; + GetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonOutputSize,&setFrameSize); + setFrameSize.nWidth = 160; + setFrameSize.nHeight = 120; + SetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonOutputSize,&setFrameSize); + getFrameSize.nSize = sizeof(OMX_FRAMESIZETYPE); + getFrameSize.nVersion = TOmxILSpecVersion(); + getFrameSize.nPortIndex = 0; + GetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonOutputSize,&getFrameSize); + if(setFrameSize.nWidth != getFrameSize.nWidth || setFrameSize.nHeight != getFrameSize.nHeight) + { + ERR_PRINTF1(_L("COmxGsTest0008Step01::doTestStepL(): OMX_IndexConfigCommonOutputSize 2 error")); + SetTestStepError(KErrGeneral); + return TestStepResult(); + } + + //Testing OMX_IndexConfigCommonInputCrop + setRecType.nSize = sizeof(OMX_CONFIG_RECTTYPE); + setRecType.nVersion = TOmxILSpecVersion(); + setRecType.nPortIndex = 0; + GetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonInputCrop,&setRecType); + setRecType.nLeft = 0x10000; + setRecType.nTop = 0x10000; + setRecType.nWidth = 320; + setRecType.nHeight = 240; + SetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonInputCrop,&setRecType); + getRecType.nSize = sizeof(OMX_CONFIG_RECTTYPE); + getRecType.nVersion = TOmxILSpecVersion(); + getRecType.nPortIndex = 0; + GetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonInputCrop,&getRecType); + if( setRecType.nLeft != getRecType.nLeft + || setRecType.nTop != getRecType.nTop + || setRecType.nWidth != getRecType.nWidth + || setRecType.nHeight != getRecType.nHeight ) + { + ERR_PRINTF1(_L("COmxGsTest0008Step01::doTestStepL(): OMX_IndexConfigCommonInputCrop 1 error")); + SetTestStepError(KErrGeneral); + return TestStepResult(); + } + + //Testing OMX_IndexConfigCommonOutputCrop + setRecType.nSize = sizeof(OMX_CONFIG_RECTTYPE); + setRecType.nVersion = TOmxILSpecVersion(); + setRecType.nPortIndex = 0; + GetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonOutputCrop,&setRecType); + setRecType.nLeft = 0x20000; + setRecType.nTop = 0x20000; + setRecType.nWidth = 160; + setRecType.nHeight = 120; + SetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonOutputCrop,&setRecType); + getRecType.nSize = sizeof(OMX_CONFIG_RECTTYPE); + getRecType.nVersion = TOmxILSpecVersion(); + getRecType.nPortIndex = 0; + GetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonOutputCrop,&getRecType); + if( setRecType.nLeft != getRecType.nLeft + || setRecType.nTop != getRecType.nTop + || setRecType.nWidth != getRecType.nWidth + || setRecType.nHeight != getRecType.nHeight ) + { + ERR_PRINTF1(_L("COmxGsTest0008Step01::doTestStepL(): OMX_IndexConfigCommonOutputCrop 1 error")); + SetTestStepError(KErrGeneral); + return TestStepResult(); + } + + //Testing OMX_IndexConfigCommonExclusionRect + setRecType.nSize = sizeof(OMX_CONFIG_RECTTYPE); + setRecType.nVersion = TOmxILSpecVersion(); + setRecType.nPortIndex = 0; + GetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonExclusionRect,&setRecType); + setRecType.nLeft = 0x20000; + setRecType.nTop = 0x20000; + setRecType.nWidth = 320; + setRecType.nHeight = 240; + SetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonExclusionRect,&setRecType); + getRecType.nSize = sizeof(OMX_CONFIG_RECTTYPE); + getRecType.nVersion = TOmxILSpecVersion(); + getRecType.nPortIndex = 0; + GetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonExclusionRect,&getRecType); + if( setRecType.nLeft != getRecType.nLeft + || setRecType.nTop != getRecType.nTop + || setRecType.nWidth != getRecType.nWidth + || setRecType.nHeight != getRecType.nHeight ) + { + ERR_PRINTF1(_L("COmxGsTest0008Step01::doTestStepL(): OMX_IndexConfigCommonExclusionRect 1 error")); + SetTestStepError(KErrGeneral); + return TestStepResult(); + } + + //Negative GetConfig test + OMX_CONFIG_CONTRASTTYPE conContrastType; + conContrastType.nSize = sizeof(OMX_CONFIG_CONTRASTTYPE); + conContrastType.nVersion = TOmxILSpecVersion(); + conContrastType.nPortIndex = 0; + GetConfig(iGraphicSinkCompHandle,OMX_IndexConfigCommonContrast,&conContrastType,OMX_ErrorUnsupportedIndex); + + SetTestStepResult(EPass); + return TestStepResult(); + } + +COmxGsTest0009Step00::~COmxGsTest0009Step00() + { + } + +COmxGsTest0009Step00::COmxGsTest0009Step00() + { + SetTestStepName(KOmxGsTest0009Step00); + } + +TVerdict COmxGsTest0009Step00::doTestStepL() + { + GetIntFromConfig(ConfigSection(),KMMTestCase,iTestCase); + GetIntFromConfig(ConfigSection(),KMMTestStep,iTestStep); + INFO_PRINTF3(_L("COmxGsTest000%dStep0%d::doTestStepL: State Loaded to Executing transition using AllocateBuffer"),iTestCase,iTestStep); + DoROmxGsTestSetup(); + StartStateTransitionTask(); + + StartTimer(); + return TestStepResult(); + } + +COmxGsTest0010Step00::~COmxGsTest0010Step00() + { + } + +COmxGsTest0010Step00::COmxGsTest0010Step00() + { + SetTestStepName(KOmxGsTest0010Step00); + } + +TVerdict COmxGsTest0010Step00::doTestStepL() + { + GetIntFromConfig(ConfigSection(),KMMTestCase,iTestCase); + GetIntFromConfig(ConfigSection(),KMMTestStep,iTestStep); + GetIntFromConfig(ConfigSection(),_L("REmptyBufferLimit"),iDoEmptyBufferDoneLimit); + INFO_PRINTF3(_L("COmxGsTest000%dStep0%d::doTestStepL: Empty Buffer Done using AllocateBuffer"),iTestCase,iTestStep); + DoROmxGsTestSetup(); + StartBufferDoneTask(); + + StartTimer(); + return TestStepResult(); + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/src/graphicsinkteststeps.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/src/graphicsinkteststeps.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,143 @@ +/* +* Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** + * @file + * @internalTechnology + */ + +#ifndef GRAPHICSINKTESTSTEPS_H +#define GRAPHICSINKTESTSTEPS_H + +#include "graphicsinktestbase.h" + +// Test step names + +_LIT(KOmxGsTest0001Step01, "MMVIDEO-OMX-GS-001-01-HP"); +_LIT(KOmxGsTest0001Step02, "MMVIDEO-OMX-GS-001-02-HP"); +_LIT(KOmxGsTest0001Step03, "MMVIDEO-OMX-GS-001-03-HP"); +_LIT(KOmxGsTest0001Step04, "MMVIDEO-OMX-GS-001-04-HP"); +_LIT(KOmxGsTest0001Step05, "MMVIDEO-OMX-GS-001-05-HP"); +_LIT(KOmxGsTest0001Step06, "MMVIDEO-OMX-GS-001-06-HP"); +_LIT(KOmxGsTest0001Step07, "MMVIDEO-OMX-GS-001-07-HP"); +_LIT(KOmxGsTest0001Step08, "MMVIDEO-OMX-GS-001-08-HP"); +_LIT(KOmxGsTest0001Step09, "MMVIDEO-OMX-GS-001-09-HP"); +_LIT(KOmxGsTest0001Step00, "MMVIDEO-OMX-GS-001-00-HP"); + +_LIT(KOmxGsTest0002Step01, "MMVIDEO-OMX-GS-002-01-HP"); +_LIT(KOmxGsTest0002Step02, "MMVIDEO-OMX-GS-002-02-HP"); +_LIT(KOmxGsTest0002Step03, "MMVIDEO-OMX-GS-002-03-HP"); +_LIT(KOmxGsTest0002Step04, "MMVIDEO-OMX-GS-002-04-HP"); + +_LIT(KOmxGsTest0003Step01, "MMVIDEO-OMX-GS-003-01-HP"); +_LIT(KOmxGsTest0003Step02, "MMVIDEO-OMX-GS-003-02-HP"); +_LIT(KOmxGsTest0003Step03, "MMVIDEO-OMX-GS-003-03-HP"); +_LIT(KOmxGsTest0003Step04, "MMVIDEO-OMX-GS-003-04-HP"); + +_LIT(KOmxGsTest0004Step01, "MMVIDEO-OMX-GS-004-01-HP"); +_LIT(KOmxGsTest0004Step02, "MMVIDEO-OMX-GS-004-02-HP"); +_LIT(KOmxGsTest0004Step03, "MMVIDEO-OMX-GS-004-03-HP"); +_LIT(KOmxGsTest0004Step04, "MMVIDEO-OMX-GS-004-04-HP"); +_LIT(KOmxGsTest0004Step05, "MMVIDEO-OMX-GS-004-05-HP"); +_LIT(KOmxGsTest0004Step06, "MMVIDEO-OMX-GS-004-06-HP"); + +_LIT(KOmxGsTest0005Step01, "MMVIDEO-OMX-GS-005-01-HP"); +_LIT(KOmxGsTest0005Step02, "MMVIDEO-OMX-GS-005-02-HP"); +_LIT(KOmxGsTest0005Step03, "MMVIDEO-OMX-GS-005-03-HP"); +_LIT(KOmxGsTest0005Step04, "MMVIDEO-OMX-GS-005-04-HP"); +_LIT(KOmxGsTest0005Step05, "MMVIDEO-OMX-GS-005-05-HP"); + +_LIT(KOmxGsTest0006Step01, "MMVIDEO-OMX-GS-006-01-HP"); +_LIT(KOmxGsTest0006Step02, "MMVIDEO-OMX-GS-006-02-HP"); + +_LIT(KOmxGsTest0007Step01, "MMVIDEO-OMX-GS-007-01-HP"); +_LIT(KOmxGsTest0007Step02, "MMVIDEO-OMX-GS-007-02-HP"); +_LIT(KOmxGsTest0007Step03, "MMVIDEO-OMX-GS-007-03-HP"); +_LIT(KOmxGsTest0007Step04, "MMVIDEO-OMX-GS-007-04-HP"); + +_LIT(KOmxGsTest0008Step01, "MMVIDEO-OMX-GS-008-01-HP"); + +_LIT(KOmxGsTest0009Step00, "MMVIDEO-OMX-GS-009-00-HP"); +_LIT(KOmxGsTest0010Step00, "MMVIDEO-OMX-GS-010-00-HP"); + +// Test step declarations, each step is contained within a seperate class +// Macro to save re-defining similar classes + +#define NEW_GS_CLASS(TEST_NUM) \ + class C##TEST_NUM \ + : public CGraphicsSinkTestBase \ + { \ + public: \ + C##TEST_NUM(); \ + ~C##TEST_NUM(); \ + TVerdict doTestStepL(); \ + private: \ + }; + + +// Now use the macro to declare all the test steps + +NEW_GS_CLASS(OmxGsTest0001Step00) +NEW_GS_CLASS(OmxGsTest0001Step01) +NEW_GS_CLASS(OmxGsTest0001Step02) +NEW_GS_CLASS(OmxGsTest0001Step03) +NEW_GS_CLASS(OmxGsTest0001Step04) +NEW_GS_CLASS(OmxGsTest0001Step05) +NEW_GS_CLASS(OmxGsTest0001Step06) +NEW_GS_CLASS(OmxGsTest0001Step07) +NEW_GS_CLASS(OmxGsTest0001Step08) +NEW_GS_CLASS(OmxGsTest0001Step09) + +NEW_GS_CLASS(OmxGsTest0002Step01) +NEW_GS_CLASS(OmxGsTest0002Step02) +NEW_GS_CLASS(OmxGsTest0002Step03) +NEW_GS_CLASS(OmxGsTest0002Step04) + +NEW_GS_CLASS(OmxGsTest0003Step01) +NEW_GS_CLASS(OmxGsTest0003Step02) +NEW_GS_CLASS(OmxGsTest0003Step03) +NEW_GS_CLASS(OmxGsTest0003Step04) + +NEW_GS_CLASS(OmxGsTest0004Step01) +NEW_GS_CLASS(OmxGsTest0004Step02) +NEW_GS_CLASS(OmxGsTest0004Step03) +NEW_GS_CLASS(OmxGsTest0004Step04) +NEW_GS_CLASS(OmxGsTest0004Step05) +NEW_GS_CLASS(OmxGsTest0004Step06) + +NEW_GS_CLASS(OmxGsTest0005Step01) +NEW_GS_CLASS(OmxGsTest0005Step02) +NEW_GS_CLASS(OmxGsTest0005Step03) +NEW_GS_CLASS(OmxGsTest0005Step04) +NEW_GS_CLASS(OmxGsTest0005Step05) + +NEW_GS_CLASS(OmxGsTest0006Step01) +NEW_GS_CLASS(OmxGsTest0006Step02) + +NEW_GS_CLASS(OmxGsTest0007Step01) +NEW_GS_CLASS(OmxGsTest0007Step02) +NEW_GS_CLASS(OmxGsTest0007Step03) +NEW_GS_CLASS(OmxGsTest0007Step04) + +NEW_GS_CLASS(OmxGsTest0008Step01) + +NEW_GS_CLASS(OmxGsTest0009Step00) +NEW_GS_CLASS(OmxGsTest0010Step00) + + +#endif //GRAPHICSINKTESTSTEPS_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/src/omxilgraphicsinksuiteserver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/src/omxilgraphicsinksuiteserver.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,192 @@ +/* +* Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** + * @file + * @internalTechnology + */ + +#include "omxilgraphicsinksuiteserver.h" +#include "graphicsinkteststeps.h" + +_LIT(KServerName,"tsu_omxilgraphicsink"); +COmxGsTestSuiteServer* COmxGsTestSuiteServer::NewL() +/** + * @return - Instance of the test server + * Same code for Secure and non-secure variants + * Called inside the MainL() function to create and start the + * CTestServer derived server. + */ + { + COmxGsTestSuiteServer * server = new (ELeave) COmxGsTestSuiteServer(); + CleanupStack::PushL(server); + + server->ConstructL(KServerName); + CleanupStack::Pop(server); + return server; + } + + +// Secure variants much simpler +// For EKA2, just an E32Main and a MainL() +LOCAL_C void MainL() +/** + * Secure variant + * Much simpler, uses the new Rendezvous() call to sync with the client + */ + { + // Leave the hooks in for platform security +#if (defined __DATA_CAGING__) + RProcess().DataCaging(RProcess::EDataCagingOn); + RProcess().DataCaging(RProcess::ESecureApiOn); +#endif + CActiveScheduler* sched=NULL; + sched=new(ELeave) CActiveScheduler; + CActiveScheduler::Install(sched); + COmxGsTestSuiteServer* server = NULL; + // Create the CTestServer derived server + TRAPD(err,server = COmxGsTestSuiteServer::NewL()); + if(!err) + { + // Sync with the client and enter the active scheduler + RProcess::Rendezvous(KErrNone); + sched->Start(); + } + delete server; + delete sched; + } + + + +GLDEF_C TInt E32Main() +/** + * @return - Standard Epoc error code on process exit + * Secure variant only + * Process entry point. Called by client using RProcess API + */ + { + __UHEAP_MARK; + CTrapCleanup* cleanup = CTrapCleanup::New(); + if(cleanup == NULL) + { + return KErrNoMemory; + } + TRAPD(err,MainL()); + delete cleanup; + __UHEAP_MARKEND; + return err; + } + + +CTestStep* COmxGsTestSuiteServer::CreateTestStep(const TDesC& aStepName) +/** + * @return - A CTestStep derived instance + * Secure and non-secure variants + * Implementation of CTestServer pure virtual + */ + { + CTestStep* testStep = NULL; + + // --------------------------------------------------------------- + // Graphics Sink Tests + // --------------------------------------------------------------- + if(aStepName == KOmxGsTest0001Step00) + testStep = new COmxGsTest0001Step00(); + else if(aStepName == KOmxGsTest0001Step01) + testStep = new COmxGsTest0001Step01(); + else if(aStepName == KOmxGsTest0001Step02) + testStep = new COmxGsTest0001Step02(); + else if(aStepName == KOmxGsTest0001Step03) + testStep = new COmxGsTest0001Step03(); + else if(aStepName == KOmxGsTest0001Step04) + testStep = new COmxGsTest0001Step04(); + else if(aStepName == KOmxGsTest0001Step05) + testStep = new COmxGsTest0001Step05(); + else if(aStepName == KOmxGsTest0001Step06) + testStep = new COmxGsTest0001Step06(); + else if(aStepName == KOmxGsTest0001Step07) + testStep = new COmxGsTest0001Step07(); + else if(aStepName == KOmxGsTest0001Step08) + testStep = new COmxGsTest0001Step08(); + else if(aStepName == KOmxGsTest0001Step09) + testStep = new COmxGsTest0001Step09(); + + else if(aStepName == KOmxGsTest0002Step01) + testStep = new COmxGsTest0002Step01(); + else if(aStepName == KOmxGsTest0002Step02) + testStep = new COmxGsTest0002Step02(); + else if(aStepName == KOmxGsTest0002Step03) + testStep = new COmxGsTest0002Step03(); + else if(aStepName == KOmxGsTest0002Step04) + testStep = new COmxGsTest0002Step04(); + + else if(aStepName == KOmxGsTest0003Step01) + testStep = new COmxGsTest0003Step01(); + else if(aStepName == KOmxGsTest0003Step02) + testStep = new COmxGsTest0003Step02(); + else if(aStepName == KOmxGsTest0003Step03) + testStep = new COmxGsTest0003Step03(); + else if(aStepName == KOmxGsTest0003Step04) + testStep = new COmxGsTest0003Step04(); + + else if(aStepName == KOmxGsTest0004Step01) + testStep = new COmxGsTest0004Step01(); + else if(aStepName == KOmxGsTest0004Step02) + testStep = new COmxGsTest0004Step02(); + else if(aStepName == KOmxGsTest0004Step03) + testStep = new COmxGsTest0004Step03(); + else if(aStepName == KOmxGsTest0004Step04) + testStep = new COmxGsTest0004Step04(); + else if(aStepName == KOmxGsTest0004Step05) + testStep = new COmxGsTest0004Step05(); + else if(aStepName == KOmxGsTest0004Step06) + testStep = new COmxGsTest0004Step06(); + + else if(aStepName == KOmxGsTest0005Step01) + testStep = new COmxGsTest0005Step01(); + else if(aStepName == KOmxGsTest0005Step02) + testStep = new COmxGsTest0005Step02(); + else if(aStepName == KOmxGsTest0005Step03) + testStep = new COmxGsTest0005Step03(); + else if(aStepName == KOmxGsTest0005Step04) + testStep = new COmxGsTest0005Step04(); + else if(aStepName == KOmxGsTest0005Step05) + testStep = new COmxGsTest0005Step05(); + + else if(aStepName == KOmxGsTest0006Step01) + testStep = new COmxGsTest0006Step01(); + else if(aStepName == KOmxGsTest0006Step02) + testStep = new COmxGsTest0006Step02(); + + else if(aStepName == KOmxGsTest0007Step01) + testStep = new COmxGsTest0007Step01(); + else if(aStepName == KOmxGsTest0007Step02) + testStep = new COmxGsTest0007Step02(); + else if(aStepName == KOmxGsTest0007Step03) + testStep = new COmxGsTest0007Step03(); + else if(aStepName == KOmxGsTest0007Step04) + testStep = new COmxGsTest0007Step04(); + else if(aStepName == KOmxGsTest0008Step01) + testStep = new COmxGsTest0008Step01(); + else if(aStepName == KOmxGsTest0009Step00) + testStep = new COmxGsTest0009Step00(); + else if(aStepName == KOmxGsTest0010Step00) + testStep = new COmxGsTest0010Step00(); + + return testStep; + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/src/omxilgraphicsinksuiteserver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/src/omxilgraphicsinksuiteserver.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,41 @@ +/* +* Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** + * @file + * @internalTechnology + */ + +#ifndef OMXILGRAPHICSINKSUITESERVER_H +#define OMXILGRAPHICSINKSUITESERVER_H + +#include + + +class COmxGsTestSuiteServer : public CTestServer + { +public: + static COmxGsTestSuiteServer* NewL(); + // Base class pure virtual override + virtual CTestStep* CreateTestStep(const TDesC& aStepName); + +// Please Add/modify your class members +private: + }; + +#endif // OMXILGRAPHICSINKSUITESERVER_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/src/omxilgraphicsinktestbase.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/src/omxilgraphicsinktestbase.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,1276 @@ +/* +* Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** + * @file + * @internalTechnology + */ + +#include "omxilgraphicsinktestbase.h" +#include +#include + +CCallbackHandler* +CCallbackHandler::NewL(COmxGsTestBase& aCameraSourceTest) + { + CCallbackHandler* self = new (ELeave) CCallbackHandler(aCameraSourceTest); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + + +void +CCallbackHandler::ConstructL() + { + OMX_CALLBACKTYPE h = + { + CCallbackHandler::EventHandler, + CCallbackHandler::EmptyBufferDone, + CCallbackHandler::FillBufferDone + }; + + iHandle = h; + CActiveScheduler::Add(this); + + User::LeaveIfError(iMsgQueue.CreateLocal(KMaxMsgQueueEntries)); + iMsgQueue.NotifyDataAvailable(iStatus); + SetActive(); + } + +CCallbackHandler::CCallbackHandler(COmxGsTestBase& aCameraSourceTest) + : CActive(EPriorityStandard), + iCameraSourceTest(aCameraSourceTest) + { + } + + +CCallbackHandler::operator OMX_CALLBACKTYPE*() + { + return &iHandle; + } + + +void +CCallbackHandler::RunL() + { + TOmxMessage msg; + while (iMsgQueue.Receive(msg)==KErrNone) + { + switch (msg.iType) + { + case EEmptyBufferCallback: + { +// MOmxInputPortCallbacks* callback = msg.iBuffer->InputPortCallbacks(); +// const CMMFBuffer* buffer = msg.iBuffer->MmfBuffer(); +// callback->EmptyBufferDone(msg.iComponent, buffer); + iCameraSourceTest.DoEmptyBufferDone(msg.iComponent, static_cast(msg.iBuffer)); + break; + } + + case EFillBufferCallback: + { + //iCameraSourceTest.DoFillBufferDone(msg.iComponent,static_cast(msg.iBuffer)); + iCameraSourceTest.DoFillBufferDone(msg.iComponent, static_cast(msg.iBuffer)); + break; + } + case EEventCallback: + { + iCameraSourceTest.DoEventHandler(msg.iComponent, + msg.iEventParams.iEvent, + msg.iEventParams.iData1, + msg.iEventParams.iData2, + msg.iEventParams.iExtra); + break; + } + default: + { + // This is an invalid state + ASSERT(EFalse); + } + } + } + + // setup for next callbacks + iStatus = KRequestPending; + iMsgQueue.NotifyDataAvailable(iStatus); + SetActive(); + + } + +CCallbackHandler::~CCallbackHandler() + { + Cancel(); + iMsgQueue.Close(); + } + + +void +CCallbackHandler::DoCancel() + { + if (iMsgQueue.Handle()) + { + iMsgQueue.CancelDataAvailable(); + } + } + +OMX_ERRORTYPE +CCallbackHandler::FillBufferDone(OMX_HANDLETYPE aComponent, + TAny* aAppData, + OMX_BUFFERHEADERTYPE* aBuffer) + { + ASSERT(aAppData); + //CCameraBuffer* pBuffer = static_cast(aBuffer->pAppPrivate); + return static_cast(aAppData)->DoFillBufferDone(aComponent, aBuffer); + } + +OMX_ERRORTYPE +CCallbackHandler::EmptyBufferDone(OMX_HANDLETYPE aComponent, + TAny* aAppData, + OMX_BUFFERHEADERTYPE* aBuffer) + { + ASSERT(aAppData); + //CCameraBuffer* pBuffer = static_cast(aBuffer->pAppPrivate); + return static_cast(aAppData)->DoEmptyBufferDone(aComponent, aBuffer); + + } + +OMX_ERRORTYPE +CCallbackHandler::EventHandler(OMX_HANDLETYPE aComponent, + TAny* aAppData, + OMX_EVENTTYPE aEvent, + TUint32 aData1, + TUint32 aData2, + TAny* aExtra) + { + ASSERT(aAppData); + CCallbackHandler::TEventParams eventParams; + eventParams.iEvent = aEvent; + eventParams.iData1 = aData1; + eventParams.iData2 = aData2; + eventParams.iExtra = aExtra; + return static_cast(aAppData)->DoEventHandler(aComponent, eventParams); + } + +OMX_ERRORTYPE CCallbackHandler::DoFillBufferDone(OMX_HANDLETYPE aComponent, + OMX_BUFFERHEADERTYPE* aBufferHeader) + { + TOmxMessage message; + message.iType = EFillBufferCallback; + message.iComponent = aComponent; + message.iBuffer = static_cast (aBufferHeader); + TInt error = iMsgQueue.Send(message); + //RDebug::Printf("CCallbackHandler:: Error: %d",error); + + return (error == KErrNone ? OMX_ErrorNone : OMX_ErrorUndefined); + } + +OMX_ERRORTYPE CCallbackHandler::DoEmptyBufferDone(OMX_HANDLETYPE aComponent, + OMX_BUFFERHEADERTYPE* aBufferHeader) + { + TOmxMessage message; + message.iType = EEmptyBufferCallback; + message.iComponent = aComponent; + message.iBuffer = static_cast (aBufferHeader); + TInt error = iMsgQueue.Send(message); + //RDebug::Printf("CCallbackHandler:: Error: %d",error); + + return (error == KErrNone ? OMX_ErrorNone : OMX_ErrorUndefined); + } + + +OMX_ERRORTYPE CCallbackHandler::DoEventHandler(OMX_HANDLETYPE aComponent, TEventParams aEventParams) + { + TOmxMessage message; + message.iType = EEventCallback; + message.iComponent = aComponent; + message.iEventParams = aEventParams; + + /* + OMX_EventCmdComplete, + OMX_EventError, + OMX_EventMark, + OMX_EventPortSettingsChanged, + OMX_EventBufferFlag, + OMX_EventResourcesAcquired, + OMX_EventComponentResumed, + OMX_EventDynamicResourcesAvailable, + OMX_EventPortFormatDetected, + OMX_EventMax = 0x7FFFFFFF + */ + + // TO DO - Put in switch on OMX_EVENTTYPE iEvent and print out the event type and relevant error code in test logs + TInt error = iMsgQueue.Send(message); + //RDebug::Printf("CCallbackHandler:: Error: %d",error); + + return (error == KErrNone ? OMX_ErrorNone : OMX_ErrorUndefined); + } + +// +// COmxGsTestBase +// + +// Device driver constants + +TVerdict COmxGsTestBase::doTestStepPreambleL() +/** + * @return - TVerdict + * Implementation of CTestStep base class virtual + * It is used for doing all initialisation common to derived classes in here. + * Make it being able to leave if there are any errors here as there's no point in + * trying to run a test step if anything fails. + * The leave will be picked up by the framework. + */ + { + // Here we check to see if there is already an active scheduler + // installed, as this function will receive multiple calls during + // Alloc testing of CS and GS components + __UHEAP_MARK; + if (!CActiveScheduler::Current()) + { + iScheduler = new (ELeave) CActiveScheduler; + CActiveScheduler::Install(iScheduler); + } + + // Make sure we are not running the Alloc tests, if we are + // then we will create these elsewhere. + if (TestStepName() != (_L("MMVIDEO-OMX-CS-004-HP")) && + TestStepName() != (_L("MMVIDEO-OMX-GS-001-00-HP")) && + TestStepName() != (_L("MMVIDEO-OMX-JP-001-00-HP")) && + TestStepName() != (_L("MMVIDEO-OMX-FS-001-00-HP")) && + TestStepName() != (_L("MMVIDEO-OMX-IW-001-00-HP"))) + { + InitialiseOmxComponents(); + if (TestStepResult() != EPass) + { + INFO_PRINTF1(_L("*** InitialiseOmxComponents() failed. No point running test case. ***")); + + // If the preamble leaves then the postamble isn't called by TEF. + // We have to do it ourselves to ensure stuff is cleaned up. + TRAP_IGNORE(doTestStepPostambleL()); + User::Leave(KErrGeneral); + } + } + + return TestStepResult(); + } + +TVerdict COmxGsTestBase::doTestStepPostambleL() +/** + * @return - TVerdict + * Implementation of CTestStep base class virtual + * It is used for doing all after test treatment common to derived classes in here. + * Make it being able to leave + * The leave will be picked up by the framework. + */ + { + CloseTestStep(); + + delete iScheduler; + __UHEAP_MARKEND; + return TestStepResult(); + } + +COmxGsTestBase::~COmxGsTestBase() + { + } + + + + +COmxGsTestBase::COmxGsTestBase() : iCamPrevState(OMX_StateInvalid), + iGphxPrevState(OMX_StateInvalid) + { + } + + +void +COmxGsTestBase::PrintOmxState(OMX_STATETYPE aOmxState) + { + switch(aOmxState) + { + case OMX_StateInvalid: + { + INFO_PRINTF1(_L("OMX STATE : OMX_StateInvalid")); + } + break; + case OMX_StateLoaded: + { + INFO_PRINTF1(_L("OMX STATE : OMX_StateLoaded")); + } + break; + case OMX_StateIdle: + { + INFO_PRINTF1(_L("OMX STATE : OMX_StateIdle")); + } + break; + case OMX_StateExecuting: + { + INFO_PRINTF1(_L("OMX STATE : OMX_StateExecuting")); + } + break; + case OMX_StatePause: + { + INFO_PRINTF1(_L("OMX STATE : OMX_StatePause")); + } + break; + case OMX_StateWaitForResources: + { + //INFO_PRINTF1(_L("OMX STATE : OMX_StateWaitForResources")); + } + break; + default: + { + //INFO_PRINTF1(_L("OMX STATE : Wrong state found")); + } + } + } + +TInt COmxGsTestBase::PrintOmxError(OMX_ERRORTYPE aOmxError) + { + switch(aOmxError) + { + case OMX_ErrorNone: + { + INFO_PRINTF1(_L("OMX ERROR : OMX_ErrorNone")); + return KErrNone; + } + + case OMX_ErrorInsufficientResources: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorInsufficientResources")); + return KErrNoMemory; //KErrNotReady; + } + + case OMX_ErrorUndefined: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorUndefined")); + return KErrGeneral; + } + + case OMX_ErrorInvalidComponentName: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorInvalidComponentName")); + return KErrBadName; + } + + case OMX_ErrorComponentNotFound: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorComponentNotFound")); + return KErrNotFound; + } + + case OMX_ErrorInvalidComponent: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorInvalidComponent")); + return KErrBadHandle; + } + + case OMX_ErrorBadParameter: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorBadParameter")); + return KErrArgument; + } + + case OMX_ErrorNotImplemented: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorNotImplemented")); + return KErrNotSupported; + } + + case OMX_ErrorUnderflow: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorUnderflow")); + return KErrUnderflow; + } + + case OMX_ErrorOverflow: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorOverflow")); + return KErrOverflow; + } + + case OMX_ErrorHardware: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorHardware")); + return KErrUnknown; + } + + case OMX_ErrorInvalidState: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorInvalidState")); + return KErrGeneral; + } + + case OMX_ErrorStreamCorrupt: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorStreamCorrupt")); + return KErrCorrupt; + } + + case OMX_ErrorPortsNotCompatible: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorPortsNotCompatible")); + //ERR_PRINTF1(_L("Ports being connected are not compatible")); + return KErrUnknown; + } + + case OMX_ErrorResourcesLost: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorResourcesLost")); + //ERR_PRINTF1(_L("Resources allocated to an idle component have been lost resulting in the component returning to the loaded state")); + return KErrNotReady; + } + + case OMX_ErrorNoMore: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorNoMore")); + //ERR_PRINTF1(_L("No more indicies can be enumerated")); + return KErrGeneral; + } + + case OMX_ErrorVersionMismatch: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorVersionMismatch")); + //ERR_PRINTF1(_L("The component detected a version mismatch")); + return KErrArgument; + } + + case OMX_ErrorNotReady: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorNotReady")); + //ERR_PRINTF1(_L("The component is not ready to return data at this time")); + return KErrNotReady; + } + + case OMX_ErrorTimeout: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorTimeout")); + //ERR_PRINTF1(_L("There was a timeout that occurred")); + return KErrTimedOut; + } + + case OMX_ErrorSameState: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorSameState")); + //ERR_PRINTF1(_L("This error occurs when trying to transition into the state you are already in")); + return KErrGeneral; + } + + case OMX_ErrorResourcesPreempted: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorResourcesPreempted")); + //ERR_PRINTF1(_L("Resources allocated to an executing or paused component have been preempted, causing the component to return to the idle state")); + return KErrGeneral; + } + + case OMX_ErrorPortUnresponsiveDuringAllocation: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorPortUnresponsiveDuringAllocation")); + //ERR_PRINTF1(_L("A non-supplier port sends this error to the IL client (via the EventHandler callback) during the allocation of buffers (on a transition from the LOADED to the IDLE state or on a port restart) when it deems that it has waited an unusually long time for the supplier to send it an allocated buffer via a UseBuffer call.")); + return KErrGeneral; //KErrTimedOut + } + + case OMX_ErrorPortUnresponsiveDuringDeallocation: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorPortUnresponsiveDuringDeallocation")); + //ERR_PRINTF1(_L("A non-supplier port sends this error to the IL client (via the EventHandler callback) during the deallocation of buffers (on a transition from the IDLE to LOADED state or on a port stop) when it deems that it has waited an unsually long time for the supplier to request the deallocation of a buffer header via a FreeBuffer call.")); + return KErrGeneral; //KErrTimedOut + } + + case OMX_ErrorPortUnresponsiveDuringStop: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorPortUnresponsiveDuringStop")); + //ERR_PRINTF1(_L("A supplier port sends this error to the IL client (via the EventHandler callback) during the stopping of a port (either on a transition from the IDLE to LOADED state or a port stop) when it deems that it has waited an unusually long time for the non-supplier to return a buffer via an EmptyThisBuffer or FillThisBuffer call.")); + return KErrGeneral; //KErrTimedOut + } + + case OMX_ErrorIncorrectStateTransition: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorIncorrectStateTransition")); + //ERR_PRINTF1(_L("Attempting a state transtion that is not allowed")); + return KErrGeneral; + } + + case OMX_ErrorIncorrectStateOperation: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorIncorrectStateOperation")); + //ERR_PRINTF1(_L("Attempting a command that is not allowed during the present state.")); + return KErrGeneral; //KErrNotSupported + } + + case OMX_ErrorUnsupportedSetting: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorUnsupportedSetting")); + //ERR_PRINTF1(_L("The values encapsulated in the parameter or config structure are not supported.")); + return KErrGeneral; //KErrNotSupported + } + + case OMX_ErrorUnsupportedIndex: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorUnsupportedIndex")); + //ERR_PRINTF1(_L("The parameter or config indicated by the given index is not supported.")); + return KErrNotSupported; //KErrTooBig or KErrGeneral + } + + case OMX_ErrorBadPortIndex: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorBadPortIndex")); + //ERR_PRINTF1(_L("The port index supplied is incorrect.")); + return KErrArgument; //KErrTooBig + } + + case OMX_ErrorPortUnpopulated: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorPortUnpopulated")); + //ERR_PRINTF1(_L("The port has lost one or more of its buffers and it thus unpopulated.")); + return KErrGeneral; + } + + case OMX_ErrorComponentSuspended: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorComponentSuspended")); + //ERR_PRINTF1(_L("Component suspended due to temporary loss of resources")); + return KErrAbort; + } + + case OMX_ErrorDynamicResourcesUnavailable: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorDynamicResourcesUnavailable")); + //ERR_PRINTF1(_L("Component suspended due to an inability to acquire dynamic resources")); + return KErrAbort; //KErrGeneral + } + + case OMX_ErrorMbErrorsInFrame: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorMbErrorsInFrame")); + //ERR_PRINTF1(_L("When the macroblock error reporting is enabled the component returns new error for every frame that has errors")); + return KErrGeneral; + } + + case OMX_ErrorFormatNotDetected: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorFormatNotDetected")); + //ERR_PRINTF1(_L("A component reports this error when it cannot parse or determine the format of an input stream.")); + return KErrCorrupt; //KErrGeneral + } + + case OMX_ErrorContentPipeOpenFailed: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorContentPipeOpenFailed")); + //R//ERR_PRINTF1(_L("The content open operation failed.")); + return KErrGeneral; + //break; + } + + case OMX_ErrorContentPipeCreationFailed: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorContentPipeCreationFailed")); + //ERR_PRINTF1(_L("The content creation operation failed.")); + return KErrGeneral; + } + + case OMX_ErrorSeperateTablesUsed: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorSeperateTablesUsed")); + //ERR_PRINTF1(_L("Separate table information is being used")); + return KErrGeneral; + } + + case OMX_ErrorTunnelingUnsupported: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorTunnelingUnsupported")); + //ERR_PRINTF1(_L("Tunneling is unsupported by the component")); + return KErrNotSupported; + } + + case OMX_ErrorMax: + { + ERR_PRINTF1(_L("OMX ERROR : OMX_ErrorMax")); + //ERR_PRINTF1(_L("OMX_ErrorMax")); + return KErrTooBig; // KErrGeneral + } + + default: + { + ERR_PRINTF1(_L("OMX ERROR : Wrong error code found")); + return KErrGeneral; + } + } + } + +void COmxGsTestBase::InfoPrint1(const TDesC& aPrint) + { + INFO_PRINTF1(aPrint); + } + +OMX_ERRORTYPE COmxGsTestBase::ConvertSymbianErrorType(TInt aError) + { + OMX_ERRORTYPE err = OMX_ErrorNone; + switch (aError) + { + case KErrNone: + err = OMX_ErrorNone; + break; + case KErrNoMemory: + err = OMX_ErrorInsufficientResources; + break; + case KErrGeneral: + break; + default: + err = OMX_ErrorUndefined; + } + return err; + } + + +void COmxGsTestBase::InitialiseOmxComponents() + { + iError = OMX_Init(); + + if (OMX_ErrorNone != iError) + { + SetTestStepError(PrintOmxError(iError)); + return SetTestStepResult(EFail); + } + + ASSERT(!iCallbackHandler); + TRAPD(error, iCallbackHandler = CCallbackHandler::NewL(*this)); + OMX_CALLBACKTYPE* omxCallbacks = *iCallbackHandler; + + if (error) + { + SetTestStepError(error); + return SetTestStepResult(EFail); + } + + OMX_PTR appData = iCallbackHandler; + + OMX_HANDLETYPE graphicsSinkHandle = NULL; + OMX_STRING graphicsSinkComponentName = "OMX.SYMBIAN.VIDEO.GRAPHICSINK"; + + iError = OMX_GetHandle( + &graphicsSinkHandle, + graphicsSinkComponentName, + appData, + omxCallbacks); + + if (OMX_ErrorNone != iError) + { + INFO_PRINTF2(_L("Error %08X loading graphics sink"), iError); + SetTestStepError(PrintOmxError(iError)); + return SetTestStepResult(EFail); + } + + iGraphicSinkCompHandle = (OMX_COMPONENTTYPE*) graphicsSinkHandle; + INFO_PRINTF2(_L("OMX.SYMBIAN.VIDEO.GRAPHICSINK: Handle: %X"), iGraphicSinkCompHandle); +/* + OMX_HANDLETYPE cameraSourceHandle = NULL; + OMX_STRING cameraSourceComponentName = "OMX.SYMBIAN.VIDEO.CAMERASOURCE"; + + iError = OMX_GetHandle( + &cameraSourceHandle, + cameraSourceComponentName, + appData, + omxCallbacks); + + if (OMX_ErrorNone != iError) + { + INFO_PRINTF2(_L("Error %08X loading camera source"), iError); + OMX_FreeHandle(iGraphicSinkCompHandle); + SetTestStepError(PrintOmxError(iError)); + return SetTestStepResult(EFail); + } + iCameraSourceCompHandle = (OMX_COMPONENTTYPE*)cameraSourceHandle; + INFO_PRINTF2(_L("OMX.SYMBIAN.VIDEO.CAMERASOURCE: Handle: %X"), iCameraSourceCompHandle); + + OMX_HANDLETYPE fileSinkHandle = NULL; + OMX_STRING fileSinkComponentName = "OMX.SYMBIAN.OTHER.FILESINK"; + + iError = OMX_GetHandle( + &fileSinkHandle, + fileSinkComponentName, + appData, + omxCallbacks); + + if (OMX_ErrorNone != iError) + { + INFO_PRINTF2(_L("Error %08X loading file sink"), iError); + OMX_FreeHandle(iGraphicSinkCompHandle); + OMX_FreeHandle(iCameraSourceCompHandle); + SetTestStepError(PrintOmxError(iError)); + return SetTestStepResult(EFail); + } + + iFileSinkCompHandle = (OMX_COMPONENTTYPE*)fileSinkHandle; + INFO_PRINTF2(_L("OMX.SYMBIAN.OTHER.FILESINK: Handle: %X"), iFileSinkCompHandle); + + + OMX_HANDLETYPE jpegEncoderHandle = NULL; + OMX_STRING jpegEncoderComponentName = "OMX.SYMBIAN.IMAGE.ENCODER.JPEG"; + + iError = OMX_GetHandle(&jpegEncoderHandle, + jpegEncoderComponentName, + appData, + omxCallbacks); + + if (OMX_ErrorNone != iError) + { + INFO_PRINTF2(_L("Error %08X loading jpeg encoder"), iError); + OMX_FreeHandle(iGraphicSinkCompHandle); + OMX_FreeHandle(iCameraSourceCompHandle); + OMX_FreeHandle(iFileSinkCompHandle); + SetTestStepError(PrintOmxError(iError)); + return SetTestStepResult(EFail); + } + + iJpegEncoderCompHandle = (OMX_COMPONENTTYPE*) jpegEncoderHandle; + INFO_PRINTF2(_L("OMX.SYMBIAN.IMAGE.ENCODER.JPEG: Handle: %X"), iJpegEncoderCompHandle); + + + OMX_HANDLETYPE imageWriterHandle = NULL; + OMX_STRING imageWriterComponentName = "OMX.SYMBIAN.IMAGE.IMAGEWRITER"; + + iError = OMX_GetHandle(&imageWriterHandle, + imageWriterComponentName, + appData, + omxCallbacks); + + if (OMX_ErrorNone != iError) + { + INFO_PRINTF2(_L("Error %08X loading image writer"), iError); + OMX_FreeHandle(iGraphicSinkCompHandle); + OMX_FreeHandle(iCameraSourceCompHandle); + OMX_FreeHandle(iFileSinkCompHandle); + OMX_FreeHandle(iJpegEncoderCompHandle); + SetTestStepError(PrintOmxError(iError)); + return SetTestStepResult(EFail); + } + + iImageWriterCompHandle = (OMX_COMPONENTTYPE*) imageWriterHandle; + INFO_PRINTF2(_L("OMX.SYMBIAN.IMAGE.IMAGEWRITER: Handle: %X"), iImageWriterCompHandle); +*/ + InitialiseTestSpecificOmxComponents(); + + SetTestStepResult(EPass); + } + +void COmxGsTestBase::InitialiseTestSpecificOmxComponents() + { + // Disable clock port in Camera Source +// INFO_PRINTF1(_L("send port 3 to disable")); +// SendCommand(iCameraSourceCompHandle, OMX_CommandPortDisable, KCameraClockPortIndex, 0); + + // Disable port VC in Camera Source +// INFO_PRINTF1(_L("send port 1 to disable")); +// SendCommand(iCameraSourceCompHandle, OMX_CommandPortDisable, KCameraVCPortIndex, 0); + } + +void COmxGsTestBase::CreateWindowL() + { + iSurfaceUpdateSession.Close(); + iSurfaceManager.Close();iWindowHandle = 0; + // Connect to a WS Session. + User::LeaveIfError(iWsSession.Connect()); + + // Create a Window Group. + iWindowGroup = RWindowGroup(iWsSession); + User::LeaveIfError(iWindowGroup.Construct(iWindowHandle++)); + + // Create the Screen device for the WServ session. + iWsSd = new (ELeave) CWsScreenDevice(iWsSession); + User::LeaveIfError(iWsSd->Construct()); + + //Done in different class + iWindow = new (ELeave) RWindow(iWsSession); + User::LeaveIfError(iWindow->Construct(iWindowGroup, iWindowHandle++)); + + iWindow2 = new (ELeave) RWindow(iWsSession); + User::LeaveIfError(iWindow2->Construct(iWindowGroup, iWindowHandle)); + + //done in different class + iGc = new (ELeave) CWindowGc(iWsSd); + User::LeaveIfError(iGc->Construct()); + + iGc2 = new (ELeave) CWindowGc(iWsSd); + User::LeaveIfError(iGc2->Construct()); + + // Reset the screen mode. + if(iWsSd->CurrentScreenMode() != 0) + { + iWsSd->SetAppScreenMode(0); + iWsSd->SetScreenMode(0); + } + + iWindow->Activate(); + iGc->Activate(*iWindow); + iGc->Clear(); + iWindow->SetVisible(ETrue); + iWsSession.Flush(); + } + +void COmxGsTestBase::CloseTest() + { + delete iCallbackHandler; + iCallbackHandler = NULL; + if(iTestChunk.Handle()) + { + iTestChunk.Close(); + } + + if (iGc) + { + delete iGc; + iGc = NULL; + } + if (iGc2) + { + delete iGc2; + iGc2 = NULL; + } + + if (iWsSd) + { + delete iWsSd; + iWsSd = NULL; + } + + iWsSession.Close(); + + if (iWindow) + { + delete iWindow; + iWindow = NULL; + } + + if (iWindow2) + { + delete iWindow2; + iWindow2 = NULL; + } + + if (iTestShutdown) + { + delete iTestShutdown; + iTestShutdown = NULL; + } + + if (iTestPause) + { + delete iTestPause; + iTestPause = NULL; + } + + if (iTestStateTransition) + { + delete iTestStateTransition; + iTestStateTransition = NULL; + } + + iSurfaceUpdateSession.Close(); + iSurfaceManager.Close(); + // Make sure we are not running the Alloc tests, if we are + // then we have already cleaned up the OMX components and core. + if(TestStepName() != (_L("MMVIDEO-OMX-CS-004-HP")) && TestStepName() != (_L("MMVIDEO-OMX-GS-001-00-HP")) + && TestStepName() != (_L("MMVIDEO-OMX-JP-001-00-HP")) && TestStepName() != (_L("MMVIDEO-OMX-FS-001-00-HP")) + && TestStepName() != (_L("MMVIDEO-OMX-IW-001-00-HP"))) + { + FreeHandles(); + iError = OMX_Deinit(); + } + + REComSession::FinalClose(); + } + +TInt COmxGsTestBase::InitialiseSurfaceManager() + { + TInt err = iSurfaceManager.Open(); + if (err == KErrNone) + { + err = iSurfaceUpdateSession.Connect(3); + } + + if (err == KErrNotFound) + { + INFO_PRINTF1(_L("Failed to find surfacemanger or surfaceupdatesession")); + INFO_PRINTF1(_L("Make sure 'SYMBIAN_GRAPHICS_USE_GCE ON' is specified in epoc.ini")); + } + + return err; + } + +TInt COmxGsTestBase::CreateAndMapSurface(const RSurfaceManager::TSurfaceCreationAttributesBuf& aReqs, TSurfaceId& aSurfaceId) + { + TInt err = iSurfaceManager.CreateSurface(aReqs, aSurfaceId); + if (err) + { + ERR_PRINTF2(_L("RSurfaceManager::CreateSurface() failed with %d"), err); + return err; + } + + err = iSurfaceManager.MapSurface(aSurfaceId, iTestChunk); + if (err) + { + ERR_PRINTF2(_L("RSurfaceManager::MapSurface() failed with %d"), err); + return err; + } + + iSurfaceId = aSurfaceId; + return KErrNone; + } + +void COmxGsTestBase::SendCommand( + OMX_HANDLETYPE aComponent, + OMX_COMMANDTYPE aCmd, + OMX_U32 aParam1, + OMX_PTR aCmdData, + OMX_ERRORTYPE aExpError) + { + iError = OMX_SendCommand(aComponent,aCmd,aParam1,aCmdData); + + if (aExpError != iError) + { + ERR_PRINTF1(_L("SendCommandErr")); + SetTestStepError(PrintOmxError(iError)); + return SetTestStepResult(EFail); + } + } + +void COmxGsTestBase::GetState(OMX_HANDLETYPE aComponent,OMX_STATETYPE* aState,OMX_STATETYPE aExpectedState) + { + iError = OMX_GetState(aComponent,aState); + if (OMX_ErrorNone != iError) + { + SetTestStepError(PrintOmxError(iError)); + return SetTestStepResult(EFail); + } + + // PrintOmxState(*aState); + if (aExpectedState != OMX_StateMax) + { + if (aExpectedState != *aState) + { + ERR_PRINTF1(_L("Did not return expected state")); + PrintOmxState(*aState); + SetTestStepError(KErrGeneral); + return SetTestStepResult(EFail); + } + } + + } + +void COmxGsTestBase::SetParameter( + OMX_HANDLETYPE aComponent, + OMX_INDEXTYPE aIndex, + OMX_PTR aComponentParameterStructure, + OMX_ERRORTYPE aExpError) + { + iError = OMX_SetParameter(aComponent, + aIndex, + aComponentParameterStructure); + if (aExpError != iError) + { + INFO_PRINTF3(_L("SetParameter() returned %08X instead of %08X"), iError, aExpError); + SetTestStepError(PrintOmxError(iError)); + return SetTestStepResult(EFail); + } + } + +void COmxGsTestBase::GetParameter( + OMX_HANDLETYPE aComponent, + OMX_INDEXTYPE aIndex, + OMX_PTR aComponentParameterStructure, + OMX_ERRORTYPE aExpError) + { + iError = OMX_GetParameter(aComponent, + aIndex, + aComponentParameterStructure); + if (aExpError != iError) + { + ERR_PRINTF3(_L("COmxGsTestBase::GetParameter - expected: %08X got: %08X"), aExpError, iError); + SetTestStepError(PrintOmxError(iError)); + return SetTestStepResult(EFail); + } + } + +void COmxGsTestBase::SetConfig( + OMX_HANDLETYPE aComponent, + OMX_INDEXTYPE aIndex, + OMX_PTR aComponentParameterStructure, + OMX_ERRORTYPE aExpError) + { + iError = OMX_SetConfig(aComponent, + aIndex, + aComponentParameterStructure); + if (aExpError != iError) + { + INFO_PRINTF1(_L("COmxGsTestBase::SetConfig fail")); + SetTestStepError(PrintOmxError(iError)); + return SetTestStepResult(EFail); + } + } + +void COmxGsTestBase::GetConfig( + OMX_HANDLETYPE aComponent, + OMX_INDEXTYPE aIndex, + OMX_PTR aComponentParameterStructure, + OMX_ERRORTYPE aExpError) + { + iError = OMX_GetConfig(aComponent, + aIndex, + aComponentParameterStructure); + if (aExpError != iError) + { + INFO_PRINTF1(_L("COmxGsTestBase::GetConfig fail")); + SetTestStepError(PrintOmxError(iError)); + return SetTestStepResult(EFail); + } + } + +void COmxGsTestBase::FreeBuffer( + OMX_HANDLETYPE aComponent, + OMX_U32 aPortIndex, + RPointerArray aArrayBufferHeaderType, + OMX_ERRORTYPE aExpError) + { + TInt bufferCount = aArrayBufferHeaderType.Count(); + + for (TInt i =0; i < bufferCount ; ++i) + { + iError = OMX_FreeBuffer(aComponent,aPortIndex,aArrayBufferHeaderType[i]); + if (aExpError != iError) + { + SetTestStepError(PrintOmxError(iError)); + return SetTestStepResult(EFail); + } + } + } + +void COmxGsTestBase::AllocateBuffer( + OMX_HANDLETYPE aComponent, + OMX_BUFFERHEADERTYPE** aBufferHeaderType, + OMX_U32 aPortIndex, + OMX_PTR aAppPrivate, + OMX_U32 aSizeBytes, + RPointerArray* aArrayBufferHeaderType, + OMX_U32 aCount, + OMX_ERRORTYPE aExpError) + { + for(TInt i = 0 ; i < aCount; i++ ) + { + iError = OMX_AllocateBuffer(aComponent,*&aBufferHeaderType,aPortIndex,aAppPrivate,aSizeBytes); + if (aExpError != iError) + { + SetTestStepError(PrintOmxError(iError)); + return SetTestStepResult(EFail); + } + + // Used for tracking + TInt err = aArrayBufferHeaderType->Append(*aBufferHeaderType); + if (err != KErrNone) + { + INFO_PRINTF2(_L("Append Buffer Failed %d"), err); + SetTestStepError(err); + return SetTestStepResult(EFail); + } + } + } + +void COmxGsTestBase::FreeHandles() + { + // Don't call this function after OMX_DeInit call + if (iGraphicSinkCompHandle) + { + INFO_PRINTF1(_L("FreeHandle for GFX ++")); + OMX_FreeHandle(iGraphicSinkCompHandle); + iGraphicSinkCompHandle = NULL; + } +/* + if(iCameraSourceCompHandle) + { + INFO_PRINTF1(_L("FreeHandle for CAM ++")); + OMX_FreeHandle(iCameraSourceCompHandle); + iCameraSourceCompHandle = NULL; + } + + if (iFileSinkCompHandle) + { + INFO_PRINTF1(_L("FreeHandle for FSK ++")); + OMX_FreeHandle(iFileSinkCompHandle); + iFileSinkCompHandle = NULL; + } + + if(iJpegEncoderCompHandle) + { + INFO_PRINTF1(_L("FreeHandle for JPEG Encoder ++")); + OMX_FreeHandle(iJpegEncoderCompHandle); + iJpegEncoderCompHandle = NULL; + } + + if(iImageWriterCompHandle) + { + INFO_PRINTF1(_L("FreeHandle for Image Writer ++")); + OMX_FreeHandle(iImageWriterCompHandle); + iImageWriterCompHandle = NULL; + } + + if(iXvidEncoderCompHandle) + { + INFO_PRINTF1(_L("FreeHandle for Xvid Encoder ++")); + OMX_FreeHandle(iXvidEncoderCompHandle); + iXvidEncoderCompHandle = NULL; + } + + if(i3gpMuxerCompHandle) + { + INFO_PRINTF1(_L("FreeHandle for 3gp Muxer ++")); + OMX_FreeHandle(i3gpMuxerCompHandle); + i3gpMuxerCompHandle = NULL; + } + + if(iClockCompHandle) + { + INFO_PRINTF1(_L("FreeHandle for Clock ++")); + OMX_FreeHandle(iClockCompHandle); + iClockCompHandle = NULL; + } +*/ + } + + + +TInt COmxGsTestBase::StateTransition(const TDesC& /*aStateTransitionName*/) + { + return KErrNone; + } + +void COmxGsTestBase::StartTimer() + { + TRAPD(err, iTestShutdown = COmxGsTestShutdown::NewL(this,1)); + if(err) + { + ERR_PRINTF1(_L("OOM ERROR")); + return SetTestStepError(err); + } + iInterval = KTSU_OMX_GS_Interval; + iTestShutdown->Start(iInterval,KErrNone, EPass); + CActiveScheduler::Start(); + } + +void COmxGsTestBase::WaitForCallbacks() + { + TRAPD(error, iTestShutdown = COmxGsTestShutdown::NewL(this,2)); + if(error) + { + ERR_PRINTF1(_L("OOM ERROR")); + return SetTestStepError(error); + } + + iInterval = KTSU_OMX_GS_CALLBACK; + iTestShutdown->Start(iInterval,KErrGeneral, EPass); + CActiveScheduler::Start(); + } + +void COmxGsTestBase::PauseTimer() + { + TRAPD(error, iTestPause = COmxGsTestShutdown::NewL(this,3)); + if(error) + { + ERR_PRINTF1(_L("OOM ERROR")); + return SetTestStepError(error); + } + + iInterval = KTSU_OMX_GS_Pause_Interval/2; + iTestPause->Start(iInterval,KErrGeneral, EPass); + } + +// ShutDown Class +COmxGsTestShutdown* COmxGsTestShutdown::NewL(COmxGsTestBase* aOmxGsTest,TInt aTimerId) + { + COmxGsTestShutdown* self = new(ELeave) COmxGsTestShutdown(aOmxGsTest,aTimerId); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +COmxGsTestShutdown::COmxGsTestShutdown(COmxGsTestBase* aOmxGsTest,TInt aTimerId) +: CTimer(EPriorityUserInput), iOmxGsTest(aOmxGsTest), iTimerId(aTimerId) + { + CActiveScheduler::Add(this); + } + +COmxGsTestShutdown::~COmxGsTestShutdown() + { + Cancel(); + } + +void COmxGsTestShutdown::ConstructL() + { + CTimer::ConstructL(); + } + +void COmxGsTestShutdown::Start(TTimeIntervalMicroSeconds32 aInterval, TInt aReason, TVerdict aResult) + { + iReason = aReason; + iResult = aResult; + After(aInterval); + } + +void COmxGsTestShutdown::RunL() + { + iOmxGsTest->PostKickOffTestL(iTimerId); + } + +COmxGsTestStateTransition* COmxGsTestStateTransition::NewL(COmxGsTestBase* aOmxGsTest,TInt aPriority) + { + COmxGsTestStateTransition* self = new(ELeave) COmxGsTestStateTransition(aOmxGsTest,aPriority); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + + } + +COmxGsTestStateTransition::COmxGsTestStateTransition(COmxGsTestBase* aOmxGsTest,TInt aPriority) +: CTimer(aPriority), iOmxGsTest(aOmxGsTest) + { + CActiveScheduler::Add(this); + } + +COmxGsTestStateTransition::~COmxGsTestStateTransition() + { + Cancel(); + } + +void COmxGsTestStateTransition::ConstructL() + { + CTimer::ConstructL(); + } + +void COmxGsTestStateTransition::Start(TTimeIntervalMicroSeconds32 aInterval,const TDesC& aStateTransitionName) + { + iStateTransitionName = aStateTransitionName; + After(aInterval); + } + +void COmxGsTestStateTransition::RunL() + { + iOmxGsTest->StateTransition(iStateTransitionName); + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/src/omxilgraphicsinktestbase.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/src/omxilgraphicsinktestbase.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,358 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** + * @file + * @internalTechnology + */ + +#ifndef OMXILGRAPHICSINKTESTBASE_H +#define OMXILGRAPHICSINKTESTBASE_H + +#include +#include +#include +#include +#include +#include + +#include "omxilmmbuffer.h" + +const TInt KTSU_OMX_GS_Interval = 0x0500000; +const TInt KTSU_OMX_GS_Pause_Interval = 0x0100000; +const TInt KTSU_OMX_GS_Pause_Wait = 2000000; +const TInt KTSU_OMX_GS_Pause_Video = 0x0050000; +const TInt KTSU_OMX_GS_State_Transition_Interval = 2000000; // 2 Seconds +const TInt KTSU_OMX_GS_CALLBACK = 1000000 ;// 2 second timer for test shutdown + +const TInt KMaxLenStateTransitionName = 126; + +const TInt KCameraVFPortIndex = 0; +const TInt KCameraVCPortIndex = 1; +const TInt KCameraICPortIndex = 2; +const TInt KCameraClockPortIndex = 3; + +_LIT(KMMTestCase, "RTestCase"); +_LIT(KMMTestStep, "RTestStep"); + +// Forward declarations +struct OMX_COMPONENTTYPE; +class COmxGsTestStateTransition; +class COmxGsTestBase; +class COmxGsTestShutdown; + + +/** + * OpenMAX call back handler used in the test code. + */ +class CCallbackHandler : public CActive + { +public: + + enum TMessageType + { + EFillBufferCallback, + EEmptyBufferCallback, + EEventCallback + }; + + class TEventParams + { + public: + OMX_EVENTTYPE iEvent; + TUint iData1; + TUint iData2; + TAny* iExtra; + }; + + class TOmxMessage + { + public: + TMessageType iType; + OMX_HANDLETYPE iComponent; + union + { + TAny* iBuffer; + TEventParams iEventParams; + }; + }; + + + static const TInt KMaxMsgQueueEntries = 10; + +public: + + static CCallbackHandler* NewL(COmxGsTestBase& aCameraSourceTest); + virtual ~CCallbackHandler(); + + operator OMX_CALLBACKTYPE*(); + + void RunL(); + void DoCancel(); + + static OMX_ERRORTYPE FillBufferDone(OMX_HANDLETYPE aComponent, + TAny* aAppData, + OMX_BUFFERHEADERTYPE* aBuffer); + + static OMX_ERRORTYPE EmptyBufferDone(OMX_HANDLETYPE aComponent, + TAny* aAppData, + OMX_BUFFERHEADERTYPE* aBuffer); + + static OMX_ERRORTYPE EventHandler(OMX_HANDLETYPE aComponent, + TAny* aAppData, + OMX_EVENTTYPE aEvent, + TUint32 aData1, + TUint32 aData2, + TAny* aExtra); + + +private: + + OMX_ERRORTYPE DoEventHandler(OMX_HANDLETYPE aComponent, + TEventParams aParams); + + OMX_ERRORTYPE DoFillBufferDone(OMX_HANDLETYPE aComponent, + OMX_BUFFERHEADERTYPE* aBufferHeader); + + OMX_ERRORTYPE DoEmptyBufferDone(OMX_HANDLETYPE aComponent, + OMX_BUFFERHEADERTYPE* aBufferHeader); + + + void ConstructL(); + CCallbackHandler(COmxGsTestBase& aCameraSourceTest); + +private: + + COmxGsTestBase& iCameraSourceTest; + RMsgQueue iMsgQueue; + OMX_CALLBACKTYPE iHandle; + + }; + + + +class COmxGsTestBase : public CTestStep + { + friend class COmxGsTestShutdown; + friend class COmxGsTestStateTransition; +public: + + COmxGsTestBase(); + + ~COmxGsTestBase(); + TVerdict doTestStepPreambleL(); + TVerdict doTestStepPostambleL(); + virtual TVerdict doTestStepL() = 0; + virtual void CloseTestStep() = 0; + void CloseTest(); + + void InfoPrint1(const TDesC& aPrint); + + virtual void DoFillBufferDone(OMX_HANDLETYPE aComponent, + OMX_BUFFERHEADERTYPE* aBufferHeader) = 0; + + virtual void DoEmptyBufferDone(OMX_HANDLETYPE aComponent, + OMX_BUFFERHEADERTYPE* aBufferHeader) = 0; + + virtual void DoEventHandler(OMX_HANDLETYPE aComponent, + OMX_EVENTTYPE aEvent, + TUint aData1, + TUint aData2, + TAny* aExtra) = 0; + + + static OMX_ERRORTYPE ConvertSymbianErrorType(TInt aError); + +protected: + void PrintOmxState(OMX_STATETYPE aOmxState); + TInt PrintOmxError(OMX_ERRORTYPE aOmxError); + + virtual void InitialiseOmxComponents(); + virtual void InitialiseTestSpecificOmxComponents(); + void CreateWindowL(); + void SendCommand( + OMX_HANDLETYPE aComponent, + OMX_COMMANDTYPE aCmd, + OMX_U32 aParam1, + OMX_PTR aCmdData, + OMX_ERRORTYPE aExpError = OMX_ErrorNone); + + void GetState(OMX_HANDLETYPE aComponent, + OMX_STATETYPE* aState, + OMX_STATETYPE aExpectedState = OMX_StateMax); + + void SetParameter( + OMX_HANDLETYPE aComponent, + OMX_INDEXTYPE aIndex, + OMX_PTR aComponentParameterStructure, + OMX_ERRORTYPE aExpError = OMX_ErrorNone); + + void GetParameter( + OMX_HANDLETYPE aComponent, + OMX_INDEXTYPE aIndex, + OMX_PTR aComponentParameterStructure, + OMX_ERRORTYPE aExpError = OMX_ErrorNone); + + void SetConfig( + OMX_HANDLETYPE aComponent, + OMX_INDEXTYPE aIndex, + OMX_PTR aComponentParameterStructure, + OMX_ERRORTYPE aExpError = OMX_ErrorNone); + + void GetConfig( + OMX_HANDLETYPE aComponent, + OMX_INDEXTYPE aIndex, + OMX_PTR aComponentParameterStructure, + OMX_ERRORTYPE aExpError = OMX_ErrorNone); + + void FreeBuffer( + OMX_HANDLETYPE aComponent, + OMX_U32 aPortIndex, + RPointerArray aArrayBufferHeaderType, + OMX_ERRORTYPE aExpError = OMX_ErrorNone); + + void AllocateBuffer( + OMX_HANDLETYPE aComponent, + OMX_BUFFERHEADERTYPE** aBufferHeaderType, + OMX_U32 aPortIndex, + OMX_PTR aAppPrivate, + OMX_U32 aSizeBytes, + RPointerArray* aArrayBufferHeaderType, + OMX_U32 aCount, + OMX_ERRORTYPE aExpError = OMX_ErrorNone); + + void FreeHandles(); + virtual TInt PostKickOffTestL(TInt aTimerId) = 0; + virtual TInt StateTransition(const TDesC& aStateTransitionName); + TInt InitialiseSurfaceManager(); + TInt CreateAndMapSurface(const RSurfaceManager::TSurfaceCreationAttributesBuf& aReqs, TSurfaceId& aSurfaceId); + void StartTimer(); + void WaitForCallbacks(); + void PauseTimer(); + +protected: + + CCallbackHandler* iCallbackHandler; +// OMX_COMPONENTTYPE* iCameraSourceCompHandle; +// OMX_COMPONENTTYPE* iCameraSourceCompHandlePort1; + OMX_COMPONENTTYPE* iGraphicSinkCompHandle; + OMX_COMPONENTTYPE* iGraphicSinkCompHandlePort1; + OMX_COMPONENTTYPE* iBufferSupplierComponent; + OMX_COMPONENTTYPE* iNonBufferSupplierComponent; +// OMX_COMPONENTTYPE* iFileSinkCompHandle; +// OMX_COMPONENTTYPE* iJpegEncoderCompHandle; +// OMX_COMPONENTTYPE* iXvidEncoderCompHandle; +// OMX_COMPONENTTYPE* i3gpMuxerCompHandle; +// OMX_COMPONENTTYPE* iClockCompHandle; +// OMX_COMPONENTTYPE* iImageWriterCompHandle; + OMX_ERRORTYPE iError; + OMX_STATETYPE iState; + OMX_INDEXTYPE iSurfaceConfigExt; + + COmxGsTestShutdown* iTestShutdown; + COmxGsTestShutdown* iTestPause; + COmxGsTestStateTransition* iTestStateTransition; + TTimeIntervalMicroSeconds32 iInterval; + + volatile OMX_STATETYPE iCamPrevState; + volatile OMX_STATETYPE iGphxPrevState; + volatile OMX_STATETYPE iBufferSupplierPrevState; + volatile OMX_STATETYPE iNonBufferSupplierPrevState; + volatile OMX_STATETYPE iGphxPort1PrevState; + volatile OMX_STATETYPE iFilePrevState; + volatile OMX_STATETYPE iJpegEncoderPrevState; + volatile OMX_STATETYPE iXvidEncoderPrevState; + volatile OMX_STATETYPE i3gpMuxerPrevState; + volatile OMX_STATETYPE iClockPrevState; + volatile OMX_STATETYPE iImageWriterPrevState; + + RWsSession iWsSession; + RWindowGroup iWindowGroup; // Window group of the AO windows. + TInt iWindowHandle; // Window handle(s) for the AO windows. This handle + // is incremental and reused by various WServ artifacts. + CWsScreenDevice *iWsSd; // Screen Device for this WServ session. + CWindowGc *iGc; // Graphics Context associated with the window. + RWindow *iWindow; + CWindowGc *iGc2; + RWindow *iWindow2; + + RSurfaceManager iSurfaceManager; + RSurfaceUpdateSession iSurfaceUpdateSession; + RChunk iTestChunk; + TSurfaceId iSurfaceId; + CActiveScheduler* iScheduler; + }; + + +/** + * Shutdown timer for tests. + */ +class COmxGsTestShutdown : public CTimer + { +public: + + static COmxGsTestShutdown* NewL(COmxGsTestBase* aOmxGsTest,TInt aTimerId = 1); + + COmxGsTestShutdown(COmxGsTestBase* aOmxGsTest,TInt aTimerId = 1); + ~COmxGsTestShutdown(); + void ConstructL(); + void Start(TTimeIntervalMicroSeconds32 aInterval, TInt aReason, TVerdict aResult); + +private: + + void RunL(); + +private: + + COmxGsTestBase* iOmxGsTest; + TTimeIntervalMicroSeconds32 iInterval; + TInt iReason; + TVerdict iResult; + TInt iTimerId; + + }; + + +class COmxGsTestStateTransition : public CTimer + { + +public: + + static COmxGsTestStateTransition* NewL(COmxGsTestBase* aOmxGsTest,TInt aPriority); + + COmxGsTestStateTransition(COmxGsTestBase* aOmxGsTest,TInt aPriority); + ~COmxGsTestStateTransition(); + void ConstructL(); + void Start(TTimeIntervalMicroSeconds32 aInterval,const TDesC& aStateTransitionName); + +protected: + TBuf iStateTransitionName; + +private: + + void RunL(); + +private: + + COmxGsTestBase* iOmxGsTest; + TTimeIntervalMicroSeconds32 iInterval; + }; + + + +#endif // OMXILGRAPHICSINKTESTBASE_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/src/omxilmmbuffer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/src/omxilmmbuffer.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,220 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + + +/** + @file + @internalComponent +*/ + +#include "omxilmmbuffer.h" + +EXPORT_C COmxILMMBuffer* COmxILMMBuffer::NewL(const RChunk& aChunk) + { + COmxILMMBuffer* self = new (ELeave) COmxILMMBuffer(aChunk); + return self; + } + +EXPORT_C COmxILMMBuffer* COmxILMMBuffer::CreateL(const COmxILMMBuffer& aCamBuf) + { + COmxILMMBuffer* self = new (ELeave) COmxILMMBuffer(aCamBuf); + return self; + } + +EXPORT_C COmxILMMBuffer::~COmxILMMBuffer() + { + iArrayOffsets.Close(); + } + +COmxILMMBuffer::COmxILMMBuffer(const RChunk& aChunk) + : iChunk(const_cast(aChunk)), + iChunkOwnerThreadId(RThread().Id()) + { + // reset offsets + iArrayOffsets.Reset(); + } + +COmxILMMBuffer::COmxILMMBuffer(const COmxILMMBuffer& aCamBuf) +: iSurfaceId(aCamBuf.iSurfaceId), + iSurfaceInfo(aCamBuf.iSurfaceInfo), + iChunk(aCamBuf.iChunk), + iChunkOwnerThreadId(aCamBuf.iChunkOwnerThreadId) + { + // reset offsets + iArrayOffsets.Reset(); + + // deep copy + for (TInt i = 0 ; i < aCamBuf.iArrayOffsets.Count() ; i++) + { + iArrayOffsets.Append(aCamBuf.iArrayOffsets[i]); + } + } + +EXPORT_C RChunk& COmxILMMBuffer::Chunk() + { + return iChunk; + } + +EXPORT_C TSurfaceId& COmxILMMBuffer::SurfaceId() + { + return iSurfaceId; + } + +EXPORT_C TThreadId& COmxILMMBuffer::ChunkOwnerThreadId() + { + return iChunkOwnerThreadId; + } + +EXPORT_C RSurfaceManager::TSurfaceInfoV01& COmxILMMBuffer::SurfaceInfoV01() + { + return iSurfaceInfo; + } + +//EXPORT_C void COmxILMMBuffer::SetChunk(RChunk* aChunk) {iChunk = *aChunk;} +//EXPORT_C void COmxILMMBuffer::SetSurfaceId(TSurfaceId* aSurfaceId) {iSurfaceId = &aSurfacdId;} + +EXPORT_C TInt COmxILMMBuffer::BytesPerPixel(OMX_COLOR_FORMATTYPE aPixelFormat) + { + switch (aPixelFormat) + { + //fall through + + //case EUidPixelFormatRGB_565: + case OMX_COLOR_Format16bitRGB565: + //case EUidPixelFormatBGR_565: + case OMX_COLOR_Format16bitBGR565: + //case EUidPixelFormatARGB_1555: + case OMX_COLOR_Format16bitARGB1555: + //case EUidPixelFormatXRGB_1555: + //case EUidPixelFormatARGB_4444: + case OMX_COLOR_Format16bitARGB4444: + //case EUidPixelFormatARGB_8332: + case OMX_COLOR_Format8bitRGB332: + //case EUidPixelFormatBGRX_5551: + //case EUidPixelFormatBGRA_5551: + //case EUidPixelFormatBGRA_4444: + //case EUidPixelFormatBGRX_4444: + //case EUidPixelFormatAP_88: + //case EUidPixelFormatXRGB_4444: + //case EUidPixelFormatXBGR_4444: + //case EUidPixelFormatYUV_422Interleaved: + //case EUidPixelFormatYUV_422Planar: + case OMX_COLOR_FormatYUV422Planar: + //case EUidPixelFormatYUV_422Reversed: + case OMX_COLOR_FormatYCrYCb: + //case EUidPixelFormatYUV_422SemiPlanar: + case OMX_COLOR_FormatYUV422SemiPlanar: + //case EUidPixelFormatYUV_422InterleavedReversed: + //case EUidPixelFormatYYUV_422Interleaved: + case OMX_COLOR_FormatCbYCrY: + case OMX_COLOR_FormatYCbYCr: + case OMX_COLOR_FormatRawBayer10bit: + { + return 2; + } + + //fall through + //case EUidPixelFormatXRGB_8888: + //case EUidPixelFormatBGRX_8888: + //case EUidPixelFormatXBGR_8888: + //case EUidPixelFormatBGRA_8888: + case OMX_COLOR_Format32bitBGRA8888: + //case EUidPixelFormatARGB_8888: + case OMX_COLOR_Format32bitARGB8888: + //case EUidPixelFormatABGR_8888: + //case EUidPixelFormatARGB_8888_PRE: + //case EUidPixelFormatABGR_8888_PRE: + //case EUidPixelFormatBGRA_8888_PRE: + //case EUidPixelFormatARGB_2101010: + //case EUidPixelFormatABGR_2101010: + { + return 4; + } + + //fall through + //case EUidPixelFormatBGR_888: + case OMX_COLOR_Format24bitBGR888: + //case EUidPixelFormatRGB_888: + case OMX_COLOR_Format24bitRGB888: + { + return 3; + } + + default: + return 0; + } + } + +EXPORT_C TInt COmxILMMBuffer::BytesPerPixel(TUidPixelFormat aPixelFormat) + { + switch (aPixelFormat) + { + //fall through + + case EUidPixelFormatRGB_565: + case EUidPixelFormatBGR_565: + case EUidPixelFormatARGB_1555: + case EUidPixelFormatXRGB_1555: + case EUidPixelFormatARGB_4444: + case EUidPixelFormatARGB_8332: + case EUidPixelFormatBGRX_5551: + case EUidPixelFormatBGRA_5551: + case EUidPixelFormatBGRA_4444: + case EUidPixelFormatBGRX_4444: + case EUidPixelFormatAP_88: + case EUidPixelFormatXRGB_4444: + case EUidPixelFormatXBGR_4444: + case EUidPixelFormatYUV_422Interleaved: + case EUidPixelFormatYUV_422Planar: + case EUidPixelFormatYUV_422Reversed: + case EUidPixelFormatYUV_422SemiPlanar: + case EUidPixelFormatYUV_422InterleavedReversed: + case EUidPixelFormatRawBayer10bit: + { + return 2; + } + + //fall through + case EUidPixelFormatXRGB_8888: + case EUidPixelFormatBGRX_8888: + case EUidPixelFormatXBGR_8888: + case EUidPixelFormatBGRA_8888: + case EUidPixelFormatARGB_8888: + case EUidPixelFormatABGR_8888: + case EUidPixelFormatARGB_8888_PRE: + case EUidPixelFormatABGR_8888_PRE: + case EUidPixelFormatBGRA_8888_PRE: + case EUidPixelFormatARGB_2101010: + case EUidPixelFormatABGR_2101010: + { + return 4; + } + + //fall through + case EUidPixelFormatBGR_888: + case EUidPixelFormatRGB_888: + { + return 3; + } + + default: + return 0; + } + } + +EXPORT_C RArray& COmxILMMBuffer::OffsetInfoArray() + { + return iArrayOffsets; + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilgraphicsink/tsrc/src/omxilmmbuffer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilgraphicsink/tsrc/src/omxilmmbuffer.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,306 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + + +/** + @file + @internalTechnology +*/ + +#ifndef OMXILMMBUFFER_H +#define OMXILMMBUFFER_H + +#include +#include +#if 0 +// pixelformats_camera.h needs to be included before surfacemanager.h or the original +// pixelformats.h will be used for the TUidPixelFormat declaration instead of the one +// in pixelformats_camera.h and the build will fail. +//#include +#include +#else +// temporary hack to keep STE compiling even if pixelformats_camera.h is not exported +#ifndef __PIXELFORMATS_H__ +#define __PIXELFORMATS_H__ + +typedef enum + { + /** + Unknown pixel format + */ + EUidPixelFormatUnknown = 0, + /** + 32-bit RGB pixel format without alpha, with 8 bits are reserved for each color + */ + EUidPixelFormatXRGB_8888 = 0x10275496, + /** + 32-bit BGR pixel format without alpha, where 8 bits are reserved for each color + */ + EUidPixelFormatBGRX_8888 = 0x102754A8, + /** + 32-bit BGR pixel format without alpha, where 8 bits are reserved for each color + */ + EUidPixelFormatXBGR_8888 = 0x10273766, + /** + 32-bit BGRA pixel format with alpha, using 8 bits per channel + */ + EUidPixelFormatBGRA_8888 = 0x102754A9, + /** + 32-bit ARGB pixel format with alpha, using 8 bits per channel + */ + EUidPixelFormatARGB_8888 = 0x10275498, + /** + 32-bit ABGR pixel format with alpha, using 8 bits per channel + */ + EUidPixelFormatABGR_8888 = 0x10275499, + /** + 32-bit ARGB pixel format with alpha (pre-multiplied), using 8 bits per channel + */ + EUidPixelFormatARGB_8888_PRE = 0x1027549A, + /** + 32-bit ABGR pixel format with alpha (pre-multiplied), using 8 bits per channel + */ + EUidPixelFormatABGR_8888_PRE = 0x1027549B, + /** + 32-bit BGRA pixel format with alpha (pre-multiplied), using 8 bits per channel + */ + EUidPixelFormatBGRA_8888_PRE = 0x10275497, + /** + 32-bit pixel format using 10 bits each for red, green, and blue, and 2 bits for + alpha + */ + EUidPixelFormatARGB_2101010 = 0x1027549D, + /** + 32-bit pixel format using 10 bits each for blue, green, and red color and 2 + bits for alpha + */ + EUidPixelFormatABGR_2101010 = 0x1027549C, + /** + 24-bit BGR pixel format with 8 bits per channel + */ + EUidPixelFormatBGR_888 = 0x102754A7, + /** + 24-bit RGB pixel format with 8 bits per channel + */ + EUidPixelFormatRGB_888 = 0x10275495, + /** + 16-bit RGB pixel format with 5 bits for red, 6 bits for green, and 5 bits for + blue + */ + EUidPixelFormatRGB_565 = 0x1027549E, + /** + 16-bit BGR pixel format with 5 bits for blue, 6 bits for green, and 5 bits for + red + */ + EUidPixelFormatBGR_565 = 0x10273765, + /** + 16-bit pixel format where 5 bits are reserved for each color and 1 bit is + reserved for alpha + */ + EUidPixelFormatARGB_1555 = 0x1027549F, + /** + 16-bit pixel format where 5 bits are reserved for each color + */ + EUidPixelFormatXRGB_1555 = 0x102754A0, + /** + 16-bit ARGB pixel format with 4 bits for each channel + */ + EUidPixelFormatARGB_4444 = 0x102754A1, + /** + 16-bit ARGB texture format using 8 bits for alpha, 3 bits each for red and + green, and 2 bits for blue + */ + EUidPixelFormatARGB_8332 = 0x102754A4, + /** + 16-bit pixel format where 5 bits are reserved for each color + */ + EUidPixelFormatBGRX_5551 = 0x102754A5, + /** + 16-bit pixel format where 5 bits are reserved for each color and 1 bit is reserved for alpha + */ + EUidPixelFormatBGRA_5551 = 0x102754AA, + /** + 16-bit BGRA pixel format with 4 bits for each channel + */ + EUidPixelFormatBGRA_4444 = 0x102754AC, + /** + 16-bit RGB pixel format using 4 bits for each color, without alpha channel + */ + EUidPixelFormatBGRX_4444 = 0x102754A6, + /** + 16-bit color indexed with 8 bits of alpha + */ + EUidPixelFormatAP_88 = 0x102754AB, + /** + 16-bit RGB pixel format using 4 bits for each color, without alpha channel + */ + EUidPixelFormatXRGB_4444 = 0x10273764, + /** + 16-bit BGR pixel format using 4 bits for each color, without alpha channel + */ + EUidPixelFormatXBGR_4444 = 0x102754B0, + /** + 8-bit RGB texture format using 3 bits for red, 3 bits for green, and 2 bits for blue + */ + EUidPixelFormatRGB_332 = 0x102754A2, + /** + 8-bit alpha only + */ + EUidPixelFormatA_8 = 0x102754A3, + /** + 8-bit BGR texture format using 3 bits for blue, 3 bits for green, and 2 bits for red + */ + EUidPixelFormatBGR_332 = 0x102754B1, + /** + 8-bit indexed (i.e. has a palette) + */ + EUidPixelFormatP_8 = 0x10273763, + /** + 4-bit indexed (i.e. has a palette) + */ + EUidPixelFormatP_4 = 0x102754AD, + /** + 2-bit indexed (i.e. has a palette) + */ + EUidPixelFormatP_2 = 0x102754AE, + /** + 1-bit indexed (i.e. has a palette) + */ + EUidPixelFormatP_1 = 0x102754AF, + /** + YUV - 4:2:0 format, 8 bits per sample, Y00Y01Y10Y11UV. + */ + EUidPixelFormatYUV_420Interleaved = 0x10273767, + /** + YUV - Three arrays Y, U, V. 4:2:0 format, 8 bits per sample, Y00Y01Y02Y03...U0...V0... + */ + EUidPixelFormatYUV_420Planar = 0x10273768, + /** + YUV 4:2:0 image format. Planar, 12 bits per pixel, Pixel order: Y00Y01Y02Y03...V0...U0... + */ + EUidPixelFormatYUV_420PlanarReversed = 0x1027376D, + /** + YUV - Two arrays, one is all Y, the other is U and V. 4:2:0 format, 8 bits per sample, Y00Y01Y02Y03...U0V0... + */ + EUidPixelFormatYUV_420SemiPlanar = 0x1027376C, + /** + YUV - Organized as YUYV. 4:2:2 format, 8 bits per sample, UY0VY1 + */ + EUidPixelFormatYUV_422Interleaved = 0x10273769, + /** + YUV - Three arrays Y, U, V + */ + EUidPixelFormatYUV_422Planar = 0x102737DA, + /** + YUV - Organized as UYVY. 4:2:2 format, 8 bits per sample, Y0UY1V + */ + EUidPixelFormatYUV_422Reversed = 0x102754B2, + /** + YUV - Two arrays, one is all Y, the other is U and V + */ + EUidPixelFormatYUV_422SemiPlanar = 0x102754B3, + /** + YUV 4:2:2 image format. 16 bits per pixel, 8 bits per sample, Pixel order: Y1VY0U. + */ + EUidPixelFormatYUV_422InterleavedReversed = 0x1027376A, + /** + YUV 4:2:2 image format. Interleaved, 16 bits per pixel, 8 bits per sample, Pixel order: Y0Y1UV. + */ + EUidPixelFormatYUV_422Interleaved16bit = 0x102737D9, + /** + YUV - 4:4:4 format, each pixel contains equal parts YUV + */ + EUidPixelFormatYUV_444Interleaved = 0x1027376B, + /** + YUV - 4:4:4 format, three arrays Y, U, V + */ + EUidPixelFormatYUV_444Planar = 0x102737DB, + /** + 8-bit grayscale. + */ + EUidPixelFormatL_8 = 0x102858EC, + /** + 4-bit grayscale. + */ + EUidPixelFormatL_4 = 0x102858ED, + /** + 2-bit grayscale. + */ + EUidPixelFormatL_2 = 0x102858EE, + /** + 1-bit grayscale (monochrome). + */ + EUidPixelFormatL_1 = 0x102858EF, + /** + Speed Tagged JPEG + */ + EUidPixelFormatSpeedTaggedJPEG = 0x102869FB, + /** + JPEG + */ + EUidPixelFormatJPEG = 0x102869FC, + + /** + Temporary addition of RAW formats. + Needs to be done in pixelformats.h by Base. + */ + EUidPixelFormatRawBayer8bit = 0x102869FD, + EUidPixelFormatRawBayer10bit = 0x102869FE, + EUidPixelFormatRawBayer8compressed = 0x102869FF + + } TUidPixelFormat; + +#endif +#endif + +#include +#include +#include + +class COmxILMMBuffer : public CBase + { + +public: + IMPORT_C static COmxILMMBuffer* NewL(const RChunk& aChunk); + IMPORT_C static COmxILMMBuffer* CreateL(const COmxILMMBuffer& aCamBuf); + + IMPORT_C ~COmxILMMBuffer(); + + IMPORT_C RChunk& Chunk(); + IMPORT_C TSurfaceId& SurfaceId(); + IMPORT_C TThreadId& ChunkOwnerThreadId(); + + //This function will be called by OMX_GraphicsSink Component during AllocateBuffer. + IMPORT_C RSurfaceManager::TSurfaceInfoV01& SurfaceInfoV01(); + IMPORT_C static TInt BytesPerPixel(OMX_COLOR_FORMATTYPE aPixelFormat); + IMPORT_C static TInt BytesPerPixel(TUidPixelFormat aPixelFormat); + + // to maintain offset aligned with buffer ID + IMPORT_C RArray& OffsetInfoArray(); + +private: + COmxILMMBuffer(const RChunk& aChunk); + COmxILMMBuffer(const COmxILMMBuffer& aCamBuf); + +private: + TSurfaceId iSurfaceId; + RSurfaceManager::TSurfaceInfoV01 iSurfaceInfo; + RChunk& iChunk; + TThreadId iChunkOwnerThreadId; + + RArray iArrayOffsets; + }; + +#endif //OMXILMMBUFFER_H diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/group/bld.inf Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +PRJ_PLATFORMS +BASEDEFAULT + +PRJ_EXPORTS +// The export of the IBY is deliberately not guarded by #ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED so that it +// can always be #included by other IBYs/OBYs. However, if NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED is not defined +// then the IBY will effectively be empty and not include anything in the ROM. + +omxilvideoscheduler.iby /epoc32/rom/include/omxilvideoscheduler.iby + +PRJ_MMPFILES +#ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED +omxilvideoscheduler.mmp +#endif // NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/group/omxilvideoscheduler.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/group/omxilvideoscheduler.iby Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +#ifndef OMXILVIDEOSCHEDULER_IBY +#define OMXILVIDEOSCHEDULER_IBY + +#ifdef NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED + +#include + +ECOM_PLUGIN(omxilvideoscheduler.dll, omxilvideoscheduler.rsc) + +data=ZRESOURCE\videoscheduler\videoscheduler.rsc resource\videoscheduler\videoscheduler.rsc + +#endif // NCP_COMMON_OMXIL_SHAI_SUPPORT_ENABLED + +#endif // OMXILVIDEOSCHEDULER_IBY diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/group/omxilvideoscheduler.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/group/omxilvideoscheduler.mmp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include "../src/omxilvideoscheduler.hrh" + +TARGET omxilvideoscheduler.dll +CAPABILITY ALL -TCB +TARGETTYPE PLUGIN +UID 0x10009D8D KUidSymbianOmxILVideoSchedulerDll +VENDORID 0x70000001 + +USERINCLUDE ../src + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + + +SOURCEPATH ../src + +SOURCE buffercopier.cpp +SOURCE buffercopierstatemonitor.cpp +SOURCE comxilvideoscheduler.cpp +SOURCE comxilvideoschedulerinputport.cpp +SOURCE comxilvideoscheduleroutputport.cpp +SOURCE comxilvideoschedulerpf.cpp +SOURCE resourcefilereader.cpp + +RESOURCE omxilvideoscheduler.rss + +START RESOURCE videoscheduler.rss +TARGETPATH resource/videoscheduler +HEADER +END + +nostrictdef + +LIBRARY euser.lib bafl.lib efsrv.lib inetprotutil.lib ecom.lib +LIBRARY omxilcomponentcommon.lib +STATICLIBRARY omxilcomponentif.lib + +// Uncomment to activate debug tracing in this module +// MACRO _OMXIL_COMMON_DEBUG_TRACING_ON diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/buffercopier.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/buffercopier.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,200 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include "buffercopier.h" + +_LIT(KBufferCopierPanic, "CBufferCopier"); + +CBufferCopier* CBufferCopier::NewL(MBufferCopierIf& aCallback, TInt aMaxBuffers) + { + CBufferCopier* self = new(ELeave) CBufferCopier(aCallback); + CleanupStack::PushL(self); + self->ConstructL(aMaxBuffers); + CleanupStack::Pop(self); + return self; + } + +CBufferCopier::CBufferCopier(MBufferCopierIf& aCallback): +CActive(EPriorityNormal), +iCallback(aCallback) + { + CActiveScheduler::Add(this); + } + +void CBufferCopier::ConstructL(TInt aMaxBuffers) + { + User::LeaveIfError(iInQueue.CreateLocal(aMaxBuffers)); + User::LeaveIfError(iOutQueue.CreateLocal(aMaxBuffers)); + User::LeaveIfError(iRemoveQueue.CreateLocal(aMaxBuffers)); + SetActive(); + iInQueue.NotifyDataAvailable(iStatus); + } + +CBufferCopier::~CBufferCopier() + { + Cancel(); + iInQueue.Close(); + iOutQueue.Close(); + iRemoveQueue.Close(); + } + +void CBufferCopier::DeliverBuffer(OMX_BUFFERHEADERTYPE* aBuffer, OMX_DIRTYPE aDirection) + { + RMsgQueue& queue = aDirection == OMX_DirInput ? iInQueue : iOutQueue; + TInt err = queue.Send(aBuffer); + // do not expect error as maximum buffer count already allocated + if(err != KErrNone) + { + User::Panic(KBufferCopierPanic, err); + } + } + +void CBufferCopier::RunL() + { + if(iInBuffer == NULL) + { + // ignore error, if KErrUnderflow then we go back to waiting on iInQueue + iInQueue.Receive(iInBuffer); + } + else + { + OMX_BUFFERHEADERTYPE* outBuffer = NULL; + TInt err = iOutQueue.Receive(outBuffer); + // if KErrUnderflow then we go back to waiting on iOutQueue + if(err == KErrNone) + { + CopyBuffer(iInBuffer, outBuffer); + iInBuffer = NULL; + } + } + + SetActive(); + if(iInBuffer == NULL) + { + iInQueue.NotifyDataAvailable(iStatus); + } + else + { + iOutQueue.NotifyDataAvailable(iStatus); + } + } + +void CBufferCopier::DoCancel() + { + iInQueue.CancelDataAvailable(); + iOutQueue.CancelDataAvailable(); + } + +void CBufferCopier::CopyBuffer(OMX_BUFFERHEADERTYPE* aInBuffer, OMX_BUFFERHEADERTYPE* aOutBuffer) + { + aOutBuffer->nOffset = 0; + TPtr8 desPtr(aOutBuffer->pBuffer, aOutBuffer->nAllocLen); + desPtr.Copy(aInBuffer->pBuffer + aInBuffer->nOffset, aInBuffer->nFilledLen); + + aOutBuffer->nFilledLen = aInBuffer->nFilledLen; + aOutBuffer->hMarkTargetComponent = aInBuffer->hMarkTargetComponent; + aOutBuffer->pMarkData = aInBuffer->pMarkData; + aOutBuffer->nTickCount = aInBuffer->nTickCount; + aOutBuffer->nTimeStamp = aInBuffer->nTimeStamp; + aOutBuffer->nFlags = aInBuffer->nFlags; + + iCallback.MbcBufferCopied(aInBuffer, aOutBuffer); + } + +TBool CBufferCopier::RemoveBuffer(OMX_BUFFERHEADERTYPE* aBuffer, OMX_DIRTYPE aDirection) + { + switch(aDirection) + { + case OMX_DirInput: + { + if(aBuffer == iInBuffer) + { + // also check the slot used for storing the input buffer when waiting for an output buffer + iInBuffer = NULL; + return ETrue; + } + else + { + return RemoveFromQueue(iInQueue, aBuffer); + } + } + case OMX_DirOutput: + return RemoveFromQueue(iOutQueue, aBuffer); + default: + User::Panic(KBufferCopierPanic, KErrArgument); + return EFalse; // prevent compiler warning + } + } + +void CBufferCopier::FlushBuffers(OMX_DIRTYPE aDirection) + { + OMX_BUFFERHEADERTYPE* buffer; + if(aDirection == OMX_DirInput) + { + if(iInBuffer) + { + iCallback.MbcBufferFlushed(iInBuffer, OMX_DirInput); + iInBuffer = NULL; + } + + while(iInQueue.Receive(buffer) != KErrUnderflow) + { + iCallback.MbcBufferFlushed(buffer, OMX_DirInput); + } + } + else if(aDirection == OMX_DirOutput) + { + while(iOutQueue.Receive(buffer) != KErrUnderflow) + { + iCallback.MbcBufferFlushed(buffer, OMX_DirOutput); + } + } + else + { + User::Panic(KBufferCopierPanic, KErrArgument); + } + } + +TBool CBufferCopier::RemoveFromQueue(RMsgQueue& aQueue, OMX_BUFFERHEADERTYPE* aBufferHeader) + { + TBool removed = EFalse; + OMX_BUFFERHEADERTYPE* bufferHeader = NULL; + while(aQueue.Receive(bufferHeader) != KErrUnderflow) + { + if(bufferHeader != aBufferHeader) + { + TInt err = iRemoveQueue.Send(bufferHeader); + __ASSERT_DEBUG(err == KErrNone, User::Panic(KBufferCopierPanic, err)); + } + else + { + removed = ETrue; + } + } + while(iRemoveQueue.Receive(bufferHeader) != KErrUnderflow) + { + TInt err = aQueue.Send(bufferHeader); + __ASSERT_DEBUG(err == KErrNone, User::Panic(KBufferCopierPanic, err)); + } + return removed; + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/buffercopier.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/buffercopier.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef BUFFERCOPIER_H_ +#define BUFFERCOPIER_H_ + +#include +#include +#include + +class MBufferCopierIf + { +public: + /** Called when the buffer copier has transferred the data from an input buffer to an output buffer. */ + virtual void MbcBufferCopied(OMX_BUFFERHEADERTYPE* aInBuffer, OMX_BUFFERHEADERTYPE* aOutBuffer) = 0; + /** Called when a buffer is flushed from the buffer copier. */ + virtual void MbcBufferFlushed(OMX_BUFFERHEADERTYPE* aBuffer, OMX_DIRTYPE aDirection) = 0; + }; + +class CBufferCopier : public CActive + { +public: + static CBufferCopier* NewL(MBufferCopierIf& aCallback, TInt aMaxBuffers); + ~CBufferCopier(); + + void DeliverBuffer(OMX_BUFFERHEADERTYPE* aBuffer, OMX_DIRTYPE aDirection); + TBool RemoveBuffer(OMX_BUFFERHEADERTYPE* aBuffer, OMX_DIRTYPE aDirection); + void FlushBuffers(OMX_DIRTYPE aDirection); + +protected: + void RunL(); + void DoCancel(); + +private: + CBufferCopier(MBufferCopierIf& aCallback); + void ConstructL(TInt aMaxBuffers); + + void CopyBuffer(OMX_BUFFERHEADERTYPE* aInBuffer, OMX_BUFFERHEADERTYPE* aOutBuffer); + TBool RemoveFromQueue(RMsgQueue& aQueue, OMX_BUFFERHEADERTYPE* aBufferHeader); + + MBufferCopierIf& iCallback; + RMsgQueue iInQueue; + RMsgQueue iOutQueue; + RMsgQueue iRemoveQueue; + OMX_BUFFERHEADERTYPE* iInBuffer; + }; + +#endif /*BUFFERCOPIER_H_*/ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/buffercopierstatemonitor.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/buffercopierstatemonitor.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,161 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ +#include "buffercopier.h" +#include "comxilvideoscheduler.h" +#include "buffercopierstatemonitor.h" +#include "log.h" + +CBufferCopierStateMonitor* CBufferCopierStateMonitor::NewL(MBufferCopierIf& aCallback, COmxILVideoScheduler& aComponent) + { + CBufferCopierStateMonitor* self = new (ELeave) CBufferCopierStateMonitor(aCallback, aComponent); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +CBufferCopierStateMonitor::CBufferCopierStateMonitor(MBufferCopierIf& aCallback, COmxILVideoScheduler& aComponent) : +CActive(EPriorityNormal), +iCallback(aCallback), +iComponent(aComponent), +iState(ENull) + { + CActiveScheduler::Add(this); + } + +CBufferCopierStateMonitor::~CBufferCopierStateMonitor() + { + Cancel(); + delete iBufferCopier; + } + +void CBufferCopierStateMonitor::ConstructL() + { + RThread me; + iConstructionThreadId = me.Id(); + + iStatus = KRequestPending; + SetActive(); + } + +void CBufferCopierStateMonitor::RunL() + { + iStatus = KRequestPending; + SetActive(); + + TInt err = DoSetState(); + + TRequestStatus *status = iCallingStatus; + RThread callingThread; + callingThread.Open(iCallingThreadId); + callingThread.RequestComplete(status, err); + callingThread.Close(); + } + +void CBufferCopierStateMonitor::DoCancel() + { + TRequestStatus* pStat = &iStatus; + User::RequestComplete(pStat, KErrCancel); + } + +TInt CBufferCopierStateMonitor::RunError(TInt aError) + { + DEBUG_PRINTF2(_L8("CBufferCopierStateMonitor::RunError %d"), aError); + aError=KErrNone; //Do not want to panic the server! + return aError; + } + +TInt CBufferCopierStateMonitor::SetState(TPFState aState) + { + DEBUG_PRINTF(_L8("CBufferCopierStateMonitor::SetState")); + + TInt err = KErrNone; + iState = aState; + + RThread me; + if(me.Id() != iConstructionThreadId) + { + // in different thread to that which 'this' was constructed + err = DoRequest(); + } + else + { + // in same thread to that which 'this' was constructed therefore + // active scheduler must exist and following call is safe + err = DoSetState(); + } + + return err; + } + +TInt CBufferCopierStateMonitor::DoSetState() + { + DEBUG_PRINTF(_L8("CBufferCopierStateMonitor::DoSetState")); + + TInt err = KErrNone; + + switch(iState) + { + case ESubLoadedToIdle: + iMaxBuffers = iComponent.BufferCount(); + delete iBufferCopier; + iBufferCopier = NULL; + TRAP(err, iBufferCopier = CBufferCopier::NewL(iCallback, iMaxBuffers)); + break; + case ESubIdleToLoaded: + delete iBufferCopier; + iBufferCopier = NULL; + break; + default: + break; + }; + + return err; + } + +TInt CBufferCopierStateMonitor::DoRequest() + { + DEBUG_PRINTF(_L8("CBufferCopierStateMonitor::DoRequest")); + + RThread me; + iCallingThreadId = me.Id(); + TRequestStatus requestStatus = KRequestPending; + iCallingStatus = &requestStatus; + + // send request to active scheduler thread + RThread schedulerThread; + TInt error = schedulerThread.Open(iConstructionThreadId); + if(error != KErrNone) + { + return error; + } + + TRequestStatus* schedulerRequest = &iStatus; + schedulerThread.RequestComplete(schedulerRequest, KErrNone); + schedulerThread.Close(); + + // block until request completes + User::WaitForRequest(requestStatus); + + return requestStatus.Int(); + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/buffercopierstatemonitor.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/buffercopierstatemonitor.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ +#ifndef BUFFERCOPIERSTATEMONITOR_H_ +#define BUFFERCOPIERSTATEMONITOR_H_ + +#include +#include + +class MBufferCopierIf; +class CBufferCopier; +class COmxILVideoScheduler; + + +class CBufferCopierStateMonitor : public CActive + { +public: + enum TPFState + { + ENull =0, + EExecuting, + EPause, + ESubLoadedToIdle, + ESubIdleToLoaded + }; +public: + static CBufferCopierStateMonitor* NewL(MBufferCopierIf& aCallback, COmxILVideoScheduler& aComponent); + ~CBufferCopierStateMonitor(); + TInt SetState(TPFState aState); + CBufferCopier* BufferCopier(){return iBufferCopier;} + +protected: + void RunL(); + void DoCancel(); + TInt RunError(TInt aError); + +private: + CBufferCopierStateMonitor(MBufferCopierIf& aCallback, COmxILVideoScheduler& aComponent); + void ConstructL(); + TInt DoSetState(); + TInt DoRequest(); + +private: + MBufferCopierIf& iCallback; + COmxILVideoScheduler& iComponent; + TInt iMaxBuffers; + CBufferCopier* iBufferCopier; + TPFState iState; + //Members to make the component thread safe. + TThreadId iConstructionThreadId; + TRequestStatus* iCallingStatus; // not owned + TThreadId iCallingThreadId; + }; + + +#endif /* BUFFERCOPIERSTATEMONITOR_H_ */ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/comxilvideoscheduler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/comxilvideoscheduler.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,237 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include +#include +#include +#include +#include + +#include "comxilvideoscheduler.h" +#include "comxilvideoschedulerinputport.h" +#include "comxilvideoscheduleroutputport.h" +#include "comxilvideoschedulerpf.h" +#include "omxilvideoscheduler.hrh" + +const OMX_U32 KInputPortIndex = 0; +const OMX_U32 KOutputPortIndex = 1; +const OMX_U32 KClockPortIndex = 2; + +_LIT8(KSymbianOmxILVideoSchedulerName, "OMX.SYMBIAN.VIDEO.VIDEOSCHEDULER"); +_LIT8(KSymbianOmxILVideoSchedulerRole, "video_scheduler.binary"); + +OMXIL_COMPONENT_ECOM_ENTRYPOINT(KUidSymbianOmxILVideoScheduler); + +OMX_ERRORTYPE SymbianErrorToOmx(TInt aError); + +// Component Entry Point +OMX_ERRORTYPE OMX_ComponentInit(OMX_HANDLETYPE aComponent) + { + TInt err = COmxILVideoScheduler::CreateComponent(aComponent); + return SymbianErrorToOmx(err); + } + +TInt COmxILVideoScheduler::CreateComponent(OMX_HANDLETYPE aComponent) + { + COmxILVideoScheduler* self = new COmxILVideoScheduler(); + + if (!self) + { + return KErrNoMemory; + } + + TRAPD(err, self->ConstructL(aComponent)); + if(err) + { + delete self; + } + return err; + } + +COmxILVideoScheduler::COmxILVideoScheduler() + { + // nothing to do + } + +void COmxILVideoScheduler::ConstructL(OMX_HANDLETYPE hComponent) + { + // STEP 1: Initialize the data received from the IL Core + COmxILComponent::ConstructL(hComponent); + + // STEP 2: Create the callback manager + // In context callback manager is used since we need output buffers to be received at the sink + // component immediately after we decide to send them. + // Also, returning clock buffers imediately avoids clock buffer starvation + MOmxILCallbackNotificationIf* callbackNotificationIf = CreateCallbackManagerL(COmxILComponent::EOutofContext); + + + // STEP 3: Create the Processing Function... + COmxILVideoSchedulerPF* pProcessingFunction = COmxILVideoSchedulerPF::NewL(*callbackNotificationIf, *this, GetHandle()); + RegisterProcessingFunction(pProcessingFunction); + + // STEP 4: Create Port manager... + CreatePortManagerL(COmxILComponent::ENonBufferSharingPortManager, + TOmxILSpecVersion(), // OMX Version + 0, // The number of audio ports in this component + 0, // The starting audio port index + 0, // The number of image ports in this component + 0, // The starting image port index + 2, // The number of video ports in this component + 0, // The starting video port index + 1, // The number of other ports in this component + 2 // The starting other port index + ); + + // create the input port + AddInputVideoPortL(); + AddOutputVideoPortL(); + AddClockPortL(); + + // STEP 5: Create the non-port related configuration manager... + RPointerArray roleList; + CleanupClosePushL(roleList); + roleList.AppendL(&KSymbianOmxILVideoSchedulerRole); + COmxILConfigManager* pConfigManager = COmxILConfigManager::NewL( + KSymbianOmxILVideoSchedulerName, + TOmxILSpecVersion(), + roleList); + CleanupStack::PopAndDestroy(); + RegisterConfigurationManager(pConfigManager); + + // And finally, let's get everything started + InitComponentL(); + } + +COmxILVideoScheduler::~COmxILVideoScheduler() + { + } + +void COmxILVideoScheduler::AddInputVideoPortL() + { + TOmxILSpecVersion specVersion; + + TOmxILCommonPortData portData( + specVersion, + KInputPortIndex, + OMX_DirInput, + 1, // minimum number of buffers + 1, // minimum buffer size, in bytes + OMX_PortDomainVideo, + OMX_FALSE, // do not need contigious buffers + 1, // 1-byte alignment + OMX_BufferSupplyInput, + KOutputPortIndex); + + iVideoInputPort = COmxILVideoSchedulerInputPort::NewL(portData); + CleanupStack::PushL(iVideoInputPort); + User::LeaveIfError(AddPort(iVideoInputPort, OMX_DirInput)); + CleanupStack::Pop(); + } + +void COmxILVideoScheduler::AddOutputVideoPortL() + { + TOmxILSpecVersion specVersion; + + TOmxILCommonPortData portData( + specVersion, + KOutputPortIndex, + OMX_DirOutput, + 1, // minimum number of buffers + 1, // minimum buffer size, in bytes + OMX_PortDomainVideo, + OMX_FALSE, // do not need contigious buffers + 1, // 1-byte alignment + OMX_BufferSupplyInput, + COmxILPort::KBufferMarkPropagationPortNotNeeded); + + iVideoOutputPort = COmxILVideoSchedulerOutputPort::NewL(portData); + CleanupStack::PushL(iVideoOutputPort); + User::LeaveIfError(AddPort(iVideoOutputPort, OMX_DirOutput)); + CleanupStack::Pop(); + } + +void COmxILVideoScheduler::AddClockPortL() + { + TOmxILSpecVersion specVersion; + + TOmxILCommonPortData portData( + specVersion, + KClockPortIndex, + OMX_DirInput, + 4, // minimum number of buffers + sizeof(OMX_TIME_MEDIATIMETYPE), // minimum buffer size, in bytes + OMX_PortDomainOther, + OMX_TRUE, // contigious buffers + 4, // 4-byte alignment + OMX_BufferSupplyOutput, + COmxILPort::KBufferMarkPropagationPortNotNeeded); + + RArray array; + CleanupClosePushL(array); + array.AppendL(OMX_OTHER_FormatTime); + iClockPort = COmxILClientClockPort::NewL(portData, array); + CleanupStack::PopAndDestroy(&array); + CleanupStack::PushL(iClockPort); + User::LeaveIfError(AddPort(iClockPort, OMX_DirInput)); + CleanupStack::Pop(); + } + +/** Returns the maximum number of buffers configured on a port. */ +TUint32 COmxILVideoScheduler::BufferCount() const + { + // due to buffer copying we do not need the same number of buffers on each port, + // so to be safe the maximum count is used when allocating queues. + // when buffer sharing is added, the buffer counts must be checked to be the same on + // the Loaded->Idle phase. + TUint32 in = iVideoInputPort->BufferCount(); + TUint32 out = iVideoOutputPort->BufferCount(); + return in > out ? in : out; + } + +OMX_ERRORTYPE COmxILVideoScheduler::MediaTimeRequest(TAny* apPrivate, OMX_TICKS aMediaTime, OMX_TICKS aOffset) + { + return iClockPort->MediaTimeRequest(apPrivate, aMediaTime, aOffset); + } + +OMX_ERRORTYPE COmxILVideoScheduler::GetWallTime(OMX_TICKS& aWallTime) + { + return iClockPort->GetWallTime(aWallTime); + } + +OMX_ERRORTYPE COmxILVideoScheduler::SetVideoStartTime(OMX_TICKS aStartTime) + { + return iClockPort->SetStartTime(aStartTime); + } + +OMX_ERRORTYPE SymbianErrorToOmx(TInt aError) + { + switch(aError) + { + case KErrNone: + return OMX_ErrorNone; + case KErrNoMemory: + return OMX_ErrorInsufficientResources; + default: + return OMX_ErrorUndefined; + } + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/comxilvideoscheduler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/comxilvideoscheduler.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef COMXILVIDEOSCHEDULER_H_ +#define COMXILVIDEOSCHEDULER_H_ + +#include + +class COmxILVideoSchedulerInputPort; +class COmxILVideoSchedulerOutputPort; +class COmxILClientClockPort; + + +NONSHARABLE_CLASS(COmxILVideoScheduler) : public COmxILComponent + { +public: + static TInt CreateComponent(OMX_HANDLETYPE hComponent); + ~COmxILVideoScheduler(); + + TUint32 BufferCount() const; + OMX_ERRORTYPE MediaTimeRequest(TAny* apPrivate, OMX_TICKS aMediaTime, OMX_TICKS aOffset); + OMX_ERRORTYPE GetWallTime(OMX_TICKS& aWallTime); + OMX_ERRORTYPE SetVideoStartTime(OMX_TICKS aStartTime); + +private: + COmxILVideoScheduler(); + void ConstructL(OMX_HANDLETYPE aComponent); + + void AddOutputVideoPortL(); + void AddInputVideoPortL(); + void AddClockPortL(); + +private: + COmxILVideoSchedulerOutputPort* iVideoOutputPort; //not owned + COmxILVideoSchedulerInputPort* iVideoInputPort;//not owned + COmxILClientClockPort* iClockPort; //not owned + }; + +#endif /*COMXILVIDEOSCHEDULER_H_*/ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/comxilvideoschedulerinputport.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/comxilvideoschedulerinputport.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,200 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include "comxilvideoschedulerinputport.h" +#include "omxilvideoschedulerextensionsindexes.h" + + +COmxILVideoSchedulerInputPort* COmxILVideoSchedulerInputPort::NewL(const TOmxILCommonPortData& aCommonPortData) + { + // TODO these arrays must left empty, to be removed from the video port constructor + RArray supportedCodings; + RArray supportedColorFormats; + + CleanupClosePushL(supportedCodings); + CleanupClosePushL(supportedColorFormats); + + COmxILVideoSchedulerInputPort* self = new(ELeave) COmxILVideoSchedulerInputPort(); + CleanupStack::PushL(self); + self->ConstructL(aCommonPortData, supportedCodings, supportedColorFormats); + CleanupStack::Pop(self); + + CleanupStack::PopAndDestroy(2, &supportedCodings); + + return self; + } + + +COmxILVideoSchedulerInputPort::COmxILVideoSchedulerInputPort() + { + } + +void COmxILVideoSchedulerInputPort::ConstructL(const TOmxILCommonPortData& aCommonPortData, + const RArray& aSupportedCodings, + const RArray& aSupportedColourFormats) + { + COmxILVideoPort::ConstructL(aCommonPortData, aSupportedCodings, aSupportedColourFormats); + // Port definition mime type. Mime type is not relevant for uncompressed video frames + iMimeTypeBuf.CreateL(KNullDesC8(), KNullDesC8().Length() + 1); + TUint8* pTUint = const_cast(iMimeTypeBuf.PtrZ()); + GetParamPortDefinition().format.video.cMIMEType = reinterpret_cast(pTUint); + + iParamVideoScheDropFrame.nSize = sizeof(OMX_NOKIA_PARAM_DROPPEDFRAMEEVENT); + iParamVideoScheDropFrame.nVersion = TOmxILSpecVersion(); + iParamVideoScheDropFrame.nPortIndex = GetParamPortDefinition().nPortIndex; + iParamVideoScheDropFrame.bEnabled = OMX_FALSE; + + GetSupportedVideoFormats().AppendL(OMX_VIDEO_CodingUnused); + GetSupportedColorFormats().AppendL(OMX_COLOR_FormatUnused); + } + +COmxILVideoSchedulerInputPort::~COmxILVideoSchedulerInputPort() + { + iMimeTypeBuf.Close(); + } + +OMX_ERRORTYPE COmxILVideoSchedulerInputPort::GetLocalOmxParamIndexes(RArray& aIndexArray) const + { + OMX_ERRORTYPE omxRetValue = COmxILVideoPort::GetLocalOmxParamIndexes(aIndexArray); + if(omxRetValue != OMX_ErrorNone) + { + return omxRetValue; + } + + TInt err = aIndexArray.InsertInOrder(OMX_NokiaIndexParamDroppedFrameEvent); + + if (err != KErrNone && err != KErrAlreadyExists) + { + return OMX_ErrorInsufficientResources; + } + + return OMX_ErrorNone; + } + +OMX_ERRORTYPE COmxILVideoSchedulerInputPort::GetLocalOmxConfigIndexes(RArray& aIndexArray) const + { + return COmxILVideoPort::GetLocalOmxConfigIndexes(aIndexArray); + } + +/** +This method provides the current values for the parameters present in the structure represented by the given index. + +@param aParamIndex The specific param index for which the current parameter values are required. + apComponentParameterStructure The pointer to the structure which will be updated to provide the current parameter values. + +@return OMX_ErrorNone if successful; + OMX_ErrorNoMore if no more formats; + OMX_ErrorUnsupportedSetting if unsupported setting is passed; +*/ +OMX_ERRORTYPE COmxILVideoSchedulerInputPort::GetParameter(OMX_INDEXTYPE aParamIndex,TAny* apComponentParameterStructure) const + { + if(aParamIndex == OMX_NokiaIndexParamDroppedFrameEvent) + { + OMX_NOKIA_PARAM_DROPPEDFRAMEEVENT* dropFrame = static_cast(apComponentParameterStructure); + *dropFrame = iParamVideoScheDropFrame; + return OMX_ErrorNone; + } + else + { + // Try the parent's indexes + return COmxILVideoPort::GetParameter(aParamIndex,apComponentParameterStructure); + } + } + +/** +This method sets the values of the parameters present in the structure represented by the given index. + +@param aParamIndex The specific param index for which the parameter values have to be set. + apComponentParameterStructure The pointer to the structure which will provide the desired parameter values to be set. + aUpdateProcessingFunction informs whether the processing function needs to be updated. + +@return OMX_ErrorNone if successful; + OMX_ErrorUnsupportedSetting if non-zero framerate value; + OMX_ErrorUnsupportedIndex if request OMX_NokiaIndexParamDroppedFrameEvent index; +*/ +OMX_ERRORTYPE COmxILVideoSchedulerInputPort::SetParameter(OMX_INDEXTYPE aParamIndex,const TAny* apComponentParameterStructure, TBool& aUpdateProcessingFunction) + { + if(aParamIndex == OMX_NokiaIndexParamDroppedFrameEvent) + { + const OMX_NOKIA_PARAM_DROPPEDFRAMEEVENT *portParameterStructure = static_cast(apComponentParameterStructure); + if (iParamVideoScheDropFrame.bEnabled != portParameterStructure->bEnabled) + { + iParamVideoScheDropFrame.bEnabled = portParameterStructure->bEnabled; + aUpdateProcessingFunction = ETrue; + } + return OMX_ErrorNone; + } + + // Try the parent's indexes + return COmxILVideoPort::SetParameter(aParamIndex, apComponentParameterStructure, aUpdateProcessingFunction); + } + + +OMX_ERRORTYPE COmxILVideoSchedulerInputPort::SetFormatInPortDefinition(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition, + TBool& /*aUpdateProcessingFunction*/) + { + GetParamPortDefinition().format.video = aPortDefinition.format.video; + TUint8* pTUint = const_cast(iMimeTypeBuf.PtrZ()); + GetParamPortDefinition().format.video.cMIMEType = reinterpret_cast(pTUint); + GetParamPortDefinition().format.video.nSliceHeight = GetParamPortDefinition().format.video.nFrameHeight; + GetParamPortDefinition().nBufferSize = GetParamPortDefinition().format.video.nStride * GetParamPortDefinition().format.video.nSliceHeight; + return OMX_ErrorNone; + } + +TBool COmxILVideoSchedulerInputPort::IsTunnelledPortCompatible(const OMX_PARAM_PORTDEFINITIONTYPE& /*aPortDefinition*/) const + { + // TODO (The base class should do this checking) + return ETrue; + } + +/** Returns the number of buffers configured on this port. */ +TUint32 COmxILVideoSchedulerInputPort::BufferCount() const + { + return GetParamPortDefinition().nBufferCountActual; + } + +/** +This method provides the index type represented by the given parameter name. + +@param aParameterName The name of extention parameter to be retrieved. + apIndexType The pointer which will retrieve the required index. + +@return OMX_ErrorNone if successful; + OMX_ErrorUnsupportedIndex if unsupported parameter name is passed; +*/ +OMX_ERRORTYPE COmxILVideoSchedulerInputPort::GetExtensionIndex(OMX_STRING aParameterName, OMX_INDEXTYPE* apIndexType) const + { + TPtrC8 receivedParameterName(const_cast(reinterpret_cast(aParameterName))); + + TPtrC8 parameterName(reinterpret_cast(sOmxNokiaIndexParamDroppedFrameEvent)); + + if (receivedParameterName == parameterName) + { + *apIndexType = static_cast(OMX_NokiaIndexParamDroppedFrameEvent); + return OMX_ErrorNone; + } + + *apIndexType = OMX_IndexMax; + return OMX_ErrorUnsupportedIndex; + } + diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/comxilvideoschedulerinputport.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/comxilvideoschedulerinputport.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef COMXILVIDEOSCHEDULERINPUTPORT_H_ +#define COMXILVIDEOSCHEDULERINPUTPORT_H_ + +#include +#include + +NONSHARABLE_CLASS(COmxILVideoSchedulerInputPort) : public COmxILVideoPort + { +public: + static COmxILVideoSchedulerInputPort* NewL(const TOmxILCommonPortData& aCommonPortData); + + ~COmxILVideoSchedulerInputPort(); + + TUint32 BufferCount() const; + + // from COmxILVideoPort + OMX_ERRORTYPE GetLocalOmxParamIndexes(RArray& aIndexArray) const; + OMX_ERRORTYPE GetLocalOmxConfigIndexes(RArray& aIndexArray) const; + OMX_ERRORTYPE GetParameter(OMX_INDEXTYPE aParamIndex, TAny* apComponentParameterStructure) const; + OMX_ERRORTYPE SetParameter(OMX_INDEXTYPE aParamIndex, const TAny* apComponentParameterStructure, + TBool& aUpdateProcessingFunction); + OMX_ERRORTYPE GetExtensionIndex(OMX_STRING aParameterName, OMX_INDEXTYPE* apIndexType) const; +protected: + OMX_ERRORTYPE SetFormatInPortDefinition(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition, + TBool& aUpdateProcessingFunction); + + TBool IsTunnelledPortCompatible(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition) const; + +private: + COmxILVideoSchedulerInputPort(); + + void ConstructL(const TOmxILCommonPortData& aCommonPortData, + const RArray& aSupportedCodings, + const RArray& aSupportedColourFormats); + +private: + RBuf8 iMimeTypeBuf; + // Extension to provide a structure for generating the video scheduler dropping frame error + OMX_NOKIA_PARAM_DROPPEDFRAMEEVENT iParamVideoScheDropFrame; + }; + +#endif /*COMXILVIDEOSCHEDULERINPUTPORT_H_*/ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/comxilvideoscheduleroutputport.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/comxilvideoscheduleroutputport.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,111 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include "comxilvideoscheduleroutputport.h" + + +COmxILVideoSchedulerOutputPort* COmxILVideoSchedulerOutputPort::NewL(const TOmxILCommonPortData& aCommonPortData) + { + // TODO these arrays must left empty, to be removed from the video port constructor + RArray supportedCodings; + RArray supportedColorFormats; + CleanupClosePushL(supportedCodings); + CleanupClosePushL(supportedColorFormats); + + COmxILVideoSchedulerOutputPort* self = new(ELeave) COmxILVideoSchedulerOutputPort(); + CleanupStack::PushL(self); + self->ConstructL(aCommonPortData, supportedCodings, supportedColorFormats); + CleanupStack::Pop(self); + + CleanupStack::PopAndDestroy(2, &supportedCodings); + + return self; + } + +COmxILVideoSchedulerOutputPort::COmxILVideoSchedulerOutputPort() + { + } + +COmxILVideoSchedulerOutputPort::~COmxILVideoSchedulerOutputPort() + { + iMimeTypeBuf.Close(); + } + +void COmxILVideoSchedulerOutputPort::ConstructL(const TOmxILCommonPortData& aCommonPortData, + const RArray& aSupportedCodings, + const RArray& aSupportedColourFormats) + { + COmxILVideoPort::ConstructL(aCommonPortData, aSupportedCodings, aSupportedColourFormats); + // Port definition mime type. Mime type is not relevant for uncompressed video frames + iMimeTypeBuf.CreateL(KNullDesC8(), KNullDesC8().Length() + 1); + TUint8* pTUint = const_cast(iMimeTypeBuf.PtrZ()); + GetParamPortDefinition().format.video.cMIMEType = reinterpret_cast(pTUint); + + GetSupportedVideoFormats().AppendL(OMX_VIDEO_CodingUnused); + GetSupportedColorFormats().AppendL(OMX_COLOR_FormatUnused); + } + +OMX_ERRORTYPE COmxILVideoSchedulerOutputPort::GetLocalOmxParamIndexes(RArray& aIndexArray) const + { + return COmxILVideoPort::GetLocalOmxParamIndexes(aIndexArray); + } + +OMX_ERRORTYPE COmxILVideoSchedulerOutputPort::GetLocalOmxConfigIndexes(RArray& aIndexArray) const + { + return COmxILVideoPort::GetLocalOmxConfigIndexes(aIndexArray); + } + +OMX_ERRORTYPE COmxILVideoSchedulerOutputPort::GetParameter(OMX_INDEXTYPE aParamIndex, + TAny* apComponentParameterStructure) const + { + return COmxILVideoPort::GetParameter(aParamIndex, apComponentParameterStructure); + } + +OMX_ERRORTYPE COmxILVideoSchedulerOutputPort::SetParameter(OMX_INDEXTYPE aParamIndex, + const TAny* apComponentParameterStructure, + TBool& aUpdateProcessingFunction) + { + return COmxILVideoPort::SetParameter(aParamIndex, apComponentParameterStructure, aUpdateProcessingFunction); + } + +OMX_ERRORTYPE COmxILVideoSchedulerOutputPort::SetFormatInPortDefinition(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition, + TBool& /*aUpdateProcessingFunction*/) + { + GetParamPortDefinition().format.video = aPortDefinition.format.video; + TUint8* pTUint = const_cast(iMimeTypeBuf.PtrZ()); + GetParamPortDefinition().format.video.cMIMEType = reinterpret_cast(pTUint); + GetParamPortDefinition().format.video.nSliceHeight = GetParamPortDefinition().format.video.nFrameHeight; + GetParamPortDefinition().nBufferSize = GetParamPortDefinition().format.video.nStride * GetParamPortDefinition().format.video.nSliceHeight; + return OMX_ErrorNone; + } + +TBool COmxILVideoSchedulerOutputPort::IsTunnelledPortCompatible(const OMX_PARAM_PORTDEFINITIONTYPE& /*aPortDefinition*/) const + { + return ETrue; + } + +/** Returns the number of buffers configured on this port. */ +TUint32 COmxILVideoSchedulerOutputPort::BufferCount() const + { + return GetParamPortDefinition().nBufferCountActual; + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/comxilvideoscheduleroutputport.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/comxilvideoscheduleroutputport.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef COMXILVIDEOSCHEDULEROUTPUTPORT_H_ +#define COMXILVIDEOSCHEDULEROUTPUTPORT_H_ + +#include + + + +NONSHARABLE_CLASS(COmxILVideoSchedulerOutputPort) : public COmxILVideoPort + { +public: + static COmxILVideoSchedulerOutputPort* NewL(const TOmxILCommonPortData& aCommonPortData); + + ~COmxILVideoSchedulerOutputPort(); + + TUint32 BufferCount() const; + + // from COmxILVideoPort + OMX_ERRORTYPE GetLocalOmxParamIndexes(RArray& aIndexArray) const; + OMX_ERRORTYPE GetLocalOmxConfigIndexes(RArray& aIndexArray) const; + OMX_ERRORTYPE GetParameter(OMX_INDEXTYPE aParamIndex, TAny* apComponentParameterStructure) const; + OMX_ERRORTYPE SetParameter(OMX_INDEXTYPE aParamIndex, const TAny* apComponentParameterStructure, + TBool& aUpdateProcessingFunction); + +protected: + OMX_ERRORTYPE SetFormatInPortDefinition(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition, + TBool& aUpdateProcessingFunction); + + TBool IsTunnelledPortCompatible(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition) const; + +private: + COmxILVideoSchedulerOutputPort(); + void ConstructL(const TOmxILCommonPortData& aCommonPortData, + const RArray& aSupportedCodings, + const RArray& aSupportedColourFormats); + +private: + //Mime Type is not important for uncompressed video but is required for the port definition structure. + RBuf8 iMimeTypeBuf; + }; + +#endif /*COMXILVIDEOSCHEDULEROUTPUTPORT_H_*/ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/comxilvideoschedulerpf.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/comxilvideoschedulerpf.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,826 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + + +#include + +#include "comxilvideoschedulerpf.h" +#include "comxilvideoscheduler.h" +#include "resourcefilereader.h" +#include "buffercopierstatemonitor.h" +#include "omxilvideoschedulerextensionsindexes.h" +#include +#include +#include "log.h" + +_LIT(KVideoSchedulerPanicCategory, "omxilvscheduler"); //should restrict to 16 characters as it is used in User::Panic +_LIT(KResourceFileName, "Z:\\resource\\videoscheduler\\videoscheduler.rsc"); +const TInt KMaxRenderTime = 1000000; +const TInt KMaxGraphicSinkBufferCount(2); //This is set as the maximum number of buffers that can be sent to the graphic sink without the risk of overloading it. + + + +COmxILVideoSchedulerPF* COmxILVideoSchedulerPF::NewL(MOmxILCallbackNotificationIf& aCallbacks, COmxILVideoScheduler& aComponent, OMX_COMPONENTTYPE* aHandle) + { + COmxILVideoSchedulerPF* self = new (ELeave) COmxILVideoSchedulerPF(aCallbacks, aComponent, aHandle); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +COmxILVideoSchedulerPF::COmxILVideoSchedulerPF(MOmxILCallbackNotificationIf& aCallbacks, COmxILVideoScheduler& aComponent, OMX_COMPONENTTYPE* aHandle) +: COmxILProcessingFunction(aCallbacks), + iComponent(aComponent), + iIsClockStopped(ETrue), + iInvalid(EFalse), + iTimeStamp(KMinTInt64), + iHandle(aHandle) + { + } + +void COmxILVideoSchedulerPF::ConstructL() + { + User::LeaveIfError(iMutex.CreateLocal()); + iBufferCopierStateMonitor = CBufferCopierStateMonitor::NewL(*this, iComponent); + // get timer info + CResourceFileReader* reader = CResourceFileReader::NewLC(KResourceFileName); + reader->ReadTimerInfoL(iRenderTime, iMaxLateness); + CleanupStack::PopAndDestroy(reader); + + // Prefill the render time array with the default render time read from resource file + for (TInt count = 0; count < KRenderTimeListLength; ++count) + { + iRenderTimeList[count] = iRenderTime; + } + iRenderTimeSum = iRenderTime * KRenderTimeListLength; + } + +COmxILVideoSchedulerPF::~COmxILVideoSchedulerPF() + { + delete iBufferCopierStateMonitor; + iMutex.Wait(); + iWaitingBuffers.Reset(); + iCompletedBuffersHeldByPause.Reset(); + iMutex.Signal(); + iMutex.Close(); + } + +OMX_ERRORTYPE COmxILVideoSchedulerPF::StateTransitionIndication(TStateIndex aNewState) + { + switch(aNewState) + { + case EStateExecuting: + { + if (iPausedState) + { + iMutex.Wait(); + iPausedState = EFalse; + + // send any buffers that received time updates during paused state + if (iOutputBufferSentCount < KMaxGraphicSinkBufferCount) // only allowed to send 2 buffers at a time + { + SubmitBufferHeldByPause(); + } + iMutex.Signal(); + } + break; + } + case EStatePause: + { + iPausedState = ETrue; + break; + } + case ESubStateLoadedToIdle: + { + TUint32 bufferCount = iComponent.BufferCount(); + + TInt error = iBufferCopierStateMonitor->SetState(CBufferCopierStateMonitor::ESubLoadedToIdle); + + if (error != KErrNone) + { + return SymbianErrorToOmx(error); + } + + error = iWaitingBuffers.Reserve(bufferCount); + if (error != KErrNone) + { + return SymbianErrorToOmx(error); + } + + error = iCompletedBuffersHeldByPause.Reserve(bufferCount); + if (error != KErrNone) + { + return SymbianErrorToOmx(error); + } + + break; + } + case EStateIdle: + { + iOutputBufferSentCount = iComponent.BufferCount(); + break; + } + case ESubStateIdleToLoaded: + { + TInt error = iBufferCopierStateMonitor->SetState(CBufferCopierStateMonitor::ESubIdleToLoaded); + if (error != KErrNone) + { + return SymbianErrorToOmx(error); + } + break; + } + default: + { + break; + } + } + + return OMX_ErrorNone; + } + +OMX_ERRORTYPE COmxILVideoSchedulerPF::BufferFlushingIndication(TUint32 aPortIndex, OMX_DIRTYPE aDirection) + { + // called from command thread + + iMutex.Wait(); + if (iBufferCopierStateMonitor->BufferCopier()) + { + if (aPortIndex == OMX_ALL) + { + iBufferCopierStateMonitor->BufferCopier()->FlushBuffers(OMX_DirInput); + iBufferCopierStateMonitor->BufferCopier()->FlushBuffers(OMX_DirOutput); + } + else + { + iBufferCopierStateMonitor->BufferCopier()->FlushBuffers(aDirection); + } + } + + if (aDirection == OMX_DirOutput || aPortIndex == OMX_ALL) + { + while (iWaitingBuffers.Count() > 0) + { + iWaitingBuffers[0]->nFilledLen = 0; + iWaitingBuffers[0]->nOffset = 0; + iWaitingBuffers[0]->nTimeStamp = 0; + iCallbacks.BufferDoneNotification(iWaitingBuffers[0], 1, OMX_DirOutput); + iWaitingBuffers.Remove(0); + iOutputBufferSentCount++; + } + if(iSinkPendingBuffer) + { + iSinkPendingBuffer->nFilledLen = 0; + iSinkPendingBuffer->nOffset = 0; + iSinkPendingBuffer->nTimeStamp = 0; + iCallbacks.BufferDoneNotification(iSinkPendingBuffer, 1, OMX_DirOutput); + iSinkPendingBuffer = NULL; + iOutputBufferSentCount++; + } + } + iMutex.Signal(); + + return OMX_ErrorNone; + } + +OMX_ERRORTYPE COmxILVideoSchedulerPF::ParamIndication(OMX_INDEXTYPE aParamIndex, + const TAny* apComponentParameterStructure) + { + DEBUG_PRINTF(_L8("COmxILVideoSchedulerProcessingFunction::ParamIndication")); + + if(aParamIndex == OMX_NokiaIndexParamDroppedFrameEvent) + { + const OMX_NOKIA_PARAM_DROPPEDFRAMEEVENT* dropFrame = static_cast(apComponentParameterStructure); + iEnableDropFrameEvent = dropFrame->bEnabled; + } + + return OMX_ErrorNone; + } + +OMX_ERRORTYPE COmxILVideoSchedulerPF::ConfigIndication(OMX_INDEXTYPE /*aConfigIndex*/, const TAny* /*apComponentConfigStructure*/) + { + return OMX_ErrorNone; + } + +OMX_ERRORTYPE COmxILVideoSchedulerPF::BufferIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, + OMX_DIRTYPE aDirection) + { + if (iInvalid) + { + return OMX_ErrorInvalidState; + } + + // called from decoder data thread or sink data thread + iMutex.Wait(); + if(aDirection == OMX_DirOutput) + { + apBufferHeader->nFlags = 0; + iOutputBufferSentCount--; + ASSERT(iOutputBufferSentCount <= iComponent.BufferCount()); + + DEBUG_PRINTF2(_L8("VS2::BufferIndication : apBufferHeader->nTickCount = %d"), apBufferHeader->nTickCount); + + // update the render time if it is set + if (apBufferHeader->nTickCount > 0 && apBufferHeader->nTickCount <= KMaxRenderTime) + { + // Add new render time to render time list, and recalculate average + iRenderTimeSum -= iRenderTimeList[iRenderTimeListPos]; + iRenderTimeSum += apBufferHeader->nTickCount; + iRenderTimeList[iRenderTimeListPos] = apBufferHeader->nTickCount; + ++iRenderTimeListPos; + iRenderTimeListPos %= KRenderTimeListLength; + + iRenderTime = iRenderTimeSum / KRenderTimeListLength; + + DEBUG_PRINTF2(_L8("VS2::BufferIndication : New iRenderTime = %ld"), iRenderTime); + } + + // previously sent buffer has come back + // send any buffers that received time updates + // at startup, iOutputBufferSentCount may be >2 if output port is non-supplier + if (!iPausedState && iOutputBufferSentCount < KMaxGraphicSinkBufferCount) + { + SubmitBufferHeldByPause(); + } + } + else if(apBufferHeader->nFlags & OMX_BUFFERFLAG_DECODEONLY) + { + // this frame is not to be rendered (probably as part of an accurate seek) + // drop the data and send it back to the decoder + apBufferHeader->nFilledLen = 0; + apBufferHeader->nFlags = 0; + apBufferHeader->nOffset = 0; + iCallbacks.BufferDoneNotification(apBufferHeader, 0, OMX_DirInput); + iMutex.Signal(); + return OMX_ErrorNone; + } + if (iBufferCopierStateMonitor->BufferCopier()) + { + iBufferCopierStateMonitor->BufferCopier()->DeliverBuffer(apBufferHeader, aDirection); + } + iMutex.Signal(); + + return OMX_ErrorNone; + } + +OMX_ERRORTYPE COmxILVideoSchedulerPF::MediaTimeIndication(const OMX_TIME_MEDIATIMETYPE& aTimeInfo) + { + // called from clock thread + + switch(aTimeInfo.eUpdateType) + { + case OMX_TIME_UpdateRequestFulfillment: + { + + iMutex.Wait(); + + TInt index = -1; + OMX_BUFFERHEADERTYPE* buffer = reinterpret_cast(aTimeInfo.nClientPrivate); + __ASSERT_DEBUG(buffer->nTimeStamp == aTimeInfo.nMediaTimestamp, Panic(EPanicBadAssociation)); + if(FindWaitingBuffer(buffer, aTimeInfo.nMediaTimestamp, index)) + { + if (iPausedState || iCompletedBuffersHeldByPause.Count() > 0) + { + TBufferMessage bufferMessage; + bufferMessage.iBufferHeader = buffer; + bufferMessage.iMediaTimeInfo = aTimeInfo; + + OMX_ERRORTYPE error = SymbianErrorToOmx(iCompletedBuffersHeldByPause.Append(bufferMessage)); // note append cannot fail, allocated enough slots + iMutex.Signal(); + return error; + } + else + { + SendTimedOutputBuffer(buffer, aTimeInfo, index); + } + } + else + { + // TODO [SL] now what? + User::Invariant(); + } + + iMutex.Signal(); + return OMX_ErrorNone; + } + + case OMX_TIME_UpdateScaleChanged: + if(aTimeInfo.xScale >= 0) + { + // the clock takes care completing requests at the correct media time + return OMX_ErrorNone; + } + else + { + // TODO think harder about implications of negative scale + // certainly the iTimeStamp checking must be reversed + ASSERT(0); + return OMX_ErrorNotImplemented; + } + + case OMX_TIME_UpdateClockStateChanged: + iClockState.eState = aTimeInfo.eState; + switch(aTimeInfo.eState) + { + case OMX_TIME_ClockStateStopped: + { + // clock stopped so remove any pending buffers from the list as time requests + // will be resent when the clock is running again + + iIsClockStopped = ETrue; + + iMutex.Wait(); + while (iCompletedBuffersHeldByPause.Count() > 0) + { + iCompletedBuffersHeldByPause.Remove(0); + } + + if(iSinkPendingBuffer && iBufferCopierStateMonitor) + { + // if sink pending buffer exist (as sink is bottleneck) then drop the frame + iBufferCopierStateMonitor->BufferCopier()->DeliverBuffer(iSinkPendingBuffer, OMX_DirOutput); + + // dropped a frame, so send an event if the dropped frame extension is enabled + if (iEnableDropFrameEvent) + { + //TODO DL: iCallbacks.EventNotification(OMX_EventNokiaDroppedFrame, 1, 0, NULL); + } + + iSinkPendingBuffer = NULL; + } + iMutex.Signal(); + } + break; + + case OMX_TIME_ClockStateWaitingForStartTime: + { + iIsClockStopped = EFalse; + // if now in WaitingForStartTime state and start time already received, send it now + if (iStartTimePending) + { + OMX_ERRORTYPE error = iComponent.SetVideoStartTime(iStartTime); + if (error != OMX_ErrorNone) + { + // iStartTimePending = EFalse; // FIXME - Is this required? + return error; + } + } + } + break; + + case OMX_TIME_ClockStateRunning: + { + iTimeStamp = KMinTInt64; + if(iIsClockStopped) + { + // the clock is running after being stopped previously + // resend time requests for waiting buffers + iIsClockStopped = EFalse; + + for (TInt i = 0; i < iWaitingBuffers.Count(); ++i) + { + iComponent.MediaTimeRequest(iWaitingBuffers[i], iWaitingBuffers[i]->nTimeStamp, iRenderTime); + } + } + } + break; + } + + iStartTimePending = EFalse; + DEBUG_PRINTF2(_L8("VS2::MediaTimeIndication : ClockStateChanged = %d"), aTimeInfo.eState); + + return OMX_ErrorNone; + + default: + return OMX_ErrorBadParameter; + } + + } + +/* Check if aBuffer still exist in the waiting queue */ +TBool COmxILVideoSchedulerPF::FindWaitingBuffer(const OMX_BUFFERHEADERTYPE* aBuffer, const OMX_TICKS& aMediaTime, TInt& aIndex) const + { + __ASSERT_DEBUG(const_cast(iMutex).IsHeld(), Panic(EPanicMutexUnheld)); + + TBool found = EFalse; + + for (TInt i=0; inTimeStamp == aMediaTime)) + { + found = ETrue; + aIndex = i; + break; + } + } + + return found; + } + +/** +Check if a specified buffer is currently held by the processing function, +and remove it if found. + +@param apBufferHeader Buffer to remove +@param aDirection Port direction +@return Flag to indicate if buffer was removed. +*/ +OMX_BOOL COmxILVideoSchedulerPF::BufferRemovalIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, OMX_DIRTYPE aDirection) + { + iMutex.Wait(); + if(iBufferCopierStateMonitor->BufferCopier() && iBufferCopierStateMonitor->BufferCopier()->RemoveBuffer(apBufferHeader, aDirection)) + { + if(aDirection == OMX_DirOutput) + { + iOutputBufferSentCount++; + } + iMutex.Signal(); + return OMX_TRUE; + } + else if(aDirection == OMX_DirOutput) + { + for (TInt i = 0; i < iWaitingBuffers.Count(); ++i) + { + if (iWaitingBuffers[i] == apBufferHeader) + { + iWaitingBuffers[i]->nFilledLen = 0; + iWaitingBuffers.Remove(i); + iOutputBufferSentCount++; + iMutex.Signal(); + return OMX_TRUE; + } + } + if(apBufferHeader == iSinkPendingBuffer) + { + iSinkPendingBuffer = NULL; + iOutputBufferSentCount++; + iMutex.Signal(); + return OMX_TRUE; + } + } + + iMutex.Signal(); + return OMX_FALSE; + } + +/* Submit the first time update buffer that still exists in the waiting queue. */ +void COmxILVideoSchedulerPF::SubmitBufferHeldByPause() + { + __ASSERT_DEBUG(iMutex.IsHeld(), Panic(EPanicMutexUnheld)); + __ASSERT_DEBUG(iOutputBufferSentCount < KMaxGraphicSinkBufferCount, Panic(EPanicBadOutputRegulation)); + + if(iSinkPendingBuffer) + { + DEBUG_PRINTF(_L8("VS2::SubmitBufferHeldByPause ***************************SEND SINK PENDING BUFFER")); + OMX_BUFFERHEADERTYPE* buffer = iSinkPendingBuffer; + iSinkPendingBuffer = NULL; + SendOutputBuffer(buffer); + return; + } + + TInt index = -1; + TBool bufferSent = EFalse; + while (iCompletedBuffersHeldByPause.Count() > 0 && !bufferSent) + { + TBufferMessage& msg = iCompletedBuffersHeldByPause[0]; + if (FindWaitingBuffer(msg.iBufferHeader, + msg.iMediaTimeInfo.nMediaTimestamp, index)) + { + DEBUG_PRINTF(_L8("VS2::SubmitBufferHeldByPause ***************************SEND HELD BUFFER")); + bufferSent = SendTimedOutputBuffer(msg.iBufferHeader, msg.iMediaTimeInfo, index); + } + iCompletedBuffersHeldByPause.Remove(0); + } + } + +/** Returns ETrue if aBuffer was sent, EFalse otherwise */ +TBool COmxILVideoSchedulerPF::SendTimedOutputBuffer(OMX_BUFFERHEADERTYPE* aBuffer, const OMX_TIME_MEDIATIMETYPE& aMediaTimeInfo, TInt aIndex) + { + __ASSERT_DEBUG(iMutex.IsHeld(), Panic(EPanicMutexUnheld)); + __ASSERT_DEBUG(aBuffer->nTimeStamp == aMediaTimeInfo.nMediaTimestamp, Panic(EPanicBadAssociation)); + __ASSERT_DEBUG(aBuffer == reinterpret_cast(aMediaTimeInfo.nClientPrivate), Panic(EPanicBadAssociation)); + +#ifdef _OMXIL_COMMON_DEBUG_TRACING_ON + DEBUG_PRINTF(_L8("VS2::SendTimedOutputBuffer **********************************")); + TTime t; + t.HomeTime(); + DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : t.HomeTime() = %ld"), t.Int64()); + DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : aMediaTimeInfo.nClientPrivate = 0x%X"), aMediaTimeInfo.nClientPrivate); + DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : aMediaTimeInfo.nMediaTimestamp = %ld"), aMediaTimeInfo.nMediaTimestamp); + DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : aMediaTimeInfo.nOffset = %ld"), aMediaTimeInfo.nOffset); + DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : aMediaTimeInfo.nWallTimeAtMediaTime = %ld"), aMediaTimeInfo.nWallTimeAtMediaTime); +#endif + + TBool bufferSent = EFalse; + + OMX_U32 flags = aBuffer->nFlags; + + // Work out how long it is from now until the frame will be rendered. + // This will be the time it takes the sink to render, minus the offset + // value from the clock completion (i.e how far before the requested + // time that the clock has completed us). A lateness of 0 means we are at + // the correct time to send the buffer, a positive lateness means we are + // late sending the buffer, and a lateness waitTime means we are early. + // For the first frame we were not able to request an early completion to + // offset the render time, so assume that the render time is 0. + OMX_TICKS lateness = 0 - aMediaTimeInfo.nOffset; + if (!(flags & OMX_BUFFERFLAG_STARTTIME)) + { + lateness += iRenderTime; + } + + DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : iRenderTime = %ld"), iRenderTime); + DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : lateness = %ld"), lateness); + DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : iMaxLateness = %ld"), iMaxLateness); + DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : iTimeStamp = %ld"), iTimeStamp); + DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : iFrameDroppedCount = %d"), iFrameDroppedCount); + DEBUG_PRINTF2(_L8("VS2::SendTimedOutputBuffer : flags = %d"), flags); + + iWaitingBuffers.Remove(aIndex); + + // Send the buffer if the wait time is within the maximum allowed delay and timestamp is later than the previous timestamp, otherwise skip the buffer + if ((lateness <= iMaxLateness || iFrameDroppedCount >= KMaxGraphicSinkBufferCount) && aMediaTimeInfo.nMediaTimestamp > iTimeStamp) // shouldn't drop more than 2 frames at a time when decoder is slow + { + DEBUG_PRINTF(_L8("VS2::SendTimedOutputBuffer ***************************SHOW")); + + bufferSent = ETrue; + iFrameDroppedCount = 0; + + SendOutputBuffer(aBuffer); + } + else + { + DEBUG_PRINTF(_L8("VS2::SendTimedOutputBuffer ***************************DROP")); + + iFrameDroppedCount++; + + // dropped a frame, so send an event if the dropped frame extension is enabled + if(iEnableDropFrameEvent) + { + //TODO DL: iCallbacks.EventNotification(OMX_EventNokiaDroppedFrame, 1, 0, NULL); + } + + // if EOS was on the buffer, send an empty buffer with EOS and send the EOS event + // if not, discard the buffer contents and post the buffer for another copy + if(flags & OMX_BUFFERFLAG_EOS) + { + DEBUG_PRINTF(_L8("VS2::SendTimedOutputBuffer ***************************SEND EMPTY EOS BUFFER")); + aBuffer->nFilledLen = 0; + aBuffer->nOffset = 0; + aBuffer->nTimeStamp = 0; + SendOutputBuffer(aBuffer); + } + else + { + TOmxILUtil::ClearBufferContents(aBuffer); + aBuffer->nOffset = 0; + if (iBufferCopierStateMonitor->BufferCopier()) + { + iBufferCopierStateMonitor->BufferCopier()->DeliverBuffer(aBuffer, OMX_DirOutput); + } + } + } + + return bufferSent; + } + +void COmxILVideoSchedulerPF::SendOutputBuffer(OMX_BUFFERHEADERTYPE* aBuffer) + { + __ASSERT_DEBUG(iMutex.IsHeld(), Panic(EPanicMutexUnheld)); + __ASSERT_DEBUG(iTimeStamp < aBuffer->nTimeStamp || aBuffer->nFlags & OMX_BUFFERFLAG_EOS, Panic(EPanicTimestampEmissionUnordered)); + + if(iOutputBufferSentCount >= KMaxGraphicSinkBufferCount) + { + DEBUG_PRINTF(_L8("VS2::SendOutputBuffer : *****************STORING SINK PENDING BUFFER")); + + // sink is bottleneck, keep the most recent pending frame but return the rest so decoder keeps running + // when sink returns a buffer send the most recent frame + if(iSinkPendingBuffer && iBufferCopierStateMonitor->BufferCopier()) + { + if (iSinkPendingBuffer->nFlags & OMX_BUFFERFLAG_EOS) + { + //if (bizarrely) pending buffer has EOS flag and another buffer replaces it. + DoSendOutputBuffer(iSinkPendingBuffer); + } + else + { + iBufferCopierStateMonitor->BufferCopier()->DeliverBuffer(iSinkPendingBuffer, OMX_DirOutput); + } + + DEBUG_PRINTF(_L8("VS2::SendOutputBuffer : *****************DROPPED EXISTING SINK PENDING BUFFER")); + + // dropped a frame, so send an event if the dropped frame extension is enabled + if(iEnableDropFrameEvent) + { + //TODO DL: iCallbacks.EventNotification(OMX_EventNokiaDroppedFrame, 1, 0, NULL); + } + } + + iSinkPendingBuffer = aBuffer; + } + else + { + DoSendOutputBuffer(aBuffer); + } + } + +/** Called when the buffer copier has transferred the data from an input buffer to an output buffer. */ +void COmxILVideoSchedulerPF::MbcBufferCopied(OMX_BUFFERHEADERTYPE* aInBuffer, OMX_BUFFERHEADERTYPE* aOutBuffer) + { + iMutex.Wait(); + + // send input buffer back + aInBuffer->nFilledLen = 0; + aInBuffer->nOffset = 0; + aInBuffer->nFlags = 0; + aInBuffer->nTimeStamp = 0; + + // Deal with any buffer marks. Currently the component framework makes an attempt to deal with + // them, but it cannot associate the input buffer mark with the corresponding output buffer so + // we may need to do some tweaking here. + if (aInBuffer->hMarkTargetComponent) + { + if (aInBuffer->hMarkTargetComponent == iHandle) + { + // There was a buffer mark on the input buffer intended for us. That means there is no + // need to send it out on the output buffer. Also, it is OK to let the component framework + // deal with it in this situation. + aOutBuffer->hMarkTargetComponent = NULL; + aOutBuffer->pMarkData = NULL; + } + else + { + // There was a buffer mark on the input buffer but it is not intended for us. If + // we let the component framework deal with it then we will get multiple marks sent + // out because we have copied it to the output buffer, and the framework will also + // store it to send out later. Clear it here so the framework does not see it. + aInBuffer->hMarkTargetComponent = NULL; + aInBuffer->pMarkData = NULL; + } + } + + OMX_ERRORTYPE error; + + iCallbacks.BufferDoneNotification(aInBuffer, 0, OMX_DirInput); + + if(aOutBuffer->nFilledLen > 0 || (aOutBuffer->nFlags & OMX_BUFFERFLAG_EOS)) + { + iWaitingBuffers.Append(aOutBuffer); // note append cannot fail, allocated enough slots + } + + if(aOutBuffer->nFlags & OMX_BUFFERFLAG_STARTTIME) + { + if(OMX_TIME_ClockStateWaitingForStartTime == iClockState.eState) + { + error = iComponent.SetVideoStartTime(aOutBuffer->nTimeStamp); + if (error != OMX_ErrorNone) + { + HandleIfError(error); + } + iStartTimePending = EFalse; + } + else + { + // delay sending until clock transitions to WaitingForStartTime + iStartTime = aOutBuffer->nTimeStamp; + iStartTimePending = ETrue; + } + } + +#ifdef _OMXIL_COMMON_DEBUG_TRACING_ON + DEBUG_PRINTF(_L8("VS2::MbcBufferCopied **********************************")); + TTime t; + t.HomeTime(); + DEBUG_PRINTF2(_L8("VS2::MbcBufferCopied : t.HomeTime() = %ld"), t.Int64()); + DEBUG_PRINTF2(_L8("VS2::MbcBufferCopied : aOutBuffer = 0x%X"), aOutBuffer); + DEBUG_PRINTF2(_L8("VS2::MbcBufferCopied : aOutBuffer->nTimeStamp = %ld"), aOutBuffer->nTimeStamp); +#endif + iMutex.Signal(); + + if (aOutBuffer->nFilledLen == 0 && !(aOutBuffer->nFlags & OMX_BUFFERFLAG_EOS)) + { + // A likely cause of receiving an empty buffer is if the decoder implements a flush as + // returning buffers to supplier or always sending buffers to peer, rather than emptied + // and queued on the output port. In this case we return the buffer immediately without + // making a media time request. Probably the timestamp is invalid or the clock is not in + // the running state, in either case we could deadlock by queueing the empty buffers after + // a flush and preventing new data from being delivered. However these buffers were not + // returned in BufferIndication() in case there were any flags that need processing. + iBufferCopierStateMonitor->BufferCopier()->DeliverBuffer(aOutBuffer, OMX_DirOutput); + } + else + { + if (!iIsClockStopped) + { + error = iComponent.MediaTimeRequest(aOutBuffer, aOutBuffer->nTimeStamp, iRenderTime); + if (error != OMX_ErrorNone) + { + HandleIfError(error); + } + } + } + } + +/** Called when a buffer is flushed from the buffer copier. */ +void COmxILVideoSchedulerPF::MbcBufferFlushed(OMX_BUFFERHEADERTYPE* aBuffer, OMX_DIRTYPE aDirection) + { + TInt portIndex = 0; + aBuffer->nFilledLen = 0; + aBuffer->nOffset = 0; + aBuffer->nFlags = 0; + aBuffer->nTimeStamp = 0; + + if (aDirection == OMX_DirOutput) + { + ++iOutputBufferSentCount; + portIndex = 1; + } + + iCallbacks.BufferDoneNotification(aBuffer, portIndex, aDirection); + } + +void COmxILVideoSchedulerPF::DoSendOutputBuffer(OMX_BUFFERHEADERTYPE* aBuffer) + { + OMX_ERRORTYPE error; + // A zero length buffer means this buffer is just being sent because it + // has the EOS flag. + if (aBuffer->nFilledLen > 0) + { + aBuffer->nTickCount = 0xC0C0C0C0; + iTimeStamp = aBuffer->nTimeStamp; + } + + error = iCallbacks.BufferDoneNotification(aBuffer, 1, OMX_DirOutput); + if (error != OMX_ErrorNone) + { + HandleIfError(error); + } + + iOutputBufferSentCount++; + + OMX_U32 flags = aBuffer->nFlags; + if(flags & OMX_BUFFERFLAG_EOS) + { + error = iCallbacks.EventNotification(OMX_EventBufferFlag, 1, flags, NULL); + if (error != OMX_ErrorNone) + { + HandleIfError(error); + } + } + } + +void COmxILVideoSchedulerPF::HandleIfError(OMX_ERRORTYPE aOmxError) + { + if (aOmxError != OMX_ErrorNone) + { + iInvalid = ETrue; + iCallbacks.ErrorEventNotification(aOmxError); + } + } + +OMX_ERRORTYPE COmxILVideoSchedulerPF::SymbianErrorToOmx(TInt aError) + { + switch(aError) + { + case KErrNone: + return OMX_ErrorNone; + case KErrNoMemory: + return OMX_ErrorInsufficientResources; + default: + return OMX_ErrorUndefined; + } + } + + + +void COmxILVideoSchedulerPF::Panic(TVideoSchedulerPanic aPanicCode) const + { + // const allows const methods to panic using this method + // however we wish to release the mutex to avoid blocking other threads + RMutex& mutex = const_cast(iMutex); + if(mutex.IsHeld()) + { + mutex.Signal(); + } + User::Panic(KVideoSchedulerPanicCategory, aPanicCode); + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/comxilvideoschedulerpf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/comxilvideoschedulerpf.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,126 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ +#ifndef COMXILVIDEOSCHEDULERPF_H_ +#define COMXILVIDEOSCHEDULERPF_H_ + +#include +#include +#include +#include "buffercopier.h" + + +// forward class declarations +class COmxILVideoScheduler; +class CBufferCopierStateMonitor; + +static const TInt KRenderTimeListLength = 5; + +/** + * These panics can only be raised in debug builds, and indicate an assertion failure due to programmer error. + */ +enum TVideoSchedulerPanic + { + EPanicMutexUnheld, // the mutex was unheld where it was expected to be held + EPanicTimestampEmissionUnordered, // buffer emission was triggered for a timestamp less than the previous emission's timestamp + EPanicBadOutputRegulation, // more output buffers were sent than intended or iSinkPendingBuffer at inappropriate time + EPanicBadAssociation // inconsistency between media time info and corresponding buffer header + }; + +NONSHARABLE_CLASS(COmxILVideoSchedulerPF) : public COmxILProcessingFunction, public MBufferCopierIf + { +public: + static COmxILVideoSchedulerPF* NewL(MOmxILCallbackNotificationIf& aCallbacks, COmxILVideoScheduler& aComponent, OMX_COMPONENTTYPE* aHandle); + ~COmxILVideoSchedulerPF(); + + // from COmxILProcessingFunction + OMX_ERRORTYPE StateTransitionIndication(TStateIndex aNewState); + OMX_ERRORTYPE BufferFlushingIndication(TUint32 aPortIndex, OMX_DIRTYPE aDirection); + OMX_ERRORTYPE ParamIndication(OMX_INDEXTYPE aParamIndex, const TAny* apComponentParameterStructure); + OMX_ERRORTYPE ConfigIndication(OMX_INDEXTYPE aConfigIndex, const TAny* apComponentConfigStructure); + OMX_ERRORTYPE BufferIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, OMX_DIRTYPE aDirection); + OMX_BOOL BufferRemovalIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, OMX_DIRTYPE aDirection); + OMX_ERRORTYPE MediaTimeIndication(const OMX_TIME_MEDIATIMETYPE& aTimeInfo); + + // from MBufferCopierIf + void MbcBufferCopied(OMX_BUFFERHEADERTYPE* aInBuffer, OMX_BUFFERHEADERTYPE* aOutBuffer); + void MbcBufferFlushed(OMX_BUFFERHEADERTYPE* aBuffer, OMX_DIRTYPE aDirection); + + MOmxILCallbackNotificationIf& GetCallbacks(); + +private: + class TBufferMessage + { + public: + OMX_BUFFERHEADERTYPE* iBufferHeader; + OMX_TIME_MEDIATIMETYPE iMediaTimeInfo; + }; + +private: + COmxILVideoSchedulerPF(MOmxILCallbackNotificationIf& aCallbacks, COmxILVideoScheduler& aComponent, OMX_COMPONENTTYPE* aHandle); + void ConstructL(); + + TBool FindWaitingBuffer(const OMX_BUFFERHEADERTYPE* aBuffer, const OMX_TICKS& aMediaTime, TInt& aIndex) const; + void SubmitBufferHeldByPause(); + TBool SendTimedOutputBuffer(OMX_BUFFERHEADERTYPE* aBuffer, const OMX_TIME_MEDIATIMETYPE& aMediaTimeInfo, TInt aIndex); + void SendOutputBuffer(OMX_BUFFERHEADERTYPE* aBuffer); + void DoSendOutputBuffer(OMX_BUFFERHEADERTYPE* aBuffer); + void HandleIfError(OMX_ERRORTYPE aOmxError); + OMX_ERRORTYPE SymbianErrorToOmx(TInt aError); + + void Panic(TVideoSchedulerPanic aPanicCode) const; + +private: + COmxILVideoScheduler& iComponent; + OMX_TICKS iRenderTime; // time it takes for Graphic Sink to render a frame + TBool iPausedState; + CBufferCopierStateMonitor* iBufferCopierStateMonitor; + RPointerArray iWaitingBuffers; // all waiting buffers, including those that received time updates + TUint32 iOutputBufferSentCount; // Only allowed to send 2 buffers at a time + RArray iCompletedBuffersHeldByPause; // buffers that receive time indications while component is paused + TInt64 iMaxLateness; // how late a buffer is allowed to be before it is dropped + + // to keep track of ClockState + OMX_TIME_CONFIG_CLOCKSTATETYPE iClockState; + + // hold on to start time if received before clock enters WaitingForStartTime state + TInt64 iStartTime; + TBool iStartTimePending; + + // any buffer that is ready to be displayed but sink is not ready to receive + OMX_BUFFERHEADERTYPE* iSinkPendingBuffer; + + TBool iIsClockStopped; + TBool iInvalid; + TUint32 iFrameDroppedCount; // shouldn't drop more than 2 frames at a time when decoder is slow + OMX_TICKS iTimeStamp; + RMutex iMutex; + OMX_BOOL iEnableDropFrameEvent; //enable the extension to notify error when drop frame happen + + TUint32 iRenderTimeList[KRenderTimeListLength]; + TInt iRenderTimeListPos; + TUint32 iRenderTimeSum; // the sum of the values in iRenderTimeList + + OMX_COMPONENTTYPE* iHandle; + }; + +#endif /*CCOMXILVIDEOSCHEDULERPF_H_*/ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/log.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/log.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,149 @@ +/* +* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifndef __SWI_LOG_H__ +#define __SWI_LOG_H__ + +#include + +class TTruncateOverflowHandler16 : public TDes16Overflow + { + public: + virtual void Overflow( TDes16& aDes ); + }; + +inline void TTruncateOverflowHandler16::Overflow( TDes16& aDes) + { + _LIT(KErrOverflowMsg,"Descriptor Overflow, hence value truncated"); + if( aDes.MaxLength() >= KErrOverflowMsg().Length() + aDes.Length() ) + aDes.Append(KErrOverflowMsg); + } + +class TTruncateOverflowHandler8 : public TDes8Overflow + { + public: + virtual void Overflow( TDes8& aDes ); + }; + +inline void TTruncateOverflowHandler8::Overflow( TDes8& aDes) + { + _LIT(KErrOverflowMsg,"Descriptor Overflow, hence value truncated"); + if( aDes.MaxLength() >= KErrOverflowMsg().Length() + aDes.Length() ) + aDes.Append(KErrOverflowMsg); + } + +namespace DSD +{ + +#ifdef _DEBUG + +#ifdef _OMXIL_COMMON_DEBUG_TRACING_ON + +#define DEBUG_PRINTF(a) {DSD::DebugPrintf(__LINE__, __FILE__, a);} +#define DEBUG_PRINTF2(a, b) {DSD::DebugPrintf(__LINE__, __FILE__, a, b);} +#define DEBUG_PRINTF3(a, b, c) {DSD::DebugPrintf(__LINE__, __FILE__, a, b, c);} +#define DEBUG_PRINTF4(a, b, c, d) {DSD::DebugPrintf(__LINE__, __FILE__, a, b, c, d);} +#define DEBUG_PRINTF5(a, b, c, d, e) {DSD::DebugPrintf(__LINE__, __FILE__, a, b, c, d, e);} + +#define DEBUG_CODE_SECTION(a) TRAP_IGNORE({ a; }) + +// UTF-8 overload of the DebufPrintf method. Should be used by default, +// since it's cheaper both in CPU cycles and stack space. + +inline void DebugPrintf(TInt aLine, char* aFile, TRefByValue aFormat, ...) + { + TTruncateOverflowHandler8 overflowHandler8; + VA_LIST list; + VA_START(list, aFormat); + + TTime now; + now.HomeTime(); + + TBuf8<1024> buffer; + _LIT8(KSwiLogPrefix, "[vidsch] "); + _LIT8(KSwiLineFileFormat, "TID[%d] : [%s:%d] -- "); + buffer.Append(KSwiLogPrefix); + RThread thread; + TUint threadId = thread.Id(); + thread.Close(); + RProcess proc; + TFileName fName = proc.FileName(); + proc.Close(); + buffer.AppendFormat(KSwiLineFileFormat, threadId, aFile, aLine); + buffer.AppendFormatList(aFormat, list ,&overflowHandler8 ); + buffer.Append(_L8("\r\n")); + + RDebug::RawPrint(buffer); + + VA_END(list); + } + +// Unicode DebufPrintf overload + +inline void DebugPrintf(TInt aLine, char* aFile, TRefByValue aFormat, ...) + { + TTruncateOverflowHandler16 overflowHandler16; + VA_LIST list; + VA_START(list, aFormat); + + TTime now; + now.HomeTime(); + + TBuf8<256> header; + _LIT8(KSwiLogPrefix, "[vidsch] "); + _LIT8(KSwiLineFileFormat, "%Ld Line: % 5d, File: %s -- "); + header.Append(KSwiLogPrefix); + header.AppendFormat(KSwiLineFileFormat, now.Int64(), aLine, aFile); + + TBuf<1024> buffer; + buffer.Copy(header); + buffer.AppendFormatList(aFormat, list ,&overflowHandler16); + buffer.Append(_L("\r\n")); + + RDebug::RawPrint(buffer); + + VA_END(list); + } +#else + +#define DEBUG_PRINTF(a) +#define DEBUG_PRINTF2(a, b) +#define DEBUG_PRINTF3(a, b, c) +#define DEBUG_PRINTF4(a, b, c, d) +#define DEBUG_PRINTF5(a, b, c, d, e) + +#define DEBUG_CODE_SECTION(a) + +#endif + +#else + +#define DEBUG_PRINTF(a) +#define DEBUG_PRINTF2(a, b) +#define DEBUG_PRINTF3(a, b, c) +#define DEBUG_PRINTF4(a, b, c, d) +#define DEBUG_PRINTF5(a, b, c, d, e) + +#define DEBUG_CODE_SECTION(a) + +#endif + + +} // namespace DSD + +#endif // __SWI_LOG_H__ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/omxilvideoscheduler.hrh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/omxilvideoscheduler.hrh Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifndef OMXILVIDEOSCHEDULER_HRH_ +#define OMXILVIDEOSCHEDULER_HRH_ + +#define KUidSymbianOmxILVideoSchedulerDll 0x1028663B +#define KUidSymbianOmxILVideoScheduler 0x1028663C + +#endif /*OMXILVIDEOSCHEDULER_HRH_*/ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/omxilvideoscheduler.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/omxilvideoscheduler.rss Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include +#include "omxilvideoscheduler.hrh" + +RESOURCE REGISTRY_INFO theInfo + { + dll_uid = KUidSymbianOmxILVideoSchedulerDll; + interfaces = + { + INTERFACE_INFO + { + interface_uid = KUidOmxILSymbianComponentIf; + implementations = + { + IMPLEMENTATION_INFO + { + implementation_uid = KUidSymbianOmxILVideoScheduler; + version_no = 1; + display_name = "OMX.SYMBIAN.VIDEO.VIDEOSCHEDULER"; + default_data = "video_scheduler.binary"; + } + }; + } + }; + } + diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/omxilvideoschedulerextensionsindexes.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/omxilvideoschedulerextensionsindexes.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef OMXILVIDEOSCHEDULEREXTENSIONSINDEXES_H_ +#define OMXILVIDEOSCHEDULEREXTENSIONSINDEXES_H_ + +/* + * Index for the dropped frame error extension + */ +#define OMX_NokiaIndexParamDroppedFrameEvent 0x7F000001 + +#endif /* OMXILVIDEOSCHEDULEREXTENSIONSINDEXES_H_ */ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/resourcefilereader.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/resourcefilereader.cpp Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,70 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#include +#include +#include "resourcefilereader.h" + + +CResourceFileReader* CResourceFileReader::NewL(const TDesC& aResourceFile) + { + CResourceFileReader* self = CResourceFileReader::NewLC(aResourceFile); + CleanupStack::Pop(self); + return self; + } + +CResourceFileReader* CResourceFileReader::NewLC(const TDesC& aResourceFile) + { + CResourceFileReader* self = new (ELeave) CResourceFileReader(); + CleanupStack::PushL(self); + self->ConstructL(aResourceFile); + return self; + } + +CResourceFileReader::CResourceFileReader() + { + } + +void CResourceFileReader::ConstructL(const TDesC& aResourceFile) + { + User::LeaveIfError(iFs.Connect()); + iResourceFile.OpenL(iFs, aResourceFile); + } + +CResourceFileReader::~CResourceFileReader() + { + iResourceFile.Close(); + iFs.Close(); + } + +void CResourceFileReader::ReadTimerInfoL(TInt64& aInitialRenderTime, TInt64& aMaxLateness) + { + HBufC8* res = iResourceFile.AllocReadLC(TIMER); + TResourceReader reader; + reader.SetBuffer(res); + + aInitialRenderTime = static_cast(reader.ReadInt32()); + aMaxLateness = static_cast(reader.ReadInt32()); + + CleanupStack::PopAndDestroy(res); + } diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/resourcefilereader.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/resourcefilereader.h Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +/** +@file +@internalComponent +*/ + +#ifndef RESOURCEFILEREADER_H +#define RESOURCEFILEREADER_H + +#include +#include + + + + +/** This class is responsible for reading the supplied resource file */ +NONSHARABLE_CLASS(CResourceFileReader) : public CBase + { +public: + static CResourceFileReader* NewL(const TDesC& aResourceFile); + static CResourceFileReader* NewLC(const TDesC& aResourceFile); + ~CResourceFileReader(); + + void ReadTimerInfoL(TInt64& aInitialRenderTime, TInt64& aMaxLateness); + +private: + CResourceFileReader(); + void ConstructL(const TDesC& aResourceFile); + +private: + RFs iFs; + RResourceFile iResourceFile; + }; + +#endif // RESOURCEFILEREADER_H + diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/videoscheduler.rh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/videoscheduler.rh Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#ifndef VIDEOSCHEDULER_RH +#define VIDEOSCHEDULER_RH + + +/** +@publishedPartner +@prototype + +Timed rendering configuration parameters +*/ +STRUCT TIMER_INFO + { + LONG initial_render_time; // initial estimate of how long it takes the sink to render a frame + LONG max_lateness; // how late a buffer can be before it will be dropped + } + +#endif /* VIDEOSCHEDULER_RH */ diff -r 000000000000 -r 5d29cba61097 omxilvideocomps/omxilvideoscheduler/src/videoscheduler.rss --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omxilvideocomps/omxilvideoscheduler/src/videoscheduler.rss Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#include "videoscheduler.rh" + + +/** Timer values for timed mode*/ +RESOURCE TIMER_INFO timer + { + initial_render_time = 20000; + max_lateness = 20000; + } diff -r 000000000000 -r 5d29cba61097 package_definition.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/package_definition.xml Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 000000000000 -r 5d29cba61097 package_map.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/package_map.xml Fri Oct 08 22:09:17 2010 +0100 @@ -0,0 +1,1 @@ +