Share via


ネットワーク ソースからイベントを取得する方法

ソース リゾルバーを使用すると、アプリケーションでネットワーク ソースを作成し、特定の URL への接続を開きます。 ネットワーク ソースは、接続を開く非同期操作の開始と終了をマークするイベントを発生させます。 アプリケーションは、 IMFSourceOpenMonitor インターフェイスを使用して、これらのイベントに登録できます。

このインターフェイスは、ネットワーク ソースが URL を非同期で開いたときに直接呼び出す IMFSourceOpenMonitor::OnSourceEvent メソッドを公開します。 ネットワーク ソースは、 MEConnectStart イベントを発生させて URL を開き始めると、アプリケーションに通知します。 その後、開いている操作が完了すると、ネットワーク ソースによって MEConnectEnd イベントが発生します。

注意

これらのイベントをアプリケーションに送信するには、ネットワーク ソースが作成される前にこれらのイベントが発生するため、ネットワーク ソースは IMFMediaEventGenerator インターフェイスを使用しません。 アプリケーションは、メディア セッションの IMFMediaEventGenerator インターフェイスを使用して、他のすべてのネットワーク ソース イベントを取得できます。

 

ネットワーク ソースからイベントを取得するには

  1. IMFSourceOpenMonitor インターフェイスを実装します。 IMFSourceOpenMonitor::OnSourceEvent メソッドの実装で、次の操作を行います。
    1. IMFMediaEvent::GetStatus を呼び出してイベントの状態を取得します。 このメソッドは、ソース リゾルバー メソッドの呼び出しなど、イベントをトリガーした操作が成功したかどうかを示します。 操作が成功しなかった場合、状態はエラー コードです。
    2. イベントの種類 ( MEConnectStart または MEConnectEnd) に基づいてイベントを処理します。このイベントは、 アプリケーションが IMFMediaEvent::GetType を呼び出すことによって取得できます。
  2. 手順 1 で説明した IMFSourceOpenMonitor 実装へのポインターを格納するように、プロパティ ストア オブジェクトでキーと値のペアを構成します。
    1. PSCreateMemoryPropertyStore 関数を呼び出して、プロパティ ストア オブジェクトを作成します。
    2. PROPERTYKEY 構造体で MFPKEY_SourceOpenMonitor プロパティを設定します。
    3. IUnknown ポインターをアプリケーションの IMFSourceOpenMonitor インターフェイスの実装に設定して、PROPVARIANT 構造体にVT_UNKNOWN型データ値を指定します。
    4. IPropertyStore::SetValue を呼び出して、プロパティ ストアにキーと値のペアを設定します。
  3. 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;
}

Media Foundation でのネットワーク