Ticket #587: ticket587.patch

File ticket587.patch, 5.4 KB (added by nanang, 13 years ago)

Rough modification: sending captured frames on the capture callback thread itself, just to check latency improvement, and measure it if any.

  • pjmedia/src/pjmedia/conference.c

     
    16911691    pjmedia_frame_type speaker_frame_type = PJMEDIA_FRAME_TYPE_NONE; 
    16921692    unsigned ci, cj, i, j; 
    16931693    pj_int16_t *p_in; 
     1694    pj_status_t status; 
    16941695     
    16951696    TRACE_((THIS_FILE, "- clock -")); 
    16961697 
     
    17241725    /* Get frames from all ports, and "mix" the signal  
    17251726     * to mix_buf of all listeners of the port. 
    17261727     */ 
    1727     for (i=0, ci=0; i<conf->max_ports && ci<conf->port_cnt; ++i) { 
     1728    for (i=1, ci=0; i<conf->max_ports && ci<conf->port_cnt-1; ++i) { 
    17281729        struct conf_port *conf_port = conf->ports[i]; 
    17291730        pj_int32_t level = 0; 
    17301731 
     
    18701871        } /* loop the listeners of conf port */ 
    18711872    } /* loop of all conf ports */ 
    18721873 
    1873     /* Time for all ports to transmit whetever they have in their 
    1874      * buffer.  
    1875      */ 
    1876     for (i=0, ci=0; i<conf->max_ports && ci<conf->port_cnt; ++i) { 
    1877         struct conf_port *conf_port = conf->ports[i]; 
    1878         pjmedia_frame_type frm_type; 
    1879         pj_status_t status; 
    1880  
    1881         if (!conf_port) 
    1882             continue; 
    1883  
    1884         /* Var "ci" is to count how many ports have been visited. */ 
    1885         ++ci; 
    1886  
    1887         status = write_port( conf, conf_port, &frame->timestamp, 
    1888                              &frm_type); 
    1889         if (status != PJ_SUCCESS) { 
    1890             /* bennylp: why do we need this???? 
    1891                One thing for sure, put_frame()/write_port() may return 
    1892                non-successfull status on Win32 if there's temporary glitch 
    1893                on network interface, so disabling the port here does not 
    1894                sound like a good idea. 
    1895  
    1896             PJ_LOG(4,(THIS_FILE, "Port %.*s put_frame() returned %d. " 
    1897                                  "Port is now disabled", 
    1898                                  (int)conf_port->name.slen, 
    1899                                  conf_port->name.ptr, 
    1900                                  status)); 
    1901             conf_port->tx_setting = PJMEDIA_PORT_DISABLE; 
    1902             */ 
    1903             continue; 
    1904         } 
    1905  
    1906         /* Set the type of frame to be returned to sound playback 
    1907          * device. 
    1908          */ 
    1909         if (i == 0) 
    1910             speaker_frame_type = frm_type; 
    1911     } 
    1912  
    1913     /* Return sound playback frame. */ 
    1914     if (conf->ports[0]->tx_level) { 
     1874    /* Get speaker frame */ 
     1875    status = write_port(conf, conf->ports[0], &frame->timestamp, 
     1876                        &speaker_frame_type); 
     1877    if (status != PJ_SUCCESS || conf->ports[0]->tx_level == 0) { 
     1878        /* Force frame type NONE */ 
     1879        speaker_frame_type = PJMEDIA_FRAME_TYPE_NONE; 
     1880    } else { 
    19151881        TRACE_((THIS_FILE, "write to audio, count=%d",  
    19161882                           conf->samples_per_frame)); 
    19171883        pjmedia_copy_samples( (pj_int16_t*)frame->buf,  
    19181884                              (const pj_int16_t*)conf->ports[0]->mix_buf,  
    19191885                              conf->samples_per_frame); 
    1920     } else { 
    1921         /* Force frame type NONE */ 
    1922         speaker_frame_type = PJMEDIA_FRAME_TYPE_NONE; 
    19231886    } 
    19241887 
    19251888    /* MUST set frame type */ 
     
    19601923    pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata; 
    19611924    struct conf_port *port = conf->ports[this_port->port_data.ldata]; 
    19621925    pj_status_t status; 
     1926    unsigned i, ci; 
     1927    pj_int16_t *p_in = (pj_int16_t*)frame->buf; 
    19631928 
    19641929    /* Check for correct size. */ 
    19651930    PJ_ASSERT_RETURN( frame->size == conf->samples_per_frame * 
     
    19741939        return PJ_SUCCESS; 
    19751940    } 
    19761941 
     1942    /* Add mic signal to all listeners. */ 
     1943    for (i=0; i < conf->ports[0]->listener_cnt; ++i) { 
     1944        struct conf_port *listener; 
     1945        pj_int32_t *mix_buf; 
     1946        unsigned k; 
     1947 
     1948        listener = conf->ports[conf->ports[0]->listener_slots[i]]; 
     1949 
     1950        /* Skip if this listener doesn't want to receive audio */ 
     1951        if (listener->tx_setting != PJMEDIA_PORT_ENABLE) 
     1952            continue; 
     1953 
     1954        mix_buf = listener->mix_buf; 
     1955 
     1956        /* Mixing signals, 
     1957         * and calculate appropriate level adjustment if there is 
     1958         * any overflowed level in the mixed signal. 
     1959         */ 
     1960        for (k=0; k<conf->samples_per_frame; ++k) { 
     1961            mix_buf[k] += p_in[k]; 
     1962            /* Check if normalization adjustment needed. */ 
     1963            if (IS_OVERFLOW(mix_buf[k])) { 
     1964                /* NORMAL_LEVEL * MAX_LEVEL / mix_buf[k]; */ 
     1965                int tmp_adj = (MAX_LEVEL<<7) / mix_buf[k]; 
     1966                if (tmp_adj<0) tmp_adj = -tmp_adj; 
     1967 
     1968                if (tmp_adj<listener->mix_adj) 
     1969                    listener->mix_adj = tmp_adj; 
     1970 
     1971            } 
     1972        } 
     1973    } 
     1974 
     1975    /* Time for all ports to transmit whetever they have in their 
     1976     * buffer.  
     1977     */ 
     1978    for (i=1, ci=0; i<conf->max_ports && ci<conf->port_cnt-1; ++i) { 
     1979        struct conf_port *conf_port = conf->ports[i]; 
     1980        pjmedia_frame_type frm_type; 
     1981        pj_status_t status; 
     1982 
     1983        /* Skip empty port. */ 
     1984        if (!conf_port) 
     1985            continue; 
     1986 
     1987        status = write_port( conf, conf_port, &frame->timestamp, 
     1988                             &frm_type); 
     1989 
     1990        pj_bzero(conf_port->mix_buf,  
     1991                 conf->samples_per_frame * sizeof(conf_port->mix_buf[0])); 
     1992 
     1993 
     1994        if (status != PJ_SUCCESS) { 
     1995            /* bennylp: why do we need this???? 
     1996               One thing for sure, put_frame()/write_port() may return 
     1997               non-successfull status on Win32 if there's temporary glitch 
     1998               on network interface, so disabling the port here does not 
     1999               sound like a good idea. 
     2000 
     2001            PJ_LOG(4,(THIS_FILE, "Port %.*s put_frame() returned %d. " 
     2002                                 "Port is now disabled", 
     2003                                 (int)conf_port->name.slen, 
     2004                                 conf_port->name.ptr, 
     2005                                 status)); 
     2006            conf_port->tx_setting = PJMEDIA_PORT_DISABLE; 
     2007            */ 
     2008            continue; 
     2009        } 
     2010    } 
     2011 
    19772012    /* Skip if no port is listening to the microphone */ 
     2013    /* 
    19782014    if (port->listener_cnt == 0) { 
     2015        status = pjmedia_delay_buf_put(port->delay_buf, (pj_int16_t*)frame->buf); 
     2016 
    19792017        return PJ_SUCCESS; 
    19802018    } 
     2019    */ 
    19812020 
    1982     status = pjmedia_delay_buf_put(port->delay_buf, (pj_int16_t*)frame->buf); 
    1983  
    1984     return status; 
     2021    return PJ_SUCCESS; 
    19852022} 
    19862023