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
jp9000 2017-05-13 23:32:40 -07:00
parent d64542e10b
commit d13fa96851
9 changed files with 30 additions and 30 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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 {

View File

@ -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)

View File

@ -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"));
}
/**

View File

@ -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*)

View File

@ -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;

View File

@ -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);