DirectShow フィルタの作り方

ここでは、Microsoft Visual Studio 2005 で DirectShow フィルタを作成する手順を説明します。

はじめに

なぜこのドキュメントを作ったのか

Windows OS 上でメディアファイルを再生する場合、一般的には DirectShow のメカニズムを使用します。 DirectShow には フィルタピン いう概念があり、 役割の異なるフィルタ同士をそのフィルタがもつピンで連結して、この間にデータを流すことで、画像や音声を再生します。 データを受信するピンを 入力ピン、データを送信するピンを 出力ピン といいます。
一般的に知られているフォーマットの画像や音声は、Microsoft が 提供してくれているフィルタで事足りるのですが、独自フォーマットの画像や音声を再生したり、特殊な 機能を持たせようとした場合には、このフィルタを自作する必要が出てきます。 しかし、DirectShow のアーキテクチャそのものの理解が DirectShow 初級者には難しく、さらに、 インターネット上のサンプルプログラムは、既存のフィルタを繋げてファイルを再生するものはあっても、 独自のフィルタを作成して、それを繋げて再生するようなものは皆無であるため、DirectShow フィルタ作成 プログラミングの敷居が高くなっています。
そこでここでは、この敷居を低くするために Microsoft の提供する DirectShow の基底クラスライブラリを 使用して、DirectShow フィルタを自作する方法をビルド環境を整えるところから説明します。

基底クラスライブラリ

基底クラスライブラリとは、Microsoft が提供する DirectShow フィルタを実装するために設計された C++ クラスと ユーティリティ関数のセットです。Platform SDK とともに提供され、このライブラリを使用した独自フィルタの サンプルコードも一緒に提供されています。フィルタ開発者は、ここで定義されている基底クラスの派生クラスを作成して、 独自フィルタを作成することで開発効率をアップさせることができます。また、この基底クラスライブラリは、 面白いことに C++ のソースコードで提供されており、lib や dll の状態で提供されているわけではありません。 Microsoft が考えるフィルタ開発者の作業シナリオは、
  1. 基底クラスライブラリを付属の makefile でビルドして、スタティックライブラリを作成する。
  2. 独自フィルタのプロジェクトを作成して、ビルド時に基底クラスライブラリをリンクする。
ということのようです。

いまどき makefile でビルドしたくないので

Visual Studio でフィルタ開発を進めようとすると、基底クラスは makefile でビルドして、独自フィルタは Visual Studio でビルドするというのは、あまりスマートな方法ではないなと思いました。両方 Visual Studio で ビルドできれば、さらに、独自フィルタと一緒にビルドできたほうがスマートではないでしょうか。そこで、 ここでは、基底クラスライブラリのソースコードを自分の開発用プロジェクトに追加して、独自フィルタの プロジェクトと一緒にビルドする方法も同時に説明します。

前提条件

Windows XP Professional 上で Microsoft Visual Studio 2005 がインストールされていることを前提とします。

フィルタ開発のため環境整備

[Step1] DirectX SDK のインストール

[Step2] Platform SDK のインストール

[Step3] Microsoft Visual Studio 2005 の環境変更

[Step4] 基底クラスライブラリのプロジェクト化

[Step5] 独自フィルタプロジェクトの作成

独自フィルタの概要

ファイル再生の基本モデル

ソースフィルタとは

パーサーフィルタとは

デコーダーフィルタとは

レンダラフィルタとは

全てのフィルタ作成に共通する作業工程

ソースフィルタの作成方法

Platform SDK の DirectShow フィルタのソースフィルタのサンプルコード Async プロジェクトを改良するのが一番の近道です。このサンプルコードは、ファイルを開いて一旦すべてのデータをメモリ上に読み込んだ後、 ファイルを閉じてから全ての操作を行う作りになっています。これでは大きいファイルを読み込みたい場合にメモリ不足になってしまい不便です。 したがって、ファイルをディスクから読み込みながら操作を行う作りに変更します。
  1. Platform SDK の DirectShow フィルタのサンプルコードをプロジェクト化する。
    デフォルトの位置は、 "C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Samples\Multimedia\DirectShow\Filters\Async" です。 ここにある、*.h ファイルと *.cpp ファイルと *.def ファイルを好みの形にプロジェクト化し、前述した独自フィルタプロジェクトで 変更すべき各種プロパティを適切な値に変更します。
  2. CMemStream クラスを CFileStream クラスなどの変更後の動きに相応しい名前に変更し、 ソースフィルタLoad メソッドが呼ばれたときに、 ファイルを開き、別ファイルを Load メソッドで開くか、フィルタが破棄されるまでは、一度開いたファイルを閉じないように修正します。

パーサーフィルタの作成方法

パーサーフィルタの基本クラスは CBaseFilter クラスで、 このクラスが入力ピン出力ピンのインスタンスのポインタを持ちます。
入力ピンの基本クラスは CBasePin クラスで、 パーサーフィルタプルモデルのフィルタであるため、入力ピンのヘルパーオブジェクトとして CPullPin クラスを使用します。
出力ピンの基本クラスは CBaseOutputPin クラスで、 IMediaSeeking インタフェースを 継承します。ちなみにシーク操作は、このクラスの SetPositions メソッドの実装がキーとなります。
以下の URL からダウンロードできるパーサーフィルタのサンプルコードが参考になります。
http://www.gdcl.co.uk/downloads.htm

デコーダーフィルタの作成方法

こちらをご覧ください。
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/DirectX9_c/directx/htm/writingtransformfilters.asp

レンダラーフィルタの作成方法

こちらをご覧ください。
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/DirectX9_c/directx/htm/writingvideorenderers.asp

デバッグ方法

GraphEdit

独自フィルタを動かすためには、フィルタを繋げて再生するためのアプリケーションが必要です。アプリケーションも自前で作っていては時間がかかります。そこで、 フィルタの動きを簡単にテストするためのツールが、GraphEdit です。使い方などについては、以下をご覧ください。
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/DirectX9_c/directx/htm/simulatinggraphbuildingwithgraphedit.asp

ログ出力

基底クラスライブラリには、簡単にログを出力できる機能があります。一番使うのは、 DbgLog マクロです。
DbgLog((LOG_TRACE, 3, TEXT("nNumber=%d"), nNumber));
と書くと、デバッグビルドしたモジュールにおいて、nNumber の値が指定したログ出力ファイルログレベル 3 以上で書き込まれます。 ログ出力ファイルの名前とログレベルの値はレジストリで設定します。これらの設定については、以下を参照してください。
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/DirectX9_c/directx/htm/debugoutputfunctions.asp

理解しておきたい仕組みと用語

CBasePin 接続処理
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/DirectX9_c/directx/htm/cbasepinconnectionprocess.asp

ストリーミングスレッドアプリケーションスレッド
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/DirectX9_c/directx/htm/streamingthreadandapplicationthread.asp

セグメント
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/DirectX9_c/directx/htm/newsegments.asp

フラッシュ
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/DirectX9_c/directx/htm/flushing.asp

シーク
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/DirectX9_c/directx/htm/seeking.asp

ストリームタイムメディアタイム
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/DirectX9_c/directx/htm/clocktimes.asp
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/DirectX9_c/directx/htm/timestampsandmediatimes.asp