summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRiza Sulistyo <riza@teluu.com>2016-04-04 01:44:10 +0000
committerRiza Sulistyo <riza@teluu.com>2016-04-04 01:44:10 +0000
commitfbbfd915b0225c657920a6696f460a687f28cc6b (patch)
tree3e8a5bce9748861c1d81f045aae0bb5a2154f44b
parent98de8381dbe5c50477e03d7571d53a836b4500fa (diff)
Re #1908: Implement new API to open speaker only in pjsua/pjsua2.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@5273 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjsip-apps/src/swig/symbols.i2
-rw-r--r--pjsip-apps/src/swig/symbols.lst2
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h65
-rw-r--r--pjsip/include/pjsua-lib/pjsua_internal.h1
-rw-r--r--pjsip/include/pjsua2/media.hpp17
-rw-r--r--pjsip/src/pjsua-lib/pjsua_aud.c79
-rw-r--r--pjsip/src/pjsua2/media.cpp37
7 files changed, 184 insertions, 19 deletions
diff --git a/pjsip-apps/src/swig/symbols.i b/pjsip-apps/src/swig/symbols.i
index 4b4e53fe..feb4f18b 100644
--- a/pjsip-apps/src/swig/symbols.i
+++ b/pjsip-apps/src/swig/symbols.i
@@ -165,3 +165,5 @@ typedef enum pjsua_call_flag {PJSUA_CALL_UNHOLD = 1, PJSUA_CALL_UPDATE_CONTACT =
typedef enum pjsua_create_media_transport_flag {PJSUA_MED_TP_CLOSE_MEMBER = 1} pjsua_create_media_transport_flag;
+typedef enum pjsua_snd_dev_mode {PJSUA_SND_DEV_SPEAKER_ONLY = 1, PJSUA_SND_DEV_NO_IMMEDIATE_OPEN = 2} pjsua_snd_dev_mode;
+
diff --git a/pjsip-apps/src/swig/symbols.lst b/pjsip-apps/src/swig/symbols.lst
index 35ba8b02..62b0e1ff 100644
--- a/pjsip-apps/src/swig/symbols.lst
+++ b/pjsip-apps/src/swig/symbols.lst
@@ -33,4 +33,4 @@ pjsip-simple/evsub.h pjsip_evsub_state
pjsip-ua/sip_inv.h pjsip_inv_state
-pjsua-lib/pjsua.h pjsua_invalid_id_const_ pjsua_state pjsua_stun_use pjsua_call_hold_type pjsua_acc_id pjsua_destroy_flag pjsua_100rel_use pjsua_sip_timer_use pjsua_ipv6_use pjsua_buddy_status pjsua_call_media_status pjsua_vid_win_id pjsua_call_id pjsua_med_tp_st pjsua_call_vid_strm_op pjsua_vid_req_keyframe_method pjsua_call_flag pjsua_create_media_transport_flag
+pjsua-lib/pjsua.h pjsua_invalid_id_const_ pjsua_state pjsua_stun_use pjsua_call_hold_type pjsua_acc_id pjsua_destroy_flag pjsua_100rel_use pjsua_sip_timer_use pjsua_ipv6_use pjsua_buddy_status pjsua_call_media_status pjsua_vid_win_id pjsua_call_id pjsua_med_tp_st pjsua_call_vid_strm_op pjsua_vid_req_keyframe_method pjsua_call_flag pjsua_create_media_transport_flag pjsua_snd_dev_mode
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index 6b6b5569..4887a97e 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -5997,6 +5997,62 @@ typedef struct pjsua_media_transport
} pjsua_media_transport;
+/**
+ * This enumeration specifies the sound device mode.
+ */
+typedef enum pjsua_snd_dev_mode
+{
+ /**
+ * Open sound device without mic (speaker only).
+ */
+ PJSUA_SND_DEV_SPEAKER_ONLY = 1,
+
+ /**
+ * Do not open sound device, after setting the sound device.
+ */
+ PJSUA_SND_DEV_NO_IMMEDIATE_OPEN = 2
+
+} pjsua_snd_dev_mode;
+
+
+/**
+ * This structure specifies the parameters to set the sound device.
+ * Use pjsua_snd_dev_param_default() to initialize this structure with
+ * default values.
+ */
+typedef struct pjsua_snd_dev_param
+{
+ /*
+ * Capture dev id.
+ *
+ * Default: PJMEDIA_AUD_DEFAULT_CAPTURE_DEV
+ */
+ int capture_dev;
+
+ /*
+ * Playback dev id.
+ *
+ * Default: PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV
+ */
+ int playback_dev;
+
+ /*
+ * Sound device mode, refer to #pjsua_snd_dev_mode.
+ *
+ * Default: 0
+ */
+ unsigned mode;
+
+} pjsua_snd_dev_param;
+
+
+/**
+ * Initialize pjsua_snd_dev_param with default values.
+ *
+ * @param prm The parameter.
+ */
+PJ_DECL(void) pjsua_snd_dev_param_default(pjsua_snd_dev_param *prm);
+
/**
* Get maxinum number of conference ports.
@@ -6384,6 +6440,15 @@ PJ_DECL(pj_status_t) pjsua_get_snd_dev(int *capture_dev,
PJ_DECL(pj_status_t) pjsua_set_snd_dev(int capture_dev,
int playback_dev);
+/**
+ * Select or change sound device according to the specified param.
+ *
+ * @param snd_param Sound device param.
+ *
+ * @return PJ_SUCCESS on success, or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pjsua_set_snd_dev2(pjsua_snd_dev_param *snd_param);
+
/**
* Set pjsua to use null sound device. The null sound device only provides
diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h
index dc98cc6f..e1fad139 100644
--- a/pjsip/include/pjsua-lib/pjsua_internal.h
+++ b/pjsip/include/pjsua-lib/pjsua_internal.h
@@ -478,6 +478,7 @@ struct pjsua_data
pjmedia_master_port *null_snd; /**< Master port for null sound. */
pjmedia_port *null_port; /**< Null port. */
pj_bool_t snd_is_on; /**< Media flow is currently active */
+ unsigned snd_mode; /**< Sound device mode. */
/* Video device */
pjmedia_vid_dev_index vcap_dev; /**< Capture device ID. */
diff --git a/pjsip/include/pjsua2/media.hpp b/pjsip/include/pjsua2/media.hpp
index e642d171..4e42c574 100644
--- a/pjsip/include/pjsua2/media.hpp
+++ b/pjsip/include/pjsua2/media.hpp
@@ -767,7 +767,9 @@ public:
/**
* Select or change capture sound device. Application may call this
- * function at any time to replace current sound device.
+ * function at any time to replace current sound device. Calling this
+ * method will not change the state of the sound device (opened/closed).
+ * Note that this method will override the mode set by setSndDevMode().
*
* @param capture_dev Device ID of the capture device.
*/
@@ -775,7 +777,9 @@ public:
/**
* Select or change playback sound device. Application may call this
- * function at any time to replace current sound device.
+ * function at any time to replace current sound device. Calling this
+ * method will not change the state of the sound device (opened/closed).
+ * Note that this method will override the mode set by setSndDevMode().
*
* @param playback_dev Device ID of the playback device.
*/
@@ -807,6 +811,15 @@ public:
MediaPort *setNoDev();
/**
+ * Set sound device mode.
+ *
+ * @param mode The sound device mode, as bitmask combination
+ * of #pjsua_snd_dev_mode
+ *
+ */
+ void setSndDevMode(unsigned mode) const throw(Error);
+
+ /**
* Change the echo cancellation settings.
*
* The behavior of this function depends on whether the sound device is
diff --git a/pjsip/src/pjsua-lib/pjsua_aud.c b/pjsip/src/pjsua-lib/pjsua_aud.c
index 9fc3e533..5ca1b346 100644
--- a/pjsip/src/pjsua-lib/pjsua_aud.c
+++ b/pjsip/src/pjsua-lib/pjsua_aud.c
@@ -687,6 +687,12 @@ on_return:
return status;
}
+PJ_DEF(void) pjsua_snd_dev_param_default(pjsua_snd_dev_param *prm)
+{
+ pj_bzero(prm, sizeof(*prm));
+ prm->capture_dev = PJMEDIA_AUD_DEFAULT_CAPTURE_DEV;
+ prm->playback_dev = PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV;
+}
/*
* Get maxinum number of conference ports.
@@ -1696,6 +1702,7 @@ static pj_status_t open_snd_dev(pjmedia_snd_port_param *param)
{
pjmedia_port *conf_port;
pj_status_t status;
+ pj_bool_t speaker_only = (pjsua_var.snd_mode & PJSUA_SND_DEV_SPEAKER_ONLY);
PJ_ASSERT_RETURN(param, PJ_EINVAL);
@@ -1724,15 +1731,29 @@ static pj_status_t open_snd_dev(pjmedia_snd_port_param *param)
if (pjsua_var.media_cfg.on_aud_prev_rec_frame)
param->on_rec_frame = &on_aud_prev_rec_frame;
- PJ_LOG(4,(THIS_FILE, "Opening sound device %s@%d/%d/%dms",
+ PJ_LOG(4,(THIS_FILE, "Opening sound device (%s) %s@%d/%d/%dms",
+ speaker_only?"speaker only":"speaker + mic",
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));
pj_log_push_indent();
- status = pjmedia_snd_port_create2( pjsua_var.snd_pool,
- param, &pjsua_var.snd_port);
+ if (speaker_only) {
+ status = pjmedia_snd_port_create_player(pjsua_var.snd_pool,
+ -1,
+ param->base.clock_rate,
+ param->base.channel_count,
+ param->base.samples_per_frame,
+ param->base.bits_per_sample,
+ 0,
+ &pjsua_var.snd_port);
+
+ } else {
+ status = pjmedia_snd_port_create2(pjsua_var.snd_pool,
+ param, &pjsua_var.snd_port);
+ }
+
if (status != PJ_SUCCESS)
goto on_error;
@@ -1920,27 +1941,46 @@ static void close_snd_dev(void)
}
+PJ_DEF(pj_status_t) pjsua_set_snd_dev(int capture_dev,
+ int playback_dev)
+{
+ pjsua_snd_dev_param param;
+
+ pjsua_snd_dev_param_default(&param);
+
+ param.capture_dev = capture_dev;
+ param.playback_dev = playback_dev;
+ /* Always open the sound device. */
+ param.mode = 0;
+
+ return pjsua_set_snd_dev2(&param);
+}
+
/*
* Select or change sound device. Application may call this function at
* any time to replace current sound device.
*/
-PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev,
- int playback_dev)
+PJ_DEF(pj_status_t) pjsua_set_snd_dev2(pjsua_snd_dev_param *snd_param)
{
unsigned alt_cr_cnt = 1;
unsigned alt_cr[] = {0, 44100, 48000, 32000, 16000, 8000};
unsigned i;
pj_status_t status = -1;
+ unsigned orig_snd_dev_mode = pjsua_var.snd_mode;
+ pj_bool_t no_change = (pjsua_var.snd_is_on || (!pjsua_var.snd_is_on &&
+ (snd_param->mode &
+ PJSUA_SND_DEV_NO_IMMEDIATE_OPEN)));
PJ_LOG(4,(THIS_FILE, "Set sound device: capture=%d, playback=%d",
- capture_dev, playback_dev));
+ snd_param->capture_dev, snd_param->playback_dev));
pj_log_push_indent();
PJSUA_LOCK();
- if (pjsua_var.cap_dev == capture_dev &&
- pjsua_var.play_dev == playback_dev &&
- pjsua_var.snd_is_on && !pjsua_var.no_snd)
+ if (pjsua_var.cap_dev == snd_param->capture_dev &&
+ pjsua_var.play_dev == snd_param->playback_dev &&
+ pjsua_var.snd_mode == snd_param->mode &&
+ !pjsua_var.no_snd && no_change)
{
PJ_LOG(4, (THIS_FILE, "No changes in capture and playback devices"));
PJSUA_UNLOCK();
@@ -1949,13 +1989,28 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev,
}
/* Null-sound */
- if (capture_dev==NULL_SND_DEV_ID && playback_dev==NULL_SND_DEV_ID) {
+ if (snd_param->capture_dev == NULL_SND_DEV_ID &&
+ snd_param->playback_dev == NULL_SND_DEV_ID)
+ {
PJSUA_UNLOCK();
status = pjsua_set_null_snd_dev();
pj_log_pop_indent();
return status;
}
+ pjsua_var.snd_mode = snd_param->mode;
+
+ if (!pjsua_var.no_snd &&
+ (snd_param->mode & PJSUA_SND_DEV_NO_IMMEDIATE_OPEN))
+ {
+ pjsua_var.cap_dev = snd_param->capture_dev;
+ pjsua_var.play_dev = snd_param->playback_dev;
+
+ PJSUA_UNLOCK();
+ pj_log_pop_indent();
+ return PJ_SUCCESS;
+ }
+
/* Set default clock rate */
alt_cr[0] = pjsua_var.media_cfg.snd_clock_rate;
if (alt_cr[0] == 0)
@@ -1982,7 +2037,8 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev,
pjsua_var.media_cfg.channel_count / 1000;
pjmedia_snd_port_param_default(&param);
param.ec_options = pjsua_var.media_cfg.ec_options;
- status = create_aud_param(&param.base, capture_dev, playback_dev,
+ status = create_aud_param(&param.base, snd_param->capture_dev,
+ snd_param->playback_dev,
alt_cr[i], pjsua_var.media_cfg.channel_count,
samples_per_frame, 16);
if (status != PJ_SUCCESS)
@@ -2008,6 +2064,7 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev,
return PJ_SUCCESS;
on_error:
+ pjsua_var.snd_mode = orig_snd_dev_mode;
PJSUA_UNLOCK();
pj_log_pop_indent();
return status;
diff --git a/pjsip/src/pjsua2/media.cpp b/pjsip/src/pjsua2/media.cpp
index 5a4e6ad0..880ade6b 100644
--- a/pjsip/src/pjsua2/media.cpp
+++ b/pjsip/src/pjsua2/media.cpp
@@ -679,17 +679,29 @@ AudioMedia &AudDevManager::getPlaybackDevMedia() throw(Error)
}
void AudDevManager::setCaptureDev(int capture_dev) const throw(Error)
-{
- int playback_dev = getPlaybackDev();
+{
+ pjsua_snd_dev_param param;
+ pjsua_snd_dev_param_default(&param);
+
+ param.capture_dev = capture_dev;
+ param.playback_dev = getPlaybackDev();
- PJSUA2_CHECK_EXPR( pjsua_set_snd_dev(capture_dev, playback_dev) );
+ param.mode = PJSUA_SND_DEV_NO_IMMEDIATE_OPEN;
+
+ PJSUA2_CHECK_EXPR( pjsua_set_snd_dev2(&param) );
}
void AudDevManager::setPlaybackDev(int playback_dev) const throw(Error)
{
- int capture_dev = getCaptureDev();
+ pjsua_snd_dev_param param;
+ pjsua_snd_dev_param_default(&param);
+
+ param.capture_dev = getCaptureDev();
+ param.playback_dev = playback_dev;
+
+ param.mode = PJSUA_SND_DEV_NO_IMMEDIATE_OPEN;
- PJSUA2_CHECK_EXPR( pjsua_set_snd_dev(capture_dev, playback_dev) );
+ PJSUA2_CHECK_EXPR( pjsua_set_snd_dev2(&param) );
}
const AudioDevInfoVector &AudDevManager::enumDev() throw(Error)
@@ -720,6 +732,21 @@ MediaPort *AudDevManager::setNoDev()
return (MediaPort*)pjsua_set_no_snd_dev();
}
+void AudDevManager::setSndDevMode(unsigned mode) const throw(Error)
+{
+ int capture_dev = 0, playback_dev = 0;
+ pjsua_snd_dev_param param;
+ pj_status_t status = pjsua_get_snd_dev(&capture_dev, &playback_dev);
+ if (status != PJ_SUCCESS) {
+ PJSUA2_RAISE_ERROR2(status, "AudDevManager::setSndDevMode()");
+ }
+ pjsua_snd_dev_param_default(&param);
+ param.capture_dev = capture_dev;
+ param.playback_dev = playback_dev;
+ param.mode = mode;
+ PJSUA2_CHECK_EXPR( pjsua_set_snd_dev2(&param) );
+}
+
void AudDevManager::setEcOptions(unsigned tail_msec,
unsigned options) throw(Error)
{