This adds code to set up the udev monitoring library and use the events
to detect connects/disconnects of devices.
When the currently used device is disconnected the plugin will stop
recording and clean up, so that the device node is freed up.
On reconnection of the device the plugin will use the event to
automatically start the capture again.
If the sample format used by PulseAudio can not be converted into an
OBS audio format it will be handled as AUDIO_FORMAT_UNKNOWN which will
not result in a proper audio recording. So instead we request a format
that OBS supports from PulseAudio and let it do the format conversion.
The format PA_SAMPLE_S24_32LE is a 24 bit audio format in 32 bit integers
and not a 32 bit audio format and so it should no be mapped to
AUDIO_FORMAT_32BIT.
Before it was giving timestamps based upon system time for each new
segment of audio data. Also, it was subtracting pulse latency from the
audio timestamp, which seems like it was really meant for use with the
pulse audio time rather than system time.
Now, it just uses system time for timestamps. Still might not be
totally perfect, but seems to be much better than it was.
This also removes the latency calculation. Latency is no longer used
because we're not using pulseaudio timing.
Allows adding Syphon servers as sources, and provides game-capture if
used with SyphonInject (specifically the scripting additions have to be
installed for SyphonInject to work from within OBS)
Typedef pointers are unsafe. If you do:
typedef struct bla *bla_t;
then you cannot use it as a constant, such as: const bla_t, because
that constant will be to the pointer itself rather than to the
underlying data. I admit this was a fundamental mistake that must
be corrected.
All typedefs that were pointer types will now have their pointers
removed from the type itself, and the pointers will be used when they
are actually used as variables/parameters/returns instead.
This does not break ABI though, which is pretty nice.
This adds a check whether the video format from the device is compatible
with obs. This could either happen if the "Leave unchanged" option is
selected for the video format, or if the driver simply overwrites the
requested video format.
Due to the refactoring of the update function the separation of data
members only to be accessed from inside/outside the capture thread is
no longer needed.
The old implementation of this function assumed that there would be some
settings that could be changed on the fly without restarting the
capture. That was actually never used for any setting.
Since the helper function also needs to pack/unpack the resolution, the
pack/unpack functions were moved to the helper library and prefixed with
v4l2_ in order to avoid possible collisions.
This was added at a time where the source properties dialog did not
pop up automatically on source creation. Now when the properties are
displayed the first device in the select input will be selected by
default if there was none already specified by the source settings.
This will make the code cleaner and also save one redundant round of
device enumeration.
The capabilities flags that were used previously describe all
capabilities the physical device offers. This would cause devices
that are accessible through multiple device nodes to show up with
all device nodes while only one of the nodes might actually offer
the needed video capture capability.
If the device has more nodes the CAP_DEVICES_CAP flag might be set
in which case the device_caps field is filled with the capabilities
that only apply to that specific node that is opened.
This prevents certain issues I've encountered with devices where they
expect to shut down in a specific thread they started up in, as well as
a number of other issues, such as the configuration dialogs.
The configuration dialogs require that a message loop be present, and
this was not the case previously because everything was in the video
thread, which has no windows-specific code.
Configuration/crossbar/etc dialogs will now execute correctly.
This adds support for dynamic format changes on the fly. Format,
resolution, sample rate, can all now be changed by the current
directshow device on the fly.
On an asynchronous video source, the source resolution is automatically
handled by the core, and set to the resolution of the last video data
that was sent. There is no need to manually specify a resolution.
When setting up the capture, the plugin will now query pulse for the default
format of the specific source instead of the server.
This is useful if a source has different settings than what the defaults are
for the server, e.g. when the source is an output with 5.1 surround sound
and the microphone input is mono while the server defaults to stereo sound.
the pos_x and pos_y variables were somewhat deceptive, because they were
not actually the poition of the cursor. They represented the position
of the cursor's bitmap on the screen, not the position of the cursor.
This implements audio support, allowing not only the ability to capture
the built-in audio from the video device's audio capture pin, but also
the ability to override the default audio with a custom audio device.
The DShowInput::Update function was split up and refactored a bit, as it
was getting a bit large and messy.
This fixes a bug where the pulseaudio plugin always reported
a speaker layout of stereo to obs, regardless of how many channels
pulseaudio actually recorded.
If the default number of channels was different to 2 this would
cause audio distortion.
Originally, I tested the fontconfig code on mac and it was working
swimmingly. However, it seems to be related to the fact that I am using
the ports/homebrew version of fontconfig. Most users do not have that
version, and instead use the system built-in version of fontconfig,
which apparently does not find any mac fonts.. at all. So, this
reverts the mac code to the older mac code we were using to manually
find and associate fonts with font files on the mac.
GCC marks fread as a function that will throw a warning if you do not
use its return value. This is most likely done as a measure to ensure
code security.
If tune or preset is invalid it'll just cause x264 to not load at all,
which I feel is a bit over the top. Instead, if the values aren't
valid, then just make it default to no tune if the tune is invalid, and
'veryfast' preset if the preset is invalid.
This should probably be reevaluated once we have
global hotkeys or other functions that would require
OBS to not be sent to sleep while in the background
without having any sort of encoder running
This uses fontconfig for looking up font files for freetype to use on
both linux and mac. It's apparently a bit more optimal and prevents us
from having to worry about the load time on the mac version as well.
Refactored and moved all the old code to the find-font-windows.c file,
as it's no longer used on anything but windows.
When looking up translated font names within font files, it was not
checking for null on the 'charset' variable (the translation character
set wasn't added/availble).
Multiplication of the matricies was being done in the wrong direction.
This caused source transformations to come out looking incorrect, for
example the linux-xshm source's cursor would not be drawn correctly or
in the right position if the source was moved/scaled/rotated. The
problem just turned out to be that the gs_matrix_* functions were
multiplying in the wrong direction. Reverse the direction of
multiplication, and the problem is solved.
it is now possible to build text-freetype2 on linux if you comment out a return() otherwise there would have been an error
Also i made the word iconv in find_package lower case, to match the APPLE cmake code
This changes the font plugin from using a font file to using a specific
installed system font, which is searched for on each specific system and
associated with the font file. It now uses a font property instead of a
path property, and font size has been removed because the font property
now handles that.
When the module is first loaded, it will build up a list of system fonts
in order to be usable by Freetype. It was quite painful to program this
because font files can contain multiple localized versions of their face
names, and then there was the issue where windows likes to mangle
custom style types to the font name. Regardless, it all seems to have
worked out pretty well.
Minor issues:
- Truetype/Opentype fonts sometimes do not automatically have
italic and/or bold styles available, it seems that the system applies
transformations manually in those cases. We don't do this yet,
however, so right now a user might select a font with italic/bold
only to discover that italic/bold doesn't always work. Not entirely
sure what to do about this yet. There's probably a freetype function
to do something like that somehow,
This also requires that iconv be used for non-windows systems to be able
to look up localized font names within font files. Windows will use
the win32 API and code page IDs to translate font names.
This moves some functions that are generic to a separate source
file. While doing so the api to those functions was improved to
be more generic and not depend on knowledge about the internal
structure of the plugin.
For the sake of consistency, renamed these two functions to include
_value at the end so they are consistent.
Renamed: To:
-------------------------------------------------------
obs_data_has_default obs_data_has_default_value
obs_data_has_autoselect obs_data_has_autoselect_value
obs_data_item_has_default obs_data_item_has_default_value
obs_data_item_has_autoselect obs_data_item_has_autoselect_value
API Removed:
- graphics_t obs_graphics();
Replaced With:
- void obs_enter_graphics();
- void obs_leave_graphics();
Description:
obs_graphics() was somewhat of a pointless function. The only time
that it was ever necessary was to pass it as a parameter to
gs_entercontext() followed by a subsequent gs_leavecontext() call after
that. So, I felt that it made a bit more sense just to implement
obs_enter_graphics() and obs_leave_graphics() functions to do the exact
same thing without having to repeat that code. There's really no need
to ever "hold" the graphics pointer, though I suppose that could change
in the future so having a similar function come back isn't out of the
question.
Still, this at least reduces the amount of unnecessary repeated code for
the time being.
The plugin now uses the generic name "OBS" to identify itself
to pulseaudio.
Until now the pulseaudio plugin used a placeholder icon for the
mixer to display. Now that we have a real icon installed to the
system we can use that instead.
According to issue #204 on the obs-studio repository, always setting the
ABR rate control method fixes the issue. I checked, and this was and
issue, and that does seem to fix the issue properly.
This functionality can now be handled automatically because locale can
now be freed seaparately from obs_module_unload with
obs_module_free_locale, which is called automatically when the module is
being freed.
Changed API:
- char *obs_find_plugin_file(const char *sub_path);
Changed to: char *obs_module_file(const char *file);
Cahnge it so you no longer need to specify a sub-path such as:
obs_find_plugin_file("module_name/file.ext")
Instead, now automatically handle the module data path so all you need
to do is:
obs_module_file("file.ext")
- int obs_load_module(const char *name);
Changed to: int obs_open_module(obs_module_t *module,
const char *path,
const char *data_path);
bool obs_init_module(obs_module_t module);
Change the module loading API so that if the front-end chooses, it can
load modules directly from a specified path, and associate a data
directory with it on the spot.
The module will not be initialized immediately; obs_init_module must
be called on the module pointer in order to fully initialize the
module. This is done so a module can be disabled by the front-end if
the it so chooses.
New API:
- void obs_add_module_path(const char *bin, const char *data);
These functions allow you to specify new module search paths to add,
and allow you to search through them, or optionally just load all
modules from them. If the string %module% is included, it will
replace it with the module's name when that string is used as a
lookup. Data paths are now directly added to the module's internal
storage structure, and when obs_find_module_file is used, it will look
up the pointer to the obs_module structure and get its data directory
that way.
Example:
obs_add_module_path("/opt/obs/my-modules/%module%/bin",
"/opt/obs/my-modules/%module%/data");
This would cause it to additionally look for the binary of a
hypthetical module named "foo" at /opt/obs/my-modules/foo/bin/foo.so
(or libfoo.so), and then look for the data in
/opt/obs/my-modules/foo/data.
This gives the front-end more flexibility for handling third-party
plugin modules, or handling all plugin modules in a custom way.
- void obs_find_modules(obs_find_module_callback_t callback, void
*param);
This searches the existing paths for modules and calls the callback
function when any are found. Useful for plugin management and custom
handling of the paths by the front-end if desired.
- void obs_load_all_modules(void);
Search through the paths and both loads and initializes all modules
automatically without custom handling.
- void obs_enum_modules(obs_enum_module_callback_t callback,
void *param);
Enumerates currently opened modules.
Those functions are actually causing more problems than
helping out with the preview because the width/height is
updated immediately while the actual size of the frames
displayed changes later.
Due to the plugin creating a thread to retrieve and output the
captured image data, care must taken to not modify data the
thread reads from the outside while the thread is running.
In previous revisions some settings accessed by the capture
thread were written to in the update function which could cause
image corruption and in the worst case crashes.
The members of the data struct are now split into two groups,
those that are used by the thread while it is running and must
not be changed from the outside, and those can be changed at any
time.
This adds a function to prepare the source_frame struct for use
with obs_source_output_video. Since all of the values except for
the timestamp and data pointers are known in before it makes
little sense to compute them over and over again.
Due to the fact that v4l2 uses a single continuous memory segment
for multi planar formats we can also precompute memory offsets for
the planes.
By using the wrapper functions supplied by libv4l2 we gain
support for formats not natively supported by obs.
The library intercepts certain system calls to transparently
enable recoding.
Until a proper fix is found to support devices that use stepwise
or continuous values for framesize and framerate this adds fixed
values that can be selected.
For devices that support discrete values those are still queried
and used.
Autoselection is only implemented for frame rate as it doesn't make
sense to autoselect the video format (Any fills the role of library
supplied autoselection) or the resolution (it may make sense to
implement resolution matching based on the current transformation
settings in the future though)
Use warn/info/debug helper macro functions to output
warnings/information/debug log data that's preformatted to include the
module and the current output name.
NOTE: In texture_setimage, I had to move variables to the top of the
scope because microsoft's C compiler will give the legacy C90 error of:
'illegal use of this type as an expression'.
To sum it up, microsoft's C compiler is still utter garbage.
Instead of using strings for setting names, use macros. Macros prevent
mis-spellings, prevent usage of the wrong name, and if you get it wrong,
it will simply fail to compile, helping to ensure that the right setting
value is being used.
Similar to the shader functions, the effect parameter functions take
the effect as a parameter. However, the effect parameter is pretty
pointless, because the effect parameter.. parameter stores the effect
pointer interally.
Since adding a source now opens the config dialog for that source
the convenience gain from having a device automatically start capturing
is outweighed by the inconvenience from having captured images
unintentionally recorded/streamed
The locale parameter was a mistake, because it puts extra needless
burden upon the module developer to have to handle this variable for
each and every single callback function. The parameter is being removed
in favor of a single centralized module callback function that
specifically updates locale information for a module only when needed.
Having the value stored here is somewhat pointless, so this is one step
in fixing the locale handling. Locale should be handled by the modules
themselves with their own loaded locale lookup information.
Due to the recent change with matrices, the way space is represented by
matrices is a bit different. The matrix stack represents the view
matrix, rather than the model matrix, so the position is more
representative of the camera (view) itself, rather than that of the
objects (model).
Common services that require specific encoder settings (specified in the
'recommended' section of the json file) will now have those encoder
settings applied before the encoders start up.
This fixes the issue with services like twitch that weren't getting
their required 2-second keyframe maximum interval set.
Apparently, despite the fact that Apple added
kAudioHardwarePropertyTranslateUIDToDevice in 10.8, it's not actually
usable in 10.8, only 10.9. So, instead of being able to use it like a
normal, sane person, we have to enumerate all devices manually and find
the AudioDeviceID ourselves. A slight annoyance and a mark against
apple's competence, but audio devices should now be working again on
10.8 at least, so whatever.
The biggest problem with DirectShow is that available configuration
capabilities can change if you so much as look at it the wrong way.
Previously, configuring devices often didn't configure the device
settings correctly, you would choose one setting and then another
setting wouldn't be compatible with that settings.
Let's take the terrible microsoft lifecam series for example. First,
you'd be at 640x480 happily webcam'ing away, which is using the YUY2
format. Then you decide "hey, this webcam resolution is a bit low. I
would love to have it a bit high resolution so it's a bit more crisp and
clear." You'd select 1280x720, and then suddenly the only format
supported is MJPEG output. However, the interface has to update that
fact, it can't list YUY2 if MJPEG is the only one available for this
resolution. This doesn't just apply to formats either, this applies to
framerates and such as well. Some framerates will only be supported by
certain resolutions which can in turn only be supported by certain
formats.
This causes user interface for configuration to be really be a nightmare
to manage if you want these features to be available to the user. It's
extremely annoying because you have to update all the configuration UI
after something has changed, double check the configuration values, and
if the values aren't supported, update those configuration values.
This covers the basics of devices. Mostly functional but not at 100%
yet. Uses 'libdshowcapture' library to capture directshow video/audio.
Both libdshowcapture and the plugin still need some work. Should at
least capture basic webcams and capture cards for the time being.