summaryrefslogtreecommitdiff
path: root/pjmedia
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2008-03-03 13:25:17 +0000
committerBenny Prijono <bennylp@teluu.com>2008-03-03 13:25:17 +0000
commit8024e6c09371abb4c7e9f1427e78e7c1c2dfb857 (patch)
treeac550b859eaf5522ff055afdf16bc0c5d2e66a5a /pjmedia
parentdc72a8ab662293c15a138be9d0c3815eeef06729 (diff)
Ticket #499: NULL frame transmission in conference bridge is not clocked at the right interval
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1839 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia')
-rw-r--r--pjmedia/src/pjmedia/conference.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/pjmedia/src/pjmedia/conference.c b/pjmedia/src/pjmedia/conference.c
index 185d08bc..83ca8e00 100644
--- a/pjmedia/src/pjmedia/conference.c
+++ b/pjmedia/src/pjmedia/conference.c
@@ -179,6 +179,23 @@ struct conf_port
unsigned tx_buf_cap; /**< Max size, in samples. */
unsigned tx_buf_count; /**< # of samples in the buffer. */
+ /* When the port is not receiving signal from any other ports (e.g. when
+ * no other ports is transmitting to this port), the bridge periodically
+ * transmit NULL frame to the port to keep the port "alive" (for example,
+ * a stream port needs this heart-beat to periodically transmit silence
+ * frame to keep NAT binding alive).
+ *
+ * This NULL frame should be sent to the port at the port's ptime rate.
+ * So if the port's ptime is greater than the bridge's ptime, the bridge
+ * needs to delay the NULL frame until it's the right time to do so.
+ *
+ * This variable keeps track of how many pending NULL samples are being
+ * "held" for this port. Once this value reaches samples_per_frame
+ * value of the port, a NULL frame is sent. The samples value on this
+ * variable is clocked at the port's clock rate.
+ */
+ unsigned tx_heart_beat;
+
/* Delay buffer is a special buffer for sound device port (port 0, master
* port) and other passive ports (sound device port is also passive port).
*
@@ -1388,15 +1405,33 @@ static pj_status_t write_port(pjmedia_conf *conf, struct conf_port *cport,
pjmedia_frame frame;
- /* Adjust the timestamp */
+ /* Clear left-over samples in tx_buffer, if any, so that it won't
+ * be transmitted next time we have audio signal.
+ */
+ cport->tx_buf_count = 0;
+
+ /* Add sample counts to heart-beat samples */
+ cport->tx_heart_beat += conf->samples_per_frame * cport->clock_rate /
+ conf->clock_rate;
+
+ /* Set frame timestamp */
frame.timestamp.u64 = timestamp->u64 * cport->clock_rate /
conf->clock_rate;
frame.type = PJMEDIA_FRAME_TYPE_NONE;
frame.buf = NULL;
frame.size = 0;
+ /* Transmit heart-beat frames (may transmit more than one NULL frame
+ * if port's ptime is less than bridge's ptime.
+ */
if (cport->port && cport->port->put_frame) {
- pjmedia_port_put_frame(cport->port, &frame);
+ while (cport->tx_heart_beat >= cport->samples_per_frame) {
+
+ pjmedia_port_put_frame(cport->port, &frame);
+
+ cport->tx_heart_beat -= cport->samples_per_frame;
+ frame.timestamp.u64 += cport->samples_per_frame;
+ }
}
cport->tx_level = 0;
@@ -1409,6 +1444,9 @@ static pj_status_t write_port(pjmedia_conf *conf, struct conf_port *cport,
return PJ_SUCCESS;
}
+ /* Reset heart-beat sample count */
+ cport->tx_heart_beat = 0;
+
buf = (pj_int16_t*) cport->mix_buf;
/* If there are sources in the mix buffer, convert the mixed samples