DirectShow: Null Renderer for Windows CE
This filter is a renderer that discards every sample it receives, without displaying or rendering the sample data. Even though this filter does not render any samples, it does wait for each sample’s presentation time before discarding the sample. Therefore, the graph will run at the normal rate. If you want the graph the run as quickly as possible, set the reference clock to NULL.
A null renderer helps retrieve the frame buffer data as if they were displayed on screen with an actual render. The buffer retrieved may or may not be the same as that retrieved by a null transform filter, depending on the graph, and in particular the media type produced the raw camera data and the type required by the display driver. For example, if the camera produces YV12 but the display driver requires RGB565, there needs to be a color space conversion filter before the renderer. In that case, the buffer retrieved by the null-transform filter will be YV12 but a null-renderer will return RGB565. The position of each filter in the graph (which is determined by Intelligent Connect if the graph was built automatically via RenderStream) will also affect the type of the buffer.
The code for a null renderer is similar to that of a null-transform filter, except that the class needs to inherit CBaseVideoRenderer:
class CNullRenderer
: public CBaseVideoRenderer, public INullRenderer
{
: public CBaseVideoRenderer, public INullRenderer
{
}
The actual rendering work is done in DoRenderSample
HRESULT DoRenderSample(IMediaSample* pMediaSample)
{
}
{
}
To tell Intelligent Connect which media type the filter will accept and which will be rejected, code the function CheckMediaType and declare sudIpPinTypes accordingly. For example, the following declaration will cause the filter to only accept (MEDIATYPE_Video, MEDIASUBTYPE_YV12):
const AMOVIESETUP_MEDIATYPE sudIpPinTypes =
{
&MEDIATYPE_Video, // MajorType
&MEDIASUBTYPE_YV12 // MinorType
}; const AMOVIESETUP_PIN sudIpPin =
{
L“Input”, // The Pins name
TRUE, // Is rendered
FALSE, // Is an output pin
FALSE, // Allowed none
FALSE, // Allowed many
&CLSID_NULL, // Connects to filter
NULL, // Connects to pin
1, // Number of types
&sudIpPinTypes // Pin details
}; const AMOVIESETUP_FILTER sudNullRenderer =
{
&CLSID_NullRenderer, // Filter CLSID
L“Null Renderer”, // String name
MERIT_NORMAL, // Filter merit
1, // Number of pins
&sudIpPin // Pin details
};
{
if (pMediaType->majortype == MEDIATYPE_Video && pMediaType->subtype == MEDIASUBTYPE_YV12)
{
return S_OK;
} else return S_FALSE;
}
{
&MEDIATYPE_Video, // MajorType
&MEDIASUBTYPE_YV12 // MinorType
}; const AMOVIESETUP_PIN sudIpPin =
{
L“Input”, // The Pins name
TRUE, // Is rendered
FALSE, // Is an output pin
FALSE, // Allowed none
FALSE, // Allowed many
&CLSID_NULL, // Connects to filter
NULL, // Connects to pin
1, // Number of types
&sudIpPinTypes // Pin details
}; const AMOVIESETUP_FILTER sudNullRenderer =
{
&CLSID_NullRenderer, // Filter CLSID
L“Null Renderer”, // String name
MERIT_NORMAL, // Filter merit
1, // Number of pins
&sudIpPin // Pin details
};
HRESULT
CheckMediaType(const CMediaType* pMediaType){
if (pMediaType->majortype == MEDIATYPE_Video && pMediaType->subtype == MEDIASUBTYPE_YV12)
{
return S_OK;
} else return S_FALSE;
}