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