From 015bc80edb31dcdf70ca9e34e10fb4c5a73998b1 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Thu, 23 Oct 2014 09:56:50 -0700 Subject: [PATCH] Add optional source flags This moves the 'flags' variable from the obs_source_frame structure to the obs_source structure, and allows user flags to be set for a specific source. Having it set on the obs_source_frame structure didn't make much sense. OBS_SOURCE_UNBUFFERED makes it so that the source does not buffer its async video output in order to try to play it on time. In other words, frames are played as soon as possible after being received. Useful when you want a source to play back as quickly as possible (webcams, certain types of capture devices) --- libobs/obs-internal.h | 3 +++ libobs/obs-source.c | 38 ++++++++++++++++++++++++++++++++++++++ libobs/obs.h | 10 ++++++++++ 3 files changed, 51 insertions(+) diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h index dbf07fb75..0f8e0ed2d 100644 --- a/libobs/obs-internal.h +++ b/libobs/obs-internal.h @@ -269,6 +269,9 @@ struct obs_source { struct obs_source_info info; volatile long refs; + /* general exposed flags that can be set for the source */ + uint32_t flags; + /* indicates ownership of the info.id buffer */ bool owns_info_id; diff --git a/libobs/obs-source.c b/libobs/obs-source.c index 8b7a92c09..f9ae3a407 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -83,6 +83,7 @@ static const char *source_signals[] = { "void volume_level(ptr source, float level, float magnitude, " "float peak)", "void update_properties(ptr source)", + "void update_flags(ptr source, int flags)", NULL }; @@ -1606,6 +1607,16 @@ static bool ready_async_frame(obs_source_t *source, uint64_t sys_time) uint64_t frame_time = next_frame->timestamp; uint64_t frame_offset = 0; + if ((source->flags & OBS_SOURCE_UNBUFFERED) != 0) { + while (source->video_frames.num > 1) { + da_erase(source->video_frames, 0); + obs_source_frame_destroy(next_frame); + next_frame = source->video_frames.array[0]; + } + + return true; + } + #if DEBUG_ASYNC_FRAMES blog(LOG_DEBUG, "source->last_frame_ts: %llu, frame_time: %llu, " "sys_offset: %llu, frame_offset: %llu, " @@ -2077,3 +2088,30 @@ void obs_source_load(obs_source_t *source) if (!source_valid(source) || !source->info.load) return; source->info.load(source->context.data, source->context.settings); } + +static inline void signal_flags_updated(obs_source_t *source) +{ + struct calldata data = {0}; + + calldata_set_ptr(&data, "source", source); + calldata_set_int(&data, "flags", source->flags); + + signal_handler_signal(source->context.signals, "update_flags", &data); + + calldata_free(&data); +} + +void obs_source_set_flags(obs_source_t *source, uint32_t flags) +{ + if (!source) return; + + if (flags != source->flags) { + source->flags = flags; + signal_flags_updated(source); + } +} + +uint32_t obs_source_get_flags(const obs_source_t *source) +{ + return source ? source->flags : 0; +} diff --git a/libobs/obs.h b/libobs/obs.h index 533482ace..5c7ae76c9 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -722,6 +722,16 @@ EXPORT void obs_source_save(obs_source_t *source); */ EXPORT void obs_source_load(obs_source_t *source); +/** Specifies that async video frames should be played as soon as possible */ +#define OBS_SOURCE_UNBUFFERED (1<<0) + +/** Sets source flags. Note that these are different from the main output + * flags. */ +EXPORT void obs_source_set_flags(obs_source_t *source, uint32_t flags); + +/** Gets source flags. */ +EXPORT uint32_t obs_source_get_flags(const obs_source_t *source); + /* ------------------------------------------------------------------------- */ /* Functions used by sources */