Skip to content

Commit 2584afa

Browse files
youennfcadubentzen
authored andcommitted
Move out of OnTrack/OnRemoveTrack libwebrtc callbacks
https://bugs.webkit.org/show_bug.cgi?id=244709 rdar://problem/99481570 Reviewed by Eric Carlson. OnTrack/OnRemoveTrack are not standard compliant. We miss some cases where these should be called (say rollback). The timing of these callbacks is also not well aligned with the specification. Instead, everytime a description is applied successfully, we store the current transceiver states from the backend. We then compute the corresponding events from the transceiver states. Covered by existing and rebased tests. * LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-rollback-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpSender-setStreams.https-expected.txt: * Source/WebCore/Modules/mediastream/MediaStream.h: * Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp: (WebCore::MediaStreamTrack::trackMutedChanged): * Source/WebCore/Modules/mediastream/MediaStreamTrack.h: (WebCore::MediaStreamTrack::setShouldFireMuteEventImmediately): * Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp: (WebCore::PeerConnectionBackend::setLocalDescription): (WebCore::setAssociatedRemoteStreams): (WebCore::isDirectionReceiving): (WebCore::processRemoteTracks): (WebCore::PeerConnectionBackend::setLocalDescriptionSucceeded): (WebCore::PeerConnectionBackend::setRemoteDescriptionSucceeded): * Source/WebCore/Modules/mediastream/PeerConnectionBackend.h: (WebCore::PeerConnectionBackend::DescriptionStates::isolatedCopy): * Source/WebCore/Modules/mediastream/RTCRtpReceiver.h: * Source/WebCore/Modules/mediastream/RTCRtpTransceiver.h: * Source/WebCore/Modules/mediastream/gstreamer/GStreamerMediaEndpoint.cpp: (WebCore::GStreamerMediaEndpoint::doSetRemoteDescription): * Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp: (WebCore::LibWebRTCMediaEndpoint::mediaStreamFromRTCStreamId): (WebCore::LibWebRTCMediaEndpoint::addPendingTrackEvent): (WebCore::LibWebRTCMediaEndpoint::collectTransceivers): (WebCore::LibWebRTCMediaEndpoint::addIceCandidate): (WebCore::LibWebRTCMediaEndpoint::OnIceCandidate): (WebCore::LibWebRTCMediaEndpointTransceiverState::isolatedCopy): (WebCore::toLibWebRTCMediaEndpointTransceiverState): (WebCore::transceiverStatesFromPeerConnection): (WebCore::LibWebRTCMediaEndpoint::setLocalSessionDescriptionSucceeded): (WebCore::LibWebRTCMediaEndpoint::setLocalSessionDescriptionFailed): (WebCore::LibWebRTCMediaEndpoint::setRemoteSessionDescriptionSucceeded): (WebCore::LibWebRTCMediaEndpoint::mediaStreamFromRTCStream): Deleted. (WebCore::LibWebRTCMediaEndpoint::newTransceiver): Deleted. (WebCore::LibWebRTCMediaEndpoint::removeRemoteTrack): Deleted. (WebCore::LibWebRTCMediaEndpoint::OnTrack): Deleted. (WebCore::LibWebRTCMediaEndpoint::OnRemoveTrack): Deleted. * Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.h: Canonical link: https://commits.webkit.org/254128@main
1 parent d325573 commit 2584afa

12 files changed

Lines changed: 299 additions & 108 deletions

LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCPeerConnection-setRemoteDescription-rollback-expected.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ PASS rollback of a local offer to negotiated stable state should enable applying
1717
PASS rollback a local offer with audio direction change to negotiated stable state and then add video receiver
1818
PASS two transceivers with same mids
1919
PASS onremovetrack fires during remote rollback
20-
FAIL rollback of a remote offer with stream changes assert_equals: expected 2 but got 1
20+
PASS rollback of a remote offer with stream changes
2121
PASS removeTrack() with a sender being rolled back does not crash or throw
2222
PASS Implicit rollback with only a datachannel works
2323

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11

2-
Harness Error (TIMEOUT), message = null
3-
42
PASS setStreams causes streams to be reported via ontrack on callee
53
PASS setStreams can be used to reconstruct a stream with a track on the remote side
64
PASS Adding streams and changing direction causes new streams to be reported via ontrack on callee
7-
TIMEOUT Adding streams to an active transceiver causes new streams to be reported via ontrack on callee Test timed out
5+
PASS Adding streams to an active transceiver causes new streams to be reported via ontrack on callee
86
PASS setStreams() fires InvalidStateError on a closed peer connection.
97

