18#ifndef FREERDP_RDPECAM_AVFOUNDATION_FRAME_RATE_H
19#define FREERDP_RDPECAM_AVFOUNDATION_FRAME_RATE_H
22#include <CoreMedia/CoreMedia.h>
23#include <winpr/assert.h>
24#include <winpr/wtypes.h>
25#include "capture_policy.h"
28static inline BOOL cam_avfoundation_frame_duration(UINT32 numerator, UINT32 denominator,
29 CMTime minimum, CMTime maximum, CMTime* duration)
31 WINPR_ASSERT(duration);
32 if (!numerator || (numerator > INT32_MAX) || !denominator || !CMTIME_IS_NUMERIC(minimum) ||
33 !CMTIME_IS_NUMERIC(maximum) || (minimum.value <= 0) || (maximum.value <= 0) ||
34 (minimum.timescale <= 0) || (maximum.timescale <= 0) || minimum.epoch || maximum.epoch ||
35 (CMTimeCompare(minimum, maximum) > 0))
37 const CMTime requested = CMTimeMake(denominator, (CMTimeScale)numerator);
38 CMTime supported = requested;
39 if (CMTimeCompare(requested, minimum) < 0)
41 else if (CMTimeCompare(requested, maximum) > 0)
47 const double seconds = CMTimeGetSeconds(requested);
48 if (fabs(CMTimeGetSeconds(supported) - seconds) >
49 seconds * CAM_AVFOUNDATION_FRAME_DURATION_TOLERANCE)
51 *duration = supported;
56static inline BOOL cam_avfoundation_frame_rate(CMTime duration, UINT32* numerator,
59 WINPR_ASSERT(numerator);
60 WINPR_ASSERT(denominator);
61 if (!CMTIME_IS_NUMERIC(duration) || (duration.value <= 0) || (duration.timescale <= 0) ||
65 UINT64 num = (UINT32)duration.timescale;
66 UINT64 den = (UINT64)duration.value;
71 const UINT64 remainder = a % b;
77 if ((num > UINT32_MAX) || (den > UINT32_MAX))
79 *numerator = (UINT32)num;
80 *denominator = (UINT32)den;