summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2008-06-13 17:01:46 +0000
committerNanang Izzuddin <nanang@teluu.com>2008-06-13 17:01:46 +0000
commite3399b0820e6010b0a2d423261d54111af63e528 (patch)
tree06cb5c02a9de8441b964f66b8c46da72f936a7b6 /pjsip
parentb7242dd477e952452a5c01b8ab49ae7e41463683 (diff)
Ticket #540: Added pjsua-lib feature auto-close sound device on idle and new pjsua option --snd-auto-close=N
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2018 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h8
-rw-r--r--pjsip/include/pjsua-lib/pjsua_internal.h2
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c1
-rw-r--r--pjsip/src/pjsua-lib/pjsua_media.c102
4 files changed, 97 insertions, 16 deletions
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index 21d8ffb1..0ee97f9c 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -3908,6 +3908,14 @@ struct pjsua_media_config
* Specify the credential to authenticate with the TURN server.
*/
pj_stun_auth_cred turn_auth_cred;
+
+ /**
+ * Specify idle time of sound device before it is automatically closed,
+ * in seconds.
+ *
+ * Default : -1 (Disable the auto-close feature of sound device)
+ */
+ int snd_auto_close_time;
};
diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h
index dfb9f84a..766d8782 100644
--- a/pjsip/include/pjsua-lib/pjsua_internal.h
+++ b/pjsip/include/pjsua-lib/pjsua_internal.h
@@ -236,7 +236,9 @@ struct pjsua_data
int cap_dev; /**< Capture device ID. */
int play_dev; /**< Playback device ID. */
pj_bool_t no_snd; /**< No sound (app will manage it) */
+ pj_pool_t *snd_pool; /**< Sound's private pool. */
pjmedia_snd_port *snd_port; /**< Sound port. */
+ pj_timer_entry snd_idle_timer;/**< Sound device idle timer. */
pjmedia_master_port *null_snd; /**< Master port for null sound. */
pjmedia_port *null_port; /**< Null port. */
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index a50ff433..a59e9346 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -171,6 +171,7 @@ PJ_DEF(void) pjsua_media_config_default(pjsua_media_config *cfg)
cfg->ilbc_mode = PJSUA_DEFAULT_ILBC_MODE;
cfg->ec_tail_len = PJSUA_DEFAULT_EC_TAIL_LEN;
cfg->jb_init = cfg->jb_min_pre = cfg->jb_max_pre = cfg->jb_max = -1;
+ cfg->snd_auto_close_time = -1;
cfg->turn_conn_type = PJ_TURN_TP_UDP;
}
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c
index d8c2cd9c..0f923452 100644
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -22,7 +22,9 @@
#define THIS_FILE "pjsua_media.c"
-#define DEFAULT_RTP_PORT 4000
+#define DEFAULT_RTP_PORT 4000
+
+#define NULL_SND_DEV_ID -99
#ifndef PJSUA_REQUIRE_CONSECUTIVE_RTCP_PORT
# define PJSUA_REQUIRE_CONSECUTIVE_RTCP_PORT 0
@@ -423,6 +425,20 @@ on_error:
return status;
}
+/* Timer callback to close sound device */
+static void close_snd_timer_cb( pj_timer_heap_t *th,
+ pj_timer_entry *entry)
+{
+ PJ_UNUSED_ARG(th);
+
+ PJ_LOG(4,(THIS_FILE,"Closing sound device after idle for %d seconds",
+ pjsua_var.media_cfg.snd_auto_close_time));
+
+ entry->id = PJ_FALSE;
+
+ close_snd_dev();
+}
+
/*
* Start pjsua media subsystem.
@@ -444,16 +460,8 @@ pj_status_t pjsua_media_subsys_start(void)
return status;
}
- /* Create sound port if none is created yet */
- if (pjsua_var.snd_port==NULL && pjsua_var.null_snd==NULL &&
- !pjsua_var.no_snd)
- {
- status = pjsua_set_snd_dev(pjsua_var.cap_dev, pjsua_var.play_dev);
- if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Error opening sound device", status);
- return status;
- }
- }
+ pj_timer_entry_init(&pjsua_var.snd_idle_timer, PJ_FALSE, NULL,
+ &close_snd_timer_cb);
return PJ_SUCCESS;
}
@@ -1327,6 +1335,25 @@ PJ_DEF(pj_status_t) pjsua_conf_remove_port(pjsua_conf_port_id id)
PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source,
pjsua_conf_port_id sink)
{
+ /* If sound device idle timer is active, cancel it first. */
+ if (pjsua_var.snd_idle_timer.id) {
+ pjsip_endpt_cancel_timer(pjsua_var.endpt, &pjsua_var.snd_idle_timer);
+ pjsua_var.snd_idle_timer.id = PJ_FALSE;
+ }
+
+ /* Create sound port if none is instantiated */
+ if (pjsua_var.snd_port==NULL && pjsua_var.null_snd==NULL &&
+ !pjsua_var.no_snd)
+ {
+ pj_status_t status;
+
+ status = pjsua_set_snd_dev(pjsua_var.cap_dev, pjsua_var.play_dev);
+ if (status != PJ_SUCCESS) {
+ pjsua_perror(THIS_FILE, "Error opening sound device", status);
+ return status;
+ }
+ }
+
return pjmedia_conf_connect_port(pjsua_var.mconf, source, sink, 0);
}
@@ -1337,7 +1364,31 @@ PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source,
PJ_DEF(pj_status_t) pjsua_conf_disconnect( pjsua_conf_port_id source,
pjsua_conf_port_id sink)
{
- return pjmedia_conf_disconnect_port(pjsua_var.mconf, source, sink);
+ pj_status_t status;
+
+ status = pjmedia_conf_disconnect_port(pjsua_var.mconf, source, sink);
+ if (status != PJ_SUCCESS)
+ return status;
+
+ /* If no port is connected, sound device must be idle. Activate sound
+ * device auto-close timer.
+ */
+ if ((pjsua_var.snd_port!=NULL || pjsua_var.null_snd!=NULL) &&
+ pjsua_var.snd_idle_timer.id==PJ_FALSE &&
+ pjmedia_conf_get_connect_count(pjsua_var.mconf) == 0 &&
+ pjsua_var.media_cfg.snd_auto_close_time >= 0)
+ {
+ pj_time_val delay;
+
+ delay.msec = 0;
+ delay.sec = pjsua_var.media_cfg.snd_auto_close_time;
+
+ pjsua_var.snd_idle_timer.id = PJ_TRUE;
+ pjsip_endpt_schedule_timer(pjsua_var.endpt, &pjsua_var.snd_idle_timer,
+ &delay);
+ }
+
+ return status;
}
@@ -1843,6 +1894,10 @@ static void close_snd_dev(void)
pjmedia_master_port_destroy(pjsua_var.null_snd, PJ_FALSE);
pjsua_var.null_snd = NULL;
}
+
+ if (pjsua_var.snd_pool)
+ pj_pool_release(pjsua_var.snd_pool);
+ pjsua_var.snd_pool = NULL;
}
/*
@@ -1863,9 +1918,17 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev,
pj_str_t tmp;
pj_status_t status = -1;
+ /* Check if NULL sound device is used */
+ if (NULL_SND_DEV_ID == capture_dev || NULL_SND_DEV_ID == playback_dev) {
+ return pjsua_set_null_snd_dev();
+ }
+
/* Close existing sound port */
close_snd_dev();
+ /* Create memory pool for sound device. */
+ pjsua_var.snd_pool = pjsua_pool_create("pjsua_snd", 4000, 4000);
+ PJ_ASSERT_RETURN(pjsua_var.snd_pool, PJ_ENOMEM);
/* Set default clock rate */
clock_rates[0] = pjsua_var.media_cfg.snd_clock_rate;
@@ -1887,7 +1950,7 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev,
/* Create the sound device. Sound port will start immediately. */
fps = 1000 / pjsua_var.media_cfg.audio_frame_ptime;
- status = pjmedia_snd_port_create(pjsua_var.pool, capture_dev,
+ status = pjmedia_snd_port_create(pjsua_var.snd_pool, capture_dev,
playback_dev,
clock_rates[i],
pjsua_var.media_cfg.channel_count,
@@ -1914,7 +1977,7 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev,
resample_opt |= PJMEDIA_RESAMPLE_USE_LINEAR;
}
- status = pjmedia_resample_port_create(pjsua_var.pool,
+ status = pjmedia_resample_port_create(pjsua_var.snd_pool,
conf_port,
selected_clock_rate,
resample_opt,
@@ -1948,7 +2011,7 @@ PJ_DEF(pj_status_t) pjsua_set_snd_dev( int capture_dev,
}
/* Set AEC */
- pjmedia_snd_port_set_ec( pjsua_var.snd_port, pjsua_var.pool,
+ pjmedia_snd_port_set_ec( pjsua_var.snd_port, pjsua_var.snd_pool,
pjsua_var.media_cfg.ec_tail_len,
pjsua_var.media_cfg.ec_options);
@@ -2019,6 +2082,10 @@ PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void)
/* Close existing sound device */
close_snd_dev();
+ /* Create memory pool for sound device. */
+ pjsua_var.snd_pool = pjsua_pool_create("pjsua_snd", 4000, 4000);
+ PJ_ASSERT_RETURN(pjsua_var.snd_pool, PJ_ENOMEM);
+
PJ_LOG(4,(THIS_FILE, "Opening null sound device.."));
/* Get the port0 of the conference bridge. */
@@ -2028,7 +2095,7 @@ PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void)
/* Create master port, connecting port0 of the conference bridge to
* a null port.
*/
- status = pjmedia_master_port_create(pjsua_var.pool, pjsua_var.null_port,
+ status = pjmedia_master_port_create(pjsua_var.snd_pool, pjsua_var.null_port,
conf_port, 0, &pjsua_var.null_snd);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to create null sound device",
@@ -2040,6 +2107,9 @@ PJ_DEF(pj_status_t) pjsua_set_null_snd_dev(void)
status = pjmedia_master_port_start(pjsua_var.null_snd);
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+ pjsua_var.cap_dev = NULL_SND_DEV_ID;
+ pjsua_var.play_dev = NULL_SND_DEV_ID;
+
return PJ_SUCCESS;
}