Source/WebCore/Modules/mediastream/MediaStream.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ class MediaStream final
7878

7979
RefPtr<MediaStream> clone();
8080

81+
using WeakValueType = MediaStreamPrivate::Observer::WeakValueType;
82+
using MediaStreamPrivate::Observer::weakPtrFactory;
83+
8184
bool active() const { return m_isActive; }
8285
bool muted() const { return m_private->muted(); }
8386

Source/WebCore/Modules/mediastream/MediaStreamTrack.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -610,12 +610,21 @@ void MediaStreamTrack::trackMutedChanged(MediaStreamTrackPrivate&)
610610
if (document->activeDOMObjectsAreStopped() || m_ended)
611611
return;
612612

613-
queueTaskKeepingObjectAlive(*this, TaskSource::Networking, [this, muted = m_private->muted()] {
613+
Function<void()> updateMuted = [this, muted = m_private->muted()] {
614614
if (!scriptExecutionContext() || scriptExecutionContext()->activeDOMObjectsAreStopped())
615615
return;
616+
617+
if (m_muted == muted)
618+
return;
619+
616620
m_muted = muted;
617621
dispatchEvent(Event::create(muted ? eventNames().muteEvent : eventNames().unmuteEvent, Event::CanBubble::No, Event::IsCancelable::No));
618-
});
622+
};
623+
if (m_shouldFireMuteEventImmediately)
624+
updateMuted();
625+
else
626+
queueTaskKeepingObjectAlive(*this, TaskSource::Networking, WTFMove(updateMuted));
627+
619628
configureTrackRendering();
620629

621630
bool wasInterrupted = m_isInterrupted;

Source/WebCore/Modules/mediastream/MediaStreamTrack.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ class MediaStreamTrack
163163
const void* logIdentifier() const final { return m_private->logIdentifier(); }
164164
#endif
165165

166+
void setShouldFireMuteEventImmediately(bool value) { m_shouldFireMuteEventImmediately = value; }
167+
166168
protected:
167169
MediaStreamTrack(ScriptExecutionContext&, Ref<MediaStreamTrackPrivate>&&);
168170

@@ -212,6 +214,7 @@ class MediaStreamTrack
212214
bool m_ended { false };
213215
const bool m_isCaptureTrack { false };
214216
bool m_isInterrupted { false };
217+
bool m_shouldFireMuteEventImmediately { false };
215218
};
216219

217220
typedef Vector<Ref<MediaStreamTrack>> MediaStreamTrackVector;

Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp

