Changeset 442


Ignore:
Timestamp:
May 14, 2006 6:23:34 PM (18 years ago)
Author:
bennylp
Message:

Fixed more bugs with multiple frame handling

Location:
pjproject/trunk
Files:
5 edited

Legend:

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

    r438 r442  
    112112 *                      delay that may be introduced by this jitter  
    113113 *                      buffer. 
     114 * @param ptime         Indication of frame duration, used to calculate  
     115 *                      the interval between jitter recalculation. 
    114116 * @param p_jb          Pointer to receive jitter buffer instance. 
    115117 * 
     
    119121                                         const pj_str_t *name, 
    120122                                         unsigned frame_size, 
     123                                         unsigned ptime, 
    121124                                         unsigned max_count, 
    122125                                         pjmedia_jbuf **p_jb); 
  • pjproject/trunk/pjmedia/src/pjmedia/conference.c

    r426 r442  
    10961096     * transmit NULL frame.  
    10971097     */ 
     1098    /* note: 
     1099     *  the "cport->sources==0" checking will cause discontinuous 
     1100     *  transmission for RTP stream. 
     1101     */ 
    10981102    if (cport->tx_setting == PJMEDIA_PORT_MUTE || cport->sources==0) { 
    10991103 
     
    11251129    buf = (pj_int16_t*)cport->mix_buf; 
    11261130 
    1127     if (cport->tx_adj_level != NORMAL_LEVEL) { 
     1131    if (cport->tx_adj_level != NORMAL_LEVEL && cport->sources) { 
    11281132 
    11291133        unsigned adj_level = cport->tx_adj_level; 
     
    11691173     * indication of the signal level of the port. 
    11701174     */ 
    1171     if (cport->need_tx_level) { 
     1175    if (cport->need_tx_level && cport->sources) { 
    11721176        pj_uint32_t level; 
    11731177 
  • pjproject/trunk/pjmedia/src/pjmedia/jbuf.c

    r438 r442  
    5151    jb_framelist    jb_framelist; 
    5252    pj_size_t       jb_frame_size;        // frame size  
     53    unsigned        jb_frame_ptime;       // frame duration. 
    5354    pj_size_t       jb_max_count;         // max frames in the jitter framelist->flist_buffer 
    5455 
     
    8182 
    8283 
     84/* Enabling this would log the jitter buffer state about once per  
     85 * second. 
     86 */ 
     87#if 0 
     88#  define TRACE__(args)     PJ_LOG(4,args) 
     89#else 
     90#  define TRACE__(args) 
     91#endif 
     92 
    8393 
    8494static pj_status_t jb_framelist_init( pj_pool_t *pool, 
     
    268278                                        const pj_str_t *name, 
    269279                                        unsigned frame_size,  
     280                                        unsigned ptime, 
    270281                                        unsigned max_count, 
    271282                                        pjmedia_jbuf **p_jb) 
     
    282293    pj_strdup_with_null(pool, &jb->name, name); 
    283294    jb->jb_frame_size    = frame_size; 
     295    jb->jb_frame_ptime   = ptime; 
    284296    jb->jb_last_seq_no   = -1; 
    285297    jb->jb_level         = 0; 
     
    368380static void jbuf_calculate_jitter(pjmedia_jbuf *jb) 
    369381{ 
    370     enum { STABLE_HISTORY_LIMIT = (100*2) }; 
     382    unsigned stable_history_limit; 
     383 
     384    stable_history_limit = 1000 / jb->jb_frame_ptime; 
    371385 
    372386    jb->jb_last_jitter = PJ_ABS(jb->jb_level-jb->jb_last_level); 
     
    377391    if (jb->jb_last_jitter < jb->jb_prefetch) { 
    378392        jb->jb_stable_hist += jb->jb_last_jitter; 
    379         if (jb->jb_stable_hist > STABLE_HISTORY_LIMIT) { 
     393        if (jb->jb_stable_hist > (int)stable_history_limit) { 
    380394            int seq_diff = (jb->jb_prefetch - jb->jb_max_hist_jitter)/3; 
    381395            if (seq_diff<1) seq_diff = 1; 
     
    388402            jb->jb_max_hist_jitter = 0; 
    389403 
    390             if (jb->jb_op_count >= STABLE_HISTORY_LIMIT*2 && 
     404            TRACE__((THIS_FILE,"jb updated(1), prefetch=%d, size=%d",  
     405                     jb->jb_prefetch, jb_framelist_size(&jb->jb_framelist))); 
     406 
     407            /* These code is used to shorten the delay in the jitter buffer. 
     408 
     409            if (jb->jb_op_count >= stable_history_limit*2 && 
    391410                (int)jb_framelist_size(&jb->jb_framelist) > jb->jb_prefetch+2) 
    392411            { 
     
    399418                jb->jb_op_count = 0; 
    400419            } 
     420            */ 
    401421 
    402422        } 
     
    409429        jb->jb_max_hist_jitter = 0; 
    410430 
    411         if (jb->jb_op_count >= STABLE_HISTORY_LIMIT * 2) { 
     431        TRACE__((THIS_FILE,"jb updated(2), prefetch=%d, size=%d",  
     432                 jb->jb_prefetch, jb_framelist_size(&jb->jb_framelist))); 
     433 
     434        /* These code is used to shorten the delay in the jitter buffer 
     435           when the current size is larger than the prefetch. But it does 
     436           not really work when the stream supports multiple frames, since 
     437           the size may grow only temporarily. 
     438 
     439        if (jb->jb_op_count >= stable_history_limit * 2) { 
    412440            if ((int)jb_framelist_size(&jb->jb_framelist) > jb->jb_prefetch+2)  
    413441            { 
     
    422450            jb->jb_op_count = 0; 
    423451        } 
     452        */ 
    424453    } 
    425454} 
  • pjproject/trunk/pjmedia/src/pjmedia/stream.c

    r440 r442  
    4141#define TRC_(expr)                      PJ_LOG(5,expr) 
    4242 
     43#define BYTES_PER_SAMPLE                2 
     44 
    4345/** 
    4446 * Media channel. 
     
    5557    void                   *out_pkt;        /**< Output buffer.             */ 
    5658    pjmedia_rtp_session     rtp;            /**< RTP session.               */ 
     59    char                    last_frm_type;  /**< Last frame type from jb    */ 
    5760}; 
    5861 
     
    153156    pjmedia_stream *stream = port->user_data; 
    154157    pjmedia_channel *channel = stream->dec; 
    155      
    156     pj_status_t status; 
    157158    unsigned samples_count, samples_per_frame, samples_required; 
    158159    pj_int16_t *p_out_samp; 
     160    pj_status_t status; 
     161 
    159162 
    160163    /* Return no frame is channel is paused */ 
     
    181184         samples_count += samples_per_frame)  
    182185    { 
    183          char frame_type; 
     186        char frame_type; 
    184187 
    185188        /* Get frame from jitter buffer. */ 
     
    199202                                                       frame_out.size, 
    200203                                                       &frame_out); 
     204 
    201205            } else { 
    202206                status = -1; 
     
    207211                pjmedia_zero_samples(p_out_samp + samples_count, 
    208212                                     samples_required - samples_count); 
     213                PJ_LOG(5,(stream->port.info.name.ptr,  "Frame lost!")); 
     214 
     215            } else { 
     216                PJ_LOG(5,(stream->port.info.name.ptr,  
     217                          "Lost frame recovered")); 
    209218            } 
    210219             
    211220        } else if (frame_type == PJMEDIA_JB_ZERO_EMPTY_FRAME) { 
    212221 
    213             /* Jitter buffer is empty, zero the remaining samples and break 
    214              * the loop. 
     222            /* Jitter buffer is empty. If this is the first "empty" state, 
     223             * activate PLC to smoothen the fade-out, otherwise zero 
     224             * the frame.  
    215225             */ 
    216             pjmedia_zero_samples(p_out_samp + samples_count, 
    217                                  samples_required - samples_count); 
     226            if (frame_type != channel->last_frm_type) { 
     227                pjmedia_jb_state jb_state; 
     228 
     229                /* Activate PLC to smoothen the missing frame */ 
     230                if (stream->codec->op->recover &&  
     231                    stream->codec_param.setting.plc)  
     232                { 
     233                    pjmedia_frame frame_out; 
     234 
     235                    do { 
     236                        frame_out.buf = p_out_samp + samples_count; 
     237                        frame_out.size = frame->size - samples_count*2; 
     238                        status = (*stream->codec->op->recover)(stream->codec, 
     239                                                               frame_out.size, 
     240                                                               &frame_out); 
     241                        if (status != PJ_SUCCESS) 
     242                            break; 
     243                        samples_count += samples_per_frame; 
     244 
     245                    } while (samples_count < samples_required); 
     246 
     247                }  
     248 
     249                /* Report the state of jitter buffer */ 
     250                pjmedia_jbuf_get_state(stream->jb, &jb_state); 
     251                PJ_LOG(5,(stream->port.info.name.ptr,  
     252                          "Jitter buffer empty (prefetch=%d)",  
     253                          jb_state.prefetch)); 
     254 
     255            } 
     256 
     257            if (samples_count < samples_required) { 
     258                pjmedia_zero_samples(p_out_samp + samples_count, 
     259                                     samples_required - samples_count); 
     260            } 
     261 
     262            channel->last_frm_type = frame_type; 
    218263            break; 
    219264 
    220265        } else if (frame_type != PJMEDIA_JB_NORMAL_FRAME) { 
     266 
     267            pjmedia_jb_state jb_state; 
    221268 
    222269            /* It can only be PJMEDIA_JB_ZERO_PREFETCH frame */ 
    223270            pj_assert(frame_type == PJMEDIA_JB_ZERO_PREFETCH_FRAME); 
    224271 
    225             /* Zero frame returned. We should zero the PCM buffer then.. */ 
    226             pjmedia_zero_samples(p_out_samp + samples_count,  
    227                                  samples_per_frame); 
     272            /* Get the state of jitter buffer */ 
     273            pjmedia_jbuf_get_state(stream->jb, &jb_state); 
     274 
     275            /* Always activate PLC when it's available.. */ 
     276            if (stream->codec->op->recover &&  
     277                stream->codec_param.setting.plc)  
     278            { 
     279                pjmedia_frame frame_out; 
     280 
     281                do { 
     282                    frame_out.buf = p_out_samp + samples_count; 
     283                    frame_out.size = frame->size - samples_count*2; 
     284                    status = (*stream->codec->op->recover)(stream->codec, 
     285                                                           frame_out.size, 
     286                                                           &frame_out); 
     287                    if (status != PJ_SUCCESS) 
     288                        break; 
     289                    samples_count += samples_per_frame; 
     290 
     291                } while (samples_count < samples_required); 
     292 
     293                PJ_LOG(5,(stream->port.info.name.ptr,  
     294                          "Jitter buffer is bufferring with plc (prefetch=%d)", 
     295                          jb_state.prefetch)); 
     296 
     297            }  
     298 
     299            if (samples_count < samples_required) { 
     300                pjmedia_zero_samples(p_out_samp + samples_count, 
     301                                     samples_required - samples_count); 
     302                PJ_LOG(5,(stream->port.info.name.ptr,  
     303                          "Jitter buffer is bufferring (prefetch=%d)..",  
     304                          jb_state.prefetch)); 
     305            } 
     306 
     307            channel->last_frm_type = frame_type; 
     308            break; 
    228309 
    229310        } else { 
     
    237318 
    238319            frame_out.buf = p_out_samp + samples_count; 
    239             frame_out.size = frame->size - samples_count*2; 
     320            frame_out.size = frame->size - samples_count*BYTES_PER_SAMPLE; 
    240321            status = stream->codec->op->decode( stream->codec, &frame_in, 
    241322                                                frame_out.size, &frame_out); 
     
    248329            } 
    249330        } 
     331 
     332        channel->last_frm_type = frame_type; 
    250333    } 
    251334 
     
    262345    } else { 
    263346        frame->type = PJMEDIA_FRAME_TYPE_AUDIO; 
    264         frame->size = samples_count * 2; 
     347        frame->size = samples_count * BYTES_PER_SAMPLE; 
    265348        frame->timestamp.u64 = 0; 
    266349    } 
     
    498581 
    499582    pj_memcpy(channel->out_pkt, rtphdr, sizeof(pjmedia_rtp_hdr)); 
     583 
    500584 
    501585    /* Send. */ 
     
    10301114        jb_max = info->jb_max; 
    10311115    else 
    1032         jb_max = 240 / (stream->port.info.samples_per_frame * 1000 /  
    1033                            info->fmt.clock_rate); 
     1116        jb_max = 360 / stream->codec_param.info.frm_ptime; 
    10341117 
    10351118    if (info->jb_min_pre >= 0) 
    10361119        jb_min_pre = info->jb_min_pre; 
    10371120    else 
    1038         jb_min_pre = 0; 
     1121        jb_min_pre = 60 / stream->codec_param.info.frm_ptime; 
    10391122 
    10401123    if (info->jb_max_pre > 0) 
    10411124        jb_max_pre = info->jb_max_pre; 
    10421125    else 
    1043         jb_max_pre = jb_max * 4 / 5; 
     1126        jb_max_pre = 240 / stream->codec_param.info.frm_ptime; 
    10441127 
    10451128    if (info->jb_init >= 0) 
    10461129        jb_init = info->jb_init; 
    10471130    else 
    1048         jb_init = jb_min_pre; 
     1131        jb_init = (jb_min_pre + jb_max_pre) / 2; 
    10491132 
    10501133 
     
    10521135    status = pjmedia_jbuf_create(pool, &stream->port.info.name, 
    10531136                                 stream->frame_size,  
     1137                                 stream->codec_param.info.frm_ptime, 
    10541138                                 jb_max, &stream->jb); 
    10551139    if (status != PJ_SUCCESS) 
  • pjproject/trunk/pjsip-apps/src/samples/siprtp_report.c

    r437 r442  
    6060 
    6161    /* Print duration */ 
    62     if (inv->state >= PJSIP_INV_STATE_CONFIRMED) { 
     62    if (inv->state >= PJSIP_INV_STATE_CONFIRMED && call->connect_time) { 
    6363 
    6464        PJ_TIME_VAL_SUB(now, call->connect_time); 
Note: See TracChangeset for help on using the changeset viewer.