libobs: Stop all source processing on destroy

Stops all video/audio IO when a source enters the destroy process.
Prevents any internal callbacks from being triggered and improves
performance.
This commit is contained in:
jp9000 2022-01-04 13:31:53 -08:00
parent 7fa07afd21
commit a5a8a7c32f
2 changed files with 30 additions and 1 deletions

View File

@ -629,6 +629,9 @@ struct obs_source {
/* ensures activate/deactivate are only called once */ /* ensures activate/deactivate are only called once */
volatile long activate_refs; volatile long activate_refs;
/* source is in the process of being destroyed */
volatile long destroying;
/* used to indicate that the source has been removed and all /* used to indicate that the source has been removed and all
* references to it should be released (not exactly how I would prefer * references to it should be released (not exactly how I would prefer
* to handle things but it's the best option) */ * to handle things but it's the best option) */

View File

@ -43,6 +43,11 @@ static inline bool deinterlacing_enabled(const struct obs_source *source)
return source->deinterlace_mode != OBS_DEINTERLACE_MODE_DISABLE; return source->deinterlace_mode != OBS_DEINTERLACE_MODE_DISABLE;
} }
static inline bool destroying(const struct obs_source *source)
{
return os_atomic_load_long(&source->destroying);
}
struct obs_source_info *get_source_info(const char *id) struct obs_source_info *get_source_info(const char *id)
{ {
for (size_t i = 0; i < obs->source_types.num; i++) { for (size_t i = 0; i < obs->source_types.num; i++) {
@ -614,6 +619,8 @@ void obs_source_destroy(struct obs_source *source)
if (!obs_source_valid(source, "obs_source_destroy")) if (!obs_source_valid(source, "obs_source_destroy"))
return; return;
os_atomic_set_long(&source->destroying, true);
if (is_audio_source(source)) { if (is_audio_source(source)) {
pthread_mutex_lock(&source->audio_cb_mutex); pthread_mutex_lock(&source->audio_cb_mutex);
da_free(source->audio_cb_list); da_free(source->audio_cb_list);
@ -2993,6 +3000,8 @@ obs_source_output_video_internal(obs_source_t *source,
void obs_source_output_video(obs_source_t *source, void obs_source_output_video(obs_source_t *source,
const struct obs_source_frame *frame) const struct obs_source_frame *frame)
{ {
if (destroying(source))
return;
if (!frame) { if (!frame) {
obs_source_output_video_internal(source, NULL); obs_source_output_video_internal(source, NULL);
return; return;
@ -3008,6 +3017,8 @@ void obs_source_output_video(obs_source_t *source,
void obs_source_output_video2(obs_source_t *source, void obs_source_output_video2(obs_source_t *source,
const struct obs_source_frame2 *frame) const struct obs_source_frame2 *frame)
{ {
if (destroying(source))
return;
if (!frame) { if (!frame) {
obs_source_output_video_internal(source, NULL); obs_source_output_video_internal(source, NULL);
return; return;
@ -3049,6 +3060,8 @@ void obs_source_set_async_rotation(obs_source_t *source, long rotation)
void obs_source_output_cea708(obs_source_t *source, void obs_source_output_cea708(obs_source_t *source,
const struct obs_source_cea_708 *captions) const struct obs_source_cea_708 *captions)
{ {
if (destroying(source))
return;
if (!captions) { if (!captions) {
return; return;
} }
@ -3108,6 +3121,8 @@ obs_source_preload_video_internal(obs_source_t *source,
{ {
if (!obs_source_valid(source, "obs_source_preload_video")) if (!obs_source_valid(source, "obs_source_preload_video"))
return; return;
if (destroying(source))
return;
if (!frame) if (!frame)
return; return;
@ -3125,6 +3140,8 @@ obs_source_preload_video_internal(obs_source_t *source,
void obs_source_preload_video(obs_source_t *source, void obs_source_preload_video(obs_source_t *source,
const struct obs_source_frame *frame) const struct obs_source_frame *frame)
{ {
if (destroying(source))
return;
if (!frame) { if (!frame) {
obs_source_preload_video_internal(source, NULL); obs_source_preload_video_internal(source, NULL);
return; return;
@ -3140,6 +3157,8 @@ void obs_source_preload_video(obs_source_t *source,
void obs_source_preload_video2(obs_source_t *source, void obs_source_preload_video2(obs_source_t *source,
const struct obs_source_frame2 *frame) const struct obs_source_frame2 *frame)
{ {
if (destroying(source))
return;
if (!frame) { if (!frame) {
obs_source_preload_video_internal(source, NULL); obs_source_preload_video_internal(source, NULL);
return; return;
@ -3178,7 +3197,8 @@ void obs_source_show_preloaded_video(obs_source_t *source)
if (!obs_source_valid(source, "obs_source_show_preloaded_video")) if (!obs_source_valid(source, "obs_source_show_preloaded_video"))
return; return;
if (destroying(source))
return;
if (!source->async_preload_frame) if (!source->async_preload_frame)
return; return;
@ -3230,6 +3250,8 @@ obs_source_set_video_frame_internal(obs_source_t *source,
void obs_source_set_video_frame(obs_source_t *source, void obs_source_set_video_frame(obs_source_t *source,
const struct obs_source_frame *frame) const struct obs_source_frame *frame)
{ {
if (destroying(source))
return;
if (!frame) { if (!frame) {
obs_source_preload_video_internal(source, NULL); obs_source_preload_video_internal(source, NULL);
return; return;
@ -3245,6 +3267,8 @@ void obs_source_set_video_frame(obs_source_t *source,
void obs_source_set_video_frame2(obs_source_t *source, void obs_source_set_video_frame2(obs_source_t *source,
const struct obs_source_frame2 *frame) const struct obs_source_frame2 *frame)
{ {
if (destroying(source))
return;
if (!frame) { if (!frame) {
obs_source_preload_video_internal(source, NULL); obs_source_preload_video_internal(source, NULL);
return; return;
@ -3460,6 +3484,8 @@ void obs_source_output_audio(obs_source_t *source,
if (!obs_source_valid(source, "obs_source_output_audio")) if (!obs_source_valid(source, "obs_source_output_audio"))
return; return;
if (destroying(source))
return;
if (!obs_ptr_valid(audio_in, "obs_source_output_audio")) if (!obs_ptr_valid(audio_in, "obs_source_output_audio"))
return; return;