Changeset 731


Ignore:
Timestamp:
Sep 20, 2006 8:02:18 PM (15 years ago)
Author:
bennylp
Message:

Automatically suspend AEC when nothing is connected to the sound port in the bridge, and resume as soon as frames are transmitted.

Location:
pjproject/trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/include/pjmedia/sound_port.h

    r658 r731  
    221221 
    222222 
     223/** 
     224 * Enable or disable echo canceller. By default the EC is enabled after it 
     225 * was created, so there is no need to enable the EC after creating it. 
     226 * This function is only useful to disable the echo canceller temporarily, 
     227 * for example during idle period, to prevent EC from using 
     228 */ 
    223229 
    224230/** 
  • pjproject/trunk/pjmedia/src/pjmedia/conference.c

    r655 r731  
    12671267 */ 
    12681268static pj_status_t write_port(pjmedia_conf *conf, struct conf_port *cport, 
    1269                               pj_uint32_t timestamp) 
     1269                              pj_uint32_t timestamp,  
     1270                              pjmedia_frame_type *frm_type) 
    12701271{ 
    12711272    pj_int16_t *buf; 
     
    12731274    pj_status_t status; 
    12741275 
     1276    *frm_type = PJMEDIA_FRAME_TYPE_AUDIO; 
     1277 
    12751278    /* If port is muted or nobody is transmitting to this port,  
    12761279     * transmit NULL frame.  
     
    12931296 
    12941297        cport->tx_level = 0; 
     1298        *frm_type = PJMEDIA_FRAME_TYPE_NONE; 
    12951299        return PJ_SUCCESS; 
    12961300 
    12971301    } else if (cport->tx_setting != PJMEDIA_PORT_ENABLE) { 
    12981302        cport->tx_level = 0; 
     1303        *frm_type = PJMEDIA_FRAME_TYPE_NONE; 
    12991304        return PJ_SUCCESS; 
    13001305    } 
     
    14871492{ 
    14881493    pjmedia_conf *conf = this_port->port_data.pdata; 
     1494    pjmedia_frame_type speaker_frame_type = PJMEDIA_FRAME_TYPE_NONE; 
    14891495    unsigned ci, cj, i, j; 
    14901496     
     
    16841690    for (i=0, ci=0; i<conf->max_ports && ci<conf->port_cnt; ++i) { 
    16851691        struct conf_port *conf_port = conf->ports[i]; 
     1692        pjmedia_frame_type frm_type; 
    16861693        pj_status_t status; 
    16871694 
     
    16921699        ++ci; 
    16931700 
    1694         status = write_port( conf, conf_port, frame->timestamp.u32.lo); 
     1701        status = write_port( conf, conf_port, frame->timestamp.u32.lo, 
     1702                             &frm_type); 
    16951703        if (status != PJ_SUCCESS) { 
    16961704            /* bennylp: why do we need this???? 
     
    17091717            continue; 
    17101718        } 
     1719 
     1720        /* Set the type of frame to be returned to sound playback 
     1721         * device. 
     1722         */ 
     1723        if (i == 0) 
     1724            speaker_frame_type = frm_type; 
    17111725    } 
    17121726 
     
    17231737 
    17241738    /* MUST set frame type */ 
    1725     frame->type = PJMEDIA_FRAME_TYPE_AUDIO; 
     1739    frame->type = speaker_frame_type; 
    17261740 
    17271741    pj_mutex_unlock(conf->mutex); 
     
    17451759{ 
    17461760    pj_assert(0); 
     1761    PJ_UNUSED_ARG(this_port); 
     1762    PJ_UNUSED_ARG(frame); 
    17471763    return -1; 
    17481764} 
  • pjproject/trunk/pjmedia/src/pjmedia/port.c

    r631 r731  
    6363{ 
    6464    PJ_ASSERT_RETURN(port && frame, PJ_EINVAL); 
    65     PJ_ASSERT_RETURN(port->get_frame, PJ_EINVALIDOP); 
    6665 
    67     return port->get_frame(port, frame); 
     66    if (port->get_frame) 
     67        return port->get_frame(port, frame); 
     68    else { 
     69        frame->type = PJMEDIA_FRAME_TYPE_NONE; 
     70        return PJ_EINVALIDOP; 
     71    } 
    6872} 
    6973 
     
    7680{ 
    7781    PJ_ASSERT_RETURN(port && frame, PJ_EINVAL); 
    78     PJ_ASSERT_RETURN(port->put_frame, PJ_EINVALIDOP); 
    7982 
    80     return port->put_frame(port, frame); 
    81  
     83    if (port->put_frame) 
     84        return port->put_frame(port, frame); 
     85    else 
     86        return PJ_EINVALIDOP; 
    8287} 
    8388 
  • pjproject/trunk/pjmedia/src/pjmedia/sound_port.c

    r723 r731  
    3535 
    3636//#define SIMULATE_LOST_PCT   20 
    37 #define AEC_TAIL    128     /* default AEC length in ms */ 
     37#define AEC_TAIL            128     /* default AEC length in ms */ 
     38#define AEC_SUSPEND_LIMIT   5       /* seconds of no activity   */ 
    3839 
    3940#define THIS_FILE           "sound_port.c" 
     
    5960    pjmedia_echo_state  *ec_state; 
    6061    unsigned             aec_tail_len; 
     62 
     63    pj_bool_t            ec_suspended; 
     64    unsigned             ec_suspend_count; 
     65    unsigned             ec_suspend_limit; 
     66 
    6167    pjmedia_plc         *plc; 
    6268 
     
    117123 
    118124    if (snd_port->ec_state) { 
     125        if (snd_port->ec_suspended) { 
     126            snd_port->ec_suspended = PJ_FALSE; 
     127            PJ_LOG(4,(THIS_FILE, "EC activated")); 
     128        } 
     129        snd_port->ec_suspend_count = 0; 
    119130        pjmedia_echo_playback(snd_port->ec_state, output); 
    120131    } 
     
    124135 
    125136no_frame: 
     137 
     138    if (!snd_port->ec_suspended) { 
     139        ++snd_port->ec_suspend_count; 
     140        if (snd_port->ec_suspend_count > snd_port->ec_suspend_limit) { 
     141            snd_port->ec_suspended = PJ_TRUE; 
     142            PJ_LOG(4,(THIS_FILE, "EC suspended because of inactivity")); 
     143        } 
     144    } 
    126145 
    127146    /* Apply PLC */ 
     
    165184 
    166185    /* Cancel echo */ 
    167     if (snd_port->ec_state) { 
     186    if (snd_port->ec_state && !snd_port->ec_suspended) { 
    168187        pjmedia_echo_capture(snd_port->ec_state, input, 0); 
    169188    } 
     
    254273    } 
    255274 
     275    /* Inactivity limit before EC is suspended. */ 
     276    snd_port->ec_suspend_limit = AEC_SUSPEND_LIMIT * 
     277                                 (snd_port->clock_rate /  
     278                                  snd_port->samples_per_frame); 
    256279 
    257280    /* Start sound stream. */ 
     
    455478        if (status != PJ_SUCCESS) 
    456479            snd_port->ec_state = NULL; 
     480        else 
     481            snd_port->ec_suspended = PJ_FALSE; 
    457482    } else { 
    458483        PJ_LOG(4,(THIS_FILE, "Echo canceller is now disabled in the " 
  • pjproject/trunk/pjmedia/src/pjmedia/wav_player.c

    r727 r731  
    7171 
    7272 
    73 static pj_status_t file_put_frame(pjmedia_port *this_port,  
    74                                   const pjmedia_frame *frame); 
    7573static pj_status_t file_get_frame(pjmedia_port *this_port,  
    7674                                  pjmedia_frame *frame); 
     
    9290                           8000, 1, 16, 80); 
    9391 
    94     port->base.put_frame = &file_put_frame; 
    9592    port->base.get_frame = &file_get_frame; 
    9693    port->base.on_destroy = &file_on_destroy; 
     
    470467 
    471468/* 
    472  * Put frame to file. 
    473  */ 
    474 static pj_status_t file_put_frame(pjmedia_port *this_port,  
    475                                   const pjmedia_frame *frame) 
    476 { 
    477     PJ_UNUSED_ARG(this_port); 
    478     PJ_UNUSED_ARG(frame); 
    479     return PJ_EINVALIDOP; 
    480 } 
    481  
    482 /* 
    483469 * Get frame from file. 
    484470 */ 
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h

    r719 r731  
    21882188     * Echo canceller tail length, in miliseconds. 
    21892189     * 
    2190      * Default: 128 (PJSUA_DEFAULT_EC_TAIL_LEN) 
     2190     * Default: PJSUA_DEFAULT_EC_TAIL_LEN 
    21912191     */ 
    21922192    unsigned            ec_tail_len; 
Note: See TracChangeset for help on using the changeset viewer.