ネットワーク ソースからイベントを取得する方法
ソース リゾルバーを使用すると、アプリケーションでネットワーク ソースを作成し、特定の URL への接続を開きます。 ネットワーク ソースは、接続を開く非同期操作の開始と終了をマークするイベントを発生させます。 アプリケーションは、 IMFSourceOpenMonitor インターフェイスを使用して、これらのイベントに登録できます。
このインターフェイスは、ネットワーク ソースが URL を非同期で開いたときに直接呼び出す IMFSourceOpenMonitor::OnSourceEvent メソッドを公開します。 ネットワーク ソースは、 MEConnectStart イベントを発生させて URL を開き始めると、アプリケーションに通知します。 その後、開いている操作が完了すると、ネットワーク ソースによって MEConnectEnd イベントが発生します。
注意
これらのイベントをアプリケーションに送信するには、ネットワーク ソースが作成される前にこれらのイベントが発生するため、ネットワーク ソースは IMFMediaEventGenerator インターフェイスを使用しません。 アプリケーションは、メディア セッションの IMFMediaEventGenerator インターフェイスを使用して、他のすべてのネットワーク ソース イベントを取得できます。
ネットワーク ソースからイベントを取得するには
-
IMFSourceOpenMonitor インターフェイスを実装します。
IMFSourceOpenMonitor::OnSourceEvent メソッドの実装で、次の操作を行います。
- IMFMediaEvent::GetStatus を呼び出してイベントの状態を取得します。 このメソッドは、ソース リゾルバー メソッドの呼び出しなど、イベントをトリガーした操作が成功したかどうかを示します。 操作が成功しなかった場合、状態はエラー コードです。
- イベントの種類 ( MEConnectStart または MEConnectEnd) に基づいてイベントを処理します。このイベントは、 アプリケーションが IMFMediaEvent::GetType を呼び出すことによって取得できます。
- 手順 1 で説明した IMFSourceOpenMonitor 実装へのポインターを格納するように、プロパティ ストア オブジェクトでキーと値のペアを構成します。
- PSCreateMemoryPropertyStore 関数を呼び出して、プロパティ ストア オブジェクトを作成します。
- PROPERTYKEY 構造体で MFPKEY_SourceOpenMonitor プロパティを設定します。
- IUnknown ポインターをアプリケーションの IMFSourceOpenMonitor インターフェイスの実装に設定して、PROPVARIANT 構造体にVT_UNKNOWN型データ値を指定します。
- IPropertyStore::SetValue を呼び出して、プロパティ ストアにキーと値のペアを設定します。
- IMFSourceResolver::CreateObjectFromURL など、アプリケーションがネットワーク ソースの作成に使用しているソース リゾルバー メソッドにプロパティ ストア ポインターを渡します。
例
次の例は、 IMFSourceOpenMonitor インターフェイスを実装して、ネットワーク ソースからイベントを取得する方法を示しています。
class CSourceOpenMonitor : public IMFSourceOpenMonitor
{
public:
CSourceOpenMonitor () : m_cRef(1) { }
STDMETHODIMP QueryInterface(REFIID riid, void** ppv)
{
static const QITAB qit[] =
{
QITABENT(CSourceOpenMonitor, IMFSourceOpenMonitor),
{ 0 }
};
return QISearch(this, qit, riid, ppv);
}
STDMETHODIMP_(ULONG) AddRef()
{
return InterlockedIncrement(&m_cRef);
}
STDMETHODIMP_(ULONG) Release()
{
LONG cRef = InterlockedDecrement(&m_cRef);
if (cRef == 0)
{
delete this;
}
// For thread safety, return a temporary variable.
return cRef;
}
STDMETHODIMP OnSourceEvent(IMFMediaEvent* pEvent)
{
MediaEventType eventType = MEUnknown; // Event type
HRESULT hrStatus = S_OK; // Event status
// Get the event type.
HRESULT hr = pEvent->GetType(&eventType);
// Get the event status. If the operation that triggered the event
// did not succeed, the status is a failure code.
if (SUCCEEDED(hr))
{
hr = pEvent->GetStatus(&hrStatus);
}
if (FAILED(hrStatus))
{
hr = hrStatus;
}
if (SUCCEEDED(hr))
{
// Switch on the event type.
switch(eventType)
{
case MEConnectStart:
// The application does something. (Not shown.)
OutputDebugString(L"Connecting...\n");
break;
case MEConnectEnd:
// The application does something. (Not shown.)
OutputDebugString(L"Connect End.\n");
break;
}
}
else
{
// Event failed.
// The application handled a failure. (Not shown.)
}
return S_OK;
}
private:
long m_cRef;
};
次の例は、URL を開いたときにネットワーク ソースで MFPKEY_SourceOpenMonitor プロパティを設定する方法を示しています。
HRESULT CreateMediaSourceWithSourceOpenMonitor(
PCWSTR pszURL,
IMFMediaSource **ppSource
)
{
IPropertyStore *pConfig = NULL;
CSourceOpenMonitor *pMonitor = new (std::nothrow) CSourceOpenMonitor();
if (pMonitor == NULL)
{
return E_OUTOFMEMORY;
}
// Configure the property store.
HRESULT hr = PSCreateMemoryPropertyStore(IID_PPV_ARGS(&pConfig));
if (SUCCEEDED(hr))
{
PROPVARIANT var;
var.vt = VT_UNKNOWN;
pMonitor->QueryInterface(IID_PPV_ARGS(&var.punkVal));
hr = pConfig->SetValue(MFPKEY_SourceOpenMonitor, var);
PropVariantClear(&var);
}
// Create the source media source.
if (SUCCEEDED(hr))
{
hr = CreateMediaSource(pszURL, pConfig, ppSource);
}
SafeRelease(&pConfig);
SafeRelease(&pMonitor);
return hr;
}
関連トピック