void PVMFBufferDataSource::HandlePortActivity(const PVMFPortActivity &aActivity)
{
    if (aActivity.iType != PVMF_PORT_ACTIVITY_OUTGOING_MSG)
        return;
    PVMFSharedMediaMsgPtr aMsg;
    while (OutgoingMsgQueueSize())
    {
        Send();
    }
}
void PVMFLoopbackIOPort::Run()
{
    //data should move through the ports only
    //when the node is active or flushing
    if (iNode->GetState() != EPVMFNodeStarted
            && !iNode->FlushPending())
        return;

    //Process incoming messages
    if (!iWaiting
            && IncomingMsgQueueSize() > 0)
    {
        //dispatch the incoming data.
        if (ProcessIncomingMsg() != PVMFSuccess)
            iNode->ReportErrorEvent(PVMF_NODE_ERROR_EVENT_LAST, (OsclAny*)this);

        //re-schedule if more data
        if (!iWaiting
                && IncomingMsgQueueSize() > 0)
        {
            RunIfNotReady();
        }
    }

    //Process outgoing messages
    if (OutgoingMsgQueueSize() > 0
            && !IsConnectedPortBusy())
    {
        //Send data to connected port
        PVMFStatus status = Send();
        if (status != PVMFSuccess)
            iNode->ReportErrorEvent(PVMF_NODE_ERROR_EVENT_LAST, (OsclAny*)this);

        //Reschedule if there's more data to process...
        if (OutgoingMsgQueueSize() > 0
                && !IsConnectedPortBusy())
        {
            RunIfNotReady();
        }
    }
}
////////////////////////////////////////////////////////////////////////////
//           Pure virtuals from OsclActiveObject
////////////////////////////////////////////////////////////////////////////
void PVMFAvcEncPort::Run()
{
    LOG_STACK_TRACE((0, "PVMFAvcEncPort::Run"));
    PVMFStatus status = PVMFSuccess;

    // Process incoming messages
    if (iTag == PVMF_AVCENC_NODE_PORT_TYPE_INPUT)
    {
        if (IncomingMsgQueueSize() > 0)
        {
            //dispatch the incoming data.
            if (iNode->IsProcessIncomingMsgReady())
            {
                status = iNode->ProcessIncomingMsg(this);
                if (status != PVMFSuccess)
                {
                    LOG_ERR((0, "PVMFAvcEncPort::Run: Error - ProcessIncomingMsg failed. status=%d", status));
                }
            }

        }


        if (iNode->IsFlushPending())
        {
            if (IncomingMsgQueueSize() == 0 && OutgoingMsgQueueSize() == 0)
            {
                iNode->FlushComplete();
            }
            else
            {
                RunIfNotReady();
            }
        }
    }

    //Process outgoing messages
    if (iTag == PVMF_AVCENC_NODE_PORT_TYPE_OUTPUT)
    {
        if (OutgoingMsgQueueSize() > 0)
        {
            if (iNode->IsProcessOutgoingMsgReady())
            {
                //Send data to connected port
                status = Send();
                switch (status)
                {
                    case PVMFSuccess:
                        // Reschedule if there's more data to process and connected port did not become busy
                        // after receiving the last msg
                        if (OutgoingMsgQueueSize() > 0 && iNode->IsProcessOutgoingMsgReady())
                        {
                            RunIfNotReady();
                        }
                        break;

                    case PVMFErrBusy:
                        // Connected port busy. Don't schedule next data
                        break;

                    default:
                        LOG_ERR((0, "PVMFAvcEncPort::Run: Error - Send() failed. status=%d", status));
                        iNode->ReportErrorEvent(PVMF_AVCENC_NODE_ERROR_ENCODE_ERROR, (OsclAny*)this);
                        break;
                }

                if (iNode->IsFlushPending())
                {
                    if (IncomingMsgQueueSize() == 0 && OutgoingMsgQueueSize() == 0)
                        iNode->FlushComplete();
                }
            }
        }

        if (iNode->IsFlushPending())
        {
            if (IncomingMsgQueueSize() == 0 && OutgoingMsgQueueSize() == 0)
                iNode->FlushComplete();
        }
    }
}
////////////////////////////////////////////////////////////////////////////
//           Pure virtuals from PVMFPortActivityHandler
////////////////////////////////////////////////////////////////////////////
void PVMFAvcEncPort::HandlePortActivity(const PVMFPortActivity& aActivity)
{
    LOG_STACK_TRACE((0, "PVMFAvcEncPort::HandlePortActivity: type=%d", aActivity.iType));

    if (aActivity.iPort != this)
    {
        LOG_ERR((0, "PVMFAvcEncPort::HandlePortActivity: Error - Activity is not on this port"));
        return;
    }

    switch (aActivity.iType)
    {
        case PVMF_PORT_ACTIVITY_CREATED:
            //Report port created info event to the node.
            iNode->ReportInfoEvent(PVMFInfoPortCreated,
                                   (OsclAny*)aActivity.iPort);
            break;

        case PVMF_PORT_ACTIVITY_DELETED:
            //Report port deleted info event to the node.
            iNode->ReportInfoEvent(PVMFInfoPortDeleted,
                                   (OsclAny*)aActivity.iPort);
            break;

        case PVMF_PORT_ACTIVITY_OUTGOING_MSG:
            // Wakeup the AO on the first message only. After that it re-schedules itself as needed.
            if (OutgoingMsgQueueSize() == 1 &&
                    !IsConnectedPortBusy())
            {
                RunIfNotReady();
            }
            break;

        case PVMF_PORT_ACTIVITY_INCOMING_MSG:
            //Wakeup the AO on the first message only. After that it re-schedules itself as needed.
            if (IncomingMsgQueueSize() == 1 &&
                    iNode->IsProcessIncomingMsgReady())
            {
                RunIfNotReady();
            }
            break;

        case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_BUSY:
            // This is handled in the input port side when IsProcessIncomingMsgReady call failed
            break;

        case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_READY:
            // Notifies the node that the output queue is ready, and the node would
            // resume encoding incoming data
            iNode->HandlePortActivity(aActivity);
            break;

        case PVMF_PORT_ACTIVITY_CONNECTED_PORT_READY:
            if (OutgoingMsgQueueSize() > 0)
                RunIfNotReady();
            break;

        case PVMF_PORT_ACTIVITY_CONNECTED_PORT_BUSY:
            // This is handled when iNode->ProcessOutgoingMsg failed with busy
            break;

        case PVMF_PORT_ACTIVITY_CONNECT:
        case PVMF_PORT_ACTIVITY_DISCONNECT:
        default:
            break;
    }
}
void PVMFAvcEncPort::ProcessOutgoingMsgReady()
{
    if (OutgoingMsgQueueSize() > 0)
        RunIfNotReady();
}
void PVMFLoopbackIOPort::HandlePortActivity(const PVMFPortActivity &aActivity)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "0x%x PVMFLoopbackPort::PortActivity: port=0x%x, type=%d",
                     this, aActivity.iPort, aActivity.iType));

    //A port is reporting some activity or state change.  This code
    //figures out whether we need to queue a processing event
    //for the AO, and/or report a node event to the observer.

    switch (aActivity.iType)
    {
        case PVMF_PORT_ACTIVITY_CREATED:
            break;

        case PVMF_PORT_ACTIVITY_DELETED:
            break;

        case PVMF_PORT_ACTIVITY_CONNECT:
            //nothing needed.
            break;

        case PVMF_PORT_ACTIVITY_DISCONNECT:
            //nothing needed.
            break;

        case PVMF_PORT_ACTIVITY_OUTGOING_MSG:
            //An outgoing message was queued on this port.
            //Wakeup the AO on the first message only-- after
            //that it re-schedules itself as needed.
            if (aActivity.iPort->OutgoingMsgQueueSize() == 1)
                RunIfNotReady();
            break;

        case PVMF_PORT_ACTIVITY_INCOMING_MSG:
            //An incoming message was queued on this port.
            //Wakeup the AO on the first message only-- after
            //that it re-schedules itself as needed.
            if (aActivity.iPort->IncomingMsgQueueSize() == 1)
                RunIfNotReady();
            break;

        case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_BUSY:
            //Outgoing queue is now busy.
            //No action is needed here-- the node checks for
            //outgoing queue busy as needed during data processing.
            break;

        case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_READY:
            //the loopback port may be waiting on this event.

            if (iWaiting)
            {
                iWaiting = false;
                RunIfNotReady();
            }
            break;


        case PVMF_PORT_ACTIVITY_CONNECTED_PORT_BUSY:
            // The connected port has become busy (its incoming queue is
            // busy).
            // No action is needed here-- the port processing code
            // checks for connected port busy during data processing.
            break;

        case PVMF_PORT_ACTIVITY_CONNECTED_PORT_READY:
            // The connected port has transitioned from Busy to Ready.
            if (OutgoingMsgQueueSize() > 0)
                RunIfNotReady();
            break;

        default:
            break;
    }
}