Changeset 1833 for pjproject/trunk/pjmedia/src/pjmedia/conference.c
- Timestamp:
- Feb 29, 2008 5:19:42 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/conference.c
r1715 r1833 19 19 #include <pjmedia/conference.h> 20 20 #include <pjmedia/alaw_ulaw.h> 21 #include <pjmedia/delaybuf.h> 21 22 #include <pjmedia/errno.h> 22 23 #include <pjmedia/port.h> … … 57 58 #define THIS_FILE "conference.c" 58 59 59 /* When delay buffer is used, we only need 1 frame buffering */ 60 #if defined(PJMEDIA_SOUND_USE_DELAYBUF) && PJMEDIA_SOUND_USE_DELAYBUF!=0 61 # define RX_BUF_COUNT 1 62 #else 63 # define RX_BUF_COUNT PJMEDIA_SOUND_BUFFER_COUNT 64 #endif 60 #define RX_BUF_COUNT PJMEDIA_SOUND_BUFFER_COUNT 65 61 66 62 #define BYTES_PER_SAMPLE 2 … … 184 180 unsigned tx_buf_count; /**< # of samples in the buffer. */ 185 181 186 /* Snd buffersis a special buffer for sound device port (port 0, master187 * port) . It's not used by other ports.182 /* Delay buffer is a special buffer for sound device port (port 0, master 183 * port) and other passive ports (sound device port is also passive port). 188 184 * 189 * There are multiple numbers of this buffer, because we can not expect 190 * the mic and speaker thread to run equally after one another. In most 191 * systems, each thread will run multiple times before the other thread 192 * gains execution time. For example, in my system, mic thread is called 193 * three times, then speaker thread is called three times, and so on. 194 */ 195 int snd_write_pos, snd_read_pos; 196 pj_int16_t *snd_buf[RX_BUF_COUNT]; /**< Buffer */ 185 * We need the delay buffer because we can not expect the mic and speaker 186 * thread to run equally after one another. In most systems, each thread 187 * will run multiple times before the other thread gains execution time. 188 * For example, in my system, mic thread is called three times, then 189 * speaker thread is called three times, and so on. This we call burst. 190 * 191 * There is also possibility of drift, unbalanced rate between put_frame 192 * and get_frame operation, in passive ports. If drift happens, snd_buf 193 * needs to be expanded or shrinked. 194 * 195 * Burst and drift are handled by delay buffer. 196 */ 197 pjmedia_delay_buf *delay_buf; 197 198 }; 198 199 … … 227 228 pjmedia_frame *frame); 228 229 static pj_status_t destroy_port(pjmedia_port *this_port); 230 static pj_status_t destroy_port_pasv(pjmedia_port *this_port); 229 231 230 232 … … 378 380 { 379 381 struct conf_port *conf_port; 380 unsigned i;381 382 pj_status_t status; 382 383 … … 386 387 return status; 387 388 388 /* Passive port has rx buffers. */ 389 for (i=0; i<RX_BUF_COUNT; ++i) { 390 conf_port->snd_buf[i] = (pj_int16_t*) 391 pj_pool_zalloc(pool, conf->samples_per_frame * 392 sizeof(conf_port->snd_buf[0][0])); 393 if (conf_port->snd_buf[i] == NULL) { 394 return PJ_ENOMEM; 395 } 396 } 397 conf_port->snd_write_pos = 0; 398 conf_port->snd_read_pos = 0; 389 /* Passive port has delay buf. */ 390 status = pjmedia_delay_buf_create(pool, name->ptr, 391 conf->clock_rate, 392 conf->samples_per_frame, 393 RX_BUF_COUNT, /* max */ 394 -1, /* delay */ 395 0, /* options */ 396 &conf_port->delay_buf); 397 if (status != PJ_SUCCESS) 398 return status; 399 399 400 400 *p_conf_port = conf_port; … … 445 445 0, /* Options */ 446 446 &conf->snd_dev_port); 447 447 448 } 448 449 … … 607 608 } 608 609 610 static pj_status_t destroy_port_pasv(pjmedia_port *this_port) { 611 pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata; 612 struct conf_port *port = conf->ports[this_port->port_data.ldata]; 613 pj_status_t status; 614 615 status = pjmedia_delay_buf_destroy(port->delay_buf); 616 if (status == PJ_SUCCESS) 617 port->delay_buf = NULL; 618 619 return status; 620 } 609 621 610 622 /* … … 786 798 port->get_frame = &get_frame_pasv; 787 799 port->put_frame = &put_frame; 788 port->on_destroy = NULL;800 port->on_destroy = &destroy_port_pasv; 789 801 790 802 … … 955 967 dst_port->name.ptr)); 956 968 957 969 /* if source port is passive port and has no listener, reset delaybuf */ 970 if (src_port->delay_buf && src_port->listener_cnt == 0) 971 pjmedia_delay_buf_reset(src_port->delay_buf); 958 972 } 959 973 … … 1617 1631 } 1618 1632 1619 /* Get frame from this port. 1620 * For p ort zero (sound port) and passive ports, get the frame from1621 * the rx_buffer instead.1633 /* Get frame from this port. 1634 * For passive ports, get the frame from the delay_buf. 1635 * For other ports, get the frame from the port. 1622 1636 */ 1623 if (conf_port->port == NULL) { 1624 pj_int16_t *snd_buf; 1625 1626 if (conf_port->snd_read_pos == conf_port->snd_write_pos) { 1627 conf_port->snd_read_pos = 1628 (conf_port->snd_write_pos+RX_BUF_COUNT-RX_BUF_COUNT/2) % 1629 RX_BUF_COUNT; 1630 } 1631 1632 /* Skip if this port is muted/disabled. */ 1633 if (conf_port->rx_setting != PJMEDIA_PORT_ENABLE) { 1634 conf_port->rx_level = 0; 1637 if (conf_port->delay_buf != NULL) { 1638 pj_status_t status; 1639 1640 status = pjmedia_delay_buf_get(conf_port->delay_buf, 1641 (pj_int16_t*)frame->buf); 1642 if (status != PJ_SUCCESS) 1635 1643 continue; 1636 }1637 1638 snd_buf = conf_port->snd_buf[conf_port->snd_read_pos];1639 pjmedia_copy_samples((pj_int16_t*)frame->buf, snd_buf,1640 conf->samples_per_frame);1641 conf_port->snd_read_pos = (conf_port->snd_read_pos+1) % RX_BUF_COUNT;1642 1644 1643 1645 } else { … … 1831 1833 1832 1834 /* 1833 * Recorder callback.1835 * Recorder (or passive port) callback. 1834 1836 */ 1835 1837 static pj_status_t put_frame(pjmedia_port *this_port, … … 1838 1840 pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata; 1839 1841 struct conf_port *port = conf->ports[this_port->port_data.ldata]; 1840 const pj_int16_t *input = (const pj_int16_t*) frame->buf; 1841 pj_int16_t *target_snd_buf; 1842 pj_status_t status; 1842 1843 1843 1844 /* Check for correct size. */ … … 1846 1847 PJMEDIA_ENCSAMPLESPFRAME); 1847 1848 1849 /* Check existance of delay_buf instance */ 1850 PJ_ASSERT_RETURN( port->delay_buf, PJ_EBUG ); 1851 1848 1852 /* Skip if this port is muted/disabled. */ 1849 1853 if (port->rx_setting != PJMEDIA_PORT_ENABLE) { … … 1856 1860 } 1857 1861 1858 1859 /* Determine which rx_buffer to fill in */ 1860 target_snd_buf = port->snd_buf[port->snd_write_pos]; 1861 1862 /* Copy samples from audio device to target rx_buffer */ 1863 pjmedia_copy_samples(target_snd_buf, input, conf->samples_per_frame); 1864 1865 /* Switch buffer */ 1866 port->snd_write_pos = (port->snd_write_pos+1)%RX_BUF_COUNT; 1867 1868 1869 return PJ_SUCCESS; 1870 } 1871 1862 status = pjmedia_delay_buf_put(port->delay_buf, (pj_int16_t*)frame->buf); 1863 1864 return status; 1865 } 1866
Note: See TracChangeset
for help on using the changeset viewer.