Skip to content

fix(sdk): scale simulcast layers explicitly for Chrome 154+ (OPTI-4760) - #563

Merged
bcostdolby merged 3 commits into
mainfrom
devin/1791497563-simulcast-scaling
Oct 9, 2026
Merged

bcostdolby merged 3 commits into
mainfrom
devin/1791497563-simulcast-scaling

Conversation

@bcostdolby

@bcostdolby bcostdolby commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes OPTI-4760. On Chrome 154 and later, simulcast: true publishes three layers that are all at full capture resolution (e.g. 3x 1280x720 at about 0.8 / 0.8 / 3.8 Mbps). Earlier Chrome versions send 1/4, 1/2 and full resolution. We have seen this in production.

Cause: WebRTC 341526e2ca "[Interop 2026] Apply simulcast scaling defaults" (chromium:344943229) makes addTransceiver write scaleResolutionDownBy: 1 on the single encoding. SdpParser.setSimulcast() then adds two more layers by munging the SDP (a=ssrc-group:SIM), and those layers get no scale. After setLocalDescription, getParameters().encodings reports scale [1, undefined, undefined], and Chrome encodes every layer at full size.

Fix: add PeerConnection.setSimulcastScaling(). Once the munged local description is set, it sets the video sender's encodings to scaleResolutionDownBy = 2 ** (n - 1 - i), i.e. [4, 2, 1] for 3 layers:

// Publish.connect(), after publish + setLocalDescription
if (!this.options.disableVideo && this.options.simulcast) await webRTCPeerInstance.setSimulcastScaling()
// getRTCLocalSDP({ setSDPToPeer: true, simulcast: true }) calls it as well
  • It does nothing if the sender has no getParameters or fewer than 2 encodings. This covers non-Chromium browsers and codecs where setSimulcast() leaves the SDP unchanged.
  • A setParameters failure is logged as a warning and does not break publishing.
  • Before this change, this path set no scaling at all, so the values match what Chrome ≤153 applied by default.

Testing

  • New unit scenarios:
    • SetLocalDescription.feature: 3 encodings are set to [4, 2, 1]; a single encoding is left unchanged; getRTCLocalSDP({simulcast:true}) calls setSimulcastScaling.
    • Publish.feature: connect({simulcast:true}) calls setSimulcastScaling once, and connect() without simulcast does not call it.
    • The full unit suite passes (177 tests) and eslint is clean.
  • Browser check with a local loopback harness. It runs the SDK's real getRTCLocalSDP({simulcast:true}) and setLocalDescription steps, with a 1280x720 fake camera in Chrome for Testing. Layer sizes are read from outbound-rtp stats:
Chrome Without fix With fix
153 (VP8, H.264) 320x180 / 640x360 / 1280x720 same, scales [4,2,1]
154 (VP8, H.264) 3x 1280x720 320x180 / 640x360 / 1280x720
157 canary (VP8, H.264) 3x 1280x720 320x180 / 640x360 / 1280x720

The scaling also still applies after a later updateBitrate() renegotiation, checked on 153, 154 and 157.

Link to Devin session: https://dolby.devinenterprise.com/sessions/00476be9da3b47819e7c35883c75e293
Open in Devin Desktop: https://dolby.devinenterprise.com/desktop/session/00476be9da3b47819e7c35883c75e293?variant=devin
Requested by: @bcostdolby


Devin Review

Co-Authored-By: Brendon Costa <brendon.costa@dolby.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@changeset-bot

changeset-bot Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 90327f9

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@millicast/sdk Patch

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

@devin-ai-integration devin-ai-integration Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin resolved the finding on 90327f9

Fixed by Devin (1)

  • Scaling tests bypass publishing integration

View all findings in Devin Review

Devin Review

devin-ai-integration Bot and others added 2 commits October 8, 2026 22:18
Co-Authored-By: Brendon Costa <brendon.costa@dolby.com>
…lcast-scaling

Co-Authored-By: Brendon Costa <brendon.costa@dolby.com>

# Conflicts:
#	packages/millicast-sdk/tests/features/Publish.feature
#	packages/millicast-sdk/tests/unit/Publish.steps.js
@bcostdolby
bcostdolby merged commit c159050 into main Oct 9, 2026
7 checks passed
@bcostdolby
bcostdolby deleted the devin/1791497563-simulcast-scaling branch October 9, 2026 02:59
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.

1 participant