Skip to content

Commit

Permalink
Fix trackInfo mismatch
Browse files Browse the repository at this point in the history
  • Loading branch information
ipavlidakis committed Dec 12, 2024
1 parent b188fc9 commit 80bd59a
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 52 deletions.
8 changes: 1 addition & 7 deletions Sources/StreamVideo/Utils/StreamRuntimeCheck.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,5 @@ public enum StreamRuntimeCheck {
/// Enables assertions thrown by the StreamVideo SDK.
///
/// When set to false, a message will be logged on console, but the assertion will not be thrown.
static var assertionsEnabled = {
#if DEBUG
return true
#else
return false
#endif
}()
static var assertionsEnabled = false
}
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,10 @@ class RTCPeerConnectionCoordinator: @unchecked Sendable {
}
}

func completeSetUp() {
setUpSubject.send(true)
}

/// Sets up the peer connection with given settings and capabilities.
///
/// - Parameters:
Expand Down Expand Up @@ -280,7 +284,6 @@ class RTCPeerConnectionCoordinator: @unchecked Sendable {
with: settings,
ownCapabilities: ownCapabilities
)
setUpSubject.send(true)
}

/// Updates the call settings.
Expand Down Expand Up @@ -620,44 +623,6 @@ class RTCPeerConnectionCoordinator: @unchecked Sendable {
let tracksInfo = WebRTCJoinRequestFactory()
.buildAnnouncedTracks(self)

func validateTracksAndTransceivers(
_ trackType: TrackType,
tracksInfo: [Stream_Video_Sfu_Models_TrackInfo]
) {
let tracks = Set(
tracksInfo
.filter {
switch (trackType, $0.trackType) {
case (.audio, .audio), (.video, .video), (.screenshare, .screenShare):
return true
default:
return false
}
}
.compactMap(\.trackID)
)
let transceivers = Set(
peerConnection
.transceivers(for: trackType)
.compactMap(\.sender.track?.trackId)
)

log.assert(
tracks == transceivers,
"""
PeerConnection tracks and transceivers mismatch
Identifier: \(identifier)
type:\(peerType)
sessionID: \(sessionId)
sfu: \(sfuAdapter.hostname)
tracks: \(tracks.sorted().joined(separator: ","))
transceivers: \(transceivers.sorted().joined(separator: ","))
""",
subsystems: subsystem
)
}

validateTracksAndTransceivers(.video, tracksInfo: tracksInfo)
validateTracksAndTransceivers(.screenshare, tracksInfo: tracksInfo)

Expand Down Expand Up @@ -751,4 +716,59 @@ class RTCPeerConnectionCoordinator: @unchecked Sendable {
.sink { [weak self] in self?.handleSubscriberOffer($0) }
.store(in: disposableBag)
}

/// Validates that the tracks intended for negotiation with the SFU match the state of the transceivers in
/// the peer connection.
///
/// This method ensures that the tracks we plan to send during negotiation (as represented by the
/// `tracksInfo` parameter) are consistent with the transceivers in the peer connection. If there is a
/// mismatch, an error is logged for debugging purposes.
///
/// - Parameters:
/// - trackType: The type of track to validate (e.g., `.audio`, `.video`, or `.screenshare`).
/// - tracksInfo: A collection of `TrackInfo` objects representing the tracks announced to
/// the SFU during negotiation.
///
/// The validation process compares the set of track IDs in the `tracksInfo` list against the set of
/// track IDs retrieved from the peer connection's transceivers for the specified `trackType`. If these
/// sets differ, it indicates a discrepancy between the announced tracks and the transceivers' actual state.
private func validateTracksAndTransceivers(
_ trackType: TrackType,
tracksInfo: [Stream_Video_Sfu_Models_TrackInfo]
) {
let tracks = Set(
tracksInfo
.filter {
switch (trackType, $0.trackType) {
case (.audio, .audio), (.video, .video), (.screenshare, .screenShare):
return true
default:
return false
}
}
.compactMap(\.trackID)
)
let transceivers = Set(
peerConnection
.transceivers(for: trackType)
.compactMap(\.sender.track?.trackId)
)

guard tracks != transceivers else {
return
}
log.error(
"""
PeerConnection tracks and transceivers mismatch
Identifier: \(identifier)
type:\(peerType)
sessionID: \(sessionId)
sfu: \(sfuAdapter.hostname)
tracks: \(tracks.sorted().joined(separator: ","))
transceivers: \(transceivers.sorted().joined(separator: ","))
""",
subsystems: subsystem
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -366,10 +366,6 @@ extension WebRTCCoordinator.StateMachine.Stage {

try Task.checkCancellation()

try await coordinator.stateAdapter.restoreScreenSharing()

try Task.checkCancellation()

reportTelemetry(
sessionId: await coordinator.stateAdapter.sessionID,
sfuAdapter: sfuAdapter
Expand Down
9 changes: 7 additions & 2 deletions Sources/StreamVideo/WebRTC/v2/WebRTCStateAdapter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -264,23 +264,28 @@ actor WebRTCStateAdapter: ObservableObject, StreamAudioSessionAdapterDelegate {
}
.store(in: peerConnectionsDisposableBag)

/// We setUp and restoreScreenSharing on the publisher in order to prepare all required tracks
/// for publication. In that way, negotiation will wait until ``completeSetUp`` has been called.
/// Then, with all the tracks prepared, will continue the negotiation flow.
try await publisher.setUp(
with: callSettings,
ownCapabilities: Array(
ownCapabilities
)
)
self.publisher = publisher
try await restoreScreenSharing()
publisher.setVideoFilter(videoFilter)
publisher.completeSetUp()

try await subscriber.setUp(
with: callSettings,
ownCapabilities: Array(
ownCapabilities
)
)

self.publisher = publisher
self.subscriber = subscriber
subscriber.completeSetUp()
}

/// Cleans up the WebRTC session by closing connections and resetting
Expand Down

0 comments on commit 80bd59a

Please sign in to comment.