Changeset 457


Ignore:
Timestamp:
May 19, 2006 3:58:13 PM (18 years ago)
Author:
bennylp
Message:

Install VAD in g711, gsm, and speex, and add the DTX support in stream.c. Also changed the way the silence detector works, and changed default speex quality/complexity to 10

Location:
pjproject/trunk/pjmedia
Files:
8 edited

Legend:

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

    r355 r457  
    3737 
    3838/** 
     39 * Suggested or default threshold to be set for fixed silence detection 
     40 * or as starting threshold for adaptive silence detection. The threshold 
     41 * has the range from zero to 255. 
     42 */ 
     43#define PJMEDIA_SILENCE_DET_THRESHOLD   4 
     44 
     45 
     46/** 
    3947 * Create voice activity detector with default settings. The default settings 
    40  * are to perform adaptive silence detection, which adjusts the noise level 
    41  * dynamically based on current input level. 
     48 * are set to adaptive silence detection with the default threshold. 
    4249 * 
    43  * @param pool          Pool for allocating the structure. 
    44  * @param p_sd          Pointer to receive the silence detector instance. 
     50 * @param pool              Pool for allocating the structure. 
     51 * @param clock_rate        Clock rate. 
     52 * @param samples_per_frame Number of samples per frame. The clock_rate and 
     53 *                          samples_per_frame is only used to calculate the 
     54 *                          frame time, from which some timing parameters 
     55 *                          are calculated from. 
     56 * @param p_sd              Pointer to receive the silence detector instance. 
    4557 * 
    46  * @return              PJ_SUCCESS on success. 
     58 * @return                  PJ_SUCCESS on success. 
    4759 */ 
    4860PJ_DECL(pj_status_t) pjmedia_silence_det_create( pj_pool_t *pool, 
     61                                                 unsigned clock_rate, 
     62                                                 unsigned samples_per_frame, 
    4963                                                 pjmedia_silence_det **p_sd ); 
    5064 
    5165 
    5266/** 
    53  * Set the sd to operate in adaptive mode. 
    54  * 
    55  * @param sd            The silence detector 
    56  * @param frame_size    Number of samples per frame. 
    57  * 
    58  * @return              PJ_SUCCESS on success. 
    59  */ 
    60 PJ_DECL(pj_status_t) pjmedia_silence_det_set_adaptive( pjmedia_silence_det *sd, 
    61                                                        unsigned frame_size); 
    62  
    63  
    64 /** 
    65  * Set the sd to operate in fixed threshold mode. 
     67 * Set the sd to operate in fixed threshold mode. With fixed threshold mode, 
     68 * the threshold will not be changed adaptively. 
    6669 * 
    6770 * @param sd                The silence detector 
    68  * @param frame_size Number of samplse per frame. 
    69  * @param threshold         The silence threshold. 
     71 * @param threshold         The silence threshold, or -1 to use default 
     72 *                          threshold. 
    7073 * 
    7174 * @return                  PJ_SUCCESS on success. 
    7275 */ 
    7376PJ_DECL(pj_status_t) pjmedia_silence_det_set_fixed( pjmedia_silence_det *sd, 
    74                                                     unsigned frame_size, 
    75                                                     unsigned threshold ); 
     77                                                    int threshold ); 
     78 
     79/** 
     80 * Set the sd to operate in adaptive mode. This is the default mode 
     81 * when the silence detector is created. 
     82 * 
     83 * @param sd                The silence detector 
     84 * @param threshold         Initial threshold to be set, or -1 to use default 
     85 *                          threshold. 
     86 * 
     87 * @return                  PJ_SUCCESS on success. 
     88 */ 
     89PJ_DECL(pj_status_t) pjmedia_silence_det_set_adaptive(pjmedia_silence_det *sd, 
     90                                                      int threshold); 
     91 
     92/** 
     93 * Set other silence detector parameters. 
     94 * 
     95 * @param sd                The silence detector 
     96 * @param min_silence       Minimum duration of silence (in msec) before  
     97 *                          silence is reported. If -1 is specified, then 
     98 *                          the default value will be used. The default is 
     99 *                          400 msec. 
     100 * @param min_signal        Minimum duration of signal (in msec) before 
     101 *                          signal is reported. If -1 is specified, then 
     102 *                          the default value will be used. The default is 
     103 *                          one frame. 
     104 * @param recalc_time       The interval to recalculate signal and silence 
     105 *                          proportion and to readjust the silence threshold 
     106 *                          when adaptive silence detection is set. If -1 
     107 *                          is specified, then the default value will be used. 
     108 *                          The default value is 5000 (msec). 
     109 * 
     110 * @return                  PJ_SUCCESS on success. 
     111 */ 
     112PJ_DECL(pj_status_t) pjmedia_silence_det_set_params( pjmedia_silence_det *sd, 
     113                                                     int min_silence, 
     114                                                     int min_signal, 
     115                                                     int recalc_time); 
    76116 
    77117/** 
  • pjproject/trunk/pjmedia/src/pjmedia-codec/gsm.c

    r438 r457  
    2121#include <pjmedia/errno.h> 
    2222#include <pjmedia/endpoint.h> 
     23#include <pjmedia/plc.h> 
    2324#include <pjmedia/port.h> 
     25#include <pjmedia/silencedet.h> 
    2426#include <pj/assert.h> 
    2527#include <pj/pool.h> 
     
    6971                                      unsigned output_buf_len,  
    7072                                      struct pjmedia_frame *output); 
     73static pj_status_t  gsm_codec_recover(pjmedia_codec *codec, 
     74                                      unsigned output_buf_len, 
     75                                      struct pjmedia_frame *output); 
    7176 
    7277/* Definition for GSM codec operations. */ 
     
    7883    &gsm_codec_parse, 
    7984    &gsm_codec_encode, 
    80     &gsm_codec_decode 
     85    &gsm_codec_decode, 
     86    &gsm_codec_recover 
    8187}; 
    8288 
     
    101107} gsm_codec_factory; 
    102108 
     109 
    103110/* GSM codec private data. */ 
    104111struct gsm_data 
    105112{ 
    106     void    *encoder; 
    107     void    *decoder; 
     113    void                *encoder; 
     114    void                *decoder; 
     115    pj_bool_t            plc_enabled; 
     116    pjmedia_plc         *plc; 
     117    pj_bool_t            vad_enabled; 
     118    pjmedia_silence_det *vad; 
    108119}; 
    109120 
     
    240251 
    241252    attr->setting.frm_per_pkt = 1; 
    242  
    243     /* Default all flag bits disabled. */ 
     253    attr->setting.vad = 1; 
     254    attr->setting.plc = 1; 
     255 
     256    /* Default all other flag bits disabled. */ 
    244257 
    245258    return PJ_SUCCESS; 
     
    277290    pjmedia_codec *codec; 
    278291    struct gsm_data *gsm_data; 
     292    pj_status_t status; 
    279293 
    280294    PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL); 
     
    298312                                  sizeof(struct gsm_data)); 
    299313        codec->codec_data = gsm_data; 
     314 
     315        /* Create PLC */ 
     316        status = pjmedia_plc_create(gsm_codec_factory.pool, 8000,  
     317                                    160, 0, &gsm_data->plc); 
     318        if (status != PJ_SUCCESS) { 
     319            pj_mutex_unlock(gsm_codec_factory.mutex); 
     320            return status; 
     321        } 
     322 
     323        /* Create silence detector */ 
     324        status = pjmedia_silence_det_create(gsm_codec_factory.pool, 
     325                                            8000, 160, 
     326                                            &gsm_data->vad); 
     327        if (status != PJ_SUCCESS) { 
     328            pj_mutex_unlock(gsm_codec_factory.mutex); 
     329            return status; 
     330        } 
    300331    } 
    301332 
     
    361392    if (!gsm_data->decoder) 
    362393        return PJMEDIA_CODEC_EFAILED; 
     394 
     395    gsm_data->vad_enabled = (attr->setting.vad != 0); 
     396    gsm_data->plc_enabled = (attr->setting.plc != 0); 
    363397 
    364398    return PJ_SUCCESS; 
     
    438472        return PJMEDIA_CODEC_EPCMTOOSHORT; 
    439473 
     474    /* Detect silence */ 
     475    if (gsm_data->vad_enabled) { 
     476        pj_bool_t is_silence; 
     477 
     478        is_silence = pjmedia_silence_det_detect(gsm_data->vad,  
     479                                                input->buf, 
     480                                                input->size / 2, 
     481                                                NULL); 
     482        if (is_silence) { 
     483            output->type = PJMEDIA_FRAME_TYPE_NONE; 
     484            output->buf = NULL; 
     485            output->size = 0; 
     486            output->timestamp.u64 = input->timestamp.u64; 
     487            return PJ_SUCCESS; 
     488        } 
     489    } 
     490 
     491    /* Encode */ 
    440492    gsm_encode(gsm_data->encoder, (short*)input->buf,  
    441493               (unsigned char*)output->buf); 
     
    473525    output->type = PJMEDIA_FRAME_TYPE_AUDIO; 
    474526 
     527    if (gsm_data->plc_enabled) 
     528        pjmedia_plc_save( gsm_data->plc, output->buf); 
     529 
     530    return PJ_SUCCESS; 
     531} 
     532 
     533 
     534/* 
     535 * Recover lost frame. 
     536 */ 
     537static pj_status_t  gsm_codec_recover(pjmedia_codec *codec, 
     538                                      unsigned output_buf_len, 
     539                                      struct pjmedia_frame *output) 
     540{ 
     541    struct gsm_data *gsm_data = codec->codec_data; 
     542 
     543    PJ_ASSERT_RETURN(gsm_data->plc_enabled, PJ_EINVALIDOP); 
     544 
     545    PJ_ASSERT_RETURN(output_buf_len >= 320, PJMEDIA_CODEC_EPCMTOOSHORT); 
     546 
     547    pjmedia_plc_generate(gsm_data->plc, output->buf); 
     548    output->size = 320; 
     549 
    475550    return PJ_SUCCESS; 
    476551} 
  • pjproject/trunk/pjmedia/src/pjmedia-codec/speex_codec.c

    r438 r457  
    3838#define THIS_FILE   "speex_codec.c" 
    3939 
    40 #define DEFAULT_QUALITY     4 
    41 #define DEFAULT_COMPLEXITY  -1 
     40#define DEFAULT_QUALITY     10 
     41#define DEFAULT_COMPLEXITY  10 
    4242 
    4343/* Prototypes for Speex factory */ 
     
    256256 
    257257    /* Somehow quality <=4 is broken in linux. */ 
    258     if (quality <= 4) { 
    259         PJ_LOG(4,(THIS_FILE, "Adjusting quality to 5 for uwb")); 
     258    if (quality <= 4 && quality >= 0) { 
     259        PJ_LOG(5,(THIS_FILE, "Adjusting quality to 5 for uwb")); 
    260260        spx_factory.speex_param[PARAM_UWB].quality = 5; 
    261261    } 
     
    412412    attr->setting.lpf =1 ; 
    413413    attr->setting.penh =1 ; 
    414  
    415     /* Default, set VAD off as it caused voice chip off */ 
    416     attr->setting.vad = 0; 
     414    attr->setting.vad = 1; 
    417415 
    418416    return PJ_SUCCESS; 
     
    572570 
    573571    /* VAD */ 
    574     tmp = attr->setting.vad; 
     572    tmp = (attr->setting.vad != 0); 
    575573    speex_encoder_ctl(spx->enc, SPEEX_SET_VAD, &tmp); 
     574    speex_encoder_ctl(spx->enc, SPEEX_SET_DTX, &tmp); 
    576575 
    577576    /* Complexity */ 
     
    688687    pj_int16_t *samp_in; 
    689688    unsigned i, samp_count, sz; 
     689    int tx; 
    690690 
    691691    spx = (struct spx_private*) codec->codec_data; 
     
    711711 
    712712    /* Encode the frame */ 
    713     speex_encode(spx->enc, tmp, &spx->enc_bits); 
     713    tx = speex_encode(spx->enc, tmp, &spx->enc_bits); 
     714 
     715    /* Check if we need not to transmit the frame (DTX) */ 
     716    if (tx == 0) { 
     717        output->buf = NULL; 
     718        output->size = 0; 
     719        output->timestamp.u64 = input->timestamp.u64; 
     720        output->type = PJMEDIA_FRAME_TYPE_NONE; 
     721        return PJ_SUCCESS; 
     722    } 
    714723 
    715724    /* Check size. */ 
  • pjproject/trunk/pjmedia/src/pjmedia/conference.c

    r442 r457  
    229229 
    230230    /* Create and init vad. */ 
    231     status = pjmedia_silence_det_create( pool, &conf_port->vad); 
     231    status = pjmedia_silence_det_create( pool,  
     232                                         port->info.clock_rate, 
     233                                         port->info.samples_per_frame, 
     234                                         &conf_port->vad); 
    232235    if (status != PJ_SUCCESS) 
    233236        return status; 
    234237 
    235     pjmedia_silence_det_set_adaptive(conf_port->vad, conf->samples_per_frame); 
     238    pjmedia_silence_det_set_fixed(conf_port->vad, 2); 
    236239 
    237240    /* Save some port's infos, for convenience. */ 
  • pjproject/trunk/pjmedia/src/pjmedia/g711.c

    r438 r457  
    2525#include <pjmedia/port.h> 
    2626#include <pjmedia/plc.h> 
     27#include <pjmedia/silencedet.h> 
    2728#include <pj/pool.h> 
    2829#include <pj/string.h> 
     
    122123struct g711_private 
    123124{ 
    124     unsigned        pt; 
    125     pj_bool_t       plc_enabled; 
    126     pjmedia_plc    *plc; 
     125    unsigned             pt; 
     126    pj_bool_t            plc_enabled; 
     127    pjmedia_plc         *plc; 
     128    pj_bool_t            vad_enabled; 
     129    pjmedia_silence_det *vad; 
    127130}; 
    128131 
     
    251254    attr->setting.plc = 1; 
    252255 
    253     /* Default all flag bits disabled. */ 
     256    /* Enable VAD by default. */ 
     257    attr->setting.vad = 1; 
     258 
     259    /* Default all other flag bits disabled. */ 
    254260 
    255261    return PJ_SUCCESS; 
     
    303309 
    304310        codec = pj_pool_alloc(g711_factory.pool, sizeof(pjmedia_codec)); 
    305         codec_priv = pj_pool_alloc(g711_factory.pool,  
    306                                    sizeof(struct g711_private)); 
     311        codec_priv = pj_pool_zalloc(g711_factory.pool,  
     312                                    sizeof(struct g711_private)); 
    307313        if (!codec || !codec_priv) { 
    308314            pj_mutex_unlock(g711_factory.mutex); 
     
    321327        } 
    322328 
     329        /* Create VAD */ 
     330        status = pjmedia_silence_det_create(g711_factory.pool, 
     331                                            8000, 80, 
     332                                            &codec_priv->vad); 
     333        if (status != PJ_SUCCESS) { 
     334            pj_mutex_unlock(g711_factory.mutex); 
     335            return status; 
     336        } 
     337 
    323338        codec->factory = factory; 
    324339        codec->op = &g711_op; 
     
    379394    priv->pt = attr->info.pt; 
    380395    priv->plc_enabled = (attr->setting.plc != 0); 
     396    priv->vad_enabled = (attr->setting.vad != 0); 
    381397    return PJ_SUCCESS; 
    382398} 
     
    429445    if (output_buf_len < input->size / 2) 
    430446        return PJMEDIA_CODEC_EFRMTOOSHORT; 
     447 
     448    /* Detect silence if VAD is enabled */ 
     449    if (priv->vad_enabled) { 
     450        pj_bool_t is_silence; 
     451 
     452        is_silence = pjmedia_silence_det_detect(priv->vad, input->buf,  
     453                                                input->size / 2, NULL); 
     454        if (is_silence) { 
     455            output->type = PJMEDIA_FRAME_TYPE_NONE; 
     456            output->buf = NULL; 
     457            output->size = 0; 
     458            output->timestamp.u64 = input->timestamp.u64; 
     459            return PJ_SUCCESS; 
     460        } 
     461    } 
    431462 
    432463    /* Encode */ 
  • pjproject/trunk/pjmedia/src/pjmedia/silencedet.c

    r229 r457  
    3333 
    3434 
     35 
    3536/** 
    3637 * This structure holds the silence detector state. 
     
    3940{ 
    4041    int       mode;             /**< VAD mode.                              */ 
    41     unsigned  frame_size;       /**< Samples per frame.                     */ 
    42  
     42    unsigned  ptime;            /**< Frame time, in msec.                   */ 
    4343 
    4444    unsigned  min_signal_cnt;   /**< # of signal frames.before talk burst   */ 
     
    6161 
    6262PJ_DEF(pj_status_t) pjmedia_silence_det_create( pj_pool_t *pool, 
     63                                                unsigned clock_rate, 
     64                                                unsigned samples_per_frame, 
    6365                                                pjmedia_silence_det **p_sd) 
    6466{ 
     
    6971    sd = pj_pool_zalloc(pool, sizeof(struct pjmedia_silence_det)); 
    7072 
     73    sd->ptime = samples_per_frame * 1000 / clock_rate; 
     74    sd->signal_cnt = 0; 
     75    sd->silence_cnt = 0; 
    7176    sd->weakest_signal = 0xFFFFFFFFUL; 
    7277    sd->loudest_silence = 0; 
    73     sd->signal_cnt = 0; 
    74     sd->silence_cnt = 0; 
    75      
    76     /* Restart in adaptive, silent mode */ 
     78      
     79    /* Default settings */ 
     80    pjmedia_silence_det_set_params(sd, -1, -1, -1); 
     81 
     82    /* Restart in fixed, silent mode */ 
    7783    sd->in_talk = PJ_FALSE; 
    78     pjmedia_silence_det_set_adaptive( sd, 160 ); 
     84    pjmedia_silence_det_set_adaptive( sd, -1 ); 
    7985 
    8086    *p_sd = sd; 
     
    8288} 
    8389 
    84 PJ_DEF(pj_status_t) pjmedia_silence_det_set_adaptive( pjmedia_silence_det *sd, 
    85                                                       unsigned frame_size) 
    86 { 
    87     PJ_ASSERT_RETURN(sd && frame_size, PJ_EINVAL); 
    88  
    89     sd->frame_size = frame_size; 
     90PJ_DEF(pj_status_t) pjmedia_silence_det_set_adaptive(pjmedia_silence_det *sd, 
     91                                                     int threshold) 
     92{ 
     93    PJ_ASSERT_RETURN(sd, PJ_EINVAL); 
     94 
     95    if (threshold < 0) 
     96        threshold = PJMEDIA_SILENCE_DET_THRESHOLD; 
     97 
    9098    sd->mode = VAD_MODE_ADAPTIVE; 
    91     sd->min_signal_cnt = 10; 
    92     sd->min_silence_cnt = 64; 
    93     sd->recalc_cnt = 250; 
    94     sd->cur_threshold = 20; 
     99    sd->cur_threshold = threshold; 
    95100 
    96101    return PJ_SUCCESS; 
     
    98103 
    99104PJ_DEF(pj_status_t) pjmedia_silence_det_set_fixed( pjmedia_silence_det *sd, 
    100                                                    unsigned frame_size, 
    101                                                    unsigned threshold ) 
    102 { 
    103     PJ_ASSERT_RETURN(sd && frame_size, PJ_EINVAL); 
     105                                                   int threshold ) 
     106{ 
     107    PJ_ASSERT_RETURN(sd, PJ_EINVAL); 
     108 
     109    if (threshold < 0) 
     110        threshold = PJMEDIA_SILENCE_DET_THRESHOLD; 
    104111 
    105112    sd->mode = VAD_MODE_FIXED; 
    106     sd->frame_size = frame_size; 
    107113    sd->cur_threshold = threshold; 
    108114 
    109115    return PJ_SUCCESS; 
    110116} 
     117 
     118PJ_DEF(pj_status_t) pjmedia_silence_det_set_params( pjmedia_silence_det *sd, 
     119                                                    int min_silence, 
     120                                                    int min_signal, 
     121                                                    int recalc_time) 
     122{ 
     123    PJ_ASSERT_RETURN(sd, PJ_EINVAL); 
     124 
     125    if (min_silence == -1) 
     126        min_silence = 500; 
     127    if (min_signal < 0) 
     128        min_signal = sd->ptime; 
     129    if (recalc_time < 0) 
     130        recalc_time = 5000; 
     131 
     132    sd->min_signal_cnt = min_signal / sd->ptime; 
     133    sd->min_silence_cnt = min_silence / sd->ptime; 
     134    sd->recalc_cnt = recalc_time / sd->ptime; 
     135 
     136    return PJ_SUCCESS; 
     137} 
     138 
    111139 
    112140PJ_DEF(pj_status_t) pjmedia_silence_det_disable( pjmedia_silence_det *sd ) 
     
    185213    } 
    186214     
    187     /* For fixed threshold sd, everything is done. */ 
    188     if (sd->mode == VAD_MODE_FIXED) { 
    189         return !sd->in_talk; 
    190     } 
    191      
    192215 
    193216    /* Count the number of silent and signal frames and calculate min/max */ 
     
    208231    if ((sd->signal_cnt + sd->silence_cnt) > sd->recalc_cnt) { 
    209232         
    210         /* Adjust silence threshold by looking at the proportions of 
    211          * signal and silence frames. 
    212          */ 
    213         if (sd->signal_cnt >= sd->recalc_cnt) { 
    214             /* All frames where signal frames. 
    215              * Increase silence threshold. 
    216              */ 
    217             sd->cur_threshold += (sd->weakest_signal - sd->cur_threshold)/4; 
    218             PJ_LOG(6,(THIS_FILE, "Vad cur_threshold increased to %d", 
    219                       sd->cur_threshold)); 
    220         } 
    221         else if (sd->silence_cnt >= sd->recalc_cnt) { 
    222             /* All frames where silence frames. 
    223              * Decrease silence threshold. 
    224              */ 
    225             sd->cur_threshold = (sd->cur_threshold+sd->loudest_silence)/2+1; 
    226             PJ_LOG(6,(THIS_FILE, "Vad cur_threshold decreased to %d", 
    227                       sd->cur_threshold)); 
    228         } 
    229         else {  
     233        if (sd->mode == VAD_MODE_ADAPTIVE) { 
    230234            pj_bool_t updated = PJ_TRUE; 
     235            unsigned pct_signal; 
     236 
     237            /* Get percentage of signal */ 
     238            pct_signal = sd->signal_cnt * 100 /  
     239                        (sd->signal_cnt + sd->silence_cnt); 
    231240 
    232241            /* Adjust according to signal/silence proportions. */ 
    233             if (sd->signal_cnt > sd->silence_cnt * 2) 
     242            if (pct_signal > 95) { 
     243                sd->cur_threshold += (sd->weakest_signal - sd->cur_threshold)/4; 
     244            } else if (pct_signal < 5) { 
     245                sd->cur_threshold = (sd->cur_threshold+sd->loudest_silence)/2+1; 
     246            } else if (pct_signal > 90) { 
    234247                sd->cur_threshold++; 
    235             else if (sd->silence_cnt >  sd->signal_cnt* 2) 
     248            } else if (pct_signal < 10) { 
    236249                sd->cur_threshold--; 
    237             else 
     250            } else { 
    238251                updated = PJ_FALSE; 
     252            } 
    239253 
    240254            if (updated) { 
    241                 PJ_LOG(6,(THIS_FILE, 
    242                           "Vad cur_threshold updated to %d", 
     255                PJ_LOG(5,(THIS_FILE, "Vad cur_threshold updated to %d", 
    243256                          sd->cur_threshold)); 
    244257            } 
  • pjproject/trunk/pjmedia/src/pjmedia/stream.c

    r452 r457  
    5757    void                   *out_pkt;        /**< Output buffer.             */ 
    5858    pjmedia_rtp_session     rtp;            /**< RTP session.               */ 
    59     char                    last_frm_type;  /**< Last frame type from jb    */ 
    6059}; 
    6160 
     
    9190    pjmedia_codec_param      codec_param;   /**< Codec param.               */ 
    9291    unsigned                 frame_size;    /**< Size of encoded base frame.*/ 
     92    pj_bool_t                is_streaming;  /**< Currently streaming?. This 
     93                                                 is used to put RTP marker 
     94                                                 bit.                       */ 
     95 
    9396    pj_mutex_t              *jb_mutex; 
    9497    pjmedia_jbuf            *jb;            /**< Jitter buffer.             */ 
     98    char                     jb_last_frm;   /**< Last frame type from jb    */ 
    9599 
    96100    pjmedia_rtcp_session     rtcp;          /**< RTCP for incoming RTP.     */ 
     
    210214             * the frame.  
    211215             */ 
    212             if (frame_type != channel->last_frm_type) { 
     216            if (frame_type != stream->jb_last_frm) { 
    213217                pjmedia_jb_state jb_state; 
    214218 
     
    244248                pjmedia_zero_samples(p_out_samp + samples_count, 
    245249                                     samples_required - samples_count); 
     250                samples_count = samples_required; 
    246251            } 
    247252 
    248             channel->last_frm_type = frame_type; 
     253            stream->jb_last_frm = frame_type; 
    249254            break; 
    250255 
     
    277282                } while (samples_count < samples_required); 
    278283 
    279                 if (channel->last_frm_type != frame_type) { 
     284                if (stream->jb_last_frm != frame_type) { 
    280285                    PJ_LOG(5,(stream->port.info.name.ptr,  
    281286                              "Jitter buffer is bufferring with plc (prefetch=%d)", 
     
    288293                pjmedia_zero_samples(p_out_samp + samples_count, 
    289294                                     samples_required - samples_count); 
     295                samples_count = samples_required; 
    290296                PJ_LOG(5,(stream->port.info.name.ptr,  
    291297                          "Jitter buffer is bufferring (prefetch=%d)..",  
     
    293299            } 
    294300 
    295             channel->last_frm_type = frame_type; 
     301            stream->jb_last_frm = frame_type; 
    296302            break; 
    297303 
     
    318324        } 
    319325 
    320         channel->last_frm_type = frame_type; 
     326        stream->jb_last_frm = frame_type; 
    321327    } 
    322328 
     
    438444    struct pjmedia_frame frame_out; 
    439445    unsigned ts_len; 
    440     pj_bool_t has_tx; 
    441446    void *rtphdr; 
    442447    int rtphdrlen; 
    443     pj_ssize_t sent; 
    444448 
    445449 
     
    454458    /* Init frame_out buffer. */ 
    455459    frame_out.buf = ((char*)channel->out_pkt) + sizeof(pjmedia_rtp_hdr); 
    456  
    457     /* Make compiler happy */ 
    458460    frame_out.size = 0; 
     461 
    459462 
    460463    /* If we have DTMF digits in the queue, transmit the digits.  
     
    463466    if (stream->tx_dtmf_count) { 
    464467 
    465         has_tx = PJ_TRUE; 
    466468        create_dtmf_payload(stream, &frame_out); 
    467469 
     
    475477    } else if (frame->type != PJMEDIA_FRAME_TYPE_NONE) { 
    476478        unsigned ts, samples_per_frame; 
    477  
    478         has_tx = PJ_TRUE; 
    479479 
    480480        /* Repeatedly call encode if there are multiple frames to be 
     
    490490            unsigned bytes_per_sample, max_size; 
    491491 
     492            /* Nb of bytes in PCM sample */ 
    492493            bytes_per_sample = stream->codec_param.info.pcm_bits_per_sample/8; 
    493494 
     495            /* Split original PCM input frame into base frame size */ 
    494496            tmp_in_frame.buf = ((char*)frame->buf) + ts * bytes_per_sample; 
    495497            tmp_in_frame.size = samples_per_frame * bytes_per_sample; 
    496498            tmp_in_frame.type = PJMEDIA_FRAME_TYPE_AUDIO; 
    497499 
     500            /* Set output frame position */ 
    498501            tmp_out_frame.buf = ((char*)frame_out.buf) + frame_out.size; 
    499502 
     
    501504                       frame_out.size; 
    502505 
     506            /* Encode! */ 
    503507            status = stream->codec->op->encode( stream->codec, &tmp_in_frame,  
    504508                                                max_size, &tmp_out_frame); 
     
    509513            } 
    510514 
     515            /* tmp_out_frame.size may be zero for silence frame. */ 
    511516            frame_out.size += tmp_out_frame.size; 
     517 
     518            /* Stop processing next PCM frame when encode() returns either  
     519             * CNG frame or NULL frame. 
     520             */ 
     521            if (tmp_out_frame.type!=PJMEDIA_FRAME_TYPE_AUDIO ||  
     522                tmp_out_frame.size==0)  
     523            { 
     524                break; 
     525            } 
     526 
    512527        } 
    513  
    514         //printf("p"); fflush(stdout); 
    515528 
    516529        /* Encapsulate. */ 
     
    523536 
    524537        /* Just update RTP session's timestamp. */ 
    525         has_tx = PJ_FALSE; 
    526538        status = pjmedia_rtp_encode_rtp( &channel->rtp,  
    527539                                         0, 0,  
     
    547559 
    548560    /* Do nothing if we have nothing to transmit */ 
    549     if (!has_tx) 
     561    if (frame_out.size == 0) { 
     562        if (stream->is_streaming) { 
     563            PJ_LOG(5,(stream->port.info.name.ptr,"Starting silence")); 
     564            stream->is_streaming = PJ_FALSE; 
     565        } 
    550566        return PJ_SUCCESS; 
    551  
    552     if (rtphdrlen != sizeof(pjmedia_rtp_hdr)) { 
    553         /* We don't support RTP with extended header yet. */ 
    554         PJ_TODO(SUPPORT_SENDING_RTP_WITH_EXTENDED_HEADER); 
    555         return PJ_SUCCESS; 
    556     } 
    557  
     567    } 
     568 
     569 
     570    /* Copy RTP header to the beginning of packet */ 
    558571    pj_memcpy(channel->out_pkt, rtphdr, sizeof(pjmedia_rtp_hdr)); 
    559572 
    560573 
    561     /* Send. */ 
    562     sent = frame_out.size+sizeof(pjmedia_rtp_hdr); 
    563  
     574    /* Set RTP marker bit if currently not streaming */ 
     575    if (stream->is_streaming == PJ_FALSE) { 
     576        pjmedia_rtp_hdr *rtp = channel->out_pkt; 
     577 
     578        rtp->m = 1; 
     579        PJ_LOG(5,(stream->port.info.name.ptr,"Start talksprut..")); 
     580    } 
     581 
     582    stream->is_streaming = PJ_TRUE; 
     583 
     584    /* Send the RTP packet to the transport. */ 
    564585    (*stream->transport->op->send_rtp)(stream->transport, 
    565                                        channel->out_pkt, sent); 
     586                                       channel->out_pkt,  
     587                                       frame_out.size +  
     588                                            sizeof(pjmedia_rtp_hdr)); 
    566589 
    567590 
  • pjproject/trunk/pjmedia/src/pjmedia/transport_udp.c

    r452 r457  
    398398    PJ_ASSERT_RETURN(tp && strm && rem_addr && addr_len, PJ_EINVAL); 
    399399 
    400     /* Remote address must be Internet address */ 
    401     PJ_ASSERT_RETURN(addr_len == sizeof(pj_sockaddr_in) && 
    402                      ((pj_sockaddr_in*)rem_addr)->sin_family == PJ_AF_INET, 
    403                      PJ_EINVAL); 
    404  
    405400    /* Must not be "attached" to existing stream */ 
    406401    PJ_ASSERT_RETURN(udp->stream == NULL, PJ_EINVALIDOP); 
Note: See TracChangeset for help on using the changeset viewer.