add adaptative algorithm tests for video too

parent 3332a756
......@@ -237,7 +237,7 @@ static void compute_available_bw(MSSimpleQosAnalyser *obj){
x_sum /= count;
y_sum /= count;
mean_bw /= count;
printf("\tEstimated BW by avg is %f kbits/s\n", mean_bw);
printf("\tEstimated 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);
......@@ -258,7 +258,8 @@ static void compute_available_bw(MSSimpleQosAnalyser *obj){
bool_t lossy_network = avg_dist > .1;
// to compute estimated BW, we need a minimum sample size
if (diff > 0.05) {
printf("\tfor line is %f kbit/s\n", -b / m);
double avail_bw = (fabs(m) > 0.0001f) ? - b / m : mean_bw;
printf("\tfor line is %f kbit/s\n", avail_bw);
printf("\t\ty=%f x + %f\n", m, b);
lossy_network |= m < .03f;
......
......@@ -98,18 +98,20 @@ static void video_stream_process_rtcp(MediaStream *media_stream, mblk_t *m){
unsigned int i;
do{
const report_block_t *rb = NULL;
if (rtcp_is_SR(m)){
const report_block_t *rb;
rb=rtcp_SR_get_report_block(m,0);
if (rb){
float rt=rtp_session_get_round_trip_propagation(stream->ms.sessions.rtp_session);
float flost;
i=report_block_get_interarrival_jitter(rb);
flost=(float)(100.0*report_block_get_fraction_lost(rb)/256.0);
ms_message("video_stream_process_rtcp[%p]: interarrival jitter=%u , lost packets percentage since last report=%f, round trip time=%f seconds",stream,i,flost,rt);
if (stream->ms.rc)
ms_bitrate_controller_process_rtcp(stream->ms.rc,m);
}
}else if (rtcp_is_RR(m)){
rb=rtcp_RR_get_report_block(m,0);
}
if (rb){
float rt=rtp_session_get_round_trip_propagation(stream->ms.sessions.rtp_session);
float flost;
i=report_block_get_interarrival_jitter(rb);
flost=(float)(100.0*report_block_get_fraction_lost(rb)/256.0);
ms_message("video_stream_process_rtcp[%p]: interarrival jitter=%u , lost packets percentage since last report=%f, round trip time=%f seconds",stream,i,flost,rt);
if (stream->ms.rc)
ms_bitrate_controller_process_rtcp(stream->ms.rc,m);
} else if (rtcp_is_PSFB(m)) {
if (rtcp_PSFB_get_type(m) == RTCP_PSFB_FIR) {
/* Special case for FIR where the packet sender ssrc must be equal to 0. */
......@@ -399,7 +401,7 @@ int video_stream_start (VideoStream *stream, RtpProfile *profile, const char *re
pt=rtp_profile_get_payload(profile,payload);
if (pt==NULL){
ms_error("videostream.c: undefined payload type.");
ms_error("videostream.c: undefined payload type %d.", payload);
return -1;
}
if (pt->flags & PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED) avpf_enabled = TRUE;
......
......@@ -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
......
......@@ -83,42 +83,6 @@ static void reset_stats(stats_t* s) {
}
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;
......@@ -133,28 +97,27 @@ static void notify_cb(void *user_data, MSFilter *f, unsigned int event, void *ev
}
typedef struct _stream_manager_t {
typedef struct _audio_stream_manager_t {
AudioStream* stream;
int local_rtp;
int local_rtcp;
stats_t stats;
} stream_manager_t ;
static stream_manager_t * stream_manager_new() {
stream_manager_t * mgr = ms_new0(stream_manager_t,1);
} audio_stream_manager_t ;
static audio_stream_manager_t * audio_stream_manager_new() {
audio_stream_manager_t * mgr = ms_new0(audio_stream_manager_t,1);
mgr->local_rtp= (rand() % ((2^16)-1024) + 1024) & ~0x1;
mgr->local_rtcp=mgr->local_rtp+1;
mgr->stream = audio_stream_new (mgr->local_rtp, mgr->local_rtcp,FALSE);
return mgr;
}
static void stream_manager_delete(stream_manager_t * mgr) {
static void audio_stream_manager_delete(audio_stream_manager_t * mgr) {
audio_stream_stop(mgr->stream);
ms_free(mgr);
}
static void stream_manager_start( stream_manager_t * mgr
static void audio_manager_start( audio_stream_manager_t * mgr
,int payload_type
,int remote_port
,int target_bitrate
......@@ -175,8 +138,8 @@ static void stream_manager_start( stream_manager_t * mgr
, NULL
, NULL
, 0),0);
}
static void basic_audio_stream() {
AudioStream * marielle = audio_stream_new (MARIELLE_RTP_PORT, MARIELLE_RTCP_PORT,FALSE);
stats_t marielle_stats;
......@@ -237,8 +200,8 @@ static void basic_audio_stream() {
#define THIRDGENERATION_BW 200000
static float adaptive_audio_stream(int codec_payload, int initial_bitrate,int target_bw, float loss_rate, int max_recv_rtcp_packet) {
stream_manager_t * marielle = stream_manager_new();
stream_manager_t * margaux = stream_manager_new();
audio_stream_manager_t * marielle = audio_stream_manager_new();
audio_stream_manager_t * margaux = audio_stream_manager_new();
int pause_time=0;
OrtpNetworkSimulatorParams params={0};
......@@ -254,21 +217,21 @@ static float adaptive_audio_stream(int codec_payload, int initial_bitrate,int ta
media_stream_enable_adaptive_bitrate_control(&marielle->stream->ms,TRUE);
stream_manager_start(marielle,codec_payload, margaux->local_rtp,initial_bitrate,HELLO_16K_1S_FILE,NULL);
audio_manager_start(marielle,codec_payload, margaux->local_rtp,initial_bitrate,HELLO_16K_1S_FILE,NULL);
ms_filter_call_method(marielle->stream->soundread,MS_FILE_PLAYER_LOOP,&pause_time);
stream_manager_start(margaux,codec_payload, marielle->local_rtp,-1,NULL,RECORDED_16K_1S_FILE);
audio_manager_start(margaux,codec_payload, marielle->local_rtp,-1,NULL,RECORDED_16K_1S_FILE);
rtp_session_enable_network_simulation(margaux->stream->ms.sessions.rtp_session,&params);
rtp_session_set_rtcp_report_interval(margaux->stream->ms.sessions.rtp_session, rtcp_interval);
wait_for_until(&marielle->stream->ms,&margaux->stream->ms,&marielle->stats.number_of_EndOfFile,10,rtcp_interval*max_recv_rtcp_packet);
marielle_send_bw=media_stream_get_up_bw(&marielle->stream->ms);
bw_usage_ratio=marielle_send_bw/params.max_bandwidth;
bw_usage_ratio=(params.max_bandwidth > 0) ? marielle_send_bw/params.max_bandwidth : 0;
ms_message("marielle sent bw=[%f], target was [%f] bw_usage_ratio [%f]",marielle_send_bw,params.max_bandwidth,bw_usage_ratio);
stream_manager_delete(marielle);
stream_manager_delete(margaux);
audio_stream_manager_delete(marielle);
audio_stream_manager_delete(margaux);
unlink(RECORDED_16K_1S_FILE);
......@@ -331,7 +294,7 @@ static void lossy_network_speex_audio_stream() {
int loss_rate = getenv("GPP_LOSS") ? atoi(getenv("GPP_LOSS")) : 0;
int max_bw = getenv("GPP_MAXBW") ? atoi(getenv("GPP_MAXBW")) * 1000: 0;
printf("\nloss_rate=%d(GPP_LOSS) max_bw=%d(GPP_MAXBW)\n", loss_rate, max_bw);
bw_usage = adaptive_audio_stream(SPEEX16_PAYLOAD_TYPE, 32000, max_bw, loss_rate, 120);
bw_usage = adaptive_audio_stream(SPEEX16_PAYLOAD_TYPE, 32000, max_bw, loss_rate, 20);
CU_ASSERT_IN_RANGE(bw_usage, .9f, 1.f);
// bw_usage = adaptive_audio_stream(SPEEX16_PAYLOAD_TYPE, 16000, EDGE_BW, 8);
// CU_ASSERT_IN_RANGE(bw_usage, .9f, 1.f);
......@@ -342,8 +305,8 @@ static void lossy_network_speex_audio_stream() {
#if 0
static void audio_stream_dtmf(int codec_payload, int initial_bitrate,int target_bw, int max_recv_rtcp_packet) {
stream_manager_t * marielle = stream_manager_new();
stream_manager_t * margaux = stream_manager_new();
audio_stream_manager_t * marielle = audio_stream_manager_new();
audio_stream_manager_t * margaux = audio_stream_manager_new();
int pause_time=0;
OrtpNetworkSimulatorParams params={0};
......@@ -358,11 +321,11 @@ static void audio_stream_dtmf(int codec_payload, int initial_bitrate,int target_
media_stream_enable_adaptive_bitrate_control(&marielle->stream->ms,TRUE);
stream_manager_start(marielle,codec_payload, margaux->local_rtp,initial_bitrate,HELLO_16K_1S_FILE,NULL);
audio_manager_start(marielle,codec_payload, margaux->local_rtp,initial_bitrate,HELLO_16K_1S_FILE,NULL);
ms_filter_call_method(marielle->stream->soundread,MS_FILE_PLAYER_LOOP,&pause_time);
unlink("blibi.wav");
stream_manager_start(margaux,codec_payload, marielle->local_rtp,-1,NULL,"blibi.wav");
audio_manager_start(margaux,codec_payload, marielle->local_rtp,-1,NULL,"blibi.wav");
rtp_session_enable_network_simulation(margaux->stream->ms.session,&params);
rtp_session_set_rtcp_report_interval(margaux->stream->ms.session, rtcp_interval);
......@@ -373,8 +336,8 @@ static void audio_stream_dtmf(int codec_payload, int initial_bitrate,int target_
ms_message("marielle sent bw= [%f] , target was [%f] recv/send [%f]",marielle_send_bw,params.max_bandwidth,recv_send_bw_ratio);
CU_ASSERT_TRUE(recv_send_bw_ratio>0.9);
stream_manager_delete(marielle);
stream_manager_delete(margaux);
audio_stream_manager_delete(marielle);
audio_stream_manager_delete(margaux);
}
......@@ -386,7 +349,7 @@ static test_t tests[] = {
{ "Adaptive audio stream [opus]", adaptive_opus_audio_stream },
{ "Adaptive audio stream [speex]", adaptive_speek16_audio_stream },
{ "Adaptive audio stream [pcma]", adaptive_pcma_audio_stream },
{ "Lossy network [speex]", lossy_network_speex_audio_stream },
{ "Lossy network", lossy_network_speex_audio_stream },
};
test_suite_t audio_stream_test_suite = {
......
......@@ -36,6 +36,42 @@ static int nb_test_suites = 0;
static unsigned char curses = 0;
#endif
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 add_test_suite(test_suite_t *suite) {
if (test_suite == NULL) {
......@@ -114,6 +150,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);
}
......
......@@ -22,6 +22,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "CUnit/Basic.h"
#include <mediastreamer2/mediastream.h>
typedef void (*test_function_t)(void);
......@@ -48,9 +50,15 @@ 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;
bool_t wait_for_list(MSList* mss,int* counter,int value,int timeout_ms);
bool_t wait_for_until(MediaStream* ms_1, MediaStream* ms_2,int* counter,int value,int timeout);
bool_t wait_for(MediaStream* ms_1, MediaStream* ms_2,int* counter,int value);
extern int mediastreamer2_tester_nb_test_suites(void);
extern int mediastreamer2_tester_nb_tests(const char *suite_name);
extern const char * mediastreamer2_tester_test_suite_name(int suite_index);
......
/*
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/dtmfgen.h"
#include "mediastreamer2/msfileplayer.h"
#include "mediastreamer2/msfilerec.h"
#include "mediastreamer2/msrtp.h"
#include "mediastreamer2/mstonedetector.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 H263_PAYLOAD_TYPE 34
#define H264_PAYLOAD_TYPE 102
#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,H263_PAYLOAD_TYPE,&payload_type_h263);
rtp_profile_set_payload(&rtp_profile,H264_PAYLOAD_TYPE,&payload_type_h264);
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_manager_t {
VideoStream* stream;
int local_rtp;
int local_rtcp;
} video_stream_manager_t ;
static video_stream_manager_t * video_stream_manager_new() {
video_stream_manager_t * mgr = ms_new0(video_stream_manager_t,1);
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);
return mgr;
}
static void video_stream_manager_delete(video_stream_manager_t * mgr) {
video_stream_stop(mgr->stream);
ms_free(mgr);
}
static void video_manager_start( video_stream_manager_t * mgr
,int payload_type
,int remote_port
,int target_bitrate
,MSWebCam * cam) {
media_stream_set_target_network_bitrate(&mgr->stream->ms,target_bitrate);
int result = video_stream_start(mgr->stream
, &rtp_profile
, "127.0.0.1"
, remote_port
, "127.0.0.1"
, remote_port+1
, payload_type
, 550
, cam);
CU_ASSERT_EQUAL(result,0);
}
#define EDGE_BW 10000
#define THIRDGENERATION_BW 200000
#define CU_ASSERT_IN_RANGE(value, inf, sup) CU_ASSERT_TRUE(value >= inf); CU_ASSERT_TRUE(value <= sup)
static float adaptive_video_stream(int payload, int initial_bitrate,int target_bw, float loss_rate, int max_recv_rtcp_packet) {
const MSList * webcams = ms_web_cam_manager_get_list(ms_web_cam_manager_get());
MSWebCam * marielle_webcam = (ms_list_size(webcams) > 0) ? (MSWebCam *) webcams->data : NULL;
// MSWebCam * margaux_webcam = (ms_list_size(webcams) > 1) ? (MSWebCam *) webcams->next->data : NULL;
video_stream_manager_t * marielle = video_stream_manager_new();
video_stream_manager_t * margaux = video_stream_manager_new();
OrtpNetworkSimulatorParams params={0};
params.enabled=TRUE;
params.loss_rate=loss_rate;
params.max_bandwidth=target_bw;
params.max_buffer_size=initial_bitrate;
float bw_usage_ratio = 0.;
// this variable should not be changed, since algorithm results rely on this value
// (the bigger it is, the more accurate is bandwidth estimation)
int rtcp_interval = 1000;
float marielle_send_bw;
media_stream_enable_adaptive_bitrate_control(&marielle->stream->ms,TRUE);
video_manager_start(marielle, payload, margaux->local_rtp, initial_bitrate, marielle_webcam);
video_manager_start(margaux, payload, marielle->local_rtp, -1, NULL);
// video_manager_start(margaux, payload, marielle->local_rtp, -1, margaux_webcam);
rtp_session_enable_network_simulation(margaux->stream->ms.sessions.rtp_session,&params);
rtp_session_set_rtcp_report_interval(margaux->stream->ms.sessions.rtp_session, rtcp_interval);
// just wait for timeout
wait_for_until(&marielle->stream->ms,&margaux->stream->ms,&marielle->local_rtp,100000,rtcp_interval*max_recv_rtcp_packet);
marielle_send_bw=media_stream_get_up_bw(&marielle->stream->ms);
bw_usage_ratio=(params.max_bandwidth > 0) ? marielle_send_bw/params.max_bandwidth : 0;
ms_message("marielle sent bw=[%f], target was [%f] bw_usage_ratio [%f]",marielle_send_bw,params.max_bandwidth,bw_usage_ratio);
video_stream_manager_delete(marielle);
video_stream_manager_delete(margaux);
return bw_usage_ratio;
}
static void lossy_network() {
bool_t supported = TRUE;//ms_filter_codec_supported("speex");
if( supported ) {
float bw_usage;
int loss_rate = getenv("GPP_LOSS") ? atoi(getenv("GPP_LOSS")) : 0;
int max_bw = getenv("GPP_MAXBW") ? atoi(getenv("GPP_MAXBW")) * 1000: 0;
printf("\nloss_rate=%d(GPP_LOSS) max_bw=%d(GPP_MAXBW)\n", loss_rate, max_bw);
bw_usage = adaptive_video_stream(H264_PAYLOAD_TYPE, 1000000, max_bw, loss_rate, 20);
CU_ASSERT_IN_RANGE(bw_usage, .9f, 1.f);
}
}
static test_t tests[] = {
{ "Lossy network", lossy_network },
};
test_suite_t video_stream_test_suite = {
"VideoStream",
tester_init,
tester_cleanup,
sizeof(tests) / sizeof(tests[0]),
tests
};
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment