Compartir a través de


Obtención de eventos del origen de red

El solucionador de origen permite a una aplicación crear un origen de red y abrir una conexión a una dirección URL específica. El origen de red genera eventos para marcar el principio y el final de la operación asincrónica de apertura de una conexión. Una aplicación puede registrarse para estos eventos mediante la interfaz IMFSourceOpenMonitor .

Esta interfaz expone el método IMFSourceOpenMonitor::OnSourceEvent que el origen de red llama directamente cuando abre la dirección URL de forma asincrónica. El origen de red notifica a la aplicación cuando comienza a abrir la dirección URL generando el evento MEConnectStart . A continuación, el origen de red genera el evento MEConnectEnd cuando finaliza la operación de apertura.

Nota

Para enviar estos eventos a la aplicación, el origen de red no usa la interfaz IMFMediaEventGenerator porque estos eventos se generan antes de crear el origen de red. La aplicación puede obtener todos los demás eventos de origen de red mediante la interfaz IMFMediaEventGenerator de la sesión multimedia.

 

Para obtener eventos del origen de red

  1. Implemente la interfaz IMFSourceOpenMonitor . En la implementación del método IMFSourceOpenMonitor::OnSourceEvent , haga lo siguiente:
    1. Obtenga el estado del evento llamando a IMFMediaEvent::GetStatus. Este método indica si la operación que desencadenó el evento, como una llamada al método de resolución de origen, se realizó correctamente. Si la operación no se realiza correctamente, el estado es un código de error.
    2. Procese el evento según el tipo de evento: MEConnectStart o MEConnectEnd, que la aplicación puede obtener llamando a IMFMediaEvent::GetType.
  2. Configure un par clave-valor en un objeto de almacén de propiedades para almacenar un puntero a la implementación imfSourceOpenMonitor descrita en el paso 1.
    1. Cree un objeto de almacén de propiedades llamando a la función PSCreateMemoryPropertyStore .
    2. Establezca la propiedad MFPKEY_SourceOpenMonitor en una estructura PROPERTYKEY .
    3. Proporcione el valor de datos de tipo VT_UNKNOWN en una estructura PROPVARIANT estableciendo el puntero IUnknown en la implementación de la aplicación de la interfaz IMFSourceOpenMonitor .
    4. Establezca el par clave-valor en el almacén de propiedades llamando a IPropertyStore::SetValue.
  3. Pase el puntero del almacén de propiedades a los métodos de resolución de origen que usa la aplicación para crear el origen de red, como IMFSourceResolver::CreateObjectFromURL y otros.

Ejemplo

En el ejemplo siguiente se muestra cómo implementar la interfaz IMFSourceOpenMonitor para obtener eventos del origen de red.

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;
};

En el ejemplo siguiente se muestra cómo establecer la propiedad MFPKEY_SourceOpenMonitor en el origen de red al abrir la dirección 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;
}

Redes en Media Foundation