Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
mediastreamer2
Commits
6dd1b2b5
Commit
6dd1b2b5
authored
Aug 27, 2010
by
Simon Morlat
Browse files
Merge branch 'master' of git.linphone.org:mediastreamer2
parents
e603af3b
ea7ca97a
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
348 additions
and
340 deletions
+348
-340
build/win32native/Makefile.am
build/win32native/Makefile.am
+1
-1
include/mediastreamer2/dtmfgen.h
include/mediastreamer2/dtmfgen.h
+6
-0
include/mediastreamer2/mediastream.h
include/mediastreamer2/mediastream.h
+26
-7
src/audiostream.c
src/audiostream.c
+62
-16
src/dtmfgen.c
src/dtmfgen.c
+76
-17
src/msrtp.c
src/msrtp.c
+41
-29
src/mtu.c
src/mtu.c
+1
-9
src/videostream.c
src/videostream.c
+134
-261
src/winsnd3.c
src/winsnd3.c
+1
-0
No files found.
build/win32native/Makefile.am
View file @
6dd1b2b5
EXTRA_DIST
=
alldescs.h mediastreamer2.vcproj
mediastream.vcproj
videodisplay.vcproj mediastreamer2.def
EXTRA_DIST
=
alldescs.h mediastreamer2.vcproj videodisplay.vcproj mediastreamer2.def
include/mediastreamer2/dtmfgen.h
View file @
6dd1b2b5
...
...
@@ -24,6 +24,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define MS_DTMF_GEN_PUT MS_FILTER_METHOD(MS_DTMF_GEN_ID,0,const char)
#define MS_DTMF_GEN_PLAY MS_FILTER_METHOD(MS_DTMF_GEN_ID,0,const char)
/*alias to put*/
/**Start playing a dtmf */
#define MS_DTMF_GEN_START MS_FILTER_METHOD(MS_DTMF_GEN_ID,1,const char)
/**Stop currently played dtmf*/
#define MS_DTMF_GEN_STOP MS_FILTER_METHOD_NO_ARG(MS_DTMF_GEN_ID,2)
extern
MSFilterDesc
ms_dtmf_gen_desc
;
#endif
include/mediastreamer2/mediastream.h
View file @
6dd1b2b5
...
...
@@ -53,6 +53,7 @@ struct _AudioStream
MSFilter
*
rtprecv
;
MSFilter
*
rtpsend
;
MSFilter
*
dtmfgen
;
MSFilter
*
dtmfgen_rtp
;
MSFilter
*
ec
;
/*echo canceler*/
MSFilter
*
volsend
,
*
volrecv
;
/*MSVolumes*/
MSFilter
*
read_resampler
;
...
...
@@ -64,6 +65,7 @@ struct _AudioStream
int
ec_tail_len
;
/*milliseconds*/
int
ec_delay
;
/*milliseconds*/
int
ec_framesize
;
/* number of fft points */
OrtpEvQueue
*
evq
;
bool_t
play_dtmfs
;
bool_t
use_gc
;
bool_t
use_agc
;
...
...
@@ -81,6 +83,7 @@ struct _RingStream
{
MSTicker
*
ticker
;
MSFilter
*
source
;
MSFilter
*
gendtmf
;
MSFilter
*
sndwrite
;
};
...
...
@@ -99,6 +102,10 @@ int audio_stream_start_with_files (AudioStream * stream, RtpProfile * prof,
int
pt
,
int
jitt_comp
,
const
char
*
infile
,
const
char
*
outfile
);
int
audio_stream_start_full
(
AudioStream
*
stream
,
RtpProfile
*
profile
,
const
char
*
remip
,
int
remport
,
int
rem_rtcp_port
,
int
payload
,
int
jitt_comp
,
const
char
*
infile
,
const
char
*
outfile
,
MSSndCard
*
playcard
,
MSSndCard
*
captcard
,
bool_t
use_ec
);
void
audio_stream_play
(
AudioStream
*
st
,
const
char
*
name
);
void
audio_stream_record
(
AudioStream
*
st
,
const
char
*
name
);
...
...
@@ -163,6 +170,12 @@ void audio_stream_get_local_rtp_stats(AudioStream *stream, rtp_stats_t *stats);
typedef
void
(
*
VideoStreamRenderCallback
)(
void
*
user_pointer
,
const
MSPicture
*
local_view
,
const
MSPicture
*
remote_view
);
typedef
enum
_VideoStreamDir
{
VideoStreamSendRecv
,
VideoStreamSendOnly
,
VideoStreamRecvOnly
}
VideoStreamDir
;
struct
_VideoStream
{
MSTicker
*
ticker
;
...
...
@@ -182,17 +195,23 @@ struct _VideoStream
VideoStreamRenderCallback
rendercb
;
void
*
render_pointer
;
char
*
display_name
;
VideoStreamDir
dir
;
bool_t
adapt_bitrate
;
};
typedef
struct
_VideoStream
VideoStream
;
VideoStream
*
video_stream_new
(
int
locport
,
bool_t
use_ipv6
);
void
video_stream_set_direction
(
VideoStream
*
vs
,
VideoStreamDir
dir
);
void
video_stream_enable_adaptive_bitrate_control
(
VideoStream
*
s
,
bool_t
yesno
);
void
video_stream_set_render_callback
(
VideoStream
*
s
,
VideoStreamRenderCallback
cb
,
void
*
user_pointer
);
void
video_stream_set_display_filter_name
(
VideoStream
*
s
,
const
char
*
fname
);
int
video_stream_start
(
VideoStream
*
stream
,
RtpProfile
*
profile
,
const
char
*
remip
,
int
remport
,
int
rem_rtcp_port
,
int
payload
,
int
jitt_comp
,
MSWebCam
*
device
);
void
video_stream_set_relay_session_id
(
VideoStream
*
stream
,
const
char
*
relay_session_id
);
void
video_stream_set_rtcp_information
(
VideoStream
*
st
,
const
char
*
cname
,
const
char
*
tool
);
/*function to call periodically to handle various events */
...
...
@@ -203,17 +222,17 @@ void video_stream_set_sent_video_size(VideoStream *stream, MSVideoSize vsize);
void
video_stream_enable_self_view
(
VideoStream
*
stream
,
bool_t
val
);
unsigned
long
video_stream_get_native_window_id
(
VideoStream
*
stream
);
/*provided for compatibility, use video_stream_set_direction() instead */
int
video_stream_recv_only_start
(
VideoStream
*
videostream
,
RtpProfile
*
profile
,
const
char
*
addr
,
int
port
,
int
used_pt
,
int
jitt_comp
);
int
video_stream_send_only_start
(
VideoStream
*
videostream
,
RtpProfile
*
profile
,
const
char
*
addr
,
int
port
,
int
rtcp_port
,
int
used_pt
,
int
jitt_comp
,
MSWebCam
*
device
);
void
video_stream_recv_only_stop
(
VideoStream
*
vs
);
void
video_stream_send_only_stop
(
VideoStream
*
vs
);
VideoStream
*
video_preview_start
(
MSWebCam
*
device
,
MSVideoSize
vsize
);
void
video_preview_stop
(
VideoStream
*
stream
);
int
video_stream_recv_only_start
(
VideoStream
*
stream
,
RtpProfile
*
profile
,
const
char
*
remip
,
int
remport
,
int
payload
,
int
jitt_comp
);
int
video_stream_send_only_start
(
VideoStream
*
stream
,
RtpProfile
*
profile
,
const
char
*
remip
,
int
remport
,
int
rem_rtcp_port
,
int
payload
,
int
jitt_comp
,
MSWebCam
*
device
);
void
video_stream_recv_only_stop
(
VideoStream
*
stream
);
void
video_stream_send_only_stop
(
VideoStream
*
stream
);
bool_t
ms_is_ipv6
(
const
char
*
address
);
#ifdef __cplusplus
...
...
src/audiostream.c
View file @
6dd1b2b5
...
...
@@ -47,7 +47,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
/* this code is not part of the library itself, it is part of the mediastream program */
void
audio_stream_free
(
AudioStream
*
stream
)
{
if
(
stream
->
session
!=
NULL
)
rtp_session_destroy
(
stream
->
session
);
if
(
stream
->
session
!=
NULL
)
{
rtp_session_unregister_event_queue
(
stream
->
session
,
stream
->
evq
);
rtp_session_destroy
(
stream
->
session
);
}
if
(
stream
->
evq
)
ortp_ev_queue_destroy
(
stream
->
evq
);
if
(
stream
->
rtpsend
!=
NULL
)
ms_filter_destroy
(
stream
->
rtpsend
);
if
(
stream
->
rtprecv
!=
NULL
)
ms_filter_destroy
(
stream
->
rtprecv
);
if
(
stream
->
soundread
!=
NULL
)
ms_filter_destroy
(
stream
->
soundread
);
...
...
@@ -62,6 +66,7 @@ void audio_stream_free(AudioStream *stream)
if
(
stream
->
ticker
!=
NULL
)
ms_ticker_destroy
(
stream
->
ticker
);
if
(
stream
->
read_resampler
!=
NULL
)
ms_filter_destroy
(
stream
->
read_resampler
);
if
(
stream
->
write_resampler
!=
NULL
)
ms_filter_destroy
(
stream
->
write_resampler
);
if
(
stream
->
dtmfgen_rtp
!=
NULL
)
ms_filter_destroy
(
stream
->
dtmfgen_rtp
);
ms_free
(
stream
);
}
...
...
@@ -142,6 +147,15 @@ bool_t audio_stream_alive(AudioStream * stream, int timeout){
RtpSession
*
session
=
stream
->
session
;
const
rtp_stats_t
*
stats
=
rtp_session_get_stats
(
session
);
if
(
stats
->
recv
!=
0
){
if
(
stream
->
evq
){
OrtpEvent
*
ev
=
ortp_ev_queue_get
(
stream
->
evq
);
if
(
ev
!=
NULL
){
if
(
ortp_event_get_type
(
ev
)
==
ORTP_EVENT_RTCP_PACKET_RECEIVED
){
stream
->
last_packet_time
=
ms_time
(
NULL
);
}
ortp_event_destroy
(
ev
);
}
}
if
(
stats
->
recv
!=
stream
->
last_packet_count
){
stream
->
last_packet_count
=
stats
->
recv
;
stream
->
last_packet_time
=
ms_time
(
NULL
);
...
...
@@ -193,7 +207,6 @@ static void payload_type_changed(RtpSession *session, unsigned long data){
audio_stream_change_decoder
(
stream
,
pt
);
}
int
audio_stream_start_full
(
AudioStream
*
stream
,
RtpProfile
*
profile
,
const
char
*
remip
,
int
remport
,
int
rem_rtcp_port
,
int
payload
,
int
jitt_comp
,
const
char
*
infile
,
const
char
*
outfile
,
MSSndCard
*
playcard
,
MSSndCard
*
captcard
,
bool_t
use_ec
)
...
...
@@ -202,6 +215,7 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
PayloadType
*
pt
;
int
tmp
;
MSConnectionHelper
h
;
int
sample_rate
;
rtp_session_set_profile
(
rtps
,
profile
);
if
(
remport
>
0
)
rtp_session_set_remote_addr_full
(
rtps
,
remip
,
remport
,
rem_rtcp_port
);
...
...
@@ -217,7 +231,7 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
stream
->
dtmfgen
=
ms_filter_new
(
MS_DTMF_GEN_ID
);
rtp_session_signal_connect
(
rtps
,
"telephone-event"
,(
RtpCallback
)
on_dtmf_received
,(
unsigned
long
)
stream
);
rtp_session_signal_connect
(
rtps
,
"payload_type_changed"
,(
RtpCallback
)
payload_type_changed
,(
unsigned
long
)
stream
);
rtp_session_signal_connect
(
rtps
,
"payload_type_changed"
,(
RtpCallback
)
payload_type_changed
,(
unsigned
long
)
stream
);
/* creates the local part */
if
(
captcard
!=
NULL
)
stream
->
soundread
=
ms_snd_card_create_reader
(
captcard
);
else
{
...
...
@@ -237,6 +251,18 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
ms_error
(
"audiostream.c: undefined payload type."
);
return
-
1
;
}
if
(
rtp_profile_get_payload_from_mime
(
profile
,
"telephone-event"
)
==
NULL
&&
(
strcasecmp
(
pt
->
mime_type
,
"pcmu"
)
==
0
||
strcasecmp
(
pt
->
mime_type
,
"pcma"
)
==
0
)){
/*if no telephone-event payload is usable and pcma or pcmu is used, we will generate
inband dtmf*/
stream
->
dtmfgen_rtp
=
ms_filter_new
(
MS_DTMF_GEN_ID
);
}
if
(
ms_filter_call_method
(
stream
->
rtpsend
,
MS_FILTER_GET_SAMPLE_RATE
,
&
sample_rate
)
!=
0
){
ms_error
(
"Sample rate is unknown for RTP side !"
);
return
-
1
;
}
stream
->
encoder
=
ms_filter_create_encoder
(
pt
->
mime_type
);
stream
->
decoder
=
ms_filter_create_decoder
(
pt
->
mime_type
);
if
((
stream
->
encoder
==
NULL
)
||
(
stream
->
decoder
==
NULL
)){
...
...
@@ -270,12 +296,12 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
}
/* give the sound filters some properties */
if
(
ms_filter_call_method
(
stream
->
soundread
,
MS_FILTER_SET_SAMPLE_RATE
,
&
pt
->
clock
_rate
)
!=
0
)
{
if
(
ms_filter_call_method
(
stream
->
soundread
,
MS_FILTER_SET_SAMPLE_RATE
,
&
sample
_rate
)
!=
0
)
{
/* need to add resampler*/
if
(
stream
->
read_resampler
==
NULL
)
stream
->
read_resampler
=
ms_filter_new
(
MS_RESAMPLE_ID
);
}
if
(
ms_filter_call_method
(
stream
->
soundwrite
,
MS_FILTER_SET_SAMPLE_RATE
,
&
pt
->
clock
_rate
)
!=
0
)
{
if
(
ms_filter_call_method
(
stream
->
soundwrite
,
MS_FILTER_SET_SAMPLE_RATE
,
&
sample
_rate
)
!=
0
)
{
/* need to add resampler*/
if
(
stream
->
write_resampler
==
NULL
)
stream
->
write_resampler
=
ms_filter_new
(
MS_RESAMPLE_ID
);
}
...
...
@@ -286,7 +312,7 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
/*configure the echo canceller if required */
if
(
use_ec
)
{
stream
->
ec
=
ms_filter_new
(
MS_SPEEX_EC_ID
);
ms_filter_call_method
(
stream
->
ec
,
MS_FILTER_SET_SAMPLE_RATE
,
&
pt
->
clock
_rate
);
ms_filter_call_method
(
stream
->
ec
,
MS_FILTER_SET_SAMPLE_RATE
,
&
sample
_rate
);
if
(
stream
->
ec_tail_len
!=
0
)
ms_filter_call_method
(
stream
->
ec
,
MS_ECHO_CANCELLER_SET_TAIL_LENGTH
,
&
stream
->
ec_tail_len
);
if
(
stream
->
ec_delay
!=
0
){
...
...
@@ -339,6 +365,8 @@ int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char
ms_connection_helper_link
(
&
h
,
stream
->
ec
,
1
,
1
);
if
(
stream
->
volsend
)
ms_connection_helper_link
(
&
h
,
stream
->
volsend
,
0
,
0
);
if
(
stream
->
dtmfgen_rtp
)
ms_connection_helper_link
(
&
h
,
stream
->
dtmfgen_rtp
,
0
,
0
);
ms_connection_helper_link
(
&
h
,
stream
->
encoder
,
0
,
0
);
ms_connection_helper_link
(
&
h
,
stream
->
rtpsend
,
0
,
-
1
);
...
...
@@ -441,6 +469,8 @@ AudioStream *audio_stream_new(int locport, bool_t ipv6){
AudioStream
*
stream
=
(
AudioStream
*
)
ms_new0
(
AudioStream
,
1
);
stream
->
session
=
create_duplex_rtpsession
(
locport
,
ipv6
);
stream
->
rtpsend
=
ms_filter_new
(
MS_RTP_SEND_ID
);
stream
->
evq
=
ortp_ev_queue_new
();
rtp_session_register_event_queue
(
stream
->
session
,
stream
->
evq
);
stream
->
play_dtmfs
=
TRUE
;
stream
->
use_gc
=
FALSE
;
stream
->
use_agc
=
FALSE
;
...
...
@@ -558,32 +588,48 @@ RingStream * ring_start_with_cb(const char *file,int interval,MSSndCard *sndcard
int
tmp
;
stream
=
(
RingStream
*
)
ms_new0
(
RingStream
,
1
);
stream
->
source
=
ms_filter_new
(
MS_FILE_PLAYER_ID
);
if
(
ms_filter_call_method
(
stream
->
source
,
MS_FILE_PLAYER_OPEN
,(
void
*
)
file
)
<
0
){
ms_filter_destroy
(
stream
->
source
);
ms_free
(
stream
);
return
NULL
;
}
if
(
file
)
ms_filter_call_method
(
stream
->
source
,
MS_FILE_PLAYER_OPEN
,(
void
*
)
file
);
ms_filter_call_method
(
stream
->
source
,
MS_FILE_PLAYER_LOOP
,
&
interval
);
ms_filter_call_method_noarg
(
stream
->
source
,
MS_FILE_PLAYER_START
);
if
(
func
!=
NULL
)
ms_filter_set_notify_callback
(
stream
->
source
,
func
,
user_data
);
stream
->
gendtmf
=
ms_filter_new
(
MS_DTMF_GEN_ID
);
stream
->
sndwrite
=
ms_snd_card_create_writer
(
sndcard
);
ms_filter_call_method
(
stream
->
source
,
MS_FILTER_GET_SAMPLE_RATE
,
&
tmp
);
ms_filter_call_method
(
stream
->
gendtmf
,
MS_FILTER_SET_SAMPLE_RATE
,
&
tmp
);
ms_filter_call_method
(
stream
->
sndwrite
,
MS_FILTER_SET_SAMPLE_RATE
,
&
tmp
);
ms_filter_call_method
(
stream
->
source
,
MS_FILTER_GET_NCHANNELS
,
&
tmp
);
ms_filter_call_method
(
stream
->
gendtmf
,
MS_FILTER_SET_NCHANNELS
,
&
tmp
);
ms_filter_call_method
(
stream
->
sndwrite
,
MS_FILTER_SET_NCHANNELS
,
&
tmp
);
stream
->
ticker
=
ms_ticker_new
();
ms_ticker_set_name
(
stream
->
ticker
,
"Audio (ring) MSTicker"
);
ms_filter_link
(
stream
->
source
,
0
,
stream
->
sndwrite
,
0
);
ms_filter_link
(
stream
->
source
,
0
,
stream
->
gendtmf
,
0
);
ms_filter_link
(
stream
->
gendtmf
,
0
,
stream
->
sndwrite
,
0
);
ms_ticker_attach
(
stream
->
ticker
,
stream
->
source
);
return
stream
;
}
void
ring_play_dtmf
(
RingStream
*
stream
,
char
dtmf
,
int
duration_ms
){
if
(
duration_ms
>
0
)
ms_filter_call_method
(
stream
->
gendtmf
,
MS_DTMF_GEN_PLAY
,
&
dtmf
);
else
ms_filter_call_method
(
stream
->
gendtmf
,
MS_DTMF_GEN_START
,
&
dtmf
);
}
void
ring_stop_dtmf
(
RingStream
*
stream
){
ms_filter_call_method_noarg
(
stream
->
gendtmf
,
MS_DTMF_GEN_STOP
);
}
void
ring_stop
(
RingStream
*
stream
){
ms_ticker_detach
(
stream
->
ticker
,
stream
->
source
);
ms_filter_unlink
(
stream
->
source
,
0
,
stream
->
sndwrite
,
0
);
ms_filter_unlink
(
stream
->
source
,
0
,
stream
->
gendtmf
,
0
);
ms_filter_unlink
(
stream
->
gendtmf
,
0
,
stream
->
sndwrite
,
0
);
ms_ticker_destroy
(
stream
->
ticker
);
ms_filter_destroy
(
stream
->
source
);
ms_filter_destroy
(
stream
->
gendtmf
);
ms_filter_destroy
(
stream
->
sndwrite
);
ms_free
(
stream
);
#ifdef _WIN32_WCE
...
...
@@ -595,10 +641,10 @@ void ring_stop(RingStream *stream){
int
audio_stream_send_dtmf
(
AudioStream
*
stream
,
char
dtmf
)
{
if
(
stream
->
rtpsend
)
if
(
stream
->
dtmfgen_rtp
)
ms_filter_call_method
(
stream
->
dtmfgen_rtp
,
MS_DTMF_GEN_PLAY
,
&
dtmf
);
else
if
(
stream
->
rtpsend
)
ms_filter_call_method
(
stream
->
rtpsend
,
MS_RTP_SEND_SEND_DTMF
,
&
dtmf
);
if
(
stream
->
dtmfgen
)
ms_filter_call_method
(
stream
->
dtmfgen
,
MS_DTMF_GEN_PUT
,
&
dtmf
);
return
0
;
}
...
...
src/dtmfgen.c
View file @
6dd1b2b5
...
...
@@ -18,6 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "mediastreamer2/dtmfgen.h"
#include "mediastreamer2/msticker.h"
#include <math.h>
...
...
@@ -26,12 +27,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define M_PI 3.14159265358979323846
#endif
#define NO_SAMPLES_THRESHOLD 100
/*ms*/
#define TRAILLING_SILENCE 500
/*ms*/
struct
DtmfGenState
{
int
rate
;
int
dur
;
int
pos
;
float
highfreq
;
float
lowfreq
;
int
nosamples_time
;
int
silence
;
char
dtmf
;
};
...
...
@@ -43,6 +49,8 @@ static void dtmfgen_init(MSFilter *f){
s
->
dur
=
s
->
rate
/
10
;
s
->
pos
=
0
;
s
->
dtmf
=
0
;
s
->
nosamples_time
=
0
;
s
->
silence
=
0
;
f
->
data
=
s
;
}
...
...
@@ -123,45 +131,94 @@ static int dtmfgen_put(MSFilter *f, void *arg){
ms_warning
(
"Not a dtmf key."
);
return
-
1
;
}
ms_filter_lock
(
f
);
s
->
lowfreq
=
s
->
lowfreq
/
s
->
rate
;
s
->
highfreq
=
s
->
highfreq
/
s
->
rate
;
s
->
dur
=
s
->
rate
/
10
;
/*100 ms duration */
s
->
silence
=
0
;
s
->
dtmf
=
dtmf
[
0
];
ms_filter_unlock
(
f
);
return
0
;
}
static
int
dtmfgen_start
(
MSFilter
*
f
,
void
*
arg
){
if
(
dtmfgen_put
(
f
,
arg
)
==
0
){
DtmfGenState
*
s
=
(
DtmfGenState
*
)
f
->
data
;
s
->
dur
=
5
*
s
->
rate
;
return
0
;
}
return
-
1
;
}
static
int
dtmfgen_stop
(
MSFilter
*
f
,
void
*
arg
){
DtmfGenState
*
s
=
(
DtmfGenState
*
)
f
->
data
;
s
->
dtmf
=
0
;
return
0
;
}
static
int
dtmfgen_set_rate
(
MSFilter
*
f
,
void
*
arg
){
DtmfGenState
*
s
=
(
DtmfGenState
*
)
f
->
data
;
s
->
rate
=*
((
int
*
)
arg
);
s
->
dur
=
s
->
rate
/
10
;
return
0
;
}
static
void
write_dtmf
(
DtmfGenState
*
s
,
int16_t
*
sample
,
int
nsamples
){
int
i
;
for
(
i
=
0
;
i
<
nsamples
&&
s
->
pos
<
s
->
dur
;
i
++
,
s
->
pos
++
){
sample
[
i
]
=
(
int16_t
)(
10000
.
0
*
sin
(
2
*
M_PI
*
(
float
)
s
->
pos
*
s
->
lowfreq
));
sample
[
i
]
+=
(
int16_t
)(
10000
.
0
*
sin
(
2
*
M_PI
*
(
float
)
s
->
pos
*
s
->
highfreq
));
}
if
(
s
->
pos
==
s
->
dur
){
s
->
pos
=
0
;
s
->
dtmf
=
0
;
s
->
silence
=
TRAILLING_SILENCE
;
}
}
static
void
dtmfgen_process
(
MSFilter
*
f
){
mblk_t
*
m
;
DtmfGenState
*
s
=
(
DtmfGenState
*
)
f
->
data
;
int
nsamples
;
while
((
m
=
ms_queue_get
(
f
->
inputs
[
0
]))
!=
NULL
){
if
(
s
->
dtmf
!=
0
){
int
nsamples
=
(
m
->
b_wptr
-
m
->
b_rptr
)
/
2
;
int
i
;
int16_t
*
sample
=
(
int16_t
*
)
m
->
b_rptr
;
for
(
i
=
0
;
i
<
nsamples
&&
s
->
pos
<
s
->
dur
;
i
++
,
s
->
pos
++
){
sample
[
i
]
=
(
int16_t
)(
10000
.
0
*
sin
(
2
*
M_PI
*
(
float
)
s
->
pos
*
s
->
lowfreq
));
sample
[
i
]
+=
(
int16_t
)(
10000
.
0
*
sin
(
2
*
M_PI
*
(
float
)
s
->
pos
*
s
->
highfreq
));
ms_filter_lock
(
f
);
if
(
ms_queue_empty
(
f
->
inputs
[
0
])){
s
->
nosamples_time
+=
f
->
ticker
->
interval
;
if
((
s
->
dtmf
!=
0
||
s
->
silence
!=
0
)
&&
s
->
nosamples_time
>
NO_SAMPLES_THRESHOLD
){
/*after 100 ms without stream we decide to generate our own sample
instead of writing into incoming stream samples*/
nsamples
=
(
f
->
ticker
->
interval
*
s
->
rate
)
/
1000
;
m
=
allocb
(
nsamples
*
2
,
0
);
if
(
s
->
silence
==
0
){
write_dtmf
(
s
,(
int16_t
*
)
m
->
b_wptr
,
nsamples
);
}
else
{
memset
(
m
->
b_wptr
,
0
,
nsamples
*
2
);
s
->
silence
-=
f
->
ticker
->
interval
;
if
(
s
->
silence
<
0
)
s
->
silence
=
0
;
}
if
(
s
->
pos
==
s
->
dur
){
s
->
pos
=
0
;
s
->
dtmf
=
0
;
m
->
b_wptr
+=
nsamples
*
2
;
ms_queue_put
(
f
->
outputs
[
0
],
m
);
}
}
else
{
s
->
nosamples_time
=
0
;
s
->
silence
=
0
;
while
((
m
=
ms_queue_get
(
f
->
inputs
[
0
]))
!=
NULL
){
if
(
s
->
dtmf
!=
0
){
nsamples
=
(
m
->
b_wptr
-
m
->
b_rptr
)
/
2
;
write_dtmf
(
s
,
(
int16_t
*
)
m
->
b_rptr
,
nsamples
);
}
ms_queue_put
(
f
->
outputs
[
0
],
m
);
}
ms_queue_put
(
f
->
outputs
[
0
],
m
);
}
ms_filter_unlock
(
f
);
}
MSFilterMethod
dtmfgen_methods
[]
=
{
{
MS_FILTER_SET_SAMPLE_RATE
,
dtmfgen_set_rate
},
{
MS_DTMF_GEN_PUT
,
dtmfgen_put
},
{
MS_DTMF_GEN_PLAY
,
dtmfgen_put
},
{
MS_DTMF_GEN_START
,
dtmfgen_start
},
{
MS_DTMF_GEN_STOP
,
dtmfgen_stop
},
{
0
,
NULL
}
};
...
...
@@ -180,7 +237,8 @@ MSFilterDesc ms_dtmf_gen_desc={
dtmfgen_process
,
NULL
,
dtmfgen_uninit
,
dtmfgen_methods
dtmfgen_methods
,
MS_FILTER_IS_PUMP
};
#else
...
...
@@ -195,7 +253,8 @@ MSFilterDesc ms_dtmf_gen_desc={
.
init
=
dtmfgen_init
,
.
process
=
dtmfgen_process
,
.
uninit
=
dtmfgen_uninit
,
.
methods
=
dtmfgen_methods
.
methods
=
dtmfgen_methods
,
.
flags
=
MS_FILTER_IS_PUMP
};
#endif
...
...
src/msrtp.c
View file @
6dd1b2b5
...
...
@@ -30,6 +30,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
struct
SenderData
{
RtpSession
*
session
;
uint32_t
tsoff
;
uint32_t
last_ts
;
int64_t
last_sent_time
;
uint32_t
skip_until
;
int
rate
;
char
dtmf
;
...
...
@@ -59,6 +61,8 @@ static void sender_init(MSFilter * f)
d
->
mute_mic
=
FALSE
;
d
->
relay_session_id_size
=
0
;
d
->
last_rsi_time
=
0
;
d
->
last_sent_time
=-
1
;
d
->
last_ts
=
0
;
f
->
data
=
d
;
}
...
...
@@ -100,9 +104,7 @@ static int sender_set_session(MSFilter * f, void *arg)
rtp_profile_get_payload
(
rtp_session_get_profile
(
s
),
rtp_session_get_send_payload_type
(
s
));
if
(
pt
!=
NULL
)
{
if
(
strcasecmp
(
"g722"
,
pt
->
mime_type
)
==
0
)
d
->
rate
=
8000
;
else
d
->
rate
=
pt
->
clock_rate
;
d
->
rate
=
pt
->
clock_rate
;
}
else
{
ms_warning
(
"Sending undefined payload type ?"
);
}
...
...
@@ -137,7 +139,22 @@ static int sender_set_relay_session_id(MSFilter *f, void*arg){
static
int
sender_get_sr
(
MSFilter
*
f
,
void
*
arg
){
SenderData
*
d
=
(
SenderData
*
)
f
->
data
;
*
(
int
*
)
arg
=
d
->
rate
;
PayloadType
*
pt
;
if
(
d
->
session
==
NULL
)
{
ms_warning
(
"Could not obtain sample rate, session is not set."
);
return
-
1
;
}
pt
=
rtp_profile_get_payload
(
rtp_session_get_profile
(
d
->
session
),
rtp_session_get_recv_payload_type
(
d
->
session
));
if
(
pt
!=
NULL
)
{
if
(
strcasecmp
(
pt
->
mime_type
,
"G722"
)
==
0
)
*
(
int
*
)
arg
=
16000
;
else
*
(
int
*
)
arg
=
pt
->
clock_rate
;
}
else
{
ms_warning
(
"MSRtpSend: Could not obtain sample rate, payload type is unknown."
);
return
-
1
;
}
return
0
;
}
...
...
@@ -146,32 +163,26 @@ static uint32_t get_cur_timestamp(MSFilter * f, uint32_t packet_ts)
{
SenderData
*
d
=
(
SenderData
*
)
f
->
data
;
uint32_t
curts
=
(
uint32_t
)(
(
f
->
ticker
->
time
*
(
uint64_t
)
d
->
rate
)
/
(
uint64_t
)
1000
)
;
int
diff
;
int
delta
=
d
->
rate
/
50
;
/*20 ms at 8000Hz */
int
diffts
;
uint32_t
netts
;
int
difftime_ts
;
netts
=
packet_ts
+
d
->
tsoff
;
diff
=
curts
-
netts
;
#ifdef AMD_HACK
if
(
diff
>
delta
)
{
d
->
tsoff
=
curts
-
packet_ts
;
netts
=
packet_ts
+
d
->
tsoff
;
ms_message
(
"synchronizing timestamp, diff=%i"
,
diff
);
}
else
if
(
diff
<
-
delta
)
{
/* d->tsoff = curts - packet_ts; */
/* hardware clock is going slower than sound card on my PDA... */
}
#else
if
((
diff
>
delta
)
||
(
diff
<
-
(
delta
*
5
)))
{
if
(
d
->
last_sent_time
==-
1
){
d
->
tsoff
=
curts
-
packet_ts
;
netts
=
packet_ts
+
d
->
tsoff
;
ms_message
(
"synchronizing timestamp, diff=%i"
,
diff
);
}
else
{
diffts
=
packet_ts
-
d
->
last_ts
;
difftime_ts
=
((
f
->
ticker
->
time
-
d
->
last_sent_time
)
*
d
->
rate
)
/
1000
;
/* detect timestamp jump in the stream and adjust so that they become continuous on the network*/
if
(
abs
(
diffts
-
difftime_ts
)
>
(
d
->
rate
/
5
)){
uint32_t
tsoff
=
curts
-
packet_ts
;
ms_message
(
"Adjusting output timestamp by %i"
,(
tsoff
-
d
->
tsoff
));
d
->
tsoff
=
tsoff
;
}
}
#endif
/*ms_message("returned ts=%u, orig_ts=%u",netts,packet_ts); */
netts
=
packet_ts
+
d
->
tsoff
;
d
->
last_sent_time
=
f
->
ticker
->
time
;
d
->
last_ts
=
packet_ts
;
return
netts
;
}
...
...
@@ -417,9 +428,7 @@ static int receiver_set_session(MSFilter * f, void *arg)
rtp_session_get_recv_payload_type
(
s
));
if
(
pt
!=
NULL
)
{
if
(
strcasecmp
(
"g722"
,
pt
->
mime_type
)
==
0
)
d
->
rate
=
8000
;
else
d
->
rate
=
pt
->
clock_rate
;
d
->
rate
=
pt
->
clock_rate
;
}
else
{
ms_warning
(
"Receiving undefined payload type %i ?"
,
rtp_session_get_recv_payload_type
(
s
));
...
...
@@ -439,7 +448,10 @@ static int receiver_get_sr(MSFilter *f, void *arg){
pt
=
rtp_profile_get_payload
(
rtp_session_get_profile
(
d
->
session
),
rtp_session_get_recv_payload_type
(
d
->
session
));
if
(
pt
!=
NULL
)
{
*
(
int
*
)
arg
=
pt
->
clock_rate
;
if
(
strcasecmp
(
pt
->
mime_type
,
"G722"
)
==
0
)
*
(
int
*
)
arg
=
16000
;
else
*
(
int
*
)
arg
=
pt
->
clock_rate
;
}
else
{
ms_warning
(
"Could not obtain sample rate, payload type is unknown."
);
return
-
1
;
...
...
src/mtu.c
View file @
6dd1b2b5
...
...
@@ -209,7 +209,7 @@ int ms_discover_mtu(const char *host){
mtu
=
1500
-
28
;
//was the size of the inital buf
do
{
int
send_returned
;
char
*
buf
=
ms_malloc
(
mtu
);
//avoid mtu greater than the beginning
char
*
buf
=
ms_malloc
0
(
mtu
);
//avoid mtu greater than the beginning
if
(
buf
==
NULL
)
{
ms_error
(
"malloc(): %s"
,
strerror
(
errno
));
...
...
@@ -220,14 +220,6 @@ int ms_discover_mtu(const char *host){
}
send_returned
=
send
(
sock
,
buf
,
mtu
,
0
);
ms_free
(
buf
);
if
(
send_returned
<
0
)
//mtu actually change...
{
ms_error
(
"send(): %s"
,
strerror
(
errno
));
err
=
close
(
sock
);
if
(
err
!=
0
)
ms_error
(
"close(): %s"
,
strerror
(
errno
));
return
-
1
;
}