Browse Source

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.
jp9000 11 years ago
parent
commit
d6e98829ca
2 changed files with 56 additions and 0 deletions
  1. 4 0
      plugins/win-dshow/data/locale/en-US.ini
  2. 52 0
      plugins/win-dshow/win-dshow.cpp

+ 4 - 0
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"

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