1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * Copyright 2020 Rockchip Electronics Co. LTD 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * Licensed under the Apache License, Version 2.0 (the "License"); 5*4882a593Smuzhiyun * you may not use this file except in compliance with the License. 6*4882a593Smuzhiyun * You may obtain a copy of the License at 7*4882a593Smuzhiyun * 8*4882a593Smuzhiyun * http://www.apache.org/licenses/LICENSE-2.0 9*4882a593Smuzhiyun * 10*4882a593Smuzhiyun * Unless required by applicable law or agreed to in writing, software 11*4882a593Smuzhiyun * distributed under the License is distributed on an "AS IS" BASIS, 12*4882a593Smuzhiyun * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*4882a593Smuzhiyun * See the License for the specific language governing permissions and 14*4882a593Smuzhiyun * limitations under the License. 15*4882a593Smuzhiyun * 16*4882a593Smuzhiyun */ 17*4882a593Smuzhiyun #ifndef SRC_RT_TASK_TASK_GRAPH_RTTASKNODEBASE_H_ 18*4882a593Smuzhiyun #define SRC_RT_TASK_TASK_GRAPH_RTTASKNODEBASE_H_ 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun #include "string.h" 21*4882a593Smuzhiyun #include <map> 22*4882a593Smuzhiyun #include <functional> 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun #include "rt_header.h" 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun #include "RTTaskNodeContext.h" 27*4882a593Smuzhiyun #include "RTTaskNodeContextManager.h" 28*4882a593Smuzhiyun #include "RTTaskNodeOptions.h" 29*4882a593Smuzhiyun #include "RTTaskNodeFactory.h" 30*4882a593Smuzhiyun #include "RTNodeCommon.h" 31*4882a593Smuzhiyun #include "RTStreamInfo.h" 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun typedef struct _RTTaskNodeInfo { 34*4882a593Smuzhiyun INT32 nodeId; 35*4882a593Smuzhiyun std::string nodeName; 36*4882a593Smuzhiyun } RTTaskNodeInfo; 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun class RTBufferListener; 39*4882a593Smuzhiyun class RTInputStreamHandler; 40*4882a593Smuzhiyun class RTInputStreamManager; 41*4882a593Smuzhiyun class RTOutputStreamHandler; 42*4882a593Smuzhiyun class RTOutputStreamManager; 43*4882a593Smuzhiyun class RTSchedulerQueue; 44*4882a593Smuzhiyun class RTMediaBufferPool; 45*4882a593Smuzhiyun class RTTaskNodeStat; 46*4882a593Smuzhiyun class RTTaskNodeBase { 47*4882a593Smuzhiyun public: 48*4882a593Smuzhiyun RTTaskNodeBase(); 49*4882a593Smuzhiyun virtual ~RTTaskNodeBase(); 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun RT_RET prepareForRun(RtMetaData* options, 52*4882a593Smuzhiyun std::function<void()> sourceNodeOpenedCallback, 53*4882a593Smuzhiyun std::function<void(RTTaskNodeContext *)> scheduleCallback); 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun RT_RET cleanupAfterRun(); getID()56*4882a593Smuzhiyun INT32 getID() { return mNodeId; } getOptions()57*4882a593Smuzhiyun RtMetaData* getOptions() { return mOptions; } 58*4882a593Smuzhiyun RT_BOOL isSource() const; 59*4882a593Smuzhiyun RT_BOOL isSink() const; 60*4882a593Smuzhiyun RT_BOOL hasMirror(RT_BOOL nodeOnly = RT_FALSE) const; 61*4882a593Smuzhiyun INT32 numInputStreams() const; 62*4882a593Smuzhiyun INT32 numOutputStreams() const; 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun RT_RET processNode(RTTaskNodeContext *packet); 65*4882a593Smuzhiyun void nodeOpened(); 66*4882a593Smuzhiyun bool closed(); 67*4882a593Smuzhiyun RT_RET flush(); 68*4882a593Smuzhiyun RT_RET reset(); 69*4882a593Smuzhiyun RT_BOOL isDone(); 70*4882a593Smuzhiyun RT_RET closeNode(); 71*4882a593Smuzhiyun RT_RET closeInputStreams(); 72*4882a593Smuzhiyun RT_RET closeOutputStreams(); 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun void setMaxInputStreamQueueSize(INT32 maxQueueSize); 75*4882a593Smuzhiyun void setMaxBatchPrcoessSize(INT32 maxBatchSize); 76*4882a593Smuzhiyun void setQueueSizeCallbacks( 77*4882a593Smuzhiyun std::function<void(RTInputStreamManager*, bool*)> becomesFullCallback, 78*4882a593Smuzhiyun std::function<void(RTInputStreamManager*, bool*)> becomesNotFullCallback, 79*4882a593Smuzhiyun std::function<void(RTInputStreamManager*, bool*)> becomesEmptyCallback); 80*4882a593Smuzhiyun initialize(INT32 node_id,RTTaskNodeInfo * nodeInfo)81*4882a593Smuzhiyun RT_RET initialize(INT32 node_id, RTTaskNodeInfo *nodeInfo) { return RT_OK; } 82*4882a593Smuzhiyun RT_RET initialize( 83*4882a593Smuzhiyun INT32 nodeId, 84*4882a593Smuzhiyun RTTaskNodeInfo *nodeInfo, 85*4882a593Smuzhiyun RTInputStreamManager *inputManager, 86*4882a593Smuzhiyun RTOutputStreamManager *outputManager); 87*4882a593Smuzhiyun RT_RET initialize(INT32 nodeId, 88*4882a593Smuzhiyun RTTaskNodeInfo *nodeInfo, 89*4882a593Smuzhiyun const std::vector<RTInputStreamManager *> &inputManagers, 90*4882a593Smuzhiyun const std::vector<RTOutputStreamManager *> &outputManagers); 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun RT_RET addStreamSource( 93*4882a593Smuzhiyun INT32 streamId, RTOutputStreamManager *lastOutputManager); 94*4882a593Smuzhiyun RT_RET addStreamSource(RTOutputStreamManager *lastOutputManager); 95*4882a593Smuzhiyun RT_RET removeStreamSource(RTOutputStreamManager *outputManager); getStreamSource()96*4882a593Smuzhiyun const std::vector<INT32> &getStreamSource() { return mSourceNodes; } 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun void checkIfBecameReady(); 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun RT_BOOL tryToBeginScheduling(); 101*4882a593Smuzhiyun void schedulingLoop(); 102*4882a593Smuzhiyun void endScheduling(); 103*4882a593Smuzhiyun 104*4882a593Smuzhiyun // Returns a pointer to the default calculator context that is used for 105*4882a593Smuzhiyun // sequential execution. A source node should always reuse its default 106*4882a593Smuzhiyun // calculator context. getDefaultNodeContext()107*4882a593Smuzhiyun RTTaskNodeContext* getDefaultNodeContext() const { 108*4882a593Smuzhiyun return mNodeContextManager.getDefaultNodeContext(); 109*4882a593Smuzhiyun } 110*4882a593Smuzhiyun getSchedulerQueue()111*4882a593Smuzhiyun RTSchedulerQueue* getSchedulerQueue() const { 112*4882a593Smuzhiyun return mSchedulerQueue; 113*4882a593Smuzhiyun } 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun // Sets the scheduler queue the node is assigned to. setSchedulerQueue(RTSchedulerQueue * queue)116*4882a593Smuzhiyun void setSchedulerQueue(RTSchedulerQueue* queue) { 117*4882a593Smuzhiyun mSchedulerQueue = queue; 118*4882a593Smuzhiyun } 119*4882a593Smuzhiyun 120*4882a593Smuzhiyun RT_RET sendInterrupt(std::string reason); 121*4882a593Smuzhiyun RT_RET cancelInterrupt(std::string reason); 122*4882a593Smuzhiyun RT_RET dump(); 123*4882a593Smuzhiyun 124*4882a593Smuzhiyun RT_RET attachOutStreamPool(RTMediaBufferPool *pool, std::string streamType = RT_NONE); 125*4882a593Smuzhiyun RT_RET detachOutStreamPool(std::string streamType = RT_NONE); 126*4882a593Smuzhiyun 127*4882a593Smuzhiyun void setComponentUid(INT32 componentUid); 128*4882a593Smuzhiyun INT32 getComponentUid(); 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun public: 131*4882a593Smuzhiyun virtual RT_RET open(RTTaskNodeContext *context) = 0; 132*4882a593Smuzhiyun virtual RT_RET process(RTTaskNodeContext *context) = 0; 133*4882a593Smuzhiyun virtual RT_RET close(RTTaskNodeContext *context) = 0; 134*4882a593Smuzhiyun virtual RT_RET invoke(RtMetaData *meta); 135*4882a593Smuzhiyun virtual RT_RET queryStat(RTTaskNodeStat *stat); queryStatInternal(RTTaskNodeStat * nodeStat)136*4882a593Smuzhiyun virtual RT_RET queryStatInternal(RTTaskNodeStat *nodeStat) { return RT_ERR_UNSUPPORT; } 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun protected: initSupportOptions()139*4882a593Smuzhiyun virtual RT_RET initSupportOptions() { return RT_OK; } invokeInternal(RtMetaData * meta)140*4882a593Smuzhiyun virtual RT_RET invokeInternal(RtMetaData *meta) { return RT_ERR_UNSUPPORT; } 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun private: 143*4882a593Smuzhiyun RT_RET addInputStreams(RTInputStreamManager *inputManager); 144*4882a593Smuzhiyun RT_RET addOutputStreams(RTOutputStreamManager *outputManager); 145*4882a593Smuzhiyun RT_RET prepareOptionsForRun(); 146*4882a593Smuzhiyun RT_RET processPassThrough(RTTaskNodeContext *nodeContext); 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun protected: 149*4882a593Smuzhiyun INT32 mNodeId; 150*4882a593Smuzhiyun RTInputStreamHandler *mInputHandler; 151*4882a593Smuzhiyun RTOutputStreamHandler *mOutputHandler; 152*4882a593Smuzhiyun 153*4882a593Smuzhiyun RtMutex mMutex; 154*4882a593Smuzhiyun 155*4882a593Smuzhiyun INT32 mCurrentInScheduling = 0; 156*4882a593Smuzhiyun INT32 mMaxInScheduling = 1; 157*4882a593Smuzhiyun // SchedulingState incidates the current state of the node scheduling process. 158*4882a593Smuzhiyun // There are four possible transitions: 159*4882a593Smuzhiyun // (a) From kIdle to kScheduling. 160*4882a593Smuzhiyun // Any thread that makes this transition becomes the scheduling thread and 161*4882a593Smuzhiyun // will be responsible for preparing and scheduling all possible invocations. 162*4882a593Smuzhiyun // (b) From kScheduling to kSchedulingPending. 163*4882a593Smuzhiyun // Any thread, except the scheduling thread, can make this transition. 164*4882a593Smuzhiyun // kSchedulingPending indicates that some recent changes require the 165*4882a593Smuzhiyun // scheduling thread to recheck the node readiness after current scheduling 166*4882a593Smuzhiyun // iteration. 167*4882a593Smuzhiyun // (c) From kSchedulingPending to kScheduling. 168*4882a593Smuzhiyun // Made by the scheduling thread to indicate that it has already caught up 169*4882a593Smuzhiyun // with all the recent changes that can affect node readiness. 170*4882a593Smuzhiyun // (d) From kScheduling to kIdle. Made by the scheduling thread when there is 171*4882a593Smuzhiyun // no more scheduling work to be done. 172*4882a593Smuzhiyun enum RTSchedulingState { 173*4882a593Smuzhiyun kIdle = 0, // 174*4882a593Smuzhiyun kScheduling = 1, // 175*4882a593Smuzhiyun kSchedulingPending = 2 176*4882a593Smuzhiyun }; 177*4882a593Smuzhiyun RTSchedulingState mSchedulingState = kIdle; 178*4882a593Smuzhiyun RTTaskNodeContextManager mNodeContextManager; 179*4882a593Smuzhiyun RtMetaData *mOptions; 180*4882a593Smuzhiyun std::function<void()> mSourceNodeOpenedCallback; 181*4882a593Smuzhiyun // The status of the current Calculator that this CalculatorNode 182*4882a593Smuzhiyun // is wrapping. kStateActive is currently used only for source nodes. 183*4882a593Smuzhiyun enum RTNodeStatus { 184*4882a593Smuzhiyun kStateUninitialized = 0, 185*4882a593Smuzhiyun kStatePrepared = 1, 186*4882a593Smuzhiyun kStateOpened = 2, 187*4882a593Smuzhiyun kStateActive = 3, 188*4882a593Smuzhiyun kStateClosed = 4 189*4882a593Smuzhiyun }; 190*4882a593Smuzhiyun RTNodeStatus mStatus = kStateUninitialized; 191*4882a593Smuzhiyun RTSchedulerQueue *mSchedulerQueue = NULL; 192*4882a593Smuzhiyun std::map<std::string/* name */, RTTaskNodeOption> mSupportOptions; 193*4882a593Smuzhiyun std::vector<INT32> mSourceNodes; 194*4882a593Smuzhiyun std::vector<RTStreamInfo *> mInputStreamInfos; 195*4882a593Smuzhiyun std::vector<RTStreamInfo *> mOutputStreamInfos; 196*4882a593Smuzhiyun RT_BOOL mIsPassThrough; 197*4882a593Smuzhiyun RtReference *mProcRef; 198*4882a593Smuzhiyun INT32 mComponentUid; 199*4882a593Smuzhiyun }; 200*4882a593Smuzhiyun 201*4882a593Smuzhiyun #endif // SRC_RT_TASK_TASK_GRAPH_RTTASKNODEBASE_H_ 202