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

Fixed more bugs with multiple frame handling

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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) 
Note: See TracChangeset for help on using the changeset viewer.