Commit Graph

257 Commits (3b48817a7b3c2ca70b5498a2e8acd5461bb4a476)

Author SHA1 Message Date
jp9000 fea4f75157 libobs: Update async video texture before effect filters
When an async video source is about to be rendered, the async texture
should be updated before any effect filtering occurs, rather than right
when it's about to render.

Fixes a few bugs:

- If the async texture hadn't drawn for its first time, and the source
  has an effect filter, it would never end up rendering the first
  frame due to the fact that it would fail on obs-source.c:2434 for the
  first filter, causing it to never actually render the source, and thus
  never get to a point in which it could call set_async_texture_size to
  establish the async texture width/height for the first time.

- Any time the async texture size changed, it would only update the
  async texture size at the end of the filter loop, which means that the
  first frame after a size change would use the old size for the filters
  rather than update to the new size right away.
2015-10-22 17:46:54 -07:00
jp9000 db7aebb940 libobs: Allow null pointer with obs_source_release_frame
A null pointer to a release/destroy function should be considered legal,
and simply do nothing.
2015-10-22 17:45:58 -07:00
jp9000 485a006215 libobs: Check source textures before destroying
Check to make sure the texrenders and textures on a source are valid
before destroying.
2015-10-21 07:46:40 -07:00
jp9000 f07ce8501f libobs: Add null debug messages for base obs funcs 2015-10-21 06:30:32 -07:00
jp9000 c27ff7903d libobs: Display debug msg in data_valid if null
Uses obs_source_valid in data_valid which will ensure a debug message is
displayed if null.
2015-10-21 06:28:03 -07:00
jp9000 8686451d5d libobs: Rename source_valid to data_valid
To prevent confusion with the new obs_source_valid function which
displays a warning, rename the "source_valid" function to "data_valid"
to emphasize that it's checking for the validity of the internal data as
well as the source itself.
2015-10-21 06:27:44 -07:00
jp9000 6ad8df8adb (API Change) libobs: Use single func for base effects
API removed:
--------------------
gs_effect_t *obs_get_default_effect(void);
gs_effect_t *obs_get_default_rect_effect(void);
gs_effect_t *obs_get_opaque_effect(void);
gs_effect_t *obs_get_solid_effect(void);
gs_effect_t *obs_get_bicubic_effect(void);
gs_effect_t *obs_get_lanczos_effect(void);
gs_effect_t *obs_get_bilinear_lowres_effect(void);

API added:
--------------------
gs_effect_t *obs_get_base_effect(enum obs_base_effect effect);

Summary:
--------------------
Combines multiple near-identical functions into a single function with
an enum parameter.
2015-10-19 00:52:45 -07:00
Richard Stanway 4b9d0256c8 libobs: Add missing mutex unlocks to some filter functions
Detected by Coverity Scan (CID 12831, 12830)
2015-10-12 23:21:45 +02:00
jp9000 6285a47726 (API Change) libobs: Pass type data to get_name callbacks
API changed from:
obs_source_info::get_name(void)
obs_output_info::get_name(void)
obs_encoder_info::get_name(void)
obs_service_info::get_name(void)

API changed to:
obs_source_info::get_name(void *type_data)
obs_output_info::get_name(void *type_data)
obs_encoder_info::get_name(void *type_data)
obs_service_info::get_name(void *type_data)

This allows the type data to be used when getting the name of the
object (useful for plugin wrappers primarily).

NOTE: Though a parameter was added, this is backward-compatible with
older plugins due to calling convention.  The new parameter will simply
be ignored by older plugins, and the stack (if used) will be cleaned up
by the caller.
2015-09-16 09:21:12 -07:00
jp9000 0ed913a136 libobs: Add functions to get private type data
The private type data is the type_data variable that's provided when
object types are registered by plugins.
2015-09-16 09:17:14 -07:00
kc5nra 3b2b7f2f37 libobs: Remove flag check when resetting timestamp
Removes obsolete check when resetting a timestamp as some sources
can register for Audio/Video async yet only output audio frames.
2015-08-02 15:54:10 -05:00
jp9000 91bfb53ed5 libobs: Fix audio filters killing video on source
When an audio filter is applied to a video source that also has
accompanying audio, it would cause the video from the source to stop
rendering.

