Skip to content

fix: RTP timestamp regression after DTX transcoder restarts - #2191

Open
vingarzan wants to merge 4 commits into
sipwise:masterfrom
vingarzan:fix/dtx-output-clock-continuity
Open

vingarzan wants to merge 4 commits into
sipwise:masterfrom
vingarzan:fix/dtx-output-clock-continuity

Conversation

@vingarzan

Copy link
Copy Markdown
Contributor

RTP timestamps can jump backwards when DTX transcoding resumes after prompt playback or media blocking. In a phone-to-browser trace, the same speech SSRC retained increasing sequence numbers but its Opus timestamps moved backwards by approximately four seconds between talk bursts. This can make receivers discard the beginning of a burst or delay playback.

__dtx_send_later() caches encoder->next_pts + first_ts from the decoder-side context in ssrc_out->ts_out. That context may use a different clock from the actual output encoder, and the assignment does not apply the encoder sample-to-RTP clock conversion. After codec handlers are stopped and their timestamp origins reset, packet_decode() reuses this cached value as the next output origin. Time spent with the encoder stopped is also omitted from the resumed RTP clock.

Cache the next RTP timestamp when the actual output packet is encoded, using the destination encoder's clock conversion. Store its corresponding wall-clock time and advance the origin by elapsed time when transcoding restarts. This keeps each listener's output clock advancing across playback and silent intervals.

Add a repeated-burst regression for PCMU input transcoded to PCMA, Opus, and G.722, with prompt playback and directional media blocking between bursts. It checks stable speech SSRCs, forward timestamp progression, elapsed-time continuity, timely RTP output, and 32-bit timestamp wraparound. Update the existing codec-reconfiguration and maximum-DTX restart tests to check elapsed output time while retaining payload, sequence, SSRC, and subsequent packet-increment checks.

Cache timestamps from the actual output encoder rather than the DTX decoder context, and retain elapsed time when transcoding resumes after playback or floor blocking. Add repeated-burst coverage for PCMA, Opus and G.722, including timestamp wraparound, and update DTX restart expectations.

Validation: 712 repeated-burst checks, 19 null-packet/DTMF checks and 87 playback checks passed. Extended DTX retains the same 56 baseline failures with no additional failures.
(cherry picked from commit d0d3b20)
@rfuchs

rfuchs commented Oct 9, 2026

Copy link
Copy Markdown
Member

This makes the test in line 2454 of auto-daemon-tests.pl fail (produces a timestamp of 6204 instead of 3320)

@vingarzan

Copy link
Copy Markdown
Contributor Author

@rfuchs Thanks for the hint, as well as help with the previous couple of PRs!

I'm also trying to improve the tests in the other remaining fix PRs. Sorry, seems I missed the PR checks...

@rfuchs

rfuchs commented Oct 9, 2026

Copy link
Copy Markdown
Member

Still a few more failures

ok 163 - no packet received (main auto-daemon-tests-dtx.pl 711)
ok 164 - G.711/AMR-WB codec change reverse - 'offer' status
ok 165 - G.711/AMR-WB codec change reverse - output 'offer' SDP
ok 166 - G.711/AMR-WB codec change reverse - 'answer' status
ok 167 - G.711/AMR-WB codec change reverse - output 'answer' SDP
rtp in 0 2007 5760 22136 0 exts
rtp recv 96 2011 8888 22136 f01c214000fffbfc92172f2134cb60281b2323300487b1304f91045ed9c66cfc28ede1c6d5e0
806007db000022b800005678f01c214000fffbfc92172f2134cb60281b2323300487b1304f91045ed9c66cfc28ede1c6d5e0
not ok 168 - received packet matches (main auto-daemon-tests-dtx.pl 765)
#   Failed test 'received packet matches (main auto-daemon-tests-dtx.pl 765)'
#   at ../perl/NGCP/Rtpengine/AutoTest.pm line 299.
#                   '`Û"¸Vxð!@ÿûü/!4Ë`(0±0O^ÙÆlü(íáÆÕà'
#     doesn't match '(?^s:^\\`\\Û\\\\`\\Vx\ð\\!\@\\ÿ\û\ü\\\/\!4\Ë\`\(\#\#0\\\±0O\\\^\Ù\Æl\ü\(\í\á\Æ\Õ\à$)'
ok 169 - receive port matches (main auto-daemon-tests-dtx.pl 765)
rtp in 0 2007 5920 22136 0 exts
rtp recv 96 2012 9208 22136 f01cc8c604559265079c2119067189d466e684e6c5c4c4cc5ec1c5f54c55de719a57c0dee4d0
806007dc000023f800005678f01cc8c604559265079c2119067189d466e684e6c5c4c4cc5ec1c5f54c55de719a57c0dee4d0
not ok 170 - received packet matches (main auto-daemon-tests-dtx.pl 767)
#   Failed test 'received packet matches (main auto-daemon-tests-dtx.pl 767)'
#   at ../perl/NGCP/Rtpengine/AutoTest.pm line 299.
#                   '`Ü#øVxðÈÆUe!qÔfææÅÄÄÌ^ÁÅõLUÞqWÀÞäÐ'
#     doesn't match '(?^s:^\\`\\Ü\\\\ \\Vx\ð\\È\Æ\U\e\\\!\\q\\Ôf\æ\\æ\Å\Ä\Ä\Ì\^\Á\Å\õLU\Þq\W\À\Þ\ä\Ð$)'
ok 171 - receive port matches (main auto-daemon-tests-dtx.pl 767)
ok 172 - G.711/AMR-WB codec change reverse - 'delete' status
new call 21-test-callID-auto-daemon-tests-dtx.pl-0.09592634536207

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants