New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
replaceTrack and removeTrack: Synchronous? #1677
Comments
I argue that either all operations (addTrack, replaceTrack, removeTrack) should be synchronous or all operations should be asynchronous. I don't see any benefit to having these be asynchronous. Can we make them all synchronous? |
In the meantime I'm planning on implementing Chrome to do it synchronously and immediately resolve the promise. |
I have a faint memory that we thought step 10.1, |
I agree that the actual steps outlined in the document do not appear to require asynchronous operation. As I recall, the argument for asynchronous operation mostly related to hardware encoders within media capture devices, under the theory that there might be an interaction between the negotiated codecs and the capabilities of the device hardware encoder. However, my own experience in general is that hardware encoders are backstopped by software encoders, so that if the negotiated codec isn't supported in hardware, software is used instead. This can easily be determined (e.g. you know what codecs the hardware encoder supports), so doesn't require asynchronous operation by itself. |
I might be ignorant here, but why would changing a track require renegotiation? Isn't it just a different stream of images, and resolution, bitrate, etc, all handled by RTP packets and whatnot, not negotiated through SDP? setParameters() on the other hand allows you to make changes to the encoder settings. I imagine getting capabilities of HW or SW to require thread/process jumps, and encoders could fail at any time. Still isn't what the encoder is capable of a problem for createOffer() etc, when checking if negotiation is needed wouldn't you just look at the state of the current local description? |
I was told changing the track might require changing encoder due to limitations to what can be encoded, and what is negotiated would be the remote description, not local, but my above question remains the same: Is getting capabilities a relevant step to determining if negotiation is needed for replaceTrack/setParameters? |
I don't think we should entertain any symmetry here. In contrast,
createOffer and createAnswer are impervious to races, so I don't see a problem here. As to whether we should rethink the
That would observably be in violation of the spec, since the spec says |
My main concern was if replaceTrack() would "undo" part of what removeTrack() was doing, like setting the track after it was null, which would arguably lead to unexpected behavior, whether or not racy. If this is a problem though, replaceTrack() could abort if it notices it has been removed when dispatching. I may be prematurely alarmed.
Ack. I ran into problems because until Chrome supports transceivers, senders are removed (not just inactivated) on removeTrack(), but I should be able to get around those problems if async is the right approach. From 3 years ago:
Sounds good, I suspect this has already been thought of and replaceTrack() should remain asynchronous. |
Most async methods are spec'ed to modify JS state on success, so this doesn't seem unexpected to me, much like both of these produce the same result: let x;
Promise.resolve().then(() => x = 1);
x = 2; let x = 2;
Promise.resolve().then(() => x = 1); Similarly, both of these produce the same result: sender = pc.addTrack(t1);
sender.replaceTrack(t2);
pc.removeTrack(sender); sender = pc.addTrack(t1);
pc.removeTrack(sender);
sender.replaceTrack(t2); What may be unexpected is that In practice, I expect racing like this is usually a bug, and best avoided: sender = pc.addTrack(t1);
await sender.replaceTrack(t2);
pc.removeTrack(sender); |
I think the concern was whether any (off-main-thread) examination of the source would be needed to determine compatibility against each listed codec. FWIW I believe all browsers today internally deal with raw frames only, where this isn't an issue. |
@henbos Edge implemented setTrack (the original name for the method) synchronously 3 years ago, and we have had no issues. |
FWIW, it seems to me that As @jan-ivar points out in #1677 (comment) there can be cases when an off-main-thread examination of the source would be needed for Are there strong reasons why we would change |
No, feel free to close this. This does expose another example of how Chromium does async operations incorrectly (https://crbug.com/webrtc/8692) but that needs to be addressed regardless. |
@aboba unless you disagree I'll close this Issue per #1677 (comment) |
@stefhak I think you can close it. |
Paraphrasing the spec ignoring some details... replaceTrack is asynchronous:
The track could be muted before the queued task is executed, this could be a problem, but ignoring that for now.
removeTrack is synchronous:
What is the expected behavior of this?
I imagine this will result in the following steps:
The removeTrack still changes the direction of the transceiver, so I suspect the renegotiation will cause the remote track to be removed regardless of the order of things, but there might be races with what sender.track is when renegotiating?
The text was updated successfully, but these errors were encountered: