Skip to content

Commit ac8b8af

Browse files
committed
[mod_opus] set RTP interval for RFC 7587 compliance
Configure proper RTP timestamp increments for Opus codec to ensure compliance with RFC 7587. This fixes timestamp handling when transcoding between different sample rates.
1 parent c7455f5 commit ac8b8af

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

src/mod/codecs/mod_opus/mod_opus.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

149150
struct {
@@ -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+
180186
static 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

Comments
 (0)