Classes are not encapsulated, but some functions are concentrated in a file.
One is the function declaration file dshowutilities. h, and the other is the function definition file dshowutilities. cpp.
The functions mentioned here are all copied from the source code or help document provided by Microsoft.
First, dshowutilities. h file
# Ifndef dshowutilities_h _
# Define dshowutilities_h _
# Include <dshow. h>
# Pragma comment (Lib, "strmiids. lib ")
// This is just a small function, but it will be used in some example code.
# Define safe_release (x) {If (x) x-> release (); X = NULL ;}
Hresult addfilterbyclsid (
Igraphbuilder * pgraph, // pointer to the filter graph manager.
Const guid & CLSID, // CLSID of the filter to create.
Lpcwstr wszname, // a name for the filter.
Ibasefilter ** PPF); // returns es a pointer to the filter.
Hresult getunconnectedpin (
Ibasefilter * pfilter, // pointer to the filter.
Pin_direction pindir, // direction of the pin to find.
Ipin ** pppin); // es a pointer to the pin.
Hresult connectfilters (
Igraphbuilder * pgraph, // filter graph manager.
Ipin * pout, // output pin on the upstream filter.
Ibasefilter * pdest); // downstream filter.
Hresult connectfilters (
Igraphbuilder * pgraph,
Ibasefilter * psrc,
Ibasefilter * pdest );
// Determine if the pin has this mediatype, stolen from SDK amcap
Bool hasmediatype (ipin * ppin, refguid majortype );
// Stolen from SDK amcap, where the above function hasmediatype is used
Bool isvideopin (ipin * ppin );
// Tear down everything downstream of a given Filter
// Delete all the filters under a given filter and implement it through recursive calling
// Stolen from SDK amcap
Void nukedownstream (ibasefilter * PF, igraphbuilder * PfG );
// Tear down everything downstream of the capture filters, so we can build
// A different capture graph. Notice that we never destroy the capture Filters
// And WDM filters upstream of them, because then all the capture settings
// We 've set wocould be lost.
// Delete the filter next to the capture filter so that a new capture graph can be created.
// The reason for not deleting the capture filter is that if the filter is deleted, the original settings are set in whitelist.
// Stolen from SDK amcap
Void teardowngraph (igraphbuilder * PFG, ivideowindow * pvw, ibasefilter * pvcap );
# Endif
The following code is in dshowutilities. cpp, which is the implementation of these functions.
// Dshowutilities. cpp --------------------------------------------------------
# Include "stdafx. H"
# Include "dshowutilities. H"
/* Configure /*-----------------------------------------------------------------------------------
The following function creates a filter with a specified class identifier (CLSID)
And adds it to the filter graph
Use example: Add Avi MUX filter to the graph
Ibasefilter * pmux;
HR = addfilterbyclsid (pgraph, clsid_avidest, l "Avi MUX", & pmux );
If (succeeded (HR ))
{
//...............
Pmux-> release ();
}
----------------------------------------------------------------------------------*/
Hresult addfilterbyclsid (
Igraphbuilder * pgraph, // pointer to the filter graph manager.
Const guid & CLSID, // CLSID of the filter to create.
Lpcwstr wszname, // a name for the filter.
Ibasefilter ** PPF) // returns es a pointer to the filter.
{
If (! Pgraph |! PPF) return e_pointer;
* PPF = 0;
Ibasefilter * pF = 0;
Hresult hR = cocreateinstance (CLSID, 0, clsctx_inproc_server,
Iid_ibasefilter, reinterpret_cast <void **> (& PF ));
If (succeeded (HR ))
{
HR = pgraph-> addfilter (PF, wszname );
If (succeeded (HR ))
* PPF = PF;
Else
PF-> release ();
}
Return hr;
}
/*----------------------------------------------------------------------------------
This function finds an unconnected pin on a filter
The following function searches on a filter for an unconnected pin,
Either input or output. It returns the first matching pin.
Finding unconnected pins is useful when you are connecting filters.
Use example:
Ipin * pout = NULL;
Hresult hR = getunconnectedpin (pfilter, pindir_output, & pout );
If (succeeded (HR ))
{
//...........
Pout-> release ();
}
Optional -----------------------------------------------------------------------------------*/
Hresult getunconnectedpin (
Ibasefilter * pfilter, // pointer to the filter.
Pin_direction pindir, // direction of the pin to find.
Ipin ** pppin) // es a pointer to the pin.
{
* Pppin = 0;
Ienumpins * penum = 0;
Ipin * ppin = 0;
Hresult hR = pfilter-> enumpins (& penum );
If (failed (HR ))
{
Return hr;
}
While (penum-> next (1, & ppin, null) = s_ OK)
{
Pin_direction thispindir;
Ppin-> querydirection (& thispindir );
If (thispindir = pindir)
{
Ipin * pTMP = 0;
HR = ppin-> connectedto (& pTMP );
If (succeeded (HR) // already connected, not the pin we want.
{
PTMP-> release ();
}
Else // unconnected, This is the pin we want.
{
Penum-> release ();
* Pppin = ppin;
Return s_ OK;
}
}
Ppin-> release ();
}
Penum-> release ();
// Did not find a matching pin.
Return e_fail;
}
/*--------------------------------------------------------------------------------
The following function connects an output pin from one filter
The first available input pin on another filter.
The previously defined function getunconnectedpin is called.
---------------------------------------------------------------------------------*/
Hresult connectfilters (
Igraphbuilder * pgraph, // filter graph manager.
Ipin * pout, // output pin on the upstream filter.
Ibasefilter * pdest) // downstream filter.
{
If (pgraph = NULL) | (pout = NULL) | (pdest = NULL ))
{
Return e_pointer;
}
# Ifdef debug
Pin_direction pindir;
Pout-> querydirection (& pindir );
_ Asserte (pindir = pindir_output );
# Endif
// Find an input pin on the downstream filter.
Ipin * pin = 0;
Hresult hR = getunconnectedpin (pdest, pindir_input, & pin); // call the previously defined function
If (failed (HR ))
{
Return hr;
}
// Try to connect them.
HR = pgraph-> connect (pout, pin );
Pin-> release ();
Return hr;
}
/*---------------------------------------------------------------------------------
Here is an overloaded version of the same function. The second parameter is
A pointer to a filter, rather than a pin.
The function connects the first filter to the second Filter
Use example:
The following example use this example to connect Avi MUX filter to file writer
Filter
Ibasefilter * pmux, * pwrite;
HR = addfilterbyclsid (pgraph, clsid_avidest, l "Avi MUX", & pmux );
If (succeeded (HR ))
{
HR = addfilterbyclsid (pgraph, clsid_filewriter, l "file writer", & pwrite );
If (succeeded (HR ))
{
HR = connectfilters (pgraph, pmux, pwrite );
// Use ifilesinkfilter to set the file name (not shown ).
Pwrite-> release ();
}
Pmux-> release ();
}
The previously defined connectfilters function and getunconnectedpin function are used.
----------------------------------------------------------------------------------*/
Hresult connectfilters (
Igraphbuilder * pgraph,
Ibasefilter * psrc,
Ibasefilter * pdest)
{
If (pgraph = NULL) | (psrc = NULL) | (pdest = NULL ))
{
Return e_pointer;
}
// Find an output pin on the first filter.
Ipin * pout = 0;
Hresult hR = getunconnectedpin (psrc, pindir_output, & pout); // the previously defined function is used.
If (failed (HR ))
{
Return hr;
}
HR = connectfilters (pgraph, pout, pdest); // use the previously defined function
Pout-> release ();
Return hr;
}
/*---------------------------------------------------------------------------------
Determine if the pin has this mediatype, stolen from SDK amcap
--------------------------------------------------------------------------------*/
Bool hasmediatype (ipin * ppin, refguid majortype)
{
If (! Ppin)
{
Return false;
}
Ienummediatypes * pmediatypes;
Hresult hR = ppin-> enummediatypes (& pmediatypes );
If (failed (HR ))
{
Return false;
}
HR = pmediatypes-> Reset ();
If (failed (HR ))
{
Return false;
}
Ulong fetched;
Am_media_type * mediatype;
While (s_ OK = pmediatypes-> next (1, & mediatype, & fetched ))
{
If (isequalguid (mediatype-> majortype, majortype ))
{
// Deletemediatype (mediatype );
Return true;
}
// Deletemediatype (mediatype );
}
Return false;
}
/*--------------------------------------------------------------------------------
Determine whether it is a video pin, stolen from SDK amcap
This function uses the above function hasmediatype.
--------------------------------------------------------------------------------*/
Bool isvideopin (ipin * ppin)
{
Return hasmediatype (ppin, mediatype_video); // The above function
}
/*---------------------------------------------------------------------------------
Tear down everything downstream of a given Filter
Delete all filters under the given filter in a graphbuilder and implement it through recursive calling.
Stolen from amcap
----------------------------------------------------------------------------------*/
Void nukedownstream (ibasefilter * PF, igraphbuilder * PfG)
{
Ipin * PP = 0, * PTO = 0;
Ulong U;
Ienumpins * pins = NULL;
Pin_info pininfo;
If (! PF)
Return;
Hresult hR = PF-> enumpins (& pins );
Pins-> Reset (); // obtain the latest data through this function call?
While (hR = noerror)
{
HR = pins-> next (1, & PP, & U); // locate the pin in the filter.
If (hR = s_ OK & pp)
{
PP-> connectedto (& PTO); // locate the pin of another filter connected to this pin
If (PTO)
{
HR = PTO-> querypininfo (& pininfo );
If (hR = noerror)
{
If (pininfo. dir = pindir_input) // only search for the pin of the Input
{
Nukedownstream (pininfo. pfilter, PfG); // recursive call
PFG-> disconnect (PTO); // remove both ends of the pin
PFG-> disconnect (PP );
PFG-> removefilter (pininfo. pfilter); // In recursive calling,
// The filter with only the input pin is deleted first.
}
Pininfo. pfilter-> release ();
}
PTO-> release ();
}
PP-> release ();
}
} // End while
If (PINs)
Pins-> release ();
}
/*---------------------------------------------------------------------------------
Tear down everything downstream of the capture filters, so we can build
A different capture graph. Notice that we never destroy the capture Filters
And WDM filters upstream of them, because then all the capture settings
We 've set wocould be lost.
Delete the filter following the capture filter to create a new capture graph.
The reason for not deleting the capture filter is that if the filter is deleted, the original settings are set in whitelist.
Stolen from SDK amcap
---------------------------------------------------------------------------------*/
Void teardowngraph (igraphbuilder * PFG, ivideowindow * pvw, ibasefilter * pvcap)
{
If (pvw) // ivideowindow stops video display
{
// Stop drawing in our window, or we may get wierd repaint Effects
Pvw-> put_owner (null );
Pvw-> put_visible (oafalse );
Pvw-> release ();
Pvw = NULL;
}
// Destroy the graph downstream of our capture Filters
If (pvcap)
Nukedownstream (pvcap, PfG); // This function tear down everything downstream of a given Filter
// However, this filter will be retained
// It should be the release of some filters.
}