summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiong Sauw Ming <ming@teluu.com>2011-03-11 06:57:24 +0000
committerLiong Sauw Ming <ming@teluu.com>2011-03-11 06:57:24 +0000
commitc44da2d6d7f8a991cd8143f97acda117a4e0a422 (patch)
treee57adad451551e486fdbb8f4de0b2240978d091d
parenta71c9ccfea1d7d9e7999037a8ee13820eb0e16e2 (diff)
Fixed #1204: Support for refreshing audio device list.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3438 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjmedia/include/pjmedia-audiodev/audiodev.h14
-rw-r--r--pjmedia/include/pjmedia-audiodev/audiodev_imp.h7
-rw-r--r--pjmedia/include/pjmedia/sound_port.h37
-rw-r--r--pjmedia/src/pjmedia-audiodev/alsa_dev.c106
-rw-r--r--pjmedia/src/pjmedia-audiodev/audiodev.c19
-rw-r--r--pjmedia/src/pjmedia-audiodev/coreaudio_dev.c3
-rw-r--r--pjmedia/src/pjmedia-audiodev/legacy_dev.c11
-rw-r--r--pjmedia/src/pjmedia-audiodev/null_dev.c11
-rw-r--r--pjmedia/src/pjmedia-audiodev/pa_dev.c12
-rw-r--r--pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp11
-rw-r--r--pjmedia/src/pjmedia-audiodev/symb_mda_dev.cpp11
-rw-r--r--pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp11
-rw-r--r--pjmedia/src/pjmedia-audiodev/wmme_dev.c199
-rw-r--r--pjmedia/src/pjmedia/sound_port.c77
-rw-r--r--pjsip/src/pjsua-lib/pjsua_media.c54
15 files changed, 479 insertions, 104 deletions
diff --git a/pjmedia/include/pjmedia-audiodev/audiodev.h b/pjmedia/include/pjmedia-audiodev/audiodev.h
index ba28bc0f..1d1c39c0 100644
--- a/pjmedia/include/pjmedia-audiodev/audiodev.h
+++ b/pjmedia/include/pjmedia-audiodev/audiodev.h
@@ -546,6 +546,20 @@ pjmedia_aud_unregister_factory(pjmedia_aud_dev_factory_create_func_ptr adf);
/**
+ * Refresh the list of sound devices installed in the system. This function
+ * will only refresh the list of audio device so all active audio streams will
+ * be unaffected. After refreshing the device list, application MUST make sure
+ * to update all index references to audio devices (i.e. all variables of type
+ * pjmedia_aud_dev_index) before calling any function that accepts audio device
+ * index as its parameter.
+ *
+ * @return PJ_SUCCESS on successful operation or the appropriate
+ * error code.
+ */
+PJ_DECL(pj_status_t) pjmedia_aud_dev_refresh(void);
+
+
+/**
* Get the number of sound devices installed in the system.
*
* @return The number of sound devices installed in the system.
diff --git a/pjmedia/include/pjmedia-audiodev/audiodev_imp.h b/pjmedia/include/pjmedia-audiodev/audiodev_imp.h
index e12c0f21..172c1279 100644
--- a/pjmedia/include/pjmedia-audiodev/audiodev_imp.h
+++ b/pjmedia/include/pjmedia-audiodev/audiodev_imp.h
@@ -92,6 +92,13 @@ typedef struct pjmedia_aud_dev_factory_op
void *user_data,
pjmedia_aud_stream **p_aud_strm);
+ /**
+ * Refresh the list of audio devices installed in the system.
+ *
+ * @param f The audio device factory.
+ */
+ pj_status_t (*refresh)(pjmedia_aud_dev_factory *f);
+
} pjmedia_aud_dev_factory_op;
diff --git a/pjmedia/include/pjmedia/sound_port.h b/pjmedia/include/pjmedia/sound_port.h
index 7293a4d7..4d2d4aff 100644
--- a/pjmedia/include/pjmedia/sound_port.h
+++ b/pjmedia/include/pjmedia/sound_port.h
@@ -63,6 +63,33 @@ PJ_BEGIN_DECL
*/
/**
+ * Sound port options.
+ */
+enum pjmedia_snd_port_option
+{
+ /**
+ * Don't start the audio device when creating a sound port.
+ */
+ PJMEDIA_SND_PORT_NO_AUTO_START = 1
+};
+
+/**
+ * This structure specifies the parameters to create the sound port.
+ */
+typedef struct pjmedia_snd_port_param
+{
+ /**
+ * Base structure.
+ */
+ pjmedia_aud_param base;
+
+ /**
+ * Sound port creation options.
+ */
+ unsigned options;
+} pjmedia_snd_port_param;
+
+/**
* This opaque type describes sound device port connection.
* Sound device port is not a media port, but it is used to connect media
* port to the sound device.
@@ -86,7 +113,7 @@ typedef struct pjmedia_snd_port pjmedia_snd_port;
* @param samples_per_frame Number of samples per frame.
* @param bits_per_sample Set the number of bits per sample. The normal
* value for this parameter is 16 bits per sample.
- * @param options Options flag, currently must be zero.
+ * @param options Options flag.
* @param p_port Pointer to receive the sound device port instance.
*
* @return PJ_SUCCESS on success, or the appropriate error
@@ -116,7 +143,7 @@ PJ_DECL(pj_status_t) pjmedia_snd_port_create( pj_pool_t *pool,
* @param samples_per_frame Number of samples per frame.
* @param bits_per_sample Set the number of bits per sample. The normal
* value for this parameter is 16 bits per sample.
- * @param options Options flag, currently must be zero.
+ * @param options Options flag.
* @param p_port Pointer to receive the sound device port instance.
*
* @return PJ_SUCCESS on success, or the appropriate error
@@ -145,7 +172,7 @@ PJ_DECL(pj_status_t) pjmedia_snd_port_create_rec(pj_pool_t *pool,
* @param samples_per_frame Number of samples per frame.
* @param bits_per_sample Set the number of bits per sample. The normal
* value for this parameter is 16 bits per sample.
- * @param options Options flag, currently must be zero.
+ * @param options Options flag.
* @param p_port Pointer to receive the sound device port instance.
*
* @return PJ_SUCCESS on success, or the appropriate error
@@ -165,14 +192,14 @@ PJ_DECL(pj_status_t) pjmedia_snd_port_create_player(pj_pool_t *pool,
* Create sound device port according to the specified parameters.
*
* @param pool Pool to allocate sound port structure.
- * @param prm Sound device settings.
+ * @param prm Sound port parameter.
* @param p_port Pointer to receive the sound device port instance.
*
* @return PJ_SUCCESS on success, or the appropriate error
* code.
*/
PJ_DECL(pj_status_t) pjmedia_snd_port_create2(pj_pool_t *pool,
- const pjmedia_aud_param *prm,
+ const pjmedia_snd_port_param *prm,
pjmedia_snd_port **p_port);
diff --git a/pjmedia/src/pjmedia-audiodev/alsa_dev.c b/pjmedia/src/pjmedia-audiodev/alsa_dev.c
index 90eca542..c2cc4e5e 100644
--- a/pjmedia/src/pjmedia-audiodev/alsa_dev.c
+++ b/pjmedia/src/pjmedia-audiodev/alsa_dev.c
@@ -57,6 +57,7 @@
*/
static pj_status_t alsa_factory_init(pjmedia_aud_dev_factory *f);
static pj_status_t alsa_factory_destroy(pjmedia_aud_dev_factory *f);
+static pj_status_t alsa_factory_refresh(pjmedia_aud_dev_factory *f);
static unsigned alsa_factory_get_dev_count(pjmedia_aud_dev_factory *f);
static pj_status_t alsa_factory_get_dev_info(pjmedia_aud_dev_factory *f,
unsigned index,
@@ -92,6 +93,7 @@ struct alsa_factory
pjmedia_aud_dev_factory base;
pj_pool_factory *pf;
pj_pool_t *pool;
+ pj_pool_t *base_pool;
unsigned dev_cnt;
pjmedia_aud_dev_info devs[MAX_DEVICES];
@@ -133,7 +135,8 @@ static pjmedia_aud_dev_factory_op alsa_factory_op =
&alsa_factory_get_dev_count,
&alsa_factory_get_dev_info,
&alsa_factory_default_param,
- &alsa_factory_create_stream
+ &alsa_factory_create_stream,
+ &alsa_factory_refresh
};
static pjmedia_aud_stream_op alsa_stream_op =
@@ -146,6 +149,20 @@ static pjmedia_aud_stream_op alsa_stream_op =
&alsa_stream_destroy
};
+static void null_alsa_error_handler (const char *file,
+ int line,
+ const char *function,
+ int err,
+ const char *fmt,
+ ...)
+{
+ PJ_UNUSED_ARG(file);
+ PJ_UNUSED_ARG(line);
+ PJ_UNUSED_ARG(function);
+ PJ_UNUSED_ARG(err);
+ PJ_UNUSED_ARG(fmt);
+}
+
static void alsa_error_handler (const char *file,
int line,
const char *function,
@@ -174,10 +191,9 @@ static void alsa_error_handler (const char *file,
}
-static pj_status_t add_dev (struct alsa_factory *af, int card, int device)
+static pj_status_t add_dev (struct alsa_factory *af, const char *dev_name)
{
pjmedia_aud_dev_info *adi;
- char dev_name[32];
snd_pcm_t* pcm;
int pb_result, ca_result;
@@ -186,8 +202,7 @@ static pj_status_t add_dev (struct alsa_factory *af, int card, int device)
adi = &af->devs[af->dev_cnt];
- TRACE_((THIS_FILE, "add_dev (%d, %d): Enter", card, device));
- sprintf (dev_name, ALSA_DEVICE_NAME, card, device);
+ TRACE_((THIS_FILE, "add_dev (%s): Enter", dev_name));
/* Try to open the device in playback mode */
pb_result = snd_pcm_open (&pcm, dev_name, SND_PCM_STREAM_PLAYBACK, 0);
@@ -245,10 +260,10 @@ pjmedia_aud_dev_factory* pjmedia_alsa_factory(pj_pool_factory *pf)
struct alsa_factory *af;
pj_pool_t *pool;
- pool = pj_pool_create(pf, "alsa_aud", 256, 256, NULL);
+ pool = pj_pool_create(pf, "alsa_aud_base", 256, 256, NULL);
af = PJ_POOL_ZALLOC_T(pool, struct alsa_factory);
af->pf = pf;
- af->pool = pool;
+ af->base_pool = pool;
af->base.op = &alsa_factory_op;
return &af->base;
@@ -258,23 +273,11 @@ pjmedia_aud_dev_factory* pjmedia_alsa_factory(pj_pool_factory *pf)
/* API: init factory */
static pj_status_t alsa_factory_init(pjmedia_aud_dev_factory *f)
{
- struct alsa_factory *af = (struct alsa_factory*)f;
- int card, device;
-
- TRACE_((THIS_FILE, "pjmedia_snd_init: Enumerate sound devices"));
- /* Enumerate sound devices */
- for (card=0; card<MAX_SOUND_CARDS; card++) {
- for (device=0; device<MAX_SOUND_DEVICES_PER_CARD; device++) {
- add_dev(af, card, device);
- }
- }
-
- /* Install error handler after enumeration, otherwise we'll get many
- * error messages about invalid card/device ID.
- */
- snd_lib_error_set_handler (alsa_error_handler);
+ pj_status_t status = alsa_factory_refresh(f);
+ if (PJ_SUCCESS != status)
+ return status;
- PJ_LOG(4,(THIS_FILE, "ALSA driver found %d devices", af->dev_cnt));
+ PJ_LOG(4,(THIS_FILE, "ALSA initialized"));
return PJ_SUCCESS;
}
@@ -284,9 +287,12 @@ static pj_status_t alsa_factory_destroy(pjmedia_aud_dev_factory *f)
{
struct alsa_factory *af = (struct alsa_factory*)f;
- if (af->pool) {
- pj_pool_t *pool = af->pool;
- af->pool = NULL;
+ if (af->pool)
+ pj_pool_release(af->pool);
+
+ if (af->base_pool) {
+ pj_pool_t *pool = af->base_pool;
+ af->base_pool = NULL;
pj_pool_release(pool);
}
@@ -297,6 +303,54 @@ static pj_status_t alsa_factory_destroy(pjmedia_aud_dev_factory *f)
}
+/* API: refresh the device list */
+static pj_status_t alsa_factory_refresh(pjmedia_aud_dev_factory *f)
+{
+ struct alsa_factory *af = (struct alsa_factory*)f;
+ char **hints, **n;
+ int err;
+
+ TRACE_((THIS_FILE, "pjmedia_snd_init: Enumerate sound devices"));
+
+ if (af->pool != NULL) {
+ pj_pool_release(af->pool);
+ af->pool = NULL;
+ }
+
+ af->pool = pj_pool_create(af->pf, "alsa_aud", 256, 256, NULL);
+ af->dev_cnt = 0;
+
+ /* Enumerate sound devices */
+ err = snd_device_name_hint(-1, "pcm", (void***)&hints);
+ if (err != 0)
+ return PJMEDIA_EAUD_SYSERR;
+
+ /* Set a null error handler prior to enumeration to suppress errors */
+ snd_lib_error_set_handler(null_alsa_error_handler);
+
+ n = hints;
+ while (*n != NULL) {
+ char *name = snd_device_name_get_hint(*n, "NAME");
+ if (name != NULL && 0 != strcmp("null", name)) {
+ add_dev(af, name);
+ free(name);
+ }
+ n++;
+ }
+
+ /* Install error handler after enumeration, otherwise we'll get many
+ * error messages about invalid card/device ID.
+ */
+ snd_lib_error_set_handler(alsa_error_handler);
+
+ err = snd_device_name_free_hint((void**)hints);
+
+ PJ_LOG(4,(THIS_FILE, "ALSA driver found %d devices", af->dev_cnt));
+
+ return PJ_SUCCESS;
+}
+
+
/* API: get device count */
static unsigned alsa_factory_get_dev_count(pjmedia_aud_dev_factory *f)
{
diff --git a/pjmedia/src/pjmedia-audiodev/audiodev.c b/pjmedia/src/pjmedia-audiodev/audiodev.c
index 2a5a8e67..b9d960fe 100644
--- a/pjmedia/src/pjmedia-audiodev/audiodev.c
+++ b/pjmedia/src/pjmedia-audiodev/audiodev.c
@@ -491,6 +491,25 @@ PJ_DEF(pj_status_t) pjmedia_aud_subsys_shutdown(void)
return PJ_SUCCESS;
}
+/* API: Refresh the list of sound devices installed in the system. */
+PJ_DEF(pj_status_t) pjmedia_aud_dev_refresh(void)
+{
+ unsigned i;
+
+ for (i=0; i<aud_subsys.drv_cnt; ++i) {
+ struct driver *drv = &aud_subsys.drv[i];
+
+ if (drv->f && drv->f->op->refresh) {
+ pj_status_t status = drv->f->op->refresh(drv->f);
+ if (status != PJ_SUCCESS) {
+ PJ_PERROR(4, (THIS_FILE, status, "Unable to refresh device "
+ "list for %s", drv->name));
+ }
+ }
+ }
+ return PJ_SUCCESS;
+}
+
/* API: Get the number of sound devices installed in the system. */
PJ_DEF(unsigned) pjmedia_aud_dev_count(void)
{
diff --git a/pjmedia/src/pjmedia-audiodev/coreaudio_dev.c b/pjmedia/src/pjmedia-audiodev/coreaudio_dev.c
index 2cebbb34..de320488 100644
--- a/pjmedia/src/pjmedia-audiodev/coreaudio_dev.c
+++ b/pjmedia/src/pjmedia-audiodev/coreaudio_dev.c
@@ -178,7 +178,8 @@ static pjmedia_aud_dev_factory_op factory_op =
&ca_factory_get_dev_count,
&ca_factory_get_dev_info,
&ca_factory_default_param,
- &ca_factory_create_stream
+ &ca_factory_create_stream,
+ &ca_factory_refresh
};
static pjmedia_aud_stream_op stream_op =
diff --git a/pjmedia/src/pjmedia-audiodev/legacy_dev.c b/pjmedia/src/pjmedia-audiodev/legacy_dev.c
index 66fad9b0..a7680f1e 100644
--- a/pjmedia/src/pjmedia-audiodev/legacy_dev.c
+++ b/pjmedia/src/pjmedia-audiodev/legacy_dev.c
@@ -51,6 +51,7 @@ struct legacy_stream
/* Prototypes */
static pj_status_t factory_init(pjmedia_aud_dev_factory *f);
static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f);
+static pj_status_t factory_refresh(pjmedia_aud_dev_factory *f);
static unsigned factory_get_dev_count(pjmedia_aud_dev_factory *f);
static pj_status_t factory_get_dev_info(pjmedia_aud_dev_factory *f,
unsigned index,
@@ -86,7 +87,8 @@ static pjmedia_aud_dev_factory_op factory_op =
&factory_get_dev_count,
&factory_get_dev_info,
&factory_default_param,
- &factory_create_stream
+ &factory_create_stream,
+ &factory_refresh
};
static pjmedia_aud_stream_op stream_op =
@@ -147,6 +149,13 @@ static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f)
return status;
}
+/* API: refresh the list of devices */
+static pj_status_t factory_refresh(pjmedia_aud_dev_factory *f)
+{
+ PJ_UNUSED_ARG(f);
+ return PJ_ENOTSUP;
+}
+
/* API: get number of devices */
static unsigned factory_get_dev_count(pjmedia_aud_dev_factory *f)
{
diff --git a/pjmedia/src/pjmedia-audiodev/null_dev.c b/pjmedia/src/pjmedia-audiodev/null_dev.c
index feb96d22..44ce6412 100644
--- a/pjmedia/src/pjmedia-audiodev/null_dev.c
+++ b/pjmedia/src/pjmedia-audiodev/null_dev.c
@@ -59,6 +59,7 @@ struct null_audio_stream
/* Prototypes */
static pj_status_t null_factory_init(pjmedia_aud_dev_factory *f);
static pj_status_t null_factory_destroy(pjmedia_aud_dev_factory *f);
+static pj_status_t null_factory_refresh(pjmedia_aud_dev_factory *f);
static unsigned null_factory_get_dev_count(pjmedia_aud_dev_factory *f);
static pj_status_t null_factory_get_dev_info(pjmedia_aud_dev_factory *f,
unsigned index,
@@ -93,7 +94,8 @@ static pjmedia_aud_dev_factory_op factory_op =
&null_factory_get_dev_count,
&null_factory_get_dev_info,
&null_factory_default_param,
- &null_factory_create_stream
+ &null_factory_create_stream,
+ &null_factory_refresh
};
static pjmedia_aud_stream_op stream_op =
@@ -166,6 +168,13 @@ static pj_status_t null_factory_destroy(pjmedia_aud_dev_factory *f)
return PJ_SUCCESS;
}
+/* API: refresh the list of devices */
+static pj_status_t null_factory_refresh(pjmedia_aud_dev_factory *f)
+{
+ PJ_UNUSED_ARG(f);
+ return PJ_SUCCESS;
+}
+
/* API: get number of devices */
static unsigned null_factory_get_dev_count(pjmedia_aud_dev_factory *f)
{
diff --git a/pjmedia/src/pjmedia-audiodev/pa_dev.c b/pjmedia/src/pjmedia-audiodev/pa_dev.c
index 1188b8ab..fb33a6aa 100644
--- a/pjmedia/src/pjmedia-audiodev/pa_dev.c
+++ b/pjmedia/src/pjmedia-audiodev/pa_dev.c
@@ -106,6 +106,7 @@ struct pa_aud_stream
/* Factory prototypes */
static pj_status_t pa_init(pjmedia_aud_dev_factory *f);
static pj_status_t pa_destroy(pjmedia_aud_dev_factory *f);
+static pj_status_t pa_refresh(pjmedia_aud_dev_factory *f);
static unsigned pa_get_dev_count(pjmedia_aud_dev_factory *f);
static pj_status_t pa_get_dev_info(pjmedia_aud_dev_factory *f,
unsigned index,
@@ -141,7 +142,8 @@ static pjmedia_aud_dev_factory_op pa_op =
&pa_get_dev_count,
&pa_get_dev_info,
&pa_default_param,
- &pa_create_stream
+ &pa_create_stream,
+ &pa_refresh
};
static pjmedia_aud_stream_op pa_strm_op =
@@ -487,6 +489,14 @@ static pj_status_t pa_destroy(pjmedia_aud_dev_factory *f)
}
+/* API: Refresh the device list. */
+static pj_status_t pa_refresh(pjmedia_aud_dev_factory *f)
+{
+ PJ_UNUSED_ARG(f);
+ return PJ_ENOTSUP;
+}
+
+
/* API: Get device count. */
static unsigned pa_get_dev_count(pjmedia_aud_dev_factory *f)
{
diff --git a/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp b/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp
index 80ca7c51..aeb5cb3b 100644
--- a/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp
+++ b/pjmedia/src/pjmedia-audiodev/symb_aps_dev.cpp
@@ -120,6 +120,7 @@ struct aps_stream
/* Prototypes */
static pj_status_t factory_init(pjmedia_aud_dev_factory *f);
static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f);
+static pj_status_t factory_refresh(pjmedia_aud_dev_factory *f);
static unsigned factory_get_dev_count(pjmedia_aud_dev_factory *f);
static pj_status_t factory_get_dev_info(pjmedia_aud_dev_factory *f,
unsigned index,
@@ -155,7 +156,8 @@ static pjmedia_aud_dev_factory_op factory_op =
&factory_get_dev_count,
&factory_get_dev_info,
&factory_default_param,
- &factory_create_stream
+ &factory_create_stream,
+ &factory_refresh
};
static pjmedia_aud_stream_op stream_op =
@@ -1444,6 +1446,13 @@ static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f)
return PJ_SUCCESS;
}
+/* API: refresh the device list */
+static pj_status_t factory_refresh(pjmedia_aud_dev_factory *f)
+{
+ PJ_UNUSED_ARG(f);
+ return PJ_ENOTSUP;
+}
+
/* API: get number of devices */
static unsigned factory_get_dev_count(pjmedia_aud_dev_factory *f)
{
diff --git a/pjmedia/src/pjmedia-audiodev/symb_mda_dev.cpp b/pjmedia/src/pjmedia-audiodev/symb_mda_dev.cpp
index 2df93836..0c9d5e28 100644
--- a/pjmedia/src/pjmedia-audiodev/symb_mda_dev.cpp
+++ b/pjmedia/src/pjmedia-audiodev/symb_mda_dev.cpp
@@ -85,6 +85,7 @@ struct mda_stream
/* Prototypes */
static pj_status_t factory_init(pjmedia_aud_dev_factory *f);
static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f);
+static pj_status_t factory_refresh(pjmedia_aud_dev_factory *f);
static unsigned factory_get_dev_count(pjmedia_aud_dev_factory *f);
static pj_status_t factory_get_dev_info(pjmedia_aud_dev_factory *f,
unsigned index,
@@ -120,7 +121,8 @@ static pjmedia_aud_dev_factory_op factory_op =
&factory_get_dev_count,
&factory_get_dev_info,
&factory_default_param,
- &factory_create_stream
+ &factory_create_stream,
+ &factory_refresh
};
static pjmedia_aud_stream_op stream_op =
@@ -834,6 +836,13 @@ static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f)
return PJ_SUCCESS;
}
+/* API: refresh the device list */
+static pj_status_t factory_refresh(pjmedia_aud_dev_factory *f)
+{
+ PJ_UNUSED_ARG(f);
+ return PJ_ENOTSUP;
+}
+
/* API: get number of devices */
static unsigned factory_get_dev_count(pjmedia_aud_dev_factory *f)
{
diff --git a/pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp b/pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp
index 2f35a660..d58cef59 100644
--- a/pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp
+++ b/pjmedia/src/pjmedia-audiodev/symb_vas_dev.cpp
@@ -130,6 +130,7 @@ struct vas_stream
/* Prototypes */
static pj_status_t factory_init(pjmedia_aud_dev_factory *f);
static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f);
+static pj_status_t factory_refresh(pjmedia_aud_dev_factory *f);
static unsigned factory_get_dev_count(pjmedia_aud_dev_factory *f);
static pj_status_t factory_get_dev_info(pjmedia_aud_dev_factory *f,
unsigned index,
@@ -165,7 +166,8 @@ static pjmedia_aud_dev_factory_op factory_op =
&factory_get_dev_count,
&factory_get_dev_info,
&factory_default_param,
- &factory_create_stream
+ &factory_create_stream,
+ &factory_refresh
};
static pjmedia_aud_stream_op stream_op =
@@ -1476,6 +1478,13 @@ static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f)
return PJ_SUCCESS;
}
+/* API: refresh the device list */
+static pj_status_t factory_refresh(pjmedia_aud_dev_factory *f)
+{
+ PJ_UNUSED_ARG(f);
+ return PJ_ENOTSUP;
+}
+
/* API: get number of devices */
static unsigned factory_get_dev_count(pjmedia_aud_dev_factory *f)
{
diff --git a/pjmedia/src/pjmedia-audiodev/wmme_dev.c b/pjmedia/src/pjmedia-audiodev/wmme_dev.c
index 4a577c78..095aead9 100644
--- a/pjmedia/src/pjmedia-audiodev/wmme_dev.c
+++ b/pjmedia/src/pjmedia-audiodev/wmme_dev.c
@@ -38,6 +38,16 @@
# pragma warning(pop)
#endif
+#ifndef PJMEDIA_WMME_DEV_USE_MMDEVICE_API
+# define PJMEDIAWMME_DEV_USE_MMDEVICE_API \
+ (defined(_WIN32_WINNT) && (_WIN32_WINNT>=0x0600))
+#endif
+
+#if PJMEDIA_WMME_DEV_USE_MMDEVICE_API != 0
+# define DRV_QUERYFUNCTIONINSTANCEID (DRV_RESERVED + 17)
+# define DRV_QUERYFUNCTIONINSTANCEIDSIZE (DRV_RESERVED + 18)
+#endif
+
/* mingw lacks WAVE_FORMAT_ALAW/MULAW */
#ifndef WAVE_FORMAT_ALAW
# define WAVE_FORMAT_ALAW 0x0006
@@ -60,12 +70,14 @@ struct wmme_dev_info
{
pjmedia_aud_dev_info info;
unsigned deviceId;
+ const wchar_t *endpointId;
};
/* WMME factory */
struct wmme_factory
{
pjmedia_aud_dev_factory base;
+ pj_pool_t *base_pool;
pj_pool_t *pool;
pj_pool_factory *pf;
@@ -121,6 +133,7 @@ struct wmme_stream
/* Prototypes */
static pj_status_t factory_init(pjmedia_aud_dev_factory *f);
static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f);
+static pj_status_t factory_refresh(pjmedia_aud_dev_factory *f);
static unsigned factory_get_dev_count(pjmedia_aud_dev_factory *f);
static pj_status_t factory_get_dev_info(pjmedia_aud_dev_factory *f,
unsigned index,
@@ -156,7 +169,8 @@ static pjmedia_aud_dev_factory_op factory_op =
&factory_get_dev_count,
&factory_get_dev_info,
&factory_default_param,
- &factory_create_stream
+ &factory_create_stream,
+ &factory_refresh
};
static pjmedia_aud_stream_op stream_op =
@@ -181,15 +195,123 @@ pjmedia_aud_dev_factory* pjmedia_wmme_factory(pj_pool_factory *pf)
struct wmme_factory *f;
pj_pool_t *pool;
- pool = pj_pool_create(pf, "WMME", 1000, 1000, NULL);
+ pool = pj_pool_create(pf, "WMME base", 1000, 1000, NULL);
f = PJ_POOL_ZALLOC_T(pool, struct wmme_factory);
f->pf = pf;
- f->pool = pool;
+ f->base_pool = pool;
f->base.op = &factory_op;
return &f->base;
}
+/* Internal: Windows Vista and Windows 7 have their device
+ * names truncated when using the waveXXX api. The names
+ * should be acquired from the MMDevice APIs
+ */
+#if PJMEDIA_WMME_DEV_USE_MMDEVICE_API != 0
+
+#define COBJMACROS
+#include <mmdeviceapi.h>
+#define INITGUID
+#include <Guiddef.h>
+#include <FunctionDiscoveryKeys_devpkey.h>
+
+DEFINE_GUID(CLSID_MMDeviceEnumerator, 0xBCDE0395, 0xE52F, 0x467C,
+ 0x8E, 0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E);
+DEFINE_GUID(IID_IMMDeviceEnumerator, 0xA95664D2, 0x9614, 0x4F35,
+ 0xA7, 0x46, 0xDE, 0x8D, 0xB6, 0x36, 0x17, 0xE6);
+
+static void get_dev_names(pjmedia_aud_dev_factory *f)
+{
+ struct wmme_factory *wf = (struct wmme_factory*)f;
+ HRESULT coinit = S_OK;
+ HRESULT hr = S_OK;
+ IMMDeviceEnumerator *pEnumerator = NULL;
+ IMMDeviceCollection *pDevices = NULL;
+ UINT cDevices = 0;
+ UINT nDevice = 0;
+
+ coinit = CoInitializeEx(NULL, COINIT_MULTITHREADED);
+ if (coinit == RPC_E_CHANGED_MODE)
+ coinit = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ if (FAILED(coinit))
+ goto on_error;
+
+ hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL,
+ CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator,
+ (void**)&pEnumerator);
+ if (FAILED(hr))
+ goto on_error;
+ hr = IMMDeviceEnumerator_EnumAudioEndpoints(pEnumerator, eAll,
+ DEVICE_STATE_ACTIVE,
+ &pDevices);
+ if (FAILED(hr))
+ goto on_error;
+ hr = IMMDeviceCollection_GetCount(pDevices, &cDevices);
+ if (FAILED(hr))
+ goto on_error;
+
+ for (nDevice = 0; nDevice < cDevices; ++nDevice) {
+ IMMDevice *pDevice = NULL;
+ IPropertyStore *pProps = NULL;
+ LPWSTR pwszID = NULL;
+ PROPVARIANT varName;
+ unsigned i;
+
+ PropVariantInit(&varName);
+
+ hr = IMMDeviceCollection_Item(pDevices, nDevice, &pDevice);
+ if (FAILED(hr))
+ goto cleanup;
+ hr = IMMDevice_GetId(pDevice, &pwszID);
+ if (FAILED(hr))
+ goto cleanup;
+ hr = IMMDevice_OpenPropertyStore(pDevice, STGM_READ, &pProps);
+ if (FAILED(hr))
+ goto cleanup;
+ hr = IPropertyStore_GetValue(pProps, &PKEY_Device_FriendlyName,
+ &varName);
+ if (FAILED(hr))
+ goto cleanup;
+
+ for (i = 0; i < wf->dev_count; ++i) {
+ if (0 == wcscmp(wf->dev_info[i].endpointId, pwszID)) {
+ wcstombs(wf->dev_info[i].info.name, varName.pwszVal,
+ sizeof(wf->dev_info[i].info.name));
+ break;
+ }
+ }
+
+ PropVariantClear(&varName);
+
+ cleanup:
+ if (pProps)
+ IPropertyStore_Release(pProps);
+ if (pwszID)
+ CoTaskMemFree(pwszID);
+ if (pDevice)
+ hr = IMMDevice_Release(pDevice);
+ }
+
+on_error:
+ if (pDevices)
+ hr = IMMDeviceCollection_Release(pDevices);
+
+ if (pEnumerator)
+ hr = IMMDeviceEnumerator_Release(pEnumerator);
+
+ if (SUCCEEDED(coinit))
+ CoUninitialize();
+}
+
+#else
+
+static void get_dev_names(pjmedia_aud_dev_factory *f)
+{
+ PJ_UNUSED_ARG(f);
+}
+
+#endif
/* Internal: build device info from WAVEINCAPS/WAVEOUTCAPS */
static void build_dev_info(UINT deviceId, struct wmme_dev_info *wdi,
@@ -261,14 +383,31 @@ static void build_dev_info(UINT deviceId, struct wmme_dev_info *wdi,
/* API: init factory */
static pj_status_t factory_init(pjmedia_aud_dev_factory *f)
{
+ pj_status_t ret = factory_refresh(f);
+ if (ret != PJ_SUCCESS)
+ return ret;
+
+ PJ_LOG(4, (THIS_FILE, "WMME initialized"));
+ return PJ_SUCCESS;
+}
+
+/* API: refresh the device list */
+static pj_status_t factory_refresh(pjmedia_aud_dev_factory *f)
+{
struct wmme_factory *wf = (struct wmme_factory*)f;
unsigned c;
int i;
int inputDeviceCount, outputDeviceCount, devCount=0;
pj_bool_t waveMapperAdded = PJ_FALSE;
+ if (wf->pool != NULL) {
+ pj_pool_release(wf->pool);
+ wf->pool = NULL;
+ }
+
/* Enumerate sound devices */
wf->dev_count = 0;
+ wf->pool = pj_pool_create(wf->pf, "WMME", 1000, 1000, NULL);
inputDeviceCount = waveInGetNumDevs();
devCount += inputDeviceCount;
@@ -314,6 +453,7 @@ static pj_status_t factory_init(pjmedia_aud_dev_factory *f)
if (mr == MMSYSERR_NOERROR) {
build_dev_info(WAVE_MAPPER, &wf->dev_info[wf->dev_count],
&wic, &woc);
+ wf->dev_info[wf->dev_count].endpointId = L"";
++wf->dev_count;
waveMapperAdded = PJ_TRUE;
}
@@ -327,6 +467,7 @@ static pj_status_t factory_init(pjmedia_aud_dev_factory *f)
UINT uDeviceID = (UINT)((i==-1) ? WAVE_MAPPER : i);
WAVEINCAPS wic;
MMRESULT mr;
+ DWORD cbEndpointId;
pj_bzero(&wic, sizeof(WAVEINCAPS));
@@ -340,6 +481,27 @@ static pj_status_t factory_init(pjmedia_aud_dev_factory *f)
build_dev_info(uDeviceID, &wf->dev_info[wf->dev_count],
&wic, NULL);
+
+#if PJMEDIA_WMME_DEV_USE_MMDEVICE_API != 0
+ /* Try to get the endpoint id of the audio device */
+ wf->dev_info[wf->dev_count].endpointId = L"";
+
+ mr = waveInMessage((HWAVEIN)IntToPtr(uDeviceID),
+ DRV_QUERYFUNCTIONINSTANCEIDSIZE,
+ (DWORD_PTR)&cbEndpointId, (DWORD_PTR)NULL);
+ if (mr == MMSYSERR_NOERROR) {
+ const wchar_t **epid = &wf->dev_info[wf->dev_count].endpointId;
+ *epid = (const wchar_t*) pj_pool_calloc(wf->pool,
+ cbEndpointId, 1);
+ mr = waveInMessage((HWAVEIN)IntToPtr(uDeviceID),
+ DRV_QUERYFUNCTIONINSTANCEID,
+ (DWORD_PTR)*epid,
+ cbEndpointId);
+ }
+#else
+ PJ_UNUSED_ARG(cbEndpointId);
+#endif
+
++wf->dev_count;
}
}
@@ -351,6 +513,7 @@ static pj_status_t factory_init(pjmedia_aud_dev_factory *f)
UINT uDeviceID = (UINT)((i==-1) ? WAVE_MAPPER : i);
WAVEOUTCAPS woc;
MMRESULT mr;
+ DWORD cbEndpointId;
pj_bzero(&woc, sizeof(WAVEOUTCAPS));
@@ -364,11 +527,34 @@ static pj_status_t factory_init(pjmedia_aud_dev_factory *f)
build_dev_info(uDeviceID, &wf->dev_info[wf->dev_count],
NULL, &woc);
+
+#if PJMEDIA_WMME_DEV_USE_MMDEVICE_API != 0
+ /* Try to get the endpoint id of the audio device */
+ wf->dev_info[wf->dev_count].endpointId = L"";
+
+ mr = waveOutMessage((HWAVEOUT)IntToPtr(uDeviceID),
+ DRV_QUERYFUNCTIONINSTANCEIDSIZE,
+ (DWORD_PTR)&cbEndpointId, (DWORD_PTR)NULL);
+ if (mr == MMSYSERR_NOERROR) {
+ const wchar_t **epid = &wf->dev_info[wf->dev_count].endpointId;
+ *epid = (const wchar_t*)pj_pool_calloc(wf->pool,
+ cbEndpointId, 1);
+ mr = waveOutMessage((HWAVEOUT)IntToPtr(uDeviceID),
+ DRV_QUERYFUNCTIONINSTANCEID,
+ (DWORD_PTR)*epid, cbEndpointId);
+ }
+#else
+ PJ_UNUSED_ARG(cbEndpointId);
+#endif
+
++wf->dev_count;
}
}
- PJ_LOG(4, (THIS_FILE, "WMME initialized, found %d devices:",
+ /* On Windows Vista and Windows 7 get the full device names */
+ get_dev_names(f);
+
+ PJ_LOG(4, (THIS_FILE, "WMME found %d devices:",
wf->dev_count));
for (c = 0; c < wf->dev_count; ++c) {
PJ_LOG(4, (THIS_FILE, " dev_id %d: %s (in=%d, out=%d)",
@@ -385,9 +571,10 @@ static pj_status_t factory_init(pjmedia_aud_dev_factory *f)
static pj_status_t factory_destroy(pjmedia_aud_dev_factory *f)
{
struct wmme_factory *wf = (struct wmme_factory*)f;
- pj_pool_t *pool = wf->pool;
+ pj_pool_t *pool = wf->base_pool;
- wf->pool = NULL;
+ pj_pool_release(wf->pool);
+ wf->base_pool = NULL;
pj_pool_release(pool);
return PJ_SUCCESS;
diff --git a/pjmedia/src/pjmedia/sound_port.c b/pjmedia/src/pjmedia/sound_port.c
index 1029fc3d..7720b630 100644
--- a/pjmedia/src/pjmedia/sound_port.c
+++ b/pjmedia/src/pjmedia/sound_port.c
@@ -48,6 +48,7 @@ struct pjmedia_snd_port
unsigned channel_count;
unsigned samples_per_frame;
unsigned bits_per_sample;
+ unsigned options;
/* software ec */
pjmedia_echo_state *ec_state;
@@ -277,7 +278,9 @@ static pj_status_t start_sound_device( pj_pool_t *pool,
}
/* Start sound stream. */
- status = pjmedia_aud_stream_start(snd_port->aud_stream);
+ if (!(snd_port->options & PJMEDIA_SND_PORT_NO_AUTO_START)) {
+ status = pjmedia_aud_stream_start(snd_port->aud_stream);
+ }
if (status != PJ_SUCCESS) {
pjmedia_aud_stream_destroy(snd_port->aud_stream);
snd_port->aud_stream = NULL;
@@ -324,22 +327,23 @@ PJ_DEF(pj_status_t) pjmedia_snd_port_create( pj_pool_t *pool,
unsigned options,
pjmedia_snd_port **p_port)
{
- pjmedia_aud_param param;
+ pjmedia_snd_port_param param;
pj_status_t status;
PJ_UNUSED_ARG(options);
- status = pjmedia_aud_dev_default_param(rec_id, &param);
+ status = pjmedia_aud_dev_default_param(rec_id, &param.base);
if (status != PJ_SUCCESS)
return status;
- param.dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
- param.rec_id = rec_id;
- param.play_id = play_id;
- param.clock_rate = clock_rate;
- param.channel_count = channel_count;
- param.samples_per_frame = samples_per_frame;
- param.bits_per_sample = bits_per_sample;
+ param.base.dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
+ param.base.rec_id = rec_id;
+ param.base.play_id = play_id;
+ param.base.clock_rate = clock_rate;
+ param.base.channel_count = channel_count;
+ param.base.samples_per_frame = samples_per_frame;
+ param.base.bits_per_sample = bits_per_sample;
+ param.options = options;
return pjmedia_snd_port_create2(pool, &param, p_port);
}
@@ -356,21 +360,22 @@ PJ_DEF(pj_status_t) pjmedia_snd_port_create_rec( pj_pool_t *pool,
unsigned options,
pjmedia_snd_port **p_port)
{
- pjmedia_aud_param param;
+ pjmedia_snd_port_param param;
pj_status_t status;
PJ_UNUSED_ARG(options);
- status = pjmedia_aud_dev_default_param(dev_id, &param);
+ status = pjmedia_aud_dev_default_param(dev_id, &param.base);
if (status != PJ_SUCCESS)
return status;
- param.dir = PJMEDIA_DIR_CAPTURE;
- param.rec_id = dev_id;
- param.clock_rate = clock_rate;
- param.channel_count = channel_count;
- param.samples_per_frame = samples_per_frame;
- param.bits_per_sample = bits_per_sample;
+ param.base.dir = PJMEDIA_DIR_CAPTURE;
+ param.base.rec_id = dev_id;
+ param.base.clock_rate = clock_rate;
+ param.base.channel_count = channel_count;
+ param.base.samples_per_frame = samples_per_frame;
+ param.base.bits_per_sample = bits_per_sample;
+ param.options = options;
return pjmedia_snd_port_create2(pool, &param, p_port);
}
@@ -388,21 +393,22 @@ PJ_DEF(pj_status_t) pjmedia_snd_port_create_player( pj_pool_t *pool,
unsigned options,
pjmedia_snd_port **p_port)
{
- pjmedia_aud_param param;
+ pjmedia_snd_port_param param;
pj_status_t status;
PJ_UNUSED_ARG(options);
- status = pjmedia_aud_dev_default_param(dev_id, &param);
+ status = pjmedia_aud_dev_default_param(dev_id, &param.base);
if (status != PJ_SUCCESS)
return status;
- param.dir = PJMEDIA_DIR_PLAYBACK;
- param.play_id = dev_id;
- param.clock_rate = clock_rate;
- param.channel_count = channel_count;
- param.samples_per_frame = samples_per_frame;
- param.bits_per_sample = bits_per_sample;
+ param.base.dir = PJMEDIA_DIR_PLAYBACK;
+ param.base.play_id = dev_id;
+ param.base.clock_rate = clock_rate;
+ param.base.channel_count = channel_count;
+ param.base.samples_per_frame = samples_per_frame;
+ param.base.bits_per_sample = bits_per_sample;
+ param.options = options;
return pjmedia_snd_port_create2(pool, &param, p_port);
}
@@ -412,7 +418,7 @@ PJ_DEF(pj_status_t) pjmedia_snd_port_create_player( pj_pool_t *pool,
* Create sound port.
*/
PJ_DEF(pj_status_t) pjmedia_snd_port_create2(pj_pool_t *pool,
- const pjmedia_aud_param *prm,
+ const pjmedia_snd_port_param *prm,
pjmedia_snd_port **p_port)
{
pjmedia_snd_port *snd_port;
@@ -423,15 +429,16 @@ PJ_DEF(pj_status_t) pjmedia_snd_port_create2(pj_pool_t *pool,
snd_port = PJ_POOL_ZALLOC_T(pool, pjmedia_snd_port);
PJ_ASSERT_RETURN(snd_port, PJ_ENOMEM);
- snd_port->dir = prm->dir;
- snd_port->rec_id = prm->rec_id;
- snd_port->play_id = prm->play_id;
+ snd_port->dir = prm->base.dir;
+ snd_port->rec_id = prm->base.rec_id;
+ snd_port->play_id = prm->base.play_id;
snd_port->dir = PJMEDIA_DIR_CAPTURE_PLAYBACK;
- snd_port->clock_rate = prm->clock_rate;
- snd_port->channel_count = prm->channel_count;
- snd_port->samples_per_frame = prm->samples_per_frame;
- snd_port->bits_per_sample = prm->bits_per_sample;
- pj_memcpy(&snd_port->aud_param, prm, sizeof(*prm));
+ snd_port->clock_rate = prm->base.clock_rate;
+ snd_port->channel_count = prm->base.channel_count;
+ snd_port->samples_per_frame = prm->base.samples_per_frame;
+ snd_port->bits_per_sample = prm->base.bits_per_sample;
+ pj_memcpy(&snd_port->aud_param, prm, sizeof(snd_port->aud_param));
+ snd_port->options = prm->options;
/* Start sound device immediately.
* If there's no port connected, the sound callback will return
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c
index 47cf1e7d..b15537b8 100644
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -36,7 +36,7 @@
static pj_uint16_t next_rtp_port;
/* Open sound dev */
-static pj_status_t open_snd_dev(pjmedia_aud_param *param);
+static pj_status_t open_snd_dev(pjmedia_snd_port_param *param);
/* Close existing sound device */
static void close_snd_dev(void);
/* Create audio device param */
@@ -1975,10 +1975,10 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source,
if (need_reopen) {
if (pjsua_var.cap_dev != NULL_SND_DEV_ID) {
- pjmedia_aud_param param;
+ pjmedia_snd_port_param param;
/* Create parameter based on peer info */
- status = create_aud_param(&param, pjsua_var.cap_dev,
+ status = create_aud_param(&param.base, pjsua_var.cap_dev,
pjsua_var.play_dev,
peer_info.clock_rate,
peer_info.channel_count,
@@ -1991,10 +1991,11 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source,
/* And peer format */
if (peer_info.format.id != PJMEDIA_FORMAT_PCM) {
- param.flags |= PJMEDIA_AUD_DEV_CAP_EXT_FORMAT;
- param.ext_fmt = peer_info.format;
+ param.base.flags |= PJMEDIA_AUD_DEV_CAP_EXT_FORMAT;
+ param.base.ext_fmt = peer_info.format;
}
+ param.options = 0;
status = open_snd_dev(&param);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Error opening sound device", status);
@@ -2665,7 +2666,7 @@ static const char *get_fmt_name(pj_uint32_t id)
}
/* Open sound device with the setting. */
-static pj_status_t open_snd_dev(pjmedia_aud_param *param)
+static pj_status_t open_snd_dev(pjmedia_snd_port_param *param)
{
pjmedia_port *conf_port;
pj_status_t status;
@@ -2673,7 +2674,9 @@ static pj_status_t open_snd_dev(pjmedia_aud_param *param)
PJ_ASSERT_RETURN(param, PJ_EINVAL);
/* Check if NULL sound device is used */
- if (NULL_SND_DEV_ID==param->rec_id || NULL_SND_DEV_ID==param->play_id) {
+ if (NULL_SND_DEV_ID==param->base.rec_id ||
+ NULL_SND_DEV_ID==param->base.play_id)
+ {
return pjsua_set_null_snd_dev();
}
@@ -2686,13 +2689,13 @@ static pj_status_t open_snd_dev(pjmedia_aud_param *param)
PJ_LOG(4,(THIS_FILE, "Opening sound device %s@%d/%d/%dms",
- get_fmt_name(param->ext_fmt.id),
- param->clock_rate, param->channel_count,
- param->samples_per_frame / param->channel_count * 1000 /
- param->clock_rate));
+ get_fmt_name(param->base.ext_fmt.id),
+ param->base.clock_rate, param->base.channel_count,
+ param->base.samples_per_frame / param->base.channel_count *
+ 1000 / param->base.clock_rate));
status = pjmedia_snd_port_create2( pjsua_var.snd_pool,
- param, &pjsua_var.snd_port);
+ param, &pjsua_var.snd_port);
if (status != PJ_SUCCESS)
return status;
@@ -2704,8 +2707,8 @@ static pj_status_t open_snd_dev(pjmedia_aud_param *param)
* clock rate is different than the sound device's clock rate.
*/
if (!pjsua_var.is_mswitch &&
- param->ext_fmt.id == PJMEDIA_FORMAT_PCM &&
- conf_port->info.clock_rate != param->clock_rate)
+ param->base.ext_fmt.id == PJMEDIA_FORMAT_PCM &&
+ conf_port->info.clock_rate != param->base.clock_rate)
{
pjmedia_port *resample_port;
unsigned resample_opt = 0;
@@ -2721,7 +2724,7 @@ static pj_status_t open_snd_dev(pjmedia_aud_param *param)
status = pjmedia_resample_port_create(pjsua_var.snd_pool,
conf_port,
- param->clock_rate,
+ param->base.clock_rate,
resample_opt,
&resample_port);
if (status != PJ_SUCCESS) {
@@ -2741,11 +2744,11 @@ static pj_status_t open_snd_dev(pjmedia_aud_param *param)
* derived from the sound device setting, so update the setting.
*/
if (pjsua_var.is_mswitch) {
- pj_memcpy(&conf_port->info.format, &param->ext_fmt,
+ pj_memcpy(&conf_port->info.format, &param->base.ext_fmt,
sizeof(conf_port->info.format));
- conf_port->info.clock_rate = param->clock_rate;
- conf_port->info.samples_per_frame = param->samples_per_frame;
- conf_port->info.channel_count = param->channel_count;
+ conf_port->info.clock_rate = param->base.clock_rate;
+ conf_port->info.samples_per_frame = param->base.samples_per_frame;
+ conf_port->info.channel_count = param->base.channel_count;
conf_port->info.bits_per_sample = 16;
}
@@ -2761,8 +2764,8 @@ static pj_status_t open_snd_dev(pjmedia_aud_param *param)
}
/* Save the device IDs */
- pjsua_var.cap_dev = param->rec_id;
- pjsua_var.play_dev = param->play_id;
+ pjsua_var.cap_dev = param->base.rec_id;
+ pjsua_var.play_dev = param->base.play_id;
/* Update sound device name. */
{
@@ -2777,14 +2780,14 @@ static pj_status_t open_snd_dev(pjmedia_aud_param *param)
status = pjmedia_aud_dev_get_info(si.rec_id, &rec_info);
if (status==PJ_SUCCESS) {
- if (param->clock_rate != pjsua_var.media_cfg.clock_rate) {
+ if (param->base.clock_rate != pjsua_var.media_cfg.clock_rate) {
char tmp_buf[128];
int tmp_buf_len = sizeof(tmp_buf);
tmp_buf_len = pj_ansi_snprintf(tmp_buf, sizeof(tmp_buf)-1,
"%s (%dKHz)",
rec_info.name,
- param->clock_rate/1000);
+ param->base.clock_rate/1000);
pj_strset(&tmp, tmp_buf, tmp_buf_len);
pjmedia_conf_set_port0_name(pjsua_var.mconf, &tmp);
} else {
@@ -2883,20 +2886,21 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev,
/* Attempts to open the sound device with different clock rates */
for (i=0; i<alt_cr_cnt; ++i) {
- pjmedia_aud_param param;
+ pjmedia_snd_port_param param;
unsigned samples_per_frame;
/* Create the default audio param */
samples_per_frame = alt_cr[i] *
pjsua_var.media_cfg.audio_frame_ptime *
pjsua_var.media_cfg.channel_count / 1000;
- status = create_aud_param(&param, capture_dev, playback_dev,
+ status = create_aud_param(&param.base, capture_dev, playback_dev,
alt_cr[i], pjsua_var.media_cfg.channel_count,
samples_per_frame, 16);
if (status != PJ_SUCCESS)
return status;
/* Open! */
+ param.options = 0;
status = open_snd_dev(&param);
if (status == PJ_SUCCESS)
break;