mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-22 21:58:08 +00:00
Add java interface for chat.
Add -D for exosip Remove obsolete media_api to avoid confusion
This commit is contained in:
parent
acd370ea93
commit
fd4937409b
17 changed files with 12 additions and 1056 deletions
|
|
@ -59,6 +59,7 @@ LOCAL_CFLAGS += \
|
|||
-DORTP_INET6 \
|
||||
-DINET6 \
|
||||
-DOSIP_MT \
|
||||
-DHAVE_EXOSIP_RESET_TRANSPORTS \
|
||||
-DENABLE_TRACE \
|
||||
-DLINPHONE_VERSION=\"$(LINPHONE_VERSION)\" \
|
||||
-DLINPHONE_PLUGINS_DIR=\"\\tmp\" \
|
||||
|
|
|
|||
|
|
@ -34,6 +34,16 @@ public interface LinphoneChatRoom {
|
|||
* send a message to peer member of this chat room.
|
||||
* @param message to be sent
|
||||
*/
|
||||
void sendMessage(String message);
|
||||
/**
|
||||
* Send a message to peer member of this chat room.
|
||||
* @param chat message
|
||||
*/
|
||||
void sendMessage(LinphoneChatMessage msg, LinphoneChatMessage.StateListener listener);
|
||||
/**
|
||||
* DEPRECATED
|
||||
* @param opaque
|
||||
* @param message
|
||||
*/
|
||||
void sendMessage(Object opaque, String message);
|
||||
|
||||
}
|
||||
|
|
|
|||
3
media_api/.gitignore
vendored
3
media_api/.gitignore
vendored
|
|
@ -1,3 +0,0 @@
|
|||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
MEDIA API DESIGN DRAFT
|
||||
**********************
|
||||
|
||||
|
||||
The objective of the media_api is to construct and run the necessary
|
||||
processing on audio and video data flows for a given call (two party call) or
|
||||
conference.
|
||||
The media_api must support calls where callmember can be remote as well
|
||||
local hosted, in other words the media_api can be used inside linphone as
|
||||
well as in sip conferencing server. The api must support multiples way of
|
||||
getting media data: from disk, from rtp, from soundcard...
|
||||
The media_api is object oriented in C, and is based on the mediastreamer library
|
||||
to deal with audio or video signals, and on glib for types and usefull routines.
|
||||
|
||||
The api must provide object and methods that describes the call, and then functions
|
||||
that executes the processing (using the mediastreamer) that is necessary for the
|
||||
call described.
|
||||
|
||||
Proposed API:
|
||||
|
||||
************************************************************************
|
||||
object: MediaFlow
|
||||
This object reprensent a media that is shared between all members of the call,
|
||||
for example voice.
|
||||
methods:
|
||||
MediaFlow *media_flow_new(char *id_string,gint type,gint duplex);
|
||||
type can be FLOW_AUDIO, FLOW_VIDEO.
|
||||
if duplex is 1, it means that the media flow is used by every member in both
|
||||
receiving and sending mode.
|
||||
id_string is just a string to identify the flow.
|
||||
|
||||
void media_flow_destroy(MediaFlow *flow);
|
||||
destructor
|
||||
|
||||
**************************************************************************
|
||||
object: CallMember
|
||||
This object reprensent a member of a call.
|
||||
methods:
|
||||
CallMember *call_member_new();
|
||||
|
||||
gint call_member_setup_flow(CallMember *member, MediaFlow *flow,
|
||||
char *rx_endpoint, char *tx_endpoint);
|
||||
This is the most important function of the API. It describes the way each
|
||||
call member receives and send a given media flow.
|
||||
The MediaFlow "flow" is added to the list of flows used by the member "member".
|
||||
rx_endpoint is a string that described how data is received by the call member.
|
||||
It should be an url, for example "rtp://213.21.54.127:7080". In this case it
|
||||
means that data will be received on port 7080 at ip address 213.21.54.127.
|
||||
tx_endpoint is a string that described how data is sent by the call member.
|
||||
The role of url is very important. They can be:
|
||||
"rtp://213.21.54.127:7080"
|
||||
"file://tmp/media.out" -a file on disk
|
||||
"oss://0" -souncard 0 using oss api
|
||||
"alsa://0" -soundcard 0 using alsa api.
|
||||
In order to work, the call member must be part of a BasicCall, as well as
|
||||
the flow must be part of the BasicCall too (using basic_call_add_flow())
|
||||
This function may (on the backend) create a MediaEndpoint object that stores
|
||||
the rx_endpoint and tx_endpoint parameter. This object is added to:
|
||||
-the list of MediaEndpoint maintained by the member (list per member)
|
||||
-the list of MediaEndpoint maintained by the flow (list per flow)
|
||||
|
||||
|
||||
**************************************************************************
|
||||
object: BasicCall
|
||||
This object handles simple calls (two party calls). It defines inside itself
|
||||
two CallMember objects.
|
||||
method:
|
||||
BasicCall *basic_call_new();
|
||||
|
||||
CallMember *basic_call_get_member(BasicCall *call, gint member_number);
|
||||
Returns a member of a BasicCall according to a number.
|
||||
|
||||
void basic_call_add_flow(BasicCall *call, MediaFlow *flow);
|
||||
Adds a flow to the call's list of flow.
|
||||
|
||||
gint basic_call_start_flow(BasicCall *call, MediaFlow *flow);
|
||||
This function construct the mediastreamer processing chain necessary to make
|
||||
the call running, if not done, and runs it using ms_start()
|
||||
|
||||
gint basic_call_stop_flow(BasicCall *call, MediaFlow *flow);
|
||||
|
||||
gint basic_call_start_all_flows(BasicCall *call);
|
||||
|
||||
void basic_call_destroy(BasicCall *call);
|
||||
Destroy all data used by the call: call members, call flows.
|
||||
|
||||
**************************************************************************
|
||||
object: ConferenceCall
|
||||
This object handles conference call (which are quite much complicated than basic
|
||||
calls). But this object should have the same method as the BasicCall object.
|
||||
|
||||
*******************************************************************
|
||||
EXAMPLE
|
||||
*******************************************************************
|
||||
|
||||
Two party call between call member A on machine "linphone.org" and call member B on machine "home.com".
|
||||
The media_api is running on "home.com".
|
||||
|
||||
A (on linphone.org) B (on home.com)
|
||||
|
||||
------>(send to rtp://home.com:7080 MSRTPReceiver------>Decode----->(send to oss:/0)
|
||||
|
||||
------<(recv on rtp://linphone.org:7020 MSRTPSender<--------Encode<-----(read on oss://0)
|
||||
|
||||
This is how to setup this call using the media_api:
|
||||
BasicCall *call;
|
||||
CallMember *memberA,*memberB;
|
||||
MediaFlow *flow;
|
||||
|
||||
/* create a basic call*/
|
||||
call=basic_call_new();
|
||||
/* get a pointer to the pre-define members of the call */
|
||||
memberA=basic_call_get_member(call,0);
|
||||
memberB=basic_call_get_member(call,1);
|
||||
|
||||
/* create a media flow */
|
||||
flow=media_flow_new("voice",FLOW_AUDIO,1);
|
||||
/* tell that the flow is used by the call */
|
||||
basic_call_add_flow(call,flow);
|
||||
/* tell how each member uses the flow (how is the interface ?)*/
|
||||
call_member_setup_flow(memberA,flow,"rtp://linphone.org:7020","rtp://home.com:7080");
|
||||
/* note: it is not efficient to do name resolution at this stage: that's why in reality numeric ip address
|
||||
should be given instead of host name */
|
||||
call_member_setup_flow(memberB,flow,"oss://0","oss://0");
|
||||
|
||||
/* start the flow */
|
||||
basic_call_start_flow(call,flow);
|
||||
|
||||
In case where the media api is running on another host called "toto" (in a media translator application for example),
|
||||
the only thing that would change is the url given to memberB: tx="rtp://home.com:8820" for example and
|
||||
rx="rtp://toto:9522".
|
||||
|
||||
In the sipomatic application (the test application I use to test linphone (it answers to call and plays
|
||||
a short annoucement)), I would write rx="file://path_to_annoucement.raw" and tx="file://dev/null" instead of
|
||||
"oss://0".
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
if BUILD_MEDIA_API
|
||||
|
||||
#the media_api library is the only one we have to build here
|
||||
lib_LTLIBRARIES=libmedia_api.la
|
||||
|
||||
#definition of the sources of libmedia_api
|
||||
libmedia_api_la_SOURCES= basiccall.c callmember.c mediaflow.c
|
||||
|
||||
# libmedia_api needs libmediastreamer
|
||||
libmedia_api_la_LIBADD=$(top_srcdir)/mediastreamer/libmediastreamer.la
|
||||
|
||||
#the media_api test program
|
||||
bin_PROGRAMS=apitest
|
||||
|
||||
apitest_SOURCES= apitest.c
|
||||
# the test program links to libmedia_api
|
||||
apitest_LDADD=libmedia_api.la
|
||||
|
||||
endif
|
||||
|
||||
DEFS=@DEFS@ @SOUNDDEFS@ -DDEBUG -DG_LOG_DOMAIN=\"MediaApi\"
|
||||
|
||||
INCLUDES=-I$(top_srcdir)/mediastreamer \
|
||||
-I$(top_srcdir)/speex \
|
||||
-I$(top_srcdir)/gsmlib \
|
||||
$(ORTP_CFLAGS) \
|
||||
-I$(top_srcdir)/lpc10-1.5 \
|
||||
-I$(top_srcdir)/ffmpeg
|
||||
|
||||
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
#include "basiccall.h"
|
||||
#include <signal.h>
|
||||
static int flag = 1;
|
||||
void stop(int sign){
|
||||
flag = 0;
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
BasicCall *call;
|
||||
char *id;
|
||||
CallMember *memberA, *memberB;
|
||||
MediaFlow *flow, *flow1;
|
||||
|
||||
signal(SIGINT, stop);
|
||||
call = basic_call_new();
|
||||
memberA = basic_call_get_member(call,MemberA);
|
||||
memberB = basic_call_get_member(call,MemberB);
|
||||
|
||||
id = "test_voice";
|
||||
printf("\n");
|
||||
flow = media_flow_new(id, MEDIA_FLOW_VOICE);
|
||||
|
||||
basic_call_add_flow(call, flow);
|
||||
|
||||
call_member_setup_flow(memberA, flow, "file://temp", "oss://0");
|
||||
call_member_setup_flow(memberB, flow, "oss://0", "oss://0");
|
||||
|
||||
media_flow_setup_fd(flow, memberA, memberB, MEDIA_FLOW_HALF_DUPLEX);
|
||||
basic_call_start_flow(call, flow);
|
||||
|
||||
while(flag){
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,170 +0,0 @@
|
|||
/*
|
||||
The objective of the media_api is to construct and run the necessary processing
|
||||
on audio and video data flows for a given call (two party call) or conference.
|
||||
Copyright (C) 2001 Sharath Udupa skuds@gmx.net
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "basiccall.h"
|
||||
#include "../mediastreamer/mscodec.h"
|
||||
|
||||
#define ONESYNC 10
|
||||
#define MULTISYNC 20
|
||||
|
||||
BasicCall *basic_call_new(){
|
||||
BasicCall *bc = (BasicCall*) g_malloc(sizeof(BasicCall));
|
||||
api_trace("basic_call_new: creating a basic call");
|
||||
bc->memberA = call_member_new("memberA");
|
||||
bc->memberB = call_member_new("memberB");
|
||||
return bc;
|
||||
}
|
||||
|
||||
CallMember *basic_call_get_member(BasicCall *call, int member_nu){
|
||||
api_trace("basic_call_get_member: called for %d",member_nu);
|
||||
if(member_nu == MemberA){
|
||||
return call->memberA;
|
||||
}
|
||||
else if(member_nu == MemberB){
|
||||
return call->memberB;
|
||||
}
|
||||
}
|
||||
|
||||
void basic_call_add_flow(BasicCall *call, MediaFlow *flow){
|
||||
api_trace("basic_call_add_flow: called for %s",flow->id);
|
||||
call->flows = g_list_append( call->flows, flow);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int find_mediaflow(gconstpointer llist, gconstpointer flow){
|
||||
//MediaFlow *mf = (MediaFlow *) ((BasicCallFlow*)llist)->mediaFlow;
|
||||
if(((MediaFlow*)flow)->id == ((MediaFlow*)llist)->id){
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int basic_call_start_flow(BasicCall *call, MediaFlow *flow){
|
||||
int i=0;
|
||||
int syncFlag=0;
|
||||
int nFlowDirections;
|
||||
MSSync *sync;
|
||||
Members *source, *destination;
|
||||
FlowDirections *fd;
|
||||
GList *elem, *selem;
|
||||
GList *snd_read = NULL, *snd_write = NULL, *filter = NULL;
|
||||
|
||||
//Commented by Sharat
|
||||
//This is initialized in media_api.c
|
||||
//when should these functions be really called?
|
||||
//ms_init();
|
||||
//ortp_init();
|
||||
|
||||
api_trace("basic_call_start_flow: called for flow %s", flow->id);
|
||||
|
||||
elem = g_list_find_custom( call->flows, flow, &find_mediaflow);
|
||||
if(elem == NULL){
|
||||
api_error("basic_call_start_flow: Called for unregistered mediaflow %s", flow->id);
|
||||
}
|
||||
|
||||
nFlowDirections = g_list_length(flow->flowDirections);
|
||||
if(flow->type == MEDIA_FLOW_VOICE){
|
||||
syncFlag = ONESYNC;
|
||||
sync = ms_timer_new();
|
||||
}
|
||||
else{
|
||||
syncFlag = MULTISYNC;
|
||||
}
|
||||
|
||||
for(i=0;i< nFlowDirections; i++){
|
||||
|
||||
if(syncFlag == MULTISYNC){
|
||||
sync = ms_timer_new();
|
||||
}
|
||||
fd = (FlowDirections*)g_list_nth_data(flow->flowDirections,i);
|
||||
source = fd->source;
|
||||
destination = fd->destination;
|
||||
|
||||
media_flow_start_fd(fd, sync);
|
||||
if(fd->type == MEDIA_FLOW_DUPLEX){
|
||||
switch(source->tx_endpoint->protocol){
|
||||
case MEDIA_ALSA:
|
||||
case MEDIA_OSS:
|
||||
snd_read = g_list_append(snd_read, fd->recv);
|
||||
}
|
||||
switch(destination->rx_endpoint->protocol){
|
||||
case MEDIA_ALSA:
|
||||
case MEDIA_OSS:
|
||||
snd_write = g_list_append(snd_write, fd->play);
|
||||
}
|
||||
|
||||
switch(destination->tx_endpoint->protocol){
|
||||
case MEDIA_ALSA:
|
||||
case MEDIA_OSS:
|
||||
snd_read = g_list_append(snd_read, fd->read);
|
||||
}
|
||||
|
||||
switch(source->rx_endpoint->protocol){
|
||||
case MEDIA_ALSA:
|
||||
case MEDIA_OSS:
|
||||
snd_write = g_list_append(snd_write, fd->send);
|
||||
}
|
||||
|
||||
}
|
||||
else if(fd->type == MEDIA_FLOW_HALF_DUPLEX){
|
||||
|
||||
switch(source->tx_endpoint->protocol){
|
||||
case MEDIA_ALSA:
|
||||
case MEDIA_OSS:
|
||||
snd_read = g_list_append(snd_read, fd->recv);
|
||||
}
|
||||
switch(destination->rx_endpoint->protocol){
|
||||
case MEDIA_ALSA:
|
||||
case MEDIA_OSS:
|
||||
snd_write = g_list_append(snd_write, fd->play);
|
||||
}
|
||||
}
|
||||
if(syncFlag == MULTISYNC){
|
||||
flow->sync = g_list_append(flow->sync, sync);
|
||||
}
|
||||
}
|
||||
if(syncFlag == ONESYNC){
|
||||
ms_start(sync);
|
||||
flow->sync = g_list_append(flow->sync, sync);
|
||||
}
|
||||
if(syncFlag == MULTISYNC){
|
||||
selem = flow->sync;
|
||||
while(selem != NULL){
|
||||
ms_start(selem->data);
|
||||
selem = g_list_next(selem);
|
||||
}
|
||||
}
|
||||
filter = snd_read;
|
||||
while(filter != NULL){
|
||||
ms_sound_read_start(MS_SOUND_READ((MSFilter*)filter->data));
|
||||
filter = g_list_next(filter);
|
||||
}
|
||||
|
||||
filter = snd_write;
|
||||
while(filter != NULL){
|
||||
ms_sound_write_start(MS_SOUND_WRITE((MSFilter*)filter->data));
|
||||
filter = g_list_next(filter);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int basic_call_stop_flow(BasicCall *call, MediaFlow *flow){
|
||||
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
The objective of the media_api is to construct and run the necessary processing
|
||||
on audio and video data flows for a given call (two party call) or conference.
|
||||
Copyright (C) 2001 Sharath Udupa skuds@gmx.net
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "mediaflow.h"
|
||||
#include "callmember.h"
|
||||
|
||||
//other includes required to be done here
|
||||
#define MemberA 1
|
||||
#define MemberB 2
|
||||
|
||||
|
||||
struct _BasicCall{
|
||||
CallMember *memberA, *memberB;
|
||||
GList *flows; //linked list of MediaFlows
|
||||
};
|
||||
|
||||
typedef struct _BasicCall BasicCall;
|
||||
|
||||
|
||||
BasicCall *basic_call_new();
|
||||
|
||||
CallMember *basic_call_get_member(BasicCall *call, int member_nu);
|
||||
|
||||
void basic_call_add_flow(BasicCall *call, MediaFlow *flow);
|
||||
|
||||
int basic_call_start_flow(BasicCall *call, MediaFlow *flow);
|
||||
|
||||
int basic_call_stop_flow(BasicCall *call, MediaFlow *flow);
|
||||
|
||||
int basic_call_start_all_flows(BasicCall *call);
|
||||
|
||||
int basic_call_destroy(BasicCall *call);
|
||||
|
||||
|
|
@ -1,153 +0,0 @@
|
|||
/*
|
||||
The objective of the media_api is to construct and run the necessary processing
|
||||
on audio and video data flows for a given call (two party call) or conference.
|
||||
Copyright (C) 2001 Sharath Udupa skuds@gmx.net
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "common.h"
|
||||
#include "callmember.h"
|
||||
#include "mediaflow.h"
|
||||
|
||||
|
||||
CallMember *call_member_new(char *name){
|
||||
CallMember *member = (CallMember*) g_malloc(sizeof(CallMember));
|
||||
api_trace("call_member_new: creating %s", name);
|
||||
member->name = name;
|
||||
member->flows = NULL;
|
||||
member->profile = NULL;
|
||||
return member;
|
||||
}
|
||||
|
||||
int call_member_set_rtp_profile(CallMember *member, RtpProfile *profile){
|
||||
member->profile = profile;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int call_member_setup_flow(CallMember *member, MediaFlow *flow, char* rx, char *tx){
|
||||
Members *mem = (Members*) g_malloc(sizeof(Members));
|
||||
Flows *flows = (Flows*) g_malloc(sizeof(Flows));
|
||||
api_trace("call_member_setup_flow: setting up flow for: CallMember->%s , MediaFlow->%s", member->name, flow->id);
|
||||
mem->member = member;
|
||||
mem->rx_endpoint = parse_end_point(rx);
|
||||
mem->tx_endpoint = parse_end_point(tx);
|
||||
flow->members = g_list_append(flow->members, mem);
|
||||
|
||||
flows->flow = flow;
|
||||
flows->rx_endpoint = parse_end_point(rx);
|
||||
flows->tx_endpoint = parse_end_point(tx);
|
||||
member->flows = g_list_append(member->flows, flows);
|
||||
return 1;
|
||||
}
|
||||
|
||||
EndPoint *parse_end_point(char *endpoint){
|
||||
EndPoint *result = (EndPoint*) g_malloc(sizeof(EndPoint));
|
||||
int i=0,len1,len2,len, tlen;
|
||||
char *str2, temp[30], *host_str;
|
||||
//api_trace("parse_end_point: parsing %s\n", endpoint);
|
||||
result->pt = -1;
|
||||
while(1){
|
||||
str2 = (char*) strpbrk(endpoint, ":");
|
||||
if(str2 == NULL){
|
||||
str2 = (char*) strpbrk(endpoint, ";");
|
||||
if(str2 == NULL){
|
||||
len = strlen(endpoint);
|
||||
}
|
||||
else{
|
||||
len1 = strlen(endpoint);
|
||||
len2 = strlen(str2);
|
||||
len = len1-len2;
|
||||
}
|
||||
}
|
||||
else{
|
||||
len1 = strlen(endpoint);
|
||||
len2 = strlen(str2);
|
||||
len = len1-len2;
|
||||
}
|
||||
strncpy(temp,endpoint,len);
|
||||
temp[len] = '\0';
|
||||
tlen = strlen(temp);
|
||||
if((tlen >= 2)&&(temp[0] == '/')&&(temp[1] == '/')){
|
||||
host_str = remove_slash(temp);
|
||||
}
|
||||
switch(i){
|
||||
case 0: if(strcmp(temp,"rtp")==0){
|
||||
result->protocol=MEDIA_RTP;
|
||||
}
|
||||
else if(strcmp(temp,"oss")==0){
|
||||
result->protocol=MEDIA_OSS;
|
||||
}
|
||||
else if(strcmp(temp,"alsa")==0){
|
||||
result->protocol=MEDIA_ALSA;
|
||||
}
|
||||
else if(strcmp(temp,"file")==0){
|
||||
result->protocol=MEDIA_FILE;
|
||||
}
|
||||
break;
|
||||
case 1: if(result->protocol==MEDIA_FILE){
|
||||
result->file=host_str;
|
||||
}
|
||||
else{
|
||||
result->host = host_str;
|
||||
}
|
||||
break;
|
||||
case 2: result->port = to_digits(temp);
|
||||
break;
|
||||
case 3: result->pt = pt_digits(temp);
|
||||
break;
|
||||
default://result->options[result->nOptions++] = temp;
|
||||
break;
|
||||
}
|
||||
if(str2 != NULL) endpoint = str2+1;
|
||||
else break;
|
||||
i++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int to_digits(char *str){
|
||||
int nu=0,a,len,i;
|
||||
len = strlen(str);
|
||||
for(i=0;i<len;i++){
|
||||
a=str[i];
|
||||
a=a-'0';
|
||||
nu = nu*10+a;
|
||||
}
|
||||
return nu;
|
||||
}
|
||||
|
||||
int pt_digits(char *str){
|
||||
int len;
|
||||
len = strlen(str);
|
||||
if((len>3)&&(str[0]=='p')&&(str[1]=='t')&&(str[2]=='=')){
|
||||
return to_digits(str+3);
|
||||
}
|
||||
else{
|
||||
api_warn("Wrong parameters passed in the endpoints");
|
||||
return 0;
|
||||
//ERROR handling
|
||||
}
|
||||
}
|
||||
char *remove_slash(char var[]){
|
||||
char *temp = (char*) g_malloc(10*sizeof(char));
|
||||
int len,i;
|
||||
len=strlen(var);
|
||||
for(i=2;i<len;i++){
|
||||
temp[i-2]=var[i];
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
The objective of the media_api is to construct and run the necessary processing
|
||||
on audio and video data flows for a given call (two party call) or conference.
|
||||
Copyright (C) 2001 Sharath Udupa skuds@gmx.net
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
struct _CallMember{
|
||||
char *name;
|
||||
GList *flows;
|
||||
RtpProfile *profile;
|
||||
};
|
||||
|
||||
typedef struct _CallMember CallMember;
|
||||
|
||||
struct _EndPoint{
|
||||
int protocol;
|
||||
char *host;
|
||||
char *file;
|
||||
int port;
|
||||
int pt;
|
||||
};
|
||||
|
||||
typedef struct _EndPoint EndPoint;
|
||||
|
||||
struct _Flows{
|
||||
struct _MediaFlow *flow;
|
||||
EndPoint *rx_endpoint;
|
||||
EndPoint *tx_endpoint;
|
||||
};
|
||||
|
||||
typedef struct _Flows Flows;
|
||||
|
||||
CallMember *call_member_new(char *);
|
||||
|
||||
int call_member_setup_flow(CallMember *member, struct _MediaFlow *flow, char *rx_enndpoint, char *tx_endpoint);
|
||||
|
||||
/* Internal functions */
|
||||
EndPoint *parse_end_point(char *endpoint);
|
||||
|
||||
char *remove_slash(char[]);
|
||||
|
||||
int to_digits(char*);
|
||||
|
||||
int pt_digits(char*);
|
||||
|
||||
|
|
@ -1 +0,0 @@
|
|||
gcc -I/home/skudupa/linphone/mediastreamer -I/home/skudupa/linphone/ffmpeg/libavcodec -I/home/skudupa/linphone/gsmlib -I/home/skudupa/linphone/lpc10-1.5 -I/home/skudupa/linphone/oRTP/src -I/usr/include/glib-1.2 -I/usr/lib/glib/include -I/usr/include/gtk-1.2 -I/usr/include/glib-1.2 -I/usr/lib/glib/include -I/usr/X11R6/include -I/home/skudupa/linphone/oRTP mediaflow.c
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
|
||||
#include "media_api.h"
|
||||
#include <glib.h>
|
||||
|
||||
#define api_trace g_message
|
||||
#define api_error g_error
|
||||
#define api_warn g_warning
|
||||
|
||||
#define MEDIA_FLOW_DUPLEX 1
|
||||
#define MEDIA_FLOW_HALF_DUPLEX 2
|
||||
|
||||
//Mediaflow type
|
||||
#define MEDIA_FLOW_VIDEO 1
|
||||
#define MEDIA_FLOW_VOICE 2
|
||||
|
||||
//Mediaflow protocols
|
||||
#define MEDIA_RTP 1
|
||||
#define MEDIA_OSS 2
|
||||
#define MEDIA_ALSA 3
|
||||
#define MEDIA_FILE 4
|
||||
|
||||
//Mediaflow codec function
|
||||
#define MEDIA_API_DECODER 1
|
||||
#define MEDIA_API_ENCODER 2
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
The objective of the media_api is to construct and run the necessary processing
|
||||
on audio and video data flows for a given call (two party call) or conference.
|
||||
Copyright (C) 2001 Sharath Udupa skuds@gmx.net
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "media_api.h"
|
||||
|
||||
/* non-standard payload types for oRTP */
|
||||
PayloadType lpc1015={
|
||||
PAYLOAD_AUDIO_PACKETIZED,
|
||||
8000,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
2400,
|
||||
"1015/8000/1"
|
||||
};
|
||||
|
||||
PayloadType speex_nb={
|
||||
PAYLOAD_AUDIO_PACKETIZED,
|
||||
8000,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
15000,
|
||||
"speex/8000/1"
|
||||
};
|
||||
|
||||
PayloadType speex_nb_lbr={
|
||||
PAYLOAD_AUDIO_PACKETIZED,
|
||||
8000,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
8000,
|
||||
"speex-lbr/8000/1"
|
||||
};
|
||||
|
||||
void media_api_init()
|
||||
{
|
||||
ortp_init();
|
||||
ortp_set_debug_file("oRTP",NULL);
|
||||
rtp_profile_set_payload(&av_profile,115,&lpc1015);
|
||||
rtp_profile_set_payload(&av_profile,110,&speex_nb);
|
||||
rtp_profile_set_payload(&av_profile,111,&speex_nb_lbr);
|
||||
rtp_profile_set_payload(&av_profile,101,&telephone_event);
|
||||
ms_init();
|
||||
ms_speex_codec_init();
|
||||
#ifdef HAVE_AVCODEC
|
||||
ms_AVCodec_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
The objective of the media_api is to construct and run the necessary processing
|
||||
on audio and video data flows for a given call (two party call) or conference.
|
||||
Copyright (C) 2001 Sharath Udupa skuds@gmx.net
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef MEDIA_API_H
|
||||
#define MEDIA_API_H
|
||||
|
||||
/* some mediastreamer include files....*/
|
||||
|
||||
#include "ms.h"
|
||||
|
||||
/* audio codecs ; all these header are not really required as we should use ms_codec_new..() to
|
||||
create codec filters*/
|
||||
/*Commented by Sharath Udupa
|
||||
#include <mscodec.h>
|
||||
#include <msMUlawdec.h>
|
||||
#include <msMUlawenc.h>
|
||||
#include <msAlawdec.h>
|
||||
#include <msAlawenc.h>
|
||||
#include <msGSMdecoder.h>
|
||||
#include <msGSMencoder.h>
|
||||
#include <msLPC10decoder.h>
|
||||
#include <msLPC10encoder.h>
|
||||
|
||||
#ifdef BUILD_FFMPEG
|
||||
#include <msavdecoder.h>
|
||||
#include <msavencoder.h>*/
|
||||
#endif
|
||||
|
||||
/* some usefull filters of the mediastreamer */
|
||||
#include "mscopy.h"
|
||||
#include "msfdispatcher.h"
|
||||
#include "msqdispatcher.h"
|
||||
|
||||
/* some synchronisation sources */
|
||||
#include <msnosync.h>
|
||||
#include <mstimer.h>
|
||||
|
||||
/* some streams sources and sinks */
|
||||
#include <msossread.h>
|
||||
#include <msosswrite.h>
|
||||
#include <msread.h>
|
||||
#include <mswrite.h>
|
||||
#include <msringplayer.h>
|
||||
#include <msrtprecv.h>
|
||||
#include <msrtpsend.h>
|
||||
#include <msv4l.h>
|
||||
#include <msvideooutput.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,179 +0,0 @@
|
|||
/*
|
||||
The objective of the media_api is to construct and run the necessary processing
|
||||
on audio and video data flows for a given call (two party call) or conference.
|
||||
Copyright (C) 2001 Sharath Udupa skuds@gmx.net
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "common.h"
|
||||
#include "mediaflow.h"
|
||||
#include "callmember.h"
|
||||
|
||||
|
||||
MediaFlow *media_flow_new(char *id_string, int type){
|
||||
MediaFlow *flow = (MediaFlow *) g_malloc(sizeof(MediaFlow)); //malloc required?
|
||||
api_trace("media_flow_new: creating %s",id_string);
|
||||
flow->id = id_string;
|
||||
flow->type = type;
|
||||
flow->flowDirections = NULL;
|
||||
flow->members = NULL;
|
||||
return flow;
|
||||
}
|
||||
|
||||
int media_flow_destroy(MediaFlow *flow){
|
||||
g_free(flow);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int media_flow_setup_fd(MediaFlow *flow, CallMember* csource, CallMember *cdestination, int direction){
|
||||
GList *source, *destination;
|
||||
char *dir;
|
||||
FlowDirections *fd = (FlowDirections *) g_malloc(sizeof(FlowDirections));
|
||||
if(direction == MEDIA_FLOW_DUPLEX) dir = "DUPLEX";
|
||||
else if(direction == MEDIA_FLOW_HALF_DUPLEX) dir = "HALF_DUPLEX";
|
||||
api_trace("media_flow_setup_fd: setting up %s flow for %s , %s",dir, csource->name, cdestination->name);
|
||||
source = g_list_find_custom(flow->members, csource, &find);
|
||||
destination =g_list_find_custom(flow->members, cdestination, &find);
|
||||
if(source == NULL){
|
||||
api_error("media_flow_setup_fd: Invalid source %s specified", csource->name);
|
||||
}
|
||||
if(destination == NULL){
|
||||
api_error("media_flow_setup_fd: Invalid destination %s specified", cdestination->name);
|
||||
//ERROR handling to be done here
|
||||
}
|
||||
fd->source = (Members*)source->data;
|
||||
fd->destination = (Members*)destination->data;
|
||||
fd->type = direction;
|
||||
flow->flowDirections = g_list_append(flow->flowDirections, fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int find(gconstpointer mem, gconstpointer cmember){
|
||||
if(!strcmp(((Members*)mem)->member->name, ((CallMember*)cmember)->name)){
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int media_flow_start_fd(FlowDirections *fd, MSSync *sync){
|
||||
Members *source, *destination;
|
||||
source = fd->source;
|
||||
destination = fd->destination;
|
||||
if(fd->type == MEDIA_FLOW_DUPLEX){
|
||||
fd->recv = set_MSFilter(source->tx_endpoint,1,fd);
|
||||
fd->dec = set_CODECFilter(source->member->profile, source->tx_endpoint->pt,MEDIA_API_DECODER);
|
||||
fd->play = set_MSFilter(destination->rx_endpoint,0,fd);
|
||||
|
||||
ms_filter_add_link(fd->recv,fd->dec);
|
||||
ms_filter_add_link(fd->dec,fd->play);
|
||||
ms_sync_attach(sync, fd->recv);
|
||||
|
||||
fd->read = set_MSFilter(destination->tx_endpoint,1,fd);
|
||||
fd->enc = set_CODECFilter(destination->member->profile, destination->tx_endpoint->pt,MEDIA_API_ENCODER);
|
||||
fd->send = set_MSFilter(source->rx_endpoint,0,fd);
|
||||
|
||||
ms_filter_add_link(fd->read, fd->enc);
|
||||
ms_filter_add_link(fd->enc, fd->send);
|
||||
ms_sync_attach(sync, fd->read);
|
||||
|
||||
}
|
||||
else if(fd->type == MEDIA_FLOW_HALF_DUPLEX){
|
||||
|
||||
fd->recv = set_MSFilter(source->tx_endpoint,1,fd);
|
||||
fd->dec = set_CODECFilter(sourcec->member->profile, source->tx_endpoint->pt,MEDIA_API_DECODER);
|
||||
fd->play = set_MSFilter(destination->rx_endpoint,0,fd);
|
||||
|
||||
ms_filter_add_link(fd->recv,fd->dec);
|
||||
ms_filter_add_link(fd->dec,fd->play);
|
||||
ms_sync_attach(sync, fd->recv);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
MSFilter *set_MSFilter(EndPoint *endpoint, int type, FlowDirections *fdir){
|
||||
MSFilter *filter;
|
||||
RtpSession *rtps;
|
||||
switch(endpoint->protocol){
|
||||
case MEDIA_RTP:
|
||||
rtps = rtp_session_new(RTP_SESSION_RECVONLY);
|
||||
rtp_session_set_local_addr(rtps,"0.0.0.0",8000,8001);
|
||||
rtp_session_set_scheduling_mode(rtps,0);
|
||||
rtp_session_set_blocking_mode(rtps,0);
|
||||
|
||||
if(type == 1){
|
||||
filter = ms_rtp_recv_new();
|
||||
ms_rtp_recv_set_session(MS_RTP_RECV(filter), rtps);
|
||||
fdir->rtpSessions = g_list_append(fdir->rtpSessions, rtps);
|
||||
return filter;
|
||||
}
|
||||
else{
|
||||
//ms_rtp_send_new
|
||||
}
|
||||
case MEDIA_OSS:
|
||||
if(type == 1){
|
||||
filter = ms_oss_read_new();
|
||||
ms_sound_read_set_device(MS_SOUND_READ(filter),0);
|
||||
return filter;
|
||||
}
|
||||
else{
|
||||
filter = ms_oss_write_new();
|
||||
ms_sound_write_set_device(MS_SOUND_WRITE(filter),0);
|
||||
return filter;
|
||||
}
|
||||
case MEDIA_FILE:
|
||||
if(type == 1){
|
||||
filter = ms_read_new(endpoint->file);
|
||||
return filter;
|
||||
}
|
||||
if(type == 0){
|
||||
filter = ms_write_new(endpoint->file);
|
||||
return filter;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
MSFilter *set_CODECFilter(RtpProfile *profile, int pt, int mode){
|
||||
PayloadType *payload;
|
||||
|
||||
switch(mode){
|
||||
case MEDIA_API_DECODER:
|
||||
payload = rtp_profile_get_payload(profile, pt);
|
||||
if(payload == NULL){
|
||||
api_error("media_api: undefined payload in URL\n");
|
||||
return NULL;
|
||||
}
|
||||
return ms_decoder_new_with_string_id(payload->mime_type);
|
||||
|
||||
//Commented this to include the new RtpProfile
|
||||
/*if(pt != -1) return ms_decoder_new_with_pt(pt);
|
||||
*else return ms_copy_new();
|
||||
*/
|
||||
case MEDIA_API_ENCODER:
|
||||
|
||||
payload = rtp_profile_get_payload(profile, pt);
|
||||
if(payload == NULL){
|
||||
api_error("media_api: undefined payload in URL\n");
|
||||
return NULL;
|
||||
}
|
||||
return ms_encoder_new_with_string_id(payload->mime_type);
|
||||
/*if(pt != -1) return ms_encoder_new_with_pt(pt);
|
||||
*else return ms_copy_new();
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
The objective of the media_api is to construct and run the necessary processing
|
||||
on audio and video data flows for a given call (two party call) or conference.
|
||||
Copyright (C) 2001 Sharath Udupa skuds@gmx.net
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a c:opy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
struct _MediaFlow{
|
||||
char *id;
|
||||
int type;
|
||||
GList *members;
|
||||
GList *flowDirections;
|
||||
GList *sync; //holds all the filters in this MediaFlow
|
||||
};
|
||||
|
||||
typedef struct _MediaFlow MediaFlow;
|
||||
|
||||
struct _Members{
|
||||
struct _CallMember *member;
|
||||
struct _EndPoint *rx_endpoint;
|
||||
struct _EndPoint *tx_endpoint;
|
||||
};
|
||||
|
||||
typedef struct _Members Members;
|
||||
|
||||
struct _FlowDirections{
|
||||
Members *source, *destination;
|
||||
MSFilter *recv,
|
||||
*dec,
|
||||
*play;
|
||||
MSFilter *read, //Filters used
|
||||
*enc, //if type==DUPLEX
|
||||
*send;
|
||||
GList *rtpSessions;
|
||||
int type;
|
||||
};
|
||||
|
||||
typedef struct _FlowDirections FlowDirections;
|
||||
|
||||
|
||||
MediaFlow *media_flow_new(char *id_string, int type);
|
||||
|
||||
int media_flow_setup_fd(MediaFlow*, struct _CallMember *, struct _CallMember *, int);
|
||||
|
||||
int media_flow_start_fd(FlowDirections *fd, MSSync *sync);
|
||||
|
||||
int media_flow_destroy(MediaFlow *flow);
|
||||
|
||||
/* Internal functions */
|
||||
int find(gconstpointer, gconstpointer);
|
||||
|
||||
MSFilter *set_MSFilter(struct _EndPoint *, int, FlowDirections *);
|
||||
|
||||
MSFilter *set_CODECFilter(RtpProfile* , int, int);
|
||||
|
||||
Loading…
Add table
Reference in a new issue