漏れバケット バッファー モデル (Microsoft Media Foundation)
ネットワーク経由でメディアをストリーミングすると、デコーダーは理論上一定のレート (送信レート) でエンコードされたデータを受信します。 デコーダーはこのデータを使用してデコードされた出力を生成します。 ただし、一般的なケースでは、デコーダーは可変レートでデータを消費します。これは、エンコーダーが 可変 エンコード レートを使用できるためです。
「漏れバケット」モデルは、スムーズな再生のためのバッファリング要件をモデル化する方法です。 このモデルでは、デコーダーはバッファーを保持します。 エンコードされたデータは、ネットワークからバッファーに、バッファーからデコーダーに送信されます。 バッファーのアンダーフローの場合は、デコーダーがバッファーからデータを削除する速度が、ネットワークによって配信されるよりも高速であることを意味します。 バッファーがオーバーフローした場合、ネットワークはデコーダーがデータを消費するよりも高速にデータを配信することを意味します。
このトピックでは、エンコードとデコードのためのバッファーの "漏れバケット" モデルについて説明します。
漏れバケット
漏れバケット モデルを理解するには、下部に小さな穴があるバケットを検討してください。 バケットを定義するパラメーターは 3 つあります。
- 容量 (B)
- バケットから水が流出する速度 (R)
- バケットの初期完全性 (F)
この比喩では、バケットはバッファーです。
正確なレート R でバケットに水が注がれた場合、入力レートは出力レートと等しいため、バケットは F のままです。 Rが一定のまま入力速度が上昇すると、バケットは水を蓄積します。 持続的な期間、入力レートが R より大きい場合は、最終的にバケットがオーバーフローします。 ただし、平均入力レートがバケットの容量を超えない限り、入力レートはバケットをオーバーフローすることなく R の周りで変化する可能性があります。 容量が大きいほど、特定の期間内に入力レートが変化する可能性があります。
ASF では、漏洩バケットは次の 3 つのパラメーターによって定義されます。
- 出力レート (R) に対応する平均ビット レート (1 秒あたりのバイト数)
- バケット容量 (B) に対応するバッファー ウィンドウ (ミリ秒単位)。
- 初期バッファーの完全性。通常は 0 に設定されます。
ビット レートは、エンコードされたストリーム内の 1 秒あたりの平均ビット数を測定します。 バッファー ウィンドウは、バッファーに収まるビット レートでのデータのミリ秒数を測定します。 ビット単位のバッファーのサイズは、R * (B/ 1000) と等しくなります。
ASF ペイロード データは、不規則な時間と不規則な量で漏洩バケットに入る可能性がありますが、バケットは一定の正のビット レートのままにしておく必要があります。 バッファー ウィンドウのため、ペイロードがバケットに入る時間とバケットが離れるまでの間に遅延が発生する可能性があります。 発生する可能性がある最大遅延は B/R です。 バケットに入力するペイロード データはプレゼンテーション時間に従い、バケットをオーバーフローさせてはなりません。 表示時間に加えて、各ペイロードには送信時間もあります。ペイロード データがビット レートに従ってバケットから出る時刻です。 漏洩したバケットがいっぱいになると、すべてのペイロードがプレゼンテーションの前またはプレゼンテーション時にバケットを離れるようにするには、送信時間がプレゼンテーション時間よりも早い必要があります。 これを実現するために、プレゼンテーション時間は B/R 値 ( プリロール) の前にシフトされ、送信時間は 0 から始まるヘッドを取得します。 送信時刻は、ペイロードがバケットに入力しすぎてデータ オブジェクトに含めることができないことを示すので、プレゼンテーション時間より後に設定する必要があります。 プリロール値は、 ASF ヘッダー オブジェクト に含まれます。
ネットワーク経由のグリッチフリー ストリーミングの場合、メディア コンテンツ内の圧縮ストリームは、再生期間中、一定のビット レートを維持する必要があります。 ASF リーク バケット モデルを使用すると、メディア データが一定のビット レートでネットワーク経由で送信されます。 リーク バケットのパラメーターは、 ASF ヘッダー オブジェクトの拡張ストリーム プロパティ オブジェクトで指定されます。 Microsoft Media Foundation では、ストリームを表すメディアの種類の属性として設定されます。
リーク バケット値は、ASF ファイル シンクと基になる ASF マルチプレクサー オブジェクトと Windows Media エンコーダーの両方で定義されます。 これらの値は、同じでも異なってもかまいません。 たとえば、オーディオ サンプルをビデオ サンプルより後で配信して、待機時間なしでファイルをストリーミングできるようにするストリーミング シナリオを考えてみましょう。 これを実現するために、メディア シンク内のオーディオ ストリームの漏れバケットを、Windows Media オーディオ エンコーダーで設定された値より大きい値に設定できます。
エンコーダーで B/R 値を設定するには、アプリケーションで MFPKEY_RAVG、 MFPKEY_BAVG、 MFPKEY_RMAX、MFPKEY_BMAXの各プロパティ を設定する 必要があります。 エンコーダーのプロパティの設定の詳細については、「 エンコード プロパティ」を参照してください。
使用中のバケット
エンコーダーの目的は、コンテンツがバッファーをオーバーフローしないようにすることです。 エンコーダーは、ビット レートとバッファー ウィンドウの値をガイドとして使用します。 バッファー ウィンドウと等しい任意の期間にわたって渡される実際のビット数は、バッファーのサイズの 2 倍を超えることはありません。
次の例を考えてみましょう。3 ガロンのバケットに穴が開き、1 ガロンが 1 分あたりに流れる可能性があります。 あなたは、スピゴットの下にバケットを置き、毎分1ガロンの速度で水を出すためにバルブを開けます。 水は入るとすぐにバケットから流れ出し、バケットに余分な水は残しません。 次に、流れをスピゴットから 1 分あたり 2 ガロンに増やします。 この速度で水が流れる毎分、2ガロンがバケットに入り、1ガロンが漏れ出し、バケットに1ガロンが残ります。 3分の終わりに、6ガロンの水がバケットに入り、3ガロンが漏れ出し、バケットがいっぱいになりました。
実際には、バッファー ウィンドウと等しい間隔での理論上の最大データ レートは実現されません。 前の例では、一定のデータ レートが想定されています。 同じ3ガロンのバケットを考えると、1分間、スピゴットから1分あたり6ガロンに流量を増加させ、その後2分間スピゴットをオフにすることができます。 バケットに入れる水の総量がバッファー ウィンドウの理論上の最大値内にある場合でも、その量がウィンドウの 1 つの部分に集中すると、バケットがオーバーフローします。 1分あたり6ガロンで、30秒のパスの直後に3ガロンのバケットがオーバーフローします。 したがって、バッファー ウィンドウの設定と等しい間隔でバッファーに配信できるデータの実際の最大量は、個々のサンプルのサイズと、それらが配信されるタイミングによって異なります。
ここまでの例ではデコーダーによって使用されるバッファーについてのみ説明してきましたが、圧縮されたコンテンツを作成するエンコーダーでもリークバケットバッファーが使用されています。 エンコーダーは、圧縮されたサンプルのビット レートをビット レートとバッファー ウィンドウで記述された境界内に保持するために、圧縮アルゴリズムに必要な調整を行います。これは、サンプルが一定のレートでデコーダーに配信されることを前提とします。 エンコーダー バケットは、デコーダー バケットをミラーリングしていると考えることができます。 エンコーダーバケットは、個々のサンプルのサイズによって決定される可変レートで充填され、平均ビットレートと等しい一定のレートでリークします。
ネットワーク経由で接続されているエンコーダーとデコーダーの次の例を考えてみましょう。 1 秒あたり 6,000 ビットのビット レートと 3 秒のバッファー ウィンドウ (合計バッファー サイズ 18,000 ビット) で、30 フレーム/秒でビデオ ファイルをエンコードします。 最初のサンプルはキー フレームとしてエンコードされ、7,000 ビットを占めます。 エンコーダー バッファーに 7,000 ビットが含まれるようになりました。 次の 29 フレームはすべて、合計 3,000 ビットの差分フレームです。 そのため、コンテンツの最初の 2 番目 (30 フレーム) では、何もリークしていない場合は、バッファーの完全性が 10,000 ビットに設定されます。ストリームのビット レートが 6,000 ビット/秒であることがわかっているため、エンコードされたコンテンツの最初の 1 秒がエンコーダー バッファーに格納された後、完全性は 4,000 ビットに低下します。 デコード アプリケーションでは、このストリームは 6,000 ビット/秒でデコーダー バッファーに配信されます。 1 秒後、バッファーには 6,000 ビットが含まれます。 最初のサンプルには 7,000 ビットが含まれているため、デコーダーがサンプルの削除を開始する前に、デコーダー バッファーをさらに入力する必要があります。
ASF ストリームの漏洩バケット値の設定
ファイル エンコード シナリオでは、アプリケーションは ASF プロファイルでストリームを構成するときに、リークバケット値を設定できます。
ストリームを作成し、ストリームの IMFASFStreamConfig インターフェイスへの参照を取得したら、次の属性を使用して値を設定できます。
- MF_ASFSTREAMCONFIG_LEAKYBUCKET1 (平均漏れバケット値)
- MF_ASFSTREAMCONFIG_LEAKYBUCKET2 (最大漏れバケット値)
ストリームの追加と IMFASFStreamConfig ポインターの取得については、「 ASF ファイル シンクへのストリーム情報の追加」を参照してください。
これらの値には、次の情報セットが含まれています。
- 平均ビットレート: メディアタイプネゴシエーション中に選択された出力メディアタイプから平均ビットレートを取得します。 MF_MT_AUDIO_AVG_BYTES_PER_SECOND属性 (オーディオ ストリームの場合) または MF_MT_AVG_BITRATE 属性 (ビデオ ストリームの場合) を使用します。
- バッファー ウィンドウ: エンコーダーのインスタンスがあり、出力メディアの種類がネゴシエートされている場合は、後でエンコーダーに IWMCodecLeakyBucket インターフェイスのクエリを実行し、IWMCodecLeakyBucket::GetBufferSizeBits (wmcodecifaces.h、 wmcodecdspuuid.lib) を呼び出すことで、この値を更新できます。 それ以外の場合は、既定値の 3000 ミリ秒を使用します。
- 初期バッファー サイズ: 0 に設定します。
アプリケーションによって提供される値は、エンコードの種類とストリームのメディアの種類によって異なります。 たとえば、 定数ビット レート エンコード には、事前に定義された固定ビット レートとバッファー ウィンドウが必要です。 アプリケーションでは、ストリームに MFPKEY_VIDEOWINDOW エンコード プロパティと MF_ASFSTREAMCONFIG_LEAKYBUCKET1 属性を設定することで、これらのリークバケット値を指定できます。 指定されたバッファー ウィンドウの値を使用して、エンコードされたファイルがデータ パケットで正しい送信時間をマークし、プリロール値が ASF ヘッダー オブジェクトに表示されるようにします。 これらの指定した値は MF_ASFSTREAMCONFIG_LEAKYBUCKET2 属性にコピーされるため、 MF_ASFSTREAMCONFIG_LEAKYBUCKET1 を設定するだけで十分です。
2 パス エンコード モードの場合は、これらの両方の属性を設定して、平均値と最大値を指定する必要があります。
VBR エンコードの場合、アプリケーションはエンコード パスが完了した後にのみ、エンコーダーによって使用されるリークバケット値を照会できます。 そのため、メディア シンクの構成中に、アプリケーションはリークバケットに関連する属性またはプロパティを設定しないことを選択できます。 エンコード後、アプリケーションはエンコーダーに対してMFPKEY_RAVG、MFPKEY_BAVG、MFPKEY_RMAX、およびMFPKEY_BMAXの各プロパティを照会し、正確な値がヘッダー オブジェクトに反映されるようにメディア シンクに設定する必要があります。 VBR エンコードの値を更新する方法のコード例については、「 チュートリアル: 1-Pass Windows Media Encoding」の「ファイル シンクのエンコード プロパティを更新する」を参照してください。
エンコードせずに Windows Media コンテンツをソースからメディア シンクにコピーする場合は、メディア シンクでリークバケットの値を設定する必要があります。
ASF マルチプレクサーのリークバケット値
Media Foundation では、 ASF マルチプレクサー によって漏洩バケット値が使用され、データ パケットの生成に使用される内部リークバケット値が設定されます。 ペイロードはメディア サンプル内に含まれており、一連のメディア サンプルは ASF データ パケットを構成します。 漏れバケット値とプレゼンテーション時間に基づいて、マルチプレクサーはメディア サンプルごとに送信時間を割り当てて、ネットワーク経由で送信されるパケットのビット レートが一定のビット レート (R) になるようにします。
アプリケーションは、マルチプレクサーでリークバケット値を直接設定することはできません。 値は、マルチプレクサーの適切な値を設定する ASF メディア シンクで指定する必要があります。 MF_ASFSTREAMCONFIG_LEAKYBUCKET1およびMF_ASFSTREAMCONFIG_LEAKYBUCKET2で設定された値は、マルチプレクサによって使用され、ASF メディア シンクに送信されるサンプルが指定された値を使用して生成されていることを検証します。
ASF メディア シンクのリークバケット値の更新
アプリケーションは、メディア シンクのプロパティ ストアで MFPKEY_ASFSTREAMSINK_CORRECTED_LEAKYBUCKET プロパティを設定することで、ストリーム レベルのリークバケット値 (ストリームの作成時に ASF プロファイルで設定) を上書きできます。 プロパティ ストアへの参照を取得するには、メディア シンクによって実装される ContentInfo オブジェクトを使用します。 詳細については、「 ファイル シンクでのプロパティの設定」を参照してください。
メモ この操作は、オーディオ ストリームに対してのみ許可されます。
このプロパティは、エンコーダーで出力の種類を設定した後に設定する必要があります。 エンコーダーは、メディアの種類で設定されたビット レートに基づいてバッファー サイズを計算し、生成されたメディア サンプルがバッファーをオーバーフローしないようにします。 エンコーダーは、圧縮中に必要な調整を行い、圧縮されたサンプルのビット レートをビット レートとバッファー ウィンドウで記述された境界内に保持します。
リーキー バケットのストリーム構成属性と同様に、DWORD の配列で平均ビット レートとバッファー サイズ、および初期バッファーの完全性を設定します。 詳細については、このトピックの「ASF ストリームのリークバケット値の設定」セクションを参照してください。
関連トピック