= !DirectShow 使用手引き = == フィルターグラフイベントの取得 再生終了などのイベントを取得するには、以下のようにします。 {{{ code c HWND hwnd; ... ATL::CComQIPtr<IMediaEventEx> me(m_FilterGraph); if (me != 0) { hRslt = me->SetNotifyWindow( (OAHWND)hwnd, WM_EVENT_NOTIFY, 0); if (FAILED(hRslt)) { return; } } }}} イベント発生時に、ウィンドウメッセージが送信されるように設定します。 {{{ code c MESSAGE_HANDLER(WM_EVENT_NOTIFY, OnEventNotify) ... LRESULT OnEventNotify( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { if (m_FilterGraph == 0) { return 0; } ATL::CComQIPtr<IMediaEvent> me(m_FilterGraph); if (me != 0) { LONG lEventCode = 0; LONG_PTR lParam1 = 0; LONG_PTR lParam2 = 0; HRESULT hRslt = me->GetEvent( &lEventCode, &lParam1, &lParam2, 0); if (SUCCEEDED(hRslt)) { if (lEventCode == EC_COMPLETE) { ATL::CComQIPtr<IMediaControl> ctrl(m_FilterGraph); if (ctrl != 0) { ctrl->Stop(); } } me->FreeEventParams( lEventCode, lParam1, lParam2); } } return 0; } }}} メッセージ処理の例は、以上のようになります。 IMediaEvent::!GetEvent(), IMediaEvent::!FreeEventParams() メソッドを使用して、イベント の情報を取得します。 ここでは、EC_COMPLETE (再生終了イベント) のとき、フィルターグラフを停止させています。 == 再生時間の取得 {{{ code c ATL::CComQIPtr<IMediaSeeking> seek(m_FilterGraph); if (seek != 0) { INT64 duration = 0; seek->GetDuration(&duration); ... } }}} 特に設定しない場合、取得される時間の単位は、100 ns 単位の値となります。(REFERENCE_TIME) == シーク処理 {{{ code c INT64 pos; ... if (m_FilterGraph != 0) { ATL::CComQIPtr<IMediaSeeking> seek(m_FilterGraph); if (seek != 0) { seek->SetPositions( &pos, AM_SEEKING_AbsolutePositioning, 0, AM_SEEKING_NoPositioning); } } }}} 通常、移動先の時間単位は、100 ns 単位となります。 == フォーマット情報取得 フィルターの出力ピンのフォーマット情報を取得するには、以下のようにできます。 {{{ code c ATL::CComPtr<IPin> pin; hRslt = filter->FindPin(L"Audio", &pin); if (FAILED(hRslt)) { return; } ATL::CComPtr<IEnumMediaTypes> em; hRslt = pin->EnumMediaTypes(&em); if (FAILED(hRslt)) { return; } for (; ; ) AM_MEDIA_TYPE* mt = 0; ULONG c = 0; hRslt = em->Next(1, &mt, &c); if (FAILED(hRslt)) { return; } if (mt == 0) { break; } if (mt->formattype == FORMAT_WaveFormatEx && mt->pbFormat != 0 && mt->cbFormat >= sizeof(WAVEFORMATEX)) { WAVEFORMATEX* w = (WAVEFORMATEX*)(mt->pbFormat); ... } QDSA_FreeMediaType(mt); } }}} IPin::!EnumMediaTypes() メソッドで IEnumMediaTypes インターフェイスを取得し、 IEnumMediaTypes::Next() メソッドで、メディアタイプを列挙します。 取得したメディアタイプ構造体のメモリーを解放するには、QDSA_FreeMediaType() 関数 を使用できます。