The original code this was from was to prevent audio-only sources from
rendering video, but I neglected to make sure that this would not apply
to filters, and thus when an audio filter is on a source with video, the
code would kill the video.
2015-07-09 02:05:09 -07:00
jp9000 526b9e6bc1 libobs: Do not add audio hotkeys for filters 2015-07-03 09:21:43 -07:00
jp9000 d9c7290891 libobs: Do not try to render audio-only sources 2015-06-25 15:55:27 -07:00
jp9000 76870d1764 libobs: Increase async jitter compensation
Due to the fact that async timestamps themselves can be susceptible to
minor jitter from certain types of inputs, increase the allowable jitter
compensation value to ensure that the rendered frame timing from async
video sources is always as close as possible to the compositor.

When the framerate of the source is the same as the framerate as the
compositor, this (combined with the fact that clamped video timing now
being used with async video frames) helps ensure that buffered async
video sources will sync up their rendering to the compositor as
accurately as possible despite jitter from the source's timestamps.

If there is no jitter in the source's timestamps then it'll always sync
up perfectly with the compositor, thanks to clamped video timing.
2015-06-04 18:05:59 -07:00
jp9000 35a35badeb libobs: Use clamped video time for async timing
When playing back buffered async frames, this reduces the probability
that new frames will be missed/skipped due to jitter in the system
timestamps.

If a buffered async source is playing at the same framerate as the
compositor and there is no jitter in the async source's timestamps, then
the async source will play back perfectly in sync with the compositor
thanks to this change, ensuring that there's no skipped or missed frames
in video playback.
2015-06-04 18:05:51 -07:00
jp9000 7f7901b930 libobs: Reset frame cache if it gets too big
When buffering is enabled for an async video source, sometimes minor
drift in timestamps or unexpected delays to frames can cause frames to
slowly buffer more and more in memory, in some cases eventually causing
the system to run out of memory.

The circumstances in which this can happen seems to depend on both the
computer and the devices in use.  So far, the only known circumstances
in which this happens are with heavily buffered devices, such as
hauppauge, where decoding can sometimes take too long and cause
continual frame playback delay, and thus continual buffering until
memory runs out.  I've never been able to replicate it on any of my
machines however, even after hours of testing.

This patch is a precautionary measure that puts a hard limit on the
number of async frames that can be currently queued to prevent any case
where memory might continually build for whatever reason.  If it goes
over the limit, it clears the cache to reset the buffering.

I had a user with this problem test this patch with success and positive
feedback, and the intervals between buffering resets were long to where
it wasn't even noticeable while streaming/recording.

Ideally when decoding frames (such as from those devices), frame
dropping should be used to ensure playback doesn't incur extra delay,
although this sort of hard limit on the frame cache should still be
implemented regardless just as a safety precaution.  For DirectShow
encoded devices I should just switch to faruton's libff for decoding and
enable the frame dropping options.  It would probably explain why no
one's ever reported it for the media source, and pretty much only from
DirectShow device usage.
2015-06-04 17:39:03 -07:00
Palana 7b3b083889 libobs: Add audio source hotkeys 2015-05-11 20:45:25 +02:00
Palana 1d39c3e9b6 (API Change) libobs: Add hotkey data to *_create functions 2015-05-11 20:45:25 +02:00
Palana 5ad553d06d libobs: Add global hotkey support 2015-05-11 20:45:24 +02:00
Palana 4d40c5c853 libobs: Extend audio_data signal with muted flag 2015-05-07 02:08:08 +02:00
Palana a563fbc05b libobs: Add weak reference type for obs_source 2015-05-07 01:57:14 +02:00
jp9000 9d82760405 libobs: Warn if source released after shutdown
Instead of letting this area of code crash, check to see if the core is
still active or not, and safely warn and ignore the release if so.
2015-04-30 05:14:38 -07:00
jp9000 908a165d62 Add planar YUV 4:4:4 format support
Adds the ability to natively output with planar YUV 4:4:4.
2015-04-17 20:16:40 -07:00
jp9000 cf28a8af22 libobs: Init source mutexes before calling create
Fixes a crash that could happen if any of the mutexes are used in the
create callback, or before the obs_source_init function is called.

