2012-03-19 10 views
2

私は、ビデオキャプチャデバイスと見なすことができるように、CLSID_VideoInputDeviceCategoryとして登録されているDirectShowソースフィルタを作成しています(たとえば、Skypeから別のWebCam)。 私のソースフィルタはhereのVCamの例に基づいていますが、今のところFillBuffer()メソッドで実装されているこのサンプル(正確には1つのビデオ出力ピンがあり、オーディオはありません)唯一の出力ピンです。DirectShow - ソースフィルタからファイルを読み取る方法

実際のシナリオは少し難解です - フィルタはCreateFile()API呼び出しを使用して開かれたハードウェアデバイスへのファイルハンドルを使用します(デバイスを開くことは自分のコントロールではなく、3Partyとしょうかん)。次に、このハンドルからデータのチャンクを読み取る必要があります(通常、256〜512バイトのチャンクサイズ)。 デバイスはWinUSBデバイスであり、3Partyフレームワークはちょうどチャンクを読み取るために開かれたファイルハンドルを "与え"ます。 フィルタによって読み取られるデータは、デバイスから「ハンドル」にストリーミングされる* .mp4ファイルです。

このシナリオは、ディスク上の* .mp4ファイル( "チャンク")から読み込み、そのデータをDirectShowグラフにプッシュするが、最初から最後までファイルを完全に読み取ることができないソースフィルタと同等です、ファイルサイズは不明です(正しい?)。

私はDirectShowには新しく、基本的な概念がいくつか欠落しているように感じます。誰でも私に次の質問のためにソリューション\リソース\説明を指示できればうれしいでしょう:

1)Web上のさまざまなソースとMicrosoft SDK(v7.1)のサンプルから、正しい&の有効なDirectShowグラフを作成して(ビデオが&オーディオを正常にレンダリングするように)、ソースフィルタピン(CSourceStreamから継承)はメソッド "GetMediaType"を実装する必要があります。この実装された関数の戻り値に応じて、アプリケーションは正しいグラフを作成してデータをレンダリングし、正しい順序でフィルタを構築することができます。これが正しければ - グラフを* .mp4入力をチャンクでレンダリングするようにグラフが構築されるように私はどのように実装しますか(一定のチャンクサイズを想定することができます)

2)私は、FillBuffer()メソッドがSetTime()を呼び出すIMediaSampleオブジェクト(取得して埋めている)に気付いています。私はデバイスから生の* .mp4データを読み込んでいます。私はデータを解析し、ストリームからフレーム&の時間値を抽出する必要がありますか?はいの場合 - 例は素晴らしいでしょう。

3)ファイルハンドル(「チャンク」)から受け取ったデータをVideo & Audioに分割する必要がありますか、ソースフィルタでデータを操作する必要がなくグラフにプッシュすることはできますか?分割が必要な場合 - どのようにして(データは連続ではなく、チャンクに分割されますか)、これが "GetMediaType"の望ましい実装に影響しますか?

誤った用語を使用している場合は、私を修正してください。

ありがとう:-)

答えて

3

これは良い質問です。一方でこれは実行可能ですが、いくつかの特定の関与があります。

まず、CLSID_VideoInputDeviceCategoryに登録されているフィルタは、ライブビデオソースとして動作することが期待されています。 (Skypeなどの)アプリケーションがビデオ解像度を設定しようとしているときに、ビデオがリアルタイムレートで動くことを期待していて、一部のアプリケーション(Skypeなど)が圧縮を期待していないそのようなH.264のようなビデオは、そのようなデバイスを拒否するだけです。アプリケーションはオーディオを探すことさえできないので、このフィルタにオーディオを添付することはできません(オーディオにフィルタがあるかどうかは分かりませんが、オーディオが存在するように.MP4ファイルが記載されています)。ご質問には

1 - あなたは、インタフェースのメソッドアプリケーションが、フィルターに呼んでチェックすることにより、アプリケーション要件のより良い絵を持っているでしょう。メソッドのほとんどはBaseClassesによって実装され、GetMediaTypeなどの内部メソッドに呼び出しを変換します。はい、それを実装する必要があります、そうすることで、あなたがサポートする特定のメディアタイプを試して、フィルタをダウンストリームのフィルタピンに接続できるようにします。

また、他のDirectShowグラフでもこのようなアプローチが有効であっても、それらは私のMP4チャンクではありません。ビデオキャプチャデバイスを実装するには、ビデオフレームを正確に配信する必要があります。圧縮解除することもできます(圧縮も可能ですが、アプリケーションとの互換性がすぐに得られます)。

あなたが考えているかもしれない解決策は、MP4チャンクを注入した内部的なグラフを内部に埋め込み、パイプラインがそれらを解析し、デコードしてカスタムレンダラに渡します。仮想デバイスをオフにします。これは良いデザインかもしれませんが、内部的にフィルターがどのように機能するかをある程度理解していることを前提としています。

2 - お使いのデバイスは、通常、ライブソースとして扱われる/期待されます。つまり、リアルタイムでビデオを配信し、必ずしもタイムスタンプされているわけではありません。だから、そこに時間を置くことができます。もちろん、元のメディアからタイムスタンプを抽出する必要があります(または、上記の1で説明した内部グラフで行います)。しかし、アプリケーションはタイムスタンプを特にプレビュー目的で削除します。ソースは「ライブ」です。

3 - オーディオに戻っても、同じ仮想デバイスにオーディオを実装することはできません。もちろん可能ですが、このフィルターはカスタムの作成グラフでも機能しているかもしれませんが、これはアプリケーションでは機能しません。彼らは別のオーディオデバイスを探していて、もしあなたがそれを実装するならば、別々のオーディオデバイスをインスタンス化します。したがって、仮想ビデオと仮想オーディオソースの両方を実装し、内部で内部同期を実装することが期待されます。これはタイムスタンプが重要な場所です。ストリーミング元のメディアファイルに元のセッションにリップシンクを正しく保存することで、ライブセッションでリップシンクを維持します。

関連する問題