Share via


네트워크 원본에서 이벤트를 가져오는 방법

원본 확인자를 사용하면 애플리케이션이 네트워크 원본을 만들고 특정 URL에 대한 연결을 열 수 있습니다. 네트워크 원본은 연결을 여는 비동기 작업의 시작과 끝을 표시하는 이벤트를 발생합니다. 애플리케이션은 IMFSourceOpenMonitor 인터페이스를 사용하여 이러한 이벤트에 등록할 수 있습니다.

이 인터페이스는 URL을 비동기적으로 열 때 네트워크 원본이 직접 호출하는 IMFSourceOpenMonitor::OnSourceEvent 메서드를 노출합니다. 네트워크 원본은 MEConnectStart 이벤트를 발생시켜 URL 열기를 시작할 때 애플리케이션에 알 수 있습니다. 그런 다음, 네트워크 원본은 열기 작업을 완료할 때 MEConnectEnd 이벤트를 발생합니다.

참고

이러한 이벤트를 애플리케이션에 보내기 위해 네트워크 원본은 IMFMediaEventGenerator 인터페이스를 사용하지 않습니다. 이러한 이벤트는 네트워크 원본을 만들기 전에 발생하기 때문입니다. 애플리케이션은 미디어 세션의 IMFMediaEventGenerator 인터페이스를 사용하여 다른 모든 네트워크 원본 이벤트를 가져올 수 있습니다.

 

네트워크 원본에서 이벤트를 얻으려면

  1. IMFSourceOpenMonitor 인터페이스를 구현합니다. IMFSourceOpenMonitor::OnSourceEvent 메서드 구현에서 다음을 수행합니다.
    1. IMFMediaEvent::GetStatus를 호출하여 이벤트 상태 가져옵니다. 이 메서드는 원본 확인자 메서드 호출과 같이 이벤트를 트리거한 작업이 성공했는지 여부를 나타냅니다. 작업이 성공하지 못하면 상태 오류 코드입니다.
    2. 이벤트 유형 인 MEConnectStart 또는 MEConnectEnd를 기반으로 이벤트를 처리합니다. 이 이벤트는 애플리케이션이 IMFMediaEvent::GetType을 호출하여 가져올 수 있습니다.
  2. 1단계에서 설명한 IMFSourceOpenMonitor 구현에 대한 포인터를 저장하도록 속성 저장소 개체에서 키-값 쌍을 구성합니다.
    1. PSCreateMemoryPropertyStore 함수를 호출하여 속성 저장소 개체를 만듭니다.
    2. PROPERTYKEY 구조체에서 MFPKEY_SourceOpenMonitor 속성을 설정합니다.
    3. IUnknown 포인터를 IMFSourceOpenMonitor 인터페이스의 애플리케이션 구현으로 설정하여 PROPVARIANT 구조에서 VT_UNKNOWN 형식 데이터 값을 제공합니다.
    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;
};

다음 예제에서는 URL을 열 때 네트워크 원본에서 MFPKEY_SourceOpenMonitor 속성을 설정하는 방법을 보여줍니다.

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의 네트워킹