Open g40 opened 7 months ago
If you want the simplest possible program and just capture images in a loop, the suggested way is to use the SnapSink.
While SnapSink::snapImage is semantically not identical to QueueSink::popOutputBuffer, for simple programs this should not really matter. As a bonus, a parallel live display will not get hindered by slow buffer processing.
(Yes, in theory a blocking popOutputBuffer can work better if you have inconsistent image processing times, but on the other hand it would be easy to accidently write "wrong" programs with that.)
Hello Tim, thanks again.
Can I get a bit more detail then about popOutputBuffer? Is that thread safe? Is it safe to call once framesQueued
has been called?
My requirement is to be able to pull all images in the incoming stream as quickly as possible as push them off to some more complex image processing. This is for industrial inspection purposes running at quite high speeds so dropping frames is really not an option. Thus minimizing both complexity and possible errors on the capture interface is highly desirable.
If it helps I can post a a very compact example of the code I am currently using.
Thanks again for listening.
If you want to get all images, QueueSink is the way to go.
popOutputBuffer is guaranteed to succeed once inside framesQueued, since there always is at least one buffer available when the function is called. You don't need to loop and framesQueued will be called again immediately if you want to simplify your program.
Yes, it is thread-safe, you can call it from any thread, even multiple times at once.
I think there are basically two ways to go about to solve your application: (1) Call popOutputBuffer in framesQueued, and pass the result to your processing code. You can use the thread framesQueued runs on for this if single-threaded is enough for you. The thread has no other task other than running framesQueued. (2) Flag an event in framesQueued, wait for that in the main thread, and do popOutputBuffer+processing there. For each event, you will have to loop popOutputBuffer until it fails, since you cannot know whether you missed an event during processing.
Both should yield very similar image throughput.
PS: I think at the moment framesQueued is called repeatedly forever until there are no buffers queued. This behavior will cause a busy loop on the framesQueued-thread in solution 2 above. This feels like a bug and will likely get changed in a future release.
Hello again and thanks for the detailed reply. Much appreciated. My minimal test bed uses precisely the second variety - the framesQueued
thread simply sets an event, upon which the main capture loop is waiting. The clarification around popOutputBuffer
is especially reassuring.
At first glance, it is not clear that the callback function
framesQueued
runs in a different thread. Might this be documented a little more clearly?The next question is can you run capture loop in a single thread? The answer seems to be yes, but with the inefficiency of polling.
The example code below is just to illustrate the concept. what would be great here is to make
popOutputBuffer()
a blocking call when given an optional timeout - this would put the calling thread to sleep until either a frame is ready or the timeout expires. Similar to WaitObject() in the Windows API.Just a thought. Thanks for listening.