2010wk38_02 default tip
authorhgs
Fri, 08 Oct 2010 22:09:17 +0100
changeset 0 5d29cba61097
2010wk38_02
mmvideo_plat/omxilvideoextensions_api/group/bld.inf
mmvideo_plat/omxilvideoextensions_api/inc/omxildroppedframeeventextension.h
mmvideo_plat/omxilvideoextensions_api/inc/omxilsymbianvideographicsinkextensions.h
mmvideo_plat/omxilvideoextensions_api/omxilvideoextensions_api.metaxml
omxilvideocomps/group/bld.inf
omxilvideocomps/group/videoomxilcompref.iby
omxilvideocomps/omxil3gpdemuxer/group/bld.inf
omxilvideocomps/omxil3gpdemuxer/group/omxil3gpdemuxer.iby
omxilvideocomps/omxil3gpdemuxer/group/omxil3gpdemuxer.mmp
omxilvideocomps/omxil3gpdemuxer/src/c3gpdemuxer.cpp
omxilvideocomps/omxil3gpdemuxer/src/c3gpdemuxer.h
omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxer.cpp
omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxer.h
omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxeraudiooutputport.cpp
omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxeraudiooutputport.h
omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerconfigmanager.cpp
omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerconfigmanager.h
omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerprocessingfunction.cpp
omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerprocessingfunction.h
omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerrequesthelper.cpp
omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxerrequesthelper.h
omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxertimeinputport.cpp
omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxertimeinputport.h
omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxervideooutputport.cpp
omxilvideocomps/omxil3gpdemuxer/src/comxil3gpdemuxervideooutputport.h
omxilvideocomps/omxil3gpdemuxer/src/log.h
omxilvideocomps/omxil3gpdemuxer/src/omxil3gpdemuxer.hrh
omxilvideocomps/omxil3gpdemuxer/src/omxil3gpdemuxer.rss
omxilvideocomps/omxil3gpdemuxer/src/omxil3gpdemuxerpanic.cpp
omxilvideocomps/omxil3gpdemuxer/src/omxil3gpdemuxerpanic.h
omxilvideocomps/omxil3gpdemuxer/src/taudioformat.h
omxilvideocomps/omxil3gpdemuxer/src/tvideoformat.h
omxilvideocomps/omxil3gpmuxer/group/bld.inf
omxilvideocomps/omxil3gpmuxer/group/omxil3gpmuxer.iby
omxilvideocomps/omxil3gpmuxer/group/omxil3gpmuxer.mmp
omxilvideocomps/omxil3gpmuxer/src/c3gpmuxer.cpp
omxilvideocomps/omxil3gpmuxer/src/c3gpmuxer.h
omxilvideocomps/omxil3gpmuxer/src/c3gpmuxerwriterthreadobserver.cpp
omxilvideocomps/omxil3gpmuxer/src/c3gpmuxerwriterthreadobserver.h
omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxer.cpp
omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxer.h
omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxeraudioinputport.cpp
omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxeraudioinputport.h
omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxerconfigmanager.cpp
omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxerconfigmanager.h
omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxerprocessingfunction.cpp
omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxerprocessingfunction.h
omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxervideoinputport.cpp
omxilvideocomps/omxil3gpmuxer/src/comxil3gpmuxervideoinputport.h
omxilvideocomps/omxil3gpmuxer/src/endwaitao.cpp
omxilvideocomps/omxil3gpmuxer/src/endwaitao.h
omxilvideocomps/omxil3gpmuxer/src/log.h
omxilvideocomps/omxil3gpmuxer/src/omxil3gpmuxer.hrh
omxilvideocomps/omxil3gpmuxer/src/omxil3gpmuxer.rss
omxilvideocomps/omxilclock/group/bld.inf
omxilvideocomps/omxilclock/group/omxilclock.iby
omxilvideocomps/omxilclock/group/omxilclock.mmp
omxilvideocomps/omxilclock/src/clockpanics.cpp
omxilvideocomps/omxilclock/src/clockpanics.h
omxilvideocomps/omxilclock/src/clocksupervisor.cpp
omxilvideocomps/omxilclock/src/clocksupervisor.h
omxilvideocomps/omxilclock/src/clockthreadnotifier.cpp
omxilvideocomps/omxilclock/src/clockthreadnotifier.h
omxilvideocomps/omxilclock/src/comxilclockcomponent.cpp
omxilvideocomps/omxilclock/src/comxilclockcomponent.h
omxilvideocomps/omxilclock/src/comxilclockconfigmanager.cpp
omxilvideocomps/omxilclock/src/comxilclockconfigmanager.h
omxilvideocomps/omxilclock/src/comxilclockoutputport.cpp
omxilvideocomps/omxilclock/src/comxilclockoutputport.h
omxilvideocomps/omxilclock/src/comxilclockprocessingfunction.cpp
omxilvideocomps/omxilclock/src/comxilclockprocessingfunction.h
omxilvideocomps/omxilclock/src/log.h
omxilvideocomps/omxilclock/src/omxilclock.hrh
omxilvideocomps/omxilclock/src/omxilclock.rss
omxilvideocomps/omxilgraphicsink/group/bld.inf
omxilvideocomps/omxilgraphicsink/group/omxilgraphicsink.iby
omxilvideocomps/omxilgraphicsink/group/omxilgraphicsink.mmp
omxilvideocomps/omxilgraphicsink/src/log.h
omxilvideocomps/omxilgraphicsink/src/mmfbuffershared.h
omxilvideocomps/omxilgraphicsink/src/omxilgraphicsink.cpp
omxilvideocomps/omxilgraphicsink/src/omxilgraphicsink.h
omxilvideocomps/omxilgraphicsink/src/omxilgraphicsink.hrh
omxilvideocomps/omxilgraphicsink/src/omxilgraphicsink.rss
omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkextensionsindexes.h
omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkpanics.cpp
omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkpanics.h
omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkprocessingfunction.cpp
omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkprocessingfunction.h
omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkprocessingfunction.inl
omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinktrace.h
omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkvpb0port.cpp
omxilvideocomps/omxilgraphicsink/src/omxilgraphicsinkvpb0port.h
omxilvideocomps/omxilgraphicsink/tsrc/group/bld.inf
omxilvideocomps/omxilgraphicsink/tsrc/group/tsu_omxilgraphicsink.iby
omxilvideocomps/omxilgraphicsink/tsrc/group/tsu_omxilgraphicsink.mmp
omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink.ini
omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_01.script
omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_02.script
omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_03.script
omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_04.script
omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_05.script
omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_06.script
omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_07.script
omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_08.script
omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_09.script
omxilvideocomps/omxilgraphicsink/tsrc/scripts/tsu_omxilgraphicsink_10.script
omxilvideocomps/omxilgraphicsink/tsrc/src/graphicsinktestbase.cpp
omxilvideocomps/omxilgraphicsink/tsrc/src/graphicsinktestbase.h
omxilvideocomps/omxilgraphicsink/tsrc/src/graphicsinkteststeps.cpp
omxilvideocomps/omxilgraphicsink/tsrc/src/graphicsinkteststeps.h
omxilvideocomps/omxilgraphicsink/tsrc/src/omxilgraphicsinksuiteserver.cpp
omxilvideocomps/omxilgraphicsink/tsrc/src/omxilgraphicsinksuiteserver.h
omxilvideocomps/omxilgraphicsink/tsrc/src/omxilgraphicsinktestbase.cpp
omxilvideocomps/omxilgraphicsink/tsrc/src/omxilgraphicsinktestbase.h
omxilvideocomps/omxilgraphicsink/tsrc/src/omxilmmbuffer.cpp
omxilvideocomps/omxilgraphicsink/tsrc/src/omxilmmbuffer.h
omxilvideocomps/omxilvideoscheduler/group/bld.inf
omxilvideocomps/omxilvideoscheduler/group/omxilvideoscheduler.iby
omxilvideocomps/omxilvideoscheduler/group/omxilvideoscheduler.mmp
omxilvideocomps/omxilvideoscheduler/src/buffercopier.cpp
omxilvideocomps/omxilvideoscheduler/src/buffercopier.h
omxilvideocomps/omxilvideoscheduler/src/buffercopierstatemonitor.cpp
omxilvideocomps/omxilvideoscheduler/src/buffercopierstatemonitor.h
omxilvideocomps/omxilvideoscheduler/src/comxilvideoscheduler.cpp
omxilvideocomps/omxilvideoscheduler/src/comxilvideoscheduler.h
omxilvideocomps/omxilvideoscheduler/src/comxilvideoschedulerinputport.cpp
omxilvideocomps/omxilvideoscheduler/src/comxilvideoschedulerinputport.h
omxilvideocomps/omxilvideoscheduler/src/comxilvideoscheduleroutputport.cpp
omxilvideocomps/omxilvideoscheduler/src/comxilvideoscheduleroutputport.h
omxilvideocomps/omxilvideoscheduler/src/comxilvideoschedulerpf.cpp
omxilvideocomps/omxilvideoscheduler/src/comxilvideoschedulerpf.h
omxilvideocomps/omxilvideoscheduler/src/log.h
omxilvideocomps/omxilvideoscheduler/src/omxilvideoscheduler.hrh
omxilvideocomps/omxilvideoscheduler/src/omxilvideoscheduler.rss
omxilvideocomps/omxilvideoscheduler/src/omxilvideoschedulerextensionsindexes.h
omxilvideocomps/omxilvideoscheduler/src/resourcefilereader.cpp
omxilvideocomps/omxilvideoscheduler/src/resourcefilereader.h
omxilvideocomps/omxilvideoscheduler/src/videoscheduler.rh
omxilvideocomps/omxilvideoscheduler/src/videoscheduler.rss
package_definition.xml
package_map.xml
--- /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
--- /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 <openmax/il/khronos/v1_x/OMX_Types.h>
+
+/**
+ * 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_ */
--- /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 <openmax/il/khronos/v1_x/OMX_Types.h>
+
+
+/**
+ * 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
--- /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 @@
+<?xml version="1.0" ?>
+<api id="69d4a4d81e97004c779eb27a0cbf00a4" dataversion="2.0">
+	<name>OpenMAX IL Video Extensions API</name>
+	<description>Symbian-specific extension APIs exposed by the graphic sink and video scheduler OpenMAX IL components.</description>
+	<type>c++</type>
+	<collection>omxilvideocomps</collection>
+	<libs>
+		<!-- The OMX IL components that implement these APIs are ECom plug-ins, so there are no LIBs to link against. -->
+	</libs>
+	<release category="platform" sinceversion="^4" />
+	<attributes>
+		<htmldocprovided>no</htmldocprovided>
+		<adaptation>no<adaptation/>
+	</attributes>
+</api>
--- /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
--- /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 <omxilgraphicsink.iby>
+#include <omxilvideoscheduler.iby>
+
+#endif // VIDEOMXILCOMPREF_IBY
--- /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
--- /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 <streamingcaf.iby>
+
+ECOM_PLUGIN(omxil3gpdemuxer.dll, omxil3gpdemuxer.rsc)
+
+#endif
+
+#endif // OMXIL3GPDEMUXER_IBY
--- /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
--- /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 <openmax/il/common/omxilcallbacknotificationif.h>
+#include <openmax/il/common/omxilutil.h>
+#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<TInt>(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<TInt>(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<TInt>(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<TInt>((iCurrentBuffer->nFilledLen + iCurrentBuffer->nOffset))
+	              ,static_cast<TInt>(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;
+	}
--- /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 <f32file.h>
+#include <e32msgqueue.h>
+#include <c3gplibrary.h>
+
+#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<OMX_BUFFERHEADERTYPE> 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<TBufferMessage> iBufferQueue;
+	TBool iBufferQueueCreated;
+	TBool iWaitingOnBufferQueue;
+
+	TPtr8 iAsyncBuf;
+
+	TBool iParserOpened;
+	TUint iStartTimePosition;
+	TBool iStartKeyFrame;
+	TUint iSeekPosition; // The requested seek time in ms.
+	};
+
+#endif //C3GPDEMUXER_H
--- /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 <openmax/il/common/omxilspecversion.h>
+#include <openmax/il/loader/omxilcomponentif.h>
+#include <openmax/il/loader/omxilsymbiancomponentif.h>
+
+#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<TDesC8> roleList;
+	CleanupClosePushL(roleList);
+	roleList.AppendL(&KSymbianOmxIL3gpDemuxerRole);
+	COmxIL3GPDemuxerConfigManager* configManager = COmxIL3GPDemuxerConfigManager::NewL(KSymbianOmxIL3gpDemuxerName, TOmxILSpecVersion(), roleList, *(static_cast<COmxIL3GPDemuxerProcessingFunction*>(pProcessingFunction)));
+	RegisterConfigurationManager(configManager);
+	CleanupStack::PopAndDestroy(&roleList);
+
+	static_cast<COmxIL3GPDemuxerProcessingFunction*>(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<OMX_OTHER_FORMATTYPE> supportedOtherFormats;
+
+	CleanupClosePushL(supportedOtherFormats);
+	supportedOtherFormats.Append(OMX_OTHER_FormatTime);
+
+	COmxIL3GPDemuxerTimeInputPort* timeInputPort = COmxIL3GPDemuxerTimeInputPort::NewL(portData, supportedOtherFormats,
+														*(static_cast<COmxIL3GPDemuxerProcessingFunction*>(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<COmxIL3GPDemuxerProcessingFunction*>(GetProcessingFunction())));
+	CleanupStack::PushL(audioOutputPort);
+	User::LeaveIfError(AddPort(audioOutputPort, OMX_DirOutput));
+	CleanupStack::Pop();//audioOutputPort
+
+	static_cast<COmxIL3GPDemuxerProcessingFunction*>(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<COmxIL3GPDemuxerProcessingFunction*>(GetProcessingFunction())));
+	CleanupStack::PushL(videoOutputPort);
+	User::LeaveIfError(AddPort(videoOutputPort, OMX_DirOutput));
+	CleanupStack::Pop();//videoOutputPort
+	static_cast<COmxIL3GPDemuxerProcessingFunction*>(GetProcessingFunction())->SetVideoPort(*videoOutputPort);
+	}
+
+OMX_ERRORTYPE SymbianErrorToOmx(TInt aError)
+	{
+	switch(aError)
+		{
+	case KErrNone:
+		return OMX_ErrorNone;
+	case KErrNoMemory:
+		return OMX_ErrorInsufficientResources;
+	default:
+		return OMX_ErrorUndefined;
+		}
+	}
--- /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 <openmax/il/common/omxilcomponent.h>
+
+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
--- /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<OMX_AUDIO_CODINGTYPE> 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<TUint8*>(iMimeTypeBuf.PtrZ());
+	paramPortDefinition.format.audio.cMIMEType = reinterpret_cast<OMX_STRING>(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<TUint>& 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<TUint>& 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<OMX_PARAM_U32TYPE*>(apComponentParameterStructure);
+			u32Type->nU32 = iProcessingFunction->NumAvailableStreams(COmxIL3GPDemuxer::EPortIndexAudioOutput);
+			return OMX_ErrorNone;
+			}
+
+		case OMX_IndexParamActiveStream:
+			{
+			OMX_PARAM_U32TYPE* u32Type = reinterpret_cast<OMX_PARAM_U32TYPE*>(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<const OMX_PARAM_U32TYPE*>(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;
+	}
--- /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 <openmax/il/common/omxilaudioport.h>
+
+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<TUint>& aIndexArray) const;
+	OMX_ERRORTYPE GetLocalOmxConfigIndexes(RArray<TUint>& 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
--- /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 <uri8.h>
+
+#include "comxil3gpdemuxerprocessingfunction.h"
+#include "comxil3gpdemuxerconfigmanager.h"
+#include "c3gpdemuxer.h"
+
+
+
+COmxIL3GPDemuxerConfigManager* COmxIL3GPDemuxerConfigManager::NewL(
+		const TDesC8& aComponentName,
+		const OMX_VERSIONTYPE& aComponentVersion,		
+		const RPointerArray<TDesC8>& 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<TDesC8>& 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<OMX_PARAM_CONTENTURITYPE*>(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<OMX_CONFIG_METADATAITEMTYPE*>(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<const OMX_PARAM_CONTENTURITYPE*>(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<OMX_TIME_CONFIG_TIMESTAMPTYPE*>(apComponentConfigStructure);
+			return iDemuxer->GetVideoTimestamp(timestampType->nTimestamp);
+			}
+
+		case OMX_IndexConfigTimeSeekMode:
+			{
+			OMX_TIME_CONFIG_SEEKMODETYPE* seekModeType = reinterpret_cast<OMX_TIME_CONFIG_SEEKMODETYPE*>(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<const OMX_TIME_CONFIG_TIMESTAMPTYPE*>(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<const OMX_TIME_CONFIG_SEEKMODETYPE*>(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;
+	}
--- /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 <openmax/il/common/omxilconfigmanager.h>
+
+// Forward declarations
+class C3GPDemuxer;
+
+
+NONSHARABLE_CLASS(COmxIL3GPDemuxerConfigManager) : public COmxILConfigManager
+	{
+public:
+	static COmxIL3GPDemuxerConfigManager* NewL(
+		const TDesC8& aComponentName,
+		const OMX_VERSIONTYPE& aComponentVersion,
+		const RPointerArray<TDesC8>& 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<TDesC8>& aComponentRoles);
+
+private:
+	HBufC8* iUri;
+	HBufC* iFilename;
+	C3GPDemuxer* iDemuxer;  // Not owned
+	OMX_TIME_SEEKMODETYPE iSeekMode;
+	COmxIL3GPDemuxerProcessingFunction& iPf;
+	};
+
+#endif //COMXIL3GPDEMUXERCONFIGMANAGER_H
--- /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 <openmax/il/common/omxilcallbacknotificationif.h>
+
+
+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<COmxIL3GPDemuxerProcessingFunction*>(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;
+		}
+	}
+
--- /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 <openmax/il/common/omxilprocessingfunction.h>
+#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
--- /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<COmxIL3GPDemuxerProcessingFunction*>(iProcessingFunction);
+    
+    iOMXError = processingFunction->DoStateTransitionIndication(iNewState);
+    }
+
+void COmxIL3GPDemuxerRequestHelper::DoBufferFlushingIndication()
+    {
+    DEBUG_PRINTF(_L8("COmxIL3GPDemuxerRequestHelper::DoBufferFlushingIndication"));
+    
+    COmxIL3GPDemuxerProcessingFunction* processingFunction = 
+             dynamic_cast<COmxIL3GPDemuxerProcessingFunction*>(iProcessingFunction);
+    
+    iOMXError = processingFunction->DoBufferFlushingIndication(iPortIndex, iDirection);
+    }
+
+void COmxIL3GPDemuxerRequestHelper::DoBufferRemovalIndication()
+    {
+    DEBUG_PRINTF(_L8("COmxIL3GPDemuxerRequestHelper::DoBufferRemovalIndication"));
+    
+    COmxIL3GPDemuxerProcessingFunction* processingFunction = 
+             dynamic_cast<COmxIL3GPDemuxerProcessingFunction*>(iProcessingFunction);
+    
+    iOMXBool = processingFunction->DoBufferRemovalIndication(ipBufferHeader, iDirection);
+    }
+
--- /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 <e32base.h>
+#include <openmax/il/common/omxilprocessingfunction.h>
+
+#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
--- /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<OMX_OTHER_FORMATTYPE>& 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<TUint>& aIndexArray) const
+	{
+	return COmxILOtherPort::GetLocalOmxParamIndexes(aIndexArray);
+	}
+
+OMX_ERRORTYPE COmxIL3GPDemuxerTimeInputPort::GetLocalOmxConfigIndexes(RArray<TUint>& 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;
+	}
--- /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 <openmax/il/common/omxilotherport.h>
+
+class COmxIL3GPDemuxerProcessingFunction;
+
+const TInt KMaxTimeBuffers = 4;
+
+NONSHARABLE_CLASS(COmxIL3GPDemuxerTimeInputPort) : public COmxILOtherPort
+	{
+public:
+	static COmxIL3GPDemuxerTimeInputPort* NewL(const TOmxILCommonPortData& aCommonPortData,
+											   const RArray<OMX_OTHER_FORMATTYPE>& aSupportedOtherFormats,
+	                                           COmxIL3GPDemuxerProcessingFunction& aProcessingFunction);
+	~COmxIL3GPDemuxerTimeInputPort();
+
+	// from COmxILOtherPort
+	OMX_ERRORTYPE GetLocalOmxParamIndexes(RArray<TUint>& aIndexArray) const;
+	OMX_ERRORTYPE GetLocalOmxConfigIndexes(RArray<TUint>& 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
--- /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<OMX_VIDEO_CODINGTYPE> supportedCodings;
+	RArray<OMX_COLOR_FORMATTYPE> 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<OMX_VIDEO_CODINGTYPE>& aSupportedCodings,
+                                                const RArray<OMX_COLOR_FORMATTYPE>& 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<TUint>& 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<TUint>& 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<OMX_PARAM_U32TYPE*>(apComponentParameterStructure);
+			u32Type->nU32 = iProcessingFunction->NumAvailableStreams(COmxIL3GPDemuxer::EPortIndexVideoOutput);
+			return OMX_ErrorNone;
+			}
+
+		case OMX_IndexParamActiveStream:
+			{
+			OMX_PARAM_U32TYPE* u32Type = reinterpret_cast<OMX_PARAM_U32TYPE*>(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<const OMX_PARAM_U32TYPE*>(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;
+	}
--- /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 <openmax/il/common/omxilvideoport.h>
+
+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<TUint>& aIndexArray) const;
+	OMX_ERRORTYPE GetLocalOmxConfigIndexes(RArray<TUint>& 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<OMX_VIDEO_CODINGTYPE>& aSupportedCodings,
+            const RArray<OMX_COLOR_FORMATTYPE>& aSupportedColourFormats);
+	
+private:
+	COmxIL3GPDemuxerProcessingFunction* iProcessingFunction;	// not owned
+	};
+
+#endif //COMXIL3GPDEMUXERVIDEOOUTPUTPORT_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 <e32debug.h>
+
+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<const TDesC8> 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<const TDesC16> 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__
--- /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_*/
--- /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 <ecom/registryinfo.rh>
+#include <openmax/il/loader/omxilcomponentif.hrh>
+#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";
+					}
+				};
+			}
+		};
+	}
+
--- /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 <e32base.h>
+
+_LIT(KPanicString, "omxil3gpdemuxer");
+
+void Panic(TPanicCode aCode)
+	{
+	User::Panic(KPanicString, aCode);
+	}
--- /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
--- /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 <openmax/il/khronos/v1_x/OMX_Audio.h>
+
+class TAudioFormat
+	{
+
+public:
+
+	OMX_AUDIO_CODINGTYPE iCoding;
+	OMX_U32 iFramesPerSample;
+	OMX_U32 iSampleRate;
+	OMX_U32 iAverageBitrate;
+
+	};
+
+#endif /*TAUDIOFORMAT_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 <openmax/il/khronos/v1_x/OMX_Video.h>
+
+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_*/
--- /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
--- /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 <streamingcaf.iby>
+
+ECOM_PLUGIN(omxil3gpmuxer.dll, omxil3gpmuxer.rsc)
+
+#endif
+
+#endif // OMXIL3GPMUXER_IBY
--- /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
--- /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 <openmax/il/common/omxilcallbacknotificationif.h>
+
+_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<C3GPMuxer*>(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<TInt>(aFrameWidth);
+	iVideoSize.iHeight = static_cast<TInt>(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<TReal>(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<const TUint8*>(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<TUint8*>(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<OMX_BUFFERHEADERTYPE*>& 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;
+		}
+	}
--- /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 <e32base.h>
+#include <e32std.h>
+#include <f32file.h>
+#include <e32msgqueue.h>
+#include <openmax/il/khronos/v1_x/OMX_Core.h>
+#include <c3gplibrary.h>
+
+#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<OMX_BUFFERHEADERTYPE*>& 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<OMX_BUFFERHEADERTYPE*> iAudioQueue;
+	RMsgQueue<OMX_BUFFERHEADERTYPE*> iVideoQueue;
+	OMX_BUFFERHEADERTYPE* iAudioBuffer;	 
+	OMX_BUFFERHEADERTYPE* iCurrentVideoBuffer;	 
+	TBool iComposerOpened;
+	TUint iAudioFrameDuration;
+	RThread iThread;
+	RMutex iQueMutex;	
+	TBool iThreadRunning;
+	CEndWaitAO* iEndWaitAO;
+	RMsgQueue<OMX_BUFFERHEADERTYPE*> iRemoveQueue;
+	TBool iPaused;
+	TBool iMuxerInvalid;
+	RBuf8 iPartialFrame;
+	OMX_BUFFERHEADERTYPE* iNextVideoBuffer;	 
+	TInt64 iVideoDuration;
+	TUint iRemoveQueueLength;
+	TBool iRemoveQueueNeedsReallocation;
+	TBool iRequestOutstanding;
+	};
+
+#endif //C3GPMUXER_H
--- /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;
+    }
--- /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 <openmax/il/common/omxilprocessingfunction.h>
+
+//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_*/
--- /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 <openmax/il/loader/omxilsymbiancomponentif.h>
+
+#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<TDesC8> roleList;
+	CleanupClosePushL(roleList);
+	roleList.AppendL(&KSymbianOmxIL3gpMuxerRole);
+	COmxIL3GPMuxerConfigManager* configManager = COmxIL3GPMuxerConfigManager::NewL(KSymbianOmxIL3gpMuxerName, TOmxILSpecVersion(), roleList);
+	RegisterConfigurationManager(configManager);
+	CleanupStack::PopAndDestroy();
+
+	static_cast<COmxIL3GPMuxerProcessingFunction*>(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<COmxIL3GPMuxerProcessingFunction*>(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<COmxIL3GPMuxerProcessingFunction*>(GetProcessingFunction())->SetAudioPort(*audioInputPort);
+	}
+
+OMX_ERRORTYPE SymbianErrorToOmx(TInt aError)
+	{
+	switch(aError)
+		{
+	case KErrNone:
+		return OMX_ErrorNone;
+	case KErrNoMemory:
+		return OMX_ErrorInsufficientResources;
+	default:
+		return OMX_ErrorUndefined;
+		}
+	}
--- /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 <openmax/il/common/omxilcomponent.h>
+
+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
--- /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<OMX_AUDIO_CODINGTYPE> 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<TUint8*>(iMimeTypeBuf.PtrZ());
+	GetParamPortDefinition().format.audio.cMIMEType = reinterpret_cast<OMX_STRING>(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<TUint>& aIndexArray) const
+	{
+	return COmxILAudioPort::GetLocalOmxParamIndexes(aIndexArray);
+	}
+
+OMX_ERRORTYPE COmxIL3GPMuxerAudioInputPort::GetLocalOmxConfigIndexes(RArray<TUint>& 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;
+	}
--- /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 <openmax/il/common/omxilaudioport.h>
+
+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<TUint>& aIndexArray) const;
+	OMX_ERRORTYPE GetLocalOmxConfigIndexes(RArray<TUint>& 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*/
--- /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 <uri8.h>
+
+#include "comxil3gpmuxerconfigmanager.h"
+#include "log.h"
+
+COmxIL3GPMuxerConfigManager* COmxIL3GPMuxerConfigManager::NewL(
+		const TDesC8& aComponentName,
+		const OMX_VERSIONTYPE& aComponentVersion,
+		const RPointerArray<TDesC8>& 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<TDesC8>& 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<OMX_PARAM_CONTENTURITYPE*>(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<const OMX_PARAM_CONTENTURITYPE*>(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;
+	}
--- /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 <openmax/il/common/omxilconfigmanager.h>
+
+NONSHARABLE_CLASS(COmxIL3GPMuxerConfigManager) : public COmxILConfigManager
+	{
+public:
+	static COmxIL3GPMuxerConfigManager* NewL(
+		const TDesC8& aComponentName,
+		const OMX_VERSIONTYPE& aComponentVersion,
+		const RPointerArray<TDesC8>& 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<TDesC8>& aComponentRoles);	
+
+private:
+	HBufC8* iUri;
+	HBufC* iFilename;
+	};
+
+#endif //COMXIL3GPMUXERCONFIGMANAGER_H
--- /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 <openmax/il/common/omxilcallbacknotificationif.h>
+#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;
+		}
+	}
--- /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 <openmax/il/common/omxilprocessingfunction.h>
+
+// 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
--- /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<OMX_VIDEO_CODINGTYPE> supportedCodings;
+	RArray<OMX_COLOR_FORMATTYPE> 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<OMX_VIDEO_CODINGTYPE>& aSupportedCodings,
+                                const RArray<OMX_COLOR_FORMATTYPE>& 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<TUint>& aIndexArray) const
+	{
+	OMX_ERRORTYPE omxRetValue = COmxILVideoPort::GetLocalOmxParamIndexes(aIndexArray);
+	if (omxRetValue != OMX_ErrorNone)
+		{
+		return omxRetValue;
+		}
+	
+	return OMX_ErrorNone;
+	}
+
+OMX_ERRORTYPE COmxIL3GPMuxerVideoInputPort::GetLocalOmxConfigIndexes(RArray<TUint>& 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;
+	}
--- /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 <openmax/il/common/omxilvideoport.h>
+
+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<TUint>& aIndexArray) const;
+	OMX_ERRORTYPE GetLocalOmxConfigIndexes(RArray<TUint>& 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<OMX_VIDEO_CODINGTYPE>& aSupportedCodings,
+            const RArray<OMX_COLOR_FORMATTYPE>& aSupportedColourFormats);
+	};
+
+#endif //COMXIL3GPMUXERVIDEOINPUTPORT_H
--- /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 <e32debug.h>
+#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);
+	}
--- /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 <e32base.h>
+
+class CEndWaitAO : public CAsyncOneShot
+	{
+public:
+	static CEndWaitAO* NewL();
+	~CEndWaitAO();
+	
+protected:
+	void RunL();
+	void DoCancel();
+	
+private:
+	CEndWaitAO();
+	
+	RThread iSchedulerThread;
+	};
+
+#endif /*ENDWAITAO_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 <e32debug.h>
+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<const TDesC8> 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<const TDesC16> 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__
--- /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_*/
--- /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 <ecom/registryinfo.rh>
+#include <openmax/il/loader/omxilcomponentif.hrh>
+#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";
+					}
+				};
+			}
+		};
+	}
+
--- /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
--- /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
--- /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
--- /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 <e32base.h>
+
+_LIT(KClockPanicCategory, "omxilclock");
+
+void Panic(TClockPanicCode aCode)
+	{
+	User::Panic(KClockPanicCategory, aCode);
+	}
--- /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_*/
--- /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 <hal.h>
+#include <openmax/il/khronos/v1_x/OMX_Other.h>	// OMX port
+#include <openmax/il/common/omxilspecversion.h>	// 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<TUint64>(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<TInt64>(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<TInt>(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<CClockSupervisor*>(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<TBool>(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<OMX_TIME_MEDIATIMETYPE*>(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<OMX_U32>(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<OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE*>(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<OMX_TIME_CONFIG_TIMESTAMPTYPE*>(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<OMX_TIME_CONFIG_TIMESTAMPTYPE*>(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<OMX_TIME_CONFIG_TIMESTAMPTYPE*>(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<OMX_TIME_CONFIG_TIMESTAMPTYPE*>(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<OMX_TIME_CONFIG_TIMESTAMPTYPE*>(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<OMX_TIME_CONFIG_SCALETYPE*>(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<OMX_TIME_CONFIG_CLOCKSTATETYPE*>(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<OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE*>(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<OMX_TIME_MEDIATIMETYPE*>(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<TInt32>(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
--- /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 <e32base.h>
+#include <openmax/il/khronos/v1_x/OMX_Other.h>
+
+/**
+ @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<TInt64> 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_
--- /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();
+    }
--- /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 <openmax/il/common/omxilprocessingfunction.h>
+
+//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_ */
--- /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 <openmax/il/common/omxilspecversion.h>
+#include <openmax/il/loader/omxilcomponentif.h>
+#include <openmax/il/loader/omxilsymbiancomponentif.h>
+
+#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<TDesC8> roleList;
+	CleanupClosePushL(roleList);
+	roleList.AppendL(&KSymbianOmxILClockRoleDes);
+	COmxILClockConfigManager* configManager = COmxILClockConfigManager::NewL(KSymbianOmxILClockNameDes, 
+							TOmxILSpecVersion(), roleList, *(static_cast<COmxILClockProcessingFunction*>(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<OMX_OTHER_FORMATTYPE> supportedOtherFormats;
+
+	CleanupClosePushL(supportedOtherFormats);
+	supportedOtherFormats.AppendL(OMX_OTHER_FormatTime);
+
+	COmxILClockOutputPort* port = COmxILClockOutputPort::NewL(portData, supportedOtherFormats,
+															*(static_cast<COmxILClockProcessingFunction*>(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;
+		}
+	}
--- /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 <openmax/il/common/omxilcomponent.h>
+
+
+
+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<COmxILClockOutputPort> iPorts;	
+	};
+	
+#endif //COMXILCLOCKOUTPUTPORT_H
--- /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<TDesC8>& 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<TDesC8>& 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<TAny*>(apComponentConfigStructure));
+	if(error != OMX_ErrorUnsupportedIndex)
+		{
+		return error;
+		}
+
+	// try base class if PF did not support the index
+	return COmxILConfigManager::SetConfig(aConfigIndex, apComponentConfigStructure);
+	}
+
--- /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 <openmax/il/common/omxilconfigmanager.h>
+
+
+
+// Forward declarations
+class COmxILClockProcessingFunction;
+
+class COmxILClockConfigManager : public COmxILConfigManager
+	{
+public:
+	static COmxILClockConfigManager* NewL(
+		const TDesC8& aComponentName,
+		const OMX_VERSIONTYPE& aComponentVersion,
+		const RPointerArray<TDesC8>& 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<TDesC8>& aComponentRoles);
+
+private:
+	COmxILClockProcessingFunction* iProcessingFunction;	// not owned
+	};
+
+#endif //COMXILCLOCKCONFIGMANAGER_H
--- /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<OMX_OTHER_FORMATTYPE>& 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<OMX_OTHER_FORMATTYPE>& aSupportedFormats)
+	{
+	COmxILOtherPort::ConstructL(aCommonPortData, aSupportedFormats);
+	}
+
+COmxILClockOutputPort::~COmxILClockOutputPort()
+	{
+	}
+	
+OMX_ERRORTYPE COmxILClockOutputPort::GetLocalOmxParamIndexes(RArray<TUint>& aIndexArray) const
+	{
+	return COmxILOtherPort::GetLocalOmxParamIndexes(aIndexArray);
+	}
+
+OMX_ERRORTYPE COmxILClockOutputPort::GetLocalOmxConfigIndexes(RArray<TUint>& 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<TAny*>(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;
+	}
--- /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 <openmax/il/common/omxilotherport.h>
+
+
+
+class COmxILClockProcessingFunction;
+
+class COmxILClockOutputPort : public COmxILOtherPort
+	{
+public:
+	static COmxILClockOutputPort* NewL(const TOmxILCommonPortData& aCommonPortData, const RArray<OMX_OTHER_FORMATTYPE>& aSupportedFormats, COmxILClockProcessingFunction& aProcessingFunction);
+	~COmxILClockOutputPort();
+
+	TInt BufferCount() const;
+
+	// from COmxILOtherPort
+	OMX_ERRORTYPE GetLocalOmxParamIndexes(RArray<TUint>& aIndexArray) const;
+	OMX_ERRORTYPE GetLocalOmxConfigIndexes(RArray<TUint>& 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<OMX_OTHER_FORMATTYPE>& aSupportedFormats);
+	
+private:
+	COmxILClockProcessingFunction* iProcessingFunction;	// not owned
+	};
+
+#endif //COMXILCLOCKOUTPUTPORT_H
--- /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 <openmax/il/common/omxilutil.h>
+#include "comxilclockprocessingfunction.h"
+#include "comxilclockcomponent.h"
+#include "clocksupervisor.h"
+#include <openmax/il/common/omxilcallbacknotificationif.h>
+#include "clockpanics.h"
+#include "omxilclock.hrh"
+
+#include <openmax/il/common/omxilspecversion.h>
+
+
+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<OMX_BUFFERHEADERTYPE*>* queue = new(ELeave) CCirBuf<OMX_BUFFERHEADERTYPE*>();
+		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<OMX_BUFFERHEADERTYPE*>& 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<OMX_BUFFERHEADERTYPE*>& 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<class T>
+static TBool RemoveFromPool(CCirBuf<T>&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<OMX_BUFFERHEADERTYPE*>& 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<OMX_BUFFERHEADERTYPE*>& 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?
+	}
+
--- /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 <openmax/il/common/omxilprocessingfunction.h>
+#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<CCirBuf<OMX_BUFFERHEADERTYPE*> > iBufferQueues;
+	RMutex iBufferMutex;
+	TBool iExecuting;
+  	};
+
+#endif //COMXILCLOCKPROCESSINGFUNCTION_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 <e32debug.h>
+
+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<const TDesC8> 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<const TDesC16> 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__
--- /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_*/
--- /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 <ecom/registryinfo.rh>
+#include <openmax/il/loader/omxilcomponentif.hrh>
+#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;
+					}
+				};
+			}
+		};
+	}
+
--- /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
--- /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
--- /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
--- /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 <e32debug.h>
+
+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<const TDesC8> 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<const TDesC16> 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__
--- /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 <e32cmn.h>
+
+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
--- /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 <openmax/il/common/omxilconfigmanager.h>
+#include <openmax/il/common/omxilspecversion.h>
+
+#include "omxilgraphicsink.h"
+#include "omxilgraphicsinkvpb0port.h"
+#include "omxilgraphicsinkprocessingfunction.h"
+#include "omxilgraphicsink.hrh"
+#include <openmax/il/loader/omxilsymbiancomponentif.h>
+#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<TDesC8> 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<OMX_VIDEO_CODINGTYPE> supportedVideoFormats;
+	RArray<OMX_COLOR_FORMATTYPE> 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;
+   }
--- /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 <openmax/il/common/omxilcomponent.h>
+
+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
--- /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
+
--- /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 <ecom/registryinfo.rh>
+#include <openmax/il/loader/omxilcomponentif.hrh>
+#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 = "<i>0x1027379e<s>VORB<d> P16";
+					}
+				};
+			}
+		};
+	}
+
--- /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_
--- /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 <e32base.h>
+
+_LIT(KGraphicSinkPanicCategory, "omxilgraphicsink");
+
+/**
+Raises a panic.
+@param The panic to be raised.
+*/
+void Panic(TGraphicSinkPanicCode aCode)
+	{
+	User::Panic(KGraphicSinkPanicCategory, aCode);
+	}
--- /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_*/
--- /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 <hal.h>
+#include <graphics/suerror.h>
+#include "omxilgraphicsinkextensionsindexes.h"
+#include <openmax/il/shai/OMX_Symbian_ComponentExt.h>
+#include <openmax/il/common/omxilcallbacknotificationif.h>
+
+// 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; i<bufferCount; i++)
+			{
+			pBufferHeader = iBuffersToEmpty[i];
+			pBufferHeader->nTickCount = 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<const OMX_PARAM_PORTDEFINITIONTYPE*>(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<const OMX_VIDEO_PARAM_PORTFORMATTYPE*>(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<const OMX_CONFIG_SCALEFACTORTYPE*>(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<const OMX_FRAMESIZETYPE*>(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<const OMX_CONFIG_RECTTYPE*>(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<TUint32*>(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<TUint32*>(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;
+    }
--- /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 <e32msgqueue.h>
+#include <openmax/il/common/omxilprocessingfunction.h>
+#include <openmax/il/extensions/omxilsymbianvideographicsinkextensions.h>
+#include <openmax/il/khronos/v1_x/OMX_Video.h>
+#include <graphics/surface.h>
+#include <graphics/surfacemanager.h>
+#include <graphics/surfaceupdateclient.h>
+#include <graphics/surfaceconfiguration.h>
+#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<OMX_BUFFERHEADERTYPE>& 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<OMX_BUFFERHEADERTYPE> 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<TInt> 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<TInt> 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<TMessageType> 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
+
--- /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<OMX_BUFFERHEADERTYPE>& 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;
+    }
--- /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 <mmvideoperformance.h>
+
+/*
+ * 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__
--- /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 <e32std.h>
+#include "omxilgraphicsinkvpb0port.h"
+#include <openmax/il/khronos/v1_x/OMX_Component.h>
+#include <openmax/il/shai/OMX_Symbian_ExtensionNames.h>
+#include <w32std.h>
+#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<OMX_VIDEO_CODINGTYPE>& aSupportedVideoFormats,
+		const RArray<OMX_COLOR_FORMATTYPE>& 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<OMX_VIDEO_CODINGTYPE>& aSupportedVideoFormats,
+                                const RArray<OMX_COLOR_FORMATTYPE>& 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<TUint8*>(iMimeTypeBuf.PtrZ());
+ 	GetParamPortDefinition().format.video.cMIMEType = reinterpret_cast<OMX_STRING>(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<TUint>& 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<TUint>& 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<OMX_SYMBIAN_VIDEO_PARAM_SURFACECONFIGURATION*>(apComponentParameterStructure);
+			*videoSurface = iParamVideoSurfaceConfiguration;
+			break;
+			}
+		case OMX_IndexParamVideoPortFormat:
+			{
+			OMX_VIDEO_PARAM_PORTFORMATTYPE* compvideoPortFormat = static_cast<OMX_VIDEO_PARAM_PORTFORMATTYPE*>(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<const OMX_VIDEO_PARAM_PORTFORMATTYPE*>(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<OMX_CONFIG_SCALEFACTORTYPE*>(apComponentParameterStructure);
+			*scaleFactor = iConfigScaleFactor;
+			break;
+			}
+		case OMX_IndexConfigCommonOutputSize:
+			{
+			OMX_FRAMESIZETYPE* frameSize = static_cast<OMX_FRAMESIZETYPE*>(apComponentParameterStructure);
+			*frameSize = iConfigFrameSize;
+			break;
+			}
+		case OMX_IndexConfigCommonInputCrop:
+		case OMX_IndexConfigCommonOutputCrop:
+		case OMX_IndexConfigCommonExclusionRect:
+			{
+			OMX_CONFIG_RECTTYPE* rec = static_cast<OMX_CONFIG_RECTTYPE*>(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<const OMX_CONFIG_SCALEFACTORTYPE*>(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<const OMX_FRAMESIZETYPE*>(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<const OMX_CONFIG_RECTTYPE*>(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<const TUint8*>(reinterpret_cast<TUint8*>(aParameterName)));
+	
+	// OMX_NokiaIndexParamGraphicSurfaceConfig
+	TPtrC8 parameterNamePtr(reinterpret_cast<const TUint8*>(sOmxSymbianGfxSurfaceConfig));
+	if (requestedParameterNamePtr == parameterNamePtr)
+		{
+		*apIndexType = static_cast<OMX_INDEXTYPE>(OMX_NokiaIndexParamGraphicSurfaceConfig);
+		return OMX_ErrorNone;   
+		}
+	   
+    // OMX_SymbianIndexConfigSharedChunkMetadata
+	TPtrC8 parameterNamePtr2(reinterpret_cast<const TUint8*>(OMX_SYMBIAN_INDEX_CONFIG_SHAREDCHUNKMETADATA_NAME));
+	if(requestedParameterNamePtr == parameterNamePtr2)
+        {
+        *apIndexType = static_cast<OMX_INDEXTYPE>(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<char*>(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);
+    }
--- /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 <openmax/il/common/omxilvideoport.h>
+#include "omxilgraphicsinkprocessingfunction.h"
+#include <openmax/il/extensions/omxilsymbianvideographicsinkextensions.h>
+#include <openmax/il/shai/OMX_Symbian_ComponentExt.h>
+#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<OMX_VIDEO_CODINGTYPE>& aSupportedVideoFormats,
+		const RArray<OMX_COLOR_FORMATTYPE>& aSupportedColorFormats,
+		COmxILGraphicSinkProcessingFunction& aGraphicSinkPF);
+	
+	~COmxILGraphicSinkVPB0Port();
+
+	OMX_ERRORTYPE GetLocalOmxParamIndexes(RArray<TUint>& aIndexArray) const;
+	OMX_ERRORTYPE GetLocalOmxConfigIndexes(RArray<TUint>& 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<OMX_VIDEO_CODINGTYPE>& aSupportedVideoFormats,
+	        const RArray<OMX_COLOR_FORMATTYPE>& 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
--- /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
--- /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
--- /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
--- /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
--- /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
--- /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
--- /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
--- /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
--- /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
--- /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
--- /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
--- /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
--- /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
--- /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
--- /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 <e32math.h>
+#include <openmax/il/shai/OMX_Symbian_ExtensionNames.h>
+#include <openmax/il/shai/OMX_Symbian_ComponentExt.h>
+
+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<OMX_COMPONENTTYPE*>(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<OMX_COMPONENTTYPE*>(aComponent);
+	if (comp == iCameraSourceCompHandle &&
+	        aEvent == OMX_EventCmdComplete &&
+	        aData1 == OMX_CommandPortDisable &&
+	        (aData2 == KCameraVCPortIndex || aData2 == KCameraClockPortIndex))
+	    {
+	    return;
+	    }
+*/	
+	OMX_ERRORTYPE errorEvent = static_cast<OMX_ERRORTYPE>( 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<char*>(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<TSurfaceConfiguration*>(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<COmxILMMBuffer*>(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<OMX_BUFFERHEADERTYPE>* 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<OMX_BUFFERHEADERTYPE> 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; index<aNumOfActualBuffer; ++index)
+		{
+		//TODO: TUint8* surfacePtr = aCamBuf->Chunk().Base() + aCamBuf->BufferOffset();
+		TUint8* surfacePtr = aCamBuf.Base() + (iOmxParamPortInput.nBufferSize * index);
+		TUint8* linePtr = surfacePtr;
+		
+		TUint16* ptr = reinterpret_cast<TUint16*>(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);
+		}
+	}
--- /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 <openmax/il/extensions/omxilsymbianvideographicsinkextensions.h>
+#include <graphics/surfaceconfiguration.h>
+#include <graphics/surfaceupdateclient.h>
+#include <openmax/il/common/omxilspecversion.h>
+
+#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<OMX_BUFFERHEADERTYPE>* aBufferHeaders,
+			OMX_U32 aPortIndex,TBool aSendCommand = ETrue);
+	void FreeBufferTaskAlt(RPointerArray<OMX_BUFFERHEADERTYPE> 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<OMX_BUFFERHEADERTYPE> iInputBufferHeaders;
+	RPointerArray<OMX_BUFFERHEADERTYPE> 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
--- /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 <openmax/il/shai/OMX_Symbian_ExtensionNames.h>
+#include <openmax/il/shai/OMX_Symbian_ComponentExt.h>
+
+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<maxComponentNameSize> componentNameBuf8;
+	componentNameBuf8 = const_cast<const TUint8*>(reinterpret_cast<TUint8*>(componentNameArray));
+	TBuf<maxComponentNameSize> componentNameBuf16;
+	// INFO_PRINTF2(_L("Component Name length: %d"), componentNameBuf8.Length());
+	componentNameBuf16.Copy(componentNameBuf8);
+	componentNameBuf16.PtrZ();
+	const TBuf<maxComponentNameSize> 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<char*>(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();
+	}
--- /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
--- /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;
+	}
--- /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 <test/testexecuteserverbase.h>
+
+
+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
--- /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 <mmf/server/mmfbuffer.h>
+#include <mmf/server/mmfdatabuffer.h>
+
+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<OMX_BUFFERHEADERTYPE*>(msg.iBuffer));
+				break;
+				}
+
+			case EFillBufferCallback:
+				{
+				//iCameraSourceTest.DoFillBufferDone(msg.iComponent,static_cast<CCameraBuffer*>(msg.iBuffer));
+				iCameraSourceTest.DoFillBufferDone(msg.iComponent, static_cast<OMX_BUFFERHEADERTYPE*>(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<CCameraBuffer*>(aBuffer->pAppPrivate);
+	return static_cast<CCallbackHandler*>(aAppData)->DoFillBufferDone(aComponent, aBuffer);
+	}
+
+OMX_ERRORTYPE
+CCallbackHandler::EmptyBufferDone(OMX_HANDLETYPE aComponent,
+									 TAny* aAppData,
+									 OMX_BUFFERHEADERTYPE* aBuffer)
+	{
+	ASSERT(aAppData);
+	//CCameraBuffer* pBuffer = static_cast<CCameraBuffer*>(aBuffer->pAppPrivate);
+	return static_cast<CCallbackHandler*>(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<CCallbackHandler*>(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 <OMX_BUFFERHEADERTYPE*>(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 <OMX_BUFFERHEADERTYPE*> (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<OMX_BUFFERHEADERTYPE> 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<OMX_BUFFERHEADERTYPE>* 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);
+	}
--- /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 <test/testexecutestepbase.h>
+#include <e32msgqueue.h>
+#include <openmax/il/khronos/v1_x/OMX_Core.h>
+#include <graphics/surfacemanager.h>
+#include <graphics/surfaceupdateclient.h>
+#include <w32std.h>
+
+#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<TOmxMessage> 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<OMX_BUFFERHEADERTYPE> aArrayBufferHeaderType,
+            OMX_ERRORTYPE aExpError = OMX_ErrorNone);
+	
+    void AllocateBuffer(
+    		OMX_HANDLETYPE aComponent,
+    		OMX_BUFFERHEADERTYPE** aBufferHeaderType,
+            OMX_U32 aPortIndex,
+            OMX_PTR aAppPrivate,
+            OMX_U32 aSizeBytes,
+            RPointerArray<OMX_BUFFERHEADERTYPE>* 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<KMaxLenStateTransitionName> iStateTransitionName;
+
+private:
+
+	void RunL();
+	
+private:
+
+	COmxGsTestBase* iOmxGsTest;
+	TTimeIntervalMicroSeconds32 iInterval;
+	};
+
+
+
+#endif // OMXILGRAPHICSINKTESTBASE_H
--- /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<RChunk&>(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<TInt>& COmxILMMBuffer::OffsetInfoArray()
+	{
+	return iArrayOffsets;
+	}
--- /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 <e32base.h>
+#include <e32cmn.h>
+#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 <pixelformats.h>
+#include <pixelformats_camera.h>
+#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 <graphics/surface.h>
+#include <graphics/surfacemanager.h>
+#include <openmax/il/khronos/v1_x/OMX_Component.h>
+
+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<TInt>& OffsetInfoArray();
+	
+private:
+	COmxILMMBuffer(const RChunk& aChunk);
+	COmxILMMBuffer(const COmxILMMBuffer& aCamBuf);
+	
+private:
+	TSurfaceId iSurfaceId;
+	RSurfaceManager::TSurfaceInfoV01 iSurfaceInfo;
+	RChunk& iChunk;
+	TThreadId iChunkOwnerThreadId;
+	
+	RArray<TInt> iArrayOffsets;
+	};
+
+#endif //OMXILMMBUFFER_H
--- /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
--- /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 <omxilcomp.iby>
+
+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
--- /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
--- /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<OMX_BUFFERHEADERTYPE*>& 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<OMX_BUFFERHEADERTYPE*>& 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;
+	}
--- /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 <e32base.h>
+#include <e32msgqueue.h>
+#include <openmax/il/khronos/v1_x/OMX_Core.h>
+
+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<OMX_BUFFERHEADERTYPE*>& aQueue, OMX_BUFFERHEADERTYPE* aBufferHeader);
+
+	MBufferCopierIf& iCallback;
+	RMsgQueue<OMX_BUFFERHEADERTYPE*> iInQueue;
+	RMsgQueue<OMX_BUFFERHEADERTYPE*> iOutQueue;
+	RMsgQueue<OMX_BUFFERHEADERTYPE*> iRemoveQueue;
+	OMX_BUFFERHEADERTYPE* iInBuffer;
+	};
+
+#endif /*BUFFERCOPIER_H_*/
--- /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();
+    }
--- /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 <e32base.h>
+#include <e32std.h>
+
+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_ */
--- /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 <openmax/il/common/omxilspecversion.h>
+#include <openmax/il/common/omxilconfigmanager.h>
+#include <openmax/il/loader/omxilcomponentif.h>
+#include <openmax/il/loader/omxilsymbiancomponentif.h>
+#include <openmax/il/common/omxilclientclockport.h>
+
+#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<TDesC8> 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<OMX_OTHER_FORMATTYPE> 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;
+		}
+	}
--- /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 <openmax/il/common/omxilcomponent.h>
+
+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_*/
--- /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<OMX_VIDEO_CODINGTYPE> supportedCodings;
+	RArray<OMX_COLOR_FORMATTYPE> 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<OMX_VIDEO_CODINGTYPE>& aSupportedCodings,
+                                    const RArray<OMX_COLOR_FORMATTYPE>& 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<TUint8*>(iMimeTypeBuf.PtrZ());
+ 	GetParamPortDefinition().format.video.cMIMEType = reinterpret_cast<OMX_STRING>(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<TUint>& 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<TUint>& 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<OMX_NOKIA_PARAM_DROPPEDFRAMEEVENT*>(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<const OMX_NOKIA_PARAM_DROPPEDFRAMEEVENT*>(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<TUint8*>(iMimeTypeBuf.PtrZ());
+ 	GetParamPortDefinition().format.video.cMIMEType = reinterpret_cast<OMX_STRING>(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<const TUint8*>(reinterpret_cast<TUint8*>(aParameterName)));
+
+    TPtrC8 parameterName(reinterpret_cast<const TUint8*>(sOmxNokiaIndexParamDroppedFrameEvent));
+    
+    if (receivedParameterName == parameterName)
+        {
+        *apIndexType = static_cast<OMX_INDEXTYPE>(OMX_NokiaIndexParamDroppedFrameEvent);
+        return OMX_ErrorNone;
+        }
+    
+    *apIndexType = OMX_IndexMax;
+    return OMX_ErrorUnsupportedIndex;
+    }
+
--- /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 <openmax/il/common/omxilvideoport.h>
+#include <openmax/il/extensions/omxildroppedframeeventextension.h>
+
+NONSHARABLE_CLASS(COmxILVideoSchedulerInputPort) : public COmxILVideoPort
+	{
+public:
+	static COmxILVideoSchedulerInputPort* NewL(const TOmxILCommonPortData& aCommonPortData);
+
+	~COmxILVideoSchedulerInputPort();
+
+	TUint32 BufferCount() const;
+	
+	// from COmxILVideoPort	
+	OMX_ERRORTYPE GetLocalOmxParamIndexes(RArray<TUint>& aIndexArray) const;
+	OMX_ERRORTYPE GetLocalOmxConfigIndexes(RArray<TUint>& 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<OMX_VIDEO_CODINGTYPE>& aSupportedCodings,
+            const RArray<OMX_COLOR_FORMATTYPE>& 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_*/
--- /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<OMX_VIDEO_CODINGTYPE> supportedCodings;
+	RArray<OMX_COLOR_FORMATTYPE> 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<OMX_VIDEO_CODINGTYPE>& aSupportedCodings,
+                                            const RArray<OMX_COLOR_FORMATTYPE>& 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<TUint8*>(iMimeTypeBuf.PtrZ());
+ 	GetParamPortDefinition().format.video.cMIMEType = reinterpret_cast<OMX_STRING>(pTUint);
+
+	GetSupportedVideoFormats().AppendL(OMX_VIDEO_CodingUnused);
+	GetSupportedColorFormats().AppendL(OMX_COLOR_FormatUnused);
+	}
+
+OMX_ERRORTYPE COmxILVideoSchedulerOutputPort::GetLocalOmxParamIndexes(RArray<TUint>& aIndexArray) const
+	{
+	return COmxILVideoPort::GetLocalOmxParamIndexes(aIndexArray);
+	}
+
+OMX_ERRORTYPE COmxILVideoSchedulerOutputPort::GetLocalOmxConfigIndexes(RArray<TUint>& 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<TUint8*>(iMimeTypeBuf.PtrZ());
+ 	GetParamPortDefinition().format.video.cMIMEType = reinterpret_cast<OMX_STRING>(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;
+	}
--- /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 <openmax/il/common/omxilvideoport.h>
+
+
+
+NONSHARABLE_CLASS(COmxILVideoSchedulerOutputPort) : public COmxILVideoPort
+	{
+public:
+	static COmxILVideoSchedulerOutputPort* NewL(const TOmxILCommonPortData& aCommonPortData);
+
+	~COmxILVideoSchedulerOutputPort();
+
+	TUint32 BufferCount() const;
+	
+	// from COmxILVideoPort	
+	OMX_ERRORTYPE GetLocalOmxParamIndexes(RArray<TUint>& aIndexArray) const;
+	OMX_ERRORTYPE GetLocalOmxConfigIndexes(RArray<TUint>& 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<OMX_VIDEO_CODINGTYPE>& aSupportedCodings,
+            const RArray<OMX_COLOR_FORMATTYPE>& aSupportedColourFormats);
+	
+private:
+    //Mime Type is not important for uncompressed video but is required for the port definition structure.
+	RBuf8 iMimeTypeBuf;
+	};
+
+#endif /*COMXILVIDEOSCHEDULEROUTPUTPORT_H_*/
--- /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 <openmax/il/common/omxilutil.h>
+
+#include "comxilvideoschedulerpf.h"
+#include "comxilvideoscheduler.h"
+#include "resourcefilereader.h"
+#include "buffercopierstatemonitor.h"
+#include "omxilvideoschedulerextensionsindexes.h"
+#include <openmax/il/extensions/omxildroppedframeeventextension.h>
+#include <openmax/il/common/omxilcallbacknotificationif.h>
+#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<const OMX_NOKIA_PARAM_DROPPEDFRAMEEVENT*>(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<OMX_BUFFERHEADERTYPE*>(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<RMutex&>(iMutex).IsHeld(), Panic(EPanicMutexUnheld));
+	
+	TBool found = EFalse;
+		
+	for (TInt i=0; i<iWaitingBuffers.Count(); ++i)
+		{
+		if ((iWaitingBuffers[i] == aBuffer) && (iWaitingBuffers[i]->nTimeStamp == 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<OMX_BUFFERHEADERTYPE*>(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<RMutex&>(iMutex);
+	if(mutex.IsHeld())
+		{
+		mutex.Signal();
+		}
+	User::Panic(KVideoSchedulerPanicCategory, aPanicCode);
+	}
--- /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 <e32std.h>
+#include <openmax/il/common/omxilprocessingfunction.h>
+#include <openmax/il/khronos/v1_x/OMX_Component.h>
+#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<OMX_BUFFERHEADERTYPE> iWaitingBuffers; // all waiting buffers, including those that received time updates
+	TUint32 iOutputBufferSentCount;	// Only allowed to send 2 buffers at a time
+	RArray<TBufferMessage> 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_*/
--- /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 <e32debug.h>
+
+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<const TDesC8> 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<const TDesC16> 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__
--- /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_*/
--- /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 <ecom/registryinfo.rh>
+#include <openmax/il/loader/omxilcomponentif.hrh>
+#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";
+					}
+				};
+			}
+		};
+	}
+
--- /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_ */
--- /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 <barsread.h>
+#include <videoscheduler.rsg>
+#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<TInt64>(reader.ReadInt32());
+	aMaxLateness = static_cast<TInt64>(reader.ReadInt32());
+	
+	CleanupStack::PopAndDestroy(res);
+	}
--- /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 <e32base.h>
+#include <barsc.h>
+
+
+
+
+/** 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
+
--- /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 */
--- /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;
+	}
--- /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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<SystemDefinition schema="3.0.0">
+	<package id="mmvideo" name="Multimedia Video" tech-domain="mm">
+		<collection id="mmvideo_plat" name="mmvideo Platform APIs">
+			<component id="omxilvideoextensions_api" name="OpenMAX IL Video Extensions" introduced="^4">
+				<meta rel="Api" href="mmvideo_plat/omxilvideoextensions_api/omxilvideoextensions_api.metaxml" />
+				<unit bldFile="mmvideo_plat/omxilvideoextensions_api/group" />
+			</component>
+		</collection>
+		<collection id="omxilvideocomps">
+			<component id="omxilvideocomps_iby" introduced="^4">
+				<!-- This is not a proper component, it just exports the collection-wide "videoomxilcompref.iby" -->
+				<unit bldFile="omxilvideocomps/group" />
+			</component>
+			<component id="omxil3gpdemuxer" name="OpenMAX IL 3GP Demuxer Component" introduced="^4">
+				<unit bldFile="omxilvideocomps/omxil3gpdemuxer/group" />
+			</component>
+			<component id="omxil3gpmuxer" name="OpenMAX IL 3GP Muxer Component" introduced="^4">
+				<unit bldFile="omxilvideocomps/omxil3gpmuxer/group" />
+			</component>
+			<component id="omxilclock" name="OpenMAX IL Clock Component" introduced="^4">
+				<unit bldFile="omxilvideocomps/omxilclock/group" />
+			</component>
+			<component id="omxilgraphicsink" name="OpenMAX IL Graphics Sink Component" introduced="^4">
+				<unit bldFile="omxilvideocomps/omxilgraphicsink/group" />
+				<unit bldFile="omxilvideocomps/omxilgraphicsink/tsrc/group" />
+			</component>
+			<component id="omxilvideoscheduler" name="OpenMAX IL Video Scheduler Component" introduced="^4">
+				<unit bldFile="omxilvideocomps/omxilvideoscheduler/group" />
+			</component>
+		</collection>
+	</package>
+</SystemDefinition>
--- /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 @@
+<PackageMap root="sf" layer="os"/>