Lines changed: 165 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -186,25 +186,113 @@ void PeerConnectionBackend::setLocalDescription(const RTCSessionDescription* ses
186186
{
187187
ASSERT(!m_peerConnection.isClosed());
188188

189+
m_isProcessingLocalDescriptionAnswer = sessionDescription && (sessionDescription->type() == RTCSdpType::Answer || sessionDescription->type() == RTCSdpType::Pranswer);
189190
m_setDescriptionCallback = WTFMove(callback);
190191
doSetLocalDescription(sessionDescription);
191192
}
192193

193-
void PeerConnectionBackend::setLocalDescriptionSucceeded(std::optional<DescriptionStates>&& descriptionStates, std::unique_ptr<RTCSctpTransportBackend>&& sctpBackend)
194+
struct MediaStreamAndTrackItem {
195+
Ref<MediaStream> stream;
196+
Ref<MediaStreamTrack> track;
197+
};
198+
199+
// https://w3c.github.io/webrtc-pc/#set-associated-remote-streams
200+
static void setAssociatedRemoteStreams(RTCRtpReceiver& receiver, const PeerConnectionBackend::TransceiverState& state, Vector<MediaStreamAndTrackItem>& addList, Vector<MediaStreamAndTrackItem>& removeList)
201+
{
202+
for (auto& currentStream : receiver.associatedStreams()) {
203+
if (currentStream && !anyOf(state.receiverStreams, [&currentStream](auto& stream) { return stream->id() == currentStream->id(); }))
204+
removeList.append({ Ref { *currentStream }, Ref { receiver.track() } });
205+
}
206+
207+
for (auto& stream : state.receiverStreams) {
208+
if (!anyOf(receiver.associatedStreams(), [&stream](auto& currentStream) { return stream->id() == currentStream->id(); }))
209+
addList.append({ *stream, Ref { receiver.track() } });
210+
}
211+
212+
receiver.setAssociatedStreams(WTF::map(state.receiverStreams, [](auto& stream) { return WeakPtr { stream.get() }; }));
213+
}
214+
215+
static bool isDirectionReceiving(RTCRtpTransceiverDirection direction)
216+
{
217+
return direction == RTCRtpTransceiverDirection::Sendrecv || direction == RTCRtpTransceiverDirection::Recvonly;
218+
}
219+
220+
// https://w3c.github.io/webrtc-pc/#process-remote-tracks
221+
static void processRemoteTracks(RTCRtpTransceiver& transceiver, PeerConnectionBackend::TransceiverState&& state, Vector<MediaStreamAndTrackItem>& addList, Vector<MediaStreamAndTrackItem>& removeList, Vector<Ref<RTCTrackEvent>>& trackEventList, Vector<Ref<MediaStreamTrack>>& muteTrackList)
222+
{
223+
auto addListSize = addList.size();
224+
auto& receiver = transceiver.receiver();
225+
setAssociatedRemoteStreams(receiver, state, addList, removeList);
226+
if ((state.firedDirection && isDirectionReceiving(*state.firedDirection) && (!transceiver.firedDirection() || !isDirectionReceiving(*transceiver.firedDirection()))) || addListSize != addList.size()) {
227+
// https://w3c.github.io/webrtc-pc/#process-remote-track-addition
228+
trackEventList.append(RTCTrackEvent::create(eventNames().trackEvent, Event::CanBubble::No, Event::IsCancelable::No, &receiver, &receiver.track(), WTFMove(state.receiverStreams), &transceiver));
229+
}
230+
if (!(state.firedDirection && isDirectionReceiving(*state.firedDirection)) && transceiver.firedDirection() && isDirectionReceiving(*transceiver.firedDirection())) {
231+
// https://w3c.github.io/webrtc-pc/#process-remote-track-removal
232+
muteTrackList.append(receiver.track());
233+
}
234+
transceiver.setFiredDirection(state.firedDirection);
235+
}
236+
237+
void PeerConnectionBackend::setLocalDescriptionSucceeded(std::optional<DescriptionStates>&& descriptionStates, std::optional<TransceiverStates>&& transceiverStates, std::unique_ptr<RTCSctpTransportBackend>&& sctpBackend)
194238
{
195239
ASSERT(isMainThread());
196240
ALWAYS_LOG(LOGIDENTIFIER);
197241

198242
ASSERT(m_setDescriptionCallback);
199-
m_peerConnection.queueTaskKeepingObjectAlive(m_peerConnection, TaskSource::Networking, [this, callback = WTFMove(m_setDescriptionCallback), descriptionStates = WTFMove(descriptionStates), sctpBackend = WTFMove(sctpBackend)]() mutable {
243+
m_peerConnection.queueTaskKeepingObjectAlive(m_peerConnection, TaskSource::Networking, [this, callback = WTFMove(m_setDescriptionCallback), descriptionStates = WTFMove(descriptionStates), transceiverStates = WTFMove(transceiverStates), sctpBackend = WTFMove(sctpBackend)]() mutable {
200244
if (m_peerConnection.isClosed())
201245
return;
202246

203-
if (descriptionStates)
204-
m_peerConnection.updateDescriptions(WTFMove(*descriptionStates));
205247
m_peerConnection.updateTransceiversAfterSuccessfulLocalDescription();
206248
m_peerConnection.updateSctpBackend(WTFMove(sctpBackend));
249+
250+
if (descriptionStates) {
251+
m_peerConnection.updateDescriptions(WTFMove(*descriptionStates));
252+
if (m_peerConnection.isClosed())
253+
return;
254+
}
255+
207256
m_peerConnection.processIceTransportChanges();
257+
if (m_peerConnection.isClosed())
258+
return;
259+
260+
if (m_isProcessingLocalDescriptionAnswer && transceiverStates) {
261+
// Compute track related events.
262+
Vector<MediaStreamAndTrackItem> removeList;
263+
Vector<Ref<MediaStreamTrack>> muteTrackList;
264+
Vector<MediaStreamAndTrackItem> addListNoOp;
265+
for (auto& transceiverState : *transceiverStates) {
266+
RefPtr<RTCRtpTransceiver> transceiver;
267+
for (auto& item : m_peerConnection.currentTransceivers()) {
268+
if (item->mid() == transceiverState.mid) {
269+
transceiver = item;
270+
break;
271+
}
272+
}
273+
if (transceiver) {
274+
if (!(transceiverState.firedDirection && isDirectionReceiving(*transceiverState.firedDirection)) && transceiver->firedDirection() && isDirectionReceiving(*transceiver->firedDirection())) {
275+
setAssociatedRemoteStreams(transceiver->receiver(), transceiverState, addListNoOp, removeList);
276+
muteTrackList.append(transceiver->receiver().track());
277+
}
278+
}
279+
transceiver->setFiredDirection(transceiverState.firedDirection);
280+
}
281+
for (auto& track : muteTrackList) {
282+
track->setShouldFireMuteEventImmediately(true);
283+
track->source().setMuted(true);
284+
track->setShouldFireMuteEventImmediately(false);
285+
if (m_peerConnection.isClosed())
286+
return;
287+
}
288+
289+
for (auto& pair : removeList) {
290+
pair.stream->privateStream().removeTrack(pair.track->privateTrack());
291+
if (m_peerConnection.isClosed())
292+
return;
293+
}
294+
}
295+
208296
callback({ });
209297
});
210298
}
@@ -231,28 +319,92 @@ void PeerConnectionBackend::setRemoteDescription(const RTCSessionDescription& se
231319
doSetRemoteDescription(sessionDescription);
232320
}
233321

234-
void PeerConnectionBackend::setRemoteDescriptionSucceeded(std::optional<DescriptionStates>&& descriptionStates, std::unique_ptr<RTCSctpTransportBackend>&& sctpBackend)
322+
void PeerConnectionBackend::setRemoteDescriptionSucceeded(std::optional<DescriptionStates>&& descriptionStates, std::optional<TransceiverStates>&& transceiverStates, std::unique_ptr<RTCSctpTransportBackend>&& sctpBackend)
235323
{
236324
ASSERT(isMainThread());
237325
ALWAYS_LOG(LOGIDENTIFIER, "Set remote description succeeded");
238326
ASSERT(m_setDescriptionCallback);
239327

240-
m_peerConnection.queueTaskKeepingObjectAlive(m_peerConnection, TaskSource::Networking, [this, callback = WTFMove(m_setDescriptionCallback), descriptionStates = WTFMove(descriptionStates), sctpBackend = WTFMove(sctpBackend), events = WTFMove(m_pendingTrackEvents)]() mutable {
328+
m_peerConnection.queueTaskKeepingObjectAlive(m_peerConnection, TaskSource::Networking, [this, callback = WTFMove(m_setDescriptionCallback), descriptionStates = WTFMove(descriptionStates), transceiverStates = WTFMove(transceiverStates), sctpBackend = WTFMove(sctpBackend), events = WTFMove(m_pendingTrackEvents)]() mutable {
241329
if (m_peerConnection.isClosed())
242330
return;
243331

244-
if (descriptionStates)
245-
m_peerConnection.updateDescriptions(WTFMove(*descriptionStates));
332+
Vector<MediaStreamAndTrackItem> removeList;
333+
if (transceiverStates) {
334+
for (auto& transceiver : m_peerConnection.currentTransceivers()) {
335+
if (!anyOf(*transceiverStates, [&transceiver](auto& state) { return state.mid == transceiver->mid(); })) {
336+
for (auto& stream : transceiver->receiver().associatedStreams()) {
337+
if (stream)
338+
removeList.append({ Ref { *stream }, Ref { transceiver->receiver().track() } });
339+
}
340+
}
341+
}
342+
}
343+
344+
m_peerConnection.updateTransceiversAfterSuccessfulRemoteDescription();
345+
m_peerConnection.updateSctpBackend(WTFMove(sctpBackend));
246346

247-
for (auto& event : events)
248-
dispatchTrackEvent(event);
347+
if (descriptionStates) {
348+
m_peerConnection.updateDescriptions(WTFMove(*descriptionStates));
349+
if (m_peerConnection.isClosed())
350+
return;
351+
}
249352

353+
m_peerConnection.processIceTransportChanges();
250354
if (m_peerConnection.isClosed())
251355
return;
252356

253-
m_peerConnection.updateTransceiversAfterSuccessfulRemoteDescription();
254-
m_peerConnection.updateSctpBackend(WTFMove(sctpBackend));
255-
m_peerConnection.processIceTransportChanges();
357+
if (transceiverStates) {
358+
// Compute track related events.
359+
Vector<Ref<MediaStreamTrack>> muteTrackList;
360+
Vector<MediaStreamAndTrackItem> addList;
361+
Vector<Ref<RTCTrackEvent>> trackEventList;
362+
for (auto& transceiverState : *transceiverStates) {
363+
RefPtr<RTCRtpTransceiver> transceiver;
364+
for (auto& item : m_peerConnection.currentTransceivers()) {
365+
if (item->mid() == transceiverState.mid) {
366+
transceiver = item;
367+
break;
368+
}
369+
}
370+
if (transceiver)
371+
processRemoteTracks(*transceiver, WTFMove(transceiverState), addList, removeList, trackEventList, muteTrackList);
372+
}
373+
374+
for (auto& track : muteTrackList) {
375+
track->setShouldFireMuteEventImmediately(true);
376+
track->source().setMuted(true);
377+
track->setShouldFireMuteEventImmediately(false);
378+
if (m_peerConnection.isClosed())
379+
return;
380+
}
381+
382+
for (auto& pair : removeList) {
383+
pair.stream->privateStream().removeTrack(pair.track->privateTrack());
384+
if (m_peerConnection.isClosed())
385+
return;
386+
}
387+
388+
for (auto& pair : addList) {
389+
pair.stream->addTrackFromPlatform(pair.track.copyRef());
390+
if (m_peerConnection.isClosed())
391+
return;
392+
}
393+
394+
for (auto& event : trackEventList) {
395+
RefPtr track = event->track();
396+
m_peerConnection.dispatchEvent(event);
397+
if (m_peerConnection.isClosed())
398+
return;
399+
400+
track->source().setMuted(false);
401+
}
402+
} else {
403+
// FIXME: Move ports out of m_pendingTrackEvents.
404+
for (auto& event : events)
405+
dispatchTrackEvent(event);
406+
}
407+
256408
callback({ });
257409
});
258410
}

Source/WebCore/Modules/mediastream/PeerConnectionBackend.h

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "RTCIceGatheringState.h"
3838
#include "RTCRtpCapabilities.h"
3939
#include "RTCRtpSendParameters.h"
40+
#include "RTCRtpTransceiverDirection.h"
4041
#include "RTCSessionDescription.h"
4142
#include "RTCSignalingState.h"
4243
#include <wtf/FixedVector.h>
@@ -136,7 +137,15 @@ class PeerConnectionBackend
136137
String currentRemoteDescriptionSdp;
137138
std::optional<RTCSdpType> pendingRemoteDescriptionSdpType;
138139
String pendingRemoteDescriptionSdp;
140+
141+
DescriptionStates isolatedCopy() &&;
142+
};
143+
struct TransceiverState {
144+
String mid;
145+
Vector<RefPtr<MediaStream>> receiverStreams;
146+
std::optional<RTCRtpTransceiverDirection> firedDirection;
139147
};
148+
using TransceiverStates = Vector<TransceiverState>;
140149

141150
void newICECandidate(String&& sdp, String&& mid, unsigned short sdpMLineIndex, String&& serverURL, std::optional<DescriptionStates>&&);
142151
void newDataChannel(UniqueRef<RTCDataChannelHandler>&&, String&&, RTCDataChannelInit&&);
@@ -211,10 +220,10 @@ class PeerConnectionBackend
211220
void createAnswerSucceeded(String&&);
212221
void createAnswerFailed(Exception&&);
213222

214-
void setLocalDescriptionSucceeded(std::optional<DescriptionStates>&&, std::unique_ptr<RTCSctpTransportBackend>&&);
223+
void setLocalDescriptionSucceeded(std::optional<DescriptionStates>&&, std::optional<TransceiverStates>&&, std::unique_ptr<RTCSctpTransportBackend>&&);
215224
void setLocalDescriptionFailed(Exception&&);
216225

217-
void setRemoteDescriptionSucceeded(std::optional<DescriptionStates>&&, std::unique_ptr<RTCSctpTransportBackend>&&);
226+
void setRemoteDescriptionSucceeded(std::optional<DescriptionStates>&&, std::optional<TransceiverStates>&&, std::unique_ptr<RTCSctpTransportBackend>&&);
218227
void setRemoteDescriptionFailed(Exception&&);
219228

220229
void validateSDP(const String&) const;
@@ -253,8 +262,24 @@ class PeerConnectionBackend
253262
const void* m_logIdentifier;
254263
#endif
255264
bool m_finishedGatheringCandidates { false };
265+
bool m_isProcessingLocalDescriptionAnswer { false };
256266
};
257267

268+
inline PeerConnectionBackend::DescriptionStates PeerConnectionBackend::DescriptionStates::isolatedCopy() &&
269+
{
270+
return DescriptionStates {
271+
signalingState,
272+
currentLocalDescriptionSdpType,
273+
WTFMove(currentLocalDescriptionSdp).isolatedCopy(),
274+
pendingLocalDescriptionSdpType,
275+
WTFMove(pendingLocalDescriptionSdp).isolatedCopy(),
276+
currentRemoteDescriptionSdpType,
277+
WTFMove(currentRemoteDescriptionSdp).isolatedCopy(),
278+
pendingRemoteDescriptionSdpType,
279+
WTFMove(pendingRemoteDescriptionSdp).isolatedCopy()
280+
};
281+
}
282+
258283
} // namespace WebCore
259284

260285
#endif // ENABLE(WEB_RTC)

Source/WebCore/Modules/mediastream/RTCRtpReceiver.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
#if ENABLE(WEB_RTC)
3434

35-
#include "MediaStreamTrack.h"
35+
#include "MediaStream.h"
3636
#include "RTCDtlsTransport.h"
3737
#include "RTCRtpReceiverBackend.h"
3838
#include "RTCRtpSynchronizationSource.h"
@@ -79,6 +79,8 @@ class RTCRtpReceiver final : public RefCounted<RTCRtpReceiver>
7979
std::optional<RTCRtpTransform::Internal> transform();
8080
ExceptionOr<void> setTransform(std::unique_ptr<RTCRtpTransform>&&);
8181

82+
const Vector<WeakPtr<MediaStream>>& associatedStreams() const { return m_associatedStreams; }
83+
void setAssociatedStreams(Vector<WeakPtr<MediaStream>>&& streams) { m_associatedStreams = WTFMove(streams); }
8284
private:
8385
RTCRtpReceiver(PeerConnectionBackend&, Ref<MediaStreamTrack>&&, std::unique_ptr<RTCRtpReceiverBackend>&&);
8486

@@ -94,6 +96,7 @@ class RTCRtpReceiver final : public RefCounted<RTCRtpReceiver>
9496
std::unique_ptr<RTCRtpReceiverBackend> m_backend;
9597
WeakPtr<PeerConnectionBackend> m_connection;
9698
std::unique_ptr<RTCRtpTransform> m_transform;
99+
Vector<WeakPtr<MediaStream>> m_associatedStreams;
97100
#if !RELEASE_LOG_DISABLED
98101
Ref<const Logger> m_logger;
99102
const void* m_logIdentifier { nullptr };

Source/WebCore/Modules/mediastream/RTCRtpTransceiver.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,14 @@ class RTCRtpTransceiver final : public RefCounted<RTCRtpTransceiver>, public Scr
7272
RTCRtpTransceiverBackend* backend() { return m_backend.get(); }
7373
void setConnection(RTCPeerConnection&);
7474

75+
std::optional<RTCRtpTransceiverDirection> firedDirection() const { return m_firedDirection; }
76+
void setFiredDirection(std::optional<RTCRtpTransceiverDirection> firedDirection) { m_firedDirection = firedDirection; }
77+
7578
private:
7679
RTCRtpTransceiver(Ref<RTCRtpSender>&&, Ref<RTCRtpReceiver>&&, std::unique_ptr<RTCRtpTransceiverBackend>&&);
7780

7881
RTCRtpTransceiverDirection m_direction;
82+
std::optional<RTCRtpTransceiverDirection> m_firedDirection;
7983

8084
Ref<RTCRtpSender> m_sender;
8185
Ref<RTCRtpReceiver> m_receiver;

0 commit comments

Comments
 (0)