RTCPeerConnection.onnegotiationneeded can sometimes fire multiple times in a row |
||||||||||||
Issue descriptionRTCPeerConnection::NegotiationNeeded() should set a negotiationneeded flag to true, and only queue the event to fire if the flag went from false to true. This flag should be reset when it fires. Currently we have no such flag, so performing multiple actions in the same task execution that require negotiation will cause multiple onnegotiationneeded events to fire (where the first one will fire at a time when all actions will be covered and the subsequent onnegotiationneeded pointless). E.g. pc.addStream(s1); pc.addStream(s2); Or pc.addTrack(t1); pc.addTrack(t2);
,
Jan 25 2018
,
Jan 25 2018
addTrack() works both with and without adapter.js: https://jsfiddle.net/yxbLvjm6/19/ onnegotiationneeded does fire multiple times but that is unrelated to whether addStream or addTrack is used.
,
Jan 25 2018
Tested with latest Chrome.
,
Jan 25 2018
Tip of tree I mean, not stable yet.
,
Feb 8 2018
,
Feb 8 2018
,
Feb 8 2018
Related: https://crbug.com/webrtc/7693
,
Feb 9 2018
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/bd82fc5c072529638631929e7f1fe75f653b52c6 commit bd82fc5c072529638631929e7f1fe75f653b52c6 Author: Henrik Boström <hbos@chromium.org> Date: Fri Feb 09 10:24:56 2018 Don't fire onnegotiationneeded if flag has already been reset. Per-spec, updating the negotiation needed flag is slightly more complicated than "= true;" and involves checking if negotiation is needed. https://w3c.github.io/webrtc-pc/#dfn-update-the-negotiation-needed-flag This operation is not implemented in third_party/webrtc, so both before and after this CL we trust that when the negotiation needed signal reaches the main thread negotiation is still needed. This may not hold in some obscure edge cases like rollback. This is an existing problem not new to this CL. This CL implements the part of the spec that says to queue a task that fires the event and resets the flag if the flag is not already reset. This resolves a long-lived bug where onnegotiationneeded is fired multiple times - once per API call instead of once for each time the flag goes from false to true. Example: pc.addTrack(t1); pc.addTrack(t2); pc.onnegotiationneeded = () => { console.log('negotiation needed!'); } Before the CL, that fired twice. Now it fires once. Both tracks set the flag and queue a task, but by the time the second task is executed the flag has already been reset so the second event is not redundently fired. Bug: 740501, webrtc:7693 Change-Id: I0430d26158d50aa4d18d5f27f92a5a7bb3e68a9d Reviewed-on: https://chromium-review.googlesource.com/908450 Commit-Queue: Henrik Boström <hbos@chromium.org> Reviewed-by: Harald Alvestrand <hta@chromium.org> Cr-Commit-Position: refs/heads/master@{#535681} [modify] https://crrev.com/bd82fc5c072529638631929e7f1fe75f653b52c6/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-events.html [modify] https://crrev.com/bd82fc5c072529638631929e7f1fe75f653b52c6/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-onnegotiationneeded-expected.txt [modify] https://crrev.com/bd82fc5c072529638631929e7f1fe75f653b52c6/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-onnegotiationneeded.html [modify] https://crrev.com/bd82fc5c072529638631929e7f1fe75f653b52c6/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp [modify] https://crrev.com/bd82fc5c072529638631929e7f1fe75f653b52c6/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h
,
Feb 9 2018
,
Feb 15 2018
,
Feb 15 2018
,
May 25 2018
I don't this this is resolved, ONN still fires too often in 68.0.3438.3
,
May 25 2018
Agree. Running the fiddle from comment 1 in 68.0.3440.0 still causes OperationError: Failed to set local answer sdp: Called in wrong state: kStable Adding log statements shows it fires twice https://jsfiddle.net/yxbLvjm6/26/ negotiating... negotiating... OperationError: Failed to set local answer sdp: Called in wrong state: kStable checking ...negotiated connected completed Compare to Firefox: negotiating... ...negotiated checking connected
,
May 30 2018
I'm not sure this is a Chrome bug. I'm leaning towards bug in the code snippet or in the spec. The onnegotiaionneeded handler in https://jsfiddle.net/yxbLvjm6/26/ is an async function. The whole function is not executed at once. Any time you do await you allow tasks to execute, by the time the async function continues executing your code after an "await", one or more task execution cycles may have been processed. Which means if anything triggers another ONN, the event should fire. Because your async handler causes setLocalDescription and setRemoteDescription, further ONN is expected. What you end up doing it attempting to perform multiple O/A cycles in "parallel", which of course will fail. Your code snippet is suffering from reentrancy problems. You can make sure that only one ONN is handled at a time like so https://jsfiddle.net/yxbLvjm6/29/ but not sure how safe that is in more general use cases. jbruaroey@ Am I missing something? Shouldn't SLD/SRD trigger ONN and cause reentrancy per above? Why doesn't Firefox do that? If ONN shouldn't fire then it is for a different reason than this bug and a new bug should be filed.
,
May 30 2018
https://w3c.github.io/webrtc-pc/#dfn-update-the-negotiation-needed-flag is pretty clear about this: If connection's [[NegotiationNeeded]] slot is false, abort these steps. Fire a simple event named negotiationneeded at connection. What you are doing is still firing onn twice in a row as shown in the screenshot. This even happens in a much simpler scenario of var pc = new RTCPeerConnection(); pc.addStream(localStream) with a stream with two tracks or var pc = new RTCPeerConnection(); pc.addTrack(localStream.getTracks()[0]); pc.addTrack(localStream.getTracks()[1]);
,
May 30 2018
#16: That's correct but I believe I fixed that. If pc.addTrack(localStream.getTracks()[0]); pc.addTrack(localStream.getTracks()[1]); means ONN fires twice regardless of O/A cycles then that is a bug.
,
May 30 2018
Oh wow it does fire twice? https://jsfiddle.net/yxbLvjm6/30/
,
May 30 2018
Need to take another look, sounds like another regression.
,
May 31 2018
,
Jun 1 2018
The NextAction date has arrived: 2018-06-01
,
Jun 30 2018
a variant of this, from https://stackoverflow.com/questions/51099707/peerconnection-cannot-create-an-answer/51112783#51112783 Steps to reproduce: 1) go to https://webrtc.github.io/samples/src/content/peerconnection/munge-sdp/ 2) get media, create peerconnection, create offer, set offer 3) set remotePeerConnection.onnegotiationneeded = (e) => console.log('ONN') 4) check remotePeerConnection.signalingState -- should be have-remote-offer 5) call remotePeerConnection.addStream(localStream) As a result ONN is called twice and in have-remote-offer. Which is a no-no and breaks the mdn demo.
,
Jul 5
test for #22 is in https://github.com/webrtc/adapter/pull/839
,
Oct 28
Note there are actually two bugs here. See https://stackoverflow.com/a/53035315/918910 which reproduces both.
,
Oct 29
#24: Thanks Jan-Ivar. CC'ing folks; this would be a nice for one of us to fix when our hands are freed.
,
Oct 29
,
Nov 30
Added to the hotlist; this one needs some love :)
,
Nov 30
,
Dec 6
This will have big impact. Should be low hanging fruit.
,
Dec 7
,
Dec 10
|
||||||||||||
►
Sign in to add a comment |
||||||||||||
Comment 1 by jbruar...@mozilla.com
, Jan 23 2018