串流路由實作考慮

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

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

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

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

裝置通知的數據流圖表。

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

串流管理

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

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

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

  3. 等候 IAudioSessionEvents::OnSessionDisconnected,並具有原因值。

    注意

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

     

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

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

  6. 執行位置對應計算。

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

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

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

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

位置對應考慮

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

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

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

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

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

關於 MMDevice API

關於 WASAPI 的

串流路由