YorVeX / xObsBeam

OBS plugin to transmit video and audio feeds between OBS instances, raw, or with lossless or lossy compression. NDI alternative.
https://obsproject.com/forum/resources/beam.1705/
MIT License
89 stars 5 forks source link

set double the size of the buffer as a limit #35

Open lublak opened 1 month ago

lublak commented 1 month ago

To support max Buffertime: grafik

YorVeX commented 1 month ago

When you specifically mentioned 5 seconds delay on that Teleport thread I was like "how nice, that's exactly the limit I got in Beam" - now I am a bit confused about this PR 🤔

In the world of live streaming 5 seconds is already taking ages when you're a viewer eagerly waiting for a reaction to your chat, but maybe your use case is different and it's a live feed without chat?

I actually did consider that "panic cutoff button" use case, but even there when fully in shock and panic, 5 seconds is quite long to pull the trigger on it, do you really think you'd need 10? I am a bit hesitant setting this limit too high, people tend to max out things without thinking about it too much and next thing I know I get crash reports because people max out their RAM. And with every request like that I wonder where my limit is, when the next person files one for 20 seconds, then for 30... 😀

I am also on Discord with username "yorvex" if you want to discuss this further (in German 😉)

lublak commented 1 month ago

@YorVeX In general, it is not important. I only use a buffer size of 3000 and a limit of 5000 anyway. The problem is if you look at my picture, if you take a buffer size of 5000, a limit of 5000 is not enough. 5000 - 5000 = 0 (reconnect every microseconds?) So I thought, if you have a buffer of 0 and the maximum limit is 5000, shouldn't the limit for a buffer size of 5000 be 10000?

Just for information: I have only increased renderDelayLimitProperty, frameBufferTimeProperty is still at 5000.

YorVeX commented 1 month ago

Ah, right, I focused on the "double the size of the buffer" part in the title and missed the "as a limit" part 😆

From your use case you might think of that setting merely as a delay, but it also is a fail-safe against any hiccups in your production chain. As an example, if your network bandwidth is temporarily insufficient because of some file transfer and your receiver is now lagging 4 seconds behind on the feed, that won't cause any harm at all if you had a 5 seconds buffer. And when the network situation recovers, the buffer can fill back up and no viewer will have ever noticed you had an issue. As long as the buffer doesn't run entirely dry you're good.

For some, this is actually the primary use case of the buffer and the unavoidable delay caused by it is an unwanted side-effect (at least where people from the chat expect fast reactions), so a trade-off has to be found between delay and stability (usually 500 to 1500 ms are the values that make the most sense in this scenario). Where you are coming from, you get the delay you want, and the extra stability as a bonus - especially compared to render delay filters, which would still show your network hiccups on the receiving end, just delayed by 5 seconds.

Compared to this powerful mechanism the render limit is a really dumb thing. All it does is detect when the feed is lagging too far behind and then force a restart of the stream. Trying to compensate for potential issues using the buffer is so much better than this, that I actually thought about just making it a toggle so you can only use either the buffer or the limit. Also the two concepts kinda contradict each other. One mechanism is for adding delay, either deliberately or as an unavoidable side-effect you made a conscious decision about, the other is for limiting the delay, with the idea "I rather want to kill and reconnect the stream than having my delay run higher than X".

But the combination might still make sense when both values are set rather low: Instead of buffering 1000 ms and being a full second behind, you could buffer 500 ms and already gain a reasonable stability boost from that while keeping the delay still very low, and additionally (more as a separate use-case here) you might want to make sure the total delay doesn't get out of control and limit it to 1000 ms.

And for the technical side of things: before your 5000 ms buffer is starving and you have an additional delay of another 5 seconds from network issues, you will get some sort of reconnect or reset on network or other levels anyway. Anything that huge buffer can't protect you from will mean something with your setup is so wrong that it will die anyway for various reasons, long before a render delay limit would kick in.

So I think the main issue here is not the render limit setting having a too low max value, but the phrasing of the warning message in your screenshot. It says the render delay limit needs to be higher, and while that is technically correct, it implies that the solution must be increasing the delay limit (and then you notice you can't solve it that way, as you cannot set it higher). But the actual correct solution would be to set the buffer to a lower value. Again, a combination of both values at even higher levels just doesn't make any sense. Actually, my suggestion to your case would be to just disable the render delay limit entirely and only go with the buffer. The situation where such a high buffer would be depleted and you get an additional delay before any other kind of reset happens just won't ever occur.

I hope that made some sense. If it didn't, it's probably more my fault than yours, I was struggling a bit to explain it properly. The problem is that part of my reasoning is knowledge I gathered during months of developing this and learning about the various difficulties coming from how things are implemented in OBS, for example (and that initially sparked the idea for the limiting feature) if you run that kind of transmission from OBS to OBS, over time the total delay between the two will vary. Usually it will slowly increase (can take minutes or hours), in my tests often to about additional 700-800 ms, then later slowly decrease, sometimes back to 200 ms, but never back to 0 unless you reset the stream. This will happen with Beam, Teleport or NDI all the same, as it's something that is coming from OBS and not the transmission protocols/plugins. I think for your use case it's irrelevant (audio and video still stay in sync, it's only the delay of the A/V feed as a whole between sender and receiver that is affected), but it can kill some others entirely.

That's only one of several things that determined how I laid out the options in Beam around the buffering and the code around error handling and (at least for me) it's impossible to recap all of that now, so in worst case this might just be a "trust me bro" situation, but it really wouldn't make sense to have a 5 second buffer with an even higher render delay limit 😛