diff --git a/plugins/win-dshow/win-dshow.cpp b/plugins/win-dshow/win-dshow.cpp index a29d92c88..068eb0b03 100644 --- a/plugins/win-dshow/win-dshow.cpp +++ b/plugins/win-dshow/win-dshow.cpp @@ -16,6 +16,9 @@ * - if device not present, wait for device to be plugged in */ +#undef min +#undef max + using namespace std; using namespace DShow; @@ -57,6 +60,27 @@ struct DShowInput { void Update(obs_data_t settings); }; +template +static bool between(T &&lower, U &&value, V &&upper) +{ + return value >= lower && value <= upper; +} + +static bool ResolutionAvailable(const VideoInfo &cap, int cx, int cy) +{ + return between(cap.minCX, cx, cap.maxCX) && + between(cap.minCY, cy, cap.maxCY); +} + +#define DEVICE_INTERVAL_DIFF_LIMIT 20 + +static bool FrameRateAvailable(const VideoInfo &cap, long long interval) +{ + return between(cap.minInterval - DEVICE_INTERVAL_DIFF_LIMIT, + interval, + cap.maxInterval + DEVICE_INTERVAL_DIFF_LIMIT); +} + void encode_dstr(struct dstr *str) { dstr_replace(str, "#", "#22"); @@ -160,6 +184,12 @@ static inline bool ConvertRes(int &cx, int &cy, const char *res) return sscanf(res, "%dx%d", &cx, &cy) == 2; } +static bool FormatMatches(VideoFormat left, VideoFormat right) +{ + return left == VideoFormat::Any || right == VideoFormat::Any || + left == right; +} + static void ApplyDefaultConfigSettings(obs_data_t settings, const VideoConfig &config) { @@ -380,30 +410,13 @@ static const FPSFormat validFPSFormats[] = { {"1", MAKE_DSHOW_FPS(1)}, }; -#define DEVICE_INTERVAL_DIFF_LIMIT 20 - static bool AddFPSRate(obs_property_t p, const FPSFormat &format, const VideoInfo &cap) { long long interval = format.interval; - if (format.interval < cap.minInterval || - format.interval > cap.maxInterval) { - /* account for slight inaccuracies in intervals - * among different devices */ - long long diff = 0; - - if (format.interval < cap.minInterval) { - interval = cap.minInterval; - diff = cap.minInterval - format.interval; - } else if (format.interval > cap.maxInterval) { - interval = cap.maxInterval; - diff = format.interval - cap.minInterval; - } - - if (diff > DEVICE_INTERVAL_DIFF_LIMIT) - return false; - } + if (!FrameRateAvailable(format, cap)) + return false; obs_property_list_add_int(p, format.text, interval); return true; @@ -417,12 +430,9 @@ static inline bool AddFPSRates(obs_property_t p, const VideoDevice &device, for (const FPSFormat &format : validFPSFormats) { for (const VideoInfo &cap : device.caps) { - if (cx >= cap.minCX && cx <= cap.maxCX && - cy >= cap.minCY && cy <= cap.maxCY) { - + if (ResolutionAvailable(cap, cx, cy)) { if (!intervalFound) { - if (interval >= cap.minInterval && - interval <= cap.maxInterval) + if (FrameRateAvailable(cap, interval)) intervalFound = true; else if (cap.minInterval < bestInterval) bestInterval = cap.minInterval; @@ -589,11 +599,9 @@ static bool UpdateVideoFormats(obs_properties_t props, VideoDevice &device, for (const VideoFormatName &name : videoFormatNames) { for (const VideoInfo &cap : device.caps) { - if (interval >= cap.minInterval && - interval <= cap.maxInterval && - cx >= cap.minCX && cx <= cap.maxCX && - cy >= cap.minCY && cy <= cap.maxCY && - cap.format == name.format) { + if (FrameRateAvailable(cap, interval) && + ResolutionAvailable(cap, cx, cy) && + FormatMatches(cap.format, name.format)) { if (format == cap.format) foundFormat = true;