fix: switch backup codec to VP8@30fps, dim H.264 pill with warning

- Backup codec changed from H.264 (OpenH264, slow) to VP8 (libvpx,
  fast) — same encoder family as VP9, lower dual-encode overhead
- Backup capped at 30fps with proportional bitrate to keep CPU
  overhead low during SIMULCAST dual-encoding
- H.264 pill visually dimmed with amber warning when selected
This commit is contained in:
Jannis Braun
2026-03-24 01:14:47 +01:00
parent a54dd9084a
commit e53d3bcb98
2 changed files with 17 additions and 9 deletions
@@ -193,7 +193,11 @@ export function ScreenShareSettingsPopover({ open, onClose, anchorRef }: ScreenS
<button <button
key={c.value} key={c.value}
onClick={() => setConfig({ codec: c.value })} onClick={() => setConfig({ codec: c.value })}
className={`${pillBase} ${config.codec === c.value ? pillSelected : pillUnselected}`} className={`${pillBase} ${
config.codec === c.value
? (c.value === 'h264' ? 'bg-accent-amber/60 text-white' : pillSelected)
: (c.value === 'h264' ? 'bg-surface-elevated/50 text-txt-tertiary hover:bg-interactive-hover' : pillUnselected)
}`}
> >
{c.label} {c.label}
</button> </button>
@@ -201,7 +205,7 @@ export function ScreenShareSettingsPopover({ open, onClose, anchorRef }: ScreenS
</div> </div>
{config.codec !== 'vp9' && ( {config.codec !== 'vp9' && (
<div className="text-[10px] text-accent-amber/80 mt-1"> <div className="text-[10px] text-accent-amber/80 mt-1">
VP9 is recommended for most setups Not recommended uses slower software encoder
</div> </div>
)} )}
</div> </div>
+11 -7
View File
@@ -27,7 +27,7 @@ export interface ScreenShareBuildResult {
videoCodec: 'vp9' | 'h264'; videoCodec: 'vp9' | 'h264';
videoEncoding: { maxBitrate: number; maxFramerate: number }; videoEncoding: { maxBitrate: number; maxFramerate: number };
simulcast: false; simulcast: false;
backupCodec?: { codec: 'h264'; encoding: { maxBitrate: number; maxFramerate: number } }; backupCodec?: { codec: 'vp8' | 'h264'; encoding: { maxBitrate: number; maxFramerate: number } };
backupCodecPolicy?: BackupCodecPolicy; backupCodecPolicy?: BackupCodecPolicy;
}; };
overdrive: OverdriveOptions; overdrive: OverdriveOptions;
@@ -131,12 +131,16 @@ export function buildScreenShareOptions(config: ScreenShareConfig): ScreenShareB
const bps = clampedKbps * 1000; const bps = clampedKbps * 1000;
const minBps = Math.round(bps * 0.25); const minBps = Math.round(bps * 0.25);
// VP9: better quality per bit, software-encoded (CPU). Best for text/static content. // VP9: better quality per bit via libvpx (software, CPU).
// H.264: hardware-encoded via NVENC/QSV/VCE (zero CPU). Universal browser support. // H.264: OpenH264 software encoder in Electron/Chrome (NOT hardware NVENC).
// When VP9 is primary, H.264 SIMULCAST backup handles Safari/incompatible viewers. // When VP9 is primary, VP8 SIMULCAST backup (also libvpx, lightweight) handles
// When H.264 is primary, no backup needed — universally supported. // incompatible viewers (Safari). Backup capped at 30fps to minimize dual-encode overhead.
const useVp9 = config.codec !== 'h264'; const useVp9 = config.codec !== 'h264';
// Backup encoding: cap at 30fps and proportional bitrate to keep CPU overhead low
const backupFps = Math.min(fps, 30);
const backupBps = Math.round(bps * (backupFps / fps));
return { return {
capture: { width: captureWidth, height: captureHeight, frameRate: fps }, capture: { width: captureWidth, height: captureHeight, frameRate: fps },
publish: { publish: {
@@ -145,8 +149,8 @@ export function buildScreenShareOptions(config: ScreenShareConfig): ScreenShareB
simulcast: false, simulcast: false,
...(useVp9 ? { ...(useVp9 ? {
backupCodec: { backupCodec: {
codec: 'h264' as const, codec: 'vp8' as const,
encoding: { maxBitrate: bps, maxFramerate: fps }, encoding: { maxBitrate: backupBps, maxFramerate: backupFps },
}, },
backupCodecPolicy: BackupCodecPolicy.SIMULCAST, backupCodecPolicy: BackupCodecPolicy.SIMULCAST,
} : {}), } : {}),