summaryrefslogtreecommitdiff
path: root/include/MESA/stream_inc/stream_bridge.h
blob: 3164854c61ea3fb3541ed3d86c653db4dcc96f12 (plain)
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
#ifndef _SAPP_STREAM_BRIDGE_H_
#define _SAPP_STREAM_BRIDGE_H_ 

#ifdef __cplusplus
extern "C" {
#endif

#include <errno.h>


/*****************************************   stream bridge API   *************************************************

   stream_bridge_xxx接口用于在不同插件之间, 创建一个通道, 支持同步和异步两种方式互相通信, 支持多对多的关系.
    
   同步模式采用callback注册方式, 避免直接使用extern声明函数, 动态、灵活、可扩展.
   异步模式是在streaminfo中保留一份数据, 功能同之前的project_req_xxx系列接口.
	
   假设插件plug A,X,Y,Z都注册同一个bridge name:"bridge_demo", bridge_id=1,

   plug A使用异步模式在streaminfo, bridge=1的空间存储了一份数据, receiver X,Y,Z可以在streaminfo生存周期内取数据.
            -------------------
            |   streaminfo    |   plug X
            |-----------------| /
   plug A-->|bridge1 -> data1 |/--plug Y
            |-----------------|\
            |bridge2 -> data2 | \ plug Z
            |-----------------|
            |bridge3 -> data3 |
            -------------------

            
    plugA发送一条同步消息, receiver X,Y,Z都可以依次收到.

        	 -------------------- plug X
             |                  /
    plug A ->|  bridge_id = 1  /--plug Y
             |                 \
             |                  \ plug Z 
             --------------------

*******************************************************************************************************************/


/* 
    bridge_name: 全局唯一, 与之前的project使用不同的命名空间, 可以重名, 
	             但是bridge_id与project_req_id不能通用!!!
	
    rw_mode类似fopen函数的参数, 只支持两个模式:
        "r": 只读,bridge_name不存在则返回错误; 
        "w": bridge_name不存在则创建一个新的bridge, 
             注意, 如果其他插件已经创建了同名bridge, 再次用"w"模式打开, 不能像fopen以截断模式重新打开一个文件, 其实bridge_id是一样的!
             建议先用"r"模式验证是否有无同名bridge; 
        
    返回值是bridge_id, 
        >=0 : success
         <0 : error
*/
int stream_bridge_build(const char *bridge_name, const char *rw_mode);


typedef void stream_bridge_free_cb_t(const struct streaminfo *stream, int bridge_id, void *data);
typedef int  stream_bridge_sync_cb_t(const struct streaminfo *stream, int bridge_id, void *data);


/* 
   注意: free函数最多只能有一个, 后面会覆盖前面的函数指针, 多次重复注册只保留最后一个!
*/
int stream_bridge_register_data_free_cb(int bridge_id, stream_bridge_free_cb_t *free_cb_fun);

/* sync回调函数可以是多个, 调用stream_bridge_sync_data_put()时, 会调用所有注册的callback函数 */
int stream_bridge_register_data_sync_cb(int bridge_id, stream_bridge_sync_cb_t *sync_cb_fun);

/*
    返回值:
        0: 没有stream_bridge_sync_cb_t函数;
        -1: error
        N: 成功调用stream_bridge_sync_cb_t函数的数量;
*/
int   stream_bridge_sync_data_put(const struct streaminfo *stream, int bridge_id, void *data);

/* 等同于之前的project_req_add_xxx, 注意如果data是malloc的内存, 要注册stream_bridge_free_cb_t, streaminfo在close时会自动free */
int   stream_bridge_async_data_put(const struct streaminfo *stream, int bridge_id, void *data); 

/* 
    返回值:
        非NULL: 插件曾经调用stream_bridge_async_data_put()存储的data值.
        NULL  : 此时会产生一种歧义, 如果stream_bridge_async_data_put()就是存了一个空指针, 或者利用C的特性, 存了一个整数0, 
                如何区别是错误还是原始数据就是0?

                如果返回值是NULL的情况下, 插件要再判断一下errno, errno == ENODATA (61), 说明确实没有插件曾经存储过数据, 是个错误. 
*/
void *stream_bridge_async_data_get(const struct streaminfo *stream, int bridge_id);  /* 等同于之前的project_get_xxx */


#ifdef __cplusplus
}
#endif

#endif