串流路由實作考慮

在 Windows 7 中,使用核心音訊 API 的高階平臺 API,例如 Media Foundation、DirectSound 和 Wave API,藉由處理從現有裝置切換至新的預設音訊端點的串流路由功能,來實作串流路由功能。 使用這些 API 的媒體應用程式會使用資料流路由行為,而不需要對來源進行任何修改。 直接WASAPI用戶端可以使用核心音訊元件傳送的通知,並實作串流路由功能。

直接 WASAPI 用戶端(直接使用 WASAPI 的媒體應用程式)會接收核心音訊元件傳送的新裝置和音訊會話通知。 串流路由功能的行為是由應用程式如何處理這些通知所定義。

MMDevice API 和音訊會話會以回呼的形式,將裝置狀態變更和會話變更的通知傳送給WASAPI 用戶端。 若要取得這些通知,客戶端必須註冊其 IMMNotificationClient IAudioSessionEvents 的作。 如需詳細資訊,請參閱 串流路由的相關通知。

在串流路由中所述的USB頭戴式裝置案例中,應用程式正在播放音訊串流,並使用MMDeviceAPI和WASAPI在預設轉譯裝置說話者上轉譯數據流。 當預設裝置變更時,應用程式會收到 IMMNotificationClient 通知。 應用程式也會收到 IAudioSessionEvents 通知,指出使用者已移除音訊端點裝置,或音訊會話所連線之裝置的數據流格式已變更。 收到通知后,應用程式會停止串流至說話者端點,並重新開啟數據流,以在目前的默認端點頭戴式裝置上轉譯。

diagram of data flow for device notifications.

為了回應這類通知,用戶端可能會以用戶選取的新格式重新開啟新預設裝置上的數據流。

串流管理

下列清單摘要說明 WASAPI 用戶端必須執行以提供數據流切換功能的步驟。

  1. 等候相關的 IMMNotificationClient 通知。 如果裝置是預設裝置, 則會接收 IMMNotificationClient::OnDefaultDeviceChanged 通知。

  2. 如果有新的裝置可用,請取得新裝置端點的參考。 呼叫新預設裝置的 IMMDeviceEnumerator::GetDefaultAudioEndpoint 如果新裝置不是預設裝置,您可以呼叫 IMMDeviceEnumerator::GetDevice 來擷取裝置。 如需詳細資訊,請參閱 取得串流路由的裝置端點。

  3. 等候使用原因值來等候 IAudioSessionEvents::OnSessionDisconnected

    注意

    由於所有這些作業都是非時序的,因此無法預測應用程式接收裝置變更和會話中斷連線通知的順序。 應用程式必須實作通知處理,才能依任何順序接收這些通知。 不過,應用程式通常會在預設裝置變更通知之前收到 AudioSessionDisconnect 值。

     

  4. 評估原因值,並判斷數據流是否需要傳輸至另一個音訊端點,或數據流需要以新的格式重新初始化。

  5. 如果原因指出數據流應該重新路由至新的預設裝置,請停止串流至舊的預設裝置。

  6. 執行位置對應計算。

  7. 開啟新裝置上的數據流,並傳輸所有狀態資訊。

  8. 在新的預設裝置上繼續串流。

  9. 處理舊預設裝置的離開。

若要讓串流切換作業看起來順暢,必須儘快完成。 這取決於新裝置上重新初始化數據流所涉及的元件效能。

位置對應考慮

當應用程式取得 IMMNotificationClientIAudioSessionEvents 通知時,它可以將現有的數據流路由傳送至新的預設裝置。 當現有音訊串流中斷並在新裝置上開啟時,新裝置上的轉譯必須從在舊裝置上停止串流的位置開始。 若要這樣做,應用程式必須具有最後一個已知的裝置位置,才能計算新裝置上的開始位置。 例如,這個位置可用來做為後續位置對應的差異位移。 當數據流開始轉譯時,新的裝置位置可以重新對應到快取的裝置位置。

下列步驟摘要說明進行無縫數據流轉換的程式。

  1. 快取舊裝置上數據流的最後一個裝置位置。
  2. 停止舊裝置上的數據流。
  3. 執行重新對應計算以取得新位置。
  4. 開始在新裝置上轉譯數據流。
  5. 釋放舊的數據流。

在轉換期間,應用程式必須確保時鐘不會脫離同步處理,導致音訊和視訊串流失同步。 如果視訊範例在音訊串流路由傳送至新裝置時繼續轉譯,就會發生這種情況。 應用程式必須快取重新對應計算的時鐘位置,並確定在新的裝置上重新開啟音訊數據流之前,不會轉譯視訊樣本,以便在剪輯繼續轉譯時同步處理音訊和視訊串流。 在某些情況下,轉譯視訊畫面的簡報時間是以音訊時鐘為基礎,就足以停止音訊串流,直到串流切換完成,而且音訊視訊同步處理不需要其他位置對應實作。

如果在轉譯時, IAudioRenderClient::GetBuffer 傳回錯誤,因為舊裝置遺失,應用程式就不需要停止舊數據流,因為串流作業已經終止。 如需處理此錯誤的相關信息,請參閱 從 Invalid-Device Error 復原。

關於 MMDevice API

關於 WASAPI

串流路由