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-codec/opus.c

    r5731 r5734  
    4343 */ 
    4444#define MAX_ENCODED_PACKET_SIZE         1280 
     45 
     46/* Default frame time (msec) */ 
     47#define PTIME                   20 
    4548 
    4649/* Tracing */ 
     
    137140    OpusRepacketizer            *dec_packer; 
    138141    pjmedia_codec_opus_config    cfg; 
    139     unsigned                     ptime; 
     142    unsigned                     enc_ptime; 
     143    unsigned                     dec_ptime; 
    140144    pjmedia_frame                dec_frame[2]; 
    141145    int                          dec_frame_index; 
     
    150154    PJMEDIA_CODEC_OPUS_DEFAULT_SAMPLE_RATE,     /* Sample rate          */ 
    151155    1,                                          /* Channel count        */ 
     156    PTIME,                                      /* Frame time           */                       
    152157    PJMEDIA_CODEC_OPUS_DEFAULT_BIT_RATE,        /* Bit rate             */ 
    153158    5,                                          /* Expected packet loss */ 
     
    387392    param->info.clock_rate = opus_cfg.sample_rate = cfg->sample_rate; 
    388393    param->info.max_bps = opus_cfg.sample_rate * 2; 
     394    param->info.frm_ptime = opus_cfg.frm_ptime = cfg->frm_ptime; 
    389395 
    390396    /* Set channel count */ 
     
    468474    attr->info.avg_bps             = opus_cfg.bit_rate; 
    469475    attr->info.max_bps             = opus_cfg.sample_rate * 2; 
    470     attr->info.frm_ptime           = 20; 
     476    attr->info.frm_ptime           = opus_cfg.frm_ptime; 
    471477    attr->setting.frm_per_pkt      = 1; 
    472478    attr->info.pcm_bits_per_sample = 16; 
     
    601607    opus_data->cfg.sample_rate = attr->info.clock_rate; 
    602608    opus_data->cfg.channel_cnt = attr->info.channel_cnt; 
    603     opus_data->ptime      = attr->info.frm_ptime; 
     609    opus_data->enc_ptime = opus_data->dec_ptime = attr->info.frm_ptime; 
    604610 
    605611    /* Allocate memory used by the codec */ 
     
    815821    } 
    816822 
    817     samples_per_frame = (opus_data->cfg.sample_rate * 
    818                          opus_data->ptime) / 1000; 
    819  
    820823    pj_memcpy(tmp_buf, pkt, pkt_size); 
    821824 
     
    837840        frames[i].buf = ((char*)pkt) + out_pos; 
    838841        frames[i].size = size; 
     842        frames[i].bit_info = opus_packet_get_nb_samples(frames[i].buf, 
     843                             frames[i].size, opus_data->cfg.sample_rate); 
     844 
     845        if (i == 0) { 
     846            unsigned ptime = frames[i].bit_info * 1000 / 
     847                             opus_data->cfg.sample_rate; 
     848            if (ptime != opus_data->dec_ptime) { 
     849                PJ_LOG(4, (THIS_FILE, "Opus ptime change detected: %d ms " 
     850                                      "--> %d ms", 
     851                                      opus_data->dec_ptime, ptime)); 
     852                opus_data->dec_ptime = ptime; 
     853                opus_data->dec_frame_index = -1; 
     854 
     855                /* Signal to the stream about ptime change. */ 
     856                frames[i].bit_info |= 0x10000; 
     857            } 
     858            samples_per_frame = frames[i].bit_info; 
     859        } 
     860 
    839861        frames[i].timestamp.u64 = ts->u64 + i * samples_per_frame; 
    840862        out_pos += size; 
     
    867889 
    868890    samples_per_frame = (opus_data->cfg.sample_rate * 
    869                          opus_data->ptime) / 1000; 
     891                         opus_data->enc_ptime) / 1000; 
    870892    frame_size = samples_per_frame * opus_data->cfg.channel_cnt * 
    871893                 sizeof(opus_int16); 
     
    9821004        frm_size = PJ_MIN(frm_size, 
    9831005                          opus_data->cfg.sample_rate * 
    984                           opus_data->ptime / 1000); 
     1006                          opus_data->dec_ptime / 1000); 
    9851007    } 
    9861008    decoded_samples = opus_decode( opus_data->dec, 
     
    10421064        /* Recover the first packet? Don't think so, fill it with zeroes. */ 
    10431065        pj_uint16_t samples_per_frame; 
    1044         samples_per_frame = (pj_uint16_t)(opus_data->cfg.sample_rate *  
    1045                                           opus_data->ptime) / 1000; 
     1066        samples_per_frame = opus_data->cfg.sample_rate * opus_data->dec_ptime/ 
     1067                            1000; 
    10461068        output->type = PJMEDIA_FRAME_TYPE_AUDIO; 
    10471069        output->size = samples_per_frame << 1; 
     
    10571079    if (inframe->type != PJMEDIA_FRAME_TYPE_AUDIO) { 
    10581080        frm_size = PJ_MIN(frm_size, opus_data->cfg.sample_rate * 
    1059                           opus_data->ptime/1000); 
     1081                          opus_data->dec_ptime/1000); 
    10601082    } 
    10611083    decoded_samples = opus_decode(opus_data->dec, 
Note: See TracChangeset for help on using the changeset viewer.