Add the option to avoid clock-less time when switching from/to null sound device#5012
Open
trengginas wants to merge 2 commits into
Open
Add the option to avoid clock-less time when switching from/to null sound device#5012trengginas wants to merge 2 commits into
trengginas wants to merge 2 commits into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds an opt-in, parameterized null sound device API in PJSUA to support “gapless” clock handover during null ⇄ real audio device transitions (notably for iOS hold/resume scenarios), while keeping the existing pjsua_set_null_snd_dev() API as a backward-compatible wrapper.
Changes:
- Introduces
pjsua_null_snd_dev_param+ default initializer and new APIpjsua_set_null_snd_dev2()to control gap-avoid behavior. - Refactors PJSUA audio device open/close paths to support overlap-based transitions and clearer teardown responsibilities.
- Exposes the new behavior through the PJSUA2
AudDevManager::setNullDev2()wrapper and updates docs/alt backend stubs for API compatibility.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| pjsip/src/pjsua2/media.cpp | Adds AudDevManager::setNullDev2(bool) wrapper calling pjsua_set_null_snd_dev2(). |
| pjsip/src/pjsua-lib/pjsua_aud.c | Implements pjsua_set_null_snd_dev2(), adds transition policy tracking, refactors close/open logic and introduces close_snd_port() helper. |
| pjsip/include/pjsua2/media.hpp | Documents and declares setNullDev2(bool avoidClockGap) in PJSUA2 API. |
| pjsip/include/pjsua-lib/pjsua.h | Adds new public param struct, default initializer, and pjsua_set_null_snd_dev2() declaration; updates docs to reference new API. |
| pjsip/include/pjsua-lib/pjsua_internal.h | Adds internal runtime flag snd_avoid_clock_gap to track one-shot transition policy. |
| pjsip-apps/src/3rdparty_media_sample/alt_pjsua_aud.c | Adds no-op stub for pjsua_set_null_snd_dev2() for the alt backend sample. |
Comment on lines
1209
to
+1211
| * Set pjsua to use null sound device. The null sound device only provides | ||
| * the timing needed by the conference bridge, and will not interract with | ||
| * any hardware. | ||
| * any hardware. For configurable behavior, use setNullDev2(). |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
nanangizz
approved these changes
Jun 11, 2026
sauwming
approved these changes
Jun 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds a configurable null sound device API to avoid a clock-less transition window when switching audio paths, while preserving backward compatibility.
Use Case Scenario (iOS Call Hold/Resume)
On iOS, the audio device may be closed when a call is put on hold.
When that happens, RTP timestamp progression may pause because the clock source is no longer running.
When the call resumes, RTP timestamp generation can continue from the value before hold, which may cause discontinuity/jitter or dropped packet behavior.
A common workaround is to switch to null sound device during hold so the media clock keeps running and RTP timestamps continue to advance.
However, with the current switching path, there can still be a brief clock-less gap when transitioning between null sound device and actual sound device in either direction.
This PR addresses that by adding a configurable transition mode to preserve clock continuity during null <> real device handover.
Motivation
Switching to null sound device can briefly leave the conference bridge without a clock source. This change introduces an opt-in transition mode that prioritizes clock continuity.
What Changed
Behavior
legacy behavior (close old path first, then start null clock).
gap-avoid behavior (start null clock first, then stop old device).
Compatibility
Existing callers using pjsua_set_null_snd_dev() continue to work unchanged.
New behavior is opt-in via the new parameterized API.
Possible Negative Impact
When the new gap-avoid mode is enabled, there is a short overlap window where null clock is started before the previous sound path is fully closed. This avoids clock loss, but increases transition complexity and may expose edge races during rapid hold/resume toggles.
Scope Notes
Testing-only legacy app changes are intentionally excluded from this PR.
Testing
Not run in this branch.