Ignore:
Timestamp:
Feb 12, 2018 6:18:22 AM (3 years ago)
Author:
ming
Message:

Fixed #2089: Support receiving Opus packets with various frame lengths

File:
1 edited

Legend:

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

    r5671 r5734  
    135135    unsigned                 enc_buf_count; /**< Number of samples in the 
    136136                                                 encoding buffer.           */ 
     137 
     138    pj_int16_t              *dec_buf;       /**< Decoding buffer.           */ 
     139    unsigned                 dec_buf_size;  /**< Decoding buffer size, in 
     140                                                 samples.                   */ 
     141    unsigned                 dec_buf_pos;   /**< First position in buf.     */ 
     142    unsigned                 dec_buf_count; /**< Number of samples in the 
     143                                                 decoding buffer.           */ 
     144 
     145    pj_uint16_t              dec_ptime;     /**< Decoder frame ptime in ms. */ 
     146    pj_bool_t                detect_ptime_change; 
     147                                            /**< Detect decode ptime change */ 
    137148 
    138149    unsigned                 plc_cnt;       /**< # of consecutive PLC frames*/ 
     
    500511 
    501512    samples_required = PJMEDIA_PIA_SPF(&stream->port.info); 
    502     samples_per_frame = stream->codec_param.info.frm_ptime * 
     513    samples_per_frame = stream->dec_ptime * 
    503514                        stream->codec_param.info.clock_rate * 
    504515                        stream->codec_param.info.channel_cnt / 
     
    506517    p_out_samp = (pj_int16_t*) frame->buf; 
    507518 
    508     for (samples_count=0; samples_count < samples_required; 
    509          samples_count += samples_per_frame) 
    510     { 
     519    for (samples_count=0; samples_count < samples_required;) { 
    511520        char frame_type; 
    512521        pj_size_t frame_size; 
    513522        pj_uint32_t bit_info; 
     523 
     524        if (stream->dec_buf && stream->dec_buf_pos < stream->dec_buf_count) { 
     525            unsigned nsamples_req = samples_required - samples_count; 
     526            unsigned nsamples_avail = stream->dec_buf_count - 
     527                                      stream->dec_buf_pos; 
     528            unsigned nsamples_copy = PJ_MIN(nsamples_req, nsamples_avail); 
     529             
     530            pjmedia_copy_samples(p_out_samp + samples_count, 
     531                                 stream->dec_buf + stream->dec_buf_pos, 
     532                                 nsamples_copy); 
     533            samples_count += nsamples_copy; 
     534            stream->dec_buf_pos += nsamples_copy; 
     535            continue; 
     536        } 
    514537 
    515538        /* Get frame from jitter buffer. */ 
     
    559582            } 
    560583 
     584            samples_count += samples_per_frame; 
    561585        } else if (frame_type == PJMEDIA_JB_ZERO_EMPTY_FRAME) { 
    562586 
     
    676700            /* Got "NORMAL" frame from jitter buffer */ 
    677701            pjmedia_frame frame_in, frame_out; 
     702            pj_bool_t use_dec_buf = PJ_FALSE; 
    678703 
    679704            stream->plc_cnt = 0; 
     
    687712            frame_out.buf = p_out_samp + samples_count; 
    688713            frame_out.size = frame->size - samples_count*BYTES_PER_SAMPLE; 
     714            if (stream->dec_buf && 
     715                bit_info * sizeof(pj_int16_t) > frame_out.size) 
     716            { 
     717                stream->dec_buf_pos = 0; 
     718                stream->dec_buf_count = bit_info; 
     719 
     720                use_dec_buf = PJ_TRUE; 
     721                frame_out.buf = stream->dec_buf; 
     722                frame_out.size = stream->dec_buf_size; 
     723            } 
     724 
    689725            status = pjmedia_codec_decode( stream->codec, &frame_in, 
    690726                                           (unsigned)frame_out.size, 
     
    694730                         status)); 
    695731 
    696                 pjmedia_zero_samples(p_out_samp + samples_count, 
    697                                      samples_per_frame); 
     732                if (use_dec_buf) { 
     733                    pjmedia_zero_samples(p_out_samp + samples_count, 
     734                                         samples_per_frame); 
     735                } else { 
     736                    pjmedia_zero_samples(stream->dec_buf, 
     737                                         stream->dec_buf_count); 
     738                } 
     739            } else if (use_dec_buf) { 
     740                stream->dec_buf_count = frame_out.size / sizeof(pj_int16_t); 
    698741            } 
    699742 
     
    710753                stream->jb_last_frm_cnt++; 
    711754            } 
     755            if (!use_dec_buf) 
     756                samples_count += samples_per_frame; 
    712757        } 
    713758    } 
     
    17551800                     status)); 
    17561801            count = 0; 
     1802        } else if (stream->detect_ptime_change && 
     1803                   frames[0].bit_info > 0xFFFF) 
     1804        { 
     1805            unsigned dec_ptime; 
     1806             
     1807            PJ_LOG(4, (stream->port.info.name.ptr, "codec decode " 
     1808                       "ptime change detected")); 
     1809            frames[0].bit_info &= 0xFFFF; 
     1810            dec_ptime = frames[0].bit_info * 1000 / 
     1811                        stream->codec_param.info.clock_rate; 
     1812            stream->rtp_rx_ts_len_per_frame= stream->rtp_rx_ts_len_per_frame * 
     1813                                             dec_ptime / stream->dec_ptime; 
     1814            stream->dec_ptime = dec_ptime; 
     1815            pjmedia_jbuf_set_ptime(stream->jb, stream->dec_ptime); 
    17571816        } 
    17581817 
     
    18251884 
    18261885        } else { 
    1827             ts_span = stream->codec_param.info.frm_ptime * 
     1886            ts_span = stream->dec_ptime * 
    18281887                      stream->codec_param.info.clock_rate / 
    18291888                      1000; 
    18301889        } 
    18311890#else 
    1832         ts_span = stream->codec_param.info.frm_ptime * 
     1891        ts_span = stream->dec_ptime * 
    18331892                  stream->codec_param.info.clock_rate / 
    18341893                  1000; 
     
    21242183        stream->codec_param.info.clock_rate = info->fmt.clock_rate; 
    21252184        stream->codec_param.info.channel_cnt = info->fmt.channel_cnt; 
     2185 
     2186        /* Allocate decoding buffer as Opus can send a packet duration of 
     2187         * up to 120 ms. 
     2188         */ 
     2189        stream->dec_buf_size = stream->codec_param.info.clock_rate * 120 / 
     2190                               1000; 
     2191        stream->dec_buf = (pj_int16_t*)pj_pool_alloc(pool, 
     2192                                                     stream->dec_buf_size * 
     2193                                                     sizeof(pj_int16_t)); 
    21262194    } 
    21272195 
     
    21312199 
    21322200    /* Set additional info and callbacks. */ 
     2201    stream->dec_ptime = stream->codec_param.info.frm_ptime; 
    21332202    afd->bits_per_sample = 16; 
    21342203    afd->frame_time_usec = stream->codec_param.info.frm_ptime * 
     
    22482317        stream->rtp_tx_ts_len_per_pkt *= opus_ts_modifier; 
    22492318        stream->rtp_rx_ts_len_per_frame *= opus_ts_modifier; 
     2319        stream->detect_ptime_change = PJ_TRUE; 
    22502320    } 
    22512321#endif 
Note: See TracChangeset for help on using the changeset viewer.