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


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

Сопоставитель источника позволяет приложению создать сетевой источник и открыть подключение к определенному 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