Fixes a bug that would allow possible infinite recursion within a source
tree. To fix this, inactive sources must be enumerated as well in order
to prevent infinite recursion.
Captions do something unusual with encoder packets: they reallocate them
due to appending extra h.264 data. Due to the way allocations are
handled with core encoder packets (they now store a reference in their
data), instead of modifying the encoder data directly, create a new
encoder packet instead and release the old packet.
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.
When there are audio sources in a scene and they've all stopped playing
their audio (audio is pending), all scene item audio actions (volume
changes, toggling visibility) will perpetually buffer and no longer be
processed until audio plays again.
So instead of that, if all audio sources have stopped playing in the
scene, just process all pending scene item audio actions immediately to
prevent them from never being processed while waiting for a scene item
to start playing audio.
Commit 53955301a2 introduced a async source texture copy bug due to
creating a new case in a switch without adding a break to the one above
it, causing it to execute both cases by mistake.
Because D3D11 specifically does not support an L8 texture format (you
have to use a shader swizzle), manually convert Y800 signals to RGBX
instead. This also fixes a bug where Y800 signals will render red.
Closesjp9000/obs-studio#718
For displays, instead of using the draw_callbacks_mutex and risk a
reverse mutual lock scenario, use a separate mutex to lock display size
data.
This bug was exposed when trying to reorder filters in the UI module.
The UI thread would try to reorder the filters, locking the filter mutex
of the source, and then the reorder would signal the UI to resize the
display, so the display would lock its draw_callbacks_mutex. Then, in
the graphics thread, it would lock the display's draw_callbacks_mutex,
try to draw the source, and then the source would try to lock that same
filter mutex.
A mutex trace:
UI thread -> lock source filter mutex -> waiting on display mutex
graphics thread -> lock display mutex -> waiting on source filter mutex
Closesjp9000/obs-studio#714
On MSVC, deprecated types/functions were being completely ignored by the
compiler due to this pragma. Any plugins/programs that depended on this
would also have this warning disabled due to it being in this file.
This pragma was most likely originally done due to the MSVC warnings for
C-standard functions, which are now ignored via _CRT_SECURE_NO_WARNINGS
on all projects instead.
When an output's context data is being created, it cannot register any
hotkeys because the output has not initialized its reference counting
capability. This is due to the fact that when a hotkey is registered,
it creates a weak reference to the source/output/service/encoder.
The solution to this is to make sure the output's reference counter data
is created before calling the create callback.
(Note: This commit also modifies the UI)
Being able to generate file names based upon a specification is useful
for more than just the UI; it can also be useful for things such as the
replay buffer where file names need to be generated on the fly.
If an async source is cropped on one side, then when the program is
restarted and the source is loaded from file, the async source will
start out with a width/height of zero. This will cause the async source
to not be drawn if cropping or scale filtering is added to the scene
item, because it has to be rendered to a texture first. However, the
source cannot reset its size until it's drawn, so it leaves it in
perpetual state of having a 0x0 size.
This fixes that problem by ensuring that the async source size is always
reset even when not being rendered.
Closejp9000/obs-studio#686
Commit aa899c2 (PR #603) added logging for Windows bitness/arch, but it
was a bit incomplete/short-sighted. It only added that information to
the regular logs. This commit makes it easier to retrieve that
information for other purposes, like the crash handler.
When a scene is duplicated the filters on the scene were not copied to
the new scene. This causes that a temporary copy of a scene renders
differently in the program than in the preview when using studio mode.
When it was checking for the BOM at the beginning of the file, it would
just return out of the function if it didn't read at least 3 bytes.
This would particularly affect text sources.
A linker error for XGetXCBConnection started occurring after the
frontend API was added, the fix is simply to make sure libobs is
properly linking to X11_XCB.
Allow outputs to force a stop even when already in the process of
stopping. If for example a stream is heavily congested and taking a
very long time to stop, this allows frontends to give the users the
option to forcibly stop the stream to make it stop as quickly as
possible.
Allows getting the current active framerate that the core is rendering
with. This takes in to account any rendering lag or stalls that may be
occurring.
Outputting a human-readable error message on library load failure makes
it a little bit easier for plugin developers to determine why a plugin
library may have failed to load (such as missing dependency), rather
than having to look up the error code each time.
Closesjp9000/obs-studio#596
P-frames were initially set as highest priority to prevent them from
being dropped (not sure what the rationale was behind this), but this
caused a problem where if there's too much congestion for whatever
reason data will continue to stay buffered, so to prevent this p-frames
should be droppable.
(Note: This commit also modifies coreaudio-encoder, win-capture, and
win-mf modules)
This reduces logging to the user's log file. Most of the things
specified are not useful for examining log files, and make reading log
files more painful.
The things that are useful to log should be up to the front-end to
implement. The core and core plugins should have minimal mandatory
logging.
Allows setting a "long" description for detailed explanation of certain
properties that may need them, but don't want to display them on the
user interface by default.
The active_refs and show_refs variable would only increment/decrement
their children if their values were 1 and 0, which means that in the
case of scenes within scenes, sub-sources of scenes within scenes would
end up having the wrong ref values.
Allows the ability to use scale filters such as point, bicubic, lanczos
on specific scene items, disabled by default. When using one of the
latter two options, if the item's scale is under half of the source's
original size, it uses the bilinear low resolution downscale shader
instead.
Adds a function to the C-family parser to go to the next token and
create a string copy of it. Useful for when you want to get a copy of
the next token regardless of what type it is.
This fixes an design flaw where a delayed output would schedule a
stop even while in the process of reconnecting instead of just shutting
down right away.
When obs_output_actual_stop is called on shutdown, it should wait for
the output to fully stop before doing anything, and then it should wait
for the data capture to end. The service should not be removed until
after the output has stopped, otherwise it could result in a possible
memory leak on stop. Packets should be freed last.
(Note: This commit also modifies obs-ffmpeg and obs-outputs)
API Changed:
obs_output_info::void (*stop)(void *data);
To:
obs_output_info::void (*stop)(void *data, uint64_t ts);
This fixes the long-time design flaw where obs_output_stop and the
output 'stop' callback would just shut down the output without
considering the timing of when obs_output_stop was used, discarding any
possible buffering and causing the output to get cut off at an
unexpected timing.
The 'stop' callback of obs_output_info now takes a timestamp with the
expectation that the output will use that timestamp to stop output data
in accordance to that timing. obs_output_stop now records the timestamp
at the time that the function is called and calls the 'stop' callback
with that timestamp. If needed, obs_output_force_stop will still stop
the output immediately without buffering.
Fixes an issue where the audio meter/fader would call an obs function
and lock another mutex, potentially causing a mutual inverted lock in
another thread.
When using GPU conversion for 4:2:0 frames on async video sources, it
would create a texture bigger than necessary and try to copy too much
data from the frame, resulting in a crash.
(Note: This commit also modifies the UI)
The editable list only had two types: A type that allows both files and
URLS, and a type that only allows strings.
This changes it so the editable list can have a "files only" type, a
"files and URLs" type, and a "strings only" type.
When a transition is a sub-source of another source, it would not call
the transition's active source enum function, meaning that any sources
the transition had would not increment their active/showing refs (it
would only be called when activating the transition directly before).
That would result in negative/invalid active/showing refs on its
sub-sources, causing them to become permanently active/inactive and/or
permanently showing/hidden.
Under certain circumstances it's necessary to seek, but if the frame
isn't loaded for the position that's being seeked to, it won't update
the texture. This just ensures the texture will update when seeking.
If custom transforms were used, the very first frame after starting
would always render with the previous transform before calculating the
new transform.
If a transition had a fixed size, it would not render itself or its
sub-sources according to that fixed size. The fixed size value was
essentially being ignored.
This fixes a bug where the sub-sources on a transition wouldn't render
with the expected size when the transition had a different size from its
sub-sources
Transition audio was programmed to stop if there is no queued audio from
both sources. Because of that, when a source's audio started after the
transition started, it would cause audio from the source to be excluded
from the transition until the transition had completed because the audio
had already been marked as stopped.
Instead, if there's no audio from the transition sources, the audio
should only be marked as stopped when video has stopped. This allows
the to/from sources to have an opportunity to start/restart audio during
the transition safely.
The field orders of retro 2x and linear 2x deinterlace shaders were
inverted. Note that yadif 2x does not act the same in this regard, its
field ordering is correct due to how it operates.
(Note: this commit also modifies the obs-filters and test-input modules)
Changes the obs_source_process_filter_begin return type so that it
returns true/false to indicate that filter processing should or should
not continue (for example if the filter is bypassed or if there's some
other sort of issue that causes the filtering to fail)
On outputs that use already-active video/audio encoder, the audio
pruning to sync up audio packets with video packets doesn't always get
called (for example if the video pruning function was called). Always
prune excess starting audio packets.
From MSDN: "The behavior of the least significant bit of the return value
is retained strictly for compatibility with 16-bit Windows applications
(which are non-preemptive) and should not be relied upon."
This caused problems with hotkeys firing if the user pressed a hotkey key
in another application, followed by the modifier keys at any other time.
OBS would then think the hotkey key was just pressed based on the was_down
behavior and incorrectly trigger a hotkey event.
Fixes 0000443.
If audio buffering is very high, the audio packets built up in the
interleaved buffer would be significantly before the first video packet,
causing the offset between the starting video/audio packet pairs to be
significantly off, leading to desync.
This issue was not spotted until recently because it only happens when
streaming/recording with same encoders while audio buffering is very
high.
The source shouldn't be inserted into obs->data.first_audio_source until it's
fully initialized, or other threads will access source->control and
dereference an uninitialized pointer.
This is a band-aid solution to be able to create temporary services
without logging them and keep them out of enumeration functions.
This is a band-aid solution -- 'master obs context lists' should not be
kept by the core. Logging of object creation/destruction should also be
controlled by the front-end instead of the core.
This patch fixes a specific crash where if the user named a filter the
same name as an input source that already existed in the system, scene
item loading code could find the filter with the same name instead of
the source, and mistakenly use it as the scene item's source directly.
This would cause a crash when trying to render that filter as a regular
source.
Marking filters as private is a temporary and simple workaround to the
solution. Filters are currently not meant to be found via the main
enumeration/search functions, which is a design flaw (lack of
consistency). In future major API revisions of libobs, filters should
be reworked to act as sources, with the sources they filter as
sub-sources ideally.
Additionally, the concept of "private context objects" and "primary
lists of context objects" in the back-end should probably also be
removed, allowing the font-end (or optional separate API layers) to
control all primary lists of obs context objects. These minor issues
that occur ultimately stem from API design flaws which need to be
corrected.
This crash happened when a filter was mistakenly used as a regular
source due to an unrelated bug in filter code and scene loading code.
The filter and the source it belongs to both had the same names, and the
source loading code found the filter and mistakenly used it as the
source instead of the actual source with the same name.
Determines whether an obs object was created successfully. If a plugin
that's used for a saved object is removed (third party plugins), its
data will become invalid, but the objects can often still be created for
the sake of preserving user settings, but sometimes these objects can
cause problems if they're actually used (such as using them for
transitions).
(Note: Also modified the obs-ffmpeg plugin module)
Allows the ability for frame data to pass 8-bit grayscale images (Y800
color format).
Closesjp9000/obs-studio#515
Adds deinterlacing API functions. Both standard and 2x variants are
supported. Deinterlacing is set via obs_source_set_deinterlace_mode and
obs_source_set_deinterlace_field_order.
This was implemented in to the core itself because deinterlacing should
happen before effect filters are processed, but after async filters are
processed. If this were added as a filter, there is the possibility
that a different filter is processed before deinterlacing, which could
mess with the result. It was also a bit easier to implement this way
due to the fact that that deinterlacing may need to have access to the
previous async frame.
Effects were split in to separate files to reduce load time (especially
for yadif shaders which take a significant amount of time to compile).
Instead of just updating the async texture variables directly in the
source, allow the ability to pass the async texture variables via
function parameters to allow the ability to parse more than one frame to
more than one texture.
This code is primarily intended to be used to upload/convert the
"previous" async frame for the deinterlacer (if necessary).
Just creates an effect to the target variable only if its current value
is null. This will be used for deinterlacing effects to prevent having
to compile the shaders unless they're actually being used.
(Note: This commit also modifies obs-filters and text-freetype2)
This simplifies writing of effects. DrawMatrix is no longer necessary
because there are no sources that require drawing with a color matrix
other than async sources, and async sources are automatically processed
and don't defer their initial render stage to filters.
When the #include directive in in the C lexer preprocessor is
encountered, the files being included need to be relative to the
directory of the file that the include was used in.
(Note: This commit also changes the UI)
Changed:
-------------------
void obs_load_sources(obs_data_array_t *sources_list);
To:
-------------------
void obs_load_sources(obs_data_array_t *sources_list,
obs_source_load_cb callback, void *private_data);
Signals should really never be required to use to make some function
work properly. The "source_load" signal was required for the
obs_load_sources function, but it's meant more for loading private data
in the settings, not for general loading of sources.
This changes it so that a callback is explicitly required to load the
sources.
The default buffering time for audio was always 1 second before the
audio subsystem was changed, and it was always more than sufficient for
max audio buffering time
Under certain circumstances, the timing_adjust variable would cause line
1161 to continually trigger over and over again. The "loop detection"
code incorrectly made it so that any timestamp that was just simply
below the expected value would be seen as a jump. After that, the
timing_adjust variable would be set for the frame again, and then the
audio would see it as a jump again after that, and those two things
would continue endlessly. This would cause stuttering particularly with
certain devices (particularly elgato/lgp/hdpvr) where the audio/video
data are decoded and sent at varying/different/unpredictable times.
To fix this issue, it should not detect values below as jumps, but
instead should only do it for values that exceed the MAX_TS_VAR (maximum
timestamp variance) value.
If obs_source::audio_ts is set to 0 (such as by discard_if_stopped in
obs-audio.c), but the push_back variable in the source_output_audio_data
function in obs-source.c was being set to true (meaning it's within the
seamless audio smoothing threshold), it would cause it to never reset
the obs_source::audio_ts value, and thus all audio data from the source
would become perpetually ignored by the audio subsystem until there was
finally some sort of timestamp jump that caused it to call
source_output_audio_place, and thus reset obs_source::audio_ts.
obs_source::audio_ts is only reset in source_output_audio_place, not in
source_output_audio_push_back, so the most simple solution is to just
call source_output_audio_push_back is obs_source::audio_ts is 0.
This code causes audio data in general to be reset (and subsequently
deleted). It should just be marked as pending and ignored until the
data is ready. The discard_if_stopped function will serve the same
purpose if the source's audio has actually stopped.
There's technically no need to clear the audio data here, nor is there
any need to try to trick the timestamp in to a different position. It
can simple just reset the audio timing.
Prevents a possible case where audio data might be deleted when it's not
necessary to delete any.
This variable is used to detect whether audio has stopped -- if audio
stops, it detects that no new data is coming in, and resets the audio
position so that it eliminates the chance of causing the audio buffering
to go haywire if audio starts up again. However, this variable was not
being reset every time the value changes, which it should.
Sometimes the A and B sources of a transition would a large difference
in their timestamps, and the calculation of where to start the audio
data for one of the sources could be above the tick size, which could
cause a crash.
If the circular audio buffer of the source has data remaining that's
less than the audio frame tick count (1024 frames), it would just leave
that audio data on the source without discarding it. However, this
could cause audio buffering to increase unnecessarily under certain
circumstances (when the next audio timestamp is within the timestamp
jump window), so it would append data to that circular buffer despite
the audio stopping that long ago, causing audio buffering to have to
increase to compensate.
Instead, just discard pending audio if it hasn't been written to. In
other words, if the audio has stopped and there's insufficient audio
left to continue processing.
With the new audio subsystem, audio buffering is minimal at all times.
However, when the audio buffering is too small or non-existent, it would
cause the audio encoders to start with a timestamp that was actually
higher than the first video frame timestamp. Video would have some
inherent buffering/delay, but then audio could return and encode almost
immediately. This created a possible window of empty time between the
first encoded video packet and the first encoded audio packet, where as
audio buffering would cause the first audio packet's timestamp to always
be way before the first video packet's timestamp. It would then
incorrectly assume the two starting points were in sync.
So instead of assuming the audio data is always first, this patch makes
video wait for audio data comes in, and conversely buffers audio data
until video comes in, and tries to find a starting point within that
video data instead, ensuring a synced starting point whether audio
buffering is active or not.
When starting a multi-track output, attempt to pair the video encoder
with one of the audio encoders to ensure that the video and audio
encoders start as close together in time as possible. This ensures the
best possible audio/video syncing point when using multi-track audio
output.
When using multi-track audio, encoders cannot be paired like they can
when only using a single audio track with video, so it has to choose the
best point in the interleaved buffer as the "starting point", and if the
encoders start up at different times, it has to prune that data and wait
to start the output on the next video keyframe. When the audio encoders
started up, there was the case where the encoders would take some time
to load, and it would cause the pruning code to wait for the next
keyframe to ensure startup syncing.
Starting the audio encoders before starting the video encoder should
reduce the possibility of that happening in a multi-track scenario.
In a multi-track scenario it was not taking in to consideration the
possibility of secondary audio tracks, which could have caused desync on
some of the audio tracks.
The seamless audio looping code would erroneously trigger for things
that weren't loops, causing the audio data to continually push back and
ignore timestamps, thus going out of sync.
There does need to be loop handling code, but due to the fact that other
things may need to trigger this code, it's best just to clear the audio
data and start from a fresh sync point. Unfortunately for the case of
loops, this means the window in which audio data loops and video frames
loop need to be muted.
Fixes an issue where audio data would not be popped if they were not
activated/presenting. This would cause the audio subsystem to
needlessly buffer when they were reactivated again. Rendering all audio
sources (excuding composite/filter sources) helps ensure that audio data
is always popped and not left to pile up.
A comment that serves as a reminder to anyone who might need to edit the
scene code. If the graphics mutex must be locked, it must be locked
first before entering the scene mutexes, or outside of the scene
mutexes.