static void adaptive_opus_audio_stream() { bool_t supported = ms_filter_codec_supported("opus"); if( supported ) { // at 8KHz -> 24kb/s // at 48KHz -> 48kb/s float bw_usage; stream_manager_t * marielle, * margaux; // on EDGEBW, both should be overconsumming start_adaptive_stream(AudioStreamType, &marielle, &margaux, OPUS_PAYLOAD_TYPE, 8000, EDGE_BW, 0, 0, 0); iterate_adaptive_stream(marielle, margaux, 10000, NULL, 0); bw_usage=media_stream_get_up_bw(&marielle->audio_stream->ms)*1./EDGE_BW; CU_ASSERT_IN_RANGE(bw_usage, 2.f, 3.f); // bad! since this codec cant change its ptime and it is the lower bitrate, no improvement can occur stop_adaptive_stream(marielle,margaux); start_adaptive_stream(AudioStreamType, &marielle, &margaux, OPUS_PAYLOAD_TYPE, 48000, EDGE_BW, 0, 0, 0); iterate_adaptive_stream(marielle, margaux, 10000, NULL, 0); bw_usage=media_stream_get_up_bw(&marielle->audio_stream->ms)*1./EDGE_BW; CU_ASSERT_IN_RANGE(bw_usage, 1.f, 1.4f); // bad! stop_adaptive_stream(marielle,margaux); // on 3G BW, both should be at max start_adaptive_stream(AudioStreamType, &marielle, &margaux, OPUS_PAYLOAD_TYPE, 8000, THIRDGENERATION_BW, 0, 0, 0); iterate_adaptive_stream(marielle, margaux, 10000, NULL, 0); bw_usage=media_stream_get_up_bw(&marielle->audio_stream->ms)*1./THIRDGENERATION_BW; CU_ASSERT_IN_RANGE(bw_usage, .1f, .15f); stop_adaptive_stream(marielle,margaux); start_adaptive_stream(AudioStreamType, &marielle, &margaux, OPUS_PAYLOAD_TYPE, 48000, THIRDGENERATION_BW, 0, 0, 0); iterate_adaptive_stream(marielle, margaux, 10000, NULL, 0); bw_usage=media_stream_get_up_bw(&marielle->audio_stream->ms)*1./THIRDGENERATION_BW; CU_ASSERT_IN_RANGE(bw_usage, .2f, .3f); stop_adaptive_stream(marielle,margaux); } }
static void iterate_adaptive_stream(stream_manager_t * marielle, stream_manager_t * margaux, int timeout_ms, int* current, int expected){ int retry=0; MediaStream *marielle_ms,*margaux_ms; if (marielle->type == AudioStreamType){ marielle_ms=&marielle->audio_stream->ms; margaux_ms=&margaux->audio_stream->ms; }else{ marielle_ms=&marielle->video_stream->ms; margaux_ms=&margaux->video_stream->ms; } while ((!current||*current<expected) && retry++ <timeout_ms/100) { media_stream_iterate(marielle_ms); media_stream_iterate(margaux_ms); handle_queue_events(marielle); if (retry%10==0) { ms_message("stream [%p] bandwidth usage: [d=%.1f,u=%.1f] kbit/sec" , marielle_ms, media_stream_get_down_bw(marielle_ms)/1000, media_stream_get_up_bw(marielle_ms)/1000); ms_message("stream [%p] bandwidth usage: [d=%.1f,u=%.1f] kbit/sec" , margaux_ms, media_stream_get_down_bw(margaux_ms)/1000, media_stream_get_up_bw(margaux_ms)/1000); } ms_usleep(100000); } }
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; }
static float adaptive_audio_stream(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(); int pause_time=0; OrtpNetworkSimulatorParams params={0}; params.enabled=TRUE; params.loss_rate=0; params.max_bandwidth=target_bw; params.max_buffer_size=initial_bitrate; float bw_usage_ratio; float marielle_send_bw; 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); 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); rtp_session_enable_network_simulation(margaux->stream->ms.sessions.rtp_session,¶ms); wait_for_until(&marielle->stream->ms,&margaux->stream->ms,&marielle->stats.number_of_EndOfFile,10,2500*max_recv_rtcp_packet); marielle_send_bw=media_stream_get_up_bw(&marielle->stream->ms); bw_usage_ratio=marielle_send_bw/params.max_bandwidth; 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); unlink(RECORDED_16K_1S_FILE); return bw_usage_ratio; }
static void adaptive_pcma_audio_stream() { bool_t supported = ms_filter_codec_supported("pcma"); if( supported ) { // at 8KHz -> 80 kb/s float bw_usage; stream_manager_t * marielle, * margaux; // yet non-adaptative codecs cannot respect low throughput limitations start_adaptive_stream(AudioStreamType, &marielle, &margaux, PCMA8_PAYLOAD_TYPE, 8000, EDGE_BW, 0, 0, 0); iterate_adaptive_stream(marielle, margaux, 10000, NULL, 0); bw_usage=media_stream_get_up_bw(&marielle->audio_stream->ms)*1./EDGE_BW; CU_ASSERT_IN_RANGE(bw_usage,6.f, 8.f); // this is bad! stop_adaptive_stream(marielle,margaux); start_adaptive_stream(AudioStreamType, &marielle, &margaux, PCMA8_PAYLOAD_TYPE, 8000, THIRDGENERATION_BW, 0, 0, 0); iterate_adaptive_stream(marielle, margaux, 10000, NULL, 0); bw_usage=media_stream_get_up_bw(&marielle->audio_stream->ms)*1./THIRDGENERATION_BW; CU_ASSERT_IN_RANGE(bw_usage, .3f, .5f); stop_adaptive_stream(marielle,margaux); } }
static void adaptive_speex16_audio_stream() { bool_t supported = ms_filter_codec_supported("speex"); if( supported ) { // at 16KHz -> 20 kb/s // at 32KHz -> 30 kb/s float bw_usage; stream_manager_t * marielle, * margaux; start_adaptive_stream(AudioStreamType, &marielle, &margaux, SPEEX16_PAYLOAD_TYPE, 32000, EDGE_BW / 2., 0, 0, 0); iterate_adaptive_stream(marielle, margaux, 10000, NULL, 0); bw_usage=media_stream_get_up_bw(&marielle->audio_stream->ms)*1./(EDGE_BW / 2.); CU_ASSERT_IN_RANGE(bw_usage, 1.f, 5.f); stop_adaptive_stream(marielle,margaux); } }
void upload_bitrate(const char* codec, int payload, int target_bw, int expect_bw) { bool_t supported = ms_filter_codec_supported(codec); if( supported ) { float upload_bw; stream_manager_t * marielle, * margaux; start_adaptive_stream(MSAudio, &marielle, &margaux, payload, target_bw*1000, target_bw*1000, 0, 50,0); //these tests check that encoders stick to the guidelines, so we must use NOT //the adaptive algorithm which would modify these guidelines media_stream_enable_adaptive_bitrate_control(&marielle->audio_stream->ms,FALSE); iterate_adaptive_stream(marielle, margaux, 15000, NULL, 0); upload_bw=media_stream_get_up_bw(&marielle->audio_stream->ms) / 1000; CU_ASSERT_IN_RANGE(upload_bw, expect_bw-2, expect_bw+2); stop_adaptive_stream(marielle,margaux); } }
static void qos_analyzer_on_action_suggested(void *user_data, int datac, const char** datav){ reporting_session_report_t *report = (reporting_session_report_t*)user_data; LinphoneCall *call = report->call; char * appendbuf; int i; int ptime = -1; int bitrate[3] = {-1, -1, -1}; int up_bw[3] = {-1, -1, -1}; int down_bw[3] = {-1, -1, -1}; MediaStream *streams[3] = { (MediaStream*) call->audiostream, (MediaStream *) call->videostream, (MediaStream *) call->textstream }; for (i = 0; i < 3; i++){ if (streams[i] != NULL){ if (streams[i]->encoder != NULL){ if (ms_filter_has_method(streams[i]->encoder,MS_FILTER_GET_BITRATE)){ ms_filter_call_method(streams[i]->encoder,MS_FILTER_GET_BITRATE,&bitrate[i]); bitrate[i] /= 1000; } } up_bw[i] = (int)(media_stream_get_up_bw(streams[i])/1000.f); down_bw[i] = (int)(media_stream_get_down_bw(streams[i])/1000.f); } } if (call->audiostream!=NULL){ if (call->audiostream->ms.encoder!=NULL){ if(ms_filter_has_method(call->audiostream->ms.encoder,MS_AUDIO_ENCODER_GET_PTIME)){ ms_filter_call_method(call->audiostream->ms.encoder,MS_AUDIO_ENCODER_GET_PTIME,&ptime); } } } appendbuf=ms_strdup_printf("%s%d;", report->qos_analyzer.timestamp?report->qos_analyzer.timestamp:"", ms_time(0)); STR_REASSIGN(report->qos_analyzer.timestamp,appendbuf); STR_REASSIGN(report->qos_analyzer.input_leg, ms_strdup_printf("%s aenc_ptime aenc_br a_dbw a_ubw venc_br v_dbw v_ubw tenc_br t_dbw t_ubw", datav[0])); appendbuf=ms_strdup_printf("%s%s %d %d %d %d %d %d %d %d %d %d;", report->qos_analyzer.input?report->qos_analyzer.input:"", datav[1], ptime, bitrate[0], down_bw[0], up_bw[0], bitrate[1], down_bw[1], up_bw[1], bitrate[2], down_bw[2], up_bw[2]); STR_REASSIGN(report->qos_analyzer.input,appendbuf); STR_REASSIGN(report->qos_analyzer.output_leg, ms_strdup(datav[2])); appendbuf=ms_strdup_printf("%s%s;", report->qos_analyzer.output?report->qos_analyzer.output:"", datav[3]); STR_REASSIGN(report->qos_analyzer.output, appendbuf); }
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(); int pause_time=0; OrtpNetworkSimulatorParams params={0}; params.enabled=TRUE; params.loss_rate=0; params.max_bandwidth=target_bw; params.max_buffer_size=initial_bitrate; float recv_send_bw_ratio; int rtcp_interval = 1000; float marielle_send_bw; 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); 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"); rtp_session_enable_network_simulation(margaux->stream->ms.session,¶ms); rtp_session_set_rtcp_report_interval(margaux->stream->ms.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); recv_send_bw_ratio=params.max_bandwidth/marielle_send_bw; 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); }