1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/mm/mmdevicefw/mdf/src/audio/HwDeviceAdapter/mdfhwdeviceadapter.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,905 @@
1.4 +// Copyright (c) 2005-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 +//
1.18 +
1.19 +#include "HwDeviceAdapter/mdfhwdeviceadapter.h"
1.20 +#include <mdf/codecapiuids.hrh>
1.21 +#include <mdf/mdfpuconfig.h>
1.22 +#include <mmf/server/devsoundstandardcustominterfaces.h>
1.23 +
1.24 +// Interface UID for the Sink Processing Unit
1.25 +const TUid KUidSourceSinkPu = {0x102730BB};
1.26 +const TInt KZerothPort = 0;
1.27 +
1.28 +/*
1.29 +The destructor. Unloads the Processing Units, deletes the
1.30 +Processing Unit Loader and frees any owned buffers.
1.31 +@see CMMFHwDevice::~CMMFHwDevice()
1.32 +*/
1.33 +CMdfHwDeviceAdapter::~CMdfHwDeviceAdapter()
1.34 + {
1.35 + Stop();
1.36 + // Unload the PUs
1.37 + if (iCodecPU)
1.38 + {
1.39 + iPuLoader->UnloadProcessingUnit(iCodecPU);
1.40 + }
1.41 + if (iAudioDevicePU)
1.42 + {
1.43 + iPuLoader->UnloadProcessingUnit(iAudioDevicePU);
1.44 + }
1.45 +
1.46 + delete iInputBuffer;
1.47 + delete iOutputBuffer;
1.48 + delete iActiveWait;
1.49 + delete iPuLoader;
1.50 + REComSession::DestroyedImplementation(iPuLoaderDtorKey);
1.51 + }
1.52 +
1.53 +/*
1.54 +Creates a new CMdfHwDeviceAdapter object. The Processing Unit Loader plugin
1.55 +is also loaded, and so the CMdfHwDeviceAdapter state is set to EProcessingUnitLoaderLoaded.
1.56 +Will leave with KErrNotFound if it, or the Processing Unit Loader plugin is not found.
1.57 +@see THwDevAdapterState
1.58 +*/
1.59 +CMdfHwDeviceAdapter* CMdfHwDeviceAdapter::NewL()
1.60 + {
1.61 + CMdfHwDeviceAdapter* self = new (ELeave) CMdfHwDeviceAdapter;
1.62 + CleanupStack::PushL (self);
1.63 + self->ConstructL();
1.64 + CleanupStack::Pop(self);
1.65 + return self;
1.66 + }
1.67 +
1.68 +/*
1.69 +Default constructor.
1.70 +*/
1.71 +CMdfHwDeviceAdapter::CMdfHwDeviceAdapter()
1.72 + {
1.73 + }
1.74 +
1.75 +/*
1.76 +Loads the Processing Unit Loader plugin.
1.77 +*/
1.78 +void CMdfHwDeviceAdapter::ConstructL()
1.79 + {
1.80 + // Load the PU Loader plugin
1.81 + iPuLoader = static_cast<CMdfPuLoader*>
1.82 + (REComSession::CreateImplementationL(TUid::Uid(KUidPuLoaderImplementation), iPuLoaderDtorKey));
1.83 + iActiveWait = new (ELeave) CActiveSchedulerWait;
1.84 + iState = EProcessingUnitLoaderLoaded;
1.85 + }
1.86 +
1.87 +/*
1.88 +@see CMMFHwDevice::Start()
1.89 +@see TDeviceFunc
1.90 +*/
1.91 +TInt CMdfHwDeviceAdapter::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 + TInt err = KErrNone;
1.101 + switch(aFuncCmd)
1.102 + {
1.103 + case EDevEncode:
1.104 + {
1.105 + err = StartEncode();
1.106 + }
1.107 + break;
1.108 + case EDevDecode:
1.109 + {
1.110 + err = StartDecode();
1.111 + }
1.112 + break;
1.113 + case EDevNullFunc:
1.114 + {
1.115 + // nothing at the moment, so fall through
1.116 + }
1.117 + //break;
1.118 + default:
1.119 + {
1.120 + err = KErrNotSupported;
1.121 + }
1.122 + break;
1.123 + }
1.124 +
1.125 +
1.126 + return err;
1.127 + }
1.128 +
1.129 +/*
1.130 +Initialises the encode operation, and set the state of the CMdfHwDeviceAdapter
1.131 +to EProcessingUnitInitializing.
1.132 +@return An error code indicating if the function call was successful.
1.133 +KErrNone on success, otherwise another of the system-wide error codes.
1.134 +*/
1.135 +TInt CMdfHwDeviceAdapter::InitializeEncode()
1.136 + {
1.137 + ASSERT(iCodecOutputPort && iSourceOutputPort);
1.138 + // Create input buffer that passes data from Source -> Codec PU
1.139 + TRAPD(err, iInputBuffer = CMMFDescriptorBuffer::NewL(iSourceOutputPort->MopBufferSize()));
1.140 + if(err != KErrNone)
1.141 + {
1.142 + return err;
1.143 + }
1.144 +
1.145 + // Create output buffer that passes decoded data from Codec PU -> Out to file
1.146 + TRAP(err, iOutputBuffer = CMMFDescriptorBuffer::NewL(iCodecOutputPort->MopBufferSize()));
1.147 + if(err != KErrNone)
1.148 + {
1.149 + return err;
1.150 + }
1.151 +
1.152 + err = iSourceOutputPort->MopUseBuffer(*iInputBuffer);
1.153 + if(err != KErrNone)
1.154 + {
1.155 + return err;
1.156 + }
1.157 + err = iCodecInputPort->MipUseBuffer(*iInputBuffer);
1.158 + if(err != KErrNone)
1.159 + {
1.160 + return err;
1.161 + }
1.162 + err = iCodecOutputPort->MopUseBuffer(*iOutputBuffer);
1.163 + if(err != KErrNone)
1.164 + {
1.165 + return err;
1.166 + }
1.167 +
1.168 + // async calls, that callback to InitializeComplete()
1.169 + iCodecPU->Initialize();
1.170 + iAudioDevicePU->Initialize();
1.171 + if (iState == EProcessingUnitLoaded)
1.172 + {
1.173 + // only wait for the callbacks if we haven't already received them
1.174 + iState = EProcessingUnitInitializing;
1.175 + iActiveWait->Start();
1.176 + }
1.177 + return iInitError;
1.178 + }
1.179 +
1.180 +/*
1.181 +Starts the encode operation, providing that the intial state of the
1.182 +CMdfHwDeviceAdapter is EProcessingUnitLoaded.
1.183 +@return An error code indicating if the function call was successful.
1.184 +KErrNone on success, otherwise another of the system-wide error codes.
1.185 +*/
1.186 +TInt CMdfHwDeviceAdapter::StartEncode()
1.187 + {
1.188 + TInt err = KErrNone;
1.189 + if (iState == EProcessingUnitLoaded)
1.190 + {
1.191 + err = InitializeEncode();
1.192 + }
1.193 + if (err != KErrNone)
1.194 + {
1.195 + return err;
1.196 + }
1.197 + if (iState == EProcessingUnitPaused)
1.198 + {
1.199 + // Ensure that the LastBuffer flags are reset.
1.200 + iInputBuffer->SetLastBuffer(EFalse);
1.201 + iOutputBuffer->SetLastBuffer(EFalse);
1.202 + }
1.203 +
1.204 + return StartExecuting();
1.205 + }
1.206 +
1.207 +/*
1.208 +Starts the execution of the encode or decode operation, and sets the state
1.209 +of the CMdfHwDeviceAdapter to EProcessingUnitExecuting.
1.210 +@return An error code indicating if the function call was successful.
1.211 +KErrNone on success, otherwise another of the system-wide error codes.
1.212 +*/
1.213 +TInt CMdfHwDeviceAdapter::StartExecuting()
1.214 + {
1.215 + TInt err = KErrNone;
1.216 + if(iFuncCmd == EDevDecode)
1.217 + {
1.218 + iCodecOutputPort->MopReadData(*iOutputBuffer);
1.219 + err = iHwDeviceObserver->FillThisHwBuffer(*iInputBuffer);
1.220 + if(err != KErrNone)
1.221 + {
1.222 + return err;
1.223 + }
1.224 + }
1.225 + else // encode
1.226 + {
1.227 + iSourceOutputPort->MopReadData(*iInputBuffer);
1.228 + iCodecOutputPort->MopReadData(*iOutputBuffer);
1.229 + }
1.230 +
1.231 + iState = EProcessingUnitExecuting;
1.232 +
1.233 + iCodecPU->Execute();
1.234 + iAudioDevicePU->Execute();
1.235 +
1.236 + return err;
1.237 + }
1.238 +
1.239 +/*
1.240 +Initialises the decode operation, and set the state of the CMdfHwDeviceAdapter
1.241 +to EProcessingUnitInitializing.
1.242 +@return An error code indicating if the function call was successful.
1.243 +KErrNone on success, otherwise another of the system-wide error codes.
1.244 +*/
1.245 +TInt CMdfHwDeviceAdapter::InitializeDecode()
1.246 + {
1.247 + ASSERT(iCodecOutputPort && iSinkInputPort);
1.248 +
1.249 + TRAPD(err, iInputBuffer = CMMFDescriptorBuffer::NewL(iCodecInputPort->MipBufferSize()));
1.250 + if(err != KErrNone)
1.251 + {
1.252 + return err;
1.253 + }
1.254 +
1.255 + iCodecInputPort->MipUseBuffer(*iInputBuffer);
1.256 + TRAP(err, iOutputBuffer = CMMFDescriptorBuffer::NewL(iCodecOutputPort->MopBufferSize()));
1.257 + if(err != KErrNone)
1.258 + {
1.259 + return err;
1.260 + }
1.261 +
1.262 + // Try to set up a tunnelbetween the output port of the PCM Pu
1.263 + // and the input port of the Sink Pu
1.264 + if (iPuLoader->TunnelSetup(*iCodecOutputPort, *iSinkInputPort) != KErrNone)
1.265 + {
1.266 + iSinkInputPort->MipUseBuffer(*iOutputBuffer);
1.267 + }
1.268 + iCodecOutputPort->MopUseBuffer(*iOutputBuffer);
1.269 +
1.270 + // async calls, that callback to InitializeComplete()
1.271 + iCodecPU->Initialize();
1.272 + iAudioDevicePU->Initialize();
1.273 + iState = EProcessingUnitInitializing;
1.274 + iActiveWait->Start();
1.275 + return KErrNone;
1.276 + }
1.277 +
1.278 +/*
1.279 +Starts the decode operation, providing that the intial state of the
1.280 +CMdfHwDeviceAdapter is EProcessingUnitLoaded.
1.281 +@return An error code indicating if the function call was successful.
1.282 +KErrNone on success, otherwise another of the system-wide error codes.
1.283 +*/
1.284 +TInt CMdfHwDeviceAdapter::StartDecode()
1.285 + {
1.286 + TInt err = KErrNone;
1.287 + if (iState == EProcessingUnitLoaded)
1.288 + {
1.289 + err = InitializeDecode();
1.290 + }
1.291 + if (err != KErrNone)
1.292 + {
1.293 + return err;
1.294 + }
1.295 + if (iState == EProcessingUnitIdle)
1.296 + {
1.297 + // Ensure that the LastBuffer flags are reset.
1.298 + iInputBuffer->SetLastBuffer(EFalse);
1.299 + iOutputBuffer->SetLastBuffer(EFalse);
1.300 + }
1.301 + return StartExecuting();
1.302 + }
1.303 +
1.304 +/*
1.305 +@see CMMFHwDevice::Stop()
1.306 +*/
1.307 +TInt CMdfHwDeviceAdapter::Stop()
1.308 + {
1.309 + if(iState == EProcessingUnitExecuting || iState == EProcessingUnitPaused)
1.310 + {
1.311 + iStopping = ETrue; // is used as a guard in ExecuteComplete
1.312 + if(iAudioDevicePU)
1.313 + {
1.314 + iAudioDevicePU->Stop();
1.315 + }
1.316 + if(iCodecPU)
1.317 + {
1.318 + iCodecPU->Stop();
1.319 + }
1.320 +
1.321 + iPCMPUCallbackComplete = EFalse;
1.322 + iSourceSinkPUCallbackComplete = EFalse;
1.323 +
1.324 + iState = EProcessingUnitIdle;
1.325 + iStopping = EFalse;
1.326 + }
1.327 + return KErrNone;
1.328 + }
1.329 +
1.330 +/*
1.331 +@see CMMFHwDevice::Pause()
1.332 +*/
1.333 +TInt CMdfHwDeviceAdapter::Pause()
1.334 + {
1.335 + TInt err = KErrNone;
1.336 + if(iState != EProcessingUnitPaused)
1.337 + {
1.338 + if(iAudioDevicePU)
1.339 + {
1.340 + err = iAudioDevicePU->Pause();
1.341 + }
1.342 + iState = EProcessingUnitPaused;
1.343 + }
1.344 + return err;
1.345 + }
1.346 +
1.347 +/*
1.348 +@see CMMFHwDevice::Init()
1.349 +*/
1.350 +TInt CMdfHwDeviceAdapter::Init(THwDeviceInitParams& aDevInfo)
1.351 + {
1.352 + if(!iCodecPU)
1.353 + {
1.354 + return KErrNotSupported;
1.355 + }
1.356 +
1.357 + // Not currently using any other members of aDevInfo, except the Observer
1.358 + // Set observer
1.359 + if(!aDevInfo.iHwDeviceObserver)
1.360 + {
1.361 + return KErrArgument;
1.362 + }
1.363 + iHwDeviceObserver = aDevInfo.iHwDeviceObserver;
1.364 +
1.365 + RPointerArray<MMdfInputPort> inputPorts;
1.366 + // Get ports and set observers
1.367 + TInt err = iCodecPU->GetInputPorts(inputPorts);
1.368 + if (err == KErrNone && inputPorts.Count() > 0)
1.369 + {
1.370 + iCodecInputPort = inputPorts[KZerothPort];
1.371 + iCodecInputPort->MipSetObserver(*this);
1.372 + }
1.373 + inputPorts.Close();
1.374 + if (err != KErrNone)
1.375 + {
1.376 + return err;
1.377 + }
1.378 + if (!iCodecInputPort)
1.379 + {
1.380 + return KErrNotFound;
1.381 + }
1.382 +
1.383 + RPointerArray<MMdfOutputPort> outputPorts;
1.384 + // Get ports and set observers
1.385 + err = iCodecPU->GetOutputPorts(outputPorts);
1.386 + if (err == KErrNone && outputPorts.Count() > 0)
1.387 + {
1.388 + iCodecOutputPort = outputPorts[KZerothPort];
1.389 + iCodecOutputPort->MopSetObserver(*this);
1.390 + }
1.391 + outputPorts.Close();
1.392 + if (err != KErrNone)
1.393 + {
1.394 + return err;
1.395 + }
1.396 + if (!iCodecOutputPort)
1.397 + {
1.398 + return KErrNotFound;
1.399 + }
1.400 +
1.401 + // Load SourceSink Pu
1.402 + TRAP(err, iAudioDevicePU = iPuLoader->LoadProcessingUnitL(*this, KUidSourceSinkPu));
1.403 + if(err!=KErrNone)
1.404 + {
1.405 + return err;
1.406 + }
1.407 +
1.408 + err = iAudioDevicePU->GetInputPorts(inputPorts);
1.409 + if (err == KErrNone && inputPorts.Count() > 0)
1.410 + {
1.411 + iSinkInputPort = inputPorts[KZerothPort];
1.412 + iSinkInputPort->MipSetObserver(*this);
1.413 + }
1.414 + inputPorts.Close();
1.415 + if (err != KErrNone)
1.416 + {
1.417 + return err;
1.418 + }
1.419 + if (!iSinkInputPort)
1.420 + {
1.421 + return KErrNotFound;
1.422 + }
1.423 +
1.424 +
1.425 + err = iAudioDevicePU->GetOutputPorts(outputPorts);
1.426 + if (err == KErrNone && outputPorts.Count() > 0)
1.427 + {
1.428 + iSourceOutputPort = outputPorts[KZerothPort];
1.429 + iSourceOutputPort->MopSetObserver(*this);
1.430 + }
1.431 + outputPorts.Close();
1.432 + if (err != KErrNone)
1.433 + {
1.434 + return err;
1.435 + }
1.436 + if (!iCodecOutputPort)
1.437 + {
1.438 + return KErrNotFound;
1.439 + }
1.440 +
1.441 + iState = EProcessingUnitLoaded;
1.442 + return KErrNone;
1.443 + }
1.444 +
1.445 +/*
1.446 +@see CMMFHwDevice::CustomInterface()
1.447 +*/
1.448 +TAny* CMdfHwDeviceAdapter::CustomInterface(TUid aInterfaceId)
1.449 + {
1.450 + if (aInterfaceId == KUidHwDeviceSetupInterface)
1.451 + {
1.452 + MMdfHwDeviceSetup* hwDeviceSetup = this;
1.453 + return hwDeviceSetup;
1.454 + }
1.455 + else if (aInterfaceId.iUid == KMmfPlaySettingsCustomInterface)
1.456 + {
1.457 + return iSinkInputPort->MipCustomInterface(aInterfaceId);
1.458 + }
1.459 + else if (aInterfaceId.iUid == KMmfRecordSettingsCustomInterface)
1.460 + {
1.461 + return iSourceOutputPort->MopCustomInterface(aInterfaceId);
1.462 + }
1.463 + else if (aInterfaceId == KUidCustomInterfaceDevSoundBitRate)
1.464 + {
1.465 + return iCodecPU->CustomInterface(aInterfaceId);
1.466 + }
1.467 + else
1.468 + {
1.469 + return NULL;
1.470 + }
1.471 + }
1.472 +
1.473 +/*
1.474 +@see CMMFHwDevice::ThisHwBufferFilled()
1.475 +*/
1.476 +TInt CMdfHwDeviceAdapter::ThisHwBufferFilled(CMMFBuffer& aFillBufferPtr)
1.477 + {
1.478 + aFillBufferPtr.SetStatus(EFull);
1.479 + iCodecInputPort->MipWriteData(aFillBufferPtr);
1.480 + return KErrNone;
1.481 + }
1.482 +
1.483 +/*
1.484 +@see CMMFHwDevice::ThisHwBufferEmptied()
1.485 +*/
1.486 +TInt CMdfHwDeviceAdapter::ThisHwBufferEmptied(CMMFBuffer& /*aEmptyBufferPtr*/)
1.487 + {
1.488 + if (iOutputBuffer->LastBuffer())
1.489 + {
1.490 + CMMFDataBuffer* buffer = static_cast <CMMFDataBuffer*> (iOutputBuffer);
1.491 + buffer->Data().SetLength(0);
1.492 + iHwDeviceObserver->EmptyThisHwBuffer(*iOutputBuffer);
1.493 + }
1.494 + else
1.495 + {
1.496 + iCodecOutputPort->MopReadData(*iOutputBuffer);
1.497 + }
1.498 + return KErrNone;
1.499 + }
1.500 +
1.501 +/*
1.502 +@see CMMFHwDevice::SetConfig()
1.503 +*/
1.504 +TInt CMdfHwDeviceAdapter::SetConfig(TTaskConfig& aConfig)
1.505 + {
1.506 + TInt err = KErrNone;
1.507 + // Call to Configure the Codec PU
1.508 + TPuTaskConfig config(aConfig);
1.509 + err = iCodecInputPort->MipConfigure(config);
1.510 + if(err != KErrNone)
1.511 + {
1.512 + return err;
1.513 + }
1.514 + err = iCodecOutputPort->MopConfigure(config);
1.515 + if(err != KErrNone)
1.516 + {
1.517 + return err;
1.518 + }
1.519 +
1.520 + // configure the audio device
1.521 + err = iSinkInputPort->MipConfigure(config);
1.522 + if(err != KErrNone)
1.523 + {
1.524 + return err;
1.525 + }
1.526 + err = iSourceOutputPort->MopConfigure(config);
1.527 + if(err != KErrNone)
1.528 + {
1.529 + return err;
1.530 + }
1.531 +
1.532 + return KErrNone;
1.533 + }
1.534 +
1.535 +/*
1.536 +@see CMMFHwDevice::StopAndDeleteCodec()
1.537 +*/
1.538 +TInt CMdfHwDeviceAdapter::StopAndDeleteCodec()
1.539 + {
1.540 + TInt stopError = Stop();
1.541 + TInt deleteError = DeleteCodec();
1.542 +
1.543 + if (stopError != KErrNone)
1.544 + {
1.545 + return stopError;
1.546 + }
1.547 + else
1.548 + {
1.549 + return deleteError;
1.550 + }
1.551 + }
1.552 +
1.553 +/*
1.554 +Unloads all Processing Units, and deletes any locally owned buffers.
1.555 +State is set to EProcessingUnitLoaderLoaded.
1.556 +
1.557 +@see CMMFHwDevice::DeleteCodec()
1.558 +*/
1.559 +TInt CMdfHwDeviceAdapter::DeleteCodec()
1.560 + {
1.561 + Stop();
1.562 + if (iCodecPU)
1.563 + {
1.564 + iPuLoader->UnloadProcessingUnit(iCodecPU);
1.565 + }
1.566 + if (iAudioDevicePU)
1.567 + {
1.568 + iPuLoader->UnloadProcessingUnit(iAudioDevicePU);
1.569 + }
1.570 +
1.571 + // CMdfHwDeviceAdapter does not own the I/O ports, which
1.572 + // have been deleted at this point by UnloadProcessingUnit()
1.573 + iCodecInputPort = NULL;
1.574 + iCodecOutputPort = NULL;
1.575 + iSinkInputPort = NULL;
1.576 + iSourceOutputPort = NULL;
1.577 +
1.578 + delete iInputBuffer;
1.579 + iInputBuffer = NULL;
1.580 + delete iOutputBuffer;
1.581 + iOutputBuffer = NULL;
1.582 +
1.583 + iState = EProcessingUnitLoaderLoaded;
1.584 +
1.585 + return KErrNone;
1.586 + }
1.587 +
1.588 +/*
1.589 +@see MMdfInputPortObserver::MipoWriteDataComplete()
1.590 +*/
1.591 +void CMdfHwDeviceAdapter::MipoWriteDataComplete(const MMdfInputPort* aInputPort,
1.592 + CMMFBuffer* aBuffer, TInt aErrorCode)
1.593 + {
1.594 + if(aErrorCode != KErrNone)
1.595 + {
1.596 + StopHwDevice(aErrorCode);
1.597 + }
1.598 + else
1.599 + {
1.600 + switch(iFuncCmd)
1.601 + {
1.602 + case EDevEncode:
1.603 + {
1.604 + if(aInputPort == iCodecInputPort)
1.605 + {
1.606 + if(aBuffer->LastBuffer())
1.607 + {
1.608 + iCodecPU->Stop();
1.609 + }
1.610 + else
1.611 + {
1.612 + // if not the last buffer, then pass buffer back to source to get more data
1.613 + iSourceOutputPort->MopReadData(*iInputBuffer);
1.614 + }
1.615 + }
1.616 + }
1.617 + break;
1.618 + case EDevDecode:
1.619 + {
1.620 + if(aInputPort == iCodecInputPort)
1.621 + {
1.622 + if (!aBuffer->LastBuffer())
1.623 + {
1.624 + // JW 22-05-06
1.625 + // if the PU is idle (having been Stopped) then
1.626 + // FillThisHwBuffer will cause a kern-exec,
1.627 + // as the DevSoundSession no longer has a buffer
1.628 + if(iState == EProcessingUnitExecuting)
1.629 + {
1.630 + TInt err = iHwDeviceObserver->FillThisHwBuffer(*aBuffer);
1.631 + if(err != KErrNone)
1.632 + {
1.633 + StopHwDevice(err);
1.634 + }
1.635 + }
1.636 + }
1.637 + }
1.638 + else // aInputPort == iSinkInputPort
1.639 + {
1.640 + if (!aBuffer->LastBuffer())
1.641 + {
1.642 + if(iSinkInputPort->MipIsTunnelled())
1.643 + {
1.644 + // This callback shouldn't occur since it should be tunnelled with the sink input port
1.645 + StopHwDevice(KErrArgument);
1.646 + }
1.647 + else
1.648 + {
1.649 + iCodecOutputPort->MopReadData(*iOutputBuffer);
1.650 + }
1.651 + }
1.652 + }
1.653 + }
1.654 + break;
1.655 + case EDevNullFunc:
1.656 + // nothing at the moment, so fall through
1.657 + default:
1.658 + StopHwDevice(KErrNotSupported);
1.659 + }
1.660 + }
1.661 + }
1.662 +
1.663 +/*
1.664 +@see MMdfInputPortObserver::MipoDisconnectTunnelComplete()
1.665 +*/
1.666 +void CMdfHwDeviceAdapter::MipoDisconnectTunnelComplete(const MMdfInputPort* aInputPort,
1.667 + TInt aErrorCode)
1.668 + {
1.669 + // The Inputport of the PcmCodecPu will no longer receive data.
1.670 + if(aErrorCode == KErrNone)
1.671 + {
1.672 + if(aInputPort == iCodecInputPort)
1.673 + {
1.674 + iPCMPuMipoStopCompleted = ETrue;
1.675 + }
1.676 + else if(aInputPort == iSinkInputPort)
1.677 + {
1.678 + // This shouldn't be called!
1.679 + iHwDeviceObserver->Error(KErrNotFound);
1.680 + }
1.681 + }
1.682 + else
1.683 + {
1.684 + iHwDeviceObserver->Error(aErrorCode);
1.685 + }
1.686 + }
1.687 +
1.688 +/*
1.689 +@see MMdfInputPortObserver::MipoRestartTunnelComplete()
1.690 +*/
1.691 +void CMdfHwDeviceAdapter::MipoRestartTunnelComplete(const MMdfInputPort* /*aInputPort*/,
1.692 + TInt /*aErrorCode*/)
1.693 + {
1.694 +
1.695 + }
1.696 +
1.697 +/*
1.698 +@see MMdfOutputPortObserver::MopoReadDataComplete()
1.699 +*/
1.700 +void CMdfHwDeviceAdapter::MopoReadDataComplete(const MMdfOutputPort* aOutputPort,
1.701 + CMMFBuffer* aBuffer, TInt aErrorCode)
1.702 + {
1.703 + if(aErrorCode != KErrNone)
1.704 + {
1.705 + StopHwDevice(aErrorCode);
1.706 + }
1.707 + else
1.708 + {
1.709 + switch(iFuncCmd)
1.710 + {
1.711 + case EDevEncode:
1.712 + {
1.713 + if(aOutputPort == iSourceOutputPort)
1.714 + {
1.715 + iCodecInputPort->MipWriteData(*aBuffer);
1.716 + }
1.717 + else // aPu == iCodecPU
1.718 + {
1.719 + TInt err = iHwDeviceObserver->EmptyThisHwBuffer(*aBuffer);
1.720 + if(err !=KErrNone)
1.721 + {
1.722 + StopHwDevice(err);
1.723 + }
1.724 + }
1.725 + }
1.726 + break;
1.727 + case EDevDecode:
1.728 + {
1.729 + if(aOutputPort == iCodecOutputPort)
1.730 + {
1.731 + if(iCodecOutputPort->MopIsTunnelled())
1.732 + {
1.733 + // This callback shouldn't occur since it should be tunnelled with the sink input port
1.734 + StopHwDevice(KErrArgument);
1.735 + }
1.736 + else
1.737 + {
1.738 + iSinkInputPort->MipWriteData(*aBuffer);
1.739 + }
1.740 + }
1.741 + }
1.742 + break;
1.743 + case EDevNullFunc:
1.744 + // nothing at the moment, so fall through
1.745 + default:
1.746 + StopHwDevice(KErrNotSupported);
1.747 + }
1.748 + }
1.749 + }
1.750 +
1.751 +/*
1.752 +@see MMdfOutputPortObserver::MopoDisconnectTunnelComplete()
1.753 +*/
1.754 +void CMdfHwDeviceAdapter::MopoDisconnectTunnelComplete(const MMdfOutputPort* aOutputPort,
1.755 + TInt aErrorCode)
1.756 + {
1.757 + if(!aOutputPort)
1.758 + {
1.759 + iHwDeviceObserver->Error(KErrArgument);
1.760 + return;
1.761 + }
1.762 +
1.763 + // The last buffer has been set, and called back to MopoReadDataComplete
1.764 + if(aErrorCode != KErrNone)
1.765 + {
1.766 + iHwDeviceObserver->Error(aErrorCode);
1.767 + return;
1.768 + }
1.769 +
1.770 + if(aOutputPort == iCodecOutputPort)
1.771 + {
1.772 + iPCMPuMopoStopCompleted = ETrue;
1.773 + }
1.774 + else if(aOutputPort == iSourceOutputPort)
1.775 + {
1.776 + iSourceSinkPuMopoStopCompleted = ETrue;
1.777 + }
1.778 + else
1.779 + {
1.780 + iHwDeviceObserver->Error(KErrArgument);
1.781 + return;
1.782 + }
1.783 +
1.784 + if(iPCMPuMipoStopCompleted && iPCMPuMopoStopCompleted && iSourceSinkPuMopoStopCompleted)
1.785 + {
1.786 + iHwDeviceObserver->Error(KErrNone);
1.787 + iState = EProcessingUnitIdle;
1.788 + }
1.789 + }
1.790 +
1.791 +/*
1.792 +@see MMdfOutputPortObserver::MopoRestartTunnelComplete()
1.793 +*/
1.794 +void CMdfHwDeviceAdapter::MopoRestartTunnelComplete(const MMdfOutputPort* /*aOutputPort*/,
1.795 + TInt /*aErrorCode*/)
1.796 + {
1.797 +
1.798 + }
1.799 +
1.800 +/*
1.801 +@see MMdfProcessingUnitObserver::InitializeComplete()
1.802 +*/
1.803 +void CMdfHwDeviceAdapter::InitializeComplete(const CMdfProcessingUnit* aPu, TInt aErrorCode)
1.804 + {
1.805 + iInitError = aErrorCode;
1.806 + if(aErrorCode != KErrNone)
1.807 + {
1.808 + // stop waiting on the active scheduler if we were doing so
1.809 + if (iState == EProcessingUnitInitializing)
1.810 + {
1.811 + // change state back to processing unit loaded
1.812 + iState = EProcessingUnitLoaded;
1.813 + iActiveWait->AsyncStop();
1.814 + }
1.815 + return;
1.816 + }
1.817 +
1.818 + if(aPu == iCodecPU)
1.819 + {
1.820 + iPCMPUCallbackComplete = ETrue;
1.821 + }
1.822 + else if(aPu == iAudioDevicePU)
1.823 + {
1.824 + iSourceSinkPUCallbackComplete = ETrue;
1.825 + }
1.826 +
1.827 + if(iPCMPUCallbackComplete && iSourceSinkPUCallbackComplete)
1.828 + {
1.829 + // reset the flags
1.830 + iPCMPUCallbackComplete = EFalse;
1.831 + iSourceSinkPUCallbackComplete = EFalse;
1.832 +
1.833 + // Both PUs initialised OK
1.834 + if (iState == EProcessingUnitInitializing)
1.835 + {
1.836 + iActiveWait->AsyncStop();
1.837 + }
1.838 + iState = EProcessingUnitIdle;
1.839 + }
1.840 + }
1.841 +
1.842 +/*
1.843 +@see MMdfProcessingUnitObserver::ExecuteComplete()
1.844 +*/
1.845 +void CMdfHwDeviceAdapter::ExecuteComplete(const CMdfProcessingUnit* aPu, TInt aErrorCode)
1.846 + {
1.847 + if(iStopping)
1.848 + {
1.849 + return;
1.850 + }
1.851 +
1.852 + if (iExecuteError == KErrNone)
1.853 + {
1.854 + iExecuteError = aErrorCode;
1.855 + }
1.856 +
1.857 + if(aPu == iCodecPU)
1.858 + {
1.859 + iPCMPUCallbackComplete = ETrue;
1.860 + }
1.861 + else if(aPu == iAudioDevicePU)
1.862 + {
1.863 + iSourceSinkPUCallbackComplete = ETrue;
1.864 + }
1.865 +
1.866 + if(iExecuteError != KErrNone || (iPCMPUCallbackComplete && iSourceSinkPUCallbackComplete))
1.867 + {
1.868 + if (iState == EProcessingUnitExecuting)
1.869 + {
1.870 + // stop the hardware device if we are still executing
1.871 + StopHwDevice(iExecuteError);
1.872 + iState = EProcessingUnitIdle;
1.873 + }
1.874 + // reset the flags
1.875 + iPCMPUCallbackComplete = EFalse;
1.876 + iSourceSinkPUCallbackComplete = EFalse;
1.877 + }
1.878 + }
1.879 +
1.880 +/*
1.881 +@see MMdfHwDeviceSetup::::SetDataTypesL()
1.882 +*/
1.883 +void CMdfHwDeviceAdapter::SetDataTypesL(TFourCC aSrcType, TFourCC aDestType)
1.884 + {
1.885 + // Find and load an appropriate Codec
1.886 + iCodecPU = iPuLoader->LoadProcessingUnitL(*this, aSrcType, aDestType);
1.887 + }
1.888 +
1.889 +/*
1.890 +Called to indicate that the Hardware Device has been stopped, leading
1.891 +to callbacks to the observer.
1.892 +@see MMMFHwDeviceObserver::Stopped()
1.893 +@see MMMFHwDeviceObserver::Error()
1.894 +*/
1.895 +void CMdfHwDeviceAdapter::StopHwDevice(TInt error)
1.896 + {
1.897 + iHwDeviceObserver->Stopped();
1.898 + iHwDeviceObserver->Error(error);
1.899 + }
1.900 +
1.901 +/*
1.902 +Returns the state of the Hardware Device Adapter object.
1.903 +*/
1.904 +void CMdfHwDeviceAdapter::GetState(THwDevAdapterState& aState) const
1.905 + {
1.906 + aState = iState;
1.907 + }
1.908 +