0

DSPACK コンポーネント ライブラリを利用して、Delphi 6 で記述された DirectShow プッシュ ソース フィルタと DirectShow シンプル オーディオ ミキサー フィルタがあります。私のアプリでは、フィルタ グラフを手動で作成し、ピン接続には IFilterGraph.ConnectDirect() を使用して、DirectShow の「インテリジェント接続」テクノロジからの干渉を回避しています。これらのフィルターの両方を、プログラム内のプライベート/未登録フィルターとして使用しています。

作成したグラフには、グラフの先頭位置を共有するキャプチャ フィルターとプッシュ ソース オーディオ フィルターがあります。それらの出力ピンは私の単純なオーディオ ミキサーに接続されており、後者は複数の入力接続をサポートしています。ミキサーは、入力ピンと出力ピンへのすべての接続を、そのコンストラクターで事前に設定されているものとまったく同じメディア形式タイプに強制します。この場合、私が使用しているフォーマット設定は、サンプル レート 8000、サンプルあたり 16 ビット、および 1 チャネルの WAV フォーマットです。DecideBufferSize() を使用して、すべてのフィルターを 50 ミリ秒のバッファー サイズに設定していることに注意してください。これにより、400 バイト (200 サンプル) の大きさのバッファーが配信されます。

キャプチャ フィルターは、DirectShow API を使用して見つけた外部 COM オブジェクトです。現在、VOIP 電話をデバイス (モニカー) として割り当てています。奇妙な理由で、私のプッシュ ソース フィルタは、キャプチャ フィルタのちょうど 7 倍の速度でバッファを送り出しています。つまり、ミキサー フィルタは、キャプチャ フィルタから受け取るバッファごとに、プッシュ ソース フィルタから 7 つのバッファを取得しています。これは、ミキサー フィルターがバッファーを取得するたびに行をデバッグして出力し、バッファーのソースであるフィルターを特定するためです。

外部コードであるため、キャプチャ フィルターがどのようにタイムスタンプを形成しているかはわかりませんが、通常のスキームだと思います。私のプッシュ ソース フィルターはゼロから始まり、FillBuffer() 呼び出しごとに、DirectShow 参照時間形式のタイムスタンプをバッファーが表す時間だけインクリメントします。

ここに私の質問があります:

1)グラフを手動で作成している場合でも、タイムスタンプは重要ですか? グラフを完全に手動で作成したとしても、DirectShow はフィルターの中間に入り、何らかの方法でピン書き込み (受信呼び出し) のタイミングに影響を与える可能性がありますか?

2) グラフ全体で均一なメディア形式が使用されているにもかかわらず、フィルタがバッファをあまりにも速く押し出す原因となるよくある間違いは何ですか?

4

1 に答える 1

3

DirectShow のソース/プッシュ フィルターは通常、ライブまたは非ライブのいずれかです。どちらもデータをパイプラインに挿入しますが、重要な違いは、ライブ フィルターがデータを生成するとすぐにストリーミングし、パイプラインの外部 (ネットワークなど) などから受信することです。

非ライブ フィルターは、できるだけ多くのデータをプッシュします。5 分間の MP3 ファイルを再生するフィラー? 一度に5分間すべて注入する準備ができています。使用可能なバッファーがなくなったときにストリーミングをブロックし、プレゼンテーション時間を尊重するのは、レンダラー フィルターのタスクです。そのため、ソース フィルターがバッファーを 100% ロードすると、再生によってバッファーが解放されるまで、何もプッシュできなくなります。

この動作の重要な部分は、メディア サンプルのタイムスタンプを正しく設定することです。タイム スタンプに失敗すると、レンダラーは時間どおりにデータを表示できず、メディアの表示/再生が遅すぎたり速すぎたりする可能性があります。

于 2011-11-19T07:30:43.207 に答える