Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libobs: Fix race when disconnecting raw video callbacks #11605

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions docs/sphinx/reference-libobs-media-io.rst
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,17 @@ Video Handler

---------------------

.. function:: bool video_output_disconnect2(video_t *video, void (*callback)(void *param, struct video_data *frame), void *param)

Disconnects a raw video callback from the video output handler.

:param video: Video output handler object
:param callback: Callback
:param param: Private data
:return: *true* if callback was removed, *false* otherwise (e.g. already removed)

---------------------

.. function:: const struct video_output_info *video_output_get_info(const video_t *video)

Gets the full video information of the video output handler.
Expand Down
9 changes: 8 additions & 1 deletion libobs/media-io/video-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -463,9 +463,14 @@ static void log_skipped(video_t *video)
}

void video_output_disconnect(video_t *video, void (*callback)(void *param, struct video_data *frame), void *param)
{
video_output_disconnect2(video, callback, param);
}

bool video_output_disconnect2(video_t *video, void (*callback)(void *param, struct video_data *frame), void *param)
{
if (!video || !callback)
return;
return false;

video = get_root(video);

Expand All @@ -485,6 +490,8 @@ void video_output_disconnect(video_t *video, void (*callback)(void *param, struc
}

pthread_mutex_unlock(&video->input_mutex);

return idx != DARRAY_INVALID;
}

bool video_output_active(const video_t *video)
Expand Down
2 changes: 2 additions & 0 deletions libobs/media-io/video-io.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ EXPORT bool video_output_connect2(video_t *video, const struct video_scale_info
void *param);
EXPORT void video_output_disconnect(video_t *video, void (*callback)(void *param, struct video_data *frame),
void *param);
EXPORT bool video_output_disconnect2(video_t *video, void (*callback)(void *param, struct video_data *frame),
void *param);

EXPORT bool video_output_active(const video_t *video);

Expand Down
10 changes: 6 additions & 4 deletions libobs/obs.c
Original file line number Diff line number Diff line change
Expand Up @@ -2929,17 +2929,19 @@ void start_raw_video(video_t *v, const struct video_scale_info *conversion, uint
void (*callback)(void *param, struct video_data *frame), void *param)
{
struct obs_core_video_mix *video = get_mix_for_video(v);
if (video)
if (!video)
return;
if (video_output_connect2(v, conversion, frame_rate_divisor, callback, param))
os_atomic_inc_long(&video->raw_active);
video_output_connect2(v, conversion, frame_rate_divisor, callback, param);
}

void stop_raw_video(video_t *v, void (*callback)(void *param, struct video_data *frame), void *param)
{
struct obs_core_video_mix *video = get_mix_for_video(v);
if (video)
if (!video)
return;
if (video_output_disconnect2(v, callback, param))
os_atomic_dec_long(&video->raw_active);
video_output_disconnect(v, callback, param);
}

void obs_add_raw_video_callback(const struct video_scale_info *conversion,
Expand Down
Loading