我正在编写一个使用AVFoundation和CMTime的应用程序。我已经记录了使用CMTime创建的CMTimeMake()实例的值。该值似乎四舍五入到最接近的整数。我需要一个具有精确值的CMTime实例,并且不进行舍入。

我已经在CMTime参考中看到了舍入常量:

enum {
   kCMTimeRoundingMethod_RoundHalfAwayFromZero = 1,
   kCMTimeRoundingMethod_RoundTowardZero = 2,
   kCMTimeRoundingMethod_RoundAwayFromZero = 3,
   kCMTimeRoundingMethod_QuickTime = 4,
   kCMTimeRoundingMethod_RoundTowardPositiveInfinity = 5,
   kCMTimeRoundingMethod_RoundTowardNegativeInfinity = 6,

   kCMTimeRoundingMethod_Default = kCMTimeRoundingMethod_RoundHalfAwayFromZero
};


没有任何示例可以说明我如何控制将哪些策略应用于CMTime实例?或者,如果这不是正确的方法,如何从CMTime实例中提取精确值?



编辑:

我已经找到并测试了CMTIME_HAS_BEEN_ROUNDED()。我将我的CMTime实例传递给该函数,并且它返回No(指示该值尚未四舍五入)。那为什么我会失去精度呢?

最佳答案

如果阅读documentation for CMTime,您将看到它使用分子和分母将时间存储为有理数。分子是int64_t,而分母是int32_t

分子指定通过了多少“滴答声”,分母指定了每秒有多少“滴答声”。

因此,0.5秒可以存储为:


100/200:100滴答声,每秒200滴答声
500/1000:500滴答声,每秒1000滴答声
8 / 16、8滴答声,每秒16滴答声


依此类推。使用的方式

CMTimeMake([[Array objectAtIndex:i]floatValue], 1);


说的是“每秒有一个刻度”,并且由于分子是整数,浮点值被截断,因此仅存储1。因此,您将时间指定为:1/1,已经过去了1个滴答,每秒1个滴答,因此实际上您正好存储1秒。

要解决此问题,取决于您要做什么以及是否关心时间范围。 Apple recommends a timescale of 600,但是如果您不在乎,则可以执行以下操作:

CMTimeMake([[Array objectAtIndex:i]floatValue]*1000, 1000);


这将时间刻度设置为1000,因此每秒1000个滴答声,因此每个滴答声为1毫秒。它还会将以秒为单位的时间转换为毫秒。请注意,它会截断第四个数字,因此,如果您有1.2345,则只会得到1.234而不是1.235。如果这对您很重要,请参见roundf

关于iphone - 使用CMTime而不四舍五入吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5418077/

10-13 09:21