diff --git a/mediastreamer2 b/mediastreamer2
index 625087594..e998419b7 160000
--- a/mediastreamer2
+++ b/mediastreamer2
@@ -1 +1 @@
-Subproject commit 6250875949495a354aea7f62e1f7aa9652397f84
+Subproject commit e998419b7fd1e43a39974d2cf408ae169888a62b
diff --git a/tester/CMakeLists.txt b/tester/CMakeLists.txt
index 6b2fa81d2..39643bfba 100644
--- a/tester/CMakeLists.txt
+++ b/tester/CMakeLists.txt
@@ -22,6 +22,7 @@
set(SOURCE_FILES
accountmanager.c
+ audio_bypass_tester.c
call_tester.c
complex_sip_call_tester.c
dtmf_tester.c
diff --git a/tester/Makefile.am b/tester/Makefile.am
index 4d3df1a78..d872f6917 100644
--- a/tester/Makefile.am
+++ b/tester/Makefile.am
@@ -112,6 +112,7 @@ lib_LTLIBRARIES = liblinphonetester.la
liblinphonetester_la_SOURCES = \
accountmanager.c \
+ audio_bypass_tester.c \
call_tester.c \
complex_sip_call_tester.c \
dtmf_tester.c \
diff --git a/tester/audio_bypass_tester.c b/tester/audio_bypass_tester.c
new file mode 100644
index 000000000..25770020d
--- /dev/null
+++ b/tester/audio_bypass_tester.c
@@ -0,0 +1,264 @@
+/*
+ liblinphone_tester - liblinphone test suite
+ Copyright (C) 2013 Belledonne Communications SARL
+
+ 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, see .
+*/
+
+#include "liblinphone_tester.h"
+#include "private.h"
+#include "mediastreamer2/msfileplayer.h"
+#include "mediastreamer2/msfilerec.h"
+
+static void audio_bypass_snd_read_init(MSFilter *f) {
+
+}
+
+static void audio_bypass_snd_read_preprocess(MSFilter *f) {
+
+}
+
+static void audio_bypass_snd_read_process(MSFilter *f) {
+ mblk_t *m = allocb(10, 0);
+ memset(m->b_wptr, 0, 10);
+ m->b_wptr += 10;
+ ms_queue_put(f->outputs[0], m);
+}
+
+static void audio_bypass_snd_read_postprocess(MSFilter *f) {
+
+}
+
+static void audio_bypass_snd_read_uninit(MSFilter *f) {
+
+}
+
+static int audio_bypass_snd_read_get_sample_rate(MSFilter *f, void *arg) {
+ int *sample_rate = (int *)arg;
+ *sample_rate = 44100;
+ return 0;
+}
+
+static int audio_bypass_snd_read_get_nchannels(MSFilter *f, void *arg) {
+ int *nchannels = (int *)arg;
+ *nchannels = 1;
+ return 0;
+}
+
+static int audio_bypass_snd_read_get_fmt(MSFilter *f, void *arg) {
+ MSPinFormat *pinFmt = (MSPinFormat *)arg;
+ pinFmt->fmt = ms_factory_get_audio_format(f->factory, "L16", 44100, 1, NULL);
+ return 0;
+}
+
+static MSFilterMethod audio_bypass_snd_read_methods[] = {
+ { MS_FILTER_GET_SAMPLE_RATE, audio_bypass_snd_read_get_sample_rate },
+ { MS_FILTER_GET_NCHANNELS, audio_bypass_snd_read_get_nchannels },
+ { MS_FILTER_GET_OUTPUT_FMT, audio_bypass_snd_read_get_fmt },
+ { 0, NULL }
+};
+
+MSFilterDesc audio_bypass_snd_read_desc = {
+ MS_FILTER_PLUGIN_ID,
+ "AudioBypassReader",
+ "audio bypass source",
+ MS_FILTER_OTHER,
+ NULL,
+ 0,
+ 1,
+ audio_bypass_snd_read_init,
+ audio_bypass_snd_read_preprocess,
+ audio_bypass_snd_read_process,
+ audio_bypass_snd_read_postprocess,
+ audio_bypass_snd_read_uninit,
+ audio_bypass_snd_read_methods
+};
+
+static void audio_bypass_snd_write_init(MSFilter *f) {
+
+}
+
+static void audio_bypass_snd_write_preprocess(MSFilter *f) {
+
+}
+
+static void audio_bypass_snd_write_process(MSFilter *f) {
+ ms_queue_get(f->inputs[0]);
+}
+
+static void audio_bypass_snd_write_postprocess(MSFilter *f) {
+
+}
+
+static void audio_bypass_snd_write_uninit(MSFilter *f) {
+
+}
+
+static int audio_bypass_snd_write_get_sample_rate(MSFilter *f, void *arg) {
+ int *sample_rate = (int*)arg;
+ *sample_rate = 44100;
+ return 0;
+}
+
+static int audio_bypass_snd_write_get_nchannels(MSFilter *obj, void *arg) {
+ int *nchannels = (int*)arg;
+ *nchannels = 1;
+ return 0;
+}
+
+static int audio_bypass_snd_write_get_fmt(MSFilter *f, void *arg) {
+ MSPinFormat *pinFmt = (MSPinFormat *)arg;
+ pinFmt->fmt = ms_factory_get_audio_format(f->factory, "L16", 44100, 1, NULL);
+ return 0;
+}
+
+static MSFilterMethod audio_bypass_snd_write_methods[] = {
+ { MS_FILTER_GET_SAMPLE_RATE, audio_bypass_snd_write_get_sample_rate },
+ { MS_FILTER_GET_NCHANNELS, audio_bypass_snd_write_get_nchannels },
+ { MS_FILTER_GET_OUTPUT_FMT, audio_bypass_snd_write_get_fmt },
+ { 0, NULL }
+};
+
+MSFilterDesc audio_bypass_snd_write_desc = {
+ MS_FILTER_PLUGIN_ID,
+ "AudioBypassWriter",
+ "audio bypass output",
+ MS_FILTER_OTHER,
+ NULL,
+ 1,
+ 0,
+ audio_bypass_snd_write_init,
+ audio_bypass_snd_write_preprocess,
+ audio_bypass_snd_write_process,
+ audio_bypass_snd_write_postprocess,
+ audio_bypass_snd_write_uninit,
+ audio_bypass_snd_write_methods
+};
+
+static MSFilter* audio_bypass_snd_card_create_reader(MSSndCard *sndcard) {
+ MSFactory *factory = ms_snd_card_get_factory(sndcard);
+ MSFilter *f = ms_factory_create_filter_from_desc(factory, &audio_bypass_snd_read_desc);
+ return f;
+}
+
+static MSFilter* audio_bypass_snd_card_create_writer(MSSndCard *sndcard) {
+ MSFactory *factory = ms_snd_card_get_factory(sndcard);
+ MSFilter *f = ms_factory_create_filter_from_desc(factory, &audio_bypass_snd_write_desc);
+
+ MSPinFormat *pinfmt = ms_new0(MSPinFormat, 0);
+ pinfmt->pin = 0;
+ pinfmt->fmt = ms_factory_get_audio_format(factory, "L16", 44100, 1, NULL);
+
+ ms_filter_call_method(f, MS_FILTER_SET_OUTPUT_FMT, pinfmt);
+ ms_free(pinfmt);
+
+ return f;
+}
+
+static void audio_bypass_snd_card_detect(MSSndCardManager *m);
+
+MSSndCardDesc audio_bypass_snd_card_desc = {
+ "audioBypass",
+ audio_bypass_snd_card_detect,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ audio_bypass_snd_card_create_reader,
+ audio_bypass_snd_card_create_writer,
+ NULL
+};
+
+static MSSndCard* create_audio_bypass_snd_card(void) {
+ MSSndCard* sndcard;
+ sndcard = ms_snd_card_new(&audio_bypass_snd_card_desc);
+ sndcard->data = NULL;
+ sndcard->name = ms_strdup("audio bypass sound card");
+ sndcard->capabilities = MS_SND_CARD_CAP_PLAYBACK | MS_SND_CARD_CAP_CAPTURE;
+ sndcard->latency = 0;
+ return sndcard;
+}
+
+static void audio_bypass_snd_card_detect(MSSndCardManager *m) {
+ ms_snd_card_manager_add_card(m, create_audio_bypass_snd_card());
+}
+
+static void audio_bypass(void) {
+ LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc_audio_bypass");
+ LinphoneCore *marie_lc = marie->lc;
+ MSFactory *marie_factory = linphone_core_get_ms_factory(marie_lc);
+ MSSndCardManager *marie_sndcard_manager = ms_factory_get_snd_card_manager(marie_factory);
+
+ LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc_audio_bypass");
+ LinphoneCore *pauline_lc = pauline->lc;
+ MSFactory *pauline_factory = linphone_core_get_ms_factory(pauline_lc);
+ MSSndCardManager *pauline_sndcard_manager = ms_factory_get_snd_card_manager(pauline_factory);
+
+ bool_t call_ok;
+ MSList *marie_audio_codecs = marie_lc->codecs_conf.audio_codecs;
+ MSList *pauline_audio_codecs = pauline_lc->codecs_conf.audio_codecs;
+
+ // Enable L16 audio codec
+ while (marie_audio_codecs) {
+ PayloadType *pt = (PayloadType *)marie_audio_codecs->data;
+ if (strcmp(pt->mime_type, "L16") == 0 && pt->channels == 1) {
+ pt->flags |= PAYLOAD_TYPE_ENABLED;
+ } else {
+ pt->flags &= PAYLOAD_TYPE_ENABLED;
+ }
+ marie_audio_codecs = ms_list_next(marie_audio_codecs);
+ }
+ while (pauline_audio_codecs) {
+ PayloadType *pt = (PayloadType *)pauline_audio_codecs->data;
+ if (strcmp(pt->mime_type, "L16") == 0 && pt->channels == 1) {
+ pt->flags |= PAYLOAD_TYPE_ENABLED;
+ } else {
+ pt->flags &= PAYLOAD_TYPE_ENABLED;
+ }
+ pauline_audio_codecs = ms_list_next(pauline_audio_codecs);
+ }
+
+ // Add our custom sound card
+ ms_snd_card_manager_register_desc(marie_sndcard_manager, &audio_bypass_snd_card_desc);
+ ms_snd_card_manager_register_desc(pauline_sndcard_manager, &audio_bypass_snd_card_desc);
+ linphone_core_reload_sound_devices(marie->lc);
+ linphone_core_reload_sound_devices(pauline->lc);
+ linphone_core_set_playback_device(marie->lc, "audioBypass: audio bypass sound card");
+ linphone_core_set_playback_device(pauline->lc, "audioBypass: audio bypass sound card");
+ linphone_core_set_capture_device(marie->lc, "audioBypass: audio bypass sound card");
+ linphone_core_set_capture_device(pauline->lc, "audioBypass: audio bypass sound card");
+
+ call_ok = call(marie, pauline);
+ BC_ASSERT_TRUE(call_ok);
+ if (!call_ok) goto end;
+
+ BC_ASSERT_STRING_EQUAL(linphone_call_params_get_used_audio_codec(linphone_call_get_current_params(linphone_core_get_current_call(marie_lc)))->mime_type, "L16");
+
+ wait_for_until(pauline->lc, marie->lc, NULL, 0, 10000);
+ end_call(marie, pauline);
+
+end:
+ linphone_core_manager_destroy(marie);
+ linphone_core_manager_destroy(pauline);
+}
+
+test_t audio_bypass_tests[] = {
+ TEST_NO_TAG("Audio Bypass", audio_bypass)
+};
+
+test_suite_t audio_bypass_suite = { "Audio Bypass", NULL, NULL,
+ liblinphone_tester_before_each, liblinphone_tester_after_each,
+ sizeof(audio_bypass_tests) / sizeof(audio_bypass_tests[0]), audio_bypass_tests };
diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h
index c9dbe89ba..7ae98bef7 100644
--- a/tester/liblinphone_tester.h
+++ b/tester/liblinphone_tester.h
@@ -61,6 +61,7 @@ extern test_suite_t multicast_call_test_suite;
extern test_suite_t multi_call_test_suite;
extern test_suite_t proxy_config_test_suite;
extern test_suite_t vcard_test_suite;
+extern test_suite_t audio_bypass_suite;
#if HAVE_SIPP
extern test_suite_t complex_sip_call_test_suite;
#endif
diff --git a/tester/rcfiles/marie_rc_audio_bypass b/tester/rcfiles/marie_rc_audio_bypass
new file mode 100644
index 000000000..6f27d215f
--- /dev/null
+++ b/tester/rcfiles/marie_rc_audio_bypass
@@ -0,0 +1,67 @@
+[sip]
+sip_port=-1
+sip_tcp_port=-1
+sip_tls_port=-1
+default_proxy=0
+ping_with_options=0
+composing_idle_timeout=1
+store_ha1_passwd=0 #used for sipp
+
+[auth_info_0]
+username=marie
+userid=marie
+passwd=secret
+realm=sip.example.org
+
+[proxy_0]
+reg_proxy=sip.example.org;transport=tcp
+reg_route=sip.example.org;transport=tcp;lr
+reg_identity="Super Marie"
+reg_expires=3600
+reg_sendregister=1
+publish=0
+dial_escape_plus=0
+
+[friend_0]
+url="Paupoche"
+pol=accept
+subscribe=0
+
+[rtp]
+audio_rtp_port=18070-28000
+video_rtp_port=28070-38000
+text_rtp_port=39000-49000
+
+[video]
+display=0
+capture=0
+show_local=0
+size=qcif
+enabled=0
+self_view=0
+automatically_initiate=0
+automatically_accept=0
+device=StaticImage: Static picture
+
+[sound]
+echocancellation=0 #to not overload cpu in case of VG
+features=NONE
+
+[net]
+dns_srv_enabled=0 #no srv needed in general
+stun_server=stun.linphone.org
+
+[misc]
+add_missing_audio_codecs=0
+
+[audio_codec_0]
+mime=L16
+rate=44100
+channels=2
+enabled=0
+
+[audio_codec_1]
+mime=L16
+rate=44100
+channels=1
+enabled=1
diff --git a/tester/rcfiles/pauline_rc_audio_bypass b/tester/rcfiles/pauline_rc_audio_bypass
new file mode 100644
index 000000000..73ad2d251
--- /dev/null
+++ b/tester/rcfiles/pauline_rc_audio_bypass
@@ -0,0 +1,65 @@
+[sip]
+sip_port=-1
+sip_tcp_port=-1
+sip_tls_port=-1
+default_proxy=0
+ping_with_options=0
+composing_idle_timeout=1
+
+[auth_info_0]
+username=pauline
+userid=pauline
+passwd=secret
+realm=sip.example.org
+
+[proxy_0]
+reg_proxy=sip2.linphone.org;transport=tls
+reg_route=sip2.linphone.org;transport=tls
+reg_identity=sip:pauline@sip.example.org
+reg_expires=3600
+reg_sendregister=1
+publish=0
+dial_escape_plus=0
+
+#[friend_0]
+#url="Mariette"
+#pol=accept
+#subscribe=0
+
+[rtp]
+audio_rtp_port=18070-28000
+video_rtp_port=39072-49000
+
+[video]
+display=0
+capture=0
+show_local=0
+size=qcif
+enabled=0
+self_view=0
+automatically_initiate=0
+automatically_accept=0
+device=StaticImage: Static picture
+
+[sound]
+echocancellation=0 #to not overload cpu in case of VG
+features=NONE
+
+[net]
+dns_srv_enabled=0 #no srv needed in general
+stun_server=stun.linphone.org
+
+[misc]
+add_missing_audio_codecs=0
+
+[audio_codec_0]
+mime=L16
+rate=44100
+channels=2
+enabled=0
+
+[audio_codec_1]
+mime=L16
+rate=44100
+channels=1
+enabled=1
diff --git a/tester/tester.c b/tester/tester.c
index 2b35d0618..f734f8006 100644
--- a/tester/tester.c
+++ b/tester/tester.c
@@ -480,6 +480,7 @@ void liblinphone_tester_add_suites() {
bc_tester_add_suite(&tunnel_test_suite);
bc_tester_add_suite(&offeranswer_test_suite);
bc_tester_add_suite(&call_test_suite);
+ bc_tester_add_suite(&audio_bypass_suite);
bc_tester_add_suite(&multi_call_test_suite);
bc_tester_add_suite(&message_test_suite);
bc_tester_add_suite(&presence_test_suite);