os/mm/mmdevicefw/mdfunittest/codecapi/omxvorbis/hwdeviceadapter/audiocodectestadapter.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // This is a re-implementation of CMdfHwDeviceCodecTestAdapter 
    15 // primarily intended for unit testing codec PUs in PREQ1024.
    16 // It is NOT a subclass, as CMdfHwDeviceCodecTestAdapter itself has no
    17 // virtual or protected methods to override.
    18 // The only difference is that it encodes and decodes from codec
    19 // to codec, unlike CMdfHwDeviceCodecTestAdapter which encodes from sounddev
    20 // (mic) to codec and decodes from codec to sounddev (speaker)
    21 // 
    22 //
    23 
    24 /**
    25  @file
    26  @internalComponent
    27 */
    28 
    29 #include "audiocodectestadapter.h"
    30 #include <mdf/codecapiuids.hrh>
    31 #include <mdf/mdfpuconfig.h>
    32 // for the bitrate custom interface
    33 #include <mmf/server/devsoundstandardcustominterfaces.h>
    34 
    35 #include <e32debug.h>
    36 
    37 // #define AUDIOCODECTESTADAPTER_DEBUG	1
    38 #if defined(AUDIOCODECTESTADAPTER_DEBUG)
    39 #define DEBUG_PRINT RDebug::Print
    40 #else
    41 #define DEBUG_PRINT
    42 #endif
    43 
    44 // Interface UID for the Processing Unit Loader
    45 const TUid KUidPuLoader = {KUidPuLoaderImplementation};
    46 
    47 
    48 CMdfHwDeviceCodecTestAdapter::~CMdfHwDeviceCodecTestAdapter()
    49 	{
    50 	Stop();
    51 	// Unload the PUs
    52 	if (iCodecPU)
    53 		{
    54 		iPuLoader->UnloadProcessingUnit(iCodecPU);
    55 		}
    56 		
    57 	// The I/O ports should have been deleted at this point
    58 
    59 	delete iInputBuffer;
    60 	delete iOutputBuffer;		
    61 	delete iActiveWait;
    62 	delete iPuLoader;	
    63 	REComSession::DestroyedImplementation(iPuLoaderDtorKey);
    64 	}
    65 
    66 CMdfHwDeviceCodecTestAdapter* CMdfHwDeviceCodecTestAdapter::NewL()
    67 	{
    68 	CMdfHwDeviceCodecTestAdapter* self = new (ELeave) CMdfHwDeviceCodecTestAdapter;
    69 	CleanupStack::PushL (self);
    70 	self->ConstructL();
    71 	CleanupStack::Pop(self);
    72 	return self;
    73 	}
    74 	
    75 CMdfHwDeviceCodecTestAdapter::CMdfHwDeviceCodecTestAdapter()
    76 	{	
    77 	}
    78 	
    79 void CMdfHwDeviceCodecTestAdapter::ConstructL()
    80 	{		
    81 	// Load the PU Loader plugin
    82 	iPuLoader = static_cast<CMdfPuLoader*>
    83 		(REComSession::CreateImplementationL(KUidPuLoader, iPuLoaderDtorKey));
    84 	iActiveWait = new (ELeave) CActiveSchedulerWait;
    85 	iState = EProcessingUnitLoaderLoaded;
    86 	}	
    87 	
    88 TInt CMdfHwDeviceCodecTestAdapter::Start(TDeviceFunc aFuncCmd, TDeviceFlow /*aFlowCmd*/)
    89 	{		
    90 	if (!((aFuncCmd == EDevEncode)|(aFuncCmd == EDevDecode)|(aFuncCmd == EDevNullFunc)))
    91 		{
    92 		return KErrArgument;	
    93 		}
    94 		
    95 	iFuncCmd = aFuncCmd;
    96 	
    97 	// NB: aFlowCmd not used - this is codec-codec processing by default.
    98 
    99 	TInt err = KErrNone;
   100 	switch(aFuncCmd)
   101 		{
   102 		case EDevEncode:
   103 			{
   104 			err = StartEncode();
   105 			}
   106 			break;
   107 		case EDevDecode:
   108 			{
   109 			err = StartDecode();
   110 			}
   111 			break;
   112 		case EDevNullFunc:
   113 		default:
   114 			{
   115 			err = KErrNotSupported;	
   116 			}		
   117 			break;
   118 		}
   119 
   120 	
   121 	return err;
   122 	}
   123 	
   124 // encode and decode logic is identical for codec-codec processing
   125 	
   126 TInt CMdfHwDeviceCodecTestAdapter::InitializeEncodeDecode()
   127 	{
   128 	DEBUG_PRINT(_L("CMdfHwDeviceCodecTestAdapter::InitializeEncodeDecode"));
   129 	
   130 	ASSERT(iOutputPort);
   131 	
   132 	iInputPortBufferSize = iInputPort->MipBufferSize();	
   133 	TRAPD(err, iInputBuffer = CMMFDescriptorBuffer::NewL(iInputPortBufferSize));
   134 	if(err != KErrNone)
   135 		{
   136 		return err;
   137 		}
   138 	iInputBuffer->SetLastBuffer(EFalse);
   139 	iInputPort->MipUseBuffer(*iInputBuffer);	
   140 	
   141 	iOutputPortBufferSize = iOutputPort->MopBufferSize();			
   142 	TRAP(err, iOutputBuffer = CMMFDescriptorBuffer::NewL(iOutputPortBufferSize));
   143 	if(err != KErrNone)
   144 		{
   145 		return err;
   146 		}	
   147 	iOutputBuffer->SetLastBuffer(EFalse);
   148 	iOutputPort->MopUseBuffer(*iOutputBuffer);		
   149 
   150 	// VD: should not move the set up of the state after sending the Initialize() calls???
   151 	iState = EProcessingUnitInitializing;
   152 		
   153 	iCodecPU->Initialize();
   154 	
   155 	iActiveWait->Start();
   156 	return KErrNone;
   157 	}
   158 
   159 TInt CMdfHwDeviceCodecTestAdapter::StartEncode()
   160 	{
   161 	DEBUG_PRINT(_L("CMdfHwDeviceCodecTestAdapter::StartEncode"));
   162 	TInt err = KErrNone;
   163 	if (iState == EProcessingUnitLoaded)
   164 		{
   165 		err = InitializeEncodeDecode();
   166 		}
   167 	if (err != KErrNone)
   168 		{
   169 		return err;
   170 		}
   171 			
   172 	return StartExecuting();	
   173 	}
   174 	
   175 TInt CMdfHwDeviceCodecTestAdapter::StartDecode()
   176 	{
   177 	DEBUG_PRINT(_L("CMdfHwDeviceCodecTestAdapter::StartDecode"));
   178 	
   179 	TInt err = KErrNone;
   180 	if (iState == EProcessingUnitLoaded)
   181 		{
   182 		err = InitializeEncodeDecode();
   183 		}
   184 	if (err != KErrNone)
   185 		{
   186 		return err;
   187 		}
   188 			
   189 	return StartExecuting();	
   190 	}
   191 
   192 TInt CMdfHwDeviceCodecTestAdapter::StartExecuting()
   193 	{
   194 	DEBUG_PRINT(_L("CMdfHwDeviceCodecTestAdapter::StartExecuting"));
   195 	TInt err = KErrNone;
   196 
   197 	iOutputPort->MopReadData(*iOutputBuffer);	
   198 	err = iHwDeviceObserver->FillThisHwBuffer(*iInputBuffer);
   199 	if(err != KErrNone)
   200 		{
   201 		return err;
   202 		}
   203 		
   204 	iState = EProcessingUnitExecuting;
   205 	iCodecPU->Execute();
   206 	
   207 	return KErrNone;
   208 	}
   209 	
   210 TInt CMdfHwDeviceCodecTestAdapter::Stop()
   211 	{	
   212 	if(iState == EProcessingUnitExecuting || iState == EProcessingUnitPaused)
   213 		{			
   214 		iStopping = ETrue; // is used as a guard in ExecuteComplete
   215 				
   216 		if(iCodecPU)
   217 			{
   218 			iCodecPU->Stop();	
   219 			}
   220 				
   221 		iPCMPUCallbackComplete = EFalse;		
   222 				
   223 		iState = EProcessingUnitIdle;
   224 		iStopping = EFalse;	
   225 		}
   226 	return KErrNone;			
   227 	}
   228 
   229 TInt CMdfHwDeviceCodecTestAdapter::Pause()
   230 	{
   231 	return iCodecPU->Pause();
   232 	}
   233 	
   234 TInt CMdfHwDeviceCodecTestAdapter::Init(THwDeviceInitParams& aDevInfo)
   235 	{
   236 	if(!iCodecPU)
   237 		{
   238 		return KErrNotSupported;
   239 		}
   240 
   241 	// Not currently using any other members of aDevInfo, except the Observer
   242 	if(!aDevInfo.iHwDeviceObserver)
   243 		{
   244 		return KErrArgument;
   245 		}
   246 	iHwDeviceObserver = aDevInfo.iHwDeviceObserver;
   247 	
   248 	// Get ports and set observers
   249 	RPointerArray<MMdfInputPort> inputPorts;
   250 	TInt err = iCodecPU->GetInputPorts(inputPorts);
   251 	if(err != KErrNone)
   252 		{
   253 		return err;
   254 		}	
   255 		
   256 	if (inputPorts.Count()<1)
   257 		{
   258 		return KErrNotFound;
   259 		}
   260 		
   261 	iInputPort = inputPorts[0];
   262 	inputPorts.Close();
   263 	
   264 	iInputPort->MipSetObserver(*this);
   265 
   266 	RPointerArray<MMdfOutputPort> outputPorts;
   267 	err = iCodecPU->GetOutputPorts(outputPorts);
   268 	if(err != KErrNone)
   269 		{
   270 		return err;
   271 		}	
   272 		
   273 	if (outputPorts.Count()<1)
   274 		{
   275 		return KErrNotFound;
   276 		}
   277 		
   278 	iOutputPort = outputPorts[0];
   279 	outputPorts.Close();
   280 	iOutputPort->MopSetObserver(*this);
   281 	
   282 	iState = EProcessingUnitLoaded;
   283 		
   284 	return KErrNone;		
   285 	}
   286 
   287 TAny* CMdfHwDeviceCodecTestAdapter::CustomInterface(TUid aInterfaceId)
   288 	{
   289 	if (aInterfaceId == KUidHwDeviceSetupInterface)
   290 		{
   291 		return static_cast<MMdfHwDeviceSetup*>(this);
   292 		}
   293 	else if (aInterfaceId.iUid == KMmfPlaySettingsCustomInterface)
   294 		{
   295 		return reinterpret_cast<MPlayCustomInterface*>(iInputPort);
   296 		}
   297 	else if (aInterfaceId.iUid == KMmfRecordSettingsCustomInterface)
   298 		{
   299 		return reinterpret_cast<MRecordCustomInterface*>(iOutputPort);
   300 		}
   301 	// if the PU is an encoder it may have a BitRate custom interface	
   302 	else if (aInterfaceId == KUidCustomInterfaceDevSoundBitRate)
   303 		{
   304 		return static_cast<MMMFDevSoundCustomInterfaceBitRate*>(iCodecPU->CustomInterface(aInterfaceId));
   305 		}
   306 	else	
   307 		{
   308 		return NULL;
   309 		}
   310 	}
   311 
   312 TInt CMdfHwDeviceCodecTestAdapter::ThisHwBufferFilled(CMMFBuffer& aFillBufferPtr)
   313 	{		
   314 	DEBUG_PRINT(_L("CMdfHwDeviceCodecTestAdapter::ThisHwBufferFilled"));
   315 	
   316 	aFillBufferPtr.SetStatus(EFull); 
   317 	
   318 	// if the buffer is empty or the last buffer, write it anyway -
   319 	// the stop / error will be generated elsewhere
   320 
   321 	iInputPort->MipWriteData(aFillBufferPtr);
   322 	return KErrNone;
   323 	}
   324 
   325 TInt CMdfHwDeviceCodecTestAdapter::ThisHwBufferEmptied(CMMFBuffer& /*aEmptyBufferPtr*/)
   326 	{
   327 	DEBUG_PRINT(_L("CMdfHwDeviceCodecTestAdapter::ThisHwBufferEmptied"));
   328 	
   329 	iOutputPort->MopReadData(*iOutputBuffer);
   330 	return KErrNone;
   331 	}
   332 	
   333 TInt CMdfHwDeviceCodecTestAdapter::SetConfig(TTaskConfig& aConfig)
   334 	{
   335 	TInt err = KErrNone;
   336 	// Call to Configure the Codec PU
   337 	TPuTaskConfig config(aConfig);
   338 	err = iInputPort->MipConfigure(config);
   339 	if(err != KErrNone)
   340 		{
   341 		return err;
   342 		}
   343 	err = iOutputPort->MopConfigure(config);
   344 	if(err != KErrNone)
   345 		{
   346 		return err;
   347 		}
   348 
   349 //	iState = EProcessingUnitConfigured;
   350 	
   351 	return KErrNone;
   352 	}
   353 
   354 TInt CMdfHwDeviceCodecTestAdapter::StopAndDeleteCodec()
   355 	{
   356 	return KErrNone;
   357 	}
   358 
   359 TInt CMdfHwDeviceCodecTestAdapter::DeleteCodec()
   360 	{
   361 	return KErrNone;
   362 	}
   363 
   364 void CMdfHwDeviceCodecTestAdapter::MipoWriteDataComplete(const MMdfInputPort* aInputPort,
   365 	CMMFBuffer* aBuffer, TInt aErrorCode)
   366 	{
   367 	DEBUG_PRINT(_L("CMdfHwDeviceCodecTestAdapter::MipoWriteDataComplete"));
   368 	
   369 	if (aErrorCode == KErrNone && aInputPort == iInputPort)
   370 		{
   371 		if(aBuffer->LastBuffer())
   372 			{
   373 			if(iFuncCmd == EDevEncode) 
   374 				{
   375 				// we must cancel the PU here if it's an encoder - the decoder
   376 				// will be done elsewhere
   377 				iCodecPU->Stop();
   378 				}
   379 			}
   380 		else
   381 			{
   382 			iHwDeviceObserver->FillThisHwBuffer(*aBuffer);
   383 			}
   384 		}
   385 	else
   386 		{
   387 		StopHwDevice(aErrorCode);
   388 		}		
   389 	}
   390 		
   391 void CMdfHwDeviceCodecTestAdapter::MipoDisconnectTunnelComplete(const MMdfInputPort* aInputPort, 
   392 	TInt aErrorCode)
   393 	{
   394 	// The Inputport of the PcmCodecPu will no longer receive data.
   395 	// Set flag to indicate that the sink outputport has been stopped?
   396 	if(aErrorCode == KErrNone)
   397 		{
   398 		if(aInputPort == iInputPort)
   399 			{
   400 			iPCMPuMipoStopCompleted = ETrue;
   401 			}
   402 		}
   403 	else
   404 		{
   405 		iHwDeviceObserver->Error(aErrorCode);
   406 		}	
   407 	}
   408 
   409 void CMdfHwDeviceCodecTestAdapter::MipoRestartTunnelComplete(const MMdfInputPort* /*aInputPort*/,
   410 	TInt /*aErrorCode*/)
   411 	{
   412 	
   413 	}
   414 
   415 void CMdfHwDeviceCodecTestAdapter::MopoReadDataComplete(const MMdfOutputPort* aOutputPort, 
   416 	CMMFBuffer* aBuffer, TInt aErrorCode)
   417 	{
   418 	DEBUG_PRINT(_L("CMdfHwDeviceCodecTestAdapter::MopoReadDataComplete"));
   419 	
   420 	if(aErrorCode == KErrNone && aOutputPort == iOutputPort)
   421 		{
   422 		iHwDeviceObserver->EmptyThisHwBuffer(*aBuffer);
   423 		}
   424 	else
   425 		{
   426 		StopHwDevice(aErrorCode);
   427 		}
   428 	}
   429 				
   430 void CMdfHwDeviceCodecTestAdapter::MopoDisconnectTunnelComplete(const MMdfOutputPort* aOutputPort,
   431 	TInt aErrorCode)
   432 	{
   433 	if(aErrorCode == KErrNone)
   434 		{
   435 		if(aOutputPort == iOutputPort)
   436 			{
   437 			iPCMPuMopoStopCompleted = ETrue;			
   438 			}
   439 		}
   440 	else
   441 		{
   442 		iHwDeviceObserver->Error(aErrorCode);
   443 		}
   444 	if(iPCMPuMipoStopCompleted && iPCMPuMopoStopCompleted)
   445 		{
   446 		iState = EProcessingUnitIdle;
   447 		}		
   448 	}
   449 	
   450 void CMdfHwDeviceCodecTestAdapter::MopoRestartTunnelComplete(const MMdfOutputPort* /* aOutputPort */,
   451 	TInt /*aErrorCode*/)
   452 	{
   453 	
   454 	}
   455 
   456 void CMdfHwDeviceCodecTestAdapter::InitializeComplete(const CMdfProcessingUnit* aPu, TInt aErrorCode)
   457 	{
   458 	if(aErrorCode != KErrNone)
   459 		{
   460 		iHwDeviceObserver->Error(aErrorCode);
   461 		return;
   462 		}
   463 			
   464 	if(aPu == iCodecPU)
   465 		{
   466 		iPCMPUCallbackComplete = ETrue;
   467 		}
   468 	
   469 	if(iPCMPUCallbackComplete)
   470 		{
   471 
   472 		// reset the flags
   473 		iPCMPUCallbackComplete = EFalse;
   474 		
   475 		// PUs initialised OK
   476 		iActiveWait->AsyncStop();
   477 
   478 		}
   479 	}
   480 
   481 void CMdfHwDeviceCodecTestAdapter::ExecuteComplete(const CMdfProcessingUnit* aPu, TInt aErrorCode)
   482 	{
   483 	if(iStopping)
   484 		{
   485 		return;
   486 		}
   487 	
   488 	if (iExecuteError == KErrNone)
   489 		{
   490 		iExecuteError = aErrorCode;
   491 		}
   492 	 		
   493 	if(aPu == iCodecPU)
   494 		{
   495 		iPCMPUCallbackComplete = ETrue;
   496 		}
   497 	
   498 	if(iExecuteError != KErrNone || (iPCMPUCallbackComplete) )
   499 		{
   500 		if (iState == EProcessingUnitExecuting)
   501 			{
   502 			// stop the hardware device if we are still executing
   503 			StopHwDevice(iExecuteError);		
   504 			iState = EProcessingUnitIdle;
   505 			}
   506 		// reset the flags
   507 		iPCMPUCallbackComplete = EFalse;
   508 		}
   509 	}
   510 
   511 void CMdfHwDeviceCodecTestAdapter::SetDataTypesL(TFourCC aSrcType, TFourCC aDestType)
   512 	{
   513 	// Find and load an appropriate Codec
   514 	iCodecPU = iPuLoader->LoadProcessingUnitL(*this, aSrcType, aDestType);
   515 	}
   516 
   517 
   518 void CMdfHwDeviceCodecTestAdapter::StopHwDevice(TInt error)
   519 	{
   520 	iHwDeviceObserver->Stopped();
   521 	iHwDeviceObserver->Error(error);		
   522 	}
   523 
   524 void CMdfHwDeviceCodecTestAdapter::GetState(THwDevAdapterState& aState) const
   525 	{
   526 	aState = iState;	
   527 	}