Ignore:
Timestamp:
Aug 1, 2009 9:20:59 AM (15 years ago)
Author:
bennylp
Message:

Initial commit for ticket #929: Improve packet lost concealment (PLC) when handling burst of lost packets

WSOLA improvements:

  • Introduce fade-out and fade-in effect
  • Limit the number of continuous synthetic samples (only take effect when fading is used)
  • Export many settings as macros:
    • PJMEDIA_WSOLA_DELAY_MSEC (was HANNING_PTIME)
    • PJMEDIA_WSOLA_TEMPLATE_LENGTH_MSEC (was TEMPLATE_PTIME)
    • PJMEDIA_WSOLA_MAX_EXPAND_MSEC

PLC:

  • added compile time macro PJMEDIA_WSOLA_PLC_NO_FADING to disable fading (default enabled)

Stream:

  • fixed bug when stream is not PLC-ing subsequent packet loss (only the first)
  • also add maximum PLC limit just as precaution if PLC doesn't limit number of synthetic frames
  • unrelated: fixed warning about unused send_keep_alive() function

Delaybuf:

  • modified to NOT use fading in WSOLA since we don't expect it to generate many continuous synthetic frames
File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/stream.c

    r2844 r2850  
    4444#define BYTES_PER_SAMPLE                2 
    4545 
     46/* Limit the number of synthetic audio samples that are generated by PLC. 
     47 * Normally PLC should have it's own means to limit the number of 
     48 * synthetic frames, so we need to set this to a reasonably large value 
     49 * just as precaution 
     50 */ 
     51#define MAX_PLC_MSEC                    240 
     52 
    4653/** 
    4754 * Media channel. 
     
    99106    unsigned                 enc_buf_count; /**< Number of samples in the 
    100107                                                 encoding buffer.           */ 
     108 
     109    unsigned                 plc_cnt;       /**< # of consecutive PLC frames*/ 
     110    unsigned                 max_plc_cnt;   /**< Max # of PLC frames        */ 
    101111 
    102112    unsigned                 vad_enabled;   /**< VAD enabled in param.      */ 
     
    198208} 
    199209 
     210#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA != 0 
    200211/* 
    201  * Send keep-alive packet. 
     212 * Send keep-alive packet using non-codec frame. 
    202213 */ 
    203214static void send_keep_alive_packet(pjmedia_stream *stream) 
    204215{ 
    205 #if defined(PJMEDIA_STREAM_ENABLE_KA) && \ 
    206     PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_EMPTY_RTP 
     216#if PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_EMPTY_RTP 
    207217 
    208218    /* Keep-alive packet is empty RTP */ 
     
    225235    TRC_((stream->port.info.name.ptr, "Keep-alive sent (empty RTP)")); 
    226236 
    227 #elif defined(PJMEDIA_STREAM_ENABLE_KA) && \ 
    228       PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_USER 
     237#elif PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_USER 
    229238 
    230239    /* Keep-alive packet is defined in PJMEDIA_STREAM_KA_USER_PKT */ 
     
    244253#endif 
    245254} 
     255#endif  /* defined(PJMEDIA_STREAM_ENABLE_KA) */ 
    246256 
    247257/* 
     
    295305            /* Activate PLC */ 
    296306            if (stream->codec->op->recover &&  
    297                 stream->codec_param.setting.plc)  
     307                stream->codec_param.setting.plc && 
     308                stream->plc_cnt < stream->max_plc_cnt)  
    298309            { 
    299310                pjmedia_frame frame_out; 
     
    305316                                                       &frame_out); 
    306317 
     318                ++stream->plc_cnt; 
     319 
    307320            } else { 
    308321                status = -1; 
     
    319332                          "Lost frame recovered")); 
    320333            } 
    321              
     334 
    322335        } else if (frame_type == PJMEDIA_JB_ZERO_EMPTY_FRAME) { 
    323336 
     
    326339             * the frame.  
    327340             */ 
    328             if (frame_type != stream->jb_last_frm) { 
     341            //Using this "if" will only invoke PLC for the first packet 
     342            //lost and not the subsequent ones. 
     343            //if (frame_type != stream->jb_last_frm) { 
     344            if (1) { 
    329345                pjmedia_jb_state jb_state; 
    330346                const char *with_plc = ""; 
     
    332348                /* Activate PLC to smoothen the missing frame */ 
    333349                if (stream->codec->op->recover &&  
    334                     stream->codec_param.setting.plc)  
     350                    stream->codec_param.setting.plc && 
     351                    stream->plc_cnt < stream->max_plc_cnt)  
    335352                { 
    336353                    pjmedia_frame frame_out; 
     
    344361                        if (status != PJ_SUCCESS) 
    345362                            break; 
     363 
    346364                        samples_count += samples_per_frame; 
    347  
    348                     } while (samples_count < samples_required); 
     365                        ++stream->plc_cnt; 
     366 
     367                    } while (samples_count < samples_required && 
     368                             stream->plc_cnt < stream->max_plc_cnt); 
    349369 
    350370                    with_plc = ", plc invoked"; 
     
    380400            /* Always activate PLC when it's available.. */ 
    381401            if (stream->codec->op->recover &&  
    382                 stream->codec_param.setting.plc)  
     402                stream->codec_param.setting.plc && 
     403                stream->plc_cnt < stream->max_plc_cnt)  
    383404            { 
    384405                pjmedia_frame frame_out; 
     
    394415                    samples_count += samples_per_frame; 
    395416 
    396                 } while (samples_count < samples_required); 
    397  
    398                 if (stream->jb_last_frm != frame_type) { 
     417                    ++stream->plc_cnt; 
     418 
     419                } while (samples_count < samples_required && 
     420                         stream->plc_cnt < stream->max_plc_cnt); 
     421 
     422                //if (stream->jb_last_frm != frame_type) { 
     423                if (1) { 
    399424                    PJ_LOG(5,(stream->port.info.name.ptr,  
    400425                              "Jitter buffer is bufferring with plc (prefetch=%d)", 
     
    419444            /* Got "NORMAL" frame from jitter buffer */ 
    420445            pjmedia_frame frame_in, frame_out; 
     446 
     447            stream->plc_cnt = 0; 
    421448 
    422449            /* Decode */ 
     
    18221849        ++stream->frame_size; 
    18231850    } 
     1851 
     1852    /* How many consecutive PLC frames can be generated */ 
     1853    stream->max_plc_cnt = (MAX_PLC_MSEC+stream->codec_param.info.frm_ptime-1)/ 
     1854                            stream->codec_param.info.frm_ptime; 
    18241855 
    18251856#if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0) 
Note: See TracChangeset for help on using the changeset viewer.