omxilcomp/omxilaudioemulator/pcmcapturer/src/omxilmicsourceprocessingfunction.h
changeset 0 58be5850fb6c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/omxilcomp/omxilaudioemulator/pcmcapturer/src/omxilmicsourceprocessingfunction.h	Thu Sep 02 20:13:57 2010 +0300
@@ -0,0 +1,234 @@
+// 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 OMXILMICSOURCEPROCESSINGFUNCTION_H
+#define OMXILMICSOURCEPROCESSINGFUNCTION_H
+
+#include <d32soundsc.h>
+#include <openmax/il/khronos/v1_x/OMX_Component.h>
+#include <openmax/il/common/omxilprocessingfunction.h>
+#include <e32msgqueue.h>
+
+/**
+    Mic Source PF Panic category
+*/
+_LIT(KOmxILMicSourcePFPanicCategory, "OmxILPcmCapturerProcFunctionPanic");
+
+// Forward declarations
+class MOmxILClockComponentCmdsIf;
+
+const TInt KMaxNumberOfSharedBuffers = 6;
+
+NONSHARABLE_CLASS(COmxILMicSourceProcessingFunction) :
+	public COmxILProcessingFunction
+	{
+
+public:
+	static COmxILMicSourceProcessingFunction* NewL(MOmxILCallbackNotificationIf& aCallbacks,
+												   MOmxILClockComponentCmdsIf& aClientClockPort);
+
+	~COmxILMicSourceProcessingFunction();
+
+	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_ERRORTYPE MediaTimeIndication(const OMX_TIME_MEDIATIMETYPE& aMediaTime);
+
+	OMX_BOOL BufferRemovalIndication(OMX_BUFFERHEADERTYPE* apBufferHeader, OMX_DIRTYPE aDirection);
+
+	OMX_ERRORTYPE DoBufferAllocation(OMX_U32 aSizeBytes, OMX_U8*& apPortSpecificBuffer, OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition);
+	void DoBufferDeallocation(OMX_PTR apPortSpecificBuffer, OMX_PTR apPortPrivate);
+	OMX_ERRORTYPE DoBufferWrapping(OMX_U32 aSizeBytes, OMX_U8* apBuffer, OMX_PTR& apPortPrivate, OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition);
+	void DoBufferUnwrapping(OMX_PTR apPortSpecificBuffer, OMX_PTR apPortPrivate);
+
+	void FillParamPCMModeType(OMX_AUDIO_PARAM_PCMMODETYPE& aPcmModeType) const;
+	TInt GetVolume() const;
+	
+	OMX_TICKS CalculateTimestamp(TUint64 aBytesTransSinceStart);	
+    void ReleasePendingBufferIfExists();	
+    
+private:
+	COmxILMicSourceProcessingFunction(MOmxILCallbackNotificationIf& aCallbacks,
+									  MOmxILClockComponentCmdsIf& aClientClockPort);
+	void ConstructL();
+
+	void FlushBufferList(RPointerArray<OMX_BUFFERHEADERTYPE>& aBufferList);
+	OMX_ERRORTYPE PostVolumeChangeEvent();
+	OMX_ERRORTYPE PostAudioFormatChangeEvent();
+
+	void ProcessMediaTimeUpdate(const OMX_TIME_MEDIATIMETYPE& aMediaTime);
+	void StartRecording();
+
+	static OMX_U32 ConvertEnumToSampleRate(TSoundRate aEnum);
+	static TSoundRate ConvertEnumToSampleRate(OMX_U32 aSampleRate);
+	static OMX_U32 ConvertEnumToBitsPerSample(TSoundEncoding aEnum);
+
+	void WaitForTransitionToPauseToFinish();
+	void TransitionToPauseFinished();	
+private:
+	OMX_STATETYPE iState;
+	RSoundSc iMicSource;
+	
+	//We have to start recording when:
+	//-We receive a call to move to executing state and clock port is disabled
+	//-We receive a call to move to executing state and the clock is running or vice versa
+	//As a result we must call RecordData() on the driver but may not have an OpenMAX IL
+	//buffer to fill.  On completion of this first RecordData() call if we still do not 
+	//have an OMX buffer to fill then we store the details of the buffer within the shared
+	//chunk in these member variables.  There is no need to queue a second RecordData(),
+	//the driver will continue recording.
+	TInt iInitialPendingBufferOffset;
+	TInt iInitialPendingBufferLength;
+	
+	static const OMX_U32 KSampleRates[];
+
+	class TSharedChunkBufConfig : public TSharedChunkBufConfigBase
+		{
+	public:
+		TInt iBufferOffsetList[KMaxNumberOfSharedBuffers];
+		};
+
+	class TMicrophoneSettings
+		{
+	public:
+		//Settings in RSoundSc
+		TInt iVolume;
+		TBool iMute;
+		TCurrentSoundFormatV02 iCurSoundFormat;
+		TSoundFormatsSupportedV02 iSupportedSoundFormat;
+		} iMicSourceSettings;
+
+	class CBufferQueue : public CActive
+		{
+	public:
+		static CBufferQueue* NewL(COmxILMicSourceProcessingFunction& aParent);
+		~CBufferQueue();
+
+		// from CActive
+		void RunL();
+		void DoCancel();
+
+		void RecordData();
+		void Cleanup();
+
+        void Pause();
+        void Stop();
+        void Resume();
+        
+        OMX_ERRORTYPE AllocateBuffer(OMX_U8*& aPortSpecificBuffer, const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition);
+		OMX_ERRORTYPE UseBuffer(OMX_U8* apBuffer, const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition);
+		void RemoveBuffer(OMX_PTR apPortSpecificBuffer);
+		void FreeBuffer(OMX_PTR aPortSpecificBuffer);
+
+		OMX_ERRORTYPE QueueBuffer(OMX_BUFFERHEADERTYPE* apBufferHeader);
+		OMX_BOOL RemoveBuffer(OMX_BUFFERHEADERTYPE* apBufferHeader);
+		void FlushBuffers(OMX_DIRTYPE aDirection);
+		void FillFirstOpenMaxIlBuffer(TInt aChunkOffset, TInt aLengthOfData);
+
+	private:
+		CBufferQueue(COmxILMicSourceProcessingFunction& aParent);
+		void ConstructL();
+		OMX_ERRORTYPE CreateBuffer(const OMX_PARAM_PORTDEFINITIONTYPE& aPortDefinition);
+		void RemoveBufferFromQueue(OMX_PTR apPortSpecificBuffer);
+		void FillOpenMaxIlBuffer(OMX_BUFFERHEADERTYPE* aBufferHeader, TInt aChunkOffset, TInt aLengthOfData);
+		void EmitEOSBuffer();
+        void FlushDriver();
+
+	private:
+		COmxILMicSourceProcessingFunction& iParent;
+
+		RChunk iSharedChunk;
+		TSharedChunkBufConfig iSharedChuckConfig;
+		TInt iSharedBufferIndex;
+		TInt iRecordedLength;
+
+		TBool iIsSupplier;
+		RFastLock iMutex;
+		RPointerArray<OMX_BUFFERHEADERTYPE> iBuffersToFill;
+		} *iBufferQueue;
+
+
+	class CCommandsQueue : public CActive
+		{
+	public:
+		static CCommandsQueue* NewL(COmxILMicSourceProcessingFunction& aParent);
+		~CCommandsQueue();
+
+		// from CActive
+		void RunL();
+		void DoCancel();
+
+		TInt Pause();
+		TInt Stop();
+        TInt StopAndReset();		
+		TInt RecordData();
+		TInt StartRecording();
+		TInt MediaTimeIndication(const OMX_TIME_MEDIATIMETYPE& aMediaTime);
+		TInt CleanupBufferQueue();
+		TInt CloseDevice();
+		TInt Resume();
+		
+		enum TMessageType
+			{
+			EMsgPause,
+			EMsgStop,
+            EMsgStopAndReset,			
+			EMsgRecord,
+			EMsgStartRecording,
+			EMsgMediaTime,
+			EMsgCleanupBuffer,
+			EMsgCloseDevice,
+			EResume
+			};
+
+		class TProcMessage
+			{
+		public:
+			TMessageType iType;
+			OMX_TIME_MEDIATIMETYPE iMediaTime;
+			};
+
+		RMsgQueue<TProcMessage> iMsgQueue;
+
+	private:
+		CCommandsQueue(COmxILMicSourceProcessingFunction& aParent);
+		void ConstructL();
+
+	private:
+		static const TInt KMaxMsgQueueEntries = 10;
+		COmxILMicSourceProcessingFunction& iParent;
+		} *iCommandsQueue;
+
+	MOmxILClockComponentCmdsIf* ipClientClockPort;
+	OMX_TICKS iMediaStartTime;
+	TUint iTotalBytesRecorded;
+	
+	TBool iStartedRecording;     //To ensure we don't initialise recording twice
+	TThreadId iOwnerThreadId;
+	CActiveSchedulerWait* iTransitionToPauseWait;
+	RSemaphore iTransitionToPauseWaitSemaphore;
+	};
+
+#endif // OMXILMICSOURCEPROCESSINGFUNCTION_H