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
fe3455c6
Commit
fe3455c6
authored
May 13, 2014
by
Gautier Pelloux-Prayer
Browse files
first try to handle congestion state and some test refactoring
parent
31e2602a
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
152 additions
and
131 deletions
+152
-131
include/mediastreamer2/bitratecontrol.h
include/mediastreamer2/bitratecontrol.h
+7
-3
include/mediastreamer2/mediastream.h
include/mediastreamer2/mediastream.h
+6
-6
src/voip/mediastream.c
src/voip/mediastream.c
+21
-21
src/voip/qosanalyzer.c
src/voip/qosanalyzer.c
+67
-75
tester/mediastreamer2_audio_stream_tester.c
tester/mediastreamer2_audio_stream_tester.c
+2
-0
tester/mediastreamer2_video_stream_tester.c
tester/mediastreamer2_video_stream_tester.c
+49
-26
No files found.
include/mediastreamer2/bitratecontrol.h
View file @
fe3455c6
...
...
@@ -86,7 +86,7 @@ struct _MSQosAnalyserDesc{
};
/**
* A MSQosAnaly
z
er is responsible to analyze RTCP feedback and suggest actions on bitrate or packet rate accordingly.
* A MSQosAnaly
s
er is responsible to analyze RTCP feedback and suggest actions on bitrate or packet rate accordingly.
* This is an abstract interface.
**/
struct
_MSQosAnalyser
{
...
...
@@ -94,15 +94,19 @@ struct _MSQosAnalyser{
int
refcnt
;
};
#define MS_QOS_ANALYSER_NETWORK_FINE 0
#define MS_QOS_ANALYSER_NETWORK_UNSTABLE 1
#define MS_QOS_ANALYSER_NETWORK_CONGESTED 2
MSQosAnalyser
*
ms_qos_analyser_ref
(
MSQosAnalyser
*
obj
);
void
ms_qos_analyser_unref
(
MSQosAnalyser
*
obj
);
void
ms_qos_analyser_suggest_action
(
MSQosAnalyser
*
obj
,
MSRateControlAction
*
action
);
bool_t
ms_qos_analyser_has_improved
(
MSQosAnalyser
*
obj
);
bool
_t
ms_qos_analyser_
is
_network_sta
bl
e
(
const
MSQosAnalyser
*
obj
);
uint32
_t
ms_qos_analyser_
get
_network_sta
t
e
(
const
MSQosAnalyser
*
obj
);
bool_t
ms_qos_analyser_process_rtcp
(
MSQosAnalyser
*
obj
,
mblk_t
*
rtcp
);
/**
* The simple qos analy
z
er is an implementation of MSQosAnalyser that performs analysis for single stream.
* The simple qos analy
s
er is an implementation of MSQosAnalyser that performs analysis for single stream.
**/
MSQosAnalyser
*
ms_simple_qos_analyser_new
(
RtpSession
*
session
);
...
...
include/mediastreamer2/mediastream.h
View file @
fe3455c6
...
...
@@ -288,11 +288,11 @@ MS2_PUBLIC int audio_stream_start_with_files (AudioStream * stream, RtpProfile *
/**
* Starts an audio stream from/to local wav files or soundcards.
*
*
* This method starts the processing of the audio stream, that is playing from wav file or soundcard, voice processing, encoding,
* sending through RTP, receiving from RTP, decoding, voice processing and wav file recording or soundcard playback.
*
*
*
*
* @param stream an AudioStream previously created with audio_stream_new().
* @param prof a RtpProfile containing all PayloadType possible during the audio session.
* @param rem_rtp_ip remote IP address where to send the encoded audio.
...
...
@@ -362,16 +362,16 @@ MS2_PUBLIC AudioStream *audio_stream_new_with_sessions(const MSMediaStreamSessio
MS2_PUBLIC
uint32_t
audio_stream_get_features
(
AudioStream
*
st
);
MS2_PUBLIC
void
audio_stream_set_features
(
AudioStream
*
st
,
uint32_t
features
);
MS2_PUBLIC
void
audio_stream_prepare_sound
(
AudioStream
*
st
,
MSSndCard
*
playcard
,
MSSndCard
*
captcard
);
MS2_PUBLIC
void
audio_stream_unprepare_sound
(
AudioStream
*
st
);
MS2_PUBLIC
bool_t
audio_stream_started
(
AudioStream
*
stream
);
/**
* Starts an audio stream from local soundcards.
*
*
* This method starts the processing of the audio stream, that is capture from soundcard, voice processing, encoding,
* sending through RTP, receiving from RTP, decoding, voice processing and soundcard playback.
*
*
* @param stream an AudioStream previously created with audio_stream_new().
* @param prof a RtpProfile containing all PayloadType possible during the audio session.
* @param remip remote IP address where to send the encoded audio.
...
...
src/voip/mediastream.c
View file @
fe3455c6
...
...
@@ -45,7 +45,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef MS_MINIMAL_MTU
/*this is used for determining the minimum size of recv buffers for RTP packets
Keep 1500 for maximum interoparibility*/
#define MS_MINIMAL_MTU 1500
#define MS_MINIMAL_MTU 1500
#endif
...
...
@@ -81,12 +81,12 @@ static void media_stream_change_decoder(MediaStream *stream, int payload) {
RtpSession
*
session
=
stream
->
sessions
.
rtp_session
;
RtpProfile
*
prof
=
rtp_session_get_profile
(
session
);
PayloadType
*
pt
=
rtp_profile_get_payload
(
prof
,
payload
);
if
(
stream
->
decoder
==
NULL
){
ms_message
(
"media_stream_change_decoder(): ignored, no decoder."
);
return
;
}
if
(
pt
!=
NULL
){
MSFilter
*
dec
;
...
...
@@ -226,7 +226,7 @@ void media_stream_free(MediaStream *stream) {
if
(
stream
->
decoder
!=
NULL
)
ms_filter_destroy
(
stream
->
decoder
);
if
(
stream
->
voidsink
!=
NULL
)
ms_filter_destroy
(
stream
->
voidsink
);
if
(
stream
->
qi
)
ms_quality_indicator_destroy
(
stream
->
qi
);
}
void
media_stream_set_rtcp_information
(
MediaStream
*
stream
,
const
char
*
cname
,
const
char
*
tool
)
{
...
...
@@ -262,7 +262,7 @@ static int check_srtp_session_created(MediaStream *stream){
err_status_t
err
;
srtp_t
session
;
RtpTransport
*
rtp
=
NULL
,
*
rtcp
=
NULL
;
err
=
ortp_srtp_create
(
&
session
,
NULL
);
if
(
err
!=
0
)
{
ms_error
(
"Failed to create srtp session (%d)"
,
err
);
...
...
@@ -284,9 +284,9 @@ static bool_t add_srtp_stream(srtp_t srtp, MSCryptoSuite suite, uint32_t ssrc, c
err_status_t
err
;
unsigned
b64_key_length
=
strlen
(
b64_key
);
ssrc_t
ssrc_conf
;
memset
(
&
policy
,
0
,
sizeof
(
policy
));
switch
(
suite
){
case
MS_AES_128_SHA1_32
:
crypto_policy_set_aes_cm_128_hmac_sha1_32
(
&
policy
.
rtp
);
...
...
@@ -330,22 +330,22 @@ static bool_t add_srtp_stream(srtp_t srtp, MSCryptoSuite suite, uint32_t ssrc, c
}
if
(
!
inbound
)
policy
.
allow_repeat_tx
=
1
;
/*necessary for telephone-events*/
/*ssrc_conf.type=inbound ? ssrc_any_inbound : ssrc_specific;*/
ssrc_conf
.
type
=
ssrc_specific
;
ssrc_conf
.
value
=
ssrc
;
policy
.
ssrc
=
ssrc_conf
;
policy
.
key
=
key
;
policy
.
next
=
NULL
;
err
=
srtp_add_stream
(
srtp
,
&
policy
);
if
(
err
!=
err_status_ok
)
{
ortp_error
(
"Failed to add stream to srtp session (%d)"
,
err
);
ortp_free
(
key
);
return
-
1
;
}
ortp_free
(
key
);
return
0
;
}
...
...
@@ -371,7 +371,7 @@ bool_t media_stream_srtp_supported(void){
}
int
media_stream_set_srtp_recv_key
(
MediaStream
*
stream
,
MSCryptoSuite
suite
,
const
char
*
key
){
if
(
!
media_stream_srtp_supported
())
{
ms_error
(
"ortp srtp support disabled in oRTP or mediastreamer2"
);
return
-
1
;
...
...
@@ -380,14 +380,14 @@ int media_stream_set_srtp_recv_key(MediaStream *stream, MSCryptoSuite suite, con
{
uint32_t
ssrc
,
send_ssrc
;
bool_t
updated
=
FALSE
;
if
(
check_srtp_session_created
(
stream
)
==-
1
)
return
-
1
;
/*check if a previous key was configured, in which case remove it*/
send_ssrc
=
rtp_session_get_send_ssrc
(
stream
->
sessions
.
rtp_session
);
ssrc
=
find_other_ssrc
(
stream
->
sessions
.
srtp_session
,
htonl
(
send_ssrc
));
/*careful: remove_stream takes the SSRC in network byte order...*/
if
(
ortp_srtp_remove_stream
(
stream
->
sessions
.
srtp_session
,
ssrc
)
==
0
)
updated
=
TRUE
;
...
...
@@ -401,20 +401,20 @@ int media_stream_set_srtp_recv_key(MediaStream *stream, MSCryptoSuite suite, con
}
int
media_stream_set_srtp_send_key
(
MediaStream
*
stream
,
MSCryptoSuite
suite
,
const
char
*
key
){
if
(
!
media_stream_srtp_supported
())
{
ms_error
(
"ortp srtp support disabled in oRTP or mediastreamer2"
);
return
-
1
;
}
#ifdef ORTP_HAVE_SRTP
{
uint32_t
ssrc
;
bool_t
updated
=
FALSE
;
if
(
check_srtp_session_created
(
stream
)
==-
1
)
return
-
1
;
/*check if a previous key was configured, in which case remove it*/
ssrc
=
rtp_session_get_send_ssrc
(
stream
->
sessions
.
rtp_session
);
if
(
ssrc
!=
0
){
...
...
@@ -465,7 +465,7 @@ void mediastream_payload_type_changed(RtpSession *session, unsigned long data) {
void
media_stream_iterate
(
MediaStream
*
stream
){
time_t
curtime
=
ms_time
(
NULL
);
if
(
stream
->
ice_check_list
)
ice_check_list_process
(
stream
->
ice_check_list
,
stream
->
sessions
.
rtp_session
);
/*we choose to update the quality indicator as much as possible, since local statistics can be computed realtime. */
if
(
stream
->
state
==
MSStreamStarted
){
...
...
@@ -483,7 +483,7 @@ void media_stream_iterate(MediaStream *stream){
OrtpEventType
evt
=
ortp_event_get_type
(
ev
);
if
(
evt
==
ORTP_EVENT_RTCP_PACKET_RECEIVED
){
mblk_t
*
m
=
ortp_event_get_data
(
ev
)
->
packet
;
ms_message
(
"%s
stream
[%p]: receiving RTCP %s%s"
,
media_stream_type_str
(
stream
),
stream
,(
rtcp_is_SR
(
m
)
?
"SR"
:
""
),(
rtcp_is_RR
(
m
)
?
"RR"
:
""
));
ms_message
(
"%s
_
stream
_iterate
[%p]: receiving
[%p]
RTCP %s%s"
,
media_stream_type_str
(
stream
),
stream
,
m
,
(
rtcp_is_SR
(
m
)
?
"SR"
:
""
),(
rtcp_is_RR
(
m
)
?
"RR"
:
""
));
stream
->
process_rtcp
(
stream
,
m
);
}
else
if
(
evt
==
ORTP_EVENT_RTCP_PACKET_EMITTED
){
ms_message
(
"%s_stream_iterate[%p]: local statistics available
\n\t
Local's current jitter buffer size:%f ms"
,
...
...
@@ -493,7 +493,7 @@ void media_stream_iterate(MediaStream *stream){
}
else
if
(
evt
==
ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED
)
{
OrtpEventData
*
evd
=
ortp_event_get_data
(
ev
);
stream
->
sessions
.
is_secured
=
evd
->
info
.
zrtp_stream_encrypted
;
ms_message
(
"%s
stream
[%p] is %s "
,
media_stream_type_str
(
stream
)
,
stream
,
stream
->
sessions
.
is_secured
?
"encrypted"
:
"not encrypted"
);
ms_message
(
"%s
_
stream
_iterate
[%p]
:
is %s "
,
media_stream_type_str
(
stream
)
,
stream
,
stream
->
sessions
.
is_secured
?
"encrypted"
:
"not encrypted"
);
}
ortp_event_destroy
(
ev
);
}
...
...
src/voip/qosanalyzer.c
View file @
fe3455c6
...
...
@@ -24,40 +24,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <math.h>
/**
* Compute the linear interpolation y = m * x + b for a given set of points.
* m is the line slope, b the y-intercept value and x_inter the x-intrecept value
* Returns 1 if x intersection could not be calculated, 0 otherwise
**/
// static int linear_regression(int n, const double x[], const double y[], double* m, double* b, double* x_inter)
// {
// int i;
// double x_sum = 0.;
// double y_sum = 0.;
// double x_square_sum = 0.;
// double x_y_sum = 0.;
// for (i = 0; i < n; i++) {
// x_sum += x[i];
// y_sum += y[i];
// x_y_sum += x[i] * y[i];
// x_square_sum += (x[i]) * (x[i]);
// }
// x_sum /= n;
// y_sum /= n;
// *m = (x_y_sum - x_sum * y_sum * n) /
// (x_square_sum - x_sum * x_sum * n);
// *b = (y_sum - *m * x_sum);
// if (fabs(*m) > 0.000001f) {
// *x_inter = - *b / *m;
// return 0;
// }
// return 1;
// }
/**
* Analyses a received RTCP packet.
* Returns TRUE is relevant information has been found in the rtcp message, FALSE otherwise.
...
...
@@ -138,14 +104,14 @@ typedef struct _MSSimpleQosAnalyser{
bool_t
rt_prop_doubled
;
bool_t
pad
[
3
];
double
points
[
150
][
2
];
bool_t
stable_
network
;
double
points
[
150
][
3
];
uint8_t
network
_state
;
}
MSSimpleQosAnalyser
;
static
bool_t
rt_prop_doubled
(
rtpstats_t
*
cur
,
rtpstats_t
*
prev
){
/
/
ms_message("AudioBitrateController: cur=%f, prev=%f",cur->rt_prop,prev->rt_prop);
/
*
ms_message("AudioBitrateController: cur=%f, prev=%f",cur->rt_prop,prev->rt_prop);
*/
if
(
cur
->
rt_prop
>=
significant_delay
&&
prev
->
rt_prop
>
0
){
if
(
cur
->
rt_prop
>=
(
prev
->
rt_prop
*
2
.
0
)){
/*propagation doubled since last report */
...
...
@@ -166,7 +132,6 @@ static bool_t rt_prop_increased(MSSimpleQosAnalyser *obj){
return
FALSE
;
}
static
bool_t
simple_analyser_process_rtcp
(
MSQosAnalyser
*
objbase
,
mblk_t
*
rtcp
){
MSSimpleQosAnalyser
*
obj
=
(
MSSimpleQosAnalyser
*
)
objbase
;
rtpstats_t
*
cur
;
...
...
@@ -191,8 +156,10 @@ static bool_t simple_analyser_process_rtcp(MSQosAnalyser *objbase, mblk_t *rtcp)
cur
->
lost_percentage
=
100
.
0
*
(
float
)
report_block_get_fraction_lost
(
rb
)
/
256
.
0
;
cur
->
int_jitter
=
1000
.
0
*
(
float
)
report_block_get_interarrival_jitter
(
rb
)
/
(
float
)
obj
->
clockrate
;
cur
->
rt_prop
=
rtp_session_get_round_trip_propagation
(
obj
->
session
);
obj
->
points
[
obj
->
curindex
-
1
][
0
]
=
rtp_session_get_send_bandwidth
(
obj
->
session
)
/
1000
.
0
;
obj
->
points
[
obj
->
curindex
-
1
][
1
]
=
(
float
)
report_block_get_fraction_lost
(
rb
)
/
256
.
0
;
obj
->
points
[
obj
->
curindex
-
1
][
1
]
=
cur
->
lost_percentage
;
obj
->
points
[
obj
->
curindex
-
1
][
2
]
=
cur
->
rt_prop
;
ms_message
(
"MSQosAnalyser: lost_percentage=%f, int_jitter=%f ms, rt_prop=%f sec, send_bw=%f"
,
cur
->
lost_percentage
,
cur
->
int_jitter
,
cur
->
rt_prop
,
obj
->
points
[
obj
->
curindex
][
0
]);
if
(
obj
->
curindex
>
2
)
printf
(
"one more %d: %f %f
\n
"
,
obj
->
curindex
-
1
,
obj
->
points
[
obj
->
curindex
-
1
][
0
],
obj
->
points
[
obj
->
curindex
-
1
][
1
]);
...
...
@@ -202,74 +169,100 @@ static bool_t simple_analyser_process_rtcp(MSQosAnalyser *objbase, mblk_t *rtcp)
static
void
compute_available_bw
(
MSSimpleQosAnalyser
*
obj
){
int
i
;
double
x_
sum
=
0
.;
double
y_
sum
=
0
.;
double
x_
mean
=
0
.;
double
y_
mean
=
0
.;
double
x_square_sum
=
0
.;
double
x_y_sum
=
0
.;
int
last
=
obj
->
curindex
-
1
;
int
f
=
last
>
15
?
last
-
13
:
2
;
//always skip the 2 first ones
int
n
=
(
last
-
f
+
1
);
double
mean_bw
=
0
.;
double
mean_diff
=
0
.;
int
x_min_ind
=
f
;
int
x_max_ind
=
f
;
bool_t
lossy_network
=
FALSE
;
double
diff
,
m
,
b
;
uint8_t
previous_state
=
obj
->
network_state
;
obj
->
network_state
=
MS_QOS_ANALYSER_NETWORK_FINE
;
if
(
n
<=
1
)
{
printf
(
"Estimated BW is %f kbit/s
\n
"
,
obj
->
points
[
0
][
0
]
*
obj
->
points
[
0
][
1
]);
return
;
}
int
count
=
n
;
//(last - f) * (last - f + 1) / 2;
double
mean_bw
=
0
.;
double
avg_dist
=
0
.;
int
x_min_ind
=
f
;
int
x_max_ind
=
f
;
for
(
i
=
f
;
i
<=
last
;
i
++
)
{
double
x
=
obj
->
points
[
i
][
0
];
double
y
=
obj
->
points
[
i
][
1
];
if
(
x
<
obj
->
points
[
x_min_ind
][
0
])
x_min_ind
=
i
;
if
(
x
>
obj
->
points
[
x_max_ind
][
0
])
x_max_ind
=
i
;
double
mul
=
1
;
// (i - f + 1);
// printf("\tadding (%f;%f) of weight %f\n", x, y, mul);
x_sum
+=
x
*
mul
;
y_sum
+=
y
*
mul
;
x_y_sum
+=
x
*
y
*
mul
*
mul
;
x_square_sum
+=
x
*
x
*
mul
*
mul
;
x_mean
+=
x
;
y_mean
+=
y
;
x_y_sum
+=
x
*
y
;
x_square_sum
+=
x
*
x
;
mean_bw
+=
x
*
(
1
-
y
);
}
x_
sum
/=
count
;
y_
sum
/=
count
;
mean_bw
/=
count
;
x_
mean
/=
n
;
y_
mean
/=
n
;
mean_bw
/=
n
;
printf
(
"
\t
Estimated BW by avg is %f kbit/s
\n
"
,
mean_bw
);
printf
(
"sum=%f xmin=%d xmax=%d
\n
"
,
x_sum
,
x_min_ind
,
x_max_ind
);
double
diff
=
(
obj
->
points
[
x_max_ind
][
0
]
-
obj
->
points
[
x_min_ind
][
0
])
/
x_sum
;
printf
(
"sum=%f xmin=%d xmax=%d
\n
"
,
x_mean
,
x_min_ind
,
x_max_ind
);
diff
=
(
obj
->
points
[
x_max_ind
][
0
]
-
obj
->
points
[
x_min_ind
][
0
])
/
x_mean
;
m
=
(
x_y_sum
-
x_mean
*
y_mean
*
n
)
/
(
x_square_sum
-
x_mean
*
x_mean
*
n
);
double
m
=
(
x_y_sum
-
x_sum
*
y_sum
*
count
)
/
(
x_square_sum
-
x_sum
*
x_sum
*
count
);
b
=
(
y_mean
-
m
*
x_mean
);
double
b
=
(
y_sum
-
m
*
x_sum
);
for
(
i
=
f
;
i
<=
last
;
i
++
)
{
double
x
=
obj
->
points
[
i
][
0
];
double
y
=
obj
->
points
[
i
][
1
];
avg
_di
st
+=
fabs
(
m
*
x
+
b
-
y
);
mean
_di
ff
+=
fabs
(
m
*
x
+
b
-
y
);
}
avg
_di
st
/=
count
;
mean
_di
ff
/=
n
;
bool_t
lossy_network
=
avg_dist
>
.
1
;
// to compute estimated BW, we need a minimum sample size
/*to compute estimated BW, we need a minimum x-axis interval size*/
if
(
diff
>
0
.
05
)
{
double
avail_bw
=
(
fabs
(
m
)
>
0
.
0001
f
)
?
-
b
/
m
:
mean_bw
;
printf
(
"
\t
for line is %f kbit/s
\n
"
,
avail_bw
);
printf
(
"
\t\t
y=%f x + %f
\n
"
,
m
,
b
);
double
avail_bw
=
(
fabs
(
m
)
>
0
.
0001
f
)
?
-
b
/
m
:
mean_bw
;
printf
(
"
\t
for line is %f kbit/s:
\t
y=%f x + %f
\n
"
,
avail_bw
,
m
,
b
);
lossy_network
|=
(
m
<
.
03
f
&&
b
>
0
.
05
);
if
(
!
lossy_network
&&
(
m
>
.
03
f
||
b
>
0
.
05
)){
obj
->
network_state
=
MS_QOS_ANALYSER_NETWORK_CONGESTED
;
}
}
else
{
printf
(
"
\t
insufficient difference between BW min and BW max: %f
\n
"
,
diff
);
lossy_network
|=
(
y_mean
>
0
.
05
);
}
if
(
lossy_network
)
{
/*since congestion may loss a high count of packets, stay in congested network while
this is not a bit more stable*/
if
(
previous_state
==
MS_QOS_ANALYSER_NETWORK_CONGESTED
)
{
obj
->
network_state
=
MS_QOS_ANALYSER_NETWORK_CONGESTED
;
}
else
{
obj
->
network_state
=
MS_QOS_ANALYSER_NETWORK_UNSTABLE
;
}
/*another hint for a bad network: packets drop mean difference is high*/
}
else
if
(
mean_diff
>
.
1
)
{
double
rtt
=
obj
->
points
[
last
][
2
];
obj
->
network_state
=
(
rtt
>
.
5
)
?
MS_QOS_ANALYSER_NETWORK_CONGESTED
:
MS_QOS_ANALYSER_NETWORK_UNSTABLE
;
}
printf
(
"
\t
avg_dist=%f
\n
"
,
avg_dist
);
printf
(
"
\t\t
I think it is a %s network
\n
"
,
lossy_network
?
"LOSSY/UNSTABLE"
:
"stable"
);
obj
->
stable_network
=
!
lossy_network
;
if
(
obj
->
network_state
==
MS_QOS_ANALYSER_NETWORK_CONGESTED
)
printf
(
"
\t\t
I think it is a %s network
\n
"
,
"C-O-N-G-E-S-T-E-D"
);
else
if
(
obj
->
network_state
==
MS_QOS_ANALYSER_NETWORK_UNSTABLE
)
printf
(
"
\t\t
I think it is a %s network
\n
"
,
"UNSTABLE"
);
else
printf
(
"
\t\t
I think it is a %s network
\n
"
,
"stable"
);
}
static
void
simple_analyser_suggest_action
(
MSQosAnalyser
*
objbase
,
MSRateControlAction
*
action
){
...
...
@@ -315,9 +308,9 @@ end:
return
FALSE
;
}
bool
_t
ms_qos_analyser_
is
_network_sta
bl
e
(
const
MSQosAnalyser
*
objbase
){
uint32
_t
ms_qos_analyser_
get
_network_sta
t
e
(
const
MSQosAnalyser
*
objbase
){
MSSimpleQosAnalyser
*
obj
=
(
MSSimpleQosAnalyser
*
)
objbase
;
return
obj
->
stable_
network
;
return
obj
->
network
_state
;
}
static
MSQosAnalyserDesc
simple_analyser_desc
=
{
...
...
@@ -330,7 +323,6 @@ MSQosAnalyser * ms_simple_qos_analyser_new(RtpSession *session){
MSSimpleQosAnalyser
*
obj
=
ms_new0
(
MSSimpleQosAnalyser
,
1
);
obj
->
session
=
session
;
obj
->
parent
.
desc
=&
simple_analyser_desc
;
obj
->
stable_network
=
TRUE
;
return
(
MSQosAnalyser
*
)
obj
;
}
tester/mediastreamer2_audio_stream_tester.c
View file @
fe3455c6
...
...
@@ -153,6 +153,8 @@ static void basic_audio_stream() {
rtp_profile_set_payload
(
profile
,
0
,
&
payload_type_pcmu8000
);
/*recorder should be initialized before sender to avoid missing the first
emitted packets*/
CU_ASSERT_EQUAL
(
audio_stream_start_full
(
margaux
,
profile
,
MARIELLE_IP
...
...
tester/mediastreamer2_video_stream_tester.c
View file @
fe3455c6
...
...
@@ -74,7 +74,7 @@ typedef struct _video_stream_manager_t {
struct
{
float
loss
;
float
rtt
;
bool_t
stable_
network
;
uint8_t
network
_state
;
}
latest_stats
;
}
video_stream_manager_t
;
static
video_stream_manager_t
*
video_stream_manager_new
()
{
...
...
@@ -82,7 +82,6 @@ static video_stream_manager_t * video_stream_manager_new() {
mgr
->
local_rtp
=
(
rand
()
%
((
2
^
16
)
-
1024
)
+
1024
)
&
~
0x1
;
mgr
->
local_rtcp
=
mgr
->
local_rtp
+
1
;
mgr
->
stream
=
video_stream_new
(
mgr
->
local_rtp
,
mgr
->
local_rtcp
,
FALSE
);
mgr
->
latest_stats
.
stable_network
=
TRUE
;
return
mgr
;
}
...
...
@@ -119,7 +118,7 @@ static void handle_queue_events(video_stream_manager_t * stream_mgr, OrtpEvQueue
while
(
NULL
!=
(
ev
=
ortp_ev_queue_get
(
evq
))){
OrtpEventType
evt
=
ortp_event_get_type
(
ev
);
OrtpEventData
*
evd
=
ortp_event_get_data
(
ev
);
/*linphone_call_stats_fill(&call->stats[stream_index],ms,ev);*/
if
(
evt
==
ORTP_EVENT_RTCP_PACKET_RECEIVED
||
evt
==
ORTP_EVENT_RTCP_PACKET_EMITTED
)
{
const
report_block_t
*
rb
=
NULL
;
if
(
rtcp_is_SR
(
evd
->
packet
)){
...
...
@@ -127,21 +126,27 @@ static void handle_queue_events(video_stream_manager_t * stream_mgr, OrtpEvQueue
}
else
if
(
rtcp_is_RR
(
evd
->
packet
)){
rb
=
rtcp_RR_get_report_block
(
evd
->
packet
,
0
);
}
printf
(
"%s RTCP thing
\n
"
,
(
evt
==
ORTP_EVENT_RTCP_PACKET_RECEIVED
)
?
"RECEIVED"
:
"EMITTED"
);
stream_mgr
->
latest_stats
.
loss
=
100
.
0
*
(
float
)
report_block_get_fraction_lost
(
rb
)
/
256
.
0
;
stream_mgr
->
latest_stats
.
rtt
=
rtp_session_get_round_trip_propagation
(
stream_mgr
->
stream
->
ms
.
sessions
.
rtp_session
);
if
(
evt
==
ORTP_EVENT_RTCP_PACKET_RECEIVED
)
stream_mgr
->
latest_stats
.
stable_network
=
ms_qos_analyser_is_network_stable
(
ms_bitrate_controller_get_qos_analyser
(
stream_mgr
->
stream
->
ms
.
rc
));
printf
(
"loss=%f
\n
"
,
stream_mgr
->
latest_stats
.
loss
);
printf
(
"RTT=%f
\n
"
,
stream_mgr
->
latest_stats
.
rtt
);
printf
(
"stable_network=%d
\n
"
,
stream_mgr
->
latest_stats
.
stable_network
);
if
(
rb
)
{
stream_mgr
->
latest_stats
.
loss
=
100
.
0
*
(
float
)
report_block_get_fraction_lost
(
rb
)
/
256
.
0
;
stream_mgr
->
latest_stats
.
rtt
=
rtp_session_get_round_trip_propagation
(
stream_mgr
->
stream
->
ms
.
sessions
.
rtp_session
);
if
(
evt
==
ORTP_EVENT_RTCP_PACKET_RECEIVED
)
stream_mgr
->
latest_stats
.
network_state
=
ms_qos_analyser_get_network_state
(
ms_bitrate_controller_get_qos_analyser
(
stream_mgr
->
stream
->
ms
.
rc
));
ms_message
(
"mediastreamer2_video_stream_tester: %s RTCP packet: loss=%f, RTT=%f, network_state=%d
\n
"
,
(
evt
==
ORTP_EVENT_RTCP_PACKET_RECEIVED
)
?
"RECEIVED"
:
"EMITTED"
,
stream_mgr
->
latest_stats
.
loss
,
stream_mgr
->
latest_stats
.
rtt
,
stream_mgr
->
latest_stats
.
network_state
);
}
}
ortp_event_destroy
(
ev
);
}
}
static
void
start_adaptive_video_stream
(
video_stream_manager_t
*
marielle
,
video_stream_manager_t
*
margaux
,
int
payload
,
int
initial_bitrate
,
int
target_bw
,
float
loss_rate
,
int
latency
,
int
max_recv_rtcp_packet
)
{
static
void
start_adaptive_video_stream
(
video_stream_manager_t
*
marielle
,
video_stream_manager_t
*
margaux
,
int
payload
,
int
initial_bitrate
,
int
target_bw
,
float
loss_rate
,
int
latency
,
int
max_recv_rtcp_packet
)
{
MSWebCam
*
marielle_webcam
=
ms_web_cam_manager_get_default_cam
(
ms_web_cam_manager_get
());
MSWebCam
*
margaux_webcam
=
ms_web_cam_manager_get_cam
(
ms_web_cam_manager_get
(),
"StaticImage: Static picture"
);
...
...
@@ -181,17 +186,27 @@ static void start_adaptive_video_stream(video_stream_manager_t * marielle, video
&
margaux
->
stream
->
ms
,
media_stream_get_down_bw
(
&
margaux
->
stream
->
ms
)
/
1000
,
media_stream_get_up_bw
(
&
margaux
->
stream
->
ms
)
/
1000
);
}
ms_usleep
(
100000
);
}
rtp_session_unregister_event_queue
(
marielle
->
stream
->
ms
.
sessions
.
rtp_session
,
evq
);
ortp_ev_queue_destroy
(
evq
);
}
#define INIT() \
marielle = video_stream_manager_new(); \
margaux = video_stream_manager_new();
#define DEINIT() \
video_stream_manager_delete(marielle); \
video_stream_manager_delete(margaux);
static
void
lossy_network
()
{
video_stream_manager_t
*
marielle
,
*
margaux
;
/*verify that some webcam is supported*/
bool_t
supported
=
(
ms_web_cam_manager_get_default_cam
(
ms_web_cam_manager_get
())
!=
NULL
);
video_stream_manager_t
*
marielle
=
video_stream_manager_new
();
video_stream_manager_t
*
margaux
=
video_stream_manager_new
();
if
(
supported
)
{
float
bw_usage
;
//for test purpose only
int
loss_rate
=
getenv
(
"GPP_LOSS"
)
?
atoi
(
getenv
(
"GPP_LOSS"
))
:
0
;
int
max_bw
=
getenv
(
"GPP_MAXBW"
)
?
atoi
(
getenv
(
"GPP_MAXBW"
))
*
1000
:
0
;
int
latency
=
getenv
(
"GPP_LAG"
)
?
atoi
(
getenv
(
"GPP_LAG"
))
:
0
;
...
...
@@ -200,27 +215,35 @@ static void lossy_network() {
printf
(
"max_bw=%d(GPP_MAXBW)
\n
"
,
max_bw
);
printf
(
"latency=%d(GPP_LAG)
\n
"
,
latency
);
INIT
();
start_adaptive_video_stream
(
marielle
,
margaux
,
VP8_PAYLOAD_TYPE
,
300000
,
max_bw
,
loss_rate
,
latency
,
20
);
float
marielle_send_bw
=
media_stream_get_up_bw
(
&
marielle
->
stream
->
ms
);
bw_usage
=
(
max_bw
>
0
)
?
marielle_send_bw
/
max_bw
:
0
;
bw_usage
=
(
max_bw
>
0
)
?
marielle_send_bw
/
max_bw
:
1
;
ms_message
(
"marielle sent bw=[%f], target was [%d] bw_usage [%f]"
,
marielle_send_bw
,
max_bw
,
bw_usage
);
DEINIT
();
CU_ASSERT_IN_RANGE
(
bw_usage
,
.
9
f
,
1
.
f
);
}
video_stream_manager_delete
(
marielle
);
video_stream_manager_delete
(
margaux
);
}
static
void
stability_network_detection
()
{
video_stream_manager_t
*
marielle
=
video_stream_manager_new
();
video_stream_manager_t
*
margaux
=
video_stream_manager_new
();
video_stream_manager_t
*
marielle
,
*
margaux
;
INIT
();
start_adaptive_video_stream
(
marielle
,
margaux
,
VP8_PAYLOAD_TYPE
,
300000
,
0
,
0
,
500
,
10
);
CU_ASSERT_TRUE
(
marielle
->
latest_stats
.
stable_network
);
video_stream_manager_delete
(
marielle
);
video_stream_manager_delete
(
margaux
);
CU_ASSERT_EQUAL
(
marielle
->
latest_stats
.
network_state
,
MS_QOS_ANALYSER_NETWORK_FINE
);
DEINIT
();
INIT
();
start_adaptive_video_stream
(
marielle
,
margaux
,
VP8_PAYLOAD_TYPE
,
300000
,
50000
,
0
,
250
,
10
);
CU_ASSERT_EQUAL
(
marielle
->
latest_stats
.
network_state
,
MS_QOS_ANALYSER_NETWORK_CONGESTED
);
DEINIT
();
INIT
();
start_adaptive_video_stream
(
marielle
,
margaux
,
VP8_PAYLOAD_TYPE
,
300000
,
0
,
15
,
250
,
10
);
CU_ASSERT_EQUAL
(
marielle
->
latest_stats
.
network_state
,
MS_QOS_ANALYSER_NETWORK_UNSTABLE
);
DEINIT
();
}
static
test_t
tests
[]
=
{
...
...
Write
Preview