DirectShowについて

DirectShowについて調べたことのメモです。 間違いもあるかもしれません‥、掲示板またはメールにてお知らせ下されば幸いです。

HOMEへ MPCについてのメモ

INDEX


DirectShow概観

DirectShowとは?APIとは?

世の中には様々なソフトウェアがあるが、各ソフトウェアがすべて固有の機能ばかりで作られているわけではない。 誰かが書いたものを再利用できれば済むところを、めいめいが一から作っていくというのでは非能率的だ。

そこで、共通な機能はあらかじめプログラミングしておいて、各ソフトウェアが必要に応じて該当機能を呼び出すようにする仕組みが必要になる。 そうした仕組みの為に作られたプログラムの集合体、又はその集合体の利用規約を、API(Application Programing Interface)と呼ぶ。 APIによって、各ソフトウェア作者は、固有機能のプログラミングに主力を注げるようになる。

DirectXは、マルチメディア機能を支援するAPI群の総称で、DirectShowはそのコンポーネントの一つ。 DirectShow APIは動画や音楽などのマルチメディアコンテンツの再生・変換・キャプチャを行うソフトウェアを支援する。

動画プレイヤーの多くは、このDirectShow APIを利用して作成されている。

参考資料
2004-10-08

DirectShowによる動画再生処理の流れ

ごく大雑把な流れはこうだ。

DirectShowによる動画再生処理の流れ図

順を追って説明する。

  1. 動画プレイヤーがDirectShow API を呼び出す。
  2. フィルタグラフマネージャが、フィルタグラフを作成する。

    フィルタグラフマネージャは、DirectShowのプログラムのひとつ。 フィルタグラフマネージャによって、動画データに合うように、各フィルタが順序良く組み合わせられる。 こうして出来上がったフィルタの組み合わせをフィルタグラフと呼ぶ。

    動画再生時のフィルタグラフ内のフィルタは、その働きに応じて4種に大別できる。 データの流れる順序で記していくと、以下のようになる。

    1. ソースフィルタ

      データをグラフ内に取り込むフィルタ。 HD内のローカルファイルの読み込みに使われるFile Source(Async.)など。

    2. スプリッタフィルタ

      入力されたデータを複数の出力に分解する。 AVIの映像データと音声データを分離するAvi Splitterなど。

      また、再生時には普通使われないが、スプリッタフィルタと対をなして、MUXフィルタというものもある。 MUXフィルタは、動画作成時に使用され、複数の入力を一つの出力に合成する。

    3. 変換フィルタ

      デコーダがこれにあたる。 動画作成時に使われるエンコーダもこのカテゴリに入る。

    4. レンダリングフィルタ

      処理の終わったデータを出力デバイスへと送り出すフィルタ。 その際、可能な限りDirectSoundやDirectDrawを使用するよう動作する。 Video Renderer, Default DirectSound Device など。Overlay MixerやVMR7, 9もここに属する。

  3. フィルタグラフに基づいて、逐次、データが処理され、デバイスへと渡される。

    フィルタグラフによる処理の完了したデータは、DirectSound(音声)、DirectDraw(映像)を通して、 サウンドカード、ビデオカードへと、それぞれ渡されて行く。

付記

公式の図も見ておいて下さい。 これです。

参考資料
2004-10-09

ピンとメディアタイプ

DirectShowフィルタは同士の接続は、「ピン」を介して行われる。 ピンには入力ピンと出力ピンがあり、それぞれのピンには扱うことの出来る「メディアタイプ」が設定されている。

メディアタイプはAM_MEDIA_TYPE構造体で定義されている。 その構成メンバは、以下のとおり。 (参考資料の丸写しですが‥。)

  • majortype

    データのカテゴリ全体を定義するGUID

  • subtype

    フォーマットをさらに細かく定義する別のGUID。この値が MEDIASUBTYPE_None の場合がある。これは、フォーマットにはサブタイプが必要ないことを意味している。

  • bFixedSizeSamples

    TRUE の場合、サンプルのサイズは固定である。

  • bTemporalCompression

    TRUE の場合、サンプルは時系列 (フレーム間) 圧縮方式で圧縮されている。値 TRUE はフレームがすべてキー フレームとは限らないことを示す。

  • lSampleSize

    サンプルのサイズ (バイト単位)。圧縮データの場合は、0 も可能。

  • formattype

    フォーマット ブロックに使う構造体を指定するGUID

  • *pUnk

    未使用。

  • cbFormat

    フォーマット ブロックのサイズ (バイト単位)。

  • *pbFormat

    フォーマット ブロックへのポインタ

