]> sjero.net Git - linphone/blob - linphone/media_api/basiccall.c
remove mediastreamer2 and add it as a submodule instead.
[linphone] / linphone / media_api / basiccall.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 \r
21 #include "basiccall.h"\r
22 #include "../mediastreamer/mscodec.h"\r
23 \r
24 #define ONESYNC 10\r
25 #define MULTISYNC 20\r
26 \r
27 BasicCall *basic_call_new(){\r
28         BasicCall *bc = (BasicCall*) g_malloc(sizeof(BasicCall));\r
29         api_trace("basic_call_new: creating a basic call");\r
30         bc->memberA = call_member_new("memberA");\r
31         bc->memberB = call_member_new("memberB");\r
32         return bc;\r
33 }\r
34 \r
35 CallMember *basic_call_get_member(BasicCall *call, int member_nu){\r
36         api_trace("basic_call_get_member: called for %d",member_nu);\r
37         if(member_nu == MemberA){\r
38                 return call->memberA;\r
39         }\r
40         else if(member_nu == MemberB){\r
41                 return call->memberB;\r
42         }\r
43 }\r
44 \r
45 void basic_call_add_flow(BasicCall *call, MediaFlow *flow){\r
46         api_trace("basic_call_add_flow: called for %s",flow->id);\r
47         call->flows = g_list_append( call->flows, flow);\r
48         return 1;\r
49 }\r
50 \r
51 int find_mediaflow(gconstpointer llist, gconstpointer flow){\r
52         //MediaFlow *mf = (MediaFlow *) ((BasicCallFlow*)llist)->mediaFlow;\r
53         if(((MediaFlow*)flow)->id == ((MediaFlow*)llist)->id){\r
54                 return 0;\r
55         }\r
56         return 1;\r
57 }\r
58 \r
59 int basic_call_start_flow(BasicCall *call, MediaFlow *flow){\r
60         int i=0;\r
61         int syncFlag=0;\r
62         int nFlowDirections;\r
63         MSSync *sync;\r
64         Members *source, *destination;\r
65         FlowDirections *fd;\r
66         GList *elem, *selem;\r
67         GList *snd_read = NULL, *snd_write = NULL, *filter = NULL;\r
68         \r
69         //Commented by Sharat\r
70         //This is initialized in media_api.c\r
71         //when should these functions be really called?\r
72         //ms_init(); \r
73         //ortp_init(); \r
74         \r
75         api_trace("basic_call_start_flow: called for flow %s", flow->id);\r
76         \r
77         elem = g_list_find_custom( call->flows, flow, &find_mediaflow);\r
78         if(elem == NULL){\r
79                 api_error("basic_call_start_flow: Called for unregistered mediaflow %s", flow->id);\r
80         }\r
81         \r
82         nFlowDirections = g_list_length(flow->flowDirections);\r
83         if(flow->type == MEDIA_FLOW_VOICE){\r
84                 syncFlag = ONESYNC;\r
85                 sync = ms_timer_new();\r
86         }\r
87         else{\r
88                 syncFlag = MULTISYNC;\r
89         }\r
90 \r
91         for(i=0;i< nFlowDirections; i++){\r
92                 \r
93                 if(syncFlag == MULTISYNC){\r
94                         sync = ms_timer_new();\r
95                 }\r
96                 fd = (FlowDirections*)g_list_nth_data(flow->flowDirections,i);\r
97                 source = fd->source;\r
98                 destination = fd->destination;\r
99 \r
100                 media_flow_start_fd(fd, sync);\r
101                 if(fd->type == MEDIA_FLOW_DUPLEX){\r
102                         switch(source->tx_endpoint->protocol){\r
103                                 case MEDIA_ALSA:\r
104                                 case MEDIA_OSS:\r
105                                         snd_read = g_list_append(snd_read, fd->recv);\r
106                         }\r
107                         switch(destination->rx_endpoint->protocol){\r
108                                 case MEDIA_ALSA:\r
109                                 case MEDIA_OSS:\r
110                                         snd_write = g_list_append(snd_write, fd->play);\r
111                         }\r
112                         \r
113                         switch(destination->tx_endpoint->protocol){\r
114                                 case MEDIA_ALSA:\r
115                                 case MEDIA_OSS:\r
116                                         snd_read = g_list_append(snd_read, fd->read);\r
117                         }\r
118                         \r
119                         switch(source->rx_endpoint->protocol){\r
120                                 case MEDIA_ALSA:\r
121                                 case MEDIA_OSS:\r
122                                         snd_write = g_list_append(snd_write, fd->send);\r
123                         }\r
124                         \r
125                 }\r
126                 else if(fd->type == MEDIA_FLOW_HALF_DUPLEX){\r
127                         \r
128                         switch(source->tx_endpoint->protocol){\r
129                                 case MEDIA_ALSA:\r
130                                 case MEDIA_OSS:\r
131                                         snd_read = g_list_append(snd_read, fd->recv);\r
132                         }\r
133                         switch(destination->rx_endpoint->protocol){\r
134                                 case MEDIA_ALSA:\r
135                                 case MEDIA_OSS:\r
136                                         snd_write = g_list_append(snd_write, fd->play);\r
137                         }\r
138                 }\r
139                 if(syncFlag == MULTISYNC){\r
140                         flow->sync = g_list_append(flow->sync, sync);\r
141                 }\r
142         }\r
143         if(syncFlag == ONESYNC){\r
144                 ms_start(sync);\r
145                 flow->sync = g_list_append(flow->sync, sync);\r
146         }\r
147         if(syncFlag == MULTISYNC){\r
148                 selem = flow->sync;\r
149                 while(selem != NULL){\r
150                         ms_start(selem->data);\r
151                         selem = g_list_next(selem);\r
152                 }\r
153         }\r
154         filter = snd_read;\r
155         while(filter != NULL){\r
156                 ms_sound_read_start(MS_SOUND_READ((MSFilter*)filter->data));\r
157                 filter = g_list_next(filter);\r
158         }\r
159 \r
160         filter = snd_write;\r
161         while(filter != NULL){\r
162                 ms_sound_write_start(MS_SOUND_WRITE((MSFilter*)filter->data));\r
163                 filter = g_list_next(filter);\r
164         }\r
165         return 1;\r
166 }\r
167 \r
168 int basic_call_stop_flow(BasicCall *call, MediaFlow *flow){\r
169 \r
170 }\r