os/mm/mmdevicefw/mdfunittest/codecapi/omxvorbis/hwdeviceadapter/audiocodectestadapter.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/mm/mmdevicefw/mdfunittest/codecapi/omxvorbis/hwdeviceadapter/audiocodectestadapter.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,527 @@
1.4 +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// This is a re-implementation of CMdfHwDeviceCodecTestAdapter
1.18 +// primarily intended for unit testing codec PUs in PREQ1024.
1.19 +// It is NOT a subclass, as CMdfHwDeviceCodecTestAdapter itself has no
1.20 +// virtual or protected methods to override.
1.21 +// The only difference is that it encodes and decodes from codec
1.22 +// to codec, unlike CMdfHwDeviceCodecTestAdapter which encodes from sounddev
1.23 +// (mic) to codec and decodes from codec to sounddev (speaker)
1.24 +//
1.25 +//
1.26 +
1.27 +/**
1.28 + @file
1.29 + @internalComponent
1.30 +*/
1.31 +
1.32 +#include "audiocodectestadapter.h"
1.33 +#include <mdf/codecapiuids.hrh>
1.34 +#include <mdf/mdfpuconfig.h>
1.35 +// for the bitrate custom interface
1.36 +#include <mmf/server/devsoundstandardcustominterfaces.h>
1.37 +
1.38 +#include <e32debug.h>
1.39 +
1.40 +// #define AUDIOCODECTESTADAPTER_DEBUG 1
1.41 +#if defined(AUDIOCODECTESTADAPTER_DEBUG)
1.42 +#define DEBUG_PRINT RDebug::Print
1.43 +#else
1.44 +#define DEBUG_PRINT
1.45 +#endif
1.46 +
1.47 +// Interface UID for the Processing Unit Loader
1.48 +const TUid KUidPuLoader = {KUidPuLoaderImplementation};
1.49 +
1.50 +
1.51 +CMdfHwDeviceCodecTestAdapter::~CMdfHwDeviceCodecTestAdapter()
1.52 + {
1.53 + Stop();
1.54 + // Unload the PUs
1.55 + if (iCodecPU)
1.56 + {
1.57 + iPuLoader->UnloadProcessingUnit(iCodecPU);
1.58 + }
1.59 +
1.60 + // The I/O ports should have been deleted at this point
1.61 +
1.62 + delete iInputBuffer;
1.63 + delete iOutputBuffer;
1.64 + delete iActiveWait;
1.65 + delete iPuLoader;
1.66 + REComSession::DestroyedImplementation(iPuLoaderDtorKey);
1.67 + }
1.68 +
1.69 +CMdfHwDeviceCodecTestAdapter* CMdfHwDeviceCodecTestAdapter::NewL()
1.70 + {
1.71 + CMdfHwDeviceCodecTestAdapter* self = new (ELeave) CMdfHwDeviceCodecTestAdapter;
1.72 + CleanupStack::PushL (self);
1.73 + self->ConstructL();
1.74 + CleanupStack::Pop(self);
1.75 + return self;
1.76 + }
1.77 +
1.78 +CMdfHwDeviceCodecTestAdapter::CMdfHwDeviceCodecTestAdapter()
1.79 + {
1.80 + }
1.81 +
1.82 +void CMdfHwDeviceCodecTestAdapter::ConstructL()
1.83 + {
1.84 + // Load the PU Loader plugin
1.85 + iPuLoader = static_cast<CMdfPuLoader*>
1.86 + (REComSession::CreateImplementationL(KUidPuLoader, iPuLoaderDtorKey));
1.87 + iActiveWait = new (ELeave) CActiveSchedulerWait;
1.88 + iState = EProcessingUnitLoaderLoaded;
1.89 + }
1.90 +
1.91 +TInt CMdfHwDeviceCodecTestAdapter::Start(TDeviceFunc aFuncCmd, TDeviceFlow /*aFlowCmd*/)
1.92 + {
1.93 + if (!((aFuncCmd == EDevEncode)|(aFuncCmd == EDevDecode)|(aFuncCmd == EDevNullFunc)))
1.94 + {
1.95 + return KErrArgument;
1.96 + }
1.97 +
1.98 + iFuncCmd = aFuncCmd;
1.99 +
1.100 + // NB: aFlowCmd not used - this is codec-codec processing by default.
1.101 +
1.102 + TInt err = KErrNone;
1.103 + switch(aFuncCmd)
1.104 + {
1.105 + case EDevEncode:
1.106 + {
1.107 + err = StartEncode();
1.108 + }
1.109 + break;
1.110 + case EDevDecode:
1.111 + {
1.112 + err = StartDecode();
1.113 + }
1.114 + break;
1.115 + case EDevNullFunc:
1.116 + default:
1.117 + {
1.118 + err = KErrNotSupported;
1.119 + }
1.120 + break;
1.121 + }
1.122 +
1.123 +
1.124 + return err;
1.125 + }
1.126 +
1.127 +// encode and decode logic is identical for codec-codec processing
1.128 +
1.129 +TInt CMdfHwDeviceCodecTestAdapter::InitializeEncodeDecode()
1.130 + {
1.131 + DEBUG_PRINT(_L("CMdfHwDeviceCodecTestAdapter::InitializeEncodeDecode"));
1.132 +
1.133 + ASSERT(iOutputPort);
1.134 +
1.135 + iInputPortBufferSize = iInputPort->MipBufferSize();
1.136 + TRAPD(err, iInputBuffer = CMMFDescriptorBuffer::NewL(iInputPortBufferSize));
1.137 + if(err != KErrNone)
1.138 + {
1.139 + return err;
1.140 + }
1.141 + iInputBuffer->SetLastBuffer(EFalse);
1.142 + iInputPort->MipUseBuffer(*iInputBuffer);
1.143 +
1.144 + iOutputPortBufferSize = iOutputPort->MopBufferSize();
1.145 + TRAP(err, iOutputBuffer = CMMFDescriptorBuffer::NewL(iOutputPortBufferSize));
1.146 + if(err != KErrNone)
1.147 + {
1.148 + return err;
1.149 + }
1.150 + iOutputBuffer->SetLastBuffer(EFalse);
1.151 + iOutputPort->MopUseBuffer(*iOutputBuffer);
1.152 +
1.153 + // VD: should not move the set up of the state after sending the Initialize() calls???
1.154 + iState = EProcessingUnitInitializing;
1.155 +
1.156 + iCodecPU->Initialize();
1.157 +
1.158 + iActiveWait->Start();
1.159 + return KErrNone;
1.160 + }
1.161 +
1.162 +TInt CMdfHwDeviceCodecTestAdapter::StartEncode()
1.163 + {
1.164 + DEBUG_PRINT(_L("CMdfHwDeviceCodecTestAdapter::StartEncode"));
1.165 + TInt err = KErrNone;
1.166 + if (iState == EProcessingUnitLoaded)
1.167 + {
1.168 + err = InitializeEncodeDecode();
1.169 + }
1.170 + if (err != KErrNone)
1.171 + {
1.172 + return err;
1.173 + }
1.174 +
1.175 + return StartExecuting();
1.176 + }
1.177 +
1.178 +TInt CMdfHwDeviceCodecTestAdapter::StartDecode()
1.179 + {
1.180 + DEBUG_PRINT(_L("CMdfHwDeviceCodecTestAdapter::StartDecode"));
1.181 +
1.182 + TInt err = KErrNone;
1.183 + if (iState == EProcessingUnitLoaded)
1.184 + {
1.185 + err = InitializeEncodeDecode();
1.186 + }
1.187 + if (err != KErrNone)
1.188 + {
1.189 + return err;
1.190 + }
1.191 +
1.192 + return StartExecuting();
1.193 + }
1.194 +
1.195 +TInt CMdfHwDeviceCodecTestAdapter::StartExecuting()
1.196 + {
1.197 + DEBUG_PRINT(_L("CMdfHwDeviceCodecTestAdapter::StartExecuting"));
1.198 + TInt err = KErrNone;
1.199 +
1.200 + iOutputPort->MopReadData(*iOutputBuffer);
1.201 + err = iHwDeviceObserver->FillThisHwBuffer(*iInputBuffer);
1.202 + if(err != KErrNone)
1.203 + {
1.204 + return err;
1.205 + }
1.206 +
1.207 + iState = EProcessingUnitExecuting;
1.208 + iCodecPU->Execute();
1.209 +
1.210 + return KErrNone;
1.211 + }
1.212 +
1.213 +TInt CMdfHwDeviceCodecTestAdapter::Stop()
1.214 + {
1.215 + if(iState == EProcessingUnitExecuting || iState == EProcessingUnitPaused)
1.216 + {
1.217 + iStopping = ETrue; // is used as a guard in ExecuteComplete
1.218 +
1.219 + if(iCodecPU)
1.220 + {
1.221 + iCodecPU->Stop();
1.222 + }
1.223 +
1.224 + iPCMPUCallbackComplete = EFalse;
1.225 +
1.226 + iState = EProcessingUnitIdle;
1.227 + iStopping = EFalse;
1.228 + }
1.229 + return KErrNone;
1.230 + }
1.231 +
1.232 +TInt CMdfHwDeviceCodecTestAdapter::Pause()
1.233 + {
1.234 + return iCodecPU->Pause();
1.235 + }
1.236 +
1.237 +TInt CMdfHwDeviceCodecTestAdapter::Init(THwDeviceInitParams& aDevInfo)
1.238 + {
1.239 + if(!iCodecPU)
1.240 + {
1.241 + return KErrNotSupported;
1.242 + }
1.243 +
1.244 + // Not currently using any other members of aDevInfo, except the Observer
1.245 + if(!aDevInfo.iHwDeviceObserver)
1.246 + {
1.247 + return KErrArgument;
1.248 + }
1.249 + iHwDeviceObserver = aDevInfo.iHwDeviceObserver;
1.250 +
1.251 + // Get ports and set observers
1.252 + RPointerArray<MMdfInputPort> inputPorts;
1.253 + TInt err = iCodecPU->GetInputPorts(inputPorts);
1.254 + if(err != KErrNone)
1.255 + {
1.256 + return err;
1.257 + }
1.258 +
1.259 + if (inputPorts.Count()<1)
1.260 + {
1.261 + return KErrNotFound;
1.262 + }
1.263 +
1.264 + iInputPort = inputPorts[0];
1.265 + inputPorts.Close();
1.266 +
1.267 + iInputPort->MipSetObserver(*this);
1.268 +
1.269 + RPointerArray<MMdfOutputPort> outputPorts;
1.270 + err = iCodecPU->GetOutputPorts(outputPorts);
1.271 + if(err != KErrNone)
1.272 + {
1.273 + return err;
1.274 + }
1.275 +
1.276 + if (outputPorts.Count()<1)
1.277 + {
1.278 + return KErrNotFound;
1.279 + }
1.280 +
1.281 + iOutputPort = outputPorts[0];
1.282 + outputPorts.Close();
1.283 + iOutputPort->MopSetObserver(*this);
1.284 +
1.285 + iState = EProcessingUnitLoaded;
1.286 +
1.287 + return KErrNone;
1.288 + }
1.289 +
1.290 +TAny* CMdfHwDeviceCodecTestAdapter::CustomInterface(TUid aInterfaceId)
1.291 + {
1.292 + if (aInterfaceId == KUidHwDeviceSetupInterface)
1.293 + {
1.294 + return static_cast<MMdfHwDeviceSetup*>(this);
1.295 + }
1.296 + else if (aInterfaceId.iUid == KMmfPlaySettingsCustomInterface)
1.297 + {
1.298 + return reinterpret_cast<MPlayCustomInterface*>(iInputPort);
1.299 + }
1.300 + else if (aInterfaceId.iUid == KMmfRecordSettingsCustomInterface)
1.301 + {
1.302 + return reinterpret_cast<MRecordCustomInterface*>(iOutputPort);
1.303 + }
1.304 + // if the PU is an encoder it may have a BitRate custom interface
1.305 + else if (aInterfaceId == KUidCustomInterfaceDevSoundBitRate)
1.306 + {
1.307 + return static_cast<MMMFDevSoundCustomInterfaceBitRate*>(iCodecPU->CustomInterface(aInterfaceId));
1.308 + }
1.309 + else
1.310 + {
1.311 + return NULL;
1.312 + }
1.313 + }
1.314 +
1.315 +TInt CMdfHwDeviceCodecTestAdapter::ThisHwBufferFilled(CMMFBuffer& aFillBufferPtr)
1.316 + {
1.317 + DEBUG_PRINT(_L("CMdfHwDeviceCodecTestAdapter::ThisHwBufferFilled"));
1.318 +
1.319 + aFillBufferPtr.SetStatus(EFull);
1.320 +
1.321 + // if the buffer is empty or the last buffer, write it anyway -
1.322 + // the stop / error will be generated elsewhere
1.323 +
1.324 + iInputPort->MipWriteData(aFillBufferPtr);
1.325 + return KErrNone;
1.326 + }
1.327 +
1.328 +TInt CMdfHwDeviceCodecTestAdapter::ThisHwBufferEmptied(CMMFBuffer& /*aEmptyBufferPtr*/)
1.329 + {
1.330 + DEBUG_PRINT(_L("CMdfHwDeviceCodecTestAdapter::ThisHwBufferEmptied"));
1.331 +
1.332 + iOutputPort->MopReadData(*iOutputBuffer);
1.333 + return KErrNone;
1.334 + }
1.335 +
1.336 +TInt CMdfHwDeviceCodecTestAdapter::SetConfig(TTaskConfig& aConfig)
1.337 + {
1.338 + TInt err = KErrNone;
1.339 + // Call to Configure the Codec PU
1.340 + TPuTaskConfig config(aConfig);
1.341 + err = iInputPort->MipConfigure(config);
1.342 + if(err != KErrNone)
1.343 + {
1.344 + return err;
1.345 + }
1.346 + err = iOutputPort->MopConfigure(config);
1.347 + if(err != KErrNone)
1.348 + {
1.349 + return err;
1.350 + }
1.351 +
1.352 +// iState = EProcessingUnitConfigured;
1.353 +
1.354 + return KErrNone;
1.355 + }
1.356 +
1.357 +TInt CMdfHwDeviceCodecTestAdapter::StopAndDeleteCodec()
1.358 + {
1.359 + return KErrNone;
1.360 + }
1.361 +
1.362 +TInt CMdfHwDeviceCodecTestAdapter::DeleteCodec()
1.363 + {
1.364 + return KErrNone;
1.365 + }
1.366 +
1.367 +void CMdfHwDeviceCodecTestAdapter::MipoWriteDataComplete(const MMdfInputPort* aInputPort,
1.368 + CMMFBuffer* aBuffer, TInt aErrorCode)
1.369 + {
1.370 + DEBUG_PRINT(_L("CMdfHwDeviceCodecTestAdapter::MipoWriteDataComplete"));
1.371 +
1.372 + if (aErrorCode == KErrNone && aInputPort == iInputPort)
1.373 + {
1.374 + if(aBuffer->LastBuffer())
1.375 + {
1.376 + if(iFuncCmd == EDevEncode)
1.377 + {
1.378 + // we must cancel the PU here if it's an encoder - the decoder
1.379 + // will be done elsewhere
1.380 + iCodecPU->Stop();
1.381 + }
1.382 + }
1.383 + else
1.384 + {
1.385 + iHwDeviceObserver->FillThisHwBuffer(*aBuffer);
1.386 + }
1.387 + }
1.388 + else
1.389 + {
1.390 + StopHwDevice(aErrorCode);
1.391 + }
1.392 + }
1.393 +
1.394 +void CMdfHwDeviceCodecTestAdapter::MipoDisconnectTunnelComplete(const MMdfInputPort* aInputPort,
1.395 + TInt aErrorCode)
1.396 + {
1.397 + // The Inputport of the PcmCodecPu will no longer receive data.
1.398 + // Set flag to indicate that the sink outputport has been stopped?
1.399 + if(aErrorCode == KErrNone)
1.400 + {
1.401 + if(aInputPort == iInputPort)
1.402 + {
1.403 + iPCMPuMipoStopCompleted = ETrue;
1.404 + }
1.405 + }
1.406 + else
1.407 + {
1.408 + iHwDeviceObserver->Error(aErrorCode);
1.409 + }
1.410 + }
1.411 +
1.412 +void CMdfHwDeviceCodecTestAdapter::MipoRestartTunnelComplete(const MMdfInputPort* /*aInputPort*/,
1.413 + TInt /*aErrorCode*/)
1.414 + {
1.415 +
1.416 + }
1.417 +
1.418 +void CMdfHwDeviceCodecTestAdapter::MopoReadDataComplete(const MMdfOutputPort* aOutputPort,
1.419 + CMMFBuffer* aBuffer, TInt aErrorCode)
1.420 + {
1.421 + DEBUG_PRINT(_L("CMdfHwDeviceCodecTestAdapter::MopoReadDataComplete"));
1.422 +
1.423 + if(aErrorCode == KErrNone && aOutputPort == iOutputPort)
1.424 + {
1.425 + iHwDeviceObserver->EmptyThisHwBuffer(*aBuffer);
1.426 + }
1.427 + else
1.428 + {
1.429 + StopHwDevice(aErrorCode);
1.430 + }
1.431 + }
1.432 +
1.433 +void CMdfHwDeviceCodecTestAdapter::MopoDisconnectTunnelComplete(const MMdfOutputPort* aOutputPort,
1.434 + TInt aErrorCode)
1.435 + {
1.436 + if(aErrorCode == KErrNone)
1.437 + {
1.438 + if(aOutputPort == iOutputPort)
1.439 + {
1.440 + iPCMPuMopoStopCompleted = ETrue;
1.441 + }
1.442 + }
1.443 + else
1.444 + {
1.445 + iHwDeviceObserver->Error(aErrorCode);
1.446 + }
1.447 + if(iPCMPuMipoStopCompleted && iPCMPuMopoStopCompleted)
1.448 + {
1.449 + iState = EProcessingUnitIdle;
1.450 + }
1.451 + }
1.452 +
1.453 +void CMdfHwDeviceCodecTestAdapter::MopoRestartTunnelComplete(const MMdfOutputPort* /* aOutputPort */,
1.454 + TInt /*aErrorCode*/)
1.455 + {
1.456 +
1.457 + }
1.458 +
1.459 +void CMdfHwDeviceCodecTestAdapter::InitializeComplete(const CMdfProcessingUnit* aPu, TInt aErrorCode)
1.460 + {
1.461 + if(aErrorCode != KErrNone)
1.462 + {
1.463 + iHwDeviceObserver->Error(aErrorCode);
1.464 + return;
1.465 + }
1.466 +
1.467 + if(aPu == iCodecPU)
1.468 + {
1.469 + iPCMPUCallbackComplete = ETrue;
1.470 + }
1.471 +
1.472 + if(iPCMPUCallbackComplete)
1.473 + {
1.474 +
1.475 + // reset the flags
1.476 + iPCMPUCallbackComplete = EFalse;
1.477 +
1.478 + // PUs initialised OK
1.479 + iActiveWait->AsyncStop();
1.480 +
1.481 + }
1.482 + }
1.483 +
1.484 +void CMdfHwDeviceCodecTestAdapter::ExecuteComplete(const CMdfProcessingUnit* aPu, TInt aErrorCode)
1.485 + {
1.486 + if(iStopping)
1.487 + {
1.488 + return;
1.489 + }
1.490 +
1.491 + if (iExecuteError == KErrNone)
1.492 + {
1.493 + iExecuteError = aErrorCode;
1.494 + }
1.495 +
1.496 + if(aPu == iCodecPU)
1.497 + {
1.498 + iPCMPUCallbackComplete = ETrue;
1.499 + }
1.500 +
1.501 + if(iExecuteError != KErrNone || (iPCMPUCallbackComplete) )
1.502 + {
1.503 + if (iState == EProcessingUnitExecuting)
1.504 + {
1.505 + // stop the hardware device if we are still executing
1.506 + StopHwDevice(iExecuteError);
1.507 + iState = EProcessingUnitIdle;
1.508 + }
1.509 + // reset the flags
1.510 + iPCMPUCallbackComplete = EFalse;
1.511 + }
1.512 + }
1.513 +
1.514 +void CMdfHwDeviceCodecTestAdapter::SetDataTypesL(TFourCC aSrcType, TFourCC aDestType)
1.515 + {
1.516 + // Find and load an appropriate Codec
1.517 + iCodecPU = iPuLoader->LoadProcessingUnitL(*this, aSrcType, aDestType);
1.518 + }
1.519 +
1.520 +
1.521 +void CMdfHwDeviceCodecTestAdapter::StopHwDevice(TInt error)
1.522 + {
1.523 + iHwDeviceObserver->Stopped();
1.524 + iHwDeviceObserver->Error(error);
1.525 + }
1.526 +
1.527 +void CMdfHwDeviceCodecTestAdapter::GetState(THwDevAdapterState& aState) const
1.528 + {
1.529 + aState = iState;
1.530 + }