mmdevicefw/mdfunittest/codecapi/omxvorbis/src/tsu_mdf_omxvorbiscodecs_record.cpp
changeset 0 79dd3e2336a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmdevicefw/mdfunittest/codecapi/omxvorbis/src/tsu_mdf_omxvorbiscodecs_record.cpp	Fri Oct 08 19:40:43 2010 +0100
@@ -0,0 +1,470 @@
+// Copyright (c) 2006-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 "tsu_mdf_omxvorbiscodecs_record.h"
+#include <openmax/il/khronos/v1_x/OMX_Core.h>
+#include <mmf/server/mmfhwdevicesetup.h>
+#include <mdf/mdfpuconfig.h>
+
+// for the bitrate custom interface
+#include <mmf/server/devsoundstandardcustominterfaces.h>
+
+//
+// RTestStepOmxVorbisCodecRecord
+// record a Vorbis file
+
+/**
+ * Constructor
+ */
+RTestStepOmxVorbisCodecRecord::RTestStepOmxVorbisCodecRecord()
+ 	{
+ 	iTestStepName = _L("MM-MDF-OMXVORBISCODECS-U-0002-HP");
+	iHeapSize = KTestHeapSize;
+ 	}
+
+/**
+ * So that CRecordAudioFile can set the test verdict and output messages
+ */
+void RTestStepOmxVorbisCodecRecord::SetVerdict(TPtrC16 aText, TVerdict aVerdict)
+	{
+	iVerdict = aVerdict;
+	INFO_PRINTF2(_L("---> %s"), aText.Ptr());
+	}
+
+/**
+ * Do the test step
+ */
+TVerdict RTestStepOmxVorbisCodecRecord::DoTestStepL()
+	{
+	iRecordAudioFile = CRecordAudioFile::NewL(this);
+	iRecordAudioFile->StartL();
+	delete iRecordAudioFile;
+	return iVerdict;
+	}
+
+// instructs the Hw Device Adapter to record a file	
+CRecordAudioFile::CRecordAudioFile(RTestStepOmxVorbisCodecs* aParent) : 
+	CActive(EPriorityNormal),
+	iState(EHwDeviceCreateAndInit),
+	iParent(aParent)
+	{
+	}
+
+//
+// CRecordAudioFile
+// Active recorder for RTestStepOmxVorbisCodecRecord and derived test classes.
+
+/**
+ * ConstructL
+ */
+void CRecordAudioFile::ConstructL()
+	{
+	CActiveScheduler::Add(this);
+	}
+
+/**
+ * NewL
+ */
+CRecordAudioFile* CRecordAudioFile::NewL(RTestStepOmxVorbisCodecs* aParent)
+	{
+	CRecordAudioFile* self = new (ELeave) CRecordAudioFile(aParent);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+	
+/**
+ * StartL
+ */
+void CRecordAudioFile::StartL()	
+	{
+	SetState(EHwDeviceCreateAndInit);
+	CActiveScheduler::Start();
+	}
+	
+/**
+ * @see CActive
+ */
+void CRecordAudioFile::DoCancel()
+	{
+	}
+
+/**
+ * Destructor
+ */
+CRecordAudioFile::~CRecordAudioFile()
+	{
+	}	
+
+/**
+ * SetState
+ */
+void CRecordAudioFile::SetState(TRecordAudioFileState aState)
+	{
+	iState = aState;
+	SetActive();	
+	TRequestStatus* status = &iStatus;
+	User::RequestComplete(status, KErrNone);	
+	}
+
+/**
+ * ReadTestFileInBuffer
+ * reads file into buffer referenced by iSourceFile
+ */
+TInt CRecordAudioFile::ReadTestFileInBuffer()
+	{
+	// we don't need to strip off the wav header
+
+	RFs fs;
+	fs.Connect();
+	
+	RFile file;
+	TInt err = file.Open(fs, KTestEncoderPlayFile, EFileRead);
+	if (err == KErrNone)
+		{
+		TInt size; 
+		err = file.Size(size);
+		if (err == KErrNone)
+			{			
+	 		iSourceFile = HBufC8::NewMax(size);
+	 		if(!iSourceFile)
+	 			{
+	 			return KErrNoMemory;
+	 			}
+	 		TPtr8 ptr = iSourceFile->Des();
+    		file.Read(ptr,size);
+    		file.Close();
+			}
+		fs.Close();
+		}
+    return err;
+	}
+
+/**
+ * @see MMMFHwDeviceObserver
+ */
+TInt CRecordAudioFile::FillThisHwBuffer(CMMFBuffer& aHwDataBuffer)
+	{	
+	// RDebug::Print(_L("CRecordAudioFile::FillThisHwBuffer"));
+
+	ReadNextBuffer(aHwDataBuffer);
+	return KErrNone;
+	}
+
+/**
+ * @see MMMFHwDeviceObserver
+ */
+TInt CRecordAudioFile::EmptyThisHwBuffer(CMMFBuffer& aEmptyBufferPtr)
+	{
+	// RDebug::Print(_L("CRecordAudioFile::EmptyThisHwBuffer"));
+
+	CMMFDataBuffer* dataBuffer = static_cast<CMMFDataBuffer*>(&aEmptyBufferPtr);
+	TInt err = KErrNone;
+	if(dataBuffer->Data().Size()) 
+		{
+		RDebug::Print(_L("CRecordAudioFile writing buffer size %d"), dataBuffer->Data().Size());
+		err = WriteDataToFile(dataBuffer->Data());
+		if(err != KErrNone)
+			{
+			return err;
+			}
+		}
+	
+	err = iHwDevice->ThisHwBufferEmptied(aEmptyBufferPtr);
+	if(err != KErrNone)
+		{
+		return err;
+		}
+
+	if(dataBuffer->LastBuffer())
+		{
+		SetState(EHwDeviceEncodeCheckData);		
+		iHwDevice->Stop();
+		}
+	return err;	
+	}
+
+TInt CRecordAudioFile::WriteDataToFile(TDes8& aData)
+	{
+	TInt err = KErrNone;	
+	err = iRecordFile.Write(aData);
+	if(err != KErrNone)
+		{
+		return err;
+		}
+	// keep record of amount of data and the number of buffers written out
+	iWrittenDataTotal += aData.Size();	
+	iBuffersWrittenCount++;	
+	RDebug::Print(_L("CRecordAudioFile:  buffers written %d, total bytes %d"), iBuffersWrittenCount, iWrittenDataTotal);
+	return err;
+	}
+	
+/**
+ * opens record file
+ */
+TInt CRecordAudioFile::SetUpRecordFile()
+	{
+	iFileServerSession.Connect();
+	TInt err = iRecordFile.Replace(iFileServerSession, KTestEncoderRecordedFile, EFileWrite|EFileShareExclusive);	
+	return err;
+	}
+
+/**
+ * closes record file
+ */
+void CRecordAudioFile::CloseRecordFile()
+	{
+	iRecordFile.Close();
+	iFileServerSession.Close();	
+	}
+
+/**
+ * send chunks of data into the encoder.
+ */
+void CRecordAudioFile::ReadNextBuffer(CMMFBuffer& aHwDataBuffer)
+    {
+	// check if finished
+	if (iFinished) 
+		{
+		iHwDevice->ThisHwBufferFilled(aHwDataBuffer);
+		SetState(EHwDeviceAllowToComplete);
+		return;
+		}
+		
+	// get a chunk of data and send it straight to the encoder
+	CMMFDataBuffer* dataBuffer = static_cast<CMMFDataBuffer*>(&aHwDataBuffer);
+	
+	TInt srcLength = iSourceFile->Size();
+	if (iSourceFileReadPos < srcLength)
+		{
+	    TUint8* data_pointer = const_cast<TUint8*>(dataBuffer->Data().Ptr());
+			
+		TInt size = srcLength - iSourceFileReadPos;
+		if (size > dataBuffer->Data().MaxLength())
+			{
+			size = dataBuffer->Data().MaxLength();			
+			}
+		Mem::Copy((TAny*)data_pointer, (TAny*)iSourceFile->Mid(iSourceFileReadPos).Ptr(), size);
+
+		// set buffer size into the CMMFBuffer
+		dataBuffer->Data().SetLength(size);
+		iSourceFileReadPos += size;	
+					
+		RDebug::Print(_L("CRecordAudioFile::data read = %d bytes"), iSourceFileReadPos);
+		
+		// callback
+		iHwDevice->ThisHwBufferFilled(aHwDataBuffer);
+		}
+	else 
+		{
+		// no more data
+		RDebug::Print(_L("CRecordAudioFile::end of data"));
+		iFinished = ETrue;
+		dataBuffer->SetLastBuffer(ETrue);
+		iHwDevice->ThisHwBufferFilled(aHwDataBuffer);
+		SetState(EHwDeviceAllowToComplete);
+		}
+    }
+
+/**
+ * @see CActive
+ */
+void CRecordAudioFile::RunL()
+	{
+	THwDeviceInitParams initParams;
+	TInt err;	
+	switch (iState)
+		{
+		case EHwDeviceCreateAndInit:
+			{		
+			err = OMX_Init();
+			if (err != KErrNone)
+				{
+				iParent->SetVerdict(_L("The OMX Core cannot be initialised"), EFail);
+				SetState(EHwDeviceError);
+				}	
+			initParams.iHwDeviceObserver = this;
+
+			// now using the AudioCodecTestAdapter
+			TRAP(err, iHwDevice = CMMFHwDevice::NewL(TUid::Uid(KUidHwDeviceAudioCodecTestAdapter)));
+			if (err != KErrNone)
+				{
+				iParent->SetVerdict(_L("The Hw Device Adapter cannot be created"), EFail);
+				OMX_Deinit();
+				SetState(EHwDeviceError);
+				}
+			MMdfHwDeviceSetup* setup = (MMdfHwDeviceSetup*)iHwDevice->CustomInterface(KUidHwDeviceSetupInterface);
+			if (setup != NULL)
+				{
+				//Record is pcm16 -> pcmU8	
+				setup->SetDataTypesL(KMMFFourCCCodePCM16, KMMFFourCCCodeTestVorbis);	
+				}				
+			err = iHwDevice->Init(initParams);
+			if (err != KErrNone)
+				{
+				CleanupAndSetDeviceError(_L("The Hw Device Adapter cannot be initialised"));
+				break;
+				}
+			iParent->SetVerdict(_L("The Hw Device Adapter created & initialised"));	
+			SetState(EHwDeviceStartEncode);			
+			break;
+			}
+		case EHwDeviceStartEncode:
+			{			
+			// if we are playing a file, first we have to open the file
+			err = ReadTestFileInBuffer();
+			if (err == KErrNotFound)
+				{
+				CleanupAndSetDeviceError(_L("Cannot open the file to be played"));
+				break;
+				}
+			iParent->SetVerdict(_L("The file to be played has opened successfully"));
+			
+			err = SetUpRecordFile();			
+			if (err)
+				{
+				CleanupAndSetDeviceError(_L("Cannot open the file to record"));
+				break;
+				}
+			
+			// configure the HwDevice
+			TTaskConfig config;
+			config.iUid = KUidTTaskConfig;
+			config.iRate = KTestSampleRate;
+			config.iStereoMode = KTestNumChannels;
+			err = iHwDevice->SetConfig(config);
+			if (err != KErrNone)
+				{
+				CleanupAndSetDeviceError(_L("The Hw Device Adapter cannot configure"));
+				break;
+				}
+				
+			// set bitrate in the encoder - this requires a custom interface
+			MMMFDevSoundCustomInterfaceBitRate* bitrateCI = (MMMFDevSoundCustomInterfaceBitRate*)iHwDevice->CustomInterface(KUidCustomInterfaceDevSoundBitRate);
+			if (bitrateCI == NULL)
+				{
+				CleanupAndSetDeviceError(_L("The Hw Device Adapter cannot find a bitrate custom interface"));
+				break;
+				}
+			else 
+				{
+				TRAP(err, bitrateCI->SetBitRateL(KTestBitRate));			
+				if (err != KErrNone)
+					{
+					CleanupAndSetDeviceError(_L("The Hw Device Adapter failed to set the bitrate"));
+					break;
+					}
+				}
+					
+			// tell the HwDeviceAdapter to record the file
+			err = iHwDevice->Start(EDevEncode, EDevOutFlow);
+			if (err != KErrNone)
+				{
+				CleanupAndSetDeviceError(_L("The Hw Device Adapter cannot start"));
+				break;
+				}
+			iParent->SetVerdict(_L("The Hw Device Adapter has started successfully"));
+			SetState(EHwDeviceAllowToComplete);			
+			break;
+			}
+		case EHwDeviceEncodeCheckData:			
+			{
+			iParent->SetVerdict(_L("The Hw Device Adapter has stopped successfully"));
+			TInt fileSize = 0;
+			err = iRecordFile.Size(fileSize);
+			if(err != KErrNone)
+				{
+				CleanupAndSetDeviceError(_L("Problem with accessing the file after writing to it"));
+				break;
+				}
+				
+			// check the recorded file against expected file size for the test to pass.
+			if(fileSize != KTestEncoderRecordedFileExpectedSize) 
+				{
+				CleanupAndSetDeviceError(_L("Unexpected amount of data written to file"));
+				break;
+				}
+			// encode succeeded
+			SetState(EHwDeviceDone);
+			break;
+			}
+		case EHwDeviceAllowToComplete:
+			break;
+		case EHwDeviceDone:
+			{
+			delete iHwDevice;
+			OMX_Deinit();	
+			Cancel();
+			CActiveScheduler::Stop();
+			CloseRecordFile();
+			break;
+			}
+		case EHwDeviceError:
+			{
+			CActiveScheduler::Stop();
+			CloseRecordFile();
+			break;
+			}
+		default:
+			{
+			CleanupAndSetDeviceError(_L("Unknown CRecordAudioFile iState"));
+			break;
+			}
+		}
+	}
+	
+/**
+ * will close down the hardware device on error
+ */
+void CRecordAudioFile::CleanupAndSetDeviceError(TPtrC16 aText)
+	{
+	iParent->SetVerdict(aText, EFail);
+	delete iHwDevice;
+	OMX_Deinit();	
+	SetState(EHwDeviceError);
+	}
+
+/**
+ * @see MMMFHwDeviceObserver
+ */
+void CRecordAudioFile::Error(TInt aError)
+	{
+	// Completion is signified by KErrUnderflow	
+	if (aError == KErrUnderflow && iStoppedReceived)
+		{
+		iParent->SetVerdict(_L("Success"));
+		}
+	else
+		{
+		iParent->SetVerdict(_L("Error from Hw Device"), EFail);
+		}
+	SetState(EHwDeviceDone);	
+	}
+	
+/**
+ * @see MMMFHwDeviceObserver
+ */
+void CRecordAudioFile::Stopped()
+	{
+	iStoppedReceived = ETrue;
+	}
+
+// end