Code submissions have continually suffered from formatting
inconsistencies that constantly have to be addressed. Using
clang-format simplifies this by making code formatting more consistent,
and allows automation of the code formatting so that maintainers can
focus more on the code itself instead of code formatting.
Adds circlebuf_push_front_zero and circlebuf_push_back_zero to
conveniently push zeroed data to the front/back of the buffer without
having to create an intermediary buffer to accomplish the same thing.
If size is 0 after popping data from the front or back, set the
start/end points to 0 as well to ensure that any subsequent buffer
pushes start from the beginning of the buffer rather than the middle of
the buffer. Reduces potential unnecessary operations in that case.
Additionally, this fixes a bug with circulebuf_pop_back where if start
position was 0, and all the data was popped off the buffer (equal to the
capacity), the end position would be equal to the original size. As an
example to replicate the bug, push 5, pop 5, then push 10. The
start/end points will be invalid.
Closesjp9000/obs-studio#954
When the C header circlebuf.h is used from a C++ source file, this
implicit cast from void to uint8_t* will cause an error unless changed
to an explicit cast.
A little bit of history about frame dropping:
I did a large number of experiments with frame dropping in old versions
of OBS1, and it's not an easy thing to deal with. I tried just about
everything from standard i-frame delay, to large buffers, to dumping
packets, to super-unnecessarily-complex things that just ended up
causing more problems than they was worth.
When I did my experiments, I found that the most ideal frame drop system
(in terms of reducing the amount of total data that needed to be
dropped) was in the 0.4xx days where I had a 3 second frame-drop buffer
where I could calculate the actual buffer size in bytes, and then
intellgently choose packets in that buffer to trim it down to a specific
size while minimizing the number of p-frames and i-frames dropped, and
preventing the actual impact of dropped frames on the stream. The
downside of it was that it required too much extra latency, and far too
many people complained about it, so it was removed in favor of the
current system.
The current system I just refer to just as 'packet dumping', which when
combined with low keyframe intervals (like most services use these
days), is the next-best method from my experience. Just dump the buffer
when you reach a threshold of buffering (which I prefer to measure with
time rather than in size), then wait for a new i-frame. Simple,
effective, and reduces the risk of consecutive buffering, while still
having fairly low impact on the stream output due to the low keyframe
interval of services.
By the way, audio will not (and should not ever) be dropped, lest you
end up with syncing issues (among other nasty things) specific to server
implementation.
- Circular buffer code wasn't correctly handling the splitting of
newly placed data segments, the code was untested and turned out to
just be backwards. It now copied the data to the back and front of
the buffer properly.
- Mixing still isn't implemented, but the audio system should be able
to start up, and mix at least once audio line for the time being.
Will have to write some test audio sources to verify things are
working properly, and build the rest of the output functionality.