フォーマット ブロックとは、フォーマットをより詳細に記述するデータのブロック。 AM_MEDIA_TYPE構造体とは別の場所に作られるが、ポインタである pbFormat メンバによって、そこへのアクセスが可能になる。

MPCは、DirectShowを使用した再生でピン接続に失敗すると、エラーメッセージを表示する。 このメッセージに、接続失敗したピンのAM_MEDIA_TYPE構造体のデータが記載されている。 (但し、*pUnk,cbFormat,*pbFormatのデータは省略されている。) (Ogg Vorbisのデコーダがなく、Ogg Splitterからのピン接続に失敗したときのもの)

用語解説
  • GUID(Global Unique Identifier)

    全世界で2つ以上のアイテムが同じ値を持つことがない一意な識別子のこと。 ここでは、WindowsのクラスIDを指している。

  • 構造体

    プログラム言語のC(およびC++)で使用されるデータ型の一つ。 複数のデータをまとめて、一つのデータの塊として処理できるようにしたもの。 構造体の中の個々のデータを、その構造体の「メンバ」と呼ぶ。

  • ポインタ

    あるデータのメモリ上の位置(アドレス)を格納した変数。

参考資料
2004-10-16

フィルタグラフの作成

フィルタグラフの構築にあたっては、アプリケーションが使用するフィルタを指定することも可能だが、 フィルタグラフマネージャに、グラフ作成の全部・一部を任すこともできる。

未完成のフィルタグラフに対し、フィルタグラフマネージャは、以下の作業を行う。

  1. メディアタイプに適合するフィルタをレジストリ内で探す。
  2. 見つかったフィルタを「メリット値」の順に試す。

これを順次繰り返すことで、自動的にフィルタグラフを完成できる。 この機能を「インテリジェント接続」と呼ぶ。

ピンによっては、レンダラまでのグラフの残りの部分を作成する処理を引き受けるものがある。 こうしたピンを見つけると、フィルタグラフマネージャは、それ以降の接続をピン自身に任せる。 ただ、こうした機能を実際に持つピンは稀。

参考資料
2004-10-16

フィルタのメリット値

フィルタグラフマネージャがフィルタを試行する時の優先順位を示す値。 メディアタイプが適合するフィルタの内、この値が大きいものから、ピン接続が試される。 基準値として、以下の値が定義されている。

  • MERIT_PREFERRED
    • 0x800000
    • 操作を直接実行することが多いフィルタ (レンダラなど)。
  • MERIT_NORMAL
    • 0x600000
    • 接続の確立に関与する可能性が高いフィルタ(スプリッタ、変換フィルタなど)。
  • MERIT_UNLIKELY
    • 0x400000
    • 接続の確立に関与する可能性があるフィルタ (ソースフィルタ、カラースペース変換フィルタなど)。
  • MERIT_DO_NOT_USE
    • 0x200000
    • 接続の確立に関与しないフィルタ。
  • MERIT_SW_COMPRESSOR
    • 0x100000
    • ハードウェア コンプレッサ フィルタ。
  • MERIT_HW_COMPRESSOR
    • 0x100050
    • ソフトウェア コンプレッサ フィルタ。

※「0x」は、その値が16進数として表示されていることを示す。※

メリット値が MERIT_DO_NOT_USE(0x200000)以下のフィルタは、インテリジェント接続の試行対象とならない。 つまり、この値以下のフィルタは、アプリケーションによって明示的に指定されない限り使用されない。

また、ここに挙げた基準値の中間値を設定することも可能。

参考資料
2004-10-16

DirectShowフィルタ

コーデック・コンテナ・DirectShowフィルタ

自分は最初、中々これらの区別がつかなかった。 (特に、コーデックとDirectShowフィルタとの区別。)

ffdshowはコーデックではない、(DirectShow)フィルタだ。

2ch辺りで上のような発言に出会うと、その度に混乱していたものだ‥。 とりあえず、現状での自分の知識を整理してみる。

