Hi all,I recently started playing with VP8 simulcasting, in order to add support for it to my Janus WebRTC server. I have something working, but many doubts on some aspects I'd like some feedback on, especially from those who've been through all this already. In fact, so far I've found this to be much more complicated than VP9 SVC (which I worked on in a branch I made available), which proved to be much easier to handle, and there doesn't seem to be much information around on how to handle this effectively apart from some higher level tutorials.Just to give you some context, I've implemented the foundations to handle how both Chrome (SDP munging) and Firefox (RID) implement simulcasting, so I'm able to negotiate support with both. So far I'm mostly working with the multiple SSRCs the browser generates when that happens, and I haven't dealt with the temporal layers yet (I plan to do that later on, re-using what I already did in that sense for VP9 SVC). I haven't shared the changes to Janus as a pull request yet (again, planning to do that as soon as it's in a better shape), but there's an online demo already in case you want to test this, and hopefully help me figure out what I may be doing wrong about the points that follow. You can find the link to the demo at the end of this post (a stupid trick to try and read the stuff in between, hehehe :-) ).Now, coming to the questions... for the sake of completeness, I'm providing a dump of the offer/answer exchanges that I do with Janus from Chrome 61, Firefox 54, and Firefox 56 respectively, in case you spot anything I'm missing there:
- I only see two of the three SSRCs in Chrome
Enabling simulcasting in Chrome by munging, should result in three SSRCs being used. I only see the first two of those, though. An old blog post by Gustavo Garcia says that can happen when no RTCP is done, which shouldn't be the case as we do that. About that, is the server supposed to do RTCP for all SSRCs, and is this required to "trigger" the third substream? If so, are separate or compound messages the way to go? There was an old question about this on this group, and apparently no response. As a side note, although REMB doesn't seem to be working for me when simulcasting (more on this later...), which might explain why the third substream never appears (Chrome probably sticks to 300k and thinks there's not enough bandwidth for that). The same happens when I enable three RIDs in Firefox, for instance, so that may be it, but not sure.
- Is there any in-band mechanism browser use to tell they'll temporarily stop sending a substream?
One thing I noticed while testing, is that often, while receiving substream #2 (the "middle quality"), I'd stop receiving those packets altogether, possibly as a decision process the browser made thinking there wasn't enough bandwidth. This becomes a problem if that was the substream I was forwarding to the user, as the video would just freeze. Ideally, there would be a way for the server to know this substream is gone for now, and fallback to the substream below that automatically. Is there such a mechanism, or are we just meant to figure this out by ourselves? I guess one way could be doing something like "didn't receive packets for X ms, switch substream", but it seems feeble, and possibly ambiguous considering simple packet loss may be occurring instead (and would still result in a partial freeze for the user until we figure that out).
- REMB seems to be ignored when simulcasting is enabled
As I was anticipating before, apparently REMB feedback Janus sends is ignored by both Chrome and Firefox when simulcasting is used, while it works as expected when it isn't. As far as I know, REMB was conceived to be a global bandwidth indicator, and not tied to a specific SSRC: from what I've read, in fact, REMB feedback in this case should result in the available bandwidth being "splitted" among the different encoders. This seems to be what's happening in my case, at least, as the default 300k are apparently "splitted" between the only two substreams I see (although one is 320x240, or 320x180 if I'm doing 16:9, and the other 640x480 or 640x360), with the only problem being that when I overwrite the REMB programmatically (something that in Janus I can do via API, see the demo below), the value I pass is ignored. Unfortunately I'm not knowledgable enough to figure out why that may be looking at the browser logs... any hint on what may be the cause, or what I should look for in the logs? Am I supposed to put all three SSRCs in the REMB SSRC feedback, or is this unneeded?
- Firefox 54 seems not to work when only two RID are provided
I noticed that in general (and unsurprisingly, considering it's a latter version) Firefox 56 seems to work much better and more consistently whan 54 when it comes to simulcasting (54 even crashed in my first experiments, but it was my fault for crafting a broken SDP, something I found an issue page for). One of the things that seem to break Firefox 54 is only setting two RIDs to enable simulcasting: when I do that, the video is never rendered, as if no keyframe ever arrived. I tried to capture the traffic using our internal Janus recordings format, and postprocessing those gave the same result. Setting the RIDs to three results in video being rendered for the first substream, although I'm then never able to switch (possibly again because of the lack of a keyframe). Firefox 56 works fine in both cases instead (apart from the fact I never see the third substream there either, possibly related to the above).- Is the PictureID rewriting really necessary?
The question comes from this thread Sergio Murillo started on Twitter. I implemented this as part of the changes I did for simulcasting, although I never encountered problems with this in the past. To clarify, in Janus some plugins do implement a form of pseudo-simulcasting, where you can basically "switch" the source of the media you're receiving dynamically (e.g., I was subscribed to Alice's video in a VideoRoom, I use the "switch" command to receive Bob's video instead, without renegotiating anything). This results, just as with simulcasting, in the RTP header being rewritten to make the switch transparent to receivers. We've used this for a long time and I never experienced problems with this (definitely no crashes, for instance). Just wondering if I was just lucky, or if this is not really a problem? In case it is, I should consider doing the same PictureID rewriting for the "legacy" switch feature as well.
Congrats. Inline...
El miércoles, 28 de junio de 2017, 17:47:22 (UTC+3), Lorenzo Miniero escribió:Hi all,I recently started playing with VP8 simulcasting, in order to add support for it to my Janus WebRTC server. I have something working, but many doubts on some aspects I'd like some feedback on, especially from those who've been through all this already. In fact, so far I've found this to be much more complicated than VP9 SVC (which I worked on in a branch I made available), which proved to be much easier to handle, and there doesn't seem to be much information around on how to handle this effectively apart from some higher level tutorials.Just to give you some context, I've implemented the foundations to handle how both Chrome (SDP munging) and Firefox (RID) implement simulcasting, so I'm able to negotiate support with both. So far I'm mostly working with the multiple SSRCs the browser generates when that happens, and I haven't dealt with the temporal layers yet (I plan to do that later on, re-using what I already did in that sense for VP9 SVC). I haven't shared the changes to Janus as a pull request yet (again, planning to do that as soon as it's in a better shape), but there's an online demo already in case you want to test this, and hopefully help me figure out what I may be doing wrong about the points that follow. You can find the link to the demo at the end of this post (a stupid trick to try and read the stuff in between, hehehe :-) ).Now, coming to the questions... for the sake of completeness, I'm providing a dump of the offer/answer exchanges that I do with Janus from Chrome 61, Firefox 54, and Firefox 56 respectively, in case you spot anything I'm missing there:
- I only see two of the three SSRCs in Chrome
Enabling simulcasting in Chrome by munging, should result in three SSRCs being used. I only see the first two of those, though. An old blog post by Gustavo Garcia says that can happen when no RTCP is done, which shouldn't be the case as we do that. About that, is the server supposed to do RTCP for all SSRCs, and is this required to "trigger" the third substream? If so, are separate or compound messages the way to go? There was an old question about this on this group, and apparently no response. As a side note, although REMB doesn't seem to be working for me when simulcasting (more on this later...), which might explain why the third substream never appears (Chrome probably sticks to 300k and thinks there's not enough bandwidth for that). The same happens when I enable three RIDs in Firefox, for instance, so that may be it, but not sure.You will get 3 resolutions only if you are transmitting in HD and the bitrate is big enough. Are you? What is your bwe according to webrtc-internals?
These are the bitrates needed for each substream to appear: https://chromium.googlesource.com/external/webrtc/+/master/webrtc/media/engine/simulcast.cc#42
- Is there any in-band mechanism browser use to tell they'll temporarily stop sending a substream?
One thing I noticed while testing, is that often, while receiving substream #2 (the "middle quality"), I'd stop receiving those packets altogether, possibly as a decision process the browser made thinking there wasn't enough bandwidth. This becomes a problem if that was the substream I was forwarding to the user, as the video would just freeze. Ideally, there would be a way for the server to know this substream is gone for now, and fallback to the substream below that automatically. Is there such a mechanism, or are we just meant to figure this out by ourselves? I guess one way could be doing something like "didn't receive packets for X ms, switch substream", but it seems feeble, and possibly ambiguous considering simple packet loss may be occurring instead (and would still result in a partial freeze for the user until we figure that out).No.
- REMB seems to be ignored when simulcasting is enabled
As I was anticipating before, apparently REMB feedback Janus sends is ignored by both Chrome and Firefox when simulcasting is used, while it works as expected when it isn't. As far as I know, REMB was conceived to be a global bandwidth indicator, and not tied to a specific SSRC: from what I've read, in fact, REMB feedback in this case should result in the available bandwidth being "splitted" among the different encoders. This seems to be what's happening in my case, at least, as the default 300k are apparently "splitted" between the only two substreams I see (although one is 320x240, or 320x180 if I'm doing 16:9, and the other 640x480 or 640x360), with the only problem being that when I overwrite the REMB programmatically (something that in Janus I can do via API, see the demo below), the value I pass is ignored. Unfortunately I'm not knowledgable enough to figure out why that may be looking at the browser logs... any hint on what may be the cause, or what I should look for in the logs? Am I supposed to put all three SSRCs in the REMB SSRC feedback, or is this unneeded?I put all of them and it works. Not sure if it should work with a single one.
- Firefox 54 seems not to work when only two RID are provided
I noticed that in general (and unsurprisingly, considering it's a latter version) Firefox 56 seems to work much better and more consistently whan 54 when it comes to simulcasting (54 even crashed in my first experiments, but it was my fault for crafting a broken SDP, something I found an issue page for). One of the things that seem to break Firefox 54 is only setting two RIDs to enable simulcasting: when I do that, the video is never rendered, as if no keyframe ever arrived. I tried to capture the traffic using our internal Janus recordings format, and postprocessing those gave the same result. Setting the RIDs to three results in video being rendered for the first substream, although I'm then never able to switch (possibly again because of the lack of a keyframe). Firefox 56 works fine in both cases instead (apart from the fact I never see the third substream there either, possibly related to the above).- Is the PictureID rewriting really necessary?
The question comes from this thread Sergio Murillo started on Twitter. I implemented this as part of the changes I did for simulcasting, although I never encountered problems with this in the past. To clarify, in Janus some plugins do implement a form of pseudo-simulcasting, where you can basically "switch" the source of the media you're receiving dynamically (e.g., I was subscribed to Alice's video in a VideoRoom, I use the "switch" command to receive Bob's video instead, without renegotiating anything). This results, just as with simulcasting, in the RTP header being rewritten to make the switch transparent to receivers. We've used this for a long time and I never experienced problems with this (definitely no crashes, for instance). Just wondering if I was just lucky, or if this is not really a problem? In case it is, I should consider doing the same PictureID rewriting for the "legacy" switch feature as well.The PictureID rewriting is needed if you are using temporal scalability, if you don't you don't need to rewrite them.
With temporal scalability and latest versions of Chrome I don't see any other way to 15fps when dropping layer2 than rewriting pictureIds. If somebody is able to get 15fps without rewriting let me know please.
--
---
You received this message because you are subscribed to the Google Groups "discuss-webrtc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrtc+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/discuss-webrtc/47a871d7-32f4-4340-afaa-2922a778696e%40googlegroups.com.
Lorenzo, are you seeing reasonable simulcast output from Firefox? I've been testing with nightly and am seeing poor framerate, sometimes there are gaps of >1 second between packets of one of the simulcast streams coming out of Firefox, wondering if anyone else is seeing that as well. It looks to be on the frame boundary, so it seems to be a performance problem where it's just taking a long time to encode the frame for each of the 3 streams.
-brian
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrt...@googlegroups.com.
First and foremost, congratulations for such your work!
More inline:
2017-06-28 17:10 GMT+02:00 Gustavo García <gust...@gmail.com>:
> REMB seems to be ignored when simulcasting is enabled
> As I was anticipating before, apparently REMB feedback Janus sends is
> ignored by both Chrome and Firefox when simulcasting is used, while it works
> as expected when it isn't. As far as I know, REMB was conceived to be a
> global bandwidth indicator, and not tied to a specific SSRC: from what I've
> read, in fact, REMB feedback in this case should result in the available
> bandwidth being "splitted" among the different encoders.
The problems with REMB are:
1) It's an abandoned draft, so you cannot rely on what the draft says,
an even less in how browsers decide to implement it. And nobody will
clarify how a specific implementation behaves.
2) REMB feedback messages have a list of SSRCs for which the given
bitrate applies. So no, it's not a "global bandwidth indicator".
Theoretically you may apply different sending bitrate limits to
separate streams (SSRCs) carried over the same transport. However,
AFAIR, Chrome (and hence all the others) don't behave that way and,
instead, apply a global limit to all the streams sent over the
transport. Not 100% sure about this.
> This seems to be
> what's happening in my case, at least, as the default 300k are apparently
> "splitted" between the only two substreams I see (although one is 320x240,
> or 320x180 if I'm doing 16:9, and the other 640x480 or 640x360), with the
> only problem being that when I overwrite the REMB programmatically
> (something that in Janus I can do via API, see the demo below), the value I
> pass is ignored. Unfortunately I'm not knowledgable enough to figure out why
> that may be looking at the browser logs... any hint on what may be the
> cause, or what I should look for in the logs? Am I supposed to put all three
> SSRCs in the REMB SSRC feedback, or is this unneeded?
Can you open chrome://webrtc-internals and check the bweforvideo info
and graph? it should tell you which limit it's applying to the video.
So, if Janus send 500kbps in REMB feedback messages, you should see
such a value in there. What do you see instead? the default 300?
NOTE: When enabling "simulcast" in Chrome, chrome://webrtc-internals
just reports info for one of the sending SSRCs. You know: "Works For
Me in Google Hangouts&Meet So Don't Bother Me®️"
| // simulcast layers at what bitrates (maximum, target, and minimum). | |
| // Important!! Keep this table from high resolution to low resolution. | |
| const SimulcastFormat kSimulcastFormats[] = { | |
| {1920, 1080, 3, 5000, 4000, 800}, | |
| {1280, 720, 3, 2500, 2500, 600}, |