Browse Source

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)
jp9000 11 years ago
parent
commit
015bc80edb
3 changed files with 51 additions and 0 deletions
  1. 3 0
      libobs/obs-internal.h
  2. 38 0
      libobs/obs-source.c
  3. 10 0
      libobs/obs.h

+ 3 - 0
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;
 

+ 38 - 0
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;
+}

+ 10 - 0
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 */