[Enhancement] iOS Audio engine input / output availability - #102
Conversation
* Audio engine input / output availability (#196) Adds a flag to override engine start/stop behavior, useful in scenarios such as CallKit, where the timing for starting AVAudioSession and AVAudioEngine is restricted. * review comments fix * fix: guard setEngineAvailability: / engineAvailability, matching other methods --------- Co-authored-by: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
Disabled knowledge base sources:
📝 WalkthroughWalkthrough
ChangesAudio engine availability
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant RTCAudioDeviceModule
participant WorkerThread
participant AudioEngineDevice
Client->>RTCAudioDeviceModule: setEngineAvailability
RTCAudioDeviceModule->>WorkerThread: BlockingCall
WorkerThread->>AudioEngineDevice: SetEngineAvailability
Client->>RTCAudioDeviceModule: engineAvailability
RTCAudioDeviceModule->>WorkerThread: BlockingCall
WorkerThread->>AudioEngineDevice: EngineAvailability
AudioEngineDevice-->>RTCAudioDeviceModule: Availability values
RTCAudioDeviceModule-->>Client: RTCAudioEngineAvailability
Possibly related PRs
Suggested reviewers: ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
WebRTC Changelog 145.11.0 — Audio Engine Availability (develop → main)
Release
145.11.0is a patch release on top of145.10.0. It contains no WebRTC baseline bump — the upstreamwebrtc.googlesource.com/srcrevision is unchanged from the previous release. The only change is a Stream fork addition to the iOS/macOSAudioEngineDevice, giving hosts an explicit way to gate when the audio engine is allowed to start and stop.Compare: main...develop
Range:
ee2a4bef1711…813e3d764850(1 commit, first-parent)Summary
AudioEngineDevicepreviously started the input and output engines purely as a function of its own enabled/running state. That works when WebRTC owns the audio lifecycle, but breaks in host-driven flows — most notably CallKit, where the system decides whenAVAudioSessionbecomes active and startingAVAudioEnginetoo early (or too late) results in no audio, a dropped route, or a hard engine failure.This release adds an availability gate: two independent flags (
inputAvailable/outputAvailable) that act as a veto on top of all existing engine-state logic. Both default totrue, so existing behavior is unchanged unless an integrator opts in by setting availability tofalse. Once set, the engine will not enable or run the corresponding direction regardless of what the rest of the state machine wants — letting the host hold the engine back until the platform says it is safe to start, then release it.The change is ported from the upstream
webrtc-sdk/webrtcfork (PR #196) and adapted for Stream, with the ObjC entry points guarded to match the rest of the audio-engine surface.Categories
Counts as reported by
scripts/generate_changelog.pyfororigin/main..origin/develop:The single commit is not auto-classified into a feature/fix bucket; it is flagged for breaking change review because it touches packaged public headers. See Notes for Reviewers — the API change is purely additive.
Stream Integration Highlights
New engine availability gate (iOS / macOS).
AudioEngineDevice::EngineStategainsinput_availableandoutput_available(both defaulting totrue). Every enabled/running query —IsInputEnabled,IsInputRunning,IsOutputEnabled,IsOutputRunning— now ANDs its result with the matching availability flag, so a single flag suppresses start/stop for that direction across the whole state machine rather than at individual call sites.Native control surface.
AudioEngineDevice::SetEngineAvailability(bool input, bool output)andAudioEngineDevice::EngineAvailability(bool*, bool*)are added, both asserting they run on the device thread. Setting availability goes through the existingModifyEngineStatetransform, so a change is applied and reconciled the same way as any other engine-state transition — no separate code path.Public ObjC API (additive).
RTCAudioDeviceModuleexposes:- (NSInteger)setEngineAvailability:(RTCAudioEngineAvailability)availability;@property(nonatomic, readonly) RTCAudioEngineAvailability engineAvailability;backed by a new lightweight struct
RTCAudioEngineAvailability { bool isInputAvailable; bool isOutputAvailable; }. Both hop to the worker thread viaBlockingCall, and both are guarded onWEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE, native-module readiness, worker-thread readiness, andisAudioEngineModule— matching the guard pattern already used by the other audio-engine-only members. Guard failures return-1(setter) or(NO, NO)(getter) instead of touching a null module.Simplified aggregate state predicates.
IsAllEnabled()/IsAllRunning()are rewritten as plainIsInputEnabled() && IsOutputEnabled()andIsInputRunning() && IsOutputRunning(), replacing the previous branch onIsOutputInputLinked(). This removes duplicated linkage logic and ensures the new availability gate is honored by the aggregate predicates too.Debug logging.
DebugEngineStatenow printsInputAvailable/OutputAvailable, so availability is visible in engine-state dumps when diagnosing "engine didn't start" reports.Header tidy-up. Trailing whitespace removed from the
RTCAudioProcessingStatestruct declaration. No functional effect.Primary use case: with CallKit, set availability to
falsewhile the call is being set up, then flip it totruefromprovider:didActivateAudioSession:so the engine starts only once the system session is active — and back tofalseon deactivation.Fixes
None in this release.
Platform / build
No build, toolchain, GN, or dependency changes.
DEPSand the upstream baseline are untouched, so this release rebuilds against the same WebRTC revision as145.10.0.Notes for Reviewers
sdk/objc/api/peerconnection/RTCAudioDeviceModule.hgains one struct, one method, and one readonly property. Nothing was renamed, removed, or re-typed, so existing consumers compile and behave unchanged.RTCAudioEngineAvailabilityis new and needs to be visible in the packaged framework headers — worth confirming it is exported alongside the otherRTC_OBJC_TYPEaudio-engine structs when the xcframework is built.input_availableandoutput_availableinitialize totrueinEngineState, and nothing in this change writes them except the new setter. A build that never callssetEngineAvailability:is behaviorally identical to145.10.0.IsAllEnabledis equivalent;IsAllRunningis subtly stricter. ForIsAllEnabled, the new expression reduces to the old one in both the linked and unlinked cases. ForIsAllRunning, the old form compared the rawinput_runningfield, whereasIsInputRunning()also applies theMuteMode::RestartEngine && input_mutedguard. Net effect: a muted-via-engine-restart device is no longer reported as "all running". This looks correct and intended, but it is the one place where behavior changes without anyone opting in — worth a focused check against mute/unmute flows usingMuteMode::RestartEngine.outputAvailable = falsesuppresses output even when output is enabled and linked to input. BecauseIsOutputInputLinked()makes output follow input, gating input alone will also stop output in voice-processing mode. Integrators generally want to set both flags together.(NO, NO)on guard failure.engineAvailabilitycannot distinguish "input and output are both unavailable" from "the audio engine module isn't ready / this isn't an engine module". Callers should not treat a(NO, NO)read as authoritative before the ADM is initialized.RTC_DCHECK_RUN_ON(thread_)and reached only via_workerThread->BlockingCall.setEngineAvailability:andengineAvailabilityare therefore synchronous and blocking — do not call them from an audio-render or other latency-sensitive callback.modules/audio_device/audio_engine_device.{h,mm}andsdk/objc/api/peerconnection/RTCAudioDeviceModule.{h,mm}. No Android, Java/JNI, frame-cryptor,pc/, orapi/changes — Android artifacts for this release carry no source changes.webrtc-sdk/webrtcPR #196, co-authored by Hiroshi Horie, with Stream-side review fixes (the guard hardening onsetEngineAvailability:/engineAvailability).Publish
145.11.0alphaflag rather than a version suffix)develop→mainSummary by CodeRabbit