Microsoft DirectX 8.0 |
ここでは、Microsoft® DirectShow® の ASF ライタ フィルタを使って、ASF (Advanced Streaming Format) でファイルを作成する方法を解説する。 ASF は、任意の種類の圧縮データまたは非圧縮データを含むことができるファイル フォーマットである。AVI や WAV などのフォーマットに対する ASF の 1 つの利点は、ASF ファイルのデータにはタイム スタンプが付けられることである。Microsoft® Windows Media Format ファイルは、Windows Media Format Software Development Kit (SDK) で指定された特定の CODEC を使用する ASF ファイルである。これらのファイルでは、 Windows Media Audio ファイルの場合に "wma" という拡張子が使用され、Windows Media Video ファイルの場合に "wmv" という拡張子が使用される。Windows Media Format の詳細については、Windows Media Technologies ホーム ページを参照すること。
DirectShow および Windows Media Format SDK には、Windows Media Format のストリームを作成および再生するアプリケーションを書くための補足情報が与えられている。詳細については、http://www.microsoft.com/hwdev/vidcap/WM_DS.htm にあるホワイト ペーパーを読むこと。
ASF Writer フィルタは、任意の数の入力ストリームを受け付けて ASF ファイルを作成する。このフィルタは、Windows Media Format 仕様に従って ASF ファイルとしての保存を行うため、Windows Media Format SDK を使用して非圧縮オーディオ ファイルまたはビデオ ファイルを Windows Media Format に変換する。ほかの CODEC を使用したり、非圧縮データを ASF フォーマットで保存する場合は、フィルタの圧縮メカニズムをバイパスすることができる。
デジタル ビデオ (DV) キャプチャ、オーディオ再圧縮、ネットワーク ストリーミングの AVI (Audio-Video Interleaved) ファイル、MPEG マルチメディア ファイルの変換など、さまざまな状況で ASF Writer を使用できる。このフィルタによって、DirectShow® で Microsoft® Windows Media Audio (WMA) ファイルおよび Windows Media Video (WMV) ファイルを作成するための唯一の手段が提供される。このフィルタは、Digital Rights Management (DRM) によって保護されている Windows Media Format ファイルを作成することもできる。
ASF Writer フィルタは、Windows Media Format SDK と共にしか使用できない。このフィルタを使うアプリケーションを開発するには、開発マシンに Windows Media Format SDK をインストールしておく必要がある。この SDK をダウンロードすると、Microsoft から電子メールでソフトウェア証明書が送信される。この証明書によって、アプリケーションは SDK のロックを解除し、Digital Rights Management (DRM) を持たない任意の Windows Media Audio ファイルまたは Windows Media Video ファイルの読み書きができるようになる。この証明書がなければ、アプリケーションは ASF Writer をフィルタに追加することができない。DRM が有効になっているファイルを読み書きするには、Windows Media Technologies Web サイトで説明しているように、Microsoft から別の証明書を入手する必要がある。
このトピックは、以下のセクションで構成される。
ASF Writer フィルタの作成時には、デフォルトのシステム プロファイルを使って自動的にフィルタが設定される。システム プロファイルの詳細については、Windows Media Format SDK で説明されている。基本的に、システム プロファイルには、ビット レート、ストリームの数とタイプ、圧縮品質など、Windows Media Format ファイルのさまざまな属性が記述される。デフォルトのプロファイルが適当でない場合、アプリケーションはフィルタの IConfigAsfWriter インターフェイスのメソッドを使って、プロファイルを変更できる。フィルタは、書き込む Windows Media Format ファイルの種類、設定する入力ピンの数、入力ピンが受け入れるメディア タイプなどのプロファイルを使って判定する。フィルタは、設定する前にグラフに追加し、アップストリーム フィルタに接続する前に設定しなければならない。
ASF Writer にプロファイルを指定する方法は、数多くある。ASF Writer は、システムで使用可能なプロファイルを一覧で示すプロパティ ページを持っている。この一覧には、指定された入力ストリームを基にフィルタで作成できるストリームの種類が示される。プロファイルの記述は、"250 Video—Creates video content for clients with 250 Kbps network connections, such as cable modems, DSL, and LAN connections" や、"128 CD Quality Audio—creates CD transparency quality audio content for clients with high-speed Internet and LAN connections. Also suited for local playback" などのように、ユーザーが読むことができる文字列で表示される。アプリケーションは、このプロパティ ページをエンド ユーザーに公開して、ユーザーがプロファイルを選択するようにできる。フィルタのプロパティ ページの表示方法については、「フィルタのプロパティ ページの表示」を参照すること。プロパティ ページを使用しない場合は、Windows Media Format SDK を使ってプロファイルの一覧を直接入手し、アプリケーションのユーザー インターフェイスを使ってエンド ユーザーに一覧を表示することができる。カスタム プロファイルを作成し、それを直接フィルタに渡すこともできる。また、Windows Media Format SDK のヘッダー ファイル Wmsysprf.h から、プロファイルのグローバル一意識別子 (GUID) をフィルタに渡すこともできる。
このフィルタでは、入力ピンの接続中にプロファイルを再設定することができるが、1 つの入力のオーディオ ストリームのプロファイルから、2 つの入力のオーディオおよびビデオ プロファイルに変わるなど、プロファイルが変更された場合は、前に接続されていたオーディオ ストリームだけが再接続される。
デフォルトでは、ASF Writer は圧縮されていないオーディオおよびビデオ ストリームを入力ピンで待ち、Windows Media Format SDK を使って圧縮を処理する。任意のデータ フォーマットを ASF に変換できるので、Windows Media Format SDK が適切な CODEC を持っていないデータ フォーマットを変換したい場合もある。ただし、その結果生成されるファイルは、完全に有効な ASF ファイルになるが、WMA または WMV ファイルとしては有効ではない。このような場合は、ASF Writer のアップストリームにあるフィルタ グラフでストリームを圧縮し、ASF Writer の圧縮メカニズムをバイパスする必要がある。そのためには、ASF Writer に接続されているアップストリーム出力ピンのメディア タイプが、現在の ASF Writer プロファイルで使用されている出力ストリームのフォーマットと完全に一致していなければならない。ASF Writer は、入力ストリームが設定済みのプロファイルとまったく同じであることを検出すると、それ以上の圧縮を試みないでデータを ASF に変換する。
IGraphBuilder::Connect メソッドの呼び出しによって、ソース フィルタとASF Writer の間にフィルタが自動的に挿入されると、ASF Writer は必ず内部で圧縮を行う。そのため、ASF Writer の圧縮メカニズムをバイパスするには、後で説明するようにグラフ全体を手動で作成しなければならない。
Windows Media Format SDK を使用するには、オーディオ ストリームが機能していなければならない。そのため、入力ピンがダミー ストリーム、つまり消音された低ビットレートのオーディオ ストリーム用のものであっても、ASF Writer は常にオーディオ入力ピンを持っていなければならない。また、すべての入力データにタイム スタンプがなければならず、フィルタを実行またはポーズする前に、すべての入力ピンが接続されていなければならない。
ASF Writer を使ってフィルタ グラフを構築する方法は 2 とおりある。1 つ目の方法では、各フィルタを手動でグラフに追加し、ピンを接続する。ASF Writer を追加した後、デフォルトのプロファイルが適当でなければ、IConfigAsfWriter のメソッドを使ってプロファイルを設定し、ASF Writer の入力ピンをアップストリーム フィルタの対応する出力ピンに接続する。
2 つ目の方法では、ASF に変換するファイルの名前を指定して IGraphBuilder::RenderFile メソッドを呼び出す。RenderFile は、ファイルをレンダリングするための完全なグラフを自動的に構築する。その後、アプリケーションのコードで、手動でレンダリング フィルタを削除して ASF Writer を挿入する。これには、次の 5 つの基本ステップが含まれる。
次の図は、ASF Writer フィルタ グラフの代表的な設定を示す。
Windows Media Format SDK にアクセスするには、アプリケーションは実行時にソフトウェア証明書 (キーとも呼ばれる) を提供しなければならない。証明書の入手方法については、Windows Media Format SDK を参照すること。DirectShow アプリケーションは、フィルタ グラフに追加されるときに ASF Writer に証明書を提供する。アプリケーションは、Component Object Model (COM) の IServiceProvider および IObjectWithSite インターフェイスを使って、キー プロバイダとして登録しなければならない。この手法を用いて、アプリケーションは IServiceProvider から派生されたキー プロバイダ クラスを実装する。このクラスは、COM の 3 つの標準メソッドである AddRef、QueryInterface、および Release と共に、フィルタ グラフ マネージャから呼び出される追加メソッド QueryService を実装する。QueryService は、Windows Media Format SDK の WMCreateCertificate メソッドを呼び出し、作成した証明書へのポインタをフィルタ グラフ マネージャに返す。証明書が有効な場合、フィルタ グラフ マネージャはグラフの構築を進めることを許可する。
注 : アプリケーションを構築するには、WMCreateCertificate のプロトタイプ用に Wmsdkidl.h をインクルードし、Microsoft から受け取った Wmstub.lib にリンクする。
次のサンプル コードに、この処理の基本的な手順を示す。
// IServiceProvider から派生されるキー プロバイダ クラスを宣言して実装する。 class CKeyProvider : public IServiceProvider { public: // IUnknown インターフェイス STDMETHODIMP QueryInterface(REFIID riid, void ** ppv); STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release(); CKeyProvider(); // IServiceProvider STDMETHODIMP QueryService(REFIID siid, REFIID riid, void **ppv); private: ULONG m_cRef; }; CKeyProvider::CKeyProvider() : m_cRef(0) { } ////////////////////////////////////////////////////////////////////////// // // IUnknown のメソッド // ////////////////////////////////////////////////////////////////////////// ULONG CKeyProvider::AddRef() { return ++m_cRef; } ULONG CKeyProvider::Release() { ASSERT(m_cRef > 0); m_cRef--; if (m_cRef == 0) { delete this; // オブジェクトはもう存在しないので、m_cRef は返さない。 return((ULONG) 0); } return(m_cRef); } // IUnknown と IServiceProvider だけをサポートする。 HRESULT CKeyProvider::QueryInterface(REFIID riid, void ** ppv) { if (riid == IID_IServiceProvider || riid == IID_IUnknown) { *ppv = (void *) static_cast<IServiceProvider *>(this); AddRef(); return NOERROR; } return E_NOINTERFACE; } STDMETHODIMP CKeyProvider::QueryService(REFIID siid, REFIID riid, void **ppv) { if (siid == __uuidof(IWMReader) && riid == IID_IUnknown) { IUnknown *punkCert; HRESULT hr = WMCreateCertificate(&punkCert); if (SUCCEEDED(hr)) { *ppv = (void *) punkCert; } return hr; } return E_NOINTERFACE; } //////////////////////////////////////////////////////////////////// // // これらの例に、アプリケーションでのメソッド呼び出しの // シーケンスを示す。簡単であるため、エラー チェックは省略した。 // /////////////////////////////////////////////////////////////////// // フィルタ グラフ マネージャを作成するが、フィルタは追加しない。 IGraphBuilder *pGraph; hr = CreateFilterGraph(&pGraph); ... // キー プロバイダ クラスをインスタンス化し、COM が静的オブジェクトを // 解放しないように AddRef の処理をする。 CKeyProvider prov; prov.AddRef(); // COM に静的オブジェクトを解放させない。 // コールバックおよび QueryService 用に、IObjectWithSite ポインタをグラフに与える。 IObjectWithSite* pObjectWithSite = NULL; hr = pGraph->QueryInterface(IID_IObjectWithSite, (void**)&pObjectWithSite); if (SUCCEEDED(hr)) { // IObjectWithSite ポインタを使って、キー プロバイダ オブジェクトを指定する。 // フィルタ グラフ マネージャは、このポインタを使って QueryService を呼び出し、 // ロック解除を行う。 // ロック解除が成功したら、グラフを構築できる。 pObjectWithSite->SetSite((IUnknown *) (IServiceProvider *) &prov); pObjectWithSite->Release(); } // 「グラフの構築」で説明したように、グラフを構築する。