Changeset 6140


Ignore:
Timestamp:
Jan 28, 2020 6:58:45 AM (8 months ago)
Author:
ming
Message:

Closed #2143: Add AEC info to call info & statistics dump

Location:
pjproject/trunk
Files:
10 edited

Legend:

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

    r5186 r6140  
    154154 
    155155 
     156/** Statistic not specified. */ 
     157#define PJMEDIA_ECHO_STAT_NOT_SPECIFIED         999999 
     158 
     159/** 
     160 * Echo cancellation statistics. 
     161 */ 
     162typedef struct pjmedia_echo_stat 
     163{ 
     164    /** 
     165     * The name of the EC backend. 
     166     * NULL if not specified. 
     167     */     
     168    const char *name; 
     169 
     170    /** 
     171     * Echo delay median value (in ms). 
     172     * PJMEDIA_ECHO_STAT_NOT_SPECIFIED if unavailable. 
     173     */ 
     174    int         median; 
     175 
     176    /** 
     177     * Echo delay standard deviation (in ms). 
     178     * PJMEDIA_ECHO_STAT_NOT_SPECIFIED if unavailable. 
     179     */ 
     180    int         std; 
     181 
     182    /** 
     183     * Fraction of poor delay. Value between 0 to 1. The closer to 1, 
     184     * the poorer the EC quality. 
     185     * PJMEDIA_ECHO_STAT_NOT_SPECIFIED if unavailable. 
     186     */ 
     187    float       frac_delay; 
     188 
     189    /** 
     190     * Learning still in progress? PJ_TRUE if yes, false if done. 
     191     * PJMEDIA_ECHO_STAT_NOT_SPECIFIED if unavailable. 
     192     */ 
     193    unsigned    learning; 
     194 
     195    /** 
     196     * Learning duration (in ms). 
     197     * PJMEDIA_ECHO_STAT_NOT_SPECIFIED if unavailable. 
     198     */ 
     199    unsigned    duration; 
     200 
     201    /** 
     202     * Detected echo tail length (in ms). 
     203     * PJMEDIA_ECHO_STAT_NOT_SPECIFIED if unavailable. 
     204     */ 
     205    unsigned    tail; 
     206 
     207    /** 
     208     * Minimum scaling factor (in ms). 
     209     * PJMEDIA_ECHO_STAT_NOT_SPECIFIED if unavailable. 
     210     */ 
     211    int         min_factor; 
     212 
     213    /** 
     214     * Average scaling factor (in ms). 
     215     * PJMEDIA_ECHO_STAT_NOT_SPECIFIED if unavailable. 
     216     */ 
     217    int         avg_factor; 
     218 
     219    /** 
     220     * Text describing the statistic. 
     221     */ 
     222    pj_str_t    stat_info; 
     223 
     224    /** 
     225     * Internal buffer. 
     226     */ 
     227    char        buf_[128]; 
     228 
     229} pjmedia_echo_stat; 
     230 
     231 
     232/** 
     233 * Initialize Echo cancellation stat. 
     234 * 
     235 * @param stat              The statistic to be initialized. 
     236 */ 
     237PJ_DECL(void) pjmedia_echo_stat_default(pjmedia_echo_stat *stat); 
    156238 
    157239 
     
    233315 
    234316/** 
     317 * Get the echo canceller statistics. 
     318 * 
     319 * @param echo          The Echo Canceller. 
     320 * @param p_stat        Pointer to receive the stat. 
     321 * 
     322 * @return              PJ_SUCCESS on success. 
     323 */ 
     324PJ_DECL(pj_status_t) pjmedia_echo_get_stat(pjmedia_echo_state *echo, 
     325                                           pjmedia_echo_stat *p_stat); 
     326 
     327 
     328/** 
    235329 * Let the Echo Canceller know that a frame has been played to the speaker. 
    236330 * The Echo Canceller will keep the frame in its internal buffer, to be used 
  • pjproject/trunk/pjmedia/include/pjmedia/sound_port.h

    r4982 r6140  
    2828#include <pjmedia/clock.h> 
    2929#include <pjmedia/port.h> 
     30#include <pjmedia/echo.h> 
    3031 
    3132PJ_BEGIN_DECL 
     
    318319 
    319320/** 
     321 * Get echo canceller statistics. 
     322 * 
     323 * @param snd_port          The sound device port. 
     324 * @param p_stat            Pointer to receive the stat. 
     325 * 
     326 * @return                  PJ_SUCCESS on success, or the appropriate error 
     327 *                          code. 
     328 */ 
     329PJ_DECL(pj_status_t) pjmedia_snd_port_get_ec_stat(pjmedia_snd_port *snd_port, 
     330                                                  pjmedia_echo_stat *p_stat); 
     331 
     332 
     333/** 
    320334 * Get a clock source from the sound port. 
    321335 * 
  • pjproject/trunk/pjmedia/src/pjmedia/echo_common.c

    r6129 r6140  
    8080                             pj_int16_t *rec_frm, 
    8181                             unsigned options ); 
     82    pj_status_t (*ec_get_stat)(void *state, 
     83                             pjmedia_echo_stat *stat); 
    8284}; 
    8385 
     
    8991    &echo_supp_destroy, 
    9092    &echo_supp_reset, 
    91     &echo_supp_cancel_echo 
     93    &echo_supp_cancel_echo, 
     94    NULL, 
     95    NULL, 
     96    &echo_supp_get_stat 
    9297}; 
    9398 
     
    135140    &webrtc_aec_destroy, 
    136141    &webrtc_aec_reset, 
    137     &webrtc_aec_cancel_echo 
    138 }; 
    139 #endif 
     142    &webrtc_aec_cancel_echo, 
     143    NULL, 
     144    NULL, 
     145    &webrtc_aec_get_stat 
     146}; 
     147#endif 
     148 
     149PJ_DEF(void) pjmedia_echo_stat_default(pjmedia_echo_stat *stat) 
     150{ 
     151    pj_bzero(stat, sizeof(pjmedia_echo_stat)); 
     152    stat->median = PJMEDIA_ECHO_STAT_NOT_SPECIFIED; 
     153    stat->std = PJMEDIA_ECHO_STAT_NOT_SPECIFIED; 
     154    stat->frac_delay = (float)PJMEDIA_ECHO_STAT_NOT_SPECIFIED; 
     155    stat->duration = PJMEDIA_ECHO_STAT_NOT_SPECIFIED; 
     156    stat->tail = PJMEDIA_ECHO_STAT_NOT_SPECIFIED; 
     157    stat->min_factor = PJMEDIA_ECHO_STAT_NOT_SPECIFIED; 
     158    stat->avg_factor = PJMEDIA_ECHO_STAT_NOT_SPECIFIED; 
     159} 
    140160 
    141161/* 
     
    425445} 
    426446 
     447 
     448/* 
     449 * Get the Echo Canceller stats.  
     450 */ 
     451PJ_DEF(pj_status_t) pjmedia_echo_get_stat(pjmedia_echo_state *echo, 
     452                                          pjmedia_echo_stat *p_stat) 
     453{ 
     454    PJ_ASSERT_RETURN(p_stat, PJ_EINVAL); 
     455 
     456    if (echo->op->ec_get_stat) 
     457        return (*echo->op->ec_get_stat)(echo->state, p_stat); 
     458 
     459    return PJ_ENOTSUP; 
     460} 
     461 
  • pjproject/trunk/pjmedia/src/pjmedia/echo_internal.h

    r5186 r6140  
    2222 
    2323#include <pjmedia/types.h> 
     24#include <pjmedia/echo.h> 
    2425 
    2526PJ_BEGIN_DECL 
     
    3637                                      void **p_state ); 
    3738PJ_DECL(pj_status_t) echo_supp_destroy(void *state); 
     39PJ_DECL(pj_status_t) echo_supp_get_stat(void *state, 
     40                                        pjmedia_echo_stat *p_stat); 
    3841PJ_DECL(void) echo_supp_reset(void *state); 
    3942PJ_DECL(pj_status_t) echo_supp_cancel_echo(void *state, 
     
    8689                                       void **p_echo ); 
    8790PJ_DECL(pj_status_t) webrtc_aec_destroy(void *state ); 
     91PJ_DECL(pj_status_t) webrtc_aec_get_stat(void *state, 
     92                                         pjmedia_echo_stat *p_stat); 
    8893PJ_DECL(void) webrtc_aec_reset(void *state ); 
    8994PJ_DECL(pj_status_t) webrtc_aec_cancel_echo(void *state, 
  • pjproject/trunk/pjmedia/src/pjmedia/echo_suppress.c

    r4728 r6140  
    805805} 
    806806 
     807 
     808PJ_DEF(pj_status_t) echo_supp_get_stat( void *state, 
     809                                        pjmedia_echo_stat *p_stat) 
     810{ 
     811    echo_supp *ec = (echo_supp*) state; 
     812 
     813    pjmedia_echo_stat_default(p_stat); 
     814    p_stat->name = "Echo suppressor"; 
     815    p_stat->learning = ec->learning; 
     816    p_stat->duration = ec->update_cnt * SEGMENT_PTIME; 
     817    p_stat->tail = (ec->tail_cnt-ec->tail_index) * SEGMENT_PTIME; 
     818    p_stat->min_factor = (int)(ec->min_factor[ec->tail_index] * 1000); 
     819    p_stat->avg_factor = (int)(ec->avg_factor[ec->tail_index] * 1000); 
     820 
     821    p_stat->stat_info.ptr = p_stat->buf_; 
     822    p_stat->stat_info.slen = 
     823        pj_ansi_snprintf(p_stat->buf_, sizeof(p_stat->buf_), 
     824                "Echo suppressor learning %s at t=%03d.%03ds, tail=%d ms,\n" 
     825                "          factor min/avg=%d.%03d/%d.%03d", 
     826                (ec->learning? "in progress": "done"), 
     827                (p_stat->duration/1000), (p_stat->duration%1000), 
     828                p_stat->tail, 
     829                p_stat->min_factor/1000, p_stat->min_factor%1000, 
     830                p_stat->avg_factor/1000, p_stat->avg_factor%1000); 
     831 
     832    return PJ_SUCCESS; 
     833} 
     834 
  • pjproject/trunk/pjmedia/src/pjmedia/echo_webrtc.c

    r6084 r6140  
    2323#include <pj/log.h> 
    2424#include <pj/pool.h> 
     25#include <pj/string.h> 
    2526 
    2627#if defined(PJMEDIA_HAS_WEBRTC_AEC) && PJMEDIA_HAS_WEBRTC_AEC != 0 
     
    5051    #define WebRtcAec_BufferFarend WebRtcAecm_BufferFarend 
    5152    #define AecConfig AecmConfig 
    52     #define SHOW_DELAY_METRICS  0 
    5353    typedef short sample; 
    5454#else 
     
    5757    typedef float sample; 
    5858 
    59     /* If SHOW_DELAY_METRICS is set to non-zero, delay metrics stats will 
    60      * be printed every SHOW_DELAY_METRICS-th call to webrtc_aec_cancel_echo(). 
    61      * For example, if ptime is 20ms, set this to 250 to print the metrics 
    62      * every 250*20/1000=5 seconds. 
    63      */ 
    64     #define SHOW_DELAY_METRICS  0 
    65      
    6659#endif 
    6760 
    6861#define BUF_LEN                 160 
     62 
     63/* Set this to 0 to disable metrics calculation. */ 
     64#define SHOW_DELAY_METRICS      1 
    6965 
    7066typedef struct webrtc_ec 
     
    8076    sample      tmp_buf[BUF_LEN]; 
    8177    sample      tmp_buf2[BUF_LEN]; 
    82 #if SHOW_DELAY_METRICS 
    83     unsigned    counter; 
    84 #endif 
    8578} webrtc_ec; 
    8679 
     
    356349    } 
    357350 
    358 #if SHOW_DELAY_METRICS 
    359     if (++echo->counter >= SHOW_DELAY_METRICS) { 
    360         int median, std; 
    361         float frac_delay; 
    362  
    363         if (WebRtcAec_GetDelayMetrics(echo->AEC_inst, &median, &std, 
    364                                       &frac_delay) == 0) 
    365         { 
    366             PJ_LOG(3, (THIS_FILE, "WebRTC delay metrics: median=%d, std=%d, " 
    367                                   "fraction of poor delays=%f", 
    368                                   median, std, frac_delay)); 
    369         } 
    370         echo->counter = 0; 
    371     } 
    372 #endif 
    373  
    374351    return PJ_SUCCESS; 
    375352} 
    376353 
    377 #endif 
     354 
     355PJ_DEF(pj_status_t) webrtc_aec_get_stat(void *state, 
     356                                        pjmedia_echo_stat *p_stat) 
     357{ 
     358    webrtc_ec *echo = (webrtc_ec*) state; 
     359 
     360    if (WebRtcAec_GetDelayMetrics(echo->AEC_inst, &p_stat->median, 
     361                                  &p_stat->std, &p_stat->frac_delay) != 0) 
     362    { 
     363        return PJ_EUNKNOWN; 
     364    } 
     365 
     366    p_stat->name = "WebRTC AEC"; 
     367    p_stat->stat_info.ptr = p_stat->buf_; 
     368    p_stat->stat_info.slen = 
     369        pj_ansi_snprintf(p_stat->buf_, sizeof(p_stat->buf_), 
     370                         "WebRTC delay metric: median=%d, std=%d, " 
     371                         "frac of poor delay=%.02f", 
     372                         p_stat->median, p_stat->std, p_stat->frac_delay); 
     373 
     374    return PJ_SUCCESS; 
     375} 
     376 
     377 
     378#endif 
  • pjproject/trunk/pjmedia/src/pjmedia/sound_port.c

    r5140 r6140  
    715715 
    716716/* 
     717 * Get echo canceller statistics. 
     718 */ 
     719PJ_DEF(pj_status_t) pjmedia_snd_port_get_ec_stat( pjmedia_snd_port *snd_port, 
     720                                                  pjmedia_echo_stat *p_stat) 
     721{ 
     722    PJ_ASSERT_RETURN(snd_port && p_stat, PJ_EINVAL); 
     723 
     724    if (snd_port->ec_state) { 
     725        return pjmedia_echo_get_stat(snd_port->ec_state, p_stat); 
     726    } else { 
     727        return PJ_ENOTFOUND; 
     728    } 
     729} 
     730 
     731                                                   
     732/* 
    717733 * Get clock source. 
    718734 */ 
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h

    r6137 r6140  
    74537453 
    74547454/** 
     7455 * Get echo canceller statistics. 
     7456 * 
     7457 * @param p_stat            Pointer to receive the stat. 
     7458 * 
     7459 * @return                  PJ_SUCCESS on success, or the appropriate error 
     7460 *                          code. 
     7461 */ 
     7462PJ_DECL(pj_status_t) pjsua_get_ec_stat(pjmedia_echo_stat *p_stat); 
     7463 
     7464 
     7465/** 
    74557466 * Check whether the sound device is currently active. The sound device 
    74567467 * may be inactive if the application has set the auto close feature to 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_aud.c

    r5979 r6140  
    22782278 
    22792279/* 
     2280 * Get echo canceller statistics. 
     2281 */ 
     2282PJ_DEF(pj_status_t) pjsua_get_ec_stat(pjmedia_echo_stat *p_stat) 
     2283{ 
     2284    if (pjsua_var.snd_port) { 
     2285        return pjmedia_snd_port_get_ec_stat(pjsua_var.snd_port, p_stat); 
     2286    } else { 
     2287        return PJ_ENOTFOUND; 
     2288    } 
     2289} 
     2290 
     2291 
     2292/* 
    22802293 * Check whether the sound device is currently active. 
    22812294 */ 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_dump.c

    r5729 r6140  
    370370        p += len; 
    371371 
     372        if (call_med->type == PJMEDIA_TYPE_AUDIO) { 
     373            if (pjsua_snd_is_active()) { 
     374                pjmedia_echo_stat stat; 
     375                pj_status_t status; 
     376                 
     377                status = pjsua_get_ec_stat(&stat); 
     378                if (status == PJ_SUCCESS) { 
     379                    len = pj_ansi_snprintf(p, end-p, "   %s  EC stat: %.*s\n", 
     380                                           indent, 
     381                                           (int)stat.stat_info.slen, 
     382                                           stat.stat_info.ptr); 
     383                    if (len < 1 || len >= end-p) { 
     384                        *p = '\0'; 
     385                        return; 
     386                    } 
     387                    p += len; 
     388                } 
     389            } 
     390        } 
     391 
    372392        /* Get and ICE SRTP status */ 
    373393        if (call_med->tp) { 
Note: See TracChangeset for help on using the changeset viewer.