簡報時鐘

簡報時鐘是物件,可產生簡報的時鐘時間。 簡報時鐘所報告的時間稱為 簡報時間。 簡報中的所有資料流程都會同步處理到簡報時間。 簡報時鐘會公開下列介面。

介面 描述
IMFPresentationClock 使用簡報時鐘的主要介面。
IMFRateControl 控制時脈速率。
IMFTimer 提供計時器回呼。
IMFShutdown 關閉簡報時鐘。

 

媒體接收會使用簡報時間來排程何時轉譯樣本。 每當媒體接收收到新的樣本時,它會從範例取得時間戳記,並在指定的時間轉譯樣本,或盡可能接近該時間。 由於拓撲中的所有媒體接收都會共用相同的簡報時鐘,因此會同步處理多個串流 (,例如音訊和視訊) 。 媒體來源和轉換不會使用簡報時鐘,因為它們不會排程何時提供樣本。 相反地,每當管線要求新的範例時,就會產生範例。

如果您使用媒體會話播放,媒體會話會處理建立簡報時鐘、選取時間來源,以及通知媒體接收的所有詳細資料。 您的應用程式可能會在播放期間使用簡報時鐘來取得目前的簡報時間,否則不會在簡報時鐘上呼叫任何方法。

時鐘時間和時鐘狀態

若要從簡報時鐘取得最新的時鐘時間,請呼叫 IMFPresentationClock::GetTime。 時鐘時間一律為 100 奈秒單位,因此一秒為 10,000,000 (10^7) 刻度。 這會對應至 10 MHz 的頻率。

簡報時鐘有三種狀態:執行中、暫停和停止。

根據預設,時鐘會以 1.0 的速率前進,這表示每 100 奈秒 1 個刻度。 若要變更時鐘前進的速率,請查詢 IMFRateControl 介面的簡報時鐘,並呼叫 IMFRateControl::SetRate

物件可以接收狀態變更的通知, (包括從簡報時鐘) 的速率變更。 若要接收通知,請實作 IMFClockStateSink 介面,並在簡報時鐘上呼叫 IMFPresentationClock::AddClockStateSink 。 關閉之前,請先呼叫 IMFPresentationClock::RemoveClockStateSink 來取消註冊物件。 媒體接收會使用此機制從時鐘接收通知。

簡報時間

媒體接收會嘗試排程每個樣本,讓樣本在正確的時間轉譯,或盡可能接近正確的時間。 適用下列定義:

  • 簡報時間。 應該呈現樣本的時間。 時間是以 100 奈秒為單位來指定。
  • 媒體時間。 相對於內容開頭的時間。 例如,如果視訊檔案的長度為 10 秒,則透過檔案的一半點有 5 秒的媒體時間。
  • 時間戳記。 在媒體範例上標示的時間。 若要取得時間戳記,請呼叫 IMFSample::GetSampleTime。 當媒體來源產生範例時,它會將時間戳記設定為等於媒體時間。 媒體會話會將時間戳記轉譯為簡報時間。

根據預設,媒體時間和簡報時間相同,例如,如果視訊畫面在來源檔案中出現 5 秒,媒體時間和簡報時間都是 5 秒。 如果您使用 Sequencer 來源,計時模型會稍微複雜一些,以在區段之間順暢轉換。 如需排序器來源計時模型的詳細資訊,請參閱 時序表示時間

媒體來源一律會將時間戳記設定為等於媒體時間。 如果簡報時間與媒體時間不一致,媒體會話會轉換媒體範例上的時間戳記。 接收接收樣本時,範例的時間戳記已轉換為簡報時間。 接收會根據簡報時鐘的目前時間排程樣本。 (無速率接收是例外狀況,因為它們會忽略簡報時鐘。)

如果應用程式搜尋到新位置,媒體會話會在指定的搜尋時間重新開機簡報時鐘。 例如,如果應用程式搜尋檔案中的 5 秒位置,媒體會話就會在 5 秒開始時鐘。 如果搜尋時間不落在主要畫面格界限上,媒體來源可能會提供稍早時間戳記的樣本。 這是必要的,讓解碼器可以解碼所有畫面。 媒體會話會先卸載或修剪樣本,再到達媒體接收,以符合要求的搜尋時間。 例如,如果搜尋時間是 5 秒,則第一個音訊範例可能會從 4.5 秒開始。 媒體會話會從第一個解碼的音訊範例修剪前 0.5 秒。

建立簡報時鐘

若要建立簡報時鐘,請呼叫 MFCreatePresentationClock。 若要關閉時鐘,請查詢 IMFShutdown 介面並呼叫 IMFShutdown::ShutdownMFCreatePresentationClock的呼叫端負責呼叫Shutdown;在大部分情況下,這是媒體會話,而不是應用程式。

簡報時間來源

雖然它的名稱,但簡報時鐘實際上不會實作時鐘。 相反地,它會從另一個物件取得時鐘時間,稱為 簡報時間來源。 時間來源可以是產生精確時鐘刻度並公開 IMFPresentationTimeSource 介面的任何物件。 下圖顯示這項程序。

顯示簡報時鐘與簡報時間來源之間關聯性的圖表

第一次建立簡報時鐘時,它沒有時間來源。 若要設定時間來源,請使用時間來源的 IMFPresentationTimeSource介面指標呼叫IMFPresentationClock::SetTimeSource。 時間來源支援與簡報時鐘相同的狀態, (執行、暫停和停止) ,而且必須實作 IMFClockStateSink 介面。 簡報時鐘會使用此介面來通知時間來源何時變更狀態。 如此一來,時間來源就會提供時鐘刻度,但表示時鐘會起始時鐘的狀態變更。

某些媒體接收可以存取精確的時鐘,因此會公開 IMFPresentationTimeSource 介面。 特別是,音訊轉譯器可以使用音效卡的頻率做為時鐘。 在音訊播放中,音訊轉譯器可作為時間來源,以便將視訊同步處理至音訊播放速率。 這通常會產生比嘗試比對音訊與外部時鐘更好的結果。

媒體基礎也會根據系統時鐘提供簡報時間來源。 若要建立此物件,請呼叫 MFCreateSystemTimeSource。 當沒有媒體接收提供時間來源時,可以使用系統時間來源。

一般而言,媒體接收必須使用提供給它的簡報時鐘,無論簡報時鐘所使用的時間來源為何。 即使媒體接收實作 IMFPresentationTimeSource,此規則仍適用。 如果簡報時鐘使用其他時間來源,媒體接收必須遵循該時間來源,而不是自己的內部時鐘。

媒體接收不會遵循簡報時鐘時,有兩種情況:

  • 某些媒體接收是 無速率的。 如果媒體接收是無速率的,它會儘快取用樣本,而不會根據簡報時鐘排程它們。 一般而言,無速率接收會將資料寫入檔案,因此最好儘快完成作業。 無速率接收會傳回 其 IMFMediaSink::GetCharacteristics 方法中的 MEDIASINK_RATELESS 旗標。 當拓撲中的所有接收都是無速率時,媒體會話會儘快透過管線推送資料。

  • 某些媒體接收無法比對速率與本身以外的時間來源。 如果是,接收會在其 GetCharacteristics 方法中傳回MEDIASINK_CANNOT_MATCH_CLOCK旗標。 管線仍然可以使用另一個時間來源,但結果會比最佳。 接收可能會落後,並在播放期間造成問題。

媒體基礎平臺 API