Question about Creating Directshow Filter with a callback
-
Hi, I am using the CPushSource Filter as a step to get my filter working, I have the Pushsource working nicely. I have a camera that requires a callback in which it sends all the images to, I simply want to take this data and transfer it to the filter but I want to do it using a callback or any other method that is efficient. Is there any way of doing this? Thanks in advance
-
Hi, I am using the CPushSource Filter as a step to get my filter working, I have the Pushsource working nicely. I have a camera that requires a callback in which it sends all the images to, I simply want to take this data and transfer it to the filter but I want to do it using a callback or any other method that is efficient. Is there any way of doing this? Thanks in advance
You should be able to add a callback function to your filter module just like you would anywhere else. If you aren't connecting to the camera within the filter, then you can add a method to your filter class which returns the address of the callback. Once you obtain an interface to the filter (when creating the graph) you can use that interface instance to call the method. I hope that make sense, Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
-
You should be able to add a callback function to your filter module just like you would anywhere else. If you aren't connecting to the camera within the filter, then you can add a method to your filter class which returns the address of the callback. Once you obtain an interface to the filter (when creating the graph) you can use that interface instance to call the method. I hope that make sense, Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
Hi Mark, Thanks for the response, so when I get the callback in the filter, how does one trigger the FillBuffer routine that talks to the output pin, is there anyway to redirect the callback data to it?
-
Hi Mark, Thanks for the response, so when I get the callback in the filter, how does one trigger the FillBuffer routine that talks to the output pin, is there anyway to redirect the callback data to it?
The source pin is derived from CSourceStream so it has its own thread that is looping calling FillBuffer(). The easiest solution based on the code you have would be to keep a copy of the current frame from the camera (given to the filter through the callback) and every time your FillBuffer override is called, copy the newest frame into the passed sample buffer and set the sample time. The only real problem with this solution is 2 threads doing the job of one - a bit innefficient especially with resources for the extra thread. The plus side to this solution is it's easiest to code. A more robust solution would be to do something closer to a capture filter. Using the existing CSource/CSourceStream classes it's relatively easy to override a few methods to not use the CAMThread base of CSourceStream. The CSourceStream::Active/CSourceStream::Inactive overrides are where the thread creation/destruction occurs. CSourceStream::ThreadProc and CSourceStream::DoBufferProcessingLoop are the methods relevant to the FillBuffer call so there you'll find the necessary calls for obtaining/releasing sample buffers and making the delivery calls. Those you'd want to do in your callback. Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
-
The source pin is derived from CSourceStream so it has its own thread that is looping calling FillBuffer(). The easiest solution based on the code you have would be to keep a copy of the current frame from the camera (given to the filter through the callback) and every time your FillBuffer override is called, copy the newest frame into the passed sample buffer and set the sample time. The only real problem with this solution is 2 threads doing the job of one - a bit innefficient especially with resources for the extra thread. The plus side to this solution is it's easiest to code. A more robust solution would be to do something closer to a capture filter. Using the existing CSource/CSourceStream classes it's relatively easy to override a few methods to not use the CAMThread base of CSourceStream. The CSourceStream::Active/CSourceStream::Inactive overrides are where the thread creation/destruction occurs. CSourceStream::ThreadProc and CSourceStream::DoBufferProcessingLoop are the methods relevant to the FillBuffer call so there you'll find the necessary calls for obtaining/releasing sample buffers and making the delivery calls. Those you'd want to do in your callback. Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
Hi Mark, Thanks for the response, so if I understood you correct, in my callback I do the following: void callback(.... ) { InActivate(); //copy the byte array to the proper pData DoBufferProcessingLoop(); Activate(); } Did I get that right?
-
Hi Mark, Thanks for the response, so if I understood you correct, in my callback I do the following: void callback(.... ) { InActivate(); //copy the byte array to the proper pData DoBufferProcessingLoop(); Activate(); } Did I get that right?
DoBufferProcessingLoop() is already running so you definitely don't want to call it. It is called by the threadproc, so it is running on the sample-push thread. I was speaking of overriding Active() and Inactive(), and in the overrides, don't create the thread at all. Then, in your callback, do the processing that DoBufferProcessingLoop() does on each iteration of its loop - get a sample buffer from the allocator, fill the sample with data, set the sample's time, and send it on downstream. So, instead of using CSourceStream for your pin class, derive a class from CSourceStream and do the overrides. Then you're essentially using the benifits of CSourceStream without the built-in thread (CSourceStream is derived from CAMThread). Take a look at the source code for CSourceStream in the DirectShow base classes and you'll see what I'm referring to (I think it's source.cpp/.h). Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
-
DoBufferProcessingLoop() is already running so you definitely don't want to call it. It is called by the threadproc, so it is running on the sample-push thread. I was speaking of overriding Active() and Inactive(), and in the overrides, don't create the thread at all. Then, in your callback, do the processing that DoBufferProcessingLoop() does on each iteration of its loop - get a sample buffer from the allocator, fill the sample with data, set the sample's time, and send it on downstream. So, instead of using CSourceStream for your pin class, derive a class from CSourceStream and do the overrides. Then you're essentially using the benifits of CSourceStream without the built-in thread (CSourceStream is derived from CAMThread). Take a look at the source code for CSourceStream in the DirectShow base classes and you'll see what I'm referring to (I think it's source.cpp/.h). Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
Hi Mark, I think I am understanding..., let me see if I have this right, so basically I override InActive and Active, I dont have to write anything in there. By overriding them they wont be able to trigger the thread to start and stop, so then in my callback I go in and pretty much do what the DoBufferProcessingLoop is doing and once I get IMediaSample *pSample I just populate it with the image data I have and we are ready to go? Did I get that right? Once again thanks