This adds the windows version of game capture.
New features:
- An option to hook any fullscreen application automatically (that
doesn't have borders) so that no specific window configuration is
required. Definitely a sorely needed feature
- An option to force memory capture for the sake of compatibility with
things such as SLI, multi-adapter setups (usually laptops), as well as
the ability to be used with the OpenGL renderer
- An optimization option to force scaling on the GPU before texture
transfer, reducing the transfer bandwidth (which is especially
important for compatibility capture)
- An optimization option to limit framerate to the current OBS framerate
to improve capture performance (mostly useful for compatibility
capture)
- An option to capture third-party overlays (such as steam)
- Logging improvements, game capture log will now be sent via pipe
instead of written to a separate file, making diagnosing problems a
little bit easier
This library is a completely refactored and rewritten version of the
original graphics hook. The code is more clean, readable, and has a
variety of new features, such as scaling and forcing memory capture.
Currently, only D3D9, 10, and 11 are implemented. (This commit may be
updated on this branch)
Before, game capture would find addresses to important graphics
functions by creating a graphics context for the desired API inside of
the hook, and then find the function addresses that way.
The big problem with that is that the context could often cause the
hooked application to crash, especially if another hook was active.
This bypasses that entire need by a simple console application that
creates the contexts, finds the hook address offsets and then returns
them via console output.
This header contains global defines, structures, and helper inline
functions for the graphics hook that will be shared between game
capture, the hook, and the get-graphics-addrs helper application.
These functions allow the safe hooking of windows functions,
specifically windows API functions that may or may not have built-in
machine code to help aid in reverse chain hooks.
If a new hook is applied to an existing forward hook, that hook will be
preserved to prevent that new hook's data from being removed
unintentionally.
Hopefully with all these precautions this will reduce the likelihood of
crashes and abnormal hook behavior, while allowing existing hooks to be
preserved, and allowing new hooks to be applied.
The glDebugMessageCallback function will set a callback that will relay
all messages coming from the driver (on supported drivers at least).
For nvidia, sometimes there are a lot of irrelevant messages, which is
nice depending on the type of application you're writing.
I actually at first thought these messages were important, but it turns
out that they're almost always irrelevant and not actually warnings.
Most of the messages at a certain type/severity are mostly for debugging
purposes or minor hints about how to maximize performance, so
unfortunately there ends up being a lot of pointless spam in the debug
output.
The particular performance messages are related to optimizations you can
get via multithreading, and are optimizations you would expect for games
more than for this type of application. They don't really apply for our
use cases most of the time.
High severity messages however are not omitted regardless of message
type.
These messages can be enabled again by simply defining the
SHOW_ALL_GL_MESSAGES macro.
Just for a quick background: D3D's fmod intrinsic is very imprecise.
Naturally floating points aren't precise at all, and when the numbers
you're dealing with become very large, it can often be off by 0.1 or
more.
However, apparently 0.1 isn't enough of an offset to ensure a proper
value when using the fmod intrinsic and then flooring the value. 0.2
seems to fix the issue and make the image display properly.
Originally I made the "win_pipe" stuff for named pipes on windows but it
was argued that it should be available to all modules and
programs/libraries that the modules might communicate with.
It cannot really be put in to libobs due to the fact that there would
hypothetically be things unrelated to libobs that might want to use it,
so I felt the best option was just to create a simple static library
specific for interprocess communication.
Non-windows versions of these functions are still yet to be implemented.
This fixes a bug where if INCLUDE_MINIMIZED was set and the window size
was (0, 0), the window would still be excluded from the resulting list
that was created.
This adds obfuscation functions primarily for use with GetProcAddress.
This takes an obfuscated string and uses a simple integer key to
de-obfuscate it to the intended function name string, which is then
loaded dynamically using GetProcAddress.
This is typically only used with functions such as OpenProcess,
SetWindowsHookEx, and the like, which can often be misinterpreted the
wrong way by security programs if those strings are found within the
strings segment of a scanned executable.
When getting the class/title/exe of a particular window handle in the
build_window_strings function, always set the class/title/exe pointers
to null to prevent any potential references to invalid values if any of
them do not happen to be set for whatever reason.
On certain GPUs, if you don't flush and the window is minimized it can
endlessly accumulate memory due to what I'm assuming are driver design
flaws (though I can't know for sure). The flush seems to prevent this
from happening, at least from my tests. It would be nice if this
weren't necessary.
This replaces the old code for the audio meter that was using
calculations in two different places with the new audio meter api.
The source signal will now emit simple levels instead of dB values,
in order to avoid dB conversion and calculation in the source.
The GUI on the other hand now expects simple position values from
the volume meter api with no knowledge about dB calculus either.
That way all code that handles those conversions is in one place,
with the option to easily add new mappings that can be used
everywhere.
This adds a volume meter object to libobs that can be used by the GUI
or plugins to convert the raw audio level data from sources to values
that can easily be used to display the audio data.
The volume meter object will use the same mapping functions as the
fader object to map dB levels to a scale.
Add more details installation/compilation instructions for
Redhat-based distros, debian-based distros, Arch Linux, Gentoo, and
OpenSUSE distros
Fix incomplete Debian installation instructions, and separate out
instructions and package requirements that were specific to Debian-based
distros. Most of the instructions in the file were previously specific
only to Debian. Also added some brief instructions for an easy and
minimal FFmpeg installation.
In older versions of visual studio 2013 microsoft's WORTHLESS C compiler
has a bug where it will, almost at random, not be able to handle having
variables declared in the middle of a function and give the warning:
"illegal use of this type as an expression". It was fixed in recent
VS2013 updates, but I'm not about to force everyone to update to it.
Because a vec3 structure can contain a __m128 variable and not the
expected three floats x, y, and z, you must use vec3_set when
setting a value for a vec3 structure to ensure that it uses the proper
intrinsics internally if necessary.
This adds functions for piping a command line program's stdin or stdout.
Note however that this is unidirectional only.
This will be especially useful later on when implementing MP4 output,
because MP4 output has to be piped to prevent unexpected program
termination from corrupting the file.
There's a little too much junk in the CONTRIBUTING file. I feel like
it's unnecessary to say some of the things that were being said in
there. It really needs to be to the point
This replaces the code for volume control with a newer version that
uses the new fader implementation in order to control the fader/slider
position and source volume.
The volume label will now indicate the gain in dB instead of percent,
mainly because it looks cool and is easy to do.
Due to libobs saving the multiplier option for the source instead of
the slider/fader positon, existing volume levels will (mostly) stay
the same with only the slider beeing at a different position.
This is of course within the resolution of the slider (100 steps).
This adds a new library of audio control functions mainly for the use in
GUIS. For now it includes an implementation of a software fader that can
be attached to sources in order to easily control the volume.
The fader can translate between fader-position, volume in dB and
multiplier with a configurable mapping function.
Currently only a cubic mapping (mul = fader_pos ^ 3) is included, but
different mappings can easily be added.
Due to libobs saving/restoring the source volume from the multiplier,
the volume levels for existing source will stay the same, and live
changing of the mapping will work without changing the source volume.
This function greatly simplifies the use of effects by making it so you
can call this function in a simple loop. This reduces boilerplate and
makes drawing with effects much easier. The gs_effect_loop function
will now automatically handle all the functions required to do drawing.
---------------------
Before:
gs_technique_t *technique = gs_effect_get_technique("technique");
size_t passes = gs_technique_begin(technique);
for (size_t pass = 0; pass < passes; pass++) {
gs_technique_begin_pass(technique, pass);
[draw]
gs_technique_end_pass(technique);
}
gs_technique_end(technique);
---------------------
After:
while (gs_effect_loop(effect, "technique")) {
[draw]
}
If you look at the previous commits, you'll see I had added
obs_source_draw before. For custom drawn sources in particular, each
time obs_source_draw was called, it would restart the effect and its
passes for each draw call, which was not optimal. It should really use
the effect functions for that. I'll have to add a function to simplify
effect usage.
I also realized that including the color matrix parameters in
obs_source_draw made the function kind of messy to use; instead,
separating the color matrix stuff out to
obs_source_draw_set_color_matrix feels a lot more clean.
On top of that, having the ability to set the position would be nice to
have as well, rather than having to mess with the matrix stuff each
time, so I also added that for the sake of convenience.
obs_source_draw will draw a texture sprite, optionally of a specific
size and/or at a specific position, as well as optionally inverted. The
texture used will be set to the 'image' parameter of whatever effect is
currently active.
obs_source_draw_set_color_matrix will set the color matrix value if the
drawing requires color matrices. It will set the 'color_matrix',
'color_range_min', and 'color_range_max' parameters of whatever effect
is currently active.
Overall, these feel much more clean to use than the previous iteration.
This adds a property to the source properties which lets the user
specify the X server to capture from. Since this is probably something
thats only useful under certain circumstances it is implemented as
an advanced setting which is only shown when the corresponding option
for advanced settings is checked.
This moves the code to start/stop the capture to respectively named
function in order to clean up the update function.
This means that the capture is stopped/started whenever the settings are
changed. While this increases overhead for some settings, this will also
enable future settings that require a full restart of capture process.
This adds the screen id from the source properties to the source
struct and changes the geometry function to use that value instead
of requiring the settings object of the source.