Como obter eventos da origem da rede
O resolvedor de origem permite que um aplicativo crie uma fonte de rede e abra uma conexão com uma URL específica. A origem da rede gera eventos para marcar o início e o fim da operação assíncrona de abertura de uma conexão. Um aplicativo pode se registrar para esses eventos usando a interface IMFSourceOpenMonitor .
Essa interface expõe o método IMFSourceOpenMonitor::OnSourceEvent que a fonte de rede chama diretamente quando abre a URL de forma assíncrona. A fonte de rede notifica o aplicativo quando ele começa a abrir a URL acionando o evento MEConnectStart . Em seguida, a fonte de rede aciona o evento MEConnectEnd quando conclui a operação aberta.
Observação
Para enviar esses eventos para o aplicativo, a fonte de rede não usa a interface IMFMediaEventGenerator porque esses eventos são gerados antes da criação da fonte de rede. O aplicativo pode obter todos os outros eventos de origem de rede usando a interface IMFMediaEventGenerator da Sessão de Mídia.
Para obter eventos da origem da rede
- Implemente a interface IMFSourceOpenMonitor . Na implementação do método IMFSourceOpenMonitor::OnSourceEvent , faça o seguinte:
- Obtenha o evento status chamando IMFMediaEvent::GetStatus. Esse método indica se a operação que disparou o evento, como uma chamada de método de resolvedor de origem, foi bem-sucedida. Se a operação não for bem-sucedida, o status será um código de falha.
- Processe o evento com base no tipo de evento: MEConnectStart ou MEConnectEnd, que o aplicativo pode obter chamando IMFMediaEvent::GetType.
- Configure um par chave-valor em um objeto de repositório de propriedades para armazenar um ponteiro para a implementação IMFSourceOpenMonitor descrita na etapa 1.
- Crie um objeto de repositório de propriedades chamando a função PSCreateMemoryPropertyStore .
- Defina a propriedade MFPKEY_SourceOpenMonitor em uma estrutura PROPERTYKEY .
- Forneça o valor de dados de tipo VT_UNKNOWN em uma estrutura PROPVARIANT definindo o ponteiro IUnknown para a implementação do aplicativo da interface IMFSourceOpenMonitor .
- Defina o par chave-valor no repositório de propriedades chamando IPropertyStore::SetValue.
- Passe o ponteiro do repositório de propriedades para os métodos de resolvedor de origem que o aplicativo está usando para criar a fonte de rede, como IMFSourceResolver::CreateObjectFromURL e outros.
Exemplo
O exemplo a seguir mostra como implementar a interface IMFSourceOpenMonitor para obter eventos da origem da rede.
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;
};
O exemplo a seguir mostra como definir a propriedade MFPKEY_SourceOpenMonitor na fonte de rede quando você abre a 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;
}
Tópicos relacionados