]> sjero.net Git - linphone/blob - media_api/mediaflow.c
e0e6be4036c13142a813bfbebd50f99227e15f21
[linphone] / media_api / mediaflow.c
1 /*\r
2         The objective of the media_api is to construct and run the necessary processing \r
3         on audio and video data flows for a given call (two party call) or conference.\r
4         Copyright (C) 2001  Sharath Udupa skuds@gmx.net\r
5 \r
6         This library is free software; you can redistribute it and/or\r
7         modify it under the terms of the GNU Lesser General Public\r
8         License as published by the Free Software Foundation; either\r
9         version 2.1 of the License, or (at your option) any later version.\r
10 \r
11         This library is distributed in the hope that it will be useful,\r
12         but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
14         Lesser General Public License for more details.\r
15 \r
16         You should have received a copy of the GNU Lesser General Public\r
17         License along with this library; if not, write to the Free Software\r
18         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19 */\r
20 #include "common.h"\r
21 #include "mediaflow.h"\r
22 #include "callmember.h"\r
23 \r
24 \r
25 MediaFlow *media_flow_new(char *id_string, int type){\r
26   MediaFlow *flow = (MediaFlow *) g_malloc(sizeof(MediaFlow));  //malloc required?\r
27   api_trace("media_flow_new: creating %s",id_string);\r
28   flow->id = id_string;\r
29   flow->type = type;\r
30   flow->flowDirections = NULL;\r
31   flow->members = NULL;\r
32   return flow;\r
33 }\r
34 \r
35 int media_flow_destroy(MediaFlow *flow){\r
36         g_free(flow);\r
37         return 1;\r
38 }\r
39 \r
40 int media_flow_setup_fd(MediaFlow *flow, CallMember* csource, CallMember *cdestination, int direction){\r
41         GList *source, *destination;\r
42         char *dir;\r
43         FlowDirections *fd = (FlowDirections *) g_malloc(sizeof(FlowDirections));\r
44         if(direction == MEDIA_FLOW_DUPLEX) dir = "DUPLEX";\r
45         else if(direction == MEDIA_FLOW_HALF_DUPLEX) dir = "HALF_DUPLEX";\r
46         api_trace("media_flow_setup_fd: setting up %s flow for %s , %s",dir, csource->name, cdestination->name);\r
47         source = g_list_find_custom(flow->members, csource, &find);\r
48         destination =g_list_find_custom(flow->members, cdestination, &find);\r
49         if(source == NULL){\r
50                 api_error("media_flow_setup_fd: Invalid source %s specified", csource->name);\r
51         }\r
52         if(destination == NULL){\r
53                 api_error("media_flow_setup_fd: Invalid destination %s specified", cdestination->name);\r
54                 //ERROR handling to be done here\r
55         }\r
56         fd->source = (Members*)source->data;\r
57         fd->destination = (Members*)destination->data;\r
58         fd->type = direction;\r
59         flow->flowDirections = g_list_append(flow->flowDirections, fd);\r
60         return 1;\r
61 }\r
62 \r
63 int find(gconstpointer mem, gconstpointer cmember){\r
64         if(!strcmp(((Members*)mem)->member->name, ((CallMember*)cmember)->name)){\r
65                 return 0;\r
66         }\r
67         return 1;\r
68 }\r
69 \r
70 int media_flow_start_fd(FlowDirections *fd, MSSync *sync){\r
71         Members *source, *destination;\r
72         source = fd->source;\r
73         destination = fd->destination;\r
74         if(fd->type == MEDIA_FLOW_DUPLEX){\r
75                 fd->recv = set_MSFilter(source->tx_endpoint,1,fd);\r
76                 fd->dec = set_CODECFilter(source->member->profile, source->tx_endpoint->pt,MEDIA_API_DECODER);\r
77                 fd->play = set_MSFilter(destination->rx_endpoint,0,fd);\r
78                 \r
79                 ms_filter_add_link(fd->recv,fd->dec);\r
80                 ms_filter_add_link(fd->dec,fd->play);\r
81                 ms_sync_attach(sync, fd->recv);\r
82                 \r
83                 fd->read = set_MSFilter(destination->tx_endpoint,1,fd);\r
84                 fd->enc = set_CODECFilter(destination->member->profile, destination->tx_endpoint->pt,MEDIA_API_ENCODER);\r
85                 fd->send = set_MSFilter(source->rx_endpoint,0,fd);\r
86                 \r
87                 ms_filter_add_link(fd->read, fd->enc);\r
88                 ms_filter_add_link(fd->enc, fd->send);\r
89                 ms_sync_attach(sync, fd->read);\r
90                 \r
91         }\r
92         else if(fd->type == MEDIA_FLOW_HALF_DUPLEX){\r
93         \r
94                 fd->recv = set_MSFilter(source->tx_endpoint,1,fd);\r
95                 fd->dec = set_CODECFilter(sourcec->member->profile, source->tx_endpoint->pt,MEDIA_API_DECODER);\r
96                 fd->play = set_MSFilter(destination->rx_endpoint,0,fd);\r
97                 \r
98                 ms_filter_add_link(fd->recv,fd->dec);\r
99                 ms_filter_add_link(fd->dec,fd->play);\r
100                 ms_sync_attach(sync, fd->recv); \r
101         }\r
102         return 1;\r
103 }\r
104 \r
105 \r
106 MSFilter *set_MSFilter(EndPoint *endpoint, int type, FlowDirections *fdir){\r
107         MSFilter *filter;\r
108         RtpSession *rtps;\r
109         switch(endpoint->protocol){\r
110                 case MEDIA_RTP:\r
111                         rtps = rtp_session_new(RTP_SESSION_RECVONLY);\r
112                         rtp_session_set_local_addr(rtps,"0.0.0.0",8000,8001);\r
113                         rtp_session_set_scheduling_mode(rtps,0);\r
114                         rtp_session_set_blocking_mode(rtps,0);\r
115                         \r
116                         if(type == 1){\r
117                                 filter = ms_rtp_recv_new();\r
118                                 ms_rtp_recv_set_session(MS_RTP_RECV(filter), rtps);\r
119                                 fdir->rtpSessions = g_list_append(fdir->rtpSessions, rtps);\r
120                                 return filter;\r
121                         }\r
122                         else{\r
123                                 //ms_rtp_send_new\r
124                         }\r
125                 case MEDIA_OSS:\r
126                         if(type == 1){\r
127                                 filter = ms_oss_read_new();\r
128                                 ms_sound_read_set_device(MS_SOUND_READ(filter),0);\r
129                                 return filter;\r
130                         }\r
131                         else{\r
132                                 filter = ms_oss_write_new();\r
133                                 ms_sound_write_set_device(MS_SOUND_WRITE(filter),0);\r
134                                 return filter;\r
135                         }\r
136                 case MEDIA_FILE:\r
137                         if(type == 1){\r
138                                 filter = ms_read_new(endpoint->file);\r
139                                 return filter;\r
140                         }\r
141                         if(type == 0){\r
142                                 filter = ms_write_new(endpoint->file);\r
143                                 return filter;\r
144                         }\r
145 \r
146         }\r
147 }\r
148 \r
149 MSFilter *set_CODECFilter(RtpProfile *profile, int pt, int mode){\r
150         PayloadType *payload;\r
151         \r
152         switch(mode){\r
153                 case MEDIA_API_DECODER: \r
154                         payload = rtp_profile_get_payload(profile, pt);\r
155                         if(payload == NULL){\r
156                                 api_error("media_api: undefined payload in URL\n");\r
157                                 return NULL;\r
158                         }\r
159                         return ms_decoder_new_with_string_id(payload->mime_type);\r
160                         \r
161                         //Commented this to include the new RtpProfile\r
162                         /*if(pt != -1) return ms_decoder_new_with_pt(pt);\r
163                          *else return ms_copy_new();\r
164                          */\r
165                 case MEDIA_API_ENCODER: \r
166                         \r
167                         payload = rtp_profile_get_payload(profile, pt);\r
168                         if(payload == NULL){\r
169                                 api_error("media_api: undefined payload in URL\n");\r
170                                 return NULL;\r
171                         }\r
172                         return ms_encoder_new_with_string_id(payload->mime_type);\r
173                         /*if(pt != -1) return ms_encoder_new_with_pt(pt);\r
174                          *else return ms_copy_new();\r
175                          */\r
176         }\r
177 }\r
178         \r
179 \r