OSCL_EXPORT_REF PVMFStatus PVMp4FFComposerPort::Connect(PVMFPortInterface* aPort)
{
    LOG_STACK_TRACE((0, "PVMp4FFComposerPort::Connect: aPort=0x%x", aPort));

    if (!aPort)
    {
        LOG_ERR((0, "PVMp4FFComposerPort::Connect: Error - Connecting to invalid port"));
        return PVMFErrArgument;
    }

    if (iConnectedPort)
    {
        LOG_ERR((0, "PVMp4FFComposerPort::Connect: Error - Already connected"));
        return PVMFFailure;
    }

    OsclAny* temp = NULL;
    aPort->QueryInterface(PVMI_CAPABILITY_AND_CONFIG_PVUUID, temp);
    PvmiCapabilityAndConfig *config = OSCL_STATIC_CAST(PvmiCapabilityAndConfig*, temp);

    if (!config)
    {
        LOG_ERR((0, "PVMp4FFComposerPort::Connect: Error - Peer port does not support capability interface"));
        return PVMFFailure;
    }

    PVMFStatus status = PVMFSuccess;
    switch (iTag)
    {
        case PVMF_MP4FFCN_PORT_TYPE_SINK:
            status = NegotiateInputSettings(config);
            break;
        default:
            LOG_ERR((0, "PVMp4FFComposerPort::Connect: Error - Invalid port tag"));
            status = PVMFFailure;
    }

    if (status != PVMFSuccess)
    {
        LOG_ERR((0, "PVMp4FFComposerPort::Connect: Error - Settings negotiation failed. status=%d", status));
        return status;
    }

    //Automatically connect the peer.
    if (aPort->PeerConnect(this) != PVMFSuccess)
    {
        LOG_ERR((0, "PVMp4FFComposerPort::Connect: Error - Peer Connect failed"));
        return PVMFFailure;
    }

    iConnectedPort = aPort;

#if PVMF_PORT_BASE_IMPL_STATS
    // Reset statistics
    oscl_memset((OsclAny*)&(PvmfPortBaseImpl::iStats), 0, sizeof(PvmfPortBaseImplStats));
#endif

    PortActivity(PVMF_PORT_ACTIVITY_CONNECT);
    return PVMFSuccess;
}
OSCL_EXPORT_REF PVMFStatus PVMFAvcEncPort::getParametersSync(PvmiMIOSession session,
        PvmiKeyType identifier,
        PvmiKvp*& parameters,
        int& num_parameter_elements,
        PvmiCapabilityContext context)
{
    LOG_STACK_TRACE((0, "PVMFAvcEncPort::getParametersSync"));
    OSCL_UNUSED_ARG(session);
    OSCL_UNUSED_ARG(context);

    parameters = NULL;
    num_parameter_elements = 0;
    PVMFStatus status = PVMFFailure;

    switch (iTag)
    {
        case PVMF_AVCENC_NODE_PORT_TYPE_INPUT:
            return GetInputParametersSync(identifier, parameters, num_parameter_elements);
        case PVMF_AVCENC_NODE_PORT_TYPE_OUTPUT:
            return GetOutputParametersSync(identifier, parameters, num_parameter_elements);
        default:
            LOG_ERR((0, "PVMFAvcEncPort::getParametersSync: Error - Invalid port tag"));
            break;
    }

    return status;
}
PVMFStatus PVMFAvcEncPort::SetFormat(PVMFFormatType aFormat)
{
    LOG_STACK_TRACE((0, "PVMFAvcEncPort::SetFormat: aFormat=%d", aFormat));
    if (!IsFormatSupported(aFormat))
        return PVMFFailure;

    iFormat = aFormat;
    return PVMFSuccess;
}
PVMFStatus PVMFAvcEncPort::AllocateKvp(PvmiKvp*& aKvp, PvmiKeyType aKey, int32 aNumParams)
{
    LOG_STACK_TRACE((0, "PVMFAvcEncPort::AllocateKvp"));
    uint8* buf = NULL;
    uint32 keyLen = oscl_strlen(aKey) + 1;
    int32 err = 0;

    OSCL_TRY(err,
             buf = (uint8*)iAlloc.allocate(aNumParams * (sizeof(PvmiKvp) + keyLen));
             if (!buf)
             OSCL_LEAVE(OsclErrNoMemory);
            );
OSCL_EXPORT_REF PVMFStatus PVMp4FFComposerPort::getParametersSync(PvmiMIOSession session,
        PvmiKeyType identifier,
        PvmiKvp*& parameters,
        int& num_parameter_elements,
        PvmiCapabilityContext context)
{
    LOG_STACK_TRACE((0, "PVMp4FFComposerPort::getParametersSync"));
    OSCL_UNUSED_ARG(session);
    OSCL_UNUSED_ARG(context);

    parameters = NULL;
    num_parameter_elements = 0;
    PVMFStatus status = PVMFFailure;

    //identifier is a key and is assumed to be null terminated
    if (oscl_strcmp(identifier, INPUT_FORMATS_CAP_QUERY) == 0)
    {
        num_parameter_elements = 9;

        status = AllocateKvp(parameters, (PvmiKeyType)INPUT_FORMATS_VALTYPE, num_parameter_elements);
        if (status != PVMFSuccess)
        {
            LOG_ERR((0, "PVMp4FFComposerPort::GetOutputParametersSync: Error - AllocateKvp failed. status=%d", status));
        }
        else
        {
            parameters[0].value.pChar_value = (char*)PVMF_MIME_AMR_IETF;
            parameters[1].value.pChar_value = (char*)PVMF_MIME_MPEG4_AUDIO;
            parameters[2].value.pChar_value = (char*)PVMF_MIME_M4V;
            parameters[3].value.pChar_value = (char*)PVMF_MIME_H2631998;
            parameters[4].value.pChar_value = (char*)PVMF_MIME_H2632000;
            parameters[5].value.pChar_value = (char*)PVMF_MIME_H264_VIDEO_MP4;
            parameters[6].value.pChar_value = (char*)PVMF_MIME_3GPP_TIMEDTEXT;
            parameters[7].value.pChar_value = (char*)PVMF_MIME_AMRWB_IETF;
            parameters[8].value.pChar_value = (char*)PVMF_MIME_QCELP;
        }
    }
    else if (oscl_strcmp(identifier, INPUT_FORMATS_CUR_QUERY) == 0)
    {
        num_parameter_elements = 1;
        status = AllocateKvp(parameters, (PvmiKeyType)INPUT_FORMATS_VALTYPE, num_parameter_elements);
        if (status != PVMFSuccess)
        {
            LOG_ERR((0, "PVMp4FFComposerPort::GetOutputParametersSync: Error - AllocateKvp failed. status=%d", status));
        }
        else
        {
            parameters[0].value.pChar_value = (char*)iFormat.getMIMEStrPtr();
        }
    }

    return status;
}
PVMFStatus PVAuthorEngineNodeUtility::Init(const PVAENodeContainer* aNode, OsclAny* aContext)
{
    LOG_STACK_TRACE((0, "PVAuthorEngineNodeUtility::Init: aNode=0x%x, aContext=0x%x", aNode, aContext));

    PVAENodeUtilCmd cmd;
    PVMFStatus status = cmd.ConstructInit((PVAENodeContainer*)aNode, aContext);
    if (status != PVMFSuccess)
    {
        LOG_ERR((0, "PVAuthorEngineNodeUtility::Init: Error - cmd.Construct failed. status=%d", status));
        return status;
    }

    return AddCmdToQueue(cmd);
}
PVMFStatus PVAuthorEngineNodeUtility::Connect(PVAENodeContainer* aMasterNode, int32 aTag1,
        PVAENodeContainer* aSlaveNode, int32 aTag2,
        const PvmfMimeString& aMimeString,
        OsclAny* aContext)
{
    LOG_STACK_TRACE((0, "PVAuthorEngineNodeUtility::Connect: &aMasterNode=0x%x, aTag1=%d, &aSlaveNode=0x%x, aTag2=%d",
                     &aMasterNode, aTag1, &aSlaveNode, aTag2));

    PVAENodeUtilCmd cmd;
    PVMFStatus status = cmd.ConstructConnect(aMasterNode, aTag1, aSlaveNode, aTag2, aMimeString, aContext);
    if (status != PVMFSuccess)
    {
        LOG_ERR((0, "PVAuthorEngineNodeUtility::Connect: Error - cmd.ConstructConnect failed. status=%d", status));
        return status;
    }

    return AddCmdToQueue(cmd);
}
PVMFStatus PVAuthorEngineNodeUtility::QueryInterface(PVAENodeContainer* aNodeContainer,
        const PVUuid& aUuid,
        PVInterface*& aInterfacePtr,
        OsclAny* aContext)
{
    LOG_STACK_TRACE((0, "PVAuthorEngineNodeUtility::QueryInterface: &aNodeContainer=0x%x, &aUuid=0x%x, aContext=0x%x",
                     &aNodeContainer, &aUuid, aContext));

    PVAENodeUtilCmd cmd;
    PVMFStatus status = cmd.ConstructQueryInterface(aNodeContainer, aUuid, aInterfacePtr, aContext);
    if (status != PVMFSuccess)
    {
        LOG_ERR((0, "PVAuthorEngineNodeUtility::QueryInterface: Error - cmd.ConstructQueryInterface failed. status=%d", status));
        return status;
    }

    return AddCmdToQueue(cmd);
}
PVMFStatus PVAuthorEngineNodeUtility::QueryUUID(PVAENodeContainer* aNodeContainer,
        const PvmfMimeString& aMimeType,
        Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids,
        bool aExactUuidsOnly,
        OsclAny* aContext)
{
    LOG_STACK_TRACE((0, "PVAuthorEngineNodeUtility::QueryUUID: &aNodeContainer=0x%x, aMimeType=%s, &aUuids=0x%x, aExactUuidsOnly=%d, aContext=0x%x",
                     &aNodeContainer, aMimeType.get_cstr(), &aUuids, aExactUuidsOnly, aContext));

    PVAENodeUtilCmd cmd;
    PVMFStatus status = cmd.ConstructQueryUUID(aNodeContainer, aMimeType, aUuids, aExactUuidsOnly, aContext);
    if (status != PVMFSuccess)
    {
        LOG_ERR((0, "PVAuthorEngineNodeUtility::QueryUUID: Error - cmd.ConstructQueryUUID failed. status=%d", status));
        return status;
    }

    return AddCmdToQueue(cmd);
}
////////////////////////////////////////////////////////////////////////////
//           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;
    }
}
PVMFStatus PVAuthorEngineNodeUtility::AddCmdToQueue(PVAENodeUtilCmd& aCmd)
{
    LOG_STACK_TRACE((0, "PVAuthorEngineNodeUtility::AddCmdToQueue"));

    int32 err = 0;
    OSCL_TRY(err, iCmdQueue.push_back(aCmd););
void PVAuthorEngineNodeUtility::Run()
{
    LOG_STACK_TRACE((0, "PVAuthorEngineNodeUtility::Run: Enter"));

    if (iCmdQueue.empty())
        return;

    PVAENodeUtilCmd cmd = iCmdQueue[0];
    if (cmd.iNodes.empty())
    {
        LOG_ERR((0, "PVAuthorEngineNodeUtility::Run: Error - cmd.iNodes is empty"));
        CompleteUtilityCmd(cmd, PVMFFailure);
        return;
    }

    PVMFStatus status = PVMFFailure;
    LOG_STACK_TRACE((0, "PVAuthorEngineNodeUtility::Run: cmd.iType=%d", cmd.iType));
    switch (cmd.iType)
    {
        case PVAENU_CMD_CONNECT:
            status = DoConnect(cmd);
            break;
        case PVAENU_CMD_DISCONNECT:
            status = DoDisconnect(cmd);
            break;
        case PVAENU_CMD_QUERY_UUID:
            status = DoQueryUuid(cmd);
            break;
        case PVAENU_CMD_QUERY_INTERFACE:
            status = DoQueryInterface(cmd);
            break;
        case PVAENU_CMD_INIT:
            status = DoInit(cmd);
            break;
        case PVAENU_CMD_PREPARE:
            status = DoPrepare(cmd);
            break;
        case PVAENU_CMD_START:
            status = DoStart(cmd);
            break;
        case PVAENU_CMD_PAUSE:
            status = DoPause(cmd);
            break;
        case PVAENU_CMD_STOP:
            status = DoStop(cmd);
            break;
        case PVAENU_CMD_FLUSH:
            status = DoFlush(cmd);
            break;
        case PVAENU_CMD_RESET:
            status = DoReset(cmd);
            break;
        default:
            status = PVMFFailure;
            break;
    }

    if (status != PVMFPending)
        CompleteUtilityCmd(cmd, status);

    LOG_STACK_TRACE((0, "PVAuthorEngineNodeUtility::Run: Exit"));
}