On slow computers - e.g. Windows 7 tablet with Intel Atom, a multi-threading issue shows up:
When multiple barcodes are processed (e.g. by calling zbar_process_one()) with the same processor instance then it happens that sooner or later the processing doesn't start anymore - the preview window stays at the zbar logo. For it to happen it doesn't matter whether the user closes the window or a barcode has been processed.
The procedure that causes this issue is proc_video_thread() which aborts processing when it doesn't get a sample image anymore but when the streaming flag is still active (proc->streaming == true).
Because proc->streaming isn't reset processing another barcode won't start anymore.
(Because of the similarity of the patches I want to mention that this issue has nothing to do with bug "vfw camera hangs in small resolutions - ID: 3337972" (https://sourceforge.net/tracker/?func=detail&aid=3337972&group_id=189236&atid=928515))
The simplest thing we could do is to always abort processing when no image is available (see patch). I don't know whether this is feasible but it works for me.
A better fix would require a different handling of the proc->streaming and vdo->active flags.
Detailed comment (from the provided patch) for the case that proc_video_thread() doesn't get a sample image:
there's one plausible reason we've got no image:
video streaming has been aborted (e.g. window has been closed by user).
However it's not wise to just test for !proc->streaming in a multi-threaded environment,
and to abort all other cases as problems that should end this thread (if proc->streaming is still true).
reason: there are two flags that determine whether streaming is active:
vdo->active and proc->streaming, both of them are set independently in zbar_processor_set_active().
real case szenario on a windows 7 tablet with intel atom:
1) main thread calls zbar_process_one(), streaming is set up and proc_video_thread() does its work
2) then e.g. user closes the preview window and zbar_process_one() in turn calls zbar_processor_set_active(proc, 0).
zbar_processor_set_active() in turn calls zbar_video_enable() which sets vdo->active=false.
3) now, before zbar_processor_set_active() is able to set proc->streaming=false proc_video_thread() runs its next loop iteration, calls zbar_video_next_image() above which immediately returns because vdo->active==false, but proc->streaming is still true