libobs: Don't use source flags for async buffering
(This commit also modifies the decklink, linux-v4l2, mac-avcapture, obs-ffmpeg, and win-dshow modules) Originally, async buffering for sources was supposed to be a user-controllable flag. However, that turned out to be less than ideal because sources (such as the win-dshow plugin) were programmed with automatic control over their buffering (such as automatically detecting USB 2.0 capture devices and then enabling in those cases). The fact that it was a flag caused a design flaw to where buffering values would be overwritten when a source is loaded from save data. Because of that, this flag is being deprecated and replaced with a specific function to enable unbuffered mode instead.master
parent
d64542e10b
commit
d13fa96851
|
@ -608,6 +608,7 @@ struct obs_source {
|
|||
bool async_flip;
|
||||
bool async_active;
|
||||
bool async_update_texture;
|
||||
bool async_unbuffered;
|
||||
struct obs_source_frame *async_preload_frame;
|
||||
DARRAY(struct async_frame) async_cache;
|
||||
DARRAY(struct obs_source_frame*)async_frames;
|
||||
|
|
|
@ -27,7 +27,7 @@ static bool ready_deinterlace_frames(obs_source_t *source, uint64_t sys_time)
|
|||
uint64_t frame_offset = 0;
|
||||
size_t idx = 1;
|
||||
|
||||
if ((source->flags & OBS_SOURCE_FLAG_UNBUFFERED) != 0) {
|
||||
if (source->async_unbuffered) {
|
||||
while (source->async_frames.num > 2) {
|
||||
da_erase(source->async_frames, 0);
|
||||
remove_async_frame(source, next_frame);
|
||||
|
|
|
@ -2602,7 +2602,7 @@ 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_FLAG_UNBUFFERED) != 0) {
|
||||
if (source->async_unbuffered) {
|
||||
while (source->async_frames.num > 1) {
|
||||
da_erase(source->async_frames, 0);
|
||||
remove_async_frame(source, next_frame);
|
||||
|
@ -4020,3 +4020,17 @@ enum obs_monitoring_type obs_source_get_monitoring_type(
|
|||
return obs_source_valid(source, "obs_source_get_monitoring_type") ?
|
||||
source->monitoring_type : OBS_MONITORING_TYPE_NONE;
|
||||
}
|
||||
|
||||
void obs_source_set_async_unbuffered(obs_source_t *source, bool unbuffered)
|
||||
{
|
||||
if (!obs_source_valid(source, "obs_source_set_async_unbuffered"))
|
||||
return;
|
||||
|
||||
source->async_unbuffered = unbuffered;
|
||||
}
|
||||
|
||||
bool obs_source_async_unbuffered(const obs_source_t *source)
|
||||
{
|
||||
return obs_source_valid(source, "obs_source_async_unbuffered") ?
|
||||
source->async_unbuffered : false;
|
||||
}
|
||||
|
|
|
@ -834,8 +834,8 @@ EXPORT bool obs_source_active(const obs_source_t *source);
|
|||
*/
|
||||
EXPORT bool obs_source_showing(const obs_source_t *source);
|
||||
|
||||
/** Specifies that async video frames should be played as soon as possible */
|
||||
#define OBS_SOURCE_FLAG_UNBUFFERED (1<<0)
|
||||
/** Unused flag */
|
||||
#define OBS_SOURCE_FLAG_UNUSED_1 (1<<0)
|
||||
/** Specifies to force audio to mono */
|
||||
#define OBS_SOURCE_FLAG_FORCE_MONO (1<<1)
|
||||
|
||||
|
@ -1100,6 +1100,10 @@ EXPORT uint64_t obs_source_get_audio_timestamp(const obs_source_t *source);
|
|||
EXPORT void obs_source_get_audio_mix(const obs_source_t *source,
|
||||
struct obs_source_audio_mix *audio);
|
||||
|
||||
EXPORT void obs_source_set_async_unbuffered(obs_source_t *source,
|
||||
bool unbuffered);
|
||||
EXPORT bool obs_source_async_unbuffered(const obs_source_t *source);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Transition-specific functions */
|
||||
enum obs_transition_target {
|
||||
|
|
|
@ -31,12 +31,7 @@ static DeckLinkDeviceDiscovery *deviceEnum = nullptr;
|
|||
static void decklink_enable_buffering(DeckLink *decklink, bool enabled)
|
||||
{
|
||||
obs_source_t *source = decklink->GetSource();
|
||||
uint32_t flags = obs_source_get_flags(source);
|
||||
if (enabled)
|
||||
flags &= ~OBS_SOURCE_FLAG_UNBUFFERED;
|
||||
else
|
||||
flags |= OBS_SOURCE_FLAG_UNBUFFERED;
|
||||
obs_source_set_flags(source, flags);
|
||||
obs_source_set_async_unbuffered(source, !enabled);
|
||||
}
|
||||
|
||||
static void *decklink_create(obs_data_t *settings, obs_source_t *source)
|
||||
|
|
|
@ -912,11 +912,8 @@ fail:
|
|||
static void v4l2_update_source_flags(struct v4l2_data *data,
|
||||
obs_data_t *settings)
|
||||
{
|
||||
uint32_t flags = obs_source_get_flags(data->source);
|
||||
flags = (obs_data_get_bool(settings, "buffering"))
|
||||
? flags & ~OBS_SOURCE_FLAG_UNBUFFERED
|
||||
: flags | OBS_SOURCE_FLAG_UNBUFFERED;
|
||||
obs_source_set_flags(data->source, flags);
|
||||
obs_source_set_async_unbuffered(data->source,
|
||||
!obs_data_get_bool(settings, "buffering"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -645,13 +645,7 @@ static inline bool update_frame(av_capture *capture,
|
|||
|
||||
static void av_capture_enable_buffering(av_capture *capture, bool enabled)
|
||||
{
|
||||
obs_source_t *source = capture->source;
|
||||
uint32_t flags = obs_source_get_flags(source);
|
||||
if (enabled)
|
||||
flags &= ~OBS_SOURCE_FLAG_UNBUFFERED;
|
||||
else
|
||||
flags |= OBS_SOURCE_FLAG_UNBUFFERED;
|
||||
obs_source_set_flags(source, flags);
|
||||
obs_source_set_async_unbuffered(capture->source, !enabled);
|
||||
}
|
||||
|
||||
static const char *av_capture_getname(void*)
|
||||
|
|
|
@ -273,14 +273,14 @@ static void ffmpeg_source_update(void *data, obs_data_t *settings)
|
|||
input_format = NULL;
|
||||
s->is_looping = obs_data_get_bool(settings, "looping");
|
||||
|
||||
obs_source_set_flags(s->source, OBS_SOURCE_FLAG_UNBUFFERED);
|
||||
obs_source_set_async_unbuffered(s->source, true);
|
||||
} else {
|
||||
input = (char *)obs_data_get_string(settings, "input");
|
||||
input_format = (char *)obs_data_get_string(settings,
|
||||
"input_format");
|
||||
s->is_looping = false;
|
||||
|
||||
obs_source_set_flags(s->source, 0);
|
||||
obs_source_set_async_unbuffered(s->source, false);
|
||||
}
|
||||
|
||||
s->input = input ? bstrdup(input) : NULL;
|
||||
|
|
|
@ -753,12 +753,7 @@ inline void DShowInput::SetupBuffering(obs_data_t *settings)
|
|||
else
|
||||
useBuffering = bufType == BufferingType::On;
|
||||
|
||||
if (useBuffering)
|
||||
flags &= ~OBS_SOURCE_FLAG_UNBUFFERED;
|
||||
else
|
||||
flags |= OBS_SOURCE_FLAG_UNBUFFERED;
|
||||
|
||||
obs_source_set_flags(source, flags);
|
||||
obs_source_set_async_unbuffered(source, !useBuffering);
|
||||
}
|
||||
|
||||
static DStr GetVideoFormatName(VideoFormat format);
|
||||
|
|
Loading…
Reference in New Issue