OBS VCE Plugin: Threading Explained
Today I’ll explain how threading works in the OBS VCE Plugin
, at least starting with Version 1.2.0pre4
. It is really simple but had a huge effect on performance and results. Let’s start with how things were handled before.
How it was Before
Before 1.2.0, the plugin was completely single-threaded: It tried to do as much as possible in the same thread as possible. This obviously had issues when the SubmitInput or QueryOutput time was larger than one ::encode call – something I didn’t think would ever happen, but it did happen and the effects were not nice. The new approach is much better, faster, delivers better quality and is less taxing too – which is strange considering that AMF is supposed to handle all synchronization for you…
What was Changed
To make it work, several changes had to be implemented. First I’d now have to queue both input and output, second I’d have to synchronize read and write access, third I’d have to figure out which parts of AMF actually need to be synchronized and lastly make everything work only when it is told to. Nobody wants an encoder that eats up all available system resources if 1.1.2 was any indication.
The Details of Threading in the Plugin
With the previous information known (planning works wonders for threading) I decided that two dedicated threads would do well: one to handle Submission and one to handle Querying.
The thread that ::encode runs on handles queueing new frames until the queue is full and dequeueing packets if there are some available. In the best case this takes less than 1ms, in the worst it takes up to 12ms.
The Submission Thread handles dequeueing frames and submitting them to AMF while the Querying Thread handles querying AMF for output and queueing up packets. All AMF accesses are synchronized in order to eliminate possible synchronization problems.
That’s basically how it works, the full implementation can be found on the GitHub of the project. I hope this clears up some questions about why OBS occasionally reports “Encoding overloaded” but the output file looks perfectly fine.