From d6e98829ca91ec35ac7a39fb3a5eebd14eebfa7f Mon Sep 17 00:00:00 2001 From: jp9000 Date: Wed, 31 Dec 2014 21:59:46 -0800 Subject: [PATCH] win-dshow: Add buffering options Allow the user to select whether to buffer the source or not. The settings are auto-detect, on, and off. Auto-Detect turns it off for non-encoded devices, and on for encoded devices. Webcams, internal devices, and other such things on windows do not really need to be buffered, and buffering incurs a tiny bit of delay, so turning off buffering is actually a little better for non-encoded devices. --- plugins/win-dshow/data/locale/en-US.ini | 4 ++ plugins/win-dshow/win-dshow.cpp | 52 +++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/plugins/win-dshow/data/locale/en-US.ini b/plugins/win-dshow/data/locale/en-US.ini index 2a54c6b5d..4290680ed 100644 --- a/plugins/win-dshow/data/locale/en-US.ini +++ b/plugins/win-dshow/data/locale/en-US.ini @@ -15,6 +15,10 @@ VideoFormat.Any="Any" VideoFormat.Unknown="Unknown (%1)" UseCustomAudioDevice="Use custom audio device" AudioDevice="Audio Device" +Buffering="Buffering" +Buffering.AutoDetect="Auto-Detect" +Buffering.Enable="Enable" +Buffering.Disable="Disable" # encoder text Bitrate="Bitrate" diff --git a/plugins/win-dshow/win-dshow.cpp b/plugins/win-dshow/win-dshow.cpp index 40232029c..e54e78100 100644 --- a/plugins/win-dshow/win-dshow.cpp +++ b/plugins/win-dshow/win-dshow.cpp @@ -35,6 +35,7 @@ using namespace DShow; #define VIDEO_FORMAT "video_format" #define LAST_VIDEO_DEV_ID "last_video_device_id" #define LAST_RESOLUTION "last_resolution" +#define BUFFERING_VAL "buffering" #define USE_CUSTOM_AUDIO "use_custom_audio_device" #define AUDIO_DEVICE_ID "audio_device_id" @@ -50,6 +51,10 @@ using namespace DShow; #define TEXT_RESOLUTION obs_module_text("Resolution") #define TEXT_VIDEO_FORMAT obs_module_text("VideoFormat") #define TEXT_FORMAT_UNKNOWN obs_module_text("VideoFormat.Unknown") +#define TEXT_BUFFERING obs_module_text("Buffering") +#define TEXT_BUFFERING_AUTO obs_module_text("Buffering.AutoDetect") +#define TEXT_BUFFERING_ON obs_module_text("Buffering.Enable") +#define TEXT_BUFFERING_OFF obs_module_text("Buffering.Disable") #define TEXT_CUSTOM_AUDIO obs_module_text("UseCustomAudioDevice") #define TEXT_AUDIO_DEVICE obs_module_text("AudioDevice") @@ -58,6 +63,12 @@ enum ResType { ResType_Custom }; +enum class BufferingType : int64_t { + Auto, + On, + Off +}; + void ffmpeg_log(void *bla, int level, const char *msg, va_list args) { DStr str; @@ -205,6 +216,8 @@ struct DShowInput { bool UpdateAudioConfig(obs_data_t *settings); void Update(obs_data_t *settings); + inline void SetupBuffering(obs_data_t *settings); + void DShowLoop(); }; @@ -652,6 +665,34 @@ static bool DetermineResolution(int &cx, int &cy, obs_data_t *settings, static long long GetOBSFPS(); +static inline bool IsEncoded(const VideoConfig &config) +{ + return config.format >= VideoFormat::MJPEG || + wstrstri(config.name.c_str(), L"elgato") != NULL || + wstrstri(config.name.c_str(), L"stream engine") != NULL; +} + +inline void DShowInput::SetupBuffering(obs_data_t *settings) +{ + BufferingType bufType; + uint32_t flags = obs_source_get_flags(source); + bool useBuffering; + + bufType = (BufferingType)obs_data_get_int(settings, BUFFERING_VAL); + + if (bufType == BufferingType::Auto) + useBuffering = IsEncoded(videoConfig); + else + useBuffering = bufType == BufferingType::On; + + if (useBuffering) + flags &= ~OBS_SOURCE_FLAG_UNBUFFERED; + else + flags |= OBS_SOURCE_FLAG_UNBUFFERED; + + obs_source_set_flags(source, flags); +} + bool DShowInput::UpdateVideoConfig(obs_data_t *settings) { string video_device_id = obs_data_get_string(settings, VIDEO_DEVICE_ID); @@ -729,6 +770,8 @@ bool DShowInput::UpdateVideoConfig(obs_data_t *settings) return false; } + SetupBuffering(settings); + return true; } @@ -1518,6 +1561,15 @@ static obs_properties_t *GetDShowProperties(void *) obs_property_set_modified_callback(p, VideoFormatChanged); + p = obs_properties_add_list(ppts, BUFFERING_VAL, TEXT_BUFFERING, + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_list_add_int(p, TEXT_BUFFERING_AUTO, + (int64_t)BufferingType::Auto); + obs_property_list_add_int(p, TEXT_BUFFERING_ON, + (int64_t)BufferingType::On); + obs_property_list_add_int(p, TEXT_BUFFERING_OFF, + (int64_t)BufferingType::Off); + /* ------------------------------------- */ /* audio settings */