I'm not sure how this function order slipped because it seems fairly
obvious that these mutexes should be created before the create callback.

Had this crash happen to me when creating a WASAPI output source, the
create callback of the WASAPI source creates a thread which outputs
audio, and that thread managed to call obs_source_output_audio before
the obs_source_init function was called, which in turn caused it to try
to use a null mutex.
2015-04-15 16:13:37 -07:00
jp9000 ab65df74e0 libobs: Increment new frame ref when first copying
When caching a new frame, keep a reference to the frame while copying to
ensure that the frame is not potentially destroyed for whatever reason
while that data is being copied.
2015-04-10 19:28:41 -07:00
jp9000 dde1a73132 libobs: Fix async texture data race
The obs_source::async_reset_texture variable can cause a data race
between threads to occur because it could be set to true in one thread
then changed back to false in another thread.  This could cause the
async texture to not update its size when it's supposed to, which can
cause a crash or corruption when copying data from a frame of a
differing size.

The solution to this is to:

- Delete the async_reset_texture variable, and make the
  set_async_texture_size function change the texture size if the
  async_width, async_height, or async_format variables differ from the
  frame's width/height/format.  Those variables are then only ever set
  in the libobs graphics thread.

- Make the cache_video function use separate variables from other
  functions to detect a change in size (due to the fact that the texture
  size should only be resized in the libobs graphics thread).  These
  variables are async_cache_width, async_cache_height, and
  async_cache_format, which are only be set in the thread that calls
  obs_source_output_video.

How to replicate the data race:

- On OSX, use window capture on a textedit window, then continually
  resize the textedit window.
2015-04-10 19:16:18 -07:00
jp9000 85a490c5e8 libobs: Remove out-of-context comment
This comment was originally for an older version of the code; I'm
guessing I forgot to remove it along with the code that it originally
belonged with.
2015-04-10 19:15:06 -07:00
jp9000 095159c23a libobs: Fix bug with filter bypassing
Due to a bad 'if' expression, when a filter that is not last in the
chain is disabled or being bypassed, it ends up still calling the
filter's video processing function unintentionally.

This fix makes sure that it only calls the appropriate render functions
if the next filter target is the source, otherwise it will just call
obs_source_video_render to process the next filter in the chain.

How to replicate the bug:
1. Create two crop filters on the same source
2. Give each crop filter a different distinct value
3. Disable both crop filters
4. The image would still be cropped
2015-04-10 07:27:26 -07:00
jp9000 95f5a3c260 libobs: Clear current async frame if cache freed
If the cache is freed the current async frame will of course become
invalid, so make sure it's set to null if the cache is freed.
2015-03-27 10:03:47 -07:00
jp9000 3a90be39dd libobs: Deallocate lingering unused cache frames
This fixes an issue where cache frames would not free at all after
having been allocated with no upper limit on the cached frame size.  If
cached frames go unused for a specific period of time, they are
deallocated and removed from the cache.

This is preferable to having an upper cache limit due to the potential
for async delay filtering.
2015-03-27 00:07:16 -07:00
jp9000 f03e66fc99 Revert "libobs: Fix memory leak (Enforce cache limit)"
This reverts commit 4459ed3e2c.
2015-03-26 23:40:36 -07:00
jp9000 4459ed3e2c libobs: Fix memory leak (Enforce cache limit)
Under certain circumstances the cache could be prone to growing too
large unintentionally.  Setting a hard maximum limit should prevent
memory from growing if we suddenly get a lot of frames.
2015-03-26 22:59:48 -07:00
jp9000 6e22ac41b8 libobs: Swap async source frames in tick
Async frames are only swapping when rendering, or when not visible.
This is a flawed design due to the fact that there are certain
circumstances where the source is neither visible nor currently
rendering.

