blob: e5ba28ef05fbf8b4568cb1989697b42d525b0565 [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 1998-2009 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
* See the License for the specific language governing permissions
* and limitations under the License.
* -------------------------------------------------------------------
*/
/**
* @file pvmf_media_input_node.cpp
* @brief
*/
#include "oscl_base.h"
#include "pvmf_media_input_node_factory.h"
#include "pvmf_media_input_node.h"
#include "pvmf_media_input_node_outport.h"
#include "oscl_dll.h"
#include "pvmf_basic_errorinfomessage.h"
#include "pvmf_media_input_node_events.h"
#ifndef PVMF_MEDIA_MSG_FORMAT_IDS_H_INCLUDED
#include "pvmf_media_msg_format_ids.h"
#endif
#ifndef PVMF_MEDIA_CMD_H_INCLUDED
#include "pvmf_media_cmd.h"
#endif
#include "oscl_assert.h"
// Define entry point for this DLL
OSCL_DLL_ENTRY_POINT_DEFAULT()
/**
//Macros for calling PVLogger
*/
#define LOGERROR(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_REL,iLogger,PVLOGMSG_ERR,m);
#define LOGINFOHI(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG,iLogger,PVLOGMSG_INFO,m);
#define LOGINFOMED(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG,iLogger,PVLOGMSG_INFO,m);
#define LOGINFOLOW(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG,iLogger,PVLOGMSG_INFO,m);
#define LOGINFO(m) LOGINFOMED(m)
#ifdef _TEST_AE_ERROR_HANDLING
#define FAIL_NODE_CMD_START 2
#define FAIL_NODE_CMD_STOP 3
#define FAIL_NODE_CMD_FLUSH 4
#define FAIL_NODE_CMD_PAUSE 5
#define FAIL_NODE_CMD_RELEASE_PORT 7
#endif
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFNodeInterface* PvmfMediaInputNodeFactory::Create(PvmiMIOControl* aMIOControl)
{
return PvmfMediaInputNode::Create(aMIOControl);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF void PvmfMediaInputNodeFactory::Delete(PVMFNodeInterface* aNode)
{
PvmfMediaInputNode::Release(aNode);
}
////////////////////////////////////////////////////////////////////////////
PVMFNodeInterface* PvmfMediaInputNode::Create(PvmiMIOControl* aIOInterfacePtr)
{
PvmfMediaInputNode* node = OSCL_NEW(PvmfMediaInputNode, ());
if (node)
{
OSCL_TRAPSTACK_PUSH(node);
node->ConstructL(aIOInterfacePtr);
OSCL_TRAPSTACK_POP();
}
return (PVMFNodeInterface*)node;
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNode::Release(PVMFNodeInterface* aNode)
{
OSCL_DELETE(((PvmfMediaInputNode*)aNode));
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNode::ThreadLogon()
{
if (iInterfaceState != EPVMFNodeCreated)
return PVMFErrInvalidState;
iLogger = PVLogger::GetLoggerObject("PvmfMediaInputNode");
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::ThreadLogon"));
if (!IsAdded())
AddToScheduler();
if (iMediaIOControl)
iMediaIOControl->ThreadLogon();
SetState(EPVMFNodeIdle);
#ifdef _TEST_AE_ERROR_HANDLING
iErrorHandlingStartFailed = false;
iErrorHandlingStopFailed = false;
iError_No_Memory = false;
iError_Out_Queue_Busy = false;
#endif
return PVMFSuccess;
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNode::ThreadLogoff()
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::ThreadLogoff"));
if (iInterfaceState != EPVMFNodeIdle)
return PVMFErrInvalidState;
if (IsAdded())
RemoveFromScheduler();
iLogger = NULL;
if (iMediaIOControl)
{
//notify the media input component that peer cap-config is no longer usable
//we do this by calling setParameterSync with NULL
OsclMemAllocator alloc;
PvmiKvp kvp;
kvp.key = NULL;
uint32 keylen = oscl_strlen(PVMF_MEDIA_INPUT_NODE_CAP_CONFIG_INTERFACE_KEY) + 1; // +1 for \0
kvp.key = (PvmiKeyType)alloc.ALLOCATE(keylen);
if (kvp.key != NULL)
{
oscl_memset(kvp.key, 0, keylen);
oscl_strncpy(kvp.key,
PVMF_MEDIA_INPUT_NODE_CAP_CONFIG_INTERFACE_KEY,
keylen-1);
kvp.value.key_specific_value = NULL;
kvp.length = 1; //since we are just passing one pointer
kvp.capacity = kvp.length;
PvmiKvp* retKvp = NULL; // for return value
int32 err;
OSCL_TRY(err, iMediaIOConfig->setParametersSync(NULL, &kvp, 1, retKvp););
/* ignore the error for now */
alloc.deallocate((OsclAny*)(kvp.key));
}
iMediaIOControl->ThreadLogoff();
iMediaIOControl->disconnect(iMediaIOSession);
//ignore any returned error.
iMediaIOState = PvmfMediaInputNode::MIO_STATE_IDLE;
}
SetState(EPVMFNodeCreated);
return PVMFSuccess;
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNode::GetCapability(PVMFNodeCapability& aNodeCapability)
{
if (!iMediaIOConfig)
return PVMFFailure;
aNodeCapability.iCanSupportMultipleInputPorts = false;
aNodeCapability.iCanSupportMultipleOutputPorts = false;
aNodeCapability.iHasMaxNumberOfPorts = true;
aNodeCapability.iMaxNumberOfPorts = 1;
PvmiKvp* kvp ;
int numParams ;
int32 err ;
int32 i ;
PVMFStatus status;
// Get input formats capability from media IO
kvp = NULL;
numParams = 0;
status = iMediaIOConfig->getParametersSync(NULL, (PvmiKeyType)INPUT_FORMATS_CAP_QUERY, kvp, numParams, NULL);
if (status == PVMFSuccess)
{
OSCL_TRY(err,
for (i = 0; i < numParams; i++)
aNodeCapability.iInputFormatCapability.push_back(PVMFFormatType(kvp[i].value.pChar_value));
);
if (kvp)
iMediaIOConfig->releaseParameters(0, kvp, numParams);
}
//else ignore errors.
// Get output formats capability from media IO
kvp = NULL;
numParams = 0;
status = iMediaIOConfig->getParametersSync(NULL, (PvmiKeyType)OUTPUT_FORMATS_CAP_QUERY, kvp, numParams, NULL);
if (status == PVMFSuccess)
{
OSCL_TRY(err,
for (i = 0; i < numParams; i++)
aNodeCapability.iOutputFormatCapability.push_back(PVMFFormatType(kvp[i].value.pChar_value));
);
if (kvp)
iMediaIOConfig->releaseParameters(0, kvp, numParams);
}
//else ignore errors.
if (aNodeCapability.iInputFormatCapability.empty() && aNodeCapability.iOutputFormatCapability.empty())
return PVMFFailure;
return PVMFSuccess;
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFPortIter* PvmfMediaInputNode::GetPorts(const PVMFPortFilter* aFilter)
{
OSCL_UNUSED_ARG(aFilter);//port filter is not implemented.
iOutPortVector.Reset();
return &iOutPortVector;
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFCommandId PvmfMediaInputNode::QueryUUID(PVMFSessionId s, const PvmfMimeString& aMimeType,
Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids,
bool aExactUuidsOnly,
const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::QueryUUID() called"));
PvmfMediaInputNodeCmd cmd;
cmd.PvmfMediaInputNodeCmdBase::Construct(s, PVMF_GENERIC_NODE_QUERYUUID, aMimeType, aUuids, aExactUuidsOnly, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFCommandId PvmfMediaInputNode::QueryInterface(PVMFSessionId s, const PVUuid& aUuid,
PVInterface*& aInterfacePtr,
const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::QueryInterface() called"));
PvmfMediaInputNodeCmd cmd;
cmd.PvmfMediaInputNodeCmdBase::Construct(s, PVMF_GENERIC_NODE_QUERYINTERFACE, aUuid, aInterfacePtr, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFCommandId PvmfMediaInputNode::RequestPort(PVMFSessionId s, int32 aPortTag, const PvmfMimeString* aPortConfig, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::RequestPort() called"));
PvmfMediaInputNodeCmd cmd;
cmd.PvmfMediaInputNodeCmdBase::Construct(s, PVMF_GENERIC_NODE_REQUESTPORT, aPortTag, aPortConfig, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFCommandId PvmfMediaInputNode::ReleasePort(PVMFSessionId s, PVMFPortInterface& aPort, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::ReleasePort() called"));
PvmfMediaInputNodeCmd cmd;
cmd.PvmfMediaInputNodeCmdBase::Construct(s, PVMF_GENERIC_NODE_RELEASEPORT, aPort, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFCommandId PvmfMediaInputNode::Init(PVMFSessionId s, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::Init() called"));
PvmfMediaInputNodeCmd cmd;
cmd.PvmfMediaInputNodeCmdBase::Construct(s, PVMF_GENERIC_NODE_INIT, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFCommandId PvmfMediaInputNode::Prepare(PVMFSessionId s, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::Prepare() called"));
PvmfMediaInputNodeCmd cmd;
cmd.PvmfMediaInputNodeCmdBase::Construct(s, PVMF_GENERIC_NODE_PREPARE, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFCommandId PvmfMediaInputNode::Start(PVMFSessionId s, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::Start() called"));
PvmfMediaInputNodeCmd cmd;
cmd.PvmfMediaInputNodeCmdBase::Construct(s, PVMF_GENERIC_NODE_START, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFCommandId PvmfMediaInputNode::Stop(PVMFSessionId s, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::Stop() called"));
PvmfMediaInputNodeCmd cmd;
cmd.PvmfMediaInputNodeCmdBase::Construct(s, PVMF_GENERIC_NODE_STOP, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFCommandId PvmfMediaInputNode::Flush(PVMFSessionId s, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::Flush() called"));
PvmfMediaInputNodeCmd cmd;
cmd.PvmfMediaInputNodeCmdBase::Construct(s, PVMF_GENERIC_NODE_FLUSH, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFCommandId PvmfMediaInputNode::Pause(PVMFSessionId s, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::Pause() called"));
PvmfMediaInputNodeCmd cmd;
cmd.PvmfMediaInputNodeCmdBase::Construct(s, PVMF_GENERIC_NODE_PAUSE, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFCommandId PvmfMediaInputNode::Reset(PVMFSessionId s, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::Reset() called"));
PvmfMediaInputNodeCmd cmd;
cmd.PvmfMediaInputNodeCmdBase::Construct(s, PVMF_GENERIC_NODE_RESET, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFCommandId PvmfMediaInputNode::CancelAllCommands(PVMFSessionId s, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::CancelAllCommands() called"));
PvmfMediaInputNodeCmd cmd;
cmd.PvmfMediaInputNodeCmdBase::Construct(s, PVMF_GENERIC_NODE_CANCELALLCOMMANDS, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFCommandId PvmfMediaInputNode::CancelCommand(PVMFSessionId s, PVMFCommandId aCmdId, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::CancelCommands() called cmdId=%d", aCmdId));
PvmfMediaInputNodeCmd cmd;
cmd.PvmfMediaInputNodeCmdBase::Construct(s, PVMF_GENERIC_NODE_CANCELCOMMAND, aCmdId, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF void PvmfMediaInputNode::addRef()
{
++iExtensionRefCount;
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF void PvmfMediaInputNode::removeRef()
{
if (iExtensionRefCount > 0)
--iExtensionRefCount;
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF bool PvmfMediaInputNode::queryInterface(const PVUuid& uuid, PVInterface*& iface)
{
if (uuid == PvmfNodesSyncControlUuid)
{
PvmfNodesSyncControlInterface* myInterface = OSCL_STATIC_CAST(PvmfNodesSyncControlInterface*, this);
iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
++iExtensionRefCount;
}
else if (uuid == PVMI_CAPABILITY_AND_CONFIG_PVUUID)
{
PvmiCapabilityAndConfig* myInterface = OSCL_STATIC_CAST(PvmiCapabilityAndConfig*, this);
iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
++iExtensionRefCount;
}
else
{
iface = NULL;
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF void PvmfMediaInputNode::RequestCompleted(const PVMFCmdResp& aResponse)
//callback from the MIO module.
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::RequestCompleted: Cmd ID=%d", aResponse.GetCmdId()));
//look for cancel completion.
if (iMediaIOCancelPending
&& aResponse.GetCmdId() == iMediaIOCancelCmdId)
{
iMediaIOCancelPending = false;
OSCL_ASSERT(!iCancelCommand.empty());
//Current cancel command is now complete.
CommandComplete(iCancelCommand, iCancelCommand.front(), PVMFSuccess);
}
//look for non-cancel completion
else if (iMediaIORequest != ENone
&& aResponse.GetCmdId() == iMediaIOCmdId)
{
OSCL_ASSERT(!iCurrentCommand.empty());
PvmfMediaInputNodeCmd& cmd = iCurrentCommand.front();
switch (iMediaIORequest)
{
case EQueryCapability:
if (aResponse.GetCmdStatus() != PVMFSuccess)
{
cmd.iEventCode = PvmfMediaInputNodeErr_MediaIOQueryCapConfigInterface;
}
else
{
if (iMediaIOConfigPVI)
{
iMediaIOConfig = OSCL_STATIC_CAST(PvmiCapabilityAndConfig*, iMediaIOConfigPVI);
iMediaIOConfigPVI = NULL;
//now attempt to provide the media input comp with the capconfig interface of the node
OsclMemAllocator alloc;
PvmiKvp kvp;
kvp.key = NULL;
uint32 keylen = oscl_strlen(PVMF_MEDIA_INPUT_NODE_CAP_CONFIG_INTERFACE_KEY) + 1; // +1 for \0
kvp.key = (PvmiKeyType)alloc.ALLOCATE(keylen);
if (kvp.key != NULL)
{
oscl_memset(kvp.key, 0, keylen);
oscl_strncpy(kvp.key,
PVMF_MEDIA_INPUT_NODE_CAP_CONFIG_INTERFACE_KEY,
keylen-1);
PvmiCapabilityAndConfig* capconfig = OSCL_STATIC_CAST(PvmiCapabilityAndConfig*, this);
kvp.value.key_specific_value = (OsclAny*)(capconfig);
kvp.length = 1; //since we are just passing one pointer
kvp.capacity = kvp.length;
PvmiKvp* retKvp = NULL; // for return value
int32 err;
OSCL_TRY(err, iMediaIOConfig->setParametersSync(NULL, &kvp, 1, retKvp););
/* ignore the error for now */
alloc.deallocate((OsclAny*)(kvp.key));
}
}
else
{
LOGERROR((0, "PvmfMediaInputNode:RequestComplete Error:Not setting Queryinterface ,iTempCapConfigInterface is NULL"));
}
}
break;
case EInit:
if (aResponse.GetCmdStatus() != PVMFSuccess)
{
cmd.iEventCode = PvmfMediaInputNodeErr_MediaIOInit;
}
else
{
iMediaIOState = MIO_STATE_INITIALIZED;
}
break;
case EStart:
if (aResponse.GetCmdStatus() != PVMFSuccess)
{
cmd.iEventCode = PvmfMediaInputNodeErr_MediaIOStart;
}
else
{
iMediaIOState = MIO_STATE_STARTED;
//tell all the ports that I/O is started.
{
uint32 i;
for (i = 0; i < iOutPortVector.size(); i++)
iOutPortVector[i]->MediaIOStarted();
}
}
break;
case EPause:
if (aResponse.GetCmdStatus() != PVMFSuccess)
{
cmd.iEventCode = PvmfMediaInputNodeErr_MediaIOPause;
}
else
{
iMediaIOState = MIO_STATE_PAUSED;
}
break;
case EStop:
if (aResponse.GetCmdStatus() != PVMFSuccess)
{
cmd.iEventCode = PvmfMediaInputNodeErr_MediaIOStop;
}
else
{
iMediaIOState = MIO_STATE_INITIALIZED;
}
break;
case EReset:
if (aResponse.GetCmdStatus() != PVMFSuccess)
{
cmd.iEventCode = PvmfMediaInputNodeErr_MediaIOReset;
}
else
{
iMediaIOState = MIO_STATE_IDLE;
SetState(EPVMFNodeIdle);
}
break;
default:
OSCL_ASSERT(false);
break;
}
//current node command is now complete.
if (IsFlushPending())
{
iMediaIORequest = ENone;
FlushComplete();
}
else
{
CommandComplete(iCurrentCommand, iCurrentCommand.front(), aResponse.GetCmdStatus());
}
}
else
{
//unexpected response.
LOGERROR((0, "PvmfMediaInputNode:RequestComplete Warning! Unexpected command ID %d"
, aResponse.GetCmdId()));
}
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF void PvmfMediaInputNode::ReportErrorEvent(PVMFEventType aEventType, PVInterface* aExtMsg)
{
OSCL_UNUSED_ARG(aEventType);
OSCL_UNUSED_ARG(aExtMsg);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF void PvmfMediaInputNode::ReportInfoEvent(PVMFEventType aEventType, PVInterface* aExtMsg)
{
if (aEventType == PVMFInfoOverflow) {
PVMFNodeInterface::ReportInfoEvent(aEventType, NULL, aExtMsg);
} else {
OSCL_UNUSED_ARG(aEventType);
OSCL_UNUSED_ARG(aExtMsg);
}
}
////////////////////////////////////////////////////////////////////////////
PvmfMediaInputNode::PvmfMediaInputNode()
: OsclActiveObject(OsclActiveObject::EPriorityNominal, "PvmfMediaInputNode")
, iMediaIOControl(NULL)
, iMediaIOSession(NULL)
, iMediaIOConfig(NULL)
, iMediaIOConfigPVI(NULL)
, iMediaIOState(PvmfMediaInputNode::MIO_STATE_IDLE)
, iEventUuid(PvmfMediaInputNodeEventTypesUUID)
, iExtensionRefCount(0)
, iLogger(NULL)
{
#ifdef _TEST_AE_ERROR_HANDLING
iChunkCount = 0;
iErrorTrackID = -1;
iTrackID = 0;
iErrorCancelMioRequest = false;
iErrorSendMioRequest = 0;
iErrorNodeCmd = 0;
#endif
}
////////////////////////////////////////////////////////////////////////////
PvmfMediaInputNode::~PvmfMediaInputNode()
{
Cancel();
if (IsAdded())
RemoveFromScheduler();
//if any MIO commands are outstanding, there will be
//a crash when they callback-- so panic here instead.
if (!iCancelCommand.empty()
|| iMediaIORequest != ENone)
OSCL_ASSERT(0);
//Cleanup allocated ports
while (!iOutPortVector.empty())
iOutPortVector.Erase(&iOutPortVector.front());
//Cleanup commands
//The command queues are self-deleting, but we want to
//notify the observer of unprocessed commands.
while (!iCurrentCommand.empty())
{
CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFFailure);
// iCurrentCommand.Erase(&iCurrentCommand.front());
}
while (!iInputCommands.empty())
{
CommandComplete(iInputCommands, iInputCommands.front(), PVMFFailure);
// iInputCommands.Erase(&iInputCommands.front());
}
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNode::ConstructL(PvmiMIOControl* aIOInterfacePtr)
{
iLogger = NULL;
iMediaIOControl = aIOInterfacePtr;
iPortActivity = 0;
iInputCommands.Construct(1, 10);//reserve 10
iCurrentCommand.Construct(1, 1);//reserve 1.
iCancelCommand.Construct(1, 1);//reserve 1.
iOutPortVector.Construct(0);//reserve zero.
iMediaIORequest = ENone;
iMediaIOCancelPending = false;
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNode::Run()
{
//Process async node commands.
if (!iInputCommands.empty())
{
ProcessCommand();
}
}
////////////////////////////////////////////////////////////////////////////
PVMFCommandId PvmfMediaInputNode::QueueCommandL(PvmfMediaInputNodeCmd& aCmd)
{
PVMFCommandId id;
id = iInputCommands.AddL(aCmd);
//wakeup the AO
RunIfNotReady();
return id;
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNode::ProcessCommand()
{
//Can't do anything when an asynchronous cancel is in progress-- just
//need to wait on completion.
if (!iCancelCommand.empty())
return ; //keep waiting.
//If a command is in progress, only hi pri cancel commands can interrupt it.
if (!iCurrentCommand.empty()
&& !iInputCommands.front().hipri())
{
return ; //keep waiting
}
//The newest or highest pri command is in the front of the queue.
OSCL_ASSERT(!iInputCommands.empty());
PvmfMediaInputNodeCmd& aCmd = iInputCommands.front();
PVMFStatus cmdstatus;
OsclAny* aEventData = NULL;
if (aCmd.hipri())
{
//save input command in cancel command
int32 err;
OSCL_TRY(err, iCancelCommand.StoreL(aCmd););
if (err != OsclErrNone)
{
cmdstatus = PVMFErrNoMemory;
}
else
{
//Process the interrupt commands.
switch (aCmd.iCmd)
{
case PVMF_GENERIC_NODE_CANCELALLCOMMANDS:
cmdstatus = DoCancelAllCommands(aCmd);
break;
case PVMF_GENERIC_NODE_CANCELCOMMAND:
cmdstatus = DoCancelCommand(aCmd);
break;
default:
OSCL_ASSERT(false);
cmdstatus = PVMFFailure;
break;
}
}
//erase the input command.
if (cmdstatus != PVMFPending)
{
//Request already failed-- erase from Cancel Command.
//Node command remains in Input Commands.
iCancelCommand.Erase(&iCurrentCommand.front());
}
else
{
//Node command is now stored in Cancel Command, so erase from Input Commands.
iInputCommands.Erase(&aCmd);
}
}
else
{
//save input command in current command
int32 err;
OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
if (err != OsclErrNone)
{
cmdstatus = PVMFErrNoMemory;
}
else
{
//Process the normal pri commands.
switch (aCmd.iCmd)
{
case PVMF_GENERIC_NODE_QUERYUUID:
cmdstatus = DoQueryUuid(aCmd);
break;
case PVMF_GENERIC_NODE_QUERYINTERFACE:
cmdstatus = DoQueryInterface(aCmd);
break;
case PVMF_GENERIC_NODE_REQUESTPORT:
cmdstatus = DoRequestPort(aCmd, aEventData);
break;
case PVMF_GENERIC_NODE_RELEASEPORT:
cmdstatus = DoReleasePort(aCmd);
break;
case PVMF_GENERIC_NODE_INIT:
cmdstatus = DoInit(aCmd);
break;
case PVMF_GENERIC_NODE_PREPARE:
cmdstatus = DoPrepare(aCmd);
break;
case PVMF_GENERIC_NODE_START:
cmdstatus = DoStart(aCmd);
break;
case PVMF_GENERIC_NODE_STOP:
cmdstatus = DoStop(aCmd);
break;
case PVMF_GENERIC_NODE_FLUSH:
cmdstatus = DoFlush(aCmd);
break;
case PVMF_GENERIC_NODE_PAUSE:
cmdstatus = DoPause(aCmd);
break;
case PVMF_GENERIC_NODE_RESET:
cmdstatus = DoReset(aCmd);
break;
default://unknown command type
OSCL_ASSERT(false);
cmdstatus = PVMFFailure;
break;
}
}
//erase the input command.
if (cmdstatus != PVMFPending)
{
//Request already failed-- erase from Current Command.
//Node command remains in Input Commands.
iCurrentCommand.Erase(&iCurrentCommand.front());
}
else
{
//Node command is now stored in Current Command, so erase from Input Commands.
iInputCommands.Erase(&aCmd);
}
}
if (cmdstatus != PVMFPending)
CommandComplete(iInputCommands, aCmd, cmdstatus, aEventData);
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNode::CommandComplete(PvmfMediaInputNodeCmdQ& aCmdQ, PvmfMediaInputNodeCmd& aCmd, PVMFStatus aStatus, OsclAny*aEventData)
{
if (aStatus == PVMFSuccess)
{
LOGINFO((0, "PvmfMediaInputNode:CommandComplete Id %d Cmd %d Status %d Context %d EVData %d EVCode %d"
, aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData, aCmd.iEventCode));
}
else
{
LOGERROR((0, "PvmfMediaInputNode:CommandComplete Error! Id %d Cmd %d Status %d Context %d EVData %d EVCode %d"
, aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData, aCmd.iEventCode));
}
//do state transitions and any final command completion.
if (aStatus == PVMFSuccess)
{
switch (aCmd.iCmd)
{
case PVMF_GENERIC_NODE_INIT:
SetState(EPVMFNodeInitialized);
break;
case PVMF_GENERIC_NODE_PREPARE:
SetState(EPVMFNodePrepared);
break;
case PVMF_GENERIC_NODE_START:
SetState(EPVMFNodeStarted);
break;
case PVMF_GENERIC_NODE_PAUSE:
SetState(EPVMFNodePaused);
break;
case PVMF_GENERIC_NODE_STOP:
SetState(EPVMFNodePrepared);
//clear the message queues of any unprocessed data now.
{
uint32 i;
for (i = 0; i < iOutPortVector.size(); i++)
iOutPortVector[i]->ClearMsgQueues();
}
break;
case PVMF_GENERIC_NODE_FLUSH:
SetState(EPVMFNodePrepared);
//Stop the ports
{
for (uint32 i = 0; i < iOutPortVector.size(); i++)
iOutPortVector[i]->Stop();
}
break;
default:
break;
}
}
//Reset the media I/O request
iMediaIORequest = ENone;
//The "startmio" command originated from port activity,
//not from the node controller, so no command complete event
//is needed.
if (aCmd.iCmd == PVMF_MEDIAIONODE_STARTMIO)
{
//Erase the command from the queue.
aCmdQ.Erase(&aCmd);
}
else
{
//Extract parameters needed for command response.
PVMFCommandId cmdId = aCmd.iId;
const OsclAny* cmdContext = aCmd.iContext;
PVMFSessionId cmdSess = aCmd.iSession;
PVMFStatus eventCode = aCmd.iEventCode;
//Erase the command from the queue.
aCmdQ.Erase(&aCmd);
if (eventCode != PvmfMediaInputNodeErr_First)
{
//create extended response.
PVMFBasicErrorInfoMessage*eventmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (eventCode, iEventUuid, NULL));
PVMFCmdResp resp(cmdId
, cmdContext
, aStatus
, OSCL_STATIC_CAST(PVInterface*, eventmsg)
, aEventData);
//report to the session observers.
PVMFNodeInterface::ReportCmdCompleteEvent(cmdSess, resp);
//remove the ref to the extended response
if (eventmsg)
eventmsg->removeRef();
}
else
{
//create basic response
PVMFCmdResp resp(cmdId, cmdContext, aStatus, aEventData);
//report to the session observers.
PVMFNodeInterface::ReportCmdCompleteEvent(cmdSess, resp);
}
}
//re-schedule if there are more commands and node isn't logged off
if (!iInputCommands.empty()
&& IsAdded())
RunIfNotReady();
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PvmfMediaInputNode::DoQueryUuid(PvmfMediaInputNodeCmd& aCmd)
{
//This node supports Query UUID from any state
OSCL_String* mimetype;
Oscl_Vector<PVUuid, OsclMemAllocator> *uuidvec;
bool exactmatch;
aCmd.PvmfMediaInputNodeCmdBase::Parse(mimetype, uuidvec, exactmatch);
uuidvec->push_back(PvmfNodesSyncControlUuid);
return PVMFSuccess;
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PvmfMediaInputNode::DoQueryInterface(PvmfMediaInputNodeCmd& aCmd)
{
PVUuid* uuid;
PVInterface** ptr;
aCmd.PvmfMediaInputNodeCmdBase::Parse(uuid, ptr);
if (uuid && ptr)
{
if (queryInterface(*uuid, *ptr))
return PVMFSuccess;
}
return PVMFFailure;
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PvmfMediaInputNode::DoRequestPort(PvmfMediaInputNodeCmd& aCmd, OsclAny*&aEventData)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::DoRequestPort"));
//This node supports port request from any state
//retrieve port tag & mimetype
int32 tag;
OSCL_String* mimetype;
aCmd.PvmfMediaInputNodeCmdBase::Parse(tag, mimetype);
switch (tag)
{
case PVMF_MEDIAIO_NODE_OUTPUT_PORT_TAG:
{
//Allocate a new port
OsclAny *ptr = NULL;
int32 err;
OSCL_TRY(err, ptr = iOutPortVector.Allocate(););
if (err != OsclErrNone || !ptr)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
(0, "PvmfMediaInputNode::DoRequestPort: Error - iOutPortVector Out of memory"));
return PVMFErrNoMemory;
}
OSCL_StackString<20> portname;
portname = "PVMFMediaIpNodeOut";
PvmfMediaInputNodeOutPort *port = OSCL_PLACEMENT_NEW(ptr, PvmfMediaInputNodeOutPort(this, portname.get_cstr()));
//set the format from the mimestring.
if (mimetype)
{
PVMFFormatType fmt = mimetype->get_str();
if (fmt != PVMF_MIME_FORMAT_UNKNOWN)
port->Configure(fmt, mimetype);
}
//Add the port to the port vector.
OSCL_TRY(err, iOutPortVector.AddL(port););
if (err != OsclErrNone)
{
iOutPortVector.DestructAndDealloc(port);
return PVMFErrNoMemory;
}
aEventData = (OsclAny*)port;
//cast the port to the generic interface before returning.
PVMFPortInterface*retval = port;
aEventData = (OsclAny*)retval;
return PVMFSuccess;
}
default:
{
//bad port tag
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
(0, "PvmfMediaInputNode::DoRequestPort: Error - Invalid port tag"));
return PVMFFailure;
}
}
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PvmfMediaInputNode::DoReleasePort(PvmfMediaInputNodeCmd& aCmd)
{
//This node supports release port from any state
PVMFPortInterface* p;
aCmd.PvmfMediaInputNodeCmdBase::Parse(p);
//search the output port vector
{
PvmfMediaInputNodeOutPort* port = (PvmfMediaInputNodeOutPort*)p;
PvmfMediaInputNodeOutPort** portPtr = iOutPortVector.FindByValue(port);
#ifdef _TEST_AE_ERROR_HANDLING
if (FAIL_NODE_CMD_RELEASE_PORT == iErrorNodeCmd)
{
portPtr = NULL;
}
#endif
if (portPtr)
{
(*portPtr)->Disconnect();
iOutPortVector.Erase(portPtr);
return PVMFSuccess;
}
}
aCmd.iEventCode = PvmfMediaInputNodeErr_PortNotExist;
return PVMFFailure;
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PvmfMediaInputNode::DoInit(PvmfMediaInputNodeCmd& aCmd)
{
OSCL_UNUSED_ARG(aCmd);
if (EPVMFNodeInitialized == iInterfaceState)
{
return PVMFSuccess;
}
if (iInterfaceState != EPVMFNodeIdle)
return PVMFErrInvalidState;
if (!iMediaIOControl)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
(0, "PvmfMediaInputNode::DoInit: Error - iMediaIOControl is NULL"));
aCmd.iEventCode = PvmfMediaInputNodeErr_MediaIONotExist;
return PVMFFailure;
}
if (iMediaIOControl->connect(iMediaIOSession, this) != PVMFSuccess)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
(0, "PvmfMediaInputNode::DoInit: Error - iMediaIOControl->connect failed"));
aCmd.iEventCode = PvmfMediaInputNodeErr_MediaIOConnect;
return PVMFFailure;
}
//Query for MIO capability and config interface
return SendMioRequest(aCmd, EQueryCapability);
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PvmfMediaInputNode::DoPrepare(PvmfMediaInputNodeCmd& aCmd)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::DoPrepare"));
if (EPVMFNodePrepared == iInterfaceState)
{
return PVMFSuccess;
}
if (iInterfaceState != EPVMFNodeInitialized)
return PVMFErrInvalidState;
return SendMioRequest(aCmd, EInit);
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PvmfMediaInputNode::DoStart(PvmfMediaInputNodeCmd& aCmd)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::DoStart"));
#ifdef _TEST_AE_ERROR_HANDLING
if (FAIL_NODE_CMD_START == iErrorNodeCmd)
{
iInterfaceState = EPVMFNodeError;
}
#endif
if (EPVMFNodeStarted == iInterfaceState)
{
return PVMFSuccess;
}
if (iInterfaceState != EPVMFNodePrepared
&& iInterfaceState != EPVMFNodePaused)
return PVMFErrInvalidState;
//Start the MIO
PVMFStatus status = SendMioRequest(aCmd, EStart);
if (status != PVMFPending)
return status;
//Start the ports
uint32 i = 0;
for (i = 0; i < iOutPortVector.size(); i++)
iOutPortVector[i]->Start();
return status;
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PvmfMediaInputNode::DoStop(PvmfMediaInputNodeCmd& aCmd)
{
#ifdef _TEST_AE_ERROR_HANDLING
if (FAIL_NODE_CMD_STOP == iErrorNodeCmd)
{
iInterfaceState = EPVMFNodeError;
}
#endif
if (EPVMFNodePrepared == iInterfaceState)
{
return PVMFSuccess;
}
if (iInterfaceState != EPVMFNodeStarted
&& iInterfaceState != EPVMFNodePaused)
return PVMFErrInvalidState;
//Stop the MIO
PVMFStatus status = SendMioRequest(aCmd, EStop);
//Stop the ports
for (uint32 i = 0; i < iOutPortVector.size(); i++)
iOutPortVector[i]->Stop();
return status;
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PvmfMediaInputNode::DoFlush(PvmfMediaInputNodeCmd& aCmd)
{
#ifdef _TEST_AE_ERROR_HANDLING
if (FAIL_NODE_CMD_FLUSH == iErrorNodeCmd)
{
iInterfaceState = EPVMFNodeError;
}
#endif
if (iInterfaceState != EPVMFNodeStarted
&& iInterfaceState != EPVMFNodePaused)
return PVMFErrInvalidState;
//Disable the input.
if (iOutPortVector.size() > 0)
{
//Stop the MIO input
SendMioRequest(aCmd, EStop);
//ignore returned error.
}
//wait for all data to be consumed
return PVMFPending;
}
////////////////////////////////////////////////////////////////////////////
bool PvmfMediaInputNode::IsFlushPending()
{
return (iCurrentCommand.size() > 0
&& iCurrentCommand.front().iCmd == PVMF_GENERIC_NODE_FLUSH);
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNode::FlushComplete()
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::FlushComplete"));
if (iMediaIORequest != ENone)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
(0, "PvmfMediaInputNode::FlushComplete: Media IO request is pending"));
return;
}
if (!PortQueuesEmpty())
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
(0, "PvmfMediaInputNode::FlushComplete: Port queues are not empty"));
return;
}
//Flush is complete.
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
(0, "PvmfMediaInputNode::FlushComplete: Done"));
CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PvmfMediaInputNode::DoPause(PvmfMediaInputNodeCmd& aCmd)
{
#ifdef _TEST_AE_ERROR_HANDLING
if (FAIL_NODE_CMD_PAUSE == iErrorNodeCmd)
{
iInterfaceState = EPVMFNodeError;
}
#endif
if (EPVMFNodePaused == iInterfaceState)
{
return PVMFSuccess;
}
if (iInterfaceState != EPVMFNodeStarted)
return PVMFErrInvalidState;
return SendMioRequest(aCmd, EPause);
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PvmfMediaInputNode::DoReset(PvmfMediaInputNodeCmd& aCmd)
{
OSCL_UNUSED_ARG(aCmd);
if (IsAdded())
{
for (uint32 i = 0; i < iOutPortVector.size(); i++)
{
iOutPortVector[i]->Stop();
iOutPortVector[i]->Disconnect();
}
//delete all ports and notify observer.
while (!iOutPortVector.empty())
iOutPortVector.Erase(&iOutPortVector.front());
//restore original port vector reserve.
iOutPortVector.Reconstruct();
//Reset the MIO
PVMFStatus status = SendMioRequest(aCmd, EReset);
return status;
}
else
{
OSCL_LEAVE(OsclErrInvalidState);
return 0;
}
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PvmfMediaInputNode::DoCancelAllCommands(PvmfMediaInputNodeCmd& aCmd)
{
//first cancel any MIO commmand in progress.
if (iMediaIORequest != ENone)
{
return CancelMioRequest(aCmd);
}
//first cancel the current command if any
{
while (!iCurrentCommand.empty())
CommandComplete(iCurrentCommand, iCurrentCommand[0], PVMFErrCancelled);
}
//next cancel all queued commands
{
//start at element 1 since this cancel command is element 0.
while (iInputCommands.size() > 1)
CommandComplete(iInputCommands, iInputCommands[1], PVMFErrCancelled);
}
//finally, report cancel complete.
return PVMFSuccess;
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PvmfMediaInputNode::DoCancelCommand(PvmfMediaInputNodeCmd& aCmd)
{
//tbd, need to cancel the MIO
//extract the command ID from the parameters.
PVMFCommandId id;
aCmd.PvmfMediaInputNodeCmdBase::Parse(id);
//first check "current" command if any
{
PvmfMediaInputNodeCmd* cmd = iCurrentCommand.FindById(id);
if (cmd)
{
//first cancel any MIO commmand in progress.
if (iMediaIORequest != ENone)
{
return CancelMioRequest(aCmd);
}
else
{
//cancel the queued command
CommandComplete(iCurrentCommand, *cmd, PVMFErrCancelled);
//report cancel success
return PVMFSuccess;
}
}
}
//next check input queue.
{
//start at element 1 since this cancel command is element 0.
PvmfMediaInputNodeCmd* cmd = iInputCommands.FindById(id, 1);
if (cmd)
{
//cancel the queued command
CommandComplete(iInputCommands, *cmd, PVMFErrCancelled);
//report cancel success
return PVMFSuccess;
}
}
//if we get here the command isn't queued so the cancel fails.
aCmd.iEventCode = PvmfMediaInputNodeErr_CmdNotQueued;
return PVMFFailure;
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PvmfMediaInputNode::SendMioRequest(PvmfMediaInputNodeCmd& aCmd, EMioRequest aRequest)
{
//Make an asynchronous request to MIO component
//and save the request in iMediaIORequest.
//there should not be a MIO command in progress..
OSCL_ASSERT(iMediaIORequest == ENone);
//save media io request.
iMediaIORequest = aRequest;
PVMFStatus status;
//Issue the command to the MIO.
switch (aRequest)
{
case EQueryCapability:
{
int32 err ;
OSCL_TRY(err,
iMediaIOCmdId = iMediaIOControl->QueryInterface(PVMI_CAPABILITY_AND_CONFIG_PVUUID,
iMediaIOConfigPVI, NULL);
);
if (err != OsclErrNone)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
(0, "PvmfMediaInputNode::DoInit: Error - iMediaIOControl->QueryInterface failed"));
aCmd.iEventCode = PvmfMediaInputNodeErr_MediaIOQueryCapConfigInterface;
status = PVMFFailure;
}
else
{
status = PVMFPending;
}
}
break;
case EInit:
{
if (iMediaIOState != MIO_STATE_IDLE)
{
aCmd.iEventCode = PvmfMediaInputNodeErr_MediaIOWrongState;
status = PVMFFailure;
break;
}
int32 err ;
OSCL_TRY(err, iMediaIOCmdId = iMediaIOControl->Init(););
if (err != OsclErrNone)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
(0, "PvmfMediaInputNode::DoInit: Error - iMediaIOControl->Init failed"));
aCmd.iEventCode = PvmfMediaInputNodeErr_MediaIOInit;
status = PVMFFailure;
}
else
{
status = PVMFPending;
}
}
break;
case EStart:
{
if (iMediaIOState != MIO_STATE_INITIALIZED
&& iMediaIOState != MIO_STATE_PAUSED)
{
aCmd.iEventCode = PvmfMediaInputNodeErr_MediaIOWrongState;
status = PVMFFailure;
break;
}
int32 err ;
OSCL_TRY(err, iMediaIOCmdId = iMediaIOControl->Start(););
#ifdef _TEST_AE_ERROR_HANDLING
if (iErrorHandlingStartFailed)
{
err = OsclErrGeneral;
}
#endif
if (err != OsclErrNone)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
(0, "PvmfMediaInputNode::DoInit: Error - iMediaIOControl->Start failed"));
aCmd.iEventCode = PvmfMediaInputNodeErr_MediaIOStart;
status = PVMFFailure;
}
else
{
status = PVMFPending;
}
}
break;
case EPause:
{
if (iMediaIOState != MIO_STATE_STARTED)
{
aCmd.iEventCode = PvmfMediaInputNodeErr_MediaIOWrongState;
status = PVMFFailure;
break;
}
int32 err = 0 ;
OSCL_TRY(err, iMediaIOCmdId = iMediaIOControl->Pause(););
#ifdef _TEST_AE_ERROR_HANDLING
if (iErrorSendMioRequest == 2)
{
err = OsclErrGeneral;
}
#endif
if (err != OsclErrNone)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
(0, "PvmfMediaInputNode::DoInit: Error - iMediaIOControl->Pause failed"));
aCmd.iEventCode = PvmfMediaInputNodeErr_MediaIOPause;
status = PVMFFailure;
}
else
{
status = PVMFPending;
}
}
break;
case EStop:
{
if (iMediaIOState != MIO_STATE_STARTED
&& iMediaIOState != MIO_STATE_PAUSED)
{
aCmd.iEventCode = PvmfMediaInputNodeErr_MediaIOWrongState;
status = PVMFFailure;
break;
}
int32 err ;
OSCL_TRY(err, iMediaIOCmdId = iMediaIOControl->Stop(););
#ifdef _TEST_AE_ERROR_HANDLING
if (iErrorHandlingStopFailed)
{
err = OsclErrGeneral;
}
#endif
if (err != OsclErrNone)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
(0, "PvmfMediaInputNode::DoInit: Error - iMediaIOControl->Stop failed"));
aCmd.iEventCode = PvmfMediaInputNodeErr_MediaIOStop;
status = PVMFFailure;
}
else
{
status = PVMFPending;
}
}
break;
case EReset:
{
int32 err ;
OSCL_TRY(err, iMediaIOCmdId = iMediaIOControl->Reset(););
if (err != OsclErrNone)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
(0, "PVMediaInputNode::SendMioRequest: Error - iMIOControl->Reset failed"));
aCmd.iEventCode = PvmfMediaInputNodeErr_MediaIOReset;
status = PVMFFailure;
}
else
{
status = PVMFPending;
}
}
break;
default:
status = PVMFFailure;
OSCL_ASSERT(false);//unrecognized command.
}
if (status == PVMFPending)
{
LOGINFOHI((0, "PvmfMediaInputNode:SendMIORequest: Command Issued to MIO component, waiting on response..."));
}
return status;
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PvmfMediaInputNode::CancelMioRequest(PvmfMediaInputNodeCmd& aCmd)
{
OSCL_ASSERT(iMediaIORequest != ENone);
OSCL_ASSERT(!iMediaIOCancelPending);
//Issue the cancel to the MIO.
iMediaIOCancelPending = true;
int32 err;
OSCL_TRY(err, iMediaIOCancelCmdId = iMediaIOControl->CancelCommand(iMediaIOCmdId););
#ifdef _TEST_AE_ERROR_HANDLING
if (iErrorCancelMioRequest)
{
err = OsclErrGeneral;
}
#endif
if (err != OsclErrNone)
{
aCmd.iEventCode = PvmfMediaInputNodeErr_MediaIOCancelCommand;
iMediaIOCancelPending = false;
return PVMFFailure;
}
LOGINFOHI((0, "PvmfMediaInputNode:SendMIORequest: Cancel Command Issued to MIO component, waiting on response..."));
return PVMFPending;//wait on request to cancel.
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNode::MioConfigured()
//called by the port when the MIO was just configured.
//only called for ports that need to wait on config before starting
//the MIO.
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PvmfMediaInputNode::MioConfigured() called"));
if (iInterfaceState == EPVMFNodeStarted)
{
PvmfMediaInputNodeCmd cmd;
cmd.PvmfMediaInputNodeCmdBase::Construct(0, PVMF_MEDIAIONODE_STARTMIO, NULL);
QueueCommandL(cmd);
}
}
////////////////////////////////////////////////////////////////////////////
// Event reporting routines.
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNode::SetState(TPVMFNodeInterfaceState s)
{
LOGINFO((0, "PvmfMediaInputNode:SetState %d", s));
PVMFNodeInterface::SetState(s);
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNode::ReportErrorEvent(PVMFEventType aEventType, OsclAny* aEventData, PVMFStatus aEventCode)
{
LOGERROR((0, "PvmfMediaInputNode:NodeErrorEvent Type %d EVData %d EVCode %d"
, aEventType, aEventData, aEventCode));
//create the extension message if any.
if (aEventCode != PvmfMediaInputNodeErr_First)
{
PVMFBasicErrorInfoMessage* eventmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (aEventCode, iEventUuid, NULL));
PVMFAsyncEvent asyncevent(PVMFErrorEvent, aEventType, NULL, OSCL_STATIC_CAST(PVInterface*, eventmsg), aEventData, NULL, 0);
PVMFNodeInterface::ReportErrorEvent(asyncevent);
eventmsg->removeRef();
}
else
PVMFNodeInterface::ReportErrorEvent(aEventType, aEventData);
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNode::ReportInfoEvent(PVMFEventType aEventType, OsclAny* aEventData, PVMFStatus aEventCode)
{
LOGINFO((0, "PvmfMediaInputNode:NodeInfoEvent Type %d EVData %d EVCode %d"
, aEventType, aEventData, aEventCode));
//create the extension message if any.
if (aEventCode != PvmfMediaInputNodeErr_First)
{
PVMFBasicErrorInfoMessage* eventmsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (aEventCode, iEventUuid, NULL));
PVMFAsyncEvent asyncevent(PVMFErrorEvent, aEventType, NULL, OSCL_STATIC_CAST(PVInterface*, eventmsg), aEventData, NULL, 0);
PVMFNodeInterface::ReportInfoEvent(asyncevent);
eventmsg->removeRef();
}
else
PVMFNodeInterface::ReportInfoEvent(aEventType, aEventData);
}
////////////////////////////////////////////////////////////////////////////
bool PvmfMediaInputNode::PortQueuesEmpty()
{
uint32 i;
for (i = 0; i < iOutPortVector.size(); i++)
{
if (iOutPortVector[i]->IncomingMsgQueueSize() > 0
|| iOutPortVector[i]->OutgoingMsgQueueSize() > 0)
{
return false;
}
}
return true;
}