Поделиться через


Получение событий из сетевого источника

Сопоставитель источника позволяет приложению создать сетевой источник и открыть подключение к конкретному URL-адресу. Источник сети вызывает события, чтобы пометить начало и конец асинхронной операции открытия подключения. Приложение может зарегистрировать эти события с помощью интерфейса IMFSourceOpenMonitor.

Этот интерфейс предоставляет метод IMFSourceOpenMonitor::OnSourceEvent, который вызывается источником сети непосредственно при открытии URL-адреса асинхронно. Сетевой источник уведомляет приложение при открытии URL-адреса, вызвав событие MEConnectStart. Сетевой источник затем вызывает событие MEConnectEnd после завершения открытия операции.

Заметка

Чтобы отправить эти события в приложение, сетевой источник не использует интерфейс IMFMediaEventGenerator, так как эти события создаются до создания сетевого источника. Приложение может получить все другие события источника сети, используя интерфейс IMFMediaEventGenerator из мультимедийного сеанса.

 

Получение событий из сетевого источника

  1. Реализуйте интерфейс IMFSourceOpenMonitor. В реализации метода IMFSourceOpenMonitor::OnSourceEvent выполните следующие действия:
    1. Получите состояние события, вызвав IMFMediaEvent::GetStatus. Этот метод указывает, успешно ли выполнена операция, активировающая событие, например вызов метода сопоставителя источника. Если операция не выполнена, состояние является кодом сбоя.
    2. Обработайте событие на основе типа события: MEConnectStart или MEConnectEnd, которое приложение может получить, вызвав IMFMediaEvent::GetType.
  2. Настройте пару "ключ-значение" в объекте хранилища свойств для хранения указателя на реализацию IMFSourceOpenMonitor, описанную на шаге 1.
    1. Создайте объект хранилища свойств, вызвав функцию PSCreateMemoryPropertyStore.
    2. Задайте свойство MFPKEY_SourceOpenMonitor в структуре PROPERTYKEY.
    3. Укажите значение данных типа VT_UNKNOWN в структуре PROPVARIANT путем задания указателя IUnknown на реализацию интерфейсаIMFSourceOpenMonitor.
    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;
};

В следующем примере показано, как задать свойство MFPKEY_SourceOpenMonitor в сетевом источнике при открытии URL-адреса:

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