Repository navigation
Conversation
Android publishers keep dynacast-paused simulcast layers paused across publisher renegotiations (publish/unpublish, codec change, ICE restart), instead of silently uploading them until the next subscribed-quality change.
🦋 Changeset detectedLatest commit: ae9fca5 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
| internal fun refreshSubscribedCodecs() { | ||
| val codecs = subscribedCodecs ?: return | ||
| setPublishingCodecs(codecs) | ||
| } |
There was a problem hiding this comment.
🔴 Quality-only pauses vanish after renegotiation
After a quality-only update, refreshSubscribedCodecs has no cached codecs to replay. The publisher answer re-enables paused layers, leaving them uploading until another quality update.
Learn more
A subscribed-quality update can contain a flat list of qualities without any subscribed codecs. handleSubscribedQualityUpdate applies that list directly with setPublishingLayers. The new replay only remembers subscribedCodecs, so these paused layers have no state to restore after a publisher answer re-enables them.
Example: A server sends an update for camera A with subscribedCodecs=[] and subscribedQualities=[HIGH disabled, LOW enabled]. The high layer pauses; an ICE-restart answer re-enables it, and refresh returns without pausing it again.
Recommended fix: Store the last flat quality update as well as the codec update and replay whichever form most recently controlled the primary sender. Clear both on unpublish or republish, and cover quality-only updates in the renegotiation test.
Was this helpful? React with 👍 or 👎 to provide feedback.
| when (val outcome = publisher?.setRemoteDescription(sessionDescription, offerId).nullSafe()) { | ||
| is Either.Left -> { | ||
| // do nothing. | ||
| listener?.onRequestSubscribedCodecRefresh() |
There was a problem hiding this comment.
🟡 Sender refresh bypasses the RTC thread
On a publisher answer, onRequestSubscribedCodecRefresh accesses WebRTC sender parameters from the engine's I/O coroutine. This can race with RTC-thread negotiation and leave paused layers active.
Learn more
The publisher answer is applied by setRemoteDescription on the RTC thread, but the suspended caller resumes on the engine's I/O dispatcher. The new synchronous callback reaches setPublishingLayersForSender, which reads and writes RtpSender.parameters. Sender operations belong on the RTC thread according to the repository's WebRTC threading rule; otherwise they can overlap further negotiation work.
Example: An answer for an ICE restart arrives while another publisher negotiation starts. The refresh accesses the sender on the I/O worker while the other negotiation uses that sender on the RTC executor.
Recommended fix: Schedule the refresh's WebRTC sender operations through launchBlockingOnRTCThread or executeBlockingOnRTCThread with the room's RTC token. Keep the cached codec state synchronized with signaling updates if the callback is dispatched asynchronously.
Was this helpful? React with 👍 or 👎 to provide feedback.
|
Diffuse output: AARJAR |
keep dynacast-paused simulcast layers paused across publisher renegotiations (publish/unpublish, codec change, ICE restart), instead of silently uploading them until the next subscribed-quality change.