@@ -144,6 +144,7 @@ struct opus_context {
144144 enc_stats_t encoder_stats ;
145145 codec_control_state_t control_state ;
146146 switch_bool_t recreate_decoder ;
147+ uint32_t encoder_samplerate ;
147148};
148149
149150struct {
@@ -177,6 +178,11 @@ static switch_bool_t switch_opus_acceptable_rate(int rate)
177178 return SWITCH_TRUE ;
178179}
179180
181+ static inline uint32_t opus_ts_step (uint32_t ptime_ms , uint32_t enc_rate )
182+ {
183+ return (ptime_ms * 48 ); /* 48 kHz RTP clock rate */
184+ }
185+
180186static uint32_t switch_opus_encoder_set_audio_bandwidth (OpusEncoder * encoder_object ,int enc_samplerate )
181187{
182188 if (enc_samplerate == 8000 ) { /* Audio Bandwidth: 0-4000Hz Sampling Rate: 8000Hz */
@@ -618,6 +624,9 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
618624 return SWITCH_STATUS_GENERR ;
619625 }
620626
627+ /* Store encoder sample rate for RTP timestamp scaling */
628+ context -> encoder_samplerate = enc_samplerate ;
629+
621630 /* https://tools.ietf.org/html/rfc7587 */
622631 if (opus_codec_settings .maxaveragebitrate ) {
623632 opus_encoder_ctl (context -> encoder_object , OPUS_SET_BITRATE (opus_codec_settings .maxaveragebitrate ));
@@ -680,6 +689,7 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
680689 if (opus_prefs .adjust_bitrate ) {
681690 switch_set_flag (codec , SWITCH_CODEC_FLAG_HAS_ADJ_BITRATE );
682691 }
692+
683693 }
684694
685695 if (decoding ) {
@@ -718,6 +728,19 @@ static switch_status_t switch_opus_init(switch_codec_t *codec, switch_codec_flag
718728 }
719729 }
720730
731+ /* Set RTP interval for RFC 7587 compliance */
732+ if (codec -> session ) {
733+ switch_rtp_t * rtp = switch_core_media_get_rtp_session (codec -> session , SWITCH_MEDIA_TYPE_AUDIO );
734+ if (rtp ) {
735+ uint32_t ptime_ms = codec -> implementation -> microseconds_per_packet / 1000 ;
736+ uint32_t step = opus_ts_step (ptime_ms , codec -> implementation -> actual_samples_per_second );
737+ switch_rtp_set_interval (rtp , ptime_ms , step );
738+ }
739+ } else {
740+ switch_log_printf (SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING ,
741+ "Opus codec initialized without session - RTP interval not configured\n" );
742+ }
743+
721744 context -> codec_settings = opus_codec_settings ;
722745 codec -> private_info = context ;
723746
0 commit comments