xuxiuxi
2017-05-11 109ffe9a777658936a38d0c146579a67c60a0d17
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
#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"
 
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<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;
};
 
#endif