コーデックとコンテナの違い。

コーデックとコンテナ、この違いは割と分かりやすい。

動画は映像データと音声データに分けられるが、これらを一つのファイルに格納する為の規格が「コンテナ」。 しばしば、「コンテナは入れ物」と説明される。

しかし、動画・音声データは結構容量を食うので、データをそのままコンテナに格納すると、ファイルサイズが馬鹿でかくなってしまう。 そこで、動画・音声データを圧縮(Compress)した状態でコンテナに格納し、再生時に圧縮データを伸張(Decompress)するという方法が一般に採られている。

この、圧縮-伸張を実現するプログラム、またはその圧縮-伸張形式をコーデック(CODEC = COMpressor + DECompressor)と呼ぶ。 コーデックは圧縮プログラムと伸張プログラムで構成され、そのそれぞれは一般的に、エンコーダ、デコーダと呼ばれる。 つまり、コーデックとは、エンコーダ、デコーダをひとつにまとめたプログラムパッケージ、またはそれらによって実現される圧縮-伸張形式そのものを指している。

コーデックとDirectShowフィルタの違い

コーデックとDirectShowフィルタ、この二つも、違うといえば全く違う。 だが、コーデックとコンテナの違いとは、違い方が異なる。 コーデックがコンテナであったりすることはありえないが、 あるコーデックがDirectShowフィルタであるということは十分ありうる。

コーデックとは、上述の通り、圧縮-伸張プログラムのパッケージ、またはその圧縮-伸張形式そのものの呼称。 一方、DirectShowフィルタは、DirectShowの規格に則って、フィルタグラフの構成要素となれるように開発されたプログラムの総称。 だから、あるコーデックが、DirectShowフィルタとして設計されていれば、そのコーデックはDirectShowフィルタであることになる。

実際、DirectShowフィルタとして実装されているコーデックは少なくない。 例えばDivX。 DivXのエンコーダ、デコーダはどちらもDirectShowフィルタとして実装されている。

ただ、すべてのコーデックがDirectShowフィルタとして実装されるというわけでもない。 ffmpeg等、非DirectShowベースの有力なCODECも存在する。

つまり、「コーデックとDirectShowフィルタは違う」と言っても、それは、「AであればBではない」という排他的関係を表してはいない。 単に、「AとBとは、発せられる視点の違う言葉だ」ということを示しているに過ぎない。

とりあえず図を作ってみる。

コーデック・コンテナ・DirectShowフィルタ関係図

ffdshowはコーデックか?

ffdshowは元々、ffmpegのlibavcodecをDirectShowフィルタ化する目的で作られたようだ。

ffdshow is DirectShow and VFW codec for decoding/encoding many video and audio formats

SourceForgeの紹介文より

‥ということなので、コーデックと呼んでもよさそうなのだが、実際のところ、エンコーダは搭載しておらず、各種圧縮形式に対するデコーダしか持っていない。 コーデックがエンコーダとデコーダのパッケージを指すことを思うと、ffdshowをコーデックと呼ぶことには抵抗を感じる。

ただ、「デコーダ」の意味合いで「コーデック」という言葉が使われている事も、少なくない。 「DVDの再生にはMPEG-2コーデックが必要」などと言う場合だ。 デコーダのみが必要な場合でも、わざわざ細かく「デコーダ」などと指定せず「コーデック」と言っておく方が、むしろ普通だとも言える。

だが、「コーデック」と言えば、そこには必ず「デコーダ」が含まれるから、こういう言い方が成り立っているだけで、 こういった言い方があるからと言って、「コーデック」= 「デコーダ」という等号が成り立っているというわけではない。 「デコーダ」単体を指すべき場合に「コーデック」という言葉を使うのは、やはり、間違っている。

また、ffdshowの機能は、単純なデコーディングのみに留まるものではない。 各種デコーダ以外にも、様々な再生支援機能が、DirectShowフィルタとして実装されている。

こうしたことを考えると、最初に挙げたffdshowの説明は、やはり、正しい。 だが、あれだけではあまりに素っ気無いので、次のようにまとめておこうと思う。

ffdshowはコーデックではなく、各種デコーダを備えた、再生専用の多機能DirectShow Filterである。
2004-10-23

HOMEへ MPCについてのメモへ TOP