Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
BC
public
mediastreamer2
Commits
ce567ebe
Commit
ce567ebe
authored
May 26, 2014
by
Ghislain MARY
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add VideoStream unit tests suite.
parent
4d6563b7
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
321 additions
and
36 deletions
+321
-36
tester/Makefile.am
tester/Makefile.am
+1
-0
tester/mediastreamer2_audio_stream_tester.c
tester/mediastreamer2_audio_stream_tester.c
+2
-36
tester/mediastreamer2_tester.c
tester/mediastreamer2_tester.c
+1
-0
tester/mediastreamer2_tester.h
tester/mediastreamer2_tester.h
+1
-0
tester/mediastreamer2_tester_private.c
tester/mediastreamer2_tester_private.c
+68
-0
tester/mediastreamer2_tester_private.h
tester/mediastreamer2_tester_private.h
+8
-0
tester/mediastreamer2_video_stream_tester.c
tester/mediastreamer2_video_stream_tester.c
+240
-0
No files found.
tester/Makefile.am
View file @
ce567ebe
...
...
@@ -14,6 +14,7 @@ mediastreamer2_tester_SOURCES= \
mediastreamer2_basic_audio_tester.c
\
mediastreamer2_sound_card_tester.c
\
mediastreamer2_audio_stream_tester.c
\
mediastreamer2_video_stream_tester.c
\
mediastreamer2_framework_tester.c
...
...
tester/mediastreamer2_audio_stream_tester.c
View file @
ce567ebe
...
...
@@ -74,51 +74,17 @@ static int tester_cleanup(void) {
#define RECORDED_8K_1S_FILE WRITE_FILE_PATH "recorded_hello8000-1s.wav"
#define RECORDED_16K_1S_FILE WRITE_FILE_PATH "recorded_hello16000-1s.wav"
typedef
struct
_stats_t
{
rtp_stats_t
rtp
;
int
number_of_EndOfFile
;
}
stats_t
;
static
void
reset_stats
(
stats_t
*
s
)
{
memset
(
s
,
0
,
sizeof
(
stats_t
));
}
bool_t
wait_for_list
(
MSList
*
mss
,
int
*
counter
,
int
value
,
int
timeout_ms
)
{
int
retry
=
0
;
MSList
*
iterator
;
while
(
*
counter
<
value
&&
retry
++
<
timeout_ms
/
100
)
{
for
(
iterator
=
mss
;
iterator
!=
NULL
;
iterator
=
iterator
->
next
)
{
MediaStream
*
stream
=
(
MediaStream
*
)(
iterator
->
data
);
media_stream_iterate
(
stream
);
if
(
retry
%
10
==
0
)
{
ms_message
(
"stream [%p] bandwidth usage: [d=%.1f,u=%.1f] kbit/sec"
,
stream
,
media_stream_get_down_bw
(
stream
)
/
1000
,
media_stream_get_up_bw
(
stream
)
/
1000
);
}
}
ms_usleep
(
100000
);
}
if
(
*
counter
<
value
)
return
FALSE
;
else
return
TRUE
;
}
bool_t
wait_for_until
(
MediaStream
*
ms_1
,
MediaStream
*
ms_2
,
int
*
counter
,
int
value
,
int
timeout
)
{
MSList
*
mss
=
NULL
;
bool_t
result
;
if
(
ms_1
)
mss
=
ms_list_append
(
mss
,
ms_1
);
if
(
ms_2
)
mss
=
ms_list_append
(
mss
,
ms_2
);
result
=
wait_for_list
(
mss
,
counter
,
value
,
timeout
);
ms_list_free
(
mss
);
return
result
;
}
bool_t
wait_for
(
MediaStream
*
ms_1
,
MediaStream
*
ms_2
,
int
*
counter
,
int
value
)
{
return
wait_for_until
(
ms_1
,
ms_2
,
counter
,
value
,
2000
);
}
static
void
notify_cb
(
void
*
user_data
,
MSFilter
*
f
,
unsigned
int
event
,
void
*
eventdata
)
{
stats_t
*
stats
=
(
stats_t
*
)
user_data
;
...
...
tester/mediastreamer2_tester.c
View file @
ce567ebe
...
...
@@ -114,6 +114,7 @@ void mediastreamer2_tester_init(void) {
add_test_suite
(
&
basic_audio_test_suite
);
add_test_suite
(
&
sound_card_test_suite
);
add_test_suite
(
&
audio_stream_test_suite
);
add_test_suite
(
&
video_stream_test_suite
);
add_test_suite
(
&
framework_test_suite
);
}
...
...
tester/mediastreamer2_tester.h
View file @
ce567ebe
...
...
@@ -48,6 +48,7 @@ extern "C" {
extern
test_suite_t
basic_audio_test_suite
;
extern
test_suite_t
sound_card_test_suite
;
extern
test_suite_t
audio_stream_test_suite
;
extern
test_suite_t
video_stream_test_suite
;
extern
test_suite_t
framework_test_suite
;
...
...
tester/mediastreamer2_tester_private.c
View file @
ce567ebe
...
...
@@ -200,3 +200,71 @@ void ms_tester_tone_generation_and_detection_loop(void) {
}
}
bool_t
wait_for_list
(
MSList
*
mss
,
int
*
counter
,
int
value
,
int
timeout_ms
)
{
return
wait_for_list_with_parse_events
(
mss
,
counter
,
value
,
timeout_ms
,
NULL
,
NULL
);
}
bool_t
wait_for_list_with_parse_events
(
MSList
*
mss
,
int
*
counter
,
int
value
,
int
timeout_ms
,
MSList
*
cbs
,
MSList
*
ptrs
)
{
MSList
*
msi
;
MSList
*
cbi
;
MSList
*
ptri
;
int
retry
=
0
;
while
((
*
counter
<
value
)
&&
(
retry
++
<
(
timeout_ms
/
100
)))
{
for
(
msi
=
mss
,
cbi
=
cbs
,
ptri
=
ptrs
;
msi
!=
NULL
;
msi
=
msi
->
next
)
{
MediaStream
*
stream
=
(
MediaStream
*
)
msi
->
data
;
ms_tester_iterate_cb
cb
=
NULL
;
media_stream_iterate
(
stream
);
if
((
retry
%
10
)
==
0
)
{
ms_message
(
"stream [%p] bandwidth usage: [d=%.1f,u=%.1f] kbit/sec"
,
stream
,
media_stream_get_down_bw
(
stream
)
/
1000
,
media_stream_get_up_bw
(
stream
)
/
1000
);
}
if
(
cbi
&&
ptri
)
{
cb
=
(
ms_tester_iterate_cb
)
cbi
->
data
;
cb
(
stream
,
ptri
->
data
);
}
if
(
cbi
)
cbi
=
cbi
->
next
;
if
(
ptri
)
ptri
=
ptri
->
next
;
}
ms_usleep
(
100000
);
}
if
(
*
counter
<
value
)
return
FALSE
;
return
TRUE
;
}
bool_t
wait_for_until
(
MediaStream
*
ms_1
,
MediaStream
*
ms_2
,
int
*
counter
,
int
value
,
int
timeout_ms
)
{
return
wait_for_until_with_parse_events
(
ms_1
,
ms_2
,
counter
,
value
,
timeout_ms
,
NULL
,
NULL
,
NULL
,
NULL
);
}
bool_t
wait_for_until_with_parse_events
(
MediaStream
*
ms1
,
MediaStream
*
ms2
,
int
*
counter
,
int
value
,
int
timeout_ms
,
ms_tester_iterate_cb
cb1
,
void
*
ptr1
,
ms_tester_iterate_cb
cb2
,
void
*
ptr2
)
{
MSList
*
mss
=
NULL
;
MSList
*
cbs
=
NULL
;
MSList
*
ptrs
=
NULL
;
bool_t
result
;
if
(
ms1
)
{
mss
=
ms_list_append
(
mss
,
ms1
);
if
(
cb1
&&
ptr1
)
{
cbs
=
ms_list_append
(
cbs
,
cb1
);
ptrs
=
ms_list_append
(
ptrs
,
ptr1
);
}
}
if
(
ms2
)
{
mss
=
ms_list_append
(
mss
,
ms2
);
if
(
cb2
&&
ptr2
)
{
cbs
=
ms_list_append
(
cbs
,
cb2
);
ptrs
=
ms_list_append
(
ptrs
,
ptr2
);
}
}
result
=
wait_for_list_with_parse_events
(
mss
,
counter
,
value
,
timeout_ms
,
cbs
,
ptrs
);
ms_list_free
(
mss
);
return
result
;
}
bool_t
wait_for
(
MediaStream
*
ms_1
,
MediaStream
*
ms_2
,
int
*
counter
,
int
value
)
{
return
wait_for_until
(
ms_1
,
ms_2
,
counter
,
value
,
2000
);
}
tester/mediastreamer2_tester_private.h
View file @
ce567ebe
...
...
@@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define _MEDIASTREAMER2_TESTER_PRIVATE_H
#include "mediastreamer2/mediastream.h"
#include "mediastreamer2/msfilter.h"
#include "mediastreamer2/msticker.h"
...
...
@@ -87,6 +88,13 @@ void ms_tester_tone_generation_loop(void);
void
ms_tester_tone_detection_loop
(
void
);
void
ms_tester_tone_generation_and_detection_loop
(
void
);
typedef
void
(
*
ms_tester_iterate_cb
)(
MediaStream
*
ms
,
void
*
user_pointer
);
bool_t
wait_for_list
(
MSList
*
mss
,
int
*
counter
,
int
value
,
int
timeout_ms
);
bool_t
wait_for_list_with_parse_events
(
MSList
*
mss
,
int
*
counter
,
int
value
,
int
timeout_ms
,
MSList
*
cbs
,
MSList
*
ptrs
);
bool_t
wait_for_until
(
MediaStream
*
ms1
,
MediaStream
*
ms2
,
int
*
counter
,
int
value
,
int
timeout_ms
);
bool_t
wait_for_until_with_parse_events
(
MediaStream
*
ms1
,
MediaStream
*
ms2
,
int
*
counter
,
int
value
,
int
timeout_ms
,
ms_tester_iterate_cb
cb1
,
void
*
ptr1
,
ms_tester_iterate_cb
cb2
,
void
*
ptr2
);
bool_t
wait_for
(
MediaStream
*
ms1
,
MediaStream
*
ms2
,
int
*
counter
,
int
value
);
#endif
/* _MEDIASTREAMER2_TESTER_PRIVATE_H */
tester/mediastreamer2_video_stream_tester.c
0 → 100644
View file @
ce567ebe
/*
mediastreamer2 library - modular sound and video processing and streaming
Copyright (C) 2006-2013 Belledonne Communications, Grenoble
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "mediastreamer2/mediastream.h"
#include "mediastreamer2/msrtp.h"
#include "private.h"
#include "mediastreamer2_tester.h"
#include "mediastreamer2_tester_private.h"
#include <stdio.h>
#include "CUnit/Basic.h"
#ifdef _MSC_VER
#define unlink _unlink
#endif
static
RtpProfile
rtp_profile
;
#define VP8_PAYLOAD_TYPE 103
static
int
tester_init
(
void
)
{
ms_init
();
ms_filter_enable_statistics
(
TRUE
);
ortp_init
();
rtp_profile_set_payload
(
&
rtp_profile
,
VP8_PAYLOAD_TYPE
,
&
payload_type_vp8
);
return
0
;
}
static
int
tester_cleanup
(
void
)
{
ms_exit
();
rtp_profile_clear_all
(
&
rtp_profile
);
return
0
;
}
#define MARIELLE_RTP_PORT 2564
#define MARIELLE_RTCP_PORT 2565
#define MARIELLE_IP "127.0.0.1"
#define MARGAUX_RTP_PORT 9864
#define MARGAUX_RTCP_PORT 9865
#define MARGAUX_IP "127.0.0.1"
typedef
struct
_video_stream_tester_stats_t
{
OrtpEvQueue
*
q
;
rtp_stats_t
rtp
;
int
number_of_SR
;
int
number_of_RR
;
int
number_of_SDES
;
int
number_of_PLI
;
int
number_of_SLI
;
int
number_of_RPSI
;
}
video_stream_tester_stats_t
;
typedef
struct
_video_stream_tester_t
{
VideoStream
*
vs
;
video_stream_tester_stats_t
stats
;
}
video_stream_tester_t
;
static
void
reset_stats
(
video_stream_tester_stats_t
*
s
)
{
memset
(
s
,
0
,
sizeof
(
video_stream_tester_stats_t
));
}
static
void
event_queue_cb
(
MediaStream
*
ms
,
void
*
user_pointer
)
{
video_stream_tester_stats_t
*
st
=
(
video_stream_tester_stats_t
*
)
user_pointer
;
OrtpEvent
*
ev
=
NULL
;
if
(
st
->
q
!=
NULL
)
{
while
((
ev
=
ortp_ev_queue_get
(
st
->
q
))
!=
NULL
)
{
OrtpEventType
evt
=
ortp_event_get_type
(
ev
);
OrtpEventData
*
d
=
ortp_event_get_data
(
ev
);
if
(
evt
==
ORTP_EVENT_RTCP_PACKET_EMITTED
)
{
do
{
if
(
rtcp_is_RR
(
d
->
packet
))
{
st
->
number_of_RR
++
;
}
else
if
(
rtcp_is_SR
(
d
->
packet
))
{
st
->
number_of_SR
++
;
}
else
if
(
rtcp_is_SDES
(
d
->
packet
))
{
st
->
number_of_SDES
++
;
}
else
if
(
rtcp_is_PSFB
(
d
->
packet
))
{
switch
(
rtcp_PSFB_get_type
(
d
->
packet
))
{
case
RTCP_PSFB_PLI
:
st
->
number_of_PLI
++
;
break
;
case
RTCP_PSFB_SLI
:
st
->
number_of_SLI
++
;
break
;
case
RTCP_PSFB_RPSI
:
st
->
number_of_RPSI
++
;
break
;
default:
break
;
}
}
}
while
(
rtcp_next_packet
(
d
->
packet
));
}
ortp_event_destroy
(
ev
);
}
}
}
static
void
init_video_streams
(
video_stream_tester_t
*
marielle
,
video_stream_tester_t
*
margaux
,
bool_t
avpf
,
OrtpNetworkSimulatorParams
*
params
)
{
PayloadType
*
pt
;
MSWebCam
*
no_webcam
=
ms_web_cam_manager_get_cam
(
ms_web_cam_manager_get
(),
"StaticImage: Static picture"
);
MSWebCam
*
default_webcam
=
ms_web_cam_manager_get_default_cam
(
ms_web_cam_manager_get
());
marielle
->
vs
=
video_stream_new
(
MARIELLE_RTP_PORT
,
MARIELLE_RTCP_PORT
,
FALSE
);
margaux
->
vs
=
video_stream_new
(
MARGAUX_RTP_PORT
,
MARGAUX_RTCP_PORT
,
FALSE
);
reset_stats
(
&
marielle
->
stats
);
reset_stats
(
&
margaux
->
stats
);
/* Enable/disable avpf. */
pt
=
rtp_profile_get_payload
(
&
rtp_profile
,
VP8_PAYLOAD_TYPE
);
CU_ASSERT_PTR_NOT_NULL_FATAL
(
pt
);
if
(
avpf
==
TRUE
)
{
payload_type_set_flag
(
pt
,
PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED
);
}
else
{
payload_type_unset_flag
(
pt
,
PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED
);
}
/* Configure network simulator. */
if
((
params
!=
NULL
)
&&
(
params
->
enabled
==
TRUE
))
{
rtp_session_enable_network_simulation
(
marielle
->
vs
->
ms
.
sessions
.
rtp_session
,
params
);
rtp_session_enable_network_simulation
(
margaux
->
vs
->
ms
.
sessions
.
rtp_session
,
params
);
}
marielle
->
stats
.
q
=
ortp_ev_queue_new
();
rtp_session_register_event_queue
(
marielle
->
vs
->
ms
.
sessions
.
rtp_session
,
marielle
->
stats
.
q
);
margaux
->
stats
.
q
=
ortp_ev_queue_new
();
rtp_session_register_event_queue
(
margaux
->
vs
->
ms
.
sessions
.
rtp_session
,
margaux
->
stats
.
q
);
CU_ASSERT_EQUAL
(
video_stream_start
(
marielle
->
vs
,
&
rtp_profile
,
MARGAUX_IP
,
MARGAUX_RTP_PORT
,
MARGAUX_IP
,
MARGAUX_RTCP_PORT
,
VP8_PAYLOAD_TYPE
,
50
,
default_webcam
),
0
);
CU_ASSERT_EQUAL
(
video_stream_start
(
margaux
->
vs
,
&
rtp_profile
,
MARIELLE_IP
,
MARIELLE_RTP_PORT
,
MARIELLE_IP
,
MARIELLE_RTCP_PORT
,
VP8_PAYLOAD_TYPE
,
50
,
no_webcam
),
0
);
}
static
void
uninit_video_streams
(
video_stream_tester_t
*
marielle
,
video_stream_tester_t
*
margaux
)
{
float
rtcp_send_bandwidth
;
PayloadType
*
pt
;
pt
=
rtp_profile_get_payload
(
&
rtp_profile
,
VP8_PAYLOAD_TYPE
);
CU_ASSERT_PTR_NOT_NULL_FATAL
(
pt
);
rtp_session_compute_send_bandwidth
(
marielle
->
vs
->
ms
.
sessions
.
rtp_session
);
rtp_session_compute_send_bandwidth
(
margaux
->
vs
->
ms
.
sessions
.
rtp_session
);
rtcp_send_bandwidth
=
rtp_session_get_rtcp_send_bandwidth
(
marielle
->
vs
->
ms
.
sessions
.
rtp_session
);
CU_ASSERT_TRUE
(
rtcp_send_bandwidth
<=
(
0
.
05
*
payload_type_get_bitrate
(
pt
)));
rtcp_send_bandwidth
=
rtp_session_get_rtcp_send_bandwidth
(
margaux
->
vs
->
ms
.
sessions
.
rtp_session
);
CU_ASSERT_TRUE
(
rtcp_send_bandwidth
<=
(
0
.
05
*
payload_type_get_bitrate
(
pt
)));
video_stream_stop
(
marielle
->
vs
);
video_stream_stop
(
margaux
->
vs
);
ortp_ev_queue_destroy
(
marielle
->
stats
.
q
);
ortp_ev_queue_destroy
(
margaux
->
stats
.
q
);
}
static
void
basic_video_stream
(
void
)
{
video_stream_tester_t
marielle
;
video_stream_tester_t
margaux
;
init_video_streams
(
&
marielle
,
&
margaux
,
FALSE
,
NULL
);
CU_ASSERT_TRUE
(
wait_for_until_with_parse_events
(
&
marielle
.
vs
->
ms
,
&
margaux
.
vs
->
ms
,
&
marielle
.
stats
.
number_of_SR
,
2
,
15000
,
event_queue_cb
,
&
marielle
.
stats
,
event_queue_cb
,
&
margaux
.
stats
));
video_stream_get_local_rtp_stats
(
marielle
.
vs
,
&
marielle
.
stats
.
rtp
);
video_stream_get_local_rtp_stats
(
margaux
.
vs
,
&
margaux
.
stats
.
rtp
);
uninit_video_streams
(
&
marielle
,
&
margaux
);
}
static
void
avpf_video_stream
(
void
)
{
video_stream_tester_t
marielle
;
video_stream_tester_t
margaux
;
OrtpNetworkSimulatorParams
params
=
{
0
};
params
.
enabled
=
TRUE
;
params
.
loss_rate
=
5
.;
init_video_streams
(
&
marielle
,
&
margaux
,
TRUE
,
&
params
);
CU_ASSERT_TRUE
(
wait_for_until_with_parse_events
(
&
marielle
.
vs
->
ms
,
&
margaux
.
vs
->
ms
,
&
marielle
.
stats
.
number_of_SR
,
2
,
15000
,
event_queue_cb
,
&
marielle
.
stats
,
event_queue_cb
,
&
margaux
.
stats
));
CU_ASSERT_TRUE
(
marielle
.
stats
.
number_of_PLI
>=
0
);
CU_ASSERT_TRUE
(
marielle
.
stats
.
number_of_SLI
>
0
);
CU_ASSERT_TRUE
(
marielle
.
stats
.
number_of_RPSI
>
0
);
uninit_video_streams
(
&
marielle
,
&
margaux
);
}
static
void
avpf_high_loss_video_stream
(
void
)
{
video_stream_tester_t
marielle
;
video_stream_tester_t
margaux
;
OrtpNetworkSimulatorParams
params
=
{
0
};
params
.
enabled
=
TRUE
;
params
.
loss_rate
=
25
.;
init_video_streams
(
&
marielle
,
&
margaux
,
TRUE
,
&
params
);
CU_ASSERT_TRUE
(
wait_for_until_with_parse_events
(
&
marielle
.
vs
->
ms
,
&
margaux
.
vs
->
ms
,
&
marielle
.
stats
.
number_of_SR
,
2
,
15000
,
event_queue_cb
,
&
marielle
.
stats
,
event_queue_cb
,
&
margaux
.
stats
));
CU_ASSERT_TRUE
(
marielle
.
stats
.
number_of_PLI
>=
0
);
CU_ASSERT_TRUE
(
marielle
.
stats
.
number_of_SLI
>
0
);
CU_ASSERT_TRUE
(
marielle
.
stats
.
number_of_RPSI
>=
0
);
uninit_video_streams
(
&
marielle
,
&
margaux
);
}
static
test_t
tests
[]
=
{
{
"Basic video stream"
,
basic_video_stream
},
{
"AVPF video stream"
,
avpf_video_stream
},
{
"AVPF high-loss video stream"
,
avpf_high_loss_video_stream
}
};
test_suite_t
video_stream_test_suite
=
{
"VideoStream"
,
tester_init
,
tester_cleanup
,
sizeof
(
tests
)
/
sizeof
(
tests
[
0
]),
tests
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment