Closed YorVeX closed 1 year ago
This is an experiment that might also fail
Unfortunately indeed it did fail. The actual implementation worked fine, but the CPU load for my test scenario was even 1-2% higher with direct send mode than with the queued send implementation, also it fluctuated a bit more, which is not desirable.
I still decided to commit in b1c9661 and then revert so that code is archived for reference or in case it becomes useful as a base for other implementations.
The System.IO.Pipelines library that Beam uses does already come with its own buffer, but that's a pure binary buffer that doesn't allow reordering frames or any monitoring to notice when the buffer fills up (e.g. because the network bandwidth is insufficient), which is why a frame send queue was introduced. There was also the internal reason that the Pipelines FlushAsync() calls may not overlap with access to the buffer.
For this one relatively stable situation where the feed is only transmitted locally (no potential network bottlenecks), synced to the OBS render thread (no ordering issues) and uncompressed (no potential CPU bottlenecks) Beam should actually send the data directly without the frame send buffer and just take the relatively low risk of buffer overflows (they will still be detected indirectly by the timestamp age check).
It will introduce extra code only for this case, because some specific Pipelines FlushAsync() synchronization needs to be done, basically this should get an entirely separate send function outside of the normal send loop. But having a way to just directly send raw data with the lowest possible CPU usage was my motivation to invent Beam in the first place (and only then came the idea to add lossless compression options and so on), so I am willing to put some extra effort into really making this one specific case as efficient as possible.
This is an experiment that might also fail but it's certainly worth a try.