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 "mediaflow.h"
\r
22 #include "callmember.h"
\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
30 flow->flowDirections = NULL;
\r
31 flow->members = NULL;
\r
35 int media_flow_destroy(MediaFlow *flow){
\r
40 int media_flow_setup_fd(MediaFlow *flow, CallMember* csource, CallMember *cdestination, int direction){
\r
41 GList *source, *destination;
\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
50 api_error("media_flow_setup_fd: Invalid source %s specified", csource->name);
\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
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
63 int find(gconstpointer mem, gconstpointer cmember){
\r
64 if(!strcmp(((Members*)mem)->member->name, ((CallMember*)cmember)->name)){
\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
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
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
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
92 else if(fd->type == MEDIA_FLOW_HALF_DUPLEX){
\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
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
106 MSFilter *set_MSFilter(EndPoint *endpoint, int type, FlowDirections *fdir){
\r
109 switch(endpoint->protocol){
\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
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
127 filter = ms_oss_read_new();
\r
128 ms_sound_read_set_device(MS_SOUND_READ(filter),0);
\r
132 filter = ms_oss_write_new();
\r
133 ms_sound_write_set_device(MS_SOUND_WRITE(filter),0);
\r
138 filter = ms_read_new(endpoint->file);
\r
142 filter = ms_write_new(endpoint->file);
\r
149 MSFilter *set_CODECFilter(RtpProfile *profile, int pt, int mode){
\r
150 PayloadType *payload;
\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
159 return ms_decoder_new_with_string_id(payload->mime_type);
\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
165 case MEDIA_API_ENCODER:
\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
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