This is what caused a memory leak when scene items were marked as
invisible, because if a source has an async child source and decides not
to render that source for whatever reason, the child source would not
process the async frames at all, and the cache would just grow.

To fix this, simply moving the async frame cycle to tick fixes the issue
due to the fact that tick is always called regardless of circumstance.
2015-03-26 22:59:48 -07:00
jp9000 621158f8e1 libobs: Fix warning
Removed this variable some time back, but didn't test on GCC (which
throws this warning), so I never knew about it until recently.
2015-03-25 14:14:40 -07:00
jp9000 74d886c2f8 libobs: Reorder filters based upon their type
If a filter is an async filter move above/below other async filters,
and similarly for effect filters move above/below other effect filters.
2015-03-25 10:03:20 -07:00
jp9000 2b4fdb19ad libobs: Filter async video before rendering
Filtering the video before it's output to the texture means that it
happens after all the processing on the timestamps and such of the video
data.  This way, the video filter does not have to worry about what's
currently buffered, and it won't affect timing.
2015-03-25 10:03:19 -07:00
jp9000 c16f1a7430 libobs: Add obs_get_source_output_flags function
Gets the output flags by its source type.
2015-03-25 10:03:17 -07:00
jp9000 1a70ae0105 libobs: Add missing function definition
obs_get_source_defaults was missing the definition for the function.
2015-03-25 10:03:17 -07:00
jp9000 f109be3010 libobs: Fix potential bug destroying filters
When OBS is shutting down, if for some reason the filter is destroyed
before the parent source is destroyed, it would try to remove itself
from the source, but it would decrement the reference and try to destroy
itself again while already in the process of destroying itself.

So, the solution was simply to make sure that if it's removing itself
from the source that it doesn't decrement its own reference.
2015-03-25 10:03:15 -07:00
jp9000 18afe82304 libobs: Skip filter if internal data not present
If the filter's binary was recently removed, the data will be invalid,
so make sure that it properly handles that situation by skipping the
filter.
2015-03-25 10:03:14 -07:00
jp9000 e31fea66be libobs: Add API to mute/unmute sources 2015-03-25 10:03:13 -07:00
jp9000 f04ef236ac libobs: Add ability to disable sources/filters 2015-03-25 10:03:13 -07:00
jp9000 98a6c8f0d0 libobs: Always enumerate filter list in reverse
The "last" filter that's rendered is technically at filter index 0, so
enumeration needs to be from the last index in the list to the first
index in the list.
2015-03-25 10:03:12 -07:00
jp9000 64943f3fc6 libobs: Lock mutex when changing filter order
Refactors the function a bit to ensure that the filter mutex is locked
when changing the filter order.
2015-03-25 10:03:11 -07:00
jp9000 dedc454caf libobs: Add "reorder_filters" source signal
Signals when the filter order has been changed for a source.
2015-03-25 10:03:10 -07:00
jp9000 4aa8f2d14b libobs: Fix bug when changing filter order
The 'idx' variable is the incorrect variable to be using here, the
variable that was supposed to be used was 'i'.
2015-03-25 10:03:09 -07:00
jp9000 86a0f370c3 libobs: Insert new filters at index 0
Technically, the "last" filter rendered is the filter at index 0, so
inserting a new filter at that point makes the most sense.
2015-03-25 10:03:08 -07:00
jp9000 c0cc81d20f libobs: Turn blending off for filter renders
When rendering a filter to a texture, the target is empty and unused, so
there's no reason for blending to be on when rendering the filter to a
render target.
2015-03-25 10:03:07 -07:00
jp9000 44e484ad34 (API Change) Fix filter rendering design flaw
obs_source_process_filter tried to do everything in a single function,
but the problem is that effect parameters would not properly be
accounted for due to the way it internally draws, therefore it was
necessary to split the functions in to two, you first call
obs_source_process_filter_begin, then you set your effect parameters,
then you finally call obs_source_process_filter_end.  This ensures that
when the filter is drawn, that the effect parameters are set.
2015-03-25 10:03:06 -07:00