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
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
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
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
21 #include "basiccall.h"
\r
22 #include "../mediastreamer/mscodec.h"
\r
25 #define MULTISYNC 20
\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
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
40 else if(member_nu == MemberB){
\r
41 return call->memberB;
\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
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
59 int basic_call_start_flow(BasicCall *call, MediaFlow *flow){
\r
62 int nFlowDirections;
\r
64 Members *source, *destination;
\r
66 GList *elem, *selem;
\r
67 GList *snd_read = NULL, *snd_write = NULL, *filter = NULL;
\r
69 //Commented by Sharat
\r
70 //This is initialized in media_api.c
\r
71 //when should these functions be really called?
\r
75 api_trace("basic_call_start_flow: called for flow %s", flow->id);
\r
77 elem = g_list_find_custom( call->flows, flow, &find_mediaflow);
\r
79 api_error("basic_call_start_flow: Called for unregistered mediaflow %s", flow->id);
\r
82 nFlowDirections = g_list_length(flow->flowDirections);
\r
83 if(flow->type == MEDIA_FLOW_VOICE){
\r
85 sync = ms_timer_new();
\r
88 syncFlag = MULTISYNC;
\r
91 for(i=0;i< nFlowDirections; i++){
\r
93 if(syncFlag == MULTISYNC){
\r
94 sync = ms_timer_new();
\r
96 fd = (FlowDirections*)g_list_nth_data(flow->flowDirections,i);
\r
97 source = fd->source;
\r
98 destination = fd->destination;
\r
100 media_flow_start_fd(fd, sync);
\r
101 if(fd->type == MEDIA_FLOW_DUPLEX){
\r
102 switch(source->tx_endpoint->protocol){
\r
105 snd_read = g_list_append(snd_read, fd->recv);
\r
107 switch(destination->rx_endpoint->protocol){
\r
110 snd_write = g_list_append(snd_write, fd->play);
\r
113 switch(destination->tx_endpoint->protocol){
\r
116 snd_read = g_list_append(snd_read, fd->read);
\r
119 switch(source->rx_endpoint->protocol){
\r
122 snd_write = g_list_append(snd_write, fd->send);
\r
126 else if(fd->type == MEDIA_FLOW_HALF_DUPLEX){
\r
128 switch(source->tx_endpoint->protocol){
\r
131 snd_read = g_list_append(snd_read, fd->recv);
\r
133 switch(destination->rx_endpoint->protocol){
\r
136 snd_write = g_list_append(snd_write, fd->play);
\r
139 if(syncFlag == MULTISYNC){
\r
140 flow->sync = g_list_append(flow->sync, sync);
\r
143 if(syncFlag == ONESYNC){
\r
145 flow->sync = g_list_append(flow->sync, sync);
\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
155 while(filter != NULL){
\r
156 ms_sound_read_start(MS_SOUND_READ((MSFilter*)filter->data));
\r
157 filter = g_list_next(filter);
\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
168 int basic_call_stop_flow(BasicCall *call, MediaFlow *flow){
\r