xingzilong
2017-08-18 9e5babf9db52e64bdae60137be7696e56241fca6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#ifndef _PIPELINE_H_
#define _PIPELINE_H_
 
#include <string>
#include <stdint.h>
#include <map>
#include <vector>
 
#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<const std::string, elem_create_func_t> 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<PipeLineElem*> elem_vec_t;
    elem_vec_t elems;
 
    typedef std::map<const std::string, std::string> params_map_t;
    params_map_t params_map;
};
 
class PipeLineElemTimingDebugger
{
public:
    PipeLineElemTimingDebugger(const PipeLineElem* _elem = nullptr);
    ~PipeLineElemTimingDebugger();
    
    const PipeLineElem* elem;
    uint64_t beginTime;
};
 
#endif