Conferencer bugfix and improvement (with patch)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi there,

I fixed a bug in the conferencer:

The code for writing to the outputs first checks, if the port is muted
or doesn't have any transmitters to it. In that case, an empty frame
is written. The case that the port is disabled is checked afterwards.
This causes dead code since a disabled output port usually doesn't
have any transmitters.
I reordered the code to first check if the output port is disabled. In
that case the port will not be written.


Further, I took function pjmedia_conf_remove_port() and extracted its
content into the functions pjmedia_conf_disconnect_port_from_sources()
and pjmedia_conf_disconnect_port_from_sinks(). This allows the removal
of all connections from or to a given port.

Please integrate.
Thanks a lot in advance.


Regards,
Michael
Index: pjmedia/src/pjmedia/conference.c
===================================================================
--- pjmedia/src/pjmedia/conference.c	(revision 5883)
+++ pjmedia/src/pjmedia/conference.c	(working copy)
@@ -1089,7 +1089,105 @@
     return PJ_SUCCESS;
 }
 
+
 /*
+ * Disconnect port from all sources
+ */
+PJ_DEF(pj_status_t)
+pjmedia_conf_disconnect_port_from_sources( pjmedia_conf *conf,
+					   unsigned sink_slot)
+{
+    unsigned i;
+
+    /* Check arguments */
+    PJ_ASSERT_RETURN(conf && sink_slot<conf->max_ports, PJ_EINVAL);
+
+    /* Remove this port from transmit array of other ports. */
+    for (i=0; i<conf->max_ports; ++i) {
+	unsigned j;
+	struct conf_port *src_port;
+
+	pj_mutex_lock(conf->mutex);
+
+	src_port = conf->ports[i];
+
+	if (!src_port) {
+	    pj_mutex_unlock(conf->mutex);
+	    continue;
+	}
+
+	if (src_port->listener_cnt == 0) {
+	    pj_mutex_unlock(conf->mutex);
+	    continue;
+	}
+
+	for (j=0; j<src_port->listener_cnt; ++j) {
+	    if (src_port->listener_slots[j] == sink_slot) {
+		pj_array_erase(src_port->listener_slots, sizeof(SLOT_TYPE),
+			       src_port->listener_cnt, j);
+		pj_assert(conf->connect_cnt > 0);
+		--conf->connect_cnt;
+		--src_port->listener_cnt;
+		break;
+	    }
+	}
+
+	pj_mutex_unlock(conf->mutex);
+    }
+
+    if (conf->connect_cnt == 0) {
+	pause_sound(conf);
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Disconnect port from all sinks
+ */
+PJ_DEF(pj_status_t)
+pjmedia_conf_disconnect_port_from_sinks( pjmedia_conf *conf,
+					 unsigned src_slot)
+{
+    struct conf_port *src_port;
+
+    /* Check arguments */
+    PJ_ASSERT_RETURN(conf && src_slot<conf->max_ports, PJ_EINVAL);
+
+    pj_mutex_lock(conf->mutex);
+
+    /* Port must be valid. */
+    src_port = conf->ports[src_slot];
+    if (!src_port) {
+	pj_mutex_unlock(conf->mutex);
+	return PJ_EINVAL;
+    }
+
+    /* Update transmitter_cnt of ports we're transmitting to */
+    while (src_port->listener_cnt) {
+	unsigned dst_slot;
+	struct conf_port *dst_port;
+
+	dst_slot = src_port->listener_slots[src_port->listener_cnt-1];
+	dst_port = conf->ports[dst_slot];
+	--dst_port->transmitter_cnt;
+	--src_port->listener_cnt;
+	pj_assert(conf->connect_cnt > 0);
+	--conf->connect_cnt;
+    }
+
+    pj_mutex_unlock(conf->mutex);
+
+    if (conf->connect_cnt == 0) {
+	pause_sound(conf);
+    }
+
+    return PJ_SUCCESS;
+}
+
+
+/*
  * Get number of ports currently registered to the conference bridge.
  */
 PJ_DEF(unsigned) pjmedia_conf_get_port_count(pjmedia_conf *conf)
@@ -1113,7 +1211,6 @@
 					      unsigned port )
 {
     struct conf_port *conf_port;
-    unsigned i;
 
     /* Check arguments */
     PJ_ASSERT_RETURN(conf && port < conf->max_ports, PJ_EINVAL);
@@ -1135,44 +1232,16 @@
     conf_port->tx_setting = PJMEDIA_PORT_DISABLE;
     conf_port->rx_setting = PJMEDIA_PORT_DISABLE;
 
-    /* Remove this port from transmit array of other ports. */
-    for (i=0; i<conf->max_ports; ++i) {
-	unsigned j;
-	struct conf_port *src_port;
+    pj_mutex_unlock(conf->mutex);
 
-	src_port = conf->ports[i];
+    /* disconnect port from all sources which are transmitting to it */
+    pjmedia_conf_disconnect_port_from_sources(conf, port);
 
-	if (!src_port)
-	    continue;
+    /* disconnect port from all sinks to which it is transmitting to */
+    pjmedia_conf_disconnect_port_from_sinks(conf, port);
 
-	if (src_port->listener_cnt == 0)
-	    continue;
+    pj_mutex_lock(conf->mutex);
 
-	for (j=0; j<src_port->listener_cnt; ++j) {
-	    if (src_port->listener_slots[j] == port) {
-		pj_array_erase(src_port->listener_slots, sizeof(SLOT_TYPE),
-			       src_port->listener_cnt, j);
-		pj_assert(conf->connect_cnt > 0);
-		--conf->connect_cnt;
-		--src_port->listener_cnt;
-		break;
-	    }
-	}
-    }
-
-    /* Update transmitter_cnt of ports we're transmitting to */
-    while (conf_port->listener_cnt) {
-	unsigned dst_slot;
-	struct conf_port *dst_port;
-
-	dst_slot = conf_port->listener_slots[conf_port->listener_cnt-1];
-	dst_port = conf->ports[dst_slot];
-	--dst_port->transmitter_cnt;
-	--conf_port->listener_cnt;
-	pj_assert(conf->connect_cnt > 0);
-	--conf->connect_cnt;
-    }
-
     /* Destroy pjmedia port if this conf port is passive port,
      * i.e: has delay buf.
      */
@@ -1187,12 +1256,6 @@
 
     pj_mutex_unlock(conf->mutex);
 
-
-    /* Stop sound if there's no connection. */
-    if (conf->connect_cnt == 0) {
-	pause_sound(conf);
-    }
-
     return PJ_SUCCESS;
 }
 
@@ -1624,11 +1687,17 @@
 
     *frm_type = PJMEDIA_FRAME_TYPE_AUDIO;
 
+    /* Skip port if it is disabled */
+    if (cport->tx_setting != PJMEDIA_PORT_ENABLE) {
+	cport->tx_level = 0;
+	*frm_type = PJMEDIA_FRAME_TYPE_NONE;
+	return PJ_SUCCESS;
+    }
     /* If port is muted or nobody is transmitting to this port, 
      * transmit NULL frame. 
      */
-    if (cport->tx_setting == PJMEDIA_PORT_MUTE || cport->transmitter_cnt==0) {
-
+    else if ((cport->tx_setting == PJMEDIA_PORT_MUTE) ||
+	     (cport->transmitter_cnt == 0)) {
 	pjmedia_frame frame;
 
 	/* Clear left-over samples in tx_buffer, if any, so that it won't
@@ -1664,11 +1733,6 @@
 	cport->tx_level = 0;
 	*frm_type = PJMEDIA_FRAME_TYPE_NONE;
 	return PJ_SUCCESS;
-
-    } else if (cport->tx_setting != PJMEDIA_PORT_ENABLE) {
-	cport->tx_level = 0;
-	*frm_type = PJMEDIA_FRAME_TYPE_NONE;
-	return PJ_SUCCESS;
     }
 
     /* Reset heart-beat sample count */
_______________________________________________
Visit our blog: http://blog.pjsip.org

pjsip mailing list
pjsip@xxxxxxxxxxxxxxx
http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org

[Index of Archives]     [Asterisk Users]     [Asterisk App Development]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [Linux API]
  Powered by Linux