obs-studio/libobs
jp9000 11106c2fce libobs: Redesign/optimize frame encoding handling
Previously, the design for the interaction between the encoder thread
and the graphics thread was that the encoder thread would signal to the
graphics thread when to start drawing each frame.  The original idea
behind this was to prevent mutually cascading stalls of encoding or
graphics rendering (i.e., if rendering took too long, then encoding
would have to catch up, then rendering would have to catch up again, and
so on, cascading upon each other).  The ultimate goal was to prevent
encoding from impacting graphics and vise versa.

However, eventually it was realized that there were some fundamental
flaws with this design.

1. Stray frame duplication.  You could not guarantee that a frame would
   render on time, so sometimes frames would unintentionally be lost if
   there was any sort of minor hiccup or if the thread took too long to
   be scheduled I'm guessing.

2. Frame timing in the rendering thread was less accurate.  The only
   place where frame timing was accurate was in the encoder thread, and
   the graphics thread was at the whim of thread scheduling.  On higher
   end computers it was typically fine, but it was just generally not
   guaranteed that a frame would be rendered when it was supposed to be
   rendered.

So the solution (originally proposed by r1ch and paibox) is to instead
keep the encoding and graphics threads separate as usual, but instead of
the encoder thread controlling the graphics thread, the graphics thread
now controls the encoder thread.  The encoder thread keeps a limited
cache of frames, then the graphics thread copies frames in to the cache
and increments a semaphore to schedule the encoder thread to encode that
data.

In the cache, each frame has an encode counter.  If the frame cache is
full (e.g., the encoder taking too long to return frames), it will not
cache a new frame, but instead will just increment the counter on the
last frame in the cache to schedule that frame to encode again, ensuring
that frames are on time and reducing CPU usage by lowering video
complexity.  If the graphics thread takes too long to render a frame,
then it will add that frame with the count value set to the total amount
of frames that were missed (actual legitimately duplicated frames).

Because the cache gives many frames of breathing room for the encoder to
encode frames, this design helps improve results especially when using
encoding presets that have higher complexity and CPU usage, minimizing
the risk of needlessly skipped or duplicated frames.

I also managed to sneak in what should be a bit of an optimization to
reduce copying of frame data, though how much of an optimization it
ultimately ends up being is debatable.

So to sum it up, this commit increases accuracy of frame timing,
completely removes stray frame duplication, gives better results for
higher complexity encoding presets, and potentially optimizes the frame
pipeline a tiny bit.
2014-12-31 04:03:47 -08:00
..
callback (API Change) Use const params where applicable 2014-09-26 17:23:07 -07:00
data libobs: Add NV12_Reverse shader 2014-12-21 10:14:18 -08:00
graphics graphics: Add gs_effect_loop helper function 2014-11-19 19:46:27 -08:00
media-io libobs: Redesign/optimize frame encoding handling 2014-12-31 04:03:47 -08:00
util libobs: Add process piping functions 2014-11-27 00:07:48 -08:00
CMakeLists.txt libobs: Use FFmpeg for image loading by default 2014-12-04 15:38:58 +01:00
LibObsConfig.cmake.in cmake: Export plugin data destination 2014-09-27 09:41:32 -07:00
LibObsConfigVersion.cmake.in Export libobs cmake target, so external plugins can be built without ugly hacks 2014-05-08 14:43:16 +02:00
obs-audio-controls.c libobs: Fix a few warnings 2014-12-28 01:03:10 -08:00
obs-audio-controls.h libobs: Add peak hold property to volmeter 2014-12-14 18:39:54 +01:00
obs-avc.c libobs: Add function to determine AVC keyframes 2014-12-21 10:14:22 -08:00
obs-avc.h libobs: Add function to determine AVC keyframes 2014-12-21 10:14:22 -08:00
obs-cocoa.c (API Change) Refactor module handling 2014-07-27 17:29:10 -07:00
obs-config.h libobs: Set version to 0.7.0 2014-12-15 01:55:18 -08:00
obs-data.c Sort obs_data_items by name 2014-10-01 15:32:49 +02:00
obs-data.h (API Change) Remove pointers from all typedefs 2014-09-25 21:48:11 -07:00
obs-defs.h Change macro to MODULE_MISSING_EXPORTS for clarity 2014-07-27 17:28:35 -07:00
obs-display.c (API Change) Use const params where applicable 2014-09-26 17:23:07 -07:00
obs-encoder.c libobs: Fix bug when SEI not present 2014-12-21 10:14:23 -08:00
obs-encoder.h libobs: Use extern "C" on export headers if C++ 2014-12-21 10:14:21 -08:00
obs-ffmpeg-compat.h Use propper ffmpeg compatiblity instead of relying on deprecated functions 2014-06-28 20:54:14 +02:00
obs-interaction.h Add interaction support to libobs 2014-09-15 17:19:37 -05:00
obs-internal.h libobs: Redesign/optimize frame encoding handling 2014-12-31 04:03:47 -08:00
obs-module.c (API Change) Remove pointers from all typedefs 2014-09-25 21:48:11 -07:00
obs-module.h Some documentation improvements in obs-module.h 2014-10-19 15:00:07 +02:00
obs-nix.c Fix calculation of physical memory on linux systems 2014-10-05 13:01:19 -07:00
obs-output.c libobs: Fix potential crash on output stop 2014-12-31 04:03:45 -08:00
obs-output.h libobs: Use extern "C" on export headers if C++ 2014-12-21 10:14:21 -08:00
obs-properties.c libobs: Add obs_property_list_insert_* functions 2014-12-09 14:21:02 -08:00
obs-properties.h libobs: Add obs_property_list_insert_* functions 2014-12-09 14:21:02 -08:00
obs-scene.c libobs: Prevent infinite source recursion 2014-12-28 01:04:26 -08:00
obs-scene.h Scenes: Implement more item positioning features 2014-06-15 20:33:13 -07:00
obs-service.c (API Change) Pass data to get_properties when possible 2014-10-01 15:39:57 +02:00
obs-service.h libobs: Use extern "C" on export headers if C++ 2014-12-21 10:14:21 -08:00
obs-source.c libobs: Fix force mono channel count 2014-12-28 03:51:06 -08:00
obs-source.h libobs: Refactor source volume transition design 2014-12-28 01:51:43 -08:00
obs-ui.h Revamp API and start using doxygen 2014-02-12 08:04:50 -07:00
obs-video.c libobs: Redesign/optimize frame encoding handling 2014-12-31 04:03:47 -08:00
obs-view.c (API Change) Remove pointers from all typedefs 2014-09-25 21:48:11 -07:00
obs-windows.c (API Change) Refactor module handling 2014-07-27 17:29:10 -07:00
obs.c libobs: Redesign/optimize frame encoding handling 2014-12-31 04:03:47 -08:00
obs.h libobs: Add flag to force source audio to mono 2014-12-28 01:51:55 -08:00
obs.hpp Fix OBSRef move assignment not releasing the previous reference 2014-10-29 16:17:07 +01:00
obsconfig.h.in Export plugin destination and relative prefix to obsconfig.h 2014-07-26 14:27:39 +02:00