Microsoft Windows CE 3.0  

Processing a Sample

Important:
This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

When a filter's input pin receives a sample, the filter processes the data in the sample and then delivers the sample to the next downstream filter. As the previous section described, the filter can do all of its processing while inside the IMemInputPin::Receiveon the downstream input pin, passing it a pointer to the sample's method, or it can hold the sample and process it afterward.

Within the call to Receive, the input pin has the option of blocking the upstream filter's calling thread. You can query the input pin's behavior by calling the IMemInputPin::ReceiveCanBlockmethod. If the return value is S_OK, the pin might block on a call to Receive. If the return value is S_FALSE, the pin will never block on calls to Receive. Based on the return value, the upstream filter might use a separate worker thread to deliver samples.

Some filters process samples in place, without copying any data. Other filters copy the data before processing it. Obviously, it is better to process samples in place whenever possible, to avoid the overhead of unneeded copy operations.

The input pin can reject samples by returning an error code or S_FALSE in its Receivemethod. The value S_FALSE indicates that the pin is flushing data (see "Flushing" below). An error code indicates some other problem. For example, if the filter is stopped, the return value is VFW_E_WRONG_STATE. If a pin rejects a sample, the upstream filter calls the IPin::EndOfStreammethod and stops sending data. If the pin returned an error code, the upstream filter also signals EC_ERRORABORT to the filter graph manager.

The upstream filter must serialize all of its Receivecalls to a given input pin.

End of Stream

When a source filter has no more data to send, it calls the IPin::EndOfStreammethod on the downstream input pin. The downstream filter propagates the call to the next filter. Eventually the EndOfStreamcall reaches the renderer filter. The renderer filter signals EC_COMPLETE to the filter graph manager.

Before posting an EC_COMPLETE notification to the application, the filter graph manager waits until all the streams signal EC_COMPLETE. The application does not receive an EC_COMPLETE notice until all the streams have completed. To determine the number of streams in the graph, the filter graph manager counts the number of filters that support IMediaSeekingor IMediaPositionand have a rendered input pin. A rendered input pin is an input pin with no corresponding outputs. The IPin::QueryInternalConnectionsmethod returns zero for a rendered input pin.

Filters must serialize EndOfStreamcalls with IMemInputPin::Receivecalls.

Flushing

Flushing is the process of discarding all the pending samples in the graph. Flushing enables the graph to be more responsive when events alter the normal data flow. For example, in a seek operation, pending data is flushed from the graph before new data is introduced. If the graph contains multiple streams, it is possible to flush individual streams separately.

Flushing is a two-stage process:

  1. The source filter calls IPin::BeginFlushon a downstream input pin. The downstream filter flushes any pending data and calls BeginFlushon the next input pin. The call propagates downstream until it reaches the renderer.
  2. The source filter calls IPin::EndFlushon the downstream input pin. Again, the downstream filter propagates this call.

    When the BeginFlushmethod is called on a filter's input pin, the filter performs the following actions:

    • Returns from any blocking calls to the input pin's IMemInputPin::Receivemethod.
    • Rejects any further samples in calls to Receive, until the EndFlushmethod is called.
    • Discards any samples that were queued for delivery to downstream filters.
    • Clears any pending calls to IPin::EndOfStream.
    • Clears any pending EC_COMPLETE notifications.
    • Calls BeginFlushon downstream input pins.

      When the EndFlushmethod is called, the filter performs the following actions:

      • Waits for queued samples to be discarded.
      • Calls EndFlushdownstream.

        At this point, the filter can accept samples again.

        In the pull model, the parser filter initiates flushing rather than the source filter. The sequence of events is the same, except that the parser also calls BeginFlushand EndFlushon the source filter's output pin.

        Critical Sections in Filters

        Because filter operations are multithreaded, it is crucial that a filter serialize certain operations. Otherwise, race conditions can result. For example, the filter might try to use an allocator that is already decommitted. Filters use two critical sections, one to hold a streaming lock and the other to hold a filter state lock.

        The streaming lock serializes streaming operations. The filter holds this lock when it processes the following method calls: