世の中には様々なソフトウェアがあるが、各ソフトウェアがすべて固有の機能ばかりで作られているわけではない。 誰かが書いたものを再利用できれば済むところを、めいめいが一から作っていくというのでは非能率的だ。
そこで、共通な機能はあらかじめプログラミングしておいて、各ソフトウェアが必要に応じて該当機能を呼び出すようにする仕組みが必要になる。 そうした仕組みの為に作られたプログラムの集合体、又はその集合体の利用規約を、API(Application Programing Interface)と呼ぶ。 APIによって、各ソフトウェア作者は、固有機能のプログラミングに主力を注げるようになる。
DirectXは、マルチメディア機能を支援するAPI群の総称で、DirectShowはそのコンポーネントの一つ。 DirectShow APIは動画や音楽などのマルチメディアコンテンツの再生・変換・キャプチャを行うソフトウェアを支援する。
動画プレイヤーの多くは、このDirectShow APIを利用して作成されている。
ごく大雑把な流れはこうだ。
順を追って説明する。
フィルタグラフマネージャは、DirectShowのプログラムのひとつ。 フィルタグラフマネージャによって、動画データに合うように、各フィルタが順序良く組み合わせられる。 こうして出来上がったフィルタの組み合わせをフィルタグラフと呼ぶ。
動画再生時のフィルタグラフ内のフィルタは、その働きに応じて4種に大別できる。 データの流れる順序で記していくと、以下のようになる。
データをグラフ内に取り込むフィルタ。 HD内のローカルファイルの読み込みに使われるFile Source(Async.)など。
入力されたデータを複数の出力に分解する。 AVIの映像データと音声データを分離するAvi Splitterなど。
また、再生時には普通使われないが、スプリッタフィルタと対をなして、MUXフィルタというものもある。 MUXフィルタは、動画作成時に使用され、複数の入力を一つの出力に合成する。
デコーダがこれにあたる。 動画作成時に使われるエンコーダもこのカテゴリに入る。
処理の終わったデータを出力デバイスへと送り出すフィルタ。 その際、可能な限りDirectSoundやDirectDrawを使用するよう動作する。 Video Renderer, Default DirectSound Device など。Overlay MixerやVMR7, 9もここに属する。
フィルタグラフによる処理の完了したデータは、DirectSound(音声)、DirectDraw(映像)を通して、 サウンドカード、ビデオカードへと、それぞれ渡されて行く。
公式の図も見ておいて下さい。 これです。
DirectShowフィルタは同士の接続は、「ピン」を介して行われる。 ピンには入力ピンと出力ピンがあり、それぞれのピンには扱うことの出来る「メディアタイプ」が設定されている。
メディアタイプはAM_MEDIA_TYPE構造体で定義されている。 その構成メンバは、以下のとおり。 (参考資料の丸写しですが‥。)
データのカテゴリ全体を定義するGUID。
フォーマットをさらに細かく定義する別のGUID。この値が MEDIASUBTYPE_None の場合がある。これは、フォーマットにはサブタイプが必要ないことを意味している。
TRUE の場合、サンプルのサイズは固定である。
TRUE の場合、サンプルは時系列 (フレーム間) 圧縮方式で圧縮されている。値 TRUE はフレームがすべてキー フレームとは限らないことを示す。
サンプルのサイズ (バイト単位)。圧縮データの場合は、0 も可能。
未使用。
フォーマット ブロックのサイズ (バイト単位)。
フォーマット ブロックへのポインタ。
フォーマット ブロックとは、フォーマットをより詳細に記述するデータのブロック。 AM_MEDIA_TYPE構造体とは別の場所に作られるが、ポインタである pbFormat メンバによって、そこへのアクセスが可能になる。
MPCは、DirectShowを使用した再生でピン接続に失敗すると、エラーメッセージを表示する。 このメッセージに、接続失敗したピンのAM_MEDIA_TYPE構造体のデータが記載されている。 (但し、*pUnk,cbFormat,*pbFormatのデータは省略されている。) 例 (Ogg Vorbisのデコーダがなく、Ogg Splitterからのピン接続に失敗したときのもの) 。
全世界で2つ以上のアイテムが同じ値を持つことがない一意な識別子のこと。 ここでは、WindowsのクラスIDを指している。
プログラム言語のC(およびC++)で使用されるデータ型の一つ。 複数のデータをまとめて、一つのデータの塊として処理できるようにしたもの。 構造体の中の個々のデータを、その構造体の「メンバ」と呼ぶ。
あるデータのメモリ上の位置(アドレス)を格納した変数。
フィルタグラフの構築にあたっては、アプリケーションが使用するフィルタを指定することも可能だが、 フィルタグラフマネージャに、グラフ作成の全部・一部を任すこともできる。
未完成のフィルタグラフに対し、フィルタグラフマネージャは、以下の作業を行う。
これを順次繰り返すことで、自動的にフィルタグラフを完成できる。 この機能を「インテリジェント接続」と呼ぶ。
ピンによっては、レンダラまでのグラフの残りの部分を作成する処理を引き受けるものがある。 こうしたピンを見つけると、フィルタグラフマネージャは、それ以降の接続をピン自身に任せる。 ただ、こうした機能を実際に持つピンは稀。
フィルタグラフマネージャがフィルタを試行する時の優先順位を示す値。 メディアタイプが適合するフィルタの内、この値が大きいものから、ピン接続が試される。 基準値として、以下の値が定義されている。
※「0x」は、その値が16進数として表示されていることを示す。※
メリット値が MERIT_DO_NOT_USE(0x200000)以下のフィルタは、インテリジェント接続の試行対象とならない。 つまり、この値以下のフィルタは、アプリケーションによって明示的に指定されない限り使用されない。
また、ここに挙げた基準値の中間値を設定することも可能。
自分は最初、中々これらの区別がつかなかった。 (特に、コーデックとDirectShowフィルタとの区別。)
ffdshowはコーデックではない、(DirectShow)フィルタだ。
2ch辺りで上のような発言に出会うと、その度に混乱していたものだ‥。 とりあえず、現状での自分の知識を整理してみる。
コーデックとコンテナ、この違いは割と分かりやすい。
動画は映像データと音声データに分けられるが、これらを一つのファイルに格納する為の規格が「コンテナ」。 しばしば、「コンテナは入れ物」と説明される。
しかし、動画・音声データは結構容量を食うので、データをそのままコンテナに格納すると、ファイルサイズが馬鹿でかくなってしまう。 そこで、動画・音声データを圧縮(Compress)した状態でコンテナに格納し、再生時に圧縮データを伸張(Decompress)するという方法が一般に採られている。
この、圧縮-伸張を実現するプログラム、またはその圧縮-伸張形式をコーデック(CODEC = COMpressor + DECompressor)と呼ぶ。 コーデックは圧縮プログラムと伸張プログラムで構成され、そのそれぞれは一般的に、エンコーダ、デコーダと呼ばれる。 つまり、コーデックとは、エンコーダ、デコーダをひとつにまとめたプログラムパッケージ、またはそれらによって実現される圧縮-伸張形式そのものを指している。
コーデックとDirectShowフィルタ、この二つも、違うといえば全く違う。 だが、コーデックとコンテナの違いとは、違い方が異なる。 コーデックがコンテナであったりすることはありえないが、 あるコーデックがDirectShowフィルタであるということは十分ありうる。
コーデックとは、上述の通り、圧縮-伸張プログラムのパッケージ、またはその圧縮-伸張形式そのものの呼称。 一方、DirectShowフィルタは、DirectShowの規格に則って、フィルタグラフの構成要素となれるように開発されたプログラムの総称。 だから、あるコーデックが、DirectShowフィルタとして設計されていれば、そのコーデックはDirectShowフィルタであることになる。
実際、DirectShowフィルタとして実装されているコーデックは少なくない。 例えばDivX。 DivXのエンコーダ、デコーダはどちらもDirectShowフィルタとして実装されている。
ただ、すべてのコーデックがDirectShowフィルタとして実装されるというわけでもない。 ffmpeg等、非DirectShowベースの有力なCODECも存在する。
つまり、「コーデックとDirectShowフィルタは違う」と言っても、それは、「AであればBではない」という排他的関係を表してはいない。 単に、「AとBとは、発せられる視点の違う言葉だ」ということを示しているに過ぎない。
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である。
DirectShowについて調べたことのメモです。 間違いもあるかもしれません‥、掲示板またはメールにてお知らせ下されば幸いです。
HOMEへ MPCについてのメモへ