Commit 6aac3afa authored by Sylvain Berfini's avatar Sylvain Berfini 🎩

Merge branch 'dev_continuous_bw_measurement'

parents 56e536fd 9302c555
......@@ -40,6 +40,8 @@ struct _MSBandwidthController{
bctbx_list_t *streams; /*list of MediaStream objects*/
struct _MediaStream *controlled_stream; /*the most bandwidth consuming stream, which is the one flow controlled*/
MSBandwidthControllerStats stats;
bool_t congestion_detected;
float remote_video_bandwidth_available_estimated;
};
/**
* The MSBandwidthController is a object managing several streams (audio, video) and monitoring congestion of inbound streams.
......
......@@ -834,7 +834,6 @@ struct _VideoStream
bool_t output_performs_decoding;
bool_t player_active;
bool_t staticimage_webcam_fps_optimization; /* if TRUE, the StaticImage webcam will ignore the fps target in order to save CPU time. Default is TRUE */
};
typedef struct _VideoStream VideoStream;
......@@ -906,6 +905,8 @@ MS2_PUBLIC MSFilter* video_stream_get_source_filter(const VideoStream* stream);
MS2_PUBLIC void video_stream_change_camera(VideoStream *stream, MSWebCam *cam);
MS2_PUBLIC void video_stream_recreate_graph(VideoStream *stream);
/**
* @brief This functions changes the source filter for the passed video stream.
* @details This is quite the same function as \ref video_stream_change_camera, but this one
......
......@@ -48,6 +48,7 @@ struct _MSFactory{
MSDevicesInfo *devices_info;
char *image_resources_dir;
char *echo_canceller_filtername;
int expected_video_bandwidth;
};
typedef struct _MSFactory MSFactory;
......@@ -412,6 +413,10 @@ MS2_PUBLIC const char * ms_factory_get_image_resources_dir(const MSFactory *f);
*/
MS2_PUBLIC void ms_factory_set_image_resources_dir(MSFactory *f, const char *path);
MS2_PUBLIC void ms_factory_set_expected_bandwidth(MSFactory *f, int bitrate);
MS2_PUBLIC int ms_factory_get_expected_bandwidth(MSFactory *f);
#ifdef __cplusplus
}
#endif
......
......@@ -408,6 +408,8 @@ MS2_PUBLIC MSVideoConfiguration ms_video_find_best_configuration_for_bitrate(con
*/
MS2_PUBLIC MSVideoConfiguration ms_video_find_best_configuration_for_size(const MSVideoConfiguration *vconf_list, MSVideoSize vsize, int cpucount);
MS2_PUBLIC MSVideoConfiguration ms_video_find_best_configuration_for_size_and_bitrate(const MSVideoConfiguration *vconf_list, MSVideoSize vsize, int cpu_count, int bitrate);
#ifdef __cplusplus
}
#endif
......
......@@ -877,6 +877,14 @@ void ms_factory_set_image_resources_dir(MSFactory *f, const char *path) {
f->image_resources_dir = bctbx_strdup(path);
}
void ms_factory_set_expected_bandwidth(MSFactory *f, int bitrate) {
f->expected_video_bandwidth = bitrate;
}
int ms_factory_get_expected_bandwidth(MSFactory *f) {
return f->expected_video_bandwidth;
}
#ifdef __ANDROID__
#include "sys/system_properties.h"
#include <jni.h>
......
......@@ -44,6 +44,7 @@ static const MSVideoConfiguration vp8_conf_list[] = {
MS_VP8_CONF(1024000, 1536000, SXGA_MINUS, 12, 2),
MS_VP8_CONF( 750000, 1024000, XGA, 12, 2),
MS_VP8_CONF( 500000, 750000, SVGA, 12, 2),
MS_VP8_CONF( 600000, 3000000, VGA, 25, 4),
MS_VP8_CONF( 300000, 500000, VGA, 12, 2),
MS_VP8_CONF( 100000, 300000, QVGA, 18, 2),
MS_VP8_CONF( 64000, 100000, QCIF, 12, 2),
......@@ -56,6 +57,7 @@ static const MSVideoConfiguration vp8_conf_list[] = {
MS_VP8_CONF(800000, 2000000, 720P, 25, 4),
MS_VP8_CONF(800000, 1536000, XGA, 25, 4),
MS_VP8_CONF( 600000, 1024000, SVGA, 25, 2),
MS_VP8_CONF( 600000, 3000000, VGA, 30, 2),
MS_VP8_CONF( 350000, 600000, VGA, 25, 2),
MS_VP8_CONF( 350000, 600000, VGA, 15, 1),
MS_VP8_CONF( 200000, 350000, CIF, 18, 1),
......@@ -579,15 +581,14 @@ static int enc_set_configuration(MSFilter *f, void *data) {
const MSVideoConfiguration *vconf = (const MSVideoConfiguration *)data;
if (vconf != &s->vconf) memcpy(&s->vconf, vconf, sizeof(MSVideoConfiguration));
if (s->vconf.required_bitrate > s->vconf.bitrate_limit)
s->vconf.required_bitrate = s->vconf.bitrate_limit;
/*if (s->vconf.required_bitrate > s->vconf.bitrate_limit)
s->vconf.required_bitrate = s->vconf.bitrate_limit;*/
s->cfg.rc_target_bitrate = (unsigned int)(((float)s->vconf.required_bitrate) * 0.92f / 1024.0f); //0.92=take into account IP/UDP/RTP overhead, in average.
if (s->ready) {
ms_filter_lock(f);
enc_postprocess(f);
enc_preprocess(f);
ms_filter_unlock(f);
return 0;
}
ms_message("Video configuration set: bitrate=%dbits/s, fps=%f, vsize=%dx%d for encoder [%p]" , s->vconf.required_bitrate,
......@@ -599,7 +600,7 @@ static int enc_set_vsize(MSFilter *f, void *data) {
MSVideoConfiguration best_vconf;
MSVideoSize *vs = (MSVideoSize *)data;
EncState *s = (EncState *)f->data;
best_vconf = ms_video_find_best_configuration_for_size(s->vconf_list, *vs, ms_factory_get_cpu_count(f->factory));
best_vconf = ms_video_find_best_configuration_for_size_and_bitrate(s->vconf_list, *vs, ms_factory_get_cpu_count(f->factory), s->vconf.required_bitrate);
s->vconf.vsize = *vs;
s->vconf.fps = best_vconf.fps;
s->vconf.bitrate_limit = best_vconf.bitrate_limit;
......@@ -643,7 +644,7 @@ static int enc_set_br(MSFilter *f, void *data) {
s->vconf.required_bitrate = br;
enc_set_configuration(f, &s->vconf);
} else {
MSVideoConfiguration best_vconf = ms_video_find_best_configuration_for_bitrate(s->vconf_list, br, ms_factory_get_cpu_count(f->factory));
MSVideoConfiguration best_vconf = ms_video_find_best_configuration_for_size_and_bitrate(s->vconf_list, s->vconf.vsize, ms_factory_get_cpu_count(f->factory), br);
enc_set_configuration(f, &best_vconf);
}
return 0;
......@@ -891,7 +892,7 @@ static void dec_init(MSFilter *f) {
static int dec_initialize_impl(MSFilter *f){
DecState *s = (DecState *)f->data;
vpx_codec_dec_cfg_t cfg;
memset(&cfg, 0, sizeof(cfg));
cfg.threads = ms_factory_get_cpu_count(f->factory);
if (vpx_codec_dec_init(&s->codec, s->iface, &cfg, s->flags)){
......@@ -907,7 +908,7 @@ static void dec_preprocess(MSFilter* f) {
/* Initialize codec */
if (!s->ready){
s->flags = 0;
#if 0
/* Deactivate fragments input for the vpx decoder because it has been broken in libvpx 1.4.
......@@ -947,12 +948,12 @@ static void dec_process(MSFilter *f) {
MSQueue frame;
MSQueue mtofree_queue;
Vp8RtpFmtFrameInfo frame_info;
if (!s->ready){
ms_queue_flush(f->inputs[0]);
return;
}
ms_filter_lock(f);
ms_queue_init(&frame);
......@@ -1019,7 +1020,7 @@ static void dec_process(MSFilter *f) {
freemsg(im);
}
}
ms_filter_unlock(f);
}
......
......@@ -76,6 +76,7 @@ static void on_congestion_state_changed(const OrtpEventData *evd, void *user_poi
ms, ms_format_type_to_string(ms->type));
return;
}
obj->congestion_detected = evd->info.congestion_detected;
session = obj->controlled_stream->sessions.rtp_session;
if (evd->info.congestion_detected){
/*We are detecting a congestion. First estimate the total bandwidth received at the time of the congestion*/
......@@ -102,11 +103,25 @@ static void on_congestion_state_changed(const OrtpEventData *evd, void *user_poi
rtp_session_send_rtcp_fb_tmmbr(session, (uint64_t)controlled_stream_bandwidth_requested);
}
static void on_video_bandwidth_estimation_available(const OrtpEventData *evd, void *user_pointer) {
MediaStream *ms = (MediaStream*)user_pointer;
MSBandwidthController *obj = ms->bandwidth_controller;
if (!obj->congestion_detected) {
RtpSession *session = obj->controlled_stream->sessions.rtp_session;
float estimated_bitrate = evd->info.video_bandwidth_available;
ms_message("MSBandwidthController: video bandwidth estimation available, sending tmmbr for stream [%p][%s] for target [%f] kbit/s",
obj->controlled_stream, ms_format_type_to_string(obj->controlled_stream->type), estimated_bitrate / 1000);
obj->remote_video_bandwidth_available_estimated = estimated_bitrate;
rtp_session_send_rtcp_fb_tmmbr(session, (uint64_t)estimated_bitrate);
}
}
/*THis function just selects a video stream if any, or an audio stream otherwise.
* It could be refined to select the most consuming stream...*/
static void elect_controlled_stream(MSBandwidthController *obj){
bctbx_list_t *elem;
bool_t done = FALSE;
OrtpVideoBandwidthEstimatorParams params = {0};
obj->controlled_stream = NULL;
for (elem = obj->streams; elem != NULL && !done; elem = elem->next){
......@@ -118,6 +133,10 @@ static void elect_controlled_stream(MSBandwidthController *obj){
case MSVideo:
obj->controlled_stream = ms;
done = TRUE;
ortp_ev_dispatcher_connect(media_stream_get_event_dispatcher(ms), ORTP_EVENT_NEW_VIDEO_BANDWIDTH_ESTIMATION_AVAILABLE, 0,
on_video_bandwidth_estimation_available, ms);
params.enabled = TRUE;
rtp_session_enable_video_bandwidth_estimator(ms->sessions.rtp_session, &params);
break;
case MSText:
break;
......@@ -127,7 +146,6 @@ static void elect_controlled_stream(MSBandwidthController *obj){
}
}
void ms_bandwidth_controller_add_stream(MSBandwidthController *obj, struct _MediaStream *stream){
ortp_ev_dispatcher_connect(media_stream_get_event_dispatcher(stream), ORTP_EVENT_CONGESTION_STATE_CHANGED, 0,
on_congestion_state_changed, stream);
......@@ -138,10 +156,15 @@ void ms_bandwidth_controller_add_stream(MSBandwidthController *obj, struct _Medi
}
void ms_bandwidth_controller_remove_stream(MSBandwidthController *obj, struct _MediaStream *stream){
OrtpVideoBandwidthEstimatorParams params = {0};
if (bctbx_list_find(obj->streams, stream) == NULL) return;
ortp_ev_dispatcher_disconnect(media_stream_get_event_dispatcher(stream), ORTP_EVENT_CONGESTION_STATE_CHANGED, 0,
on_congestion_state_changed);
rtp_session_enable_congestion_detection(stream->sessions.rtp_session, FALSE);
ortp_ev_dispatcher_disconnect(media_stream_get_event_dispatcher(stream), ORTP_EVENT_NEW_VIDEO_BANDWIDTH_ESTIMATION_AVAILABLE, 0,
on_video_bandwidth_estimation_available);
params.enabled = FALSE;
rtp_session_enable_video_bandwidth_estimator(stream->sessions.rtp_session, &params);
stream->bandwidth_controller = NULL;
obj->streams = bctbx_list_remove(obj->streams, stream);
elect_controlled_stream(obj);
......
......@@ -624,17 +624,34 @@ MSWebCamDesc *ms_mire_webcam_desc_get(void){
static void apply_bitrate_limit(MediaStream *obj, int br_limit){
int previous_br_limit = rtp_session_get_target_upload_bandwidth(obj->sessions.rtp_session);
if (!obj->encoder){
ms_warning("TMMNR not applicable because no encoder for this stream.");
return;
}
if (rtp_session_get_target_upload_bandwidth(obj->sessions.rtp_session) == br_limit) return;
if (previous_br_limit == br_limit) {
ms_message("Previous bitrate limit was already %i, skipping...", br_limit);
return;
}
if (ms_filter_call_method(obj->encoder,MS_FILTER_SET_BITRATE, &br_limit) != 0){
ms_warning("Failed to apply bitrate constraint to %s", obj->encoder->desc->name);
}
media_stream_set_target_network_bitrate(obj, br_limit);
rtp_session_set_target_upload_bandwidth(obj->sessions.rtp_session, br_limit);
if (obj->type == MSVideo) {
MSVideoConfiguration *vconf_list = NULL;
MSVideoConfiguration vconf1, vconf2;
ms_filter_call_method(obj->encoder, MS_VIDEO_ENCODER_GET_CONFIGURATION_LIST, &vconf_list);
vconf1 = ms_video_find_best_configuration_for_bitrate(vconf_list, previous_br_limit, ms_factory_get_cpu_count(obj->factory));
vconf2 = ms_video_find_best_configuration_for_bitrate(vconf_list, br_limit, ms_factory_get_cpu_count(obj->factory));
if (vconf1.required_bitrate != vconf2.required_bitrate || vconf1.bitrate_limit != vconf2.bitrate_limit) {
ms_message("VideoStream[%p]: bitrate update will change video configuration, recreate graph", obj);
video_stream_recreate_graph((VideoStream *)obj);
}
}
}
static void tmmbr_received(const OrtpEventData *evd, void *user_pointer) {
......@@ -643,7 +660,7 @@ static void tmmbr_received(const OrtpEventData *evd, void *user_pointer) {
case RTCP_RTPFB_TMMBR: {
int tmmbr_mxtbr = (int)rtcp_RTPFB_tmmbr_get_max_bitrate(evd->packet);
ms_message("MediaStream[%p]: received a TMMBR for %i kbits/s"
ms_message("MediaStream[%p]: received a TMMBR for bitrate %i kbits/s"
, ms, (int)(tmmbr_mxtbr/1000));
apply_bitrate_limit(ms, tmmbr_mxtbr);
break;
......
......@@ -969,3 +969,36 @@ MSVideoConfiguration ms_video_find_best_configuration_for_size(const MSVideoConf
best_vconf.vsize=vsize;
return best_vconf;
}
MSVideoConfiguration ms_video_find_best_configuration_for_size_and_bitrate(const MSVideoConfiguration *vconf_list, MSVideoSize vsize, int cpu_count, int bitrate) {
const MSVideoConfiguration *vconf_it = vconf_list;
MSVideoConfiguration best_vconf={0};
int min_score=INT32_MAX;
int ref_pixels=vsize.height*vsize.width;
if (bitrate == 0) return ms_video_find_best_configuration_for_size(vconf_list, vsize, cpu_count);
/* search for configuration that is first nearest to target video size, then target bitrate and finally has the greater fps,
* but any case making sure the the cpu count is sufficient*/
while(TRUE) {
int pixels=vconf_it->vsize.width*vconf_it->vsize.height;
int score=abs(pixels-ref_pixels);
if (cpu_count>=vconf_it->mincpu){
if (score<min_score){
best_vconf=*vconf_it;
min_score=score;
}else if (score==min_score) {
if (bitrate <= vconf_it->bitrate_limit && bitrate >= vconf_it->required_bitrate) {
best_vconf=*vconf_it;
}
}
}
if (vconf_it->required_bitrate==0) {
break;
}
vconf_it++;
}
best_vconf.vsize = vsize;
return best_vconf;
}
......@@ -457,6 +457,7 @@ static MSVideoSize get_with_same_orientation_and_ratio(MSVideoSize size, MSVideo
static void configure_video_source(VideoStream *stream){
MSVideoSize vsize,cam_vsize;
float fps=15;
int bitrate;
MSPixFmt format=MS_PIX_FMT_UNKNOWN;
MSVideoEncoderPixFmt encoder_supports_source_format;
int ret;
......@@ -477,6 +478,13 @@ static void configure_video_source(VideoStream *stream){
video_stream_set_native_preview_window_id(stream, stream->preview_window_id);
}
ms_filter_call_method(stream->ms.encoder, MS_FILTER_GET_BITRATE, &bitrate);
if (bitrate == 0) {
bitrate = ms_factory_get_expected_bandwidth(stream->ms.factory);
ms_message("Encoder current bitrate is 0, using expected bandwidth %i", bitrate);
ms_filter_call_method(stream->ms.encoder, MS_FILTER_SET_BITRATE, &bitrate);
}
ms_filter_call_method(stream->ms.encoder,MS_FILTER_GET_VIDEO_SIZE,&vsize);
vsize=get_compatible_size(vsize,stream->sent_vsize);
if (stream->preview_vsize.width!=0){
......@@ -817,8 +825,13 @@ static void apply_bitrate_limit(VideoStream *stream, PayloadType *pt) {
MSVideoConfiguration *vconf_list = NULL;
if (stream->ms.target_bitrate<=0) {
stream->ms.target_bitrate=pt->normal_bitrate;
ms_message("target bitrate not set for stream [%p] using payload's bitrate is %i",stream,stream->ms.target_bitrate);
stream->ms.target_bitrate = ms_factory_get_expected_bandwidth(stream->ms.factory);
if (stream->ms.target_bitrate <= 0) {
stream->ms.target_bitrate=pt->normal_bitrate;
ms_message("target bitrate not set for stream [%p] using payload's bitrate is %i",stream,stream->ms.target_bitrate);
} else {
ms_message("target bitrate not set for stream [%p] using expected bitrate is %i",stream,stream->ms.target_bitrate);
}
}
ms_message("Limiting bitrate of video encoder to %i bits/s for stream [%p]",stream->ms.target_bitrate,stream);
......@@ -1196,10 +1209,7 @@ void video_stream_update_video_params(VideoStream *stream){
*
* @return NULL if keep_old_source is FALSE, or the previous source filter if keep_old_source is TRUE
*/
static MSFilter* _video_stream_change_camera(VideoStream *stream, MSWebCam *cam, MSFilter* new_source, MSFilter *sink, bool_t keep_old_source){
PayloadType *pt;
RtpProfile *profile;
int payload;
static MSFilter* _video_stream_change_camera(VideoStream *stream, MSWebCam *cam, MSFilter* new_source, MSFilter *sink, bool_t keep_old_source, bool_t skip_payload_config){
MSFilter* old_source = NULL;
bool_t new_src_different = (new_source && new_source != stream->source);
bool_t use_player = (sink && !stream->player_active) || (!sink && stream->player_active);
......@@ -1256,17 +1266,23 @@ static MSFilter* _video_stream_change_camera(VideoStream *stream, MSWebCam *cam,
ms_filter_call_method(stream->output,MS_VIDEO_DISPLAY_SET_DEVICE_ORIENTATION,&stream->device_orientation);
}
/* Apply bitrate limit to increase video size if the preferred one has changed. */
profile = rtp_session_get_profile(stream->ms.sessions.rtp_session);
payload = rtp_session_get_send_payload_type(stream->ms.sessions.rtp_session);
pt = rtp_profile_get_payload(profile, payload);
if (stream->source_performs_encoding == TRUE) {
MSPixFmt format = mime_type_to_pix_format(pt->mime_type);
ms_filter_call_method(stream->source, MS_FILTER_SET_PIX_FMT, &format);
}
apply_video_preset(stream, pt);
if (pt->normal_bitrate > 0){
apply_bitrate_limit(stream ,pt);
if (!skip_payload_config) {
PayloadType *pt;
RtpProfile *profile;
int payload;
/* Apply bitrate limit to increase video size if the preferred one has changed. */
profile = rtp_session_get_profile(stream->ms.sessions.rtp_session);
payload = rtp_session_get_send_payload_type(stream->ms.sessions.rtp_session);
pt = rtp_profile_get_payload(profile, payload);
if (stream->source_performs_encoding == TRUE) {
MSPixFmt format = mime_type_to_pix_format(pt->mime_type);
ms_filter_call_method(stream->source, MS_FILTER_SET_PIX_FMT, &format);
}
apply_video_preset(stream, pt);
if (pt->normal_bitrate > 0){
apply_bitrate_limit(stream ,pt);
}
}
configure_video_source(stream);
......@@ -1291,24 +1307,28 @@ static MSFilter* _video_stream_change_camera(VideoStream *stream, MSWebCam *cam,
}
void video_stream_change_camera(VideoStream *stream, MSWebCam *cam){
_video_stream_change_camera(stream, cam, NULL, NULL, FALSE);
_video_stream_change_camera(stream, cam, NULL, NULL, FALSE, FALSE);
}
MSFilter* video_stream_change_camera_keep_previous_source(VideoStream *stream, MSWebCam *cam){
return _video_stream_change_camera(stream, cam, NULL, NULL, TRUE);
return _video_stream_change_camera(stream, cam, NULL, NULL, TRUE, FALSE);
}
MSFilter* video_stream_change_source_filter(VideoStream *stream, MSWebCam* cam, MSFilter* filter, bool_t keep_previous ){
return _video_stream_change_camera(stream, cam, filter, NULL, keep_previous);
return _video_stream_change_camera(stream, cam, filter, NULL, keep_previous, FALSE);
}
void video_stream_open_player(VideoStream *stream, MSFilter *sink){
ms_message("video_stream_open_player(): sink=%p",sink);
_video_stream_change_camera(stream, stream->cam, NULL, sink, FALSE);
_video_stream_change_camera(stream, stream->cam, NULL, sink, FALSE, FALSE);
}
void video_stream_close_player(VideoStream *stream){
_video_stream_change_camera(stream,stream->cam, NULL, NULL, FALSE);
_video_stream_change_camera(stream,stream->cam, NULL, NULL, FALSE, FALSE);
}
void video_stream_recreate_graph(VideoStream *stream){
_video_stream_change_camera(stream,stream->cam, NULL, NULL, FALSE, TRUE);
}
void video_stream_send_fir(VideoStream *stream) {
......
......@@ -89,6 +89,7 @@ typedef struct _stream_manager_t {
float congestion_bw_estim;
} adaptive_stats;
MSBandwidthController *bw_controller;
void* user_data;
} stream_manager_t ;
......@@ -105,6 +106,7 @@ stream_manager_t * stream_manager_new(MSFormatType type) {
}else{
#if VIDEO_ENABLED
mgr->video_stream=video_stream_new (_factory, mgr->local_rtp, mgr->local_rtcp,FALSE);
mgr->bw_controller = ms_bandwidth_controller_new();
#else
ms_fatal("Unsupported stream type [%s]",ms_format_type_to_string(mgr->type));
#endif
......@@ -124,6 +126,7 @@ static void stream_manager_delete(stream_manager_t * mgr) {
audio_stream_stop(mgr->audio_stream);
}else{
#if VIDEO_ENABLED
ms_bandwidth_controller_destroy(mgr->bw_controller);
video_stream_stop(mgr->video_stream);
#else
ms_fatal("Unsupported stream type [%s]",ms_format_type_to_string(mgr->type));
......@@ -258,9 +261,16 @@ void start_adaptive_stream(MSFormatType type, stream_manager_t ** pmarielle, str
audio_manager_start(margaux,payload,marielle->local_rtp,0,NULL,recorded_file);
}else{
#if VIDEO_ENABLED
struct _MediaStream *margaux_video_stream = &(margaux->video_stream->ms);
OrtpVideoBandwidthEstimatorParams params = {0};
marielle->video_stream->staticimage_webcam_fps_optimization = FALSE;
video_manager_start(marielle,payload,margaux->local_rtp,0,marielle_webcam);
video_stream_set_direction(margaux->video_stream, MediaStreamRecvOnly);
ms_bandwidth_controller_add_stream(margaux->bw_controller, margaux_video_stream);
params.packet_count_min = 5;
params.packets_size_max = 5;
params.enabled = TRUE;
rtp_session_enable_video_bandwidth_estimator(margaux_video_stream->sessions.rtp_session, &params);
video_manager_start(margaux,payload,marielle->local_rtp,0,NULL);
#else
ms_fatal("Unsupported stream type [%s]",ms_format_type_to_string(marielle->type));
......@@ -304,6 +314,9 @@ static void iterate_adaptive_stream(stream_manager_t * marielle, stream_manager_
}
static void stop_adaptive_stream(stream_manager_t *marielle, stream_manager_t *margaux, bool_t destroy_files){
#if VIDEO_ENABLED
ms_bandwidth_controller_remove_stream(margaux->bw_controller, &(margaux->video_stream->ms));
#endif
stream_manager_delete(marielle);
stream_manager_delete(margaux);
}
......@@ -523,14 +536,14 @@ static void upload_bitrate_opus_3g(void) {
void adaptive_video(int max_bw, int exp_min_bw, int exp_max_bw, int loss_rate, int exp_min_loss, int exp_max_loss) {
bool_t supported = ms_filter_codec_supported("VP8");
if( supported ) {
stream_manager_t * marielle, * margaux;
start_adaptive_stream(MSVideo, &marielle, &margaux, VP8_PAYLOAD_TYPE, 300*1000, max_bw*1000, loss_rate, 50,0);
stream_manager_t *marielle, *margaux;
start_adaptive_stream(MSVideo, &marielle, &margaux, VP8_PAYLOAD_TYPE, 300*1000, max_bw*1000, loss_rate, 50, 0, 0);
iterate_adaptive_stream(marielle, margaux, 100000, &marielle->rtcp_count, 7);
BC_ASSERT_GREATER(marielle->adaptive_stats.loss_estim, exp_min_loss, int, "%d");
BC_ASSERT_LOWER(marielle->adaptive_stats.loss_estim, exp_max_loss, int, "%d");
BC_ASSERT_GREATER(marielle->adaptive_stats.congestion_bw_estim, exp_min_bw, int, "%d");
BC_ASSERT_LOWER(marielle->adaptive_stats.congestion_bw_estim, exp_max_bw, int, "%d");
stop_adaptive_stream(marielle,margaux,TRUE);
stop_adaptive_stream(marielle, margaux, TRUE);
}
}
......@@ -549,6 +562,18 @@ static void adaptive_vp8_lossy_congestion() {
}
#endif
void video_bandwidth_estimation(int exp_bw_min, int exp_bw_max) {
stream_manager_t * marielle, * margaux;
start_adaptive_stream(MSVideo, &marielle, &margaux, VP8_PAYLOAD_TYPE, THIRDGENERATION_BW*1000, THIRDGENERATION_BW*1000, 0, 50, 0, FALSE);
iterate_adaptive_stream(marielle, margaux, 600000, (int *)&margaux->bw_controller->remote_video_bandwidth_available_estimated, 1);
BC_ASSERT_GREATER(margaux->bw_controller->remote_video_bandwidth_available_estimated, exp_bw_min, int, "%d");
BC_ASSERT_LOWER(margaux->bw_controller->remote_video_bandwidth_available_estimated, exp_bw_max, int, "%d");
stop_adaptive_stream(marielle, margaux, TRUE);
}
static void video_bandwidth_estimator(void) {
video_bandwidth_estimation(300000000, 1000000000); // kbits/s
}
static test_t tests[] = {
TEST_NO_TAG("Packet duplication", packet_duplication),
......@@ -568,6 +593,7 @@ static test_t tests[] = {
TEST_NO_TAG("Network detection [VP8] - congested", adaptive_vp8_congestion),
TEST_NO_TAG("Network detection [VP8] - lossy congested", adaptive_vp8_lossy_congestion),
#endif
TEST_NO_TAG("Video bandwidth estimator", video_bandwidth_estimator),
};
test_suite_t adaptive_test_suite = {
......
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