summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e3089a0)
raw | patch | inline | side by side (parent: e3089a0)
author | Rishabh Garg <rishabh@ti.com> | |
Tue, 17 Apr 2018 10:41:39 +0000 (16:11 +0530) | ||
committer | Sivaraj R <sivaraj@ti.com> | |
Wed, 18 Apr 2018 04:50:18 +0000 (10:20 +0530) |
Signed-off-by: Rishabh Garg <rishabh@ti.com>
fvid2.h | patch | blob | history | |
fvid2_component.mk | [changed mode: 0644->0755] | patch | blob | history |
include/fvid2_graph.h | [new file with mode: 0755] | patch | blob |
src/fvid2_graph.c | [new file with mode: 0755] | patch | blob |
src/makefile | [changed mode: 0644->0755] | patch | blob | history |
index 2470d591811953d6eb1e391f095899032437910f..011dac8cdc21a6b88a7efbd93ebafc79717c4315 100644 (file)
--- a/fvid2.h
+++ b/fvid2.h
#include <ti/drv/fvid2/include/fvid2_utils.h>
#include <ti/drv/fvid2/include/fvid2_api.h>
#include <ti/drv/fvid2/include/fvid2_drvMgr.h>
+#include <ti/drv/fvid2/include/fvid2_graph.h>
#ifdef __cplusplus
extern "C" {
diff --git a/fvid2_component.mk b/fvid2_component.mk
--- a/fvid2_component.mk
+++ b/fvid2_component.mk
#
ifeq ($(fvid2_component_make_include), )
-fvid2_default_SOCLIST = j7 am65x
+fvid2_default_SOCLIST = j7 am65xx
fvid2_default_j7_CORELIST = mcu1_0 mcu1_1
-fvid2_default_am65x_CORELIST = mcu1_0 mcu1_1 mpu1_0
+fvid2_default_am65xx_CORELIST = mcu1_0 mcu1_1 mpu1_0
############################
# fvid2 package
diff --git a/include/fvid2_graph.h b/include/fvid2_graph.h
--- /dev/null
+++ b/include/fvid2_graph.h
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) Texas Instruments Incorporated 2018
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file fvid2_graph.h
+ *
+ * \brief FVID2 Graph interface file.
+ */
+
+#ifndef FVID2_GRAPH_H_
+#define FVID2_GRAPH_H_
+
+/* ========================================================================== */
+/* Include Files */
+/* ========================================================================== */
+
+#include <ti/drv/fvid2/fvid2.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ========================================================================== */
+/* Macros & Typedefs */
+/* ========================================================================== */
+
+#define FVID2_GRAPH_DEF_ALIGN ((uint32_t) 16U)
+#define FVID2_GRAPH_INVALID_NODE_ID ((uint32_t) 0U)
+#define FVID2_GRAPH_MAX_NODES ((uint32_t) 80U)
+#define FVID2_GRAPH_MAX_NUM_PATHS ((uint32_t) 20U)
+
+typedef enum
+{
+ FVID2_GRAPH_NM_DISABLE,
+ FVID2_GRAPH_NM_ENABLE,
+ FVID2_GRAPH_NM_CHECK
+} Fvid2_GraphNodeMode;
+
+typedef enum
+{
+ FVID2_GRAPH_NT_DUMMY,
+ FVID2_GRAPH_NT_DSS, /* DSS */
+ FVID2_GRAPH_NT_MAX_NODETYPE
+} Fvid2_GraphNodeTypes;
+
+typedef enum
+{
+ FVID2_GRAPH_NT_IN_SINGLE,
+ FVID2_GRAPH_NT_IN_MULTI,
+ FVID2_GRAPH_NT_IN_EMPTY
+} Fvid2_GraphNodeInputType;
+
+typedef enum
+{
+ FVID2_GRAPH_NT_OUT_SINGLE,
+ FVID2_GRAPH_NT_OUT_MULTI,
+ FVID2_GRAPH_NT_OUT_EMPTY
+} Fvid2_GraphNodeOutputType;
+
+/* ========================================================================== */
+/* Structure Declarations */
+/* ========================================================================== */
+
+typedef struct Fvid2_GraphNodeInfo_t Fvid2_GraphNodeInfo;
+
+typedef struct Fvid2_GraphNodeSet_t
+{
+ uint32_t numNodes;
+ /**< Number of input/output nodes */
+ Fvid2_GraphNodeInfo *node[FVID2_GRAPH_MAX_NUM_PATHS];
+ /**< Pointer to the input/output node */
+ uint32_t isEnabled[FVID2_GRAPH_MAX_NUM_PATHS];
+ /**< Flag to indicate whether input/output is enabled or not. */
+} Fvid2_GraphNodeSet;
+
+struct Fvid2_GraphNodeInfo_t
+{
+ /*Used to select config structure from the CreateParams */
+ uint32_t nodeNum;
+
+ /* Tree-connections */
+ Fvid2_GraphNodeInputType inType;
+ Fvid2_GraphNodeOutputType outType;
+
+ /* SI/SO/MI/MO */
+ uint32_t nodeType;
+
+ void *corePtr;
+ uint32_t isDummy;
+ uint32_t inUse;
+ Fvid2_GraphNodeSet input;
+ Fvid2_GraphNodeSet output;
+};
+
+typedef struct
+{
+ uint32_t numNodes;
+ Fvid2_GraphNodeInfo *list;
+} Fvid2_GraphNodeInfoList;
+
+/**
+ * \brief Structure containing edge information. Edge is a connection
+ * between two nodes i.e. two modules. Video Hardware can be represented
+ * by a graph, where each module is node and edge is present between two
+ * nodes if they are connected.
+ */
+typedef struct
+{
+ uint32_t startNode;
+ /**< Starting node of the edge */
+ uint32_t endNode;
+ /**< End node of the edge */
+} Fvid2_GraphEdgeInfo;
+
+typedef struct
+{
+ uint32_t numEdges;
+ /**< Number of the edge */
+ Fvid2_GraphEdgeInfo *list;
+ /**< Edge list */
+} Fvid2_GraphEdgeInfoList;
+
+typedef struct
+{
+ Fvid2_GraphNodeInfoList *nodeList;
+ Fvid2_GraphEdgeInfoList *edgeList;
+} Fvid2_GraphInfo;
+
+/* ========================================================================== */
+/* Function Declarations */
+/* ========================================================================== */
+
+Fvid2_GraphInfo *Fvid2_graphInit(const Fvid2_GraphNodeInfoList *inNodeList,
+ const Fvid2_GraphEdgeInfoList *inEdgeList,
+ Fvid2_GraphInfo *graphHandle);
+
+int32_t Fvid2_graphDeInit(Fvid2_GraphInfo *graphHandle);
+
+Fvid2_GraphNodeInfo *Fvid2_graphGetNodeInfo(
+ const Fvid2_GraphNodeInfoList *nodeList,
+ uint32_t cnt);
+
+int32_t Fvid2_graphAllocNodes(const Fvid2_GraphNodeInfoList *nodeList,
+ const Fvid2_GraphEdgeInfoList *edgeList,
+ Fvid2_GraphNodeMode mode);
+
+int32_t Fvid2_graphGetPath(const Fvid2_GraphNodeInfoList *inNodeList,
+ const Fvid2_GraphEdgeInfoList *inEdgeList,
+ Fvid2_GraphNodeInfoList *outNodeList,
+ Fvid2_GraphEdgeInfoList *outEdgeList,
+ uint32_t maxOutNodeCnt,
+ uint32_t maxOutEdgeCnt);
+
+int32_t Fvid2_graphFreePath(Fvid2_GraphNodeInfoList *nodeList,
+ Fvid2_GraphEdgeInfoList *edgeList);
+
+int32_t Fvid2_graphStackIsLastNode(const Fvid2_GraphNodeInfo *currNode,
+ uint32_t isForward);
+
+void Fvid2_graphStackInitTraverser(Fvid2_GraphNodeInfo *node);
+
+Fvid2_GraphNodeInfo *Fvid2_graphGetNextNodeToTraverse(uint32_t isForward);
+
+uint32_t Fvid2_graphIsNodeInputAvailable(
+ const Fvid2_GraphNodeInfoList *nodeList,
+ uint32_t nodeNum);
+
+uint32_t Fvid2_graphIsNodeOutputAvailable(
+ const Fvid2_GraphNodeInfoList *nodeList,
+ uint32_t nodeNum);
+
+void Fvid2_graphInitTraverser(Fvid2_GraphNodeInfo *node);
+
+Fvid2_GraphNodeInfo *Fvid2_graphGetNextChildNode(
+ const Fvid2_GraphNodeInfo *currNode,
+ uint32_t isForward);
+
+Fvid2_GraphNodeInfo *Fvid2_graphStackPeak(uint32_t *stNum);
+
+int32_t Fvid2_graphGetEnabledIndex(const uint32_t *array, uint32_t size);
+
+void Fvid2_graphAddEdge(Fvid2_GraphEdgeInfo *edge,
+ uint32_t startNode,
+ uint32_t endNode);
+
+#ifdef __cplusplus /* If this is a C++ compiler, end C linkage */
+}
+#endif
+
+#endif /* FVID2_GRAPH_H_ */
diff --git a/src/fvid2_graph.c b/src/fvid2_graph.c
--- /dev/null
+++ b/src/fvid2_graph.c
@@ -0,0 +1,686 @@
+/*
+ * Copyright (c) Texas Instruments Incorporated 2018
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file fvid2_graph.c
+ *
+ * \brief File containing the graph functions for resource management.
+ *
+ */
+
+/* ========================================================================== */
+/* Include Files */
+/* ========================================================================== */
+
+#include <stdint.h>
+#include <ti/drv/fvid2/fvid2.h>
+
+/* ========================================================================== */
+/* Macros & Typedefs */
+/* ========================================================================== */
+
+/* None */
+
+/* ========================================================================== */
+/* Structure Declarations */
+/* ========================================================================== */
+
+typedef struct Fvid2_GraphStack_t
+{
+ Fvid2_GraphNodeInfo *node[FVID2_GRAPH_MAX_NODES];
+ /**< Array of node pointers */
+ int32_t stNum[FVID2_GRAPH_MAX_NODES];
+ /**< Keeps track of which child of this node is next to be visited, on
+ * the stack for a node. */
+ uint8_t isVisited[FVID2_GRAPH_MAX_NODES];
+ /**< Flag keeps track of whether given node is visited or not */
+ int32_t top;
+ /**< Top marker of the stack */
+} Fvid2_GraphStack;
+
+/* ========================================================================== */
+/* Internal Function Declarations */
+/* ========================================================================== */
+
+static int32_t Fvid2_graphConnect(const Fvid2_GraphNodeInfoList *inNodeList,
+ const Fvid2_GraphEdgeInfoList *inEdgeList);
+static void Fvid2_graphStackReset(void);
+static void Fvid2_graphStackPush(Fvid2_GraphNodeInfo *node);
+static void Fvid2_graphStackPop(void);
+static uint32_t Fvid2_graphStackIsVisited(const Fvid2_GraphNodeInfo *node);
+int32_t Fvid2_graphStackIsLastNode(const Fvid2_GraphNodeInfo *currNode,
+ uint32_t isForward);
+
+/* ========================================================================== */
+/* Global Variables */
+/* ========================================================================== */
+
+static Fvid2_GraphStack gFvid2GraphNodeStack;
+
+/* ========================================================================== */
+/* Function Definitions */
+/* ========================================================================== */
+
+/* Helper function */
+static int32_t Fvid2_graphConnect(const Fvid2_GraphNodeInfoList *inNodeList,
+ const Fvid2_GraphEdgeInfoList *inEdgeList)
+{
+ Fvid2_GraphNodeInfo *nodes = inNodeList->list;
+ Fvid2_GraphEdgeInfo *edges = inEdgeList->list;
+ uint32_t cnt, startNode, endNode, index1, index2;
+ for (cnt = 0; cnt < inNodeList->numNodes; cnt++)
+ {
+ Fvid2Utils_memset(&nodes[cnt].input, 0, sizeof (Fvid2_GraphNodeSet));
+ Fvid2Utils_memset(&nodes[cnt].output, 0, sizeof (Fvid2_GraphNodeSet));
+ }
+
+ for (cnt = 0U; cnt < inEdgeList->numEdges; cnt++)
+ {
+ startNode = edges[cnt].startNode;
+ endNode = edges[cnt].endNode;
+ /* End Node is output node for the start Node so update
+ * information in start node*/
+ index1 = nodes[startNode].output.numNodes;
+ nodes[startNode].output.node[index1] = &nodes[endNode];
+ nodes[startNode].output.numNodes++;
+ GT_assert(Fvid2Trace, (index1 < FVID2_GRAPH_MAX_NUM_PATHS));
+
+ /* Start Node is input node for the end Node so update
+ * information in end node*/
+ index2 = nodes[endNode].input.numNodes;
+ nodes[endNode].input.node[index2] = &nodes[startNode];
+ nodes[endNode].input.numNodes++;
+ GT_assert(Fvid2Trace, (index2 < FVID2_GRAPH_MAX_NUM_PATHS));
+
+ /* Dummy node's input is always enabled */
+ if ((TRUE == nodes[endNode].isDummy) &&
+ (TRUE == nodes[startNode].isDummy))
+ {
+ nodes[startNode].output.isEnabled[index1] = TRUE;
+ nodes[endNode].input.isEnabled[index2] = TRUE;
+ }
+ }
+
+ return FVID2_SOK;
+}
+
+/** \brief Creates static DSS topology for the fixed edges/nodes. There
+ * are some dummy nodes in the DSS topology. Input and output of these
+ * nodes are always enabled and cannot be changed. This function creates
+ * this static table.
+ * Called at the init time only
+ */
+Fvid2_GraphInfo *Fvid2_graphInit(const Fvid2_GraphNodeInfoList *inNodeList,
+ const Fvid2_GraphEdgeInfoList *inEdgeList,
+ Fvid2_GraphInfo *graphHandle)
+{
+ GT_assert(Fvid2Trace, (graphHandle != NULL));
+ GT_assert(Fvid2Trace, (graphHandle->nodeList != NULL));
+ GT_assert(Fvid2Trace, (graphHandle->edgeList != NULL));
+
+ GT_assert(Fvid2Trace, (inNodeList != NULL));
+ GT_assert(Fvid2Trace, (inEdgeList != NULL));
+
+ graphHandle->nodeList->numNodes = inNodeList->numNodes;
+ graphHandle->edgeList->numEdges = inEdgeList->numEdges;
+ graphHandle->nodeList->list = inNodeList->list;
+ graphHandle->edgeList->list = inEdgeList->list;
+
+ Fvid2_graphConnect(inNodeList, inEdgeList);
+ return graphHandle;
+}
+
+int32_t Fvid2_graphDeInit(Fvid2_GraphInfo *graphHandle)
+{
+ return FVID2_SOK;
+}
+
+/** \brief Function to get the pointer to node for the given index
+ */
+Fvid2_GraphNodeInfo *Fvid2_graphGetNodeInfo(
+ const Fvid2_GraphNodeInfoList *nodeList,
+ uint32_t cnt)
+{
+ Fvid2_GraphNodeInfo *node = NULL;
+ if (cnt < nodeList->numNodes)
+ {
+ node = &nodeList->list[cnt];
+ }
+ return (node);
+}
+
+/** \brief This function allocates nodes within the CORE by enabling
+ * specified edges.
+ *
+ * To enable an edge, it enables output of source node and
+ * enables input of the target node.
+ *
+ * Returns error if a node is already active.
+ *
+ * TODO: First edge is assumed as input, Why/How to disable edges?,
+ * Multiple handle support.
+ * TODO: If FAIL, run through again and disable if anything was enabled.
+ */
+
+uint32_t Fvid2_graphIsNodeInputAvailable(
+ const Fvid2_GraphNodeInfoList *nodeList,
+ uint32_t nodeNum)
+{
+ uint32_t j;
+ uint32_t retVal = TRUE;
+ Fvid2_GraphNodeInfo *curNode = Fvid2_graphGetNodeInfo(nodeList, nodeNum);
+ if (NULL == curNode)
+ {
+ retVal = FALSE;
+ }
+ else
+ {
+ for (j = 0; j < curNode->input.numNodes; j++)
+ {
+ if (FVID2_GRAPH_NM_ENABLE == curNode->input.isEnabled[j])
+ {
+ retVal = FALSE;
+ break;
+ }
+ }
+ }
+ return retVal;
+}
+
+uint32_t Fvid2_graphIsNodeOutputAvailable(
+ const Fvid2_GraphNodeInfoList *nodeList,
+ uint32_t nodeNum)
+{
+ uint32_t j;
+ uint32_t retVal = TRUE;
+ Fvid2_GraphNodeInfo *curNode = Fvid2_graphGetNodeInfo(nodeList, nodeNum);
+ if (NULL == curNode)
+ {
+ retVal = FALSE;
+ }
+ else
+ {
+ for (j = 0; j < curNode->output.numNodes; j++)
+ {
+ if (FVID2_GRAPH_NM_ENABLE == curNode->output.isEnabled[j])
+ {
+ retVal = FALSE;
+ break;
+ }
+ }
+ }
+ return retVal;
+}
+
+int32_t Fvid2_graphAllocNodes(const Fvid2_GraphNodeInfoList *nodeList,
+ const Fvid2_GraphEdgeInfoList *edgeList,
+ Fvid2_GraphNodeMode mode)
+{
+ uint32_t i, j;
+ int32_t retVal = FVID2_SOK;
+ Fvid2_GraphEdgeInfo *inputEdgeList = edgeList->list;
+ for (i = 0; i < edgeList->numEdges; i++)
+ {
+ Fvid2_GraphNodeInfo *startNode = Fvid2_graphGetNodeInfo(
+ nodeList, inputEdgeList[i].startNode);
+ GT_assert(Fvid2Trace, (startNode != NULL));
+ Fvid2_GraphNodeInfo *endNode = Fvid2_graphGetNodeInfo(
+ nodeList, inputEdgeList[i].endNode);
+ GT_assert(Fvid2Trace, (endNode != NULL));
+ if ((startNode->nodeNum == FVID2_GRAPH_INVALID_NODE_ID) &&
+ (endNode->nodeNum == FVID2_GRAPH_INVALID_NODE_ID))
+ {
+ break;
+ }
+
+ /* TODO: Multiple connections from different path probably does not work
+ **/
+ /* here. Will it be ever required? */
+ /* Example: One handle connects one source for blender, Second handle */
+ /* connects second source for blender - Is such a case required?
+ **/
+ if (FVID2_GRAPH_NT_OUT_SINGLE == startNode->outType)
+ {
+ uint32_t inUse = FALSE;
+ for (j = 0; j < startNode->output.numNodes; j++)
+ {
+ if (FVID2_GRAPH_NM_ENABLE == startNode->output.isEnabled[j])
+ {
+ inUse = TRUE;
+ break;
+ }
+ }
+ if ((FALSE == inUse) || (FVID2_GRAPH_NM_DISABLE == mode))
+ {
+ for (j = 0; j < startNode->output.numNodes; j++)
+ {
+ if (startNode->output.node[j] == endNode)
+ {
+ startNode->output.isEnabled[j] = mode;
+ break;
+ }
+ }
+ if (j == startNode->output.numNodes)
+ {
+ retVal = FVID2_EFAIL;
+ }
+ }
+ }
+ else if (FVID2_GRAPH_NT_OUT_MULTI == startNode->outType)
+ {
+ for (j = 0; j < startNode->output.numNodes; j++)
+ {
+ if (startNode->output.node[j] == endNode)
+ {
+ startNode->output.isEnabled[j] = mode;
+ break;
+ }
+ }
+ if (j == startNode->output.numNodes)
+ {
+ retVal = FVID2_EFAIL;
+ }
+ }
+ else
+ {
+ /*Do nothing */
+ }
+
+ if (FVID2_GRAPH_NT_IN_SINGLE == endNode->inType)
+ {
+ uint32_t inUse = FALSE;
+ for (j = 0; j < endNode->input.numNodes; j++)
+ {
+ if (FVID2_GRAPH_NM_ENABLE == endNode->input.isEnabled[j])
+ {
+ inUse = TRUE;
+ break;
+ }
+ }
+ if ((FALSE == inUse) || (FVID2_GRAPH_NM_DISABLE == mode))
+ {
+ for (j = 0; j < endNode->input.numNodes; j++)
+ {
+ if (endNode->input.node[j] == startNode)
+ {
+ endNode->input.isEnabled[j] = mode;
+ break;
+ }
+ }
+ if (j == endNode->input.numNodes)
+ {
+ retVal = FVID2_EFAIL;
+ }
+ }
+ }
+ else if (FVID2_GRAPH_NT_IN_MULTI == endNode->inType)
+ {
+ for (j = 0; j < endNode->input.numNodes; j++)
+ {
+ if (endNode->input.node[j] == startNode)
+ {
+ endNode->input.isEnabled[j] = mode;
+ break;
+ }
+ }
+ if (j == endNode->input.numNodes)
+ {
+ retVal = FVID2_EFAIL;
+ }
+ }
+ else
+ {
+ /*Do nothing */
+ }
+ }
+
+ return retVal;
+}
+
+/**
+ * findPath()
+ */
+/**
+ * Inputs
+ * PORTA/B_08/16/24
+ * isCSCEnabled
+ * isSCEnabled
+ */
+/**
+ * Algo:
+ * Decide FirstNode
+ * Decide LastNodes
+ * curNode = FirstNode
+ * if(isCSCEnabled) {join curNode to CSC; curNode = CSC}
+ * if(isSCEnabled) {join curNode to SC; curNode = SC}
+ * foreach(LastNode_option1, LastNode_option2)
+ * {
+ * join curNode to LastNode
+ * if (successful) break
+ * else next
+ * }
+ */
+
+/** \brief This function gets a list of valid nodes in an edge list and
+ * also enable the input in each entry. Fill in VpsCore_VipPathObj
+ *
+ * Should be called only after Fvid2_graphAllocNodes() is successful
+ *
+ * TODO: Connections should be made in this function and not copied from
+ * main graph (as is done currently) since this will fail for multiple handle
+ * scenarios.
+ */
+int32_t Fvid2_graphGetPath(const Fvid2_GraphNodeInfoList *inNodeList,
+ const Fvid2_GraphEdgeInfoList *inEdgeList,
+ Fvid2_GraphNodeInfoList *outNodeList,
+ Fvid2_GraphEdgeInfoList *outEdgeList,
+ uint32_t maxOutNodeCnt,
+ uint32_t maxOutEdgeCnt)
+{
+ uint32_t i, j;
+ uint32_t pathEdgeCount = inEdgeList->numEdges;
+ uint32_t pathNodeCount = 0;
+ uint32_t numInNodes = inNodeList->numNodes;
+ uint32_t nodes[FVID2_GRAPH_MAX_NODES] = {0};
+
+ for (i = 0; i < inEdgeList->numEdges; i++)
+ {
+ j = inEdgeList->list[i].startNode;
+ nodes[j] = 1U;
+ j = inEdgeList->list[i].endNode;
+ nodes[j] = 1U;
+ }
+
+ for (i = 0; i < numInNodes; i++)
+ {
+ if (nodes[i] == 1U)
+ {
+ pathNodeCount++;
+ }
+ }
+
+ GT_assert(Fvid2Trace, (pathNodeCount < maxOutNodeCnt));
+ outNodeList->numNodes = pathNodeCount;
+
+ GT_assert(Fvid2Trace, (outNodeList->list != NULL));
+
+ GT_assert(Fvid2Trace, (pathEdgeCount < maxOutEdgeCnt));
+ outEdgeList->numEdges = pathEdgeCount;
+ GT_assert(Fvid2Trace, (outEdgeList->list != NULL));
+
+ for (i = 0; i < pathEdgeCount; i++)
+ {
+ outEdgeList->list[i].startNode =
+ inEdgeList->list[i].startNode;
+ outEdgeList->list[i].endNode =
+ inEdgeList->list[i].endNode;
+ }
+
+ j = 0;
+ for (i = 0; i < numInNodes; i++)
+ {
+ if (nodes[i] == 1U)
+ {
+ Fvid2Utils_memcpy((void *) &outNodeList->list[j],
+ (void *) &inNodeList->list[i],
+ sizeof (Fvid2_GraphNodeInfo));
+
+ /* Reset connection info from the original graph */
+ Fvid2Utils_memset((void *) (outNodeList->list[j].input.node), 0,
+ sizeof (Fvid2_GraphNodeInfo *) * FVID2_GRAPH_MAX_NUM_PATHS);
+ Fvid2Utils_memset((void *) (outNodeList->list[j].output.node), 0,
+ sizeof (Fvid2_GraphNodeInfo *) * FVID2_GRAPH_MAX_NUM_PATHS);
+ j++;
+ }
+ }
+
+ return FVID2_SOK;
+}
+
+int32_t Fvid2_graphFreePath(Fvid2_GraphNodeInfoList *nodeList,
+ Fvid2_GraphEdgeInfoList *edgeList)
+{
+ if (NULL != nodeList->list)
+ {
+ nodeList->numNodes = 0;
+ nodeList->list = NULL;
+ }
+ if (NULL != edgeList->list)
+ {
+ edgeList->numEdges = 0;
+ edgeList->list = NULL;
+ }
+ return FVID2_SOK;
+}
+
+void Fvid2_graphInitTraverser(Fvid2_GraphNodeInfo *node)
+{
+ /* Initialize Stack */
+ Fvid2_graphStackReset();
+
+ /* Push root node onto stack */
+ Fvid2_graphStackPush(node);
+}
+
+static void Fvid2_graphStackReset(void)
+{
+ Fvid2Utils_memset(&gFvid2GraphNodeStack, 0, sizeof (gFvid2GraphNodeStack));
+ gFvid2GraphNodeStack.top = (-(int32_t)1);
+
+ /* Initialize All stack numbers with -1 */
+ Fvid2Utils_memset(gFvid2GraphNodeStack.stNum, 0, sizeof (uint32_t) * FVID2_GRAPH_MAX_NODES);
+ Fvid2Utils_memset(gFvid2GraphNodeStack.isVisited, 0, sizeof (FVID2_GRAPH_MAX_NODES));
+}
+
+/* Push a node on the stack */
+static void Fvid2_graphStackPush(Fvid2_GraphNodeInfo *node)
+{
+ gFvid2GraphNodeStack.top++;
+ gFvid2GraphNodeStack.node[gFvid2GraphNodeStack.top] = node;
+}
+
+/* Remove top node from the stack */
+static void Fvid2_graphStackPop(void)
+{
+ /* Remove the node from the stack */
+ gFvid2GraphNodeStack.stNum[gFvid2GraphNodeStack.top] = 0;
+ gFvid2GraphNodeStack.node[gFvid2GraphNodeStack.top] = NULL;
+ gFvid2GraphNodeStack.top--;
+}
+
+static uint32_t Fvid2_graphStackIsVisited(const Fvid2_GraphNodeInfo *node)
+{
+ uint32_t visited = TRUE;
+
+ if (0 == gFvid2GraphNodeStack.isVisited[node->nodeNum])
+ {
+ visited = FALSE;
+ }
+
+ return (visited);
+}
+
+int32_t Fvid2_graphStackIsLastNode(const Fvid2_GraphNodeInfo *currNode,
+ uint32_t isForward)
+{
+ int32_t ret = (int32_t) TRUE;
+
+ if (((TRUE == isForward) && (0 != currNode->output.numNodes)) ||
+ ((FALSE == isForward) && (0 != currNode->input.numNodes)))
+ {
+ ret = (int32_t) FALSE;
+ }
+
+ return (ret);
+}
+
+/* Function to get the next enabled node for the currNode */
+Fvid2_GraphNodeInfo *Fvid2_graphGetNextChildNode(
+ const Fvid2_GraphNodeInfo *currNode,
+ uint32_t isForward)
+{
+ Fvid2_GraphNodeInfo *node = NULL;
+ uint32_t isEnabled = TRUE;
+ uint32_t nodeNum, nextNodeNum;
+ uint32_t loopEnd = 1U;
+
+ nodeNum = gFvid2GraphNodeStack.top;
+ nextNodeNum = (uint32_t) gFvid2GraphNodeStack.stNum[nodeNum];
+ do
+ {
+ /* Traversing from input Node to Venc Nodes */
+ if (TRUE == isForward)
+ {
+ /* Get the next node from the output nodes */
+ if (nextNodeNum < currNode->output.numNodes)
+ {
+ node = currNode->output.node[nextNodeNum];
+ isEnabled = currNode->output.isEnabled[nextNodeNum];
+ }
+ else
+ {
+ loopEnd = 0;
+ }
+ }
+ else /* Traversing from Venc Nodes to input node */
+ {
+ /* Get the next node from the input nodes */
+ if (nextNodeNum < currNode->input.numNodes)
+ {
+ node = currNode->input.node[(nextNodeNum)];
+ isEnabled = currNode->input.isEnabled[nextNodeNum];
+ }
+ else
+ {
+ loopEnd = 0;
+ }
+ }
+ if (0U == loopEnd)
+ {
+ break;
+ }
+ nextNodeNum += 1U;
+ } while (FALSE == isEnabled);
+
+ if (FALSE == isEnabled)
+ {
+ node = NULL;
+ }
+ else
+ {
+ gFvid2GraphNodeStack.stNum[nodeNum] = (int32_t) nextNodeNum;
+ }
+ return (node);
+}
+
+/* Get the top node on the stack */
+Fvid2_GraphNodeInfo *Fvid2_graphStackPeak(uint32_t *stNum)
+{
+ *stNum = (uint32_t) gFvid2GraphNodeStack.stNum[gFvid2GraphNodeStack.top];
+ return (gFvid2GraphNodeStack.node[gFvid2GraphNodeStack.top]);
+}
+
+Fvid2_GraphNodeInfo *Fvid2_graphGetNextNodeToTraverse(uint32_t isForward)
+{
+ uint32_t nodeNum;
+ Fvid2_GraphNodeInfo *currNode = NULL, *nextNode = NULL;
+
+ while (gFvid2GraphNodeStack.top > (-(int32_t)1))
+ {
+ /* Get the stack top node */
+ currNode = Fvid2_graphStackPeak(&nodeNum);
+
+ if (FALSE == Fvid2_graphStackIsVisited(currNode))
+ {
+ /* If current node is ot visited, return it to the caller. */
+ break;
+ }
+ else
+ {
+ /* Get the Next Node */
+ nextNode = Fvid2_graphGetNextChildNode(currNode, isForward);
+
+ /* If next node is not null, push it onto stack so that it can
+ * be traversed */
+ if (NULL != nextNode)
+ {
+ /* Push the start node onto stack */
+ Fvid2_graphStackPush(nextNode);
+ }
+ else
+ {
+ /* Remove the node from the stack */
+ Fvid2_graphStackPop();
+ }
+ }
+ }
+ if ((-(int32_t)1) == gFvid2GraphNodeStack.top)
+ {
+ currNode = NULL;
+ }
+
+ if (NULL != currNode)
+ {
+ nodeNum = currNode->nodeNum;
+ gFvid2GraphNodeStack.isVisited[nodeNum] = (uint8_t) 1;
+ }
+
+ return (currNode);
+}
+
+int32_t Fvid2_graphGetEnabledIndex(const uint32_t *array, uint32_t size)
+{
+ uint32_t i;
+ int32_t retVal = FVID2_EFAIL;
+
+ for (i = 0; i < size; i++)
+ {
+ if ((uint32_t) 0 != array[i])
+ {
+ retVal = (int32_t) i;
+ break;
+ }
+ }
+ return retVal;
+}
+
+void Fvid2_graphAddEdge(Fvid2_GraphEdgeInfo *edge,
+ uint32_t startNode,
+ uint32_t endNode)
+{
+ if (startNode != endNode)
+ {
+ edge->startNode = startNode;
+ edge->endNode = endNode;
+ }
+}
+
diff --git a/src/makefile b/src/makefile
--- a/src/makefile
+++ b/src/makefile
# Common source files and CFLAGS across all platforms and cores
PACKAGE_SRCS_COMMON = .
-SRCS_COMMON += fvid2_drvMgr.c fvid2_utils.c
+SRCS_COMMON += fvid2_drvMgr.c fvid2_utils.c fvid2_graph.c
CFLAGS_LOCAL_COMMON = $(PDK_CFLAGS)
PACKAGE_SRCS_COMMON = fvid2.h fvid2_component.mk include src