/* ------------------------------------------------------------------ * 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. * ------------------------------------------------------------------- */ #ifndef PVAE_NODE_UTILITY_H_INCLUDED #define PVAE_NODE_UTILTIY_H_INCLUDED #ifndef OSCL_BASE_H_INCLUDED #include "oscl_base.h" #endif #ifndef OSCL_SCHEDULER_AO_H_INCLUDED #include "oscl_scheduler_ao.h" #endif #ifndef OSCL_VECTOR_H_INCLUDED #include "oscl_vector.h" #endif #ifndef PVLOGGER_H_INCLUDED #include "pvlogger.h" #endif #ifndef PV_ENGINE_TYPES_H_INCLUDED #include "pv_engine_types.h" #endif #ifndef PVMF_NODE_INTERFACE_H_INCLUDED #include "pvmf_node_interface.h" #endif #define LOG_STACK_TRACE(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, m) #define LOG_DEBUG(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, m) #define LOG_ERR(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_REL,iLogger,PVLOGMSG_ERR,m) /** Structure to contain a node and all ports and extensions associated to it */ class PVAENodeContainer { public: PVAENodeContainer() { iNode = NULL; iSessionId = 0; iNodeCapConfigIF = NULL; }; PVMFNodeInterface* iNode; PVMFSessionId iSessionId; PVUuid iUuid; Oscl_Vector<PVMFPortInterface*, OsclMemAllocator> iInputPorts; Oscl_Vector<PVMFPortInterface*, OsclMemAllocator> iOutputPorts; Oscl_Vector<PVInterface*, OsclMemAllocator> iExtensions; Oscl_Vector<PVUuid, OsclMemAllocator> iExtensionUuids; PVInterface* iNodeCapConfigIF; }; /** A vector of node container structures */ typedef Oscl_Vector<PVAENodeContainer*, OsclMemAllocator> PVAENodeContainerVector; /** Enumerated list of node commands */ typedef enum { PVAENU_CMD_NONE, PVAENU_CMD_CONNECT, PVAENU_CMD_DISCONNECT, PVAENU_CMD_QUERY_UUID, PVAENU_CMD_QUERY_INTERFACE, PVAENU_CMD_INIT, PVAENU_CMD_PREPARE, PVAENU_CMD_START, PVAENU_CMD_STOP, PVAENU_CMD_FLUSH, PVAENU_CMD_PAUSE, PVAENU_CMD_RESET, } PVAENodeUtilCmdType; /** Node utility command class */ class PVAENodeUtilCmd { public: PVAENodeUtilCmd() : iType(PVAENU_CMD_NONE), iParam1(NULL), iParam2(NULL), iContext(NULL) {} PVAENodeUtilCmd(const PVAENodeUtilCmd& aCmd) { Copy(aCmd); } PVAENodeUtilCmd& operator=(const PVAENodeUtilCmd& aCmd) { Copy(aCmd); return (*this); } // For most commands PVMFStatus Construct(PVAENodeUtilCmdType aType, const PVAENodeContainerVector& aNodes, OsclAny* aContext) { iType = aType; iNodes = aNodes; iContext = aContext; return PVMFSuccess; } // For Connect PVMFStatus ConstructConnect(PVAENodeContainer* aMasterNode, int32 aTag1, PVAENodeContainer* aSlaveNode, int32 aTag2, const PvmfMimeString& aMimeType, OsclAny* aContext) { iType = PVAENU_CMD_CONNECT; iContext = aContext; iParam1 = (OsclAny*)aTag1; iParam2 = (OsclAny*)aTag2; int32 err = 0; OSCL_TRY(err, iNodes.push_back(aMasterNode); iNodes.push_back(aSlaveNode); iMimeType = aMimeType; ); OSCL_FIRST_CATCH_ANY(err, return PVMFErrNoMemory;); return PVMFSuccess; } PVMFStatus ParseConnect(int32& aTag1, int32& aTag2, PvmfMimeString& aMimeType) { if (iType != PVAENU_CMD_CONNECT) return PVMFFailure; aTag1 = (int32)iParam1; aTag2 = (int32)iParam2; aMimeType = iMimeType; return PVMFSuccess; } PVMFStatus ConstructDisconnect(PVAENodeContainer* aNodeContainer, OsclAny* aContext) { iType = PVAENU_CMD_DISCONNECT; iContext = aContext; int32 err = 0; OSCL_TRY(err, iNodes.push_back(aNodeContainer); ); OSCL_FIRST_CATCH_ANY(err, return PVMFErrNoMemory;); return PVMFSuccess; } PVMFStatus ConstructQueryUUID(PVAENodeContainer* aNodeContainer, const PvmfMimeString& aMimeType, Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids, bool aExactUuidsOnly, OsclAny* aContext) { iType = PVAENU_CMD_QUERY_UUID; iContext = aContext; iParam1 = (OsclAny*) & aUuids; iParam2 = (OsclAny*)aExactUuidsOnly; int32 err = 0; OSCL_TRY(err, iNodes.push_back(aNodeContainer); iMimeType = aMimeType; ); OSCL_FIRST_CATCH_ANY(err, return PVMFErrNoMemory;); return PVMFSuccess; } PVMFStatus ParseQueryUUID(Oscl_Vector<PVUuid, OsclMemAllocator>* aUuids, bool& aExactUuidsOnly) { if (iType != PVAENU_CMD_QUERY_UUID) return PVMFFailure; aUuids = (Oscl_Vector<PVUuid, OsclMemAllocator>*)iParam1; aExactUuidsOnly = (iParam2 != NULL); // iParam2 is a bool return PVMFSuccess; } PVMFStatus ConstructQueryInterface(PVAENodeContainer* aNodeContainer, const PVUuid& aUuid, PVInterface*& aInterfacePtr, OsclAny* aContext) { iType = PVAENU_CMD_QUERY_INTERFACE; iContext = aContext; iParam1 = (OsclAny*) & aInterfacePtr; iUuid = aUuid; int32 err = 0; OSCL_TRY(err, iNodes.push_back(aNodeContainer); ); OSCL_FIRST_CATCH_ANY(err, return PVMFErrNoMemory;); return PVMFSuccess; } PVMFStatus ParseQueryInterface(PVInterface**& aInterfacePtr) { if (iType != PVAENU_CMD_QUERY_INTERFACE) return PVMFFailure; aInterfacePtr = (PVInterface**)iParam1; return PVMFSuccess; } PVMFStatus ConstructInit(PVAENodeContainer* aNodeContainer, OsclAny* aContext) { iType = PVAENU_CMD_INIT; iContext = aContext; int32 err = 0; OSCL_TRY(err, iNodes.push_back(aNodeContainer); ); OSCL_FIRST_CATCH_ANY(err, return PVMFErrNoMemory;); return PVMFSuccess; } PVAENodeUtilCmdType iType; PVAENodeContainerVector iNodes; OSCL_HeapString<OsclMemAllocator> iMimeType; PVUuid iUuid; // For QueryInterface OsclAny* iParam1; OsclAny* iParam2; OsclAny* iContext; private: void Copy(const PVAENodeUtilCmd& aCmd) { iType = aCmd.iType; iNodes = aCmd.iNodes; iMimeType = aCmd.iMimeType; iUuid = aCmd.iUuid; iParam1 = aCmd.iParam1; iParam2 = aCmd.iParam2; iContext = aCmd.iContext; } }; /** Observer class to listen for utility command completion events */ class PVAENodeUtilObserver { public: virtual void NodeUtilCommandCompleted(const PVMFCmdResp& aResponse) = 0; virtual void NodeUtilErrorEvent(const PVMFAsyncEvent& aEvent) = 0; virtual ~PVAENodeUtilObserver() {} }; /** * Utility class to connect two nodes and handle node commands to multiple * nodes. Users of this utility must provide PVMFNodeCmdStatusObserver, * PVMFNodeErrorEventObserver and PVMFNodeInfoEventObserver in order to * receive callbacks for results of command issued to this utility. * * While this utility is processing a command, it will change the nodes' * observers to this utility. Therefore there must be no pending commands * in the node before this method is called. Other users of the node must not * change the observers until this command is completed. Also, no additional commands * should be made to these nodes until the command is completed. When the * command is complete, the observers of the node will be set to the observers * of this utility. */ class PVAuthorEngineNodeUtility : public OsclTimerObject, public PVMFNodeCmdStatusObserver { public: PVAuthorEngineNodeUtility(); virtual ~PVAuthorEngineNodeUtility(); /** * Sets command status observer. After a utility * command is completed, the command status observer for the nodes * will be sent to the observer set here. * * @param aObserver Command status observer */ void SetObserver(const PVAENodeUtilObserver& aObserver) { iObserver = (PVAENodeUtilObserver*) & aObserver; } /** * Connect two nodes. An output port will be requested from the specified * input node, and an input port will be requested from the specified output * node. The two ports will then be connected to establish a connection * between the two nodes. This utility will callback to report status of * the command after the connection is complete and will return the newly * requested and connected ports will be added to the iInPorts or iOutPorts * vector in the PVAENodeContainer objects passed in. * * @param aInputNode Container of input node of the connection. The newly requested * port will be added to the iOutPorts vector of the node container. * @param aOutputNode Container of output node of the connection. The newly requested * port will be added to the iInPorts vector of the node container. * @param aContext Optional opaque data to be passed back to user with the command response * @returns Completion status */ PVMFStatus Connect(PVAENodeContainer* aMasterNode, int32 aTag1, PVAENodeContainer* aSlaveNode, int32 aTag2, const PvmfMimeString& aMimeType, OsclAny* aContext = NULL); /** * Disconnect and release all ports of a node. * * @param aNodeContainer Container for node which ports will be disonnected and released * @param aContext Optional opaque data to be passed back to user with the command response * @returns Completion status */ PVMFStatus Disconnect(PVAENodeContainer* aNodeContainer, OsclAny* aContext = NULL); /** * Query UUIDs supported by the specified node. * * @param aNodeContainer Container for node to which this query is made * @param aMimeType The MIME type of the desired interfaces * @param aUuids A vector to hold the discovered UUIDs * @param aExactUuidsOnly Turns on/off the retrival of UUIDs with aMimeType as a base type * @param aContext Optional opaque data to be passed back to user with the command response * @returns Completion status */ PVMFStatus QueryUUID(PVAENodeContainer* aNodeContainer, const PvmfMimeString& aMimeType, Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids, bool aExactUuidsOnly = false, OsclAny* aContext = NULL); /** * Query for interface of specified Uuid from the specified node. The queried interface * object will be added to the iExtensions vector and stored in the interface pointer * provided by user. Also, Uuid of the queried interface will be added to the * iExtensionsUuid vector. * * @param aNodeContainer Container for node to which this query is made * @param aUuid The UUID of the desired interface * @param aInterfacePtr Optional interface pointer to store the requested interface * @param aContext Optional opaque data to be passed back to user with the command response * @returns Completion status */ PVMFStatus QueryInterface(PVAENodeContainer* aNodeContainer, const PVUuid& aUuid, PVInterface*& aInterfacePtr, OsclAny* aContext = NULL); /** * Initialize a node * * @param aNode Node container containing the node to be initialized. * @param aContext Optional opaque data to be passed back to user with the command response * @returns Completion status */ PVMFStatus Init(const PVAENodeContainer* aNode, OsclAny* aContext = NULL); /** * Initialize all nodes in the vector. * * @param aNodes Vector of nodes to be initialized * @param aContext Optional opaque data to be passed back to user with the command response * @returns Completion status */ PVMFStatus Init(const PVAENodeContainerVector& aNodes, OsclAny* aContext = NULL); /** * Prepare all nodes in the vector. * * @param aNodes Vector of nodes to be prepared * @param aContext Optional opaque data to be passed back to user with the command response * @returns Completion status */ PVMFStatus Prepare(const PVAENodeContainerVector& aNodes, OsclAny* aContext = NULL); /** * Start all ports of all nodes in the vector. * * @param aNodes Vector of nodes to be started * @param aContext Optional opaque data to be passed back to user with the command response * @returns Completion status */ PVMFStatus Start(const PVAENodeContainerVector& aNodes, OsclAny* aContext = NULL); /** * Pause all ports of all nodes in the vector. * * @param aNodes Vector of nodes to be paused * @param aContext Optional opaque data to be passed back to user with the command response * @returns Completion status */ PVMFStatus Pause(const PVAENodeContainerVector& aNodes, OsclAny* aContext = NULL); /** * Stop all ports of all nodes in the vector. * * @param aNodes Vector of nodes to be stopped * @param aContext Optional opaque data to be passed back to user with the command response * @returns Completion status */ PVMFStatus Stop(const PVAENodeContainerVector& aNodes, OsclAny* aContext = NULL); /** * Flush all ports of all nodes in the vector. * * @param aNodes Vector of nodes to be flushed * @param aContext Optional opaque data to be passed back to user with the command response * @returns Completion status */ PVMFStatus Flush(const PVAENodeContainerVector& aNodes, OsclAny* aContext = NULL); /** * Start all ports of all nodes in the vector. * * @param aNodes Vector of nodes to be reset * @param aContext Optional opaque data to be passed back to user with the command response * @returns Completion status */ PVMFStatus Reset(const PVAENodeContainerVector& aNodes, OsclAny* aContext = NULL); /** * Provides the size of command queue * * @returns Number of pending commands in command queue */ uint32 GetCommandQueueSize(); // Implement pure virtual method of PVMFNodeCmdStatusObserver void NodeCommandCompleted(const PVMFCmdResp& aResponse); private: void Run(); // Command queue routines PVMFStatus AddCmdToQueue(PVAENodeUtilCmd& aCmd); void CompleteUtilityCmd(const PVAENodeUtilCmd& aCmd, PVMFStatus aStatus); // Command processing routines PVMFStatus DoConnect(const PVAENodeUtilCmd& aCmd); PVMFStatus CompleteConnect(const PVAENodeUtilCmd& aCmd, const PVMFCmdResp& aResponse); PVMFStatus DoDisconnect(const PVAENodeUtilCmd& aCmd); PVMFStatus DoQueryUuid(const PVAENodeUtilCmd& aCmd); PVMFStatus DoQueryInterface(const PVAENodeUtilCmd& aCmd); PVMFStatus CompleteQueryInterface(const PVAENodeUtilCmd& aCmd); PVMFStatus DoInit(const PVAENodeUtilCmd& aCmd); PVMFStatus DoPrepare(const PVAENodeUtilCmd& aCmd); PVMFStatus DoStart(const PVAENodeUtilCmd& aCmd); PVMFStatus DoPause(const PVAENodeUtilCmd& aCmd); PVMFStatus DoStop(const PVAENodeUtilCmd& aCmd); PVMFStatus DoFlush(const PVAENodeUtilCmd& aCmd); PVMFStatus DoReset(const PVAENodeUtilCmd& aCmd); PVMFStatus CompleteStateTransition(const PVAENodeUtilCmd& aCmd, TPVMFNodeInterfaceState aState); PVMFStatus ReleasePort(PVAENodeContainer*&, PVMFPortInterface*&); // Observer PVAENodeUtilObserver* iObserver; // Command queue Oscl_Vector<PVAENodeUtilCmd, OsclMemAllocator> iCmdQueue; PVLogger* iLogger; }; #endif // PVAE_NODE_UTILTIY_H_INCLUDED