#ifndef _PIPELINE_H_ #define _PIPELINE_H_ #include #include #include #include #define PLGP_RTSP_SDP "RTSP_SDP" #define PLGP_RTSP_FMTP "RTSP_FMTP" #define PLGP_RTSP_WIDTH "RTSP_WIDTH" #define PLGP_RTSP_HEIGHT "RTSP_HEIGHT" #define PLGP_RTSP_FPS "RTSP_FPS" #define PLGP_DEC_SPS_B64 "DEC_SPS_B64" #define PLGP_DEC_PPS_B64 "DEC_PPS_B64" #define PLGP_ENC_SPS_B64 "ENC_SPS_B64" #define PLGP_ENC_PPS_B64 "ENC_PPS_B64" #define ENABLE_PIPELINE_ELEM_TIMING_DEBUGGER class PipeLineElem; class PipeLine; struct PipeMaterial; typedef void (* pm_deleter_func)(PipeMaterial* pm, bool lastRet); typedef bool (* pm_breaker_func)(const PipeMaterial* pm, void* args); // return true if continue breaking up // PipeMaterial instance should be unref when pay() finished struct PipeMaterial { enum PipeMaterialBufferType { PMT__FIRST, PMT_NONE, // buffer = nullptr, buffSize = 0 PMT_BYTES, // buffer = uint8_t[N], buffSize = N PMT_PTR, // buffer = void*, buffSize = 0 PMT_FRAME, // buffer = MB_Frame*, buffSize = 0 PMT_PM_LIST, // buffer = PipeMaterial*[N], buffSize = N PMT_FRAME_LIST, // buffer = MB_Frame*[N], buffSize = N PMT__LAST }; PipeMaterialBufferType type; void* buffer; size_t buffSize; PipeLineElem* former; pm_deleter_func deleter; void* args; PipeMaterial(); void exec_deleter(bool lastRet); void reset() { PipeMaterial _temp; *this = _temp; } int breake(PipeMaterialBufferType selectPmType, int _selectMbfType, pm_breaker_func breaker, void* args = nullptr) const; int breake(int _selectMbfUsage, pm_breaker_func breaker, void* args = nullptr) const; //#todo assemble pm/mbf into this pm void assemble(); }; class PipeLineElem { public: PipeLineElem() : manager(nullptr) { } virtual ~PipeLineElem() { } virtual bool init(void* args) = 0; virtual void finit() = 0; // buffer: delete it who create it virtual bool pay(const PipeMaterial& pm) = 0; virtual bool gain(PipeMaterial& pm) = 0; public: PipeLine* manager; }; typedef PipeLineElem* (*elem_create_func_t)(); typedef void (*elem_destory_func_t)(PipeLineElem* elem); // 0 (there is no elem). do nothing // 1 (there is one elem). gain --> pm.deleter // 2 (there is two elems). gain --> pay --> pm.deleter // 3 (there is more than two elems). // gain --> [pay --> pm.deleter --> gain -->] [pay --> pm.deleter --> gain -->] ... --> pay --> pm.deleter class PipeLine { friend class PipeDebugger; public: PipeLine(); // stop and delete all managed elements ~PipeLine(); bool register_elem_creator(const std::string& type, elem_create_func_t func); static bool register_global_elem_creator(const std::string& type, elem_create_func_t func); void push_elem(PipeLineElem* elem); PipeLineElem* push_elem(const std::string& type); void push_front_elem(PipeLineElem* elem); bool remove_elem(PipeLineElem* elem); PipeLineElem* at(int idx); void finit(elem_destory_func_t elem_destory_func); bool check_pipe_complete(PipeLineElem* lastRetElem) const; // do pipe sync. returns the element who returns false, or the last one. // if false return, the element should deal with pm, clean up. PipeLineElem* pipe(PipeMaterial* pm = nullptr); void set_param(const std::string& name, const std::string& value); std::string get_param(const std::string& name) const; private: typedef std::map elem_create_func_map_t; elem_create_func_map_t elem_create_func_map; static elem_create_func_map_t global_elem_create_func_map; typedef std::vector elem_vec_t; elem_vec_t elems; typedef std::map params_map_t; params_map_t params_map; }; class PipeLineElemTimingDebugger { public: PipeLineElemTimingDebugger(const PipeLineElem* _elem = nullptr); ~PipeLineElemTimingDebugger(); const PipeLineElem* elem; uint64_t beginTime; }; #endif