當前位置:編程學習大全網 - 圖片素材 - 這可能是最詳細的CMTime教程

這可能是最詳細的CMTime教程

最近在做視頻開發,避不開就是會用到 CMTime 。根據網上之前的教程, CMTime 的用法其實挺簡單的,例如:

然後告訴妳 seconds 是時長, preferredTimeScale 是幀率。

這裏 value 表示視頻的幀數, preferredTimeScale 表示每秒的幀數。所以這裏 seconds 是 10000/600 = 16.667

OK,以上其實理解起來沒問題,但是當我們在處理視頻的時候,常常要把後面的 timeScale 寫成600:

那麽這裏就有個問題:如果 timeScale 表示的幀率,這裏的意思是視頻每秒的幀率是600幀麽

我們知道人眼可識別的幀率24幀就夠了,iPhone手機拍攝幀率為60fps,部分安卓手機的幀率甚至只有30fps。那麽這裏為什麽要設置為600呢?

重新去查Apple的文檔,看到裏面這麽解釋:

這裏的意思是使用600幀,可以兼容各種視頻幀率(24fps, 30fps, 25fps等),是這些幀率的最小公倍數。不過這並不能解釋之前的困惑,設置成600以後,視頻的幀率真的達到600fps了麽?這樣子GPU在處理照片的時候不會出現問題嗎?

假設我們需要在視頻文件中精確地指定壹個時刻,比如35:06。通常的方法是把時間表示為壹個雙精度的浮點數據,比如: NSTimeInterval t = 2106.0; 那這個方法在大多數情況下是沒有問題的,但是當我們把非常長的時間段劃分成非常小的切片時,就會出現問題。不直接進行浮點類型的運算,而是把壹個 double 類型可以容納大約16位有效數字(十進制)的8個字節的內存空間(在其他通用平臺上, sizeof(NSTimeInterval) == sizeof(Float64) == sizeof(double) == 8 )。 再次普及double浮點型數據的換算過程和推算原理

浮點數存在壹個大問題: 重復操作(加法,乘法等)導致不精確的積累,於是在視頻時長很長的時候這個差異會被無限放大,從而在同步多個媒體流時可能導致錯誤。

這裏舉個栗子。壹百萬個0.000001相加,結果約為1.0000000000079181。該錯誤是由於1e-6不能以我們使用的 double 類型精確的表示,所以我們改為使用二進制近似位,它的低有效位不同。這並不是壹個大問題,但是當妳在運行壹個HTTP流服務器的時候,那麽妳可能會無限期的每秒去積累這種不精確度。

這就促使我們去找到壹種更精確表達時間的方式,通過消除double類型和他們固有的不精確性(不說他們的硬編碼舍入行為)。

雖然Apple已經有很多數據結構來表示Mac和iOS平臺上的時間,但是在iOS4和Mac OS X 10.7 推出的時候,加上了CMTime和CMTimeRange。CMTime的類型定義如下:

顯然, CMTime 定義是壹個C語言的結構體,CMTime是以分數的形式表示時間, value 表示分子, timescale 表示分母, flags 是位掩碼,表示時間的指定狀態。

這裏 value , timescale 是分別以 64位 和 32位 整數來存儲的,我們從上文已經知道,這樣可以避免 double 類型帶來的精度丟失。另外,通過用 64位 整數來表示分子,我們可以為每個 timescale 表示90億個不同的正值,最多19位唯壹的十進制數字。

那麽 timescale 又是什麽? 它表示每秒分割的“切片”數。 CMTime 的整體精度就是受到這個限制的。比如:

如果 timescale 為1,則不能有對象表示小於1秒的時間戳,並且時間戳以1秒為增量。類似的,如果 timescale 是1000,則每秒被分割成1000個,並且該 value 表示我們要顯示的毫秒數。

所以當妳試圖表示0.5秒的時候,妳千萬不能這麽寫:

這裏interval實際上是0 而不是0.5。

所以為了能讓妳選擇合理的時間尺度確保不被截斷,Apple建議我們使用600。如果妳需要對音頻文件進行更精確的所以,妳可以把timescale設為60,000或更高。這裏64位 value的好處就是,妳仍然可以用這種方式來明確的表示580萬年的增量,即1/60,000秒。

所以,這裏可以得出結論:

  • 上一篇:基於JSP SSH的網上購物系統畢業答辯壹般會問什麽問題
  • 下一篇:《天降女子》相似的有哪些?
  • copyright 2024編程學習大全網