Использование CMTime без округления? - PullRequest
0 голосов
/ 24 марта 2011

Я пишу приложение, которое использует 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 экземпляра?


Edit:

Я нашел и протестировал CMTIME_HAS_BEEN_ROUNDED(). Я передал свой экземпляр CMTime этой функции, и он возвращает No (указывая, что значение не было округлено). Так почему я теряю точность?

Ответы [ 2 ]

7 голосов
/ 25 марта 2011

Если вы прочитаете документацию для 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 секунду.

Чтобы это исправить, это зависит от того, что вы хотите сделать, и заботитесь ли вы о сроках. Apple рекомендует шкалу времени 600 , но если вам все равно, вы можете просто сделать это:

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

Это устанавливает временной масштаб на 1000, поэтому 1000 тиков в секунду, то есть одна миллисекунда на тик. Он также преобразует время в секундах в миллисекунды. Обратите внимание, что он усекает 4-ю цифру, поэтому, если у вас 1,2345, вы просто получите 1,234, а не 1,235. Если это важно для вас, см. roundf.

0 голосов
/ 19 марта 2015

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

Это помогло мне получить точное время в миллисекундах.Приветствия.

...