Receiving and Delivering Samples

[The feature associated with this page, DirectShow, is a legacy feature. It has been superseded by MediaPlayer, IMFMediaEngine, and Audio/Video Capture in Media Foundation. Those features have been optimized for Windows 10 and Windows 11. Microsoft strongly recommends that new code use MediaPlayer, IMFMediaEngine and Audio/Video Capture in Media Foundation instead of DirectShow, when possible. Microsoft suggests that existing code that uses the legacy APIs be rewritten to use the new APIs if possible.]

The following pseudocode shows how to implement the IMemInput::Receive method:

HRESULT CMyInputPin::Receive(IMediaSample *pSample)
{
    CAutoLock cObjectLock(&m_csReceive);

    // Perhaps the filter needs to wait on something.
    WaitForSingleObject(m_hSomeEventThatReceiveNeedsToWaitOn, INFINITE);

    // Before using resources, make sure it is safe to proceed. Do not
    // continue if the base-class method returns anything besides S_OK.
    hr = CBaseInputPin::Receive(pSample);
    if (hr != S_OK) 
    {
        return hr;
    }

    /* It is safe to use resources allocated in Active and Pause. */

    // Deliver sample(s), via your output pin(s).
    for (each output pin)
        pOutputPin->Deliver(pSample);

    return hr;
}

The Receive method holds the streaming lock, not the filter lock. The filter might need to wait on some event before it can process the data, shown here by the call to WaitForSingleObject. Not every filter will need to do this. The CBaseInputPin::Receive method verifies some general streaming conditions. It returns VFW_E_WRONG_STATE if the filter is stopped, S_FALSE if the filter is flushing, and so forth. Any return code other than S_OK indicates that the Receive method should return immediately and not process the sample.

After the sample is processed, deliver it to the downstream filter by calling CBaseOutputPin::Deliver. This helper method calls IMemInputPin::Receive on the downstream input pin. A filter might deliver samples to several pins.