Greetings,
I have discovered a dangling pointer bug in my USB camera's UM proxy filter
aggregated com object which has now raised in my mind a design question.
The aggregated COM object (I'll call it the extension) provides an interface
for setting various custom camera parameters to the associated Stream Class
driver I have written. This interface is used by all property pages I
provide for the camera and also by some custom applications we produce.
Many of the parameters can change the format of the image stream. In order
to be as friendly as possible, I have attempted to have the extension
rebuild the filter graph when any of the format changing parameters is
modified.
The thinking here was that the extension, as the central object that sends
IOCtrls to the KM driver, is in the best position to know which of the many
parameters actually impact the image format and thus can reduce the number
of times the graph needs to be rebuilt (and also reduce the amount of
knowledge the caller must possess).
The implementation was to derive my extension from IDistributorNotify in
addition to my custom interface. In theory, this will let the extension
know (via the NotifyGraphChange method) when the associated filter is
added/removed from a graph, has its pins connected/unconnected, and when any
other change to the graph happens. Thus in my NotifyGraphChange method, I
call m_baseFilter->QueryFilterInfo(&fInf) on the camera's proxy filter and
save the fInf.pGraph pointer (if it exists). Then when any relevant
parameter is changed, say the X Dimension of the image, I can get the
IGraphConfig from the graph and do a Reconnect. I am using the rather brute
force method of Reconnect as it is my general understanding (and experience)
that renegotiating a format after the initial pin connection is either not
supported or completely broken depending on whether you are a Stream
Class/AVStream driver and perhaps upon the Windows version.
The trouble with this implementation seems to be that while
NotifyGraphChange gets called in many of the listed instances, it does not
get called when the filter is removed from the graph. Thus depending on the
specifics of the graph manipulation, I sometimes end up with a call through
an invalid m_graph pointer to Nowheresville with predictable results.
While I am sure I can tiptoe around this issue by being a bit more clever
(and correct for that matter) in my NotifyGraphChange analysis (for example
I have observed that it is always called correctly on pin connect/disconnect
and thus I could force my m_graph parameter to NULL then) I am wondering if
I am really going about this in the right way. Perhaps the trouble is an
abuse of IDistributorNotify. It occurred to me for example that there may
be some completely different interface I have not stumbled across yet that
sorts this. Or perhaps there is something that could be used from kernel
mode that would be more robust (I thought there might be some standard EVENT
that would do the trick for example).
Is there a preferred technique for notifying a filter graph that the format
has changed and the graph must be rebuilt? Or am I already on the right
track?
Best regards,
Tom Udale