#ifndef _PIPELINE_H_ #define _PIPELINE_H_ #include #include #include #include #define PLGP_RTSP_SDP "RTSP_SDP" #define PLGP_RTSP_FMTP "RTSP_FMTP" class PipeLineElem; class PipeLine; struct PipeMaterial; typedef void (* pm_deleter_func)(PipeMaterial* pm); // 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_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(); }; 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)(); // 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); 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); // do pipe async void pipe_start(); void pipe_notify(PipeLineElem*); void pipe_stop(); 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; }; #endif