blob: 06eb3327ea8e3d08257201341a228e4017bb07a7 [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_dummy_fileoutput_node.cpp
* @brief Simple dummy file output node. Does not Write incoming data to any
* file
*
*/
#include "pvmf_dummy_fileoutput_inport.h"
#include "pvmf_dummy_fileoutput_node.h"
#include "pvlogger.h"
#include "oscl_error_codes.h"
#include "pvmf_media_cmd.h"
#include "pvmf_media_msg_format_ids.h"
#include "pvmf_timedtext.h"
////////////////////////////////////////////////////////////////////////////
PVMFDummyFileOutputNode::PVMFDummyFileOutputNode(int32 aPriority)
: OsclActiveObject(aPriority, "PVMFDummyFileOutputNode")
, iCmdIdCounter(0)
, iInPort(NULL)
, iFileOpened(0)
, iFirstMediaData(false)
, iLogger(NULL)
, iFormat(PVMF_MIME_FORMAT_UNKNOWN)
, iExtensionRefCount(0)
, iMaxFileSizeEnabled(false)
, iMaxDurationEnabled(false)
, iMaxFileSize(0)
, iMaxDuration(0)
, iFileSize(0)
, iFileSizeReportEnabled(false)
, iDurationReportEnabled(false)
, iFileSizeReportFreq(0)
, iDurationReportFreq(0)
, iNextFileSizeReport(0)
, iNextDurationReport(0)
, iClock(NULL)
, iEarlyMargin(DEFAULT_EARLY_MARGIN)
, iLateMargin(DEFAULT_LATE_MARGIN)
{
ConstructL();
int32 err;
OSCL_TRY(err,
//Create the input command queue. Use a reserve to avoid lots of
//dynamic memory allocation.
iInputCommands.Construct(PVMF_FILE_OUTPUT_NODE_COMMAND_ID_START, PVMF_FILE_OUTPUT_NODE_COMMAND_VECTOR_RESERVE);
//Create the "current command" queue. It will only contain one
//command at a time, so use a reserve of 1.
iCurrentCommand.Construct(0, 1);
//Create the port vector.
iPortVector.Construct(PVMF_FILE_OUTPUT_NODE_PORT_VECTOR_RESERVE);
//Set the node capability data.
//This node can support an unlimited number of ports.
iCapability.iCanSupportMultipleInputPorts = false;
iCapability.iCanSupportMultipleOutputPorts = false;
iCapability.iHasMaxNumberOfPorts = true;
iCapability.iMaxNumberOfPorts = 1;
);
if (err != OsclErrNone)
{
//if a leave happened, cleanup and re-throw the error
iInputCommands.clear();
iCurrentCommand.clear();
iPortVector.clear();
iCapability.iInputFormatCapability.clear();
iCapability.iOutputFormatCapability.clear();
OSCL_CLEANUP_BASE_CLASS(PVMFNodeInterface);
OSCL_CLEANUP_BASE_CLASS(OsclActiveObject);
OSCL_LEAVE(err);
}
ChangeNodeState(EPVMFNodeCreated);
}
////////////////////////////////////////////////////////////////////////////
PVMFDummyFileOutputNode::~PVMFDummyFileOutputNode()
{
//thread logoff
if (IsAdded())
RemoveFromScheduler();
//Cleanup allocated interfaces
//Cleanup allocated ports
if (iInPort)
{
OSCL_DELETE(((PVMFDummyFileOutputInPort*)iInPort));
iInPort = NULL;
}
//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);
}
while (!iInputCommands.empty())
{
CommandComplete(iInputCommands, iInputCommands.front(), PVMFFailure);
}
//cleanup port activity events
iPortActivityQueue.clear();
if (iAlloc)
{
OSCL_DELETE(iAlloc);
}
}
////////////////////////////////////////////////////////////////////////////
void PVMFDummyFileOutputNode::ConstructL()
{
iAlloc = (Oscl_DefAlloc*)(new PVMFFileOutputAlloc());
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFDummyFileOutputNode::ThreadLogon()
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFDummyFileOutputNode:ThreadLogon"));
switch (iInterfaceState)
{
case EPVMFNodeCreated:
if (!IsAdded())
AddToScheduler();
iLogger = PVLogger::GetLoggerObject("PVMFDummyFileOutputNode");
SetState(EPVMFNodeIdle);
return PVMFSuccess;
// break; This break statement was removed to avoid compiler warning for Unreachable Code
default:
return PVMFErrInvalidState;
// break; This break statement was removed to avoid compiler warning for Unreachable Code
}
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFDummyFileOutputNode::ThreadLogoff()
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFDummyFileOutputNode:ThreadLogoff"));
switch (iInterfaceState)
{
case EPVMFNodeIdle:
if (IsAdded())
RemoveFromScheduler();
iLogger = NULL;
SetState(EPVMFNodeCreated);
return PVMFSuccess;
// break; This break statement was removed to avoid compiler warning for Unreachable Code
default:
return PVMFErrInvalidState;
// break; This break statement was removed to avoid compiler warning for Unreachable Code
}
}
////////////////////////////////////////////////////////////////////////////
void PVMFDummyFileOutputNode::CloseOutputFile()
{
// Close output file
if (iFileOpened)
{
iOutputFile.Close();
iFs.Close();
iFileOpened = 0;
}
}
////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFDummyFileOutputNode::Init(PVMFSessionId s, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFDummyFileOutputNode:Init"));
PVMFDummyFileOutputNodeCommand cmd;
cmd.PVMFDummyFileOutputNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_INIT, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFDummyFileOutputNode::Prepare(PVMFSessionId s, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFDummyFileOutputNode:Prepare"));
PVMFDummyFileOutputNodeCommand cmd;
cmd.PVMFDummyFileOutputNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_PREPARE, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFDummyFileOutputNode::GetCapability(PVMFNodeCapability& aNodeCapability)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFDummyFileOutputNode:GetCapability"));
iCapability.iInputFormatCapability.clear();
if (iFormat != PVMF_MIME_FORMAT_UNKNOWN)
{
// Format is already set, so return only that one
iCapability.iInputFormatCapability.push_back(iFormat);
}
else
{
iCapability.iInputFormatCapability.push_back(PVMF_MIME_AMR_IETF);
iCapability.iInputFormatCapability.push_back(PVMF_MIME_M4V);
iCapability.iInputFormatCapability.push_back(PVMF_MIME_PCM8);
iCapability.iInputFormatCapability.push_back(PVMF_MIME_PCM16);
iCapability.iInputFormatCapability.push_back(PVMF_MIME_YUV420);
iCapability.iInputFormatCapability.push_back(PVMF_MIME_ADTS);
iCapability.iInputFormatCapability.push_back(PVMF_MIME_H2632000);
iCapability.iInputFormatCapability.push_back(PVMF_MIME_PCM);
iCapability.iInputFormatCapability.push_back(PVMF_MIME_3GPP_TIMEDTEXT);
}
aNodeCapability = iCapability;
return PVMFSuccess;
}
////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFDummyFileOutputNode::QueryUUID(PVMFSessionId s, const PvmfMimeString& aMimeType,
Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids,
bool aExactUuidsOnly,
const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFDummyFileOutputNode:QueryUUID"));
PVMFDummyFileOutputNodeCommand cmd;
cmd.PVMFDummyFileOutputNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_QUERYUUID, aMimeType, aUuids, aExactUuidsOnly, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFDummyFileOutputNode::QueryInterface(PVMFSessionId s, const PVUuid& aUuid,
PVInterface*& aInterfacePtr,
const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFDummyFileOutputNode:QueryInterface"));
PVMFDummyFileOutputNodeCommand cmd;
cmd.PVMFDummyFileOutputNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_QUERYINTERFACE, aUuid, aInterfacePtr, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFDummyFileOutputNode::RequestPort(PVMFSessionId s, int32 aPortTag, const PvmfMimeString* aPortConfig, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFDummyFileOutputNode:RequestPort"));
PVMFDummyFileOutputNodeCommand cmd;
cmd.PVMFDummyFileOutputNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_REQUESTPORT, aPortTag, aPortConfig, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFDummyFileOutputNode::ReleasePort(PVMFSessionId s, PVMFPortInterface& aPort, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFDummyFileOutputNode:ReleasePort"));
PVMFDummyFileOutputNodeCommand cmd;
cmd.PVMFDummyFileOutputNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_RELEASEPORT, aPort, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
PVMFPortIter* PVMFDummyFileOutputNode::GetPorts(const PVMFPortFilter* aFilter)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFDummyFileOutputNode:GetPorts"));
OSCL_UNUSED_ARG(aFilter);//port filter is not implemented.
iPortVector.Reset();
return &iPortVector;
}
////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFDummyFileOutputNode::Start(PVMFSessionId s, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFDummyFileOutputNode:Start"));
PVMFDummyFileOutputNodeCommand cmd;
cmd.PVMFDummyFileOutputNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_START, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFDummyFileOutputNode::Stop(PVMFSessionId s, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFDummyFileOutputNode:Stop"));
PVMFDummyFileOutputNodeCommand cmd;
cmd.PVMFDummyFileOutputNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_STOP, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
/**
//Queue an asynchronous node command
*/
PVMFCommandId PVMFDummyFileOutputNode::Flush(PVMFSessionId s, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFDummyFileOutputNode:Flush"));
PVMFDummyFileOutputNodeCommand cmd;
cmd.PVMFDummyFileOutputNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_FLUSH, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFDummyFileOutputNode::Pause(PVMFSessionId s, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFDummyFileOutputNode:Pause"));
PVMFDummyFileOutputNodeCommand cmd;
cmd.PVMFDummyFileOutputNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_PAUSE, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFDummyFileOutputNode::Reset(PVMFSessionId s, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFDummyFileOutputNode:Reset"));
PVMFDummyFileOutputNodeCommand cmd;
cmd.PVMFDummyFileOutputNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_RESET, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFDummyFileOutputNode::CancelAllCommands(PVMFSessionId s, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFDummyFileOutputNode:CancelAllCommands"));
PVMFDummyFileOutputNodeCommand cmd;
cmd.PVMFDummyFileOutputNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_CANCELALLCOMMANDS, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFDummyFileOutputNode::CancelCommand(PVMFSessionId s, PVMFCommandId aCmdId, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFDummyFileOutputNode:CancelCommand"));
PVMFDummyFileOutputNodeCommand cmd;
cmd.PVMFDummyFileOutputNodeCommandBase::Construct(s, PVMF_GENERIC_NODE_CANCELCOMMAND, aCmdId, aContext);
return QueueCommandL(cmd);
}
////////////////////////////////////////////////////////////////////////////
void PVMFDummyFileOutputNode::addRef()
{
++iExtensionRefCount;
}
////////////////////////////////////////////////////////////////////////////
void PVMFDummyFileOutputNode::removeRef()
{
if (iExtensionRefCount > 0)
--iExtensionRefCount;
}
////////////////////////////////////////////////////////////////////////////
bool PVMFDummyFileOutputNode::queryInterface(const PVUuid& uuid, PVInterface*& iface)
{
if (uuid == PVMFDummyFileOutputNodeConfigUuid)
{
PVMFDummyFileOutputNodeConfigInterface* myInterface = OSCL_STATIC_CAST(PVMFDummyFileOutputNodeConfigInterface*, this);
iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
++iExtensionRefCount;
}
else if (uuid == PvmfComposerSizeAndDurationUuid)
{
PvmfComposerSizeAndDurationInterface* myInterface = OSCL_STATIC_CAST(PvmfComposerSizeAndDurationInterface*, this);
iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
++iExtensionRefCount;
}
else 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;
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFDummyFileOutputNode::SetMaxDuration(bool aEnable, uint32 aMaxDurationMilliseconds)
{
iMaxDurationEnabled = aEnable;
if (iMaxDurationEnabled)
{
iMaxDuration = aMaxDurationMilliseconds;
}
else
{
iMaxDuration = 0;
}
return PVMFSuccess;
}
////////////////////////////////////////////////////////////////////////////
void PVMFDummyFileOutputNode::GetMaxDurationConfig(bool& aEnable, uint32& aMaxDurationMilliseconds)
{
aEnable = iMaxDurationEnabled;
aMaxDurationMilliseconds = iMaxDuration;
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFDummyFileOutputNode::SetDurationProgressReport(bool aEnable, uint32 aReportFrequency)
{
iDurationReportEnabled = aEnable;
if (iDurationReportEnabled)
{
iDurationReportFreq = aReportFrequency;
}
return PVMFSuccess;
}
////////////////////////////////////////////////////////////////////////////
void PVMFDummyFileOutputNode::GetDurationProgressReportConfig(bool& aEnable, uint32& aReportFrequency)
{
aEnable = iDurationReportEnabled;
aReportFrequency = iDurationReportFreq;
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFDummyFileOutputNode::SetClock(PVMFMediaClock* aClock)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFDummyFileOutputNode::SetClock: aClock=0x%x", aClock));
iClock = aClock;
if (iInPort)
{
return ((PVMFDummyFileOutputInPort*)iInPort)->SetClock(aClock);
}
return PVMFSuccess;
}
///////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFDummyFileOutputNode::ChangeClockRate(int32 aRate)
{
OSCL_UNUSED_ARG(aRate);
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFDummyFileOutputNode::ChangeClockRate: aRate=%d", aRate));
return PVMFSuccess;
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFDummyFileOutputNode::SetMargins(int32 aEarlyMargin, int32 aLateMargin)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFDummyFileOutputNode::SetMargins: aEarlyMargin=%d, aLateMargin=%d", aEarlyMargin, aLateMargin));
iEarlyMargin = aEarlyMargin;
iLateMargin = aLateMargin;
if (iInPort)
{
return ((PVMFDummyFileOutputInPort*)iInPort)->SetMargins(aEarlyMargin, aLateMargin);
}
return PVMFSuccess;
}
////////////////////////////////////////////////////////////////////////////
void PVMFDummyFileOutputNode::ClockStarted(void)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFDummyFileOutputNode::ClockStarted"));
if (iInPort)
{
((PVMFDummyFileOutputInPort*)iInPort)->Start();
}
}
////////////////////////////////////////////////////////////////////////////
void PVMFDummyFileOutputNode::ClockStopped(void)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFDummyFileOutputNode::ClockStopped"));
if (iInPort)
{
((PVMFDummyFileOutputInPort*)iInPort)->Pause();
}
}
////////////////////////////////////////////////////////////////////////////
PVMFCommandId PVMFDummyFileOutputNode::SkipMediaData(PVMFSessionId aSessionId,
PVMFTimestamp aResumeTimestamp,
uint32 aStreamID,
bool aPlayBackPositionContinuous,
OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFDummyFileOutputNode::SkipMediaData: aResumeTimestamp=%d, aContext=0x%x",
aResumeTimestamp, aContext));
if (!iInPort)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
(0, "PVMFDummyFileOutputNode::SkipMediaData: Error - Input port has not been created"));
OSCL_LEAVE(OsclErrNotReady);
return 0;
}
switch (iInterfaceState)
{
case EPVMFNodeStarted:
case EPVMFNodeInitialized:
case EPVMFNodePaused:
return ((PVMFDummyFileOutputInPort*)iInPort)->SkipMediaData(aSessionId, aResumeTimestamp, aStreamID, aPlayBackPositionContinuous, aContext);
default:
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
(0, "PVMFDummyFileOutputNode::SkipMediaData: Error - Wrong state"));
OSCL_LEAVE(OsclErrInvalidState);
return 0;
}
}
////////////////////////////////////////////////////////////////////////////
void PVMFDummyFileOutputNode::Run()
{
if (!iInputCommands.empty())
{
if (ProcessCommand(iInputCommands.front()))
{
//note: need to check the state before re-scheduling
//since the node could have been reset in the ProcessCommand
//call.
if (iInterfaceState != EPVMFNodeCreated)
RunIfNotReady();
return;
}
}
// Process port activity
if (!iPortActivityQueue.empty()
&& (iInterfaceState == EPVMFNodeStarted || FlushPending()))
{
// If the port activity cannot be processed because a port is
// busy, discard the activity and continue to process the next
// activity in queue until getting to one that can be processed.
while (!iPortActivityQueue.empty())
{
if (ProcessPortActivity())
break; //processed a port
}
//Re-schedule
RunIfNotReady();
return;
}
//If we get here we did not process any ports or commands.
//Check for completion of a flush command...
if (FlushPending()
&& iPortActivityQueue.empty())
{
SetState(EPVMFNodePrepared);
iInPort->ResumeInput();
CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
RunIfNotReady();
}
}
void PVMFDummyFileOutputNode::HandlePortActivity(const PVMFPortActivity &aActivity)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "0x%x PVMFDummyFileOutputNode::PortActivity: port=0x%x, type=%d",
this, aActivity.iPort, aActivity.iType));
switch (aActivity.iType)
{
case PVMF_PORT_ACTIVITY_OUTGOING_MSG:
//An outgoing message was queued on this port.
//We only need to queue a port activity event on the
//first message. Additional events will be queued during
//the port processing as needed.
if (aActivity.iPort->OutgoingMsgQueueSize() == 1)
QueuePortActivity(aActivity);
break;
case PVMF_PORT_ACTIVITY_INCOMING_MSG:
if (aActivity.iPort->IncomingMsgQueueSize() == 1)
QueuePortActivity(aActivity);
break;
case PVMF_PORT_ACTIVITY_DELETED:
//Report port deleted info event to the node.
ReportInfoEvent(PVMFInfoPortDeleted
, (OsclAny*)aActivity.iPort);
//Purge any port activity events already queued
//for this port.
{
for (uint32 i = 0; i < iPortActivityQueue.size();)
{
if (iPortActivityQueue[i].iPort == aActivity.iPort)
iPortActivityQueue.erase(&iPortActivityQueue[i]);
else
i++;
}
}
break;
case PVMF_PORT_ACTIVITY_CONNECT:
//nothing needed.
break;
case PVMF_PORT_ACTIVITY_DISCONNECT:
//nothing needed.
break;
default:
break;
}
}
/////////////////////////////////////////////////////
// Port Processing routines
/////////////////////////////////////////////////////
void PVMFDummyFileOutputNode::QueuePortActivity(const PVMFPortActivity &aActivity)
{
//queue a new port activity event
int32 err;
OSCL_TRY(err, iPortActivityQueue.push_back(aActivity););
if (err != OsclErrNone)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
(0, "0x%x PVMFDummyFileOutputNode::PortActivity: Error - iPortActivityQueue.push_back() failed", this));
ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aActivity.iPort));
}
else
{
//wake up the AO to process the port activity event.
RunIfNotReady();
}
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFDummyFileOutputNode::ProcessIncomingData(PVMFSharedMediaDataPtr aMediaData)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFDummyFileOutputNode::ProcessIncomingData()"));
PVMFStatus status = PVMFSuccess;
OsclRefCounterMemFrag frag;
uint32 numFrags = aMediaData->getNumFragments();
OsclRefCounterMemFrag formatSpecificInfo;
aMediaData->getFormatSpecificInfo(formatSpecificInfo);
for (uint32 i = 0; (i < numFrags) && status == PVMFSuccess; i++)
{
aMediaData->getMediaFragment(i, frag);
switch (iInterfaceState)
{
case EPVMFNodeStarted:
break;
case EPVMFNodeInitialized:
// Already stopped. Ignore incoming data.
break;
default:
// Wrong state
PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR,
(0, "PVMFDummyFileOutputNode::ProcessIncomingData: Error - Wrong state"));
status = PVMFFailure;
break;
}
}
return status;
}
//////////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFDummyFileOutputNode::SendDurationProgress(uint32 aTimestamp)
{
if (iDurationReportEnabled &&
aTimestamp >= iNextDurationReport)
{
iNextDurationReport = aTimestamp - (aTimestamp % iDurationReportFreq) + iDurationReportFreq;
ReportInfoEvent(PVMF_COMPOSER_DURATION_PROGRESS, (OsclAny*)aTimestamp);
}
return PVMFSuccess;
}
//////////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFDummyFileOutputNode::SendFileSizeProgress()
{
if (iFileSizeReportEnabled &&
iFileSize >= iNextFileSizeReport)
{
iNextFileSizeReport = iFileSize - (iFileSize % iFileSizeReportFreq) + iFileSizeReportFreq;
ReportInfoEvent(PVMF_COMPOSER_FILESIZE_PROGRESS, (OsclAny*)iFileSize);
}
return PVMFSuccess;
}
//////////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFDummyFileOutputNode::CheckMaxFileSize(uint32 aFrameSize)
{
if (iMaxFileSizeEnabled)
{
if ((iFileSize + aFrameSize) >= iMaxFileSize)
{
// Change state to initialized
ChangeNodeState(EPVMFNodeInitialized);
// Clear all pending port activity
ClearPendingPortActivity();
// Report max file size event
ReportInfoEvent(PVMF_COMPOSER_MAXFILESIZE_REACHED, NULL);
return PVMFSuccess;
}
return PVMFPending;
}
return PVMFErrNotSupported;
}
//////////////////////////////////////////////////////////////////////////////////
PVMFStatus PVMFDummyFileOutputNode::CheckMaxDuration(uint32 aTimestamp)
{
if (iMaxDurationEnabled)
{
if (aTimestamp >= iMaxDuration)
{
// Change state to initialized
ChangeNodeState(EPVMFNodeInitialized);
// Clear all pending port activity
ClearPendingPortActivity();
// Report max duration event
ReportInfoEvent(PVMF_COMPOSER_MAXDURATION_REACHED, NULL);
return PVMFSuccess;
}
return PVMFPending;
}
return PVMFErrNotSupported;
}
//////////////////////////////////////////////////////////////////////////////////
void PVMFDummyFileOutputNode::ClearPendingPortActivity()
{
// index starts at 1 because the current command (i.e. iCmdQueue[0]) will be
// erased inside Run
while (!iInputCommands.empty())
{
CommandComplete(iInputCommands, iInputCommands.front(), PVMFFailure);
}
}
void PVMFDummyFileOutputNode::ChangeNodeState(TPVMFNodeInterfaceState aNewState)
{
iInterfaceState = aNewState;
}
//////////////////////////////////////////////////////////////////////////////////////////
void PVMFDummyFileOutputNode::CommandComplete(PVMFDummyFileOutputNodeCmdQ& aCmdQ, PVMFDummyFileOutputNodeCommand& aCmd, PVMFStatus aStatus, OsclAny* aEventData)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFDummyFileOutputNode:CommandComplete Id %d Cmd %d Status %d Context %d Data %d"
, aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));
//create response
PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, aEventData);
PVMFSessionId session = aCmd.iSession;
//Erase the command from the queue.
aCmdQ.Erase(&aCmd);
//Report completion to the session observer.
ReportCmdCompleteEvent(session, resp);
}
PVMFCommandId PVMFDummyFileOutputNode::QueueCommandL(PVMFDummyFileOutputNodeCommand& aCmd)
{
PVMFCommandId id;
id = iInputCommands.AddL(aCmd);
//wakeup the AO
RunIfNotReady();
return id;
}
/////////////////////////////////////////////////////
bool PVMFDummyFileOutputNode::ProcessPortActivity()
{//called by the AO to process a port activity message
//Pop the queue...
PVMFPortActivity activity(iPortActivityQueue.front());
iPortActivityQueue.erase(&iPortActivityQueue.front());
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "0x%x PVMFDummyFileOutputNode::ProcessPortActivity: port=0x%x, type=%d",
this, activity.iPort, activity.iType));
int32 err = OsclErrNone;
PVMFStatus status = PVMFSuccess;
switch (activity.iType)
{
case PVMF_PORT_ACTIVITY_INCOMING_MSG:
status = ProcessIncomingMsg(activity.iPort);
//if there is still data, queue another port activity event.
//tbd-- do we need to do this even if port is busy?
if (activity.iPort->IncomingMsgQueueSize() > 0)
{
OSCL_TRY(err, iPortActivityQueue.push_back(activity););
}
break;
case PVMF_PORT_ACTIVITY_OUTGOING_MSG:
default:
return false;
// break; This statement was removed to avoid compiler warning for Unreachable Code
}
return true;
}
/////////////////////////////////////////////////////
PVMFStatus PVMFDummyFileOutputNode::ProcessIncomingMsg(PVMFPortInterface* aPort)
{
//Called by the AO to process one buffer off the port's
//incoming data queue. This routine will dequeue and
//dispatch the data.
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "0x%x PVMFDummyFileOutputNode::ProcessIncomingMsg: aPort=0x%x", this, aPort));
if (aPort->GetPortTag() != PVMF_DUMMY_FILE_OUTPUT_NODE_PORT_TYPE_SINK)
{
return PVMFFailure;
}
PVMFSharedMediaMsgPtr msg;
PVMFStatus status = aPort->DequeueIncomingMsg(msg);
if (status != PVMFSuccess)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
(0, "0x%x PVMFDummyFileOutputNode::ProcessIncomingMsg: Error - DequeueIncomingMsg failed", this));
return status;
}
/*
INFORMATION!!!
The FileOutputNode is generally used by the engine unit tests as SinkNode
For now, most of the unit tests have OBSOLETED the use of FileOutputNode,
But still some of the tests are using the FileOutputNode in place of,
MIO (RefFileOutput).
Since the usage FileOutputNode is not defined yet, we are adding support for
BOS Message as a NO-OP so that the node should be able to handle Any and all
the BOS Messages gracefully.
IMPORTANT!!!,
For Complete support of BOS in the FileOutputNode, we need to make more changes.
Those changes will be done only once the life scope of FileOutputNode is defined.
*/
if (msg->getFormatID() == PVMF_MEDIA_CMD_BOS_FORMAT_ID)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVFileOutputNode::ProcessIncomingMsg BOS Recieved"));
return PVMFSuccess;
}
// Transfer to the port's sync queue to do synchronization
// This is temporary until data is directly saved to the sync queue
uint32 dropped;
uint32 skipped;
status = ((PVMFDummyFileOutputInPort*)aPort)->iDataQueue.QueueMediaData(msg, &dropped, &skipped);
if (dropped > 0)
{
PVMFNodeInterface::ReportInfoEvent(PVMFInfoDataDiscarded);
}
if (status == PVMFErrNoMemory)
{
return PVMFFailure;
}
else
{
return PVMFSuccess;
}
}
bool PVMFDummyFileOutputNode::ProcessCommand(PVMFDummyFileOutputNodeCommand& aCmd)
{
//normally this node will not start processing one command
//until the prior one is finished. However, a hi priority
//command such as Cancel must be able to interrupt a command
//in progress.
if (!iCurrentCommand.empty() && !aCmd.hipri())
return false;
switch (aCmd.iCmd)
{
case PVMF_GENERIC_NODE_QUERYUUID:
DoQueryUuid(aCmd);
break;
case PVMF_GENERIC_NODE_QUERYINTERFACE:
DoQueryInterface(aCmd);
break;
case PVMF_GENERIC_NODE_REQUESTPORT:
DoRequestPort(aCmd);
break;
case PVMF_GENERIC_NODE_RELEASEPORT:
DoReleasePort(aCmd);
break;
case PVMF_GENERIC_NODE_INIT:
DoInit(aCmd);
break;
case PVMF_GENERIC_NODE_PREPARE:
DoPrepare(aCmd);
break;
case PVMF_GENERIC_NODE_START:
DoStart(aCmd);
break;
case PVMF_GENERIC_NODE_STOP:
DoStop(aCmd);
break;
case PVMF_GENERIC_NODE_FLUSH:
DoFlush(aCmd);
break;
case PVMF_GENERIC_NODE_PAUSE:
DoPause(aCmd);
break;
case PVMF_GENERIC_NODE_RESET:
DoReset(aCmd);
break;
case PVMF_GENERIC_NODE_CANCELALLCOMMANDS:
DoCancelAllCommands(aCmd);
break;
case PVMF_GENERIC_NODE_CANCELCOMMAND:
DoCancelCommand(aCmd);
break;
default://unknown command type
CommandComplete(iInputCommands, aCmd, PVMFFailure);
break;
}
return true;
}
/**
//A routine to tell if a flush operation is in progress.
*/
bool PVMFDummyFileOutputNode::FlushPending()
{
return (iCurrentCommand.size() > 0
&& iCurrentCommand.front().iCmd == PVMF_GENERIC_NODE_FLUSH);
}
void PVMFDummyFileOutputNode::DoQueryUuid(PVMFDummyFileOutputNodeCommand& aCmd)
{
//This node supports Query UUID from any state
OSCL_String* mimetype;
Oscl_Vector<PVUuid, OsclMemAllocator> *uuidvec;
bool exactmatch;
aCmd.PVMFDummyFileOutputNodeCommandBase::Parse(mimetype, uuidvec, exactmatch);
//Try to match the input mimetype against any of
//the custom interfaces for this node
//Match against custom interface1...
if (*mimetype == PVMF_FILE_OUTPUT_NODE_CUSTOM1_MIMETYPE
//also match against base mimetypes for custom interface1,
//unless exactmatch is set.
|| (!exactmatch && *mimetype == PVMF_FILE_OUTPUT_NODE_MIMETYPE)
|| (!exactmatch && *mimetype == PVMF_BASEMIMETYPE))
{
//PVUuid uuid(PVMF_SOCKET_NODE_CUSTOM1_UUID);
uuidvec->push_back(PVMFDummyFileOutputNodeConfigUuid);
uuidvec->push_back(PvmfComposerSizeAndDurationUuid);
uuidvec->push_back(PvmfNodesSyncControlUuid);
}
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
}
void PVMFDummyFileOutputNode::DoQueryInterface(PVMFDummyFileOutputNodeCommand& aCmd)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFDummyFileOutputNode::DoQueryInterface"));
PVUuid* uuid;
PVInterface** ptr;
aCmd.PVMFDummyFileOutputNodeCommandBase::Parse(uuid, ptr);
if (queryInterface(*uuid, *ptr))
{
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
}
else
{
CommandComplete(iInputCommands, aCmd, PVMFFailure);
}
}
void PVMFDummyFileOutputNode::DoInit(PVMFDummyFileOutputNodeCommand& aCmd)
{
PVMFStatus iRet = PVMFSuccess;
switch (iInterfaceState)
{
case EPVMFNodeIdle:
//this node doesn't need to do anything to get ready
//to start.
SetState(EPVMFNodeInitialized);
break;
case EPVMFNodeInitialized:
break;
default:
iRet = PVMFErrInvalidState;
break;
}
CommandComplete(iInputCommands, aCmd, iRet);
}
/**
//Called by the command handler AO to do the node Prepare
*/
void PVMFDummyFileOutputNode::DoPrepare(PVMFDummyFileOutputNodeCommand& aCmd)
{
PVMFStatus iRet = PVMFSuccess;
switch (iInterfaceState)
{
case EPVMFNodeInitialized:
//this node doesn't need to do anything to get ready
//to start.
SetState(EPVMFNodePrepared);
break;
case EPVMFNodePrepared:
break;
default:
iRet = PVMFErrInvalidState;
break;
}
CommandComplete(iInputCommands, aCmd, iRet);
}
void PVMFDummyFileOutputNode::DoStart(PVMFDummyFileOutputNodeCommand& aCmd)
{
PVMFStatus status = PVMFSuccess;
switch (iInterfaceState)
{
case EPVMFNodePrepared:
case EPVMFNodePaused:
{
if (!iClock)
{
// If not using sync clock, start processing incoming data
((PVMFDummyFileOutputInPort*)iInPort)->Start();
}
if (!iFileOpened)
{
if (iFs.Connect() != 0)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
(0, "PVMFDummyFileOutputNode::DoStart: iFs.Connect Error."));
status = PVMFErrNoResources;
break;
}
if (0 != iOutputFile.Open(iOutputFileName.get_cstr(), Oscl_File::MODE_READWRITE | Oscl_File::MODE_BINARY, iFs))
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
(0, "PVMFDummyFileOutputNode::DoStart: iOutputFile.Open Error."));
status = PVMFErrNoResources;
break;
}
iFileOpened = 1;
iFirstMediaData = true;
}
SetState(EPVMFNodeStarted);
break;
}
case EPVMFNodeStarted:
status = PVMFSuccess;
break;
default:
status = PVMFErrInvalidState;
break;
}
CommandComplete(iInputCommands, aCmd, status);
}
void PVMFDummyFileOutputNode::DoStop(PVMFDummyFileOutputNodeCommand& aCmd)
{
switch (iInterfaceState)
{
case EPVMFNodeStarted:
case EPVMFNodePaused:
// Stop data source
if (iInPort)
{
((PVMFDummyFileOutputInPort*)iInPort)->Stop();
CloseOutputFile();
}
// Clear queued messages in ports
uint32 i;
for (i = 0; i < iPortVector.size(); i++)
iPortVector[i]->ClearMsgQueues();
// Clear scheduled port activities
iPortActivityQueue.clear();
//transition to Initialized state
SetState(EPVMFNodePrepared);
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
break;
case EPVMFNodePrepared:
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
break;
default:
CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
break;
}
}
void PVMFDummyFileOutputNode::DoFlush(PVMFDummyFileOutputNodeCommand& aCmd)
{
switch (iInterfaceState)
{
case EPVMFNodeStarted:
case EPVMFNodePaused:
//the flush is asynchronous. move the command from
//the input command queue to the current command, where
//it will remain until the flush completes.
int32 err;
OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
if (err != OsclErrNone)
{
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
iInputCommands.Erase(&aCmd);
//Notify all ports to suspend their input
{
for (uint32 i = 0; i < iPortVector.size(); i++)
iPortVector[i]->SuspendInput();
}
// Stop data source
break;
default:
CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
break;
}
}
void PVMFDummyFileOutputNode::DoPause(PVMFDummyFileOutputNodeCommand& aCmd)
{
switch (iInterfaceState)
{
case EPVMFNodeStarted:
{
// Pause data source
if (!iClock)
{
// If not using sync clock, pause processing of incoming data
((PVMFDummyFileOutputInPort*)iInPort)->Pause();
}
SetState(EPVMFNodePaused);
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
break;
}
case EPVMFNodePaused:
{
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
}
break;
default:
CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
break;
}
}
void PVMFDummyFileOutputNode::DoReset(PVMFDummyFileOutputNodeCommand& aCmd)
{
if (IsAdded())
{
if (iInPort)
{
OSCL_DELETE(((PVMFDummyFileOutputInPort*)iInPort));
iInPort = NULL;
}
//logoff & go back to Created state.
SetState(EPVMFNodeIdle);
ThreadLogoff();
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
}
else
{
OSCL_LEAVE(OsclErrInvalidState);
}
}
void PVMFDummyFileOutputNode::DoRequestPort(PVMFDummyFileOutputNodeCommand& aCmd)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFDummyFileOutputNode::DoRequestPort"));
//This node supports port request from any state
//retrieve port tag.
int32 tag;
OSCL_String* portconfig;
aCmd.PVMFDummyFileOutputNodeCommandBase::Parse(tag, portconfig);
//validate the tag...
switch (tag)
{
case PVMF_DUMMY_FILE_OUTPUT_NODE_PORT_TYPE_SINK:
break;
default:
//bad port tag
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
(0, "PVMFDummyFileOutputNode::DoRequestPort: Error - Invalid port tag"));
CommandComplete(iInputCommands, aCmd, PVMFFailure);
return;
}
if (iInPort)
{
// it's been taken for now, so reject this request
CommandComplete(iInputCommands, aCmd, PVMFFailure);
return;
}
// Create and configure output port
int32 err;
PVMFFormatType fmt = PVMF_MIME_FORMAT_UNKNOWN;
if (portconfig)
{
fmt = portconfig->get_str();
}
if (iFormat != PVMF_MIME_FORMAT_UNKNOWN &&
iFormat != fmt)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR,
(0, "PVMFDummyFileOutputNode::DoRequestPort: Error - Format not supported (format was preset)"));
CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
return;
}
OSCL_TRY(err, iInPort = OSCL_NEW(PVMFDummyFileOutputInPort, (tag, this)););
if (err != OsclErrNone || !iInPort)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR,
(0, "PVMFDummyFileOutputNode::DoRequestPort: Error - PVMFDummyFileOutputInPort::Create() failed"));
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
((PVMFDummyFileOutputInPort*)iInPort)->SetClock(iClock);
((PVMFDummyFileOutputInPort*)iInPort)->SetMargins(iEarlyMargin, iLateMargin);
//if format was provided in mimestring, set it now.
if (portconfig)
{
PVMFFormatType fmt = portconfig->get_str();
if (fmt != PVMF_MIME_FORMAT_UNKNOWN
&& ((PVMFDummyFileOutputInPort*)iInPort)->IsFormatSupported(fmt))
{
((PVMFDummyFileOutputInPort*)iInPort)->iFormat = fmt;
((PVMFDummyFileOutputInPort*)iInPort)->FormatUpdated();
}
}
//Return the port pointer to the caller.
CommandComplete(iInputCommands, aCmd, PVMFSuccess, (OsclAny*)iInPort);
}
void PVMFDummyFileOutputNode::DoReleasePort(PVMFDummyFileOutputNodeCommand& aCmd)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFDummyFileOutputNode::DoReleasePort"));
if (iInPort)
{
OSCL_DELETE(((PVMFDummyFileOutputInPort*)iInPort));
iInPort = NULL;
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
return;
}
CommandComplete(iInputCommands, aCmd, PVMFFailure);
}
void PVMFDummyFileOutputNode::DoCancelAllCommands(PVMFDummyFileOutputNodeCommand& aCmd)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFDummyFileOutputNode::DoCancelAllCommands"));
//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.
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
}
void PVMFDummyFileOutputNode::DoCancelCommand(PVMFDummyFileOutputNodeCommand& aCmd)
{
//extract the command ID from the parameters.
PVMFCommandId id;
aCmd.PVMFDummyFileOutputNodeCommandBase::Parse(id);
//first check "current" command if any
{
PVMFDummyFileOutputNodeCommand* cmd = iCurrentCommand.FindById(id);
if (cmd)
{
//cancel the queued command
CommandComplete(iCurrentCommand, *cmd, PVMFErrCancelled);
//report cancel success
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
return;
}
}
//next check input queue.
{
//start at element 1 since this cancel command is element 0.
PVMFDummyFileOutputNodeCommand* cmd = iInputCommands.FindById(id, 1);
if (cmd)
{
//cancel the queued command
CommandComplete(iInputCommands, *cmd, PVMFErrCancelled);
//report cancel success
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
return;
}
}
//if we get here the command isn't queued so the cancel fails.
CommandComplete(iInputCommands, aCmd, PVMFFailure);
}