共用方式為


在數據流中定位

[與此頁面相關聯的功能,AVIFile 函式和巨集,是舊版功能。 來源讀取器已取代它。 來源讀取器 已針對 Windows 10 和 Windows 11 優化。 Microsoft 強烈建議新的代碼盡可能使用 Source Reader,而不是 AVIFile 函式和巨集。 Microsoft建議使用舊版 API 的現有程式代碼,盡可能改寫成使用新的 API。]

AVIFile 提供數種方式來尋找並移至數據流中的位置。 本節中的函式和巨集可讓您的應用程式在數據流中尋找起始位置、長度和主要畫面格(包含範例中的完整影像)。 函式和巨集也會藉由計算從數據流開頭到數據流中任何點播放數據流所需的經過時間,將時間與數據流中的位置產生關聯。

尋找起始位置

您可以使用 AVIStreamStart 函式,擷取影片串流中第一個畫面的範例編號。 (根據作者的喜好,電影的畫面可能從範例 0 或 1 開始。您也可以使用 AVIStreamInfo 函式來取得此資訊。 此函式會將範例編號儲存在 AVISTREAMINFO 結構的 dwStart 成員中。 您可以使用 AVIStreamStartTime 巨集,取得串流第一個範例的開始時間。

您可以使用 AVIStreamLength 函式來擷取數據流長度。 此函式會傳回數據流中的樣本數目。 您也可以使用 AVIStreamInfo 函式來取得此資訊。 此函式會將數據流長度儲存在 AVISTREAMINFO 結構的 dwLength 成員中。 若要以毫秒為單位擷取數據流的長度,請使用 AVIStreamLengthTime 巨集。

在視訊串流中,每個範例通常會對應至視訊畫面。 不過,可能有沒有影片數據的範例。 如果您呼叫指定其中一個位置的 AVIStreamRead 函式,則會傳回 0 個字節的數據長度。 您可以使用 AVIStreamFindSample 函式並指定FIND_ANY旗標,來尋找包含數據的範例。

在音訊數據流中,每個範例都會對應至一個音訊數據的數據區塊。 例如,如果音訊數據的格式為 22 kHz 自適應差分脈衝編碼調變 (ADPCM),則 AVIStreamLength 的每個取樣 將對應到一個包含 256 位元組壓縮音訊數據的區塊。 此音訊數據區塊會在未壓縮時包含大約500個音訊樣本。 不過,AVIFile 的函式和巨集會將每個 256 位元組區塊視為單一範例。

注意

串流中的有效位置範圍從開頭到末尾,即從串流起始點加上其長度所得的結果。 起始位置與長度的總和所指的位置對應於最後一個數據渲染後的時間,但該位置不包含任何數據。 您可以使用 AVIStreamEnd 巨集來擷取代表數據流結尾的樣本編號。 您可以使用 AVIStreamEndTime 巨集,以毫秒為單位擷取代表數據流結尾的時間值。

 

尋找範例和關鍵幀

您可以使用 AVIStreamFindSample 函式,在數據流中搜尋不同類型的範例。 此函式會向後或向前搜尋數據流中是否有適當類型的樣本,從您指定的樣本編號開始。 您可以在 AVIStreamFindSample 呼叫序列中指定旗標,以搜尋數據流中的不同類型的範例。 指定FIND_ANY旗標來找出無空樣本,或略過缺少數據的樣本。 指定FIND_KEY旗標來搜尋包含數據的主要畫面格,以轉譯完整的影像,而不需要參考先前的畫面格。 指定要搜尋格式變更的FIND_FORMAT旗標。 AVIStreamFindSample 主要用於視訊串流。

使用 AVIFile 函式的數個巨集增強了串流搜索功能。 下列清單提供每個巨集的簡要描述。 搜尋特定位置或數據類型的巨集需要在數據流中指定起始位置。

巨集 描述
AVIStreamIsKeyFrame 指出指定數據流中的範例是否為關鍵幀。
AVIStreamNearestKeyFrame 定位數據流中指定位置或之前的關鍵畫面。
AVIStreamNearestKeyFrameTime 決定對應到數據流中指定時間所在或之前的最近關鍵影格開始的時間。
AVIStreamNearestSample 在數據流中尋找指定位置或其前方最近的非空樣本。
AVIStreamNearestSampleTime 決定數據流中最接近指定時間的樣本開頭對應的時間。
AVIStreamNextKeyFrame 找出數據流中指定位置之後的下一個主要畫面格。
AVIStreamNextKeyFrameTime 傳回從指定時間開始的數據流中下一個關鍵幀的時間。
AVIStreamNextSample 從數據流中指定的位置找出下一個無空樣本。
AVIStreamNextSampleTime 傳回樣本在數據流中切換至下一個樣本的時間點。
AVIStreamPrevKeyFrame 在數據流中找出位於指定位置之前的關鍵幀。
AVIStreamPrevKeyFrameTime 從給定時間開始,傳回數據流中上一個關鍵畫面的時間。
AVIStreamPrevSample 找出在數據流中指定位置前面的無空範例。
AVIStreamPrevSampleTime 決定上一個樣本取代其前一個樣本在數據流中的時間。
AVIStreamSampleToSample 傳回數據流中與第二個數據流中同時發生的樣本。

 

在範例與時間之間切換

您可以使用 AVIStreamSampleToTime 函式,判斷數據流開頭到範例的經過時間。 此函式會將樣本數轉換成以毫秒表示的時間值。 對於視訊畫面(跨越數毫秒),這個值代表範例開始播放的時間,因為播放開始,並假設視訊剪輯以正常速度播放。 針對音訊範例(以毫秒為單位有數個樣本),時間值會對應到樣本開始播放的時間,並假設音訊數據流以正常速度播放。

相反地,您可以使用 AVIStreamTimeToSample 函式,找到與時間值相關聯的範例編號。 此函式會將毫秒值轉換成樣本數位,並假設視訊剪輯以正常速度播放。

由於 AVIStreamSampleToTime 會傳回畫面開始播放的時間,因此 AVIStreamSampleToTimeAVIStreamTimeToSample 之間的關聯性不完全是逆向的關係。 它們會比判斷時間更明確地判斷檔案中的位置。 例如,兩個連續的音訊範例可能會在相同的毫秒內播放。 使用 AVIStreamSampleToTime 來轉換樣本數位會導致相同的時間值。 如果您使用 AVIStreamTimeToSample,將時間值轉換為樣本數,則會參考單一範例。