共用方式為


使用協力廠商編解碼器建立 ASF 檔案

[與此頁面相關聯的功能 Windows Media Format 11 SDK是舊版功能。 來源讀取器和接收寫入器已取代它。 來源讀取器和接收寫入器已針對Windows 10和Windows 11進行優化。 Microsoft 強烈建議新程式碼盡可能使用來源讀取器和接收寫入器,而不是Windows Media Format 11 SDK。 Microsoft 建議盡可能重寫使用舊版 API 的現有程式碼,以使用新的 API。]

您可以使用 Windows 媒體格式 SDK 來建立 ASF 檔案,其中包含以您選擇的任何編解碼器編碼的數位媒體。 使用此 SDK 隨附的編解碼器以外的編解碼器時,您必須執行下列步驟。

  1. 使用所需的編解碼器來編碼內容。
  2. 尋找或建立 GUID 值,以識別使用步驟 1 中使用的編解碼器編碼的內容。
  3. 建立新的設定檔,或修改現有的設定檔以與編碼內容搭配使用。
    • 為具有適當主要類型的編碼內容建立資料流程。 如需主要媒體類型的詳細資訊,請參閱 媒體類型。 使用步驟 2 中所識別的 GUID 做為媒體子類型。
    • 將資料流程的位元速率和緩衝區視窗設定為不會產生緩衝區溢位的值。 您應該能夠在編碼時從編解碼器取得這些值。 SDK 執行時間元件會檢查位元速率/緩衝區視窗值,並視需要卸載範例,讓指定的資料符合這些值。 如果您設定的值不正確,檔案將不會正確串流,導致播放不佳。
    • 針對視訊串流,您必須將WMVIDEOINFOHEADER結構中包含的BITMAPINFOHEADER結構的biCompression成員設定為內容的適當 FOURCC 值。 這個值必須等於子類型 GUID 的前四個位元組。 例如,如果 biCompression 是 MAKEFOURCC ('T','E','S','T') =0x54455354,則子類型 GUID 會如下所示:54455354-XXXX-XXXX-XXXX-XXXXXXXXXXXX。
  4. 建立寫入器物件,並載入在上一個步驟中建立的設定檔。 如需寫入檔案的詳細資訊,請參閱 撰寫 ASF 檔案
  5. 迴圈查看檔案的輸入,並像平常一樣為每個輸入屬性指派輸入屬性。 如需輸入的詳細資訊,請參閱 使用輸入。 針對使用協力廠商編解碼器編碼的資料流程,請先將 IWMInputMediaProps 介面指標設定為 Null ,再呼叫 IWMWriter::BeginWriting
  6. 使用在上一個步驟中建立的新設定檔來寫入檔案。 使用 IWMWriterAdvanced::WriteStreamSample 而非 IWMWriter::WriteSample傳遞壓縮的樣本。 針對影片,您必須將WM_SF_CLEANPOINT傳遞為 dwFlags 參數,以指定哪些範例是主要畫面格。

若要處理並解壓縮以協力廠商編解碼器編碼的資料流程,您必須讀取壓縮的資料流程範例。 讀取應用程式也必須處理資料流程的範例解壓縮。

將 MPEG-2 資料流程放入 ASF

注意

本主題適用于使用 Windows Media Format SDK 將 MPEG-2 (或其他使用 B 框架的壓縮格式) 到 ASF 檔案容器的應用程式。

 

寫入器物件要求所有輸入樣本都有時間戳記,並假設每個輸入樣本的呈現時間晚于前面。 雖然幾乎所有未壓縮的視訊,甚至部分壓縮的視訊串流都符合這些條件,但 MPEG-2 資料流程不會。 在 MPEG-2 中,並非所有樣本都會時間戳記,而且當 B 畫面格存在時,範例解碼順序與轉譯順序不同。 當寫入器物件遇到順序錯亂的樣本時,會將它們重新排列成「正確」的順序。 因此,若要在 ASF 容器中以原生方式儲存 MPEG-2 資料流程 (未解碼) ,您必須執行下列步驟:

寫入檔案時:

  1. 將固定大小資料單位延伸模組 (DUE) 新增至每個輸入範例,以保存包含範例實際 MPEG 時間戳記開始時間和停止時間值的 結構。 如果範例沒有時間戳記,請使用 -1 表示這些值。
  2. 提供寫入器物件「虛擬」輸入時間戳記,這些時間戳記一律會增加,如此一來,它就會以與收到的範例完全相同的順序將範例寫入檔案。 虛擬時間戳記應該大約對應到實際呈現時間,如一段時間的平均值。 虛擬時間戳記會形成搜尋時程表,因此,如果它們與即時戳記相關,則檔案上的搜尋作業會產生非預期的結果。 不過,樣本時間之間的抖動量有限,不會影響搜尋作業。

讀取檔案時:

  • 針對從檔案讀取的每個範例,檢查 DUE。 如果它包含大於或等於零的開始時間,請在將該值傳遞至解碼器之前,將該值複製到輸出範例的時間戳記。 將輸出範例上的所有其他時間戳記設定為 Null。 在 DirectShow 中,這是藉由呼叫 IMediaSample::SetTime (NullNull) 來完成。

緩衝內容

IWMWriter 介面

IWMWriterAdvanced 介面

使用非同步讀取器傳遞壓縮的範例

使用同步讀取器擷取資料流程範例

WMVIDEOINFOHEADER

使用設定檔

寫入 ASF 檔案