-
-
Notifications
You must be signed in to change notification settings - Fork 464
Prevent image buffer exhaustion on Android using Qt #938
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prevent image buffer exhaustion on Android using Qt #938
Conversation
This commit fixes the following exception: java.lang.IllegalStateException: maxImages (10) has already been acquired, call #close before acquiring more. This exception is thrown when the device cannot process the images fast enough. Note that Qt captures the images in a separate (Java) thread (on Android) and sends them asynchronously to the main (GUI) thread. This fix moves the processing to a separate thread and discards all new images while another image (frame) is still being processed. This allows Qt to close the Android resources before the buffer is full. In recent versions of Qt, Qt catches this exception itself (see https:// bugreports.qt.io/browse/QTBUG-116526) by restarting the camera, but frequent restarts may degrade performance. On non-Android platforms, this fix has the advantage that the GUI remains responsive even if the barcode processing is slow, and that always the most recently captured frame is processed. Related to zxing-cpp#743
Note that this PR only fixes the Qt6 implementation. However, I assume Qt5 is affected too by this bug. I'm not sure whether we should still put some effort in Qt5 as Qt5 will be EoS very soon. |
Thanks for your contribution. I'd like to suggest though, to not 'force' the use of a multi-threaded approach on everyone using that header file. What about adding some pre-processor macro like |
I'm not really against such an approach, but
Therefore, I would rather add an option to disable the multi-threaded approach than expecting the user to enable the multi-threaded approach (especially on Android) or just enable the multi-threaded approach always. Note that for rare cases, one can also call What do you prefer? |
Alright. First up: it is actually nice to see that someone takes any interest in this Qt wrapper stuff. Until now, it seemed hardly anyone is using that at all. Second: I agree with all your points above. My hesitation was mainly caused by a lack of active memory what this code I wrote years ago actually does, plus I didn't properly look at what your change was doing. I somehow thought you made the After freshening up my memory, I see the situation as follows.
I agree that the 3rd use-case should be asynchronous by default, and also be limited to processing only the most recent frame(s) by default. This gives the best out-of-the-box user experience. With that established, I wonder whether there is room for improving your PR by maybe making use of a If you would look into how this could be implemented neatly, that would be much appreciated. |
Concerning the interest in this repo by the Qt community, I think a lot of them are still using Using Concerning the hiding of implementation details, is it your intention to keep the Qt wrapper header-only? |
In case you are interested in ancient history, you might want to have a look at #75. I had another quick glance at the repo and it seems the project can safely be considered as abandoned.
That is true. I was thinking about mentioning Qt in the "wrappers" section of the readme for quite some time. But with the feeling that this is not really used, I did not want to set something in stone. The example code I can change however I see fit without worrying about backward compatibility.
Oh, it definitively does ;).
Sure, the default should be 1. My point was to make it flexible.
Not necessarily, if there is a clear advantage of doing something else. The header-only approach makes it trivial to build and distribute the wrapper. If we'd consider the |
@axxel I changed the implementation to use a |
a15036a
to
efb08a0
Compare
That looks really neat. One thing though: I fear |
@axxel I added the requested changes, although I think a dead-lock could not happen as the destruction is called in the same thread as the |
Thanks a lot for your time. If you have more suggestions on how to improve this qt-thingy or its visibility inside the qt-zxing community, I am all ears. |
Concerning the Qt visibility, I would:
However, note that I'm not an expert in managing visibility of open source libraries. |
This commit fixes the following exception:
java.lang.IllegalStateException: maxImages (10) has already been acquired, call #close before acquiring more.
This exception is thrown when the device cannot process the images fast enough.
Note that Qt captures the images in a separate (Java) thread (on Android) and sends them asynchronously to the main (GUI) thread.
This fix moves the processing to a separate thread and discards all new images while another image (frame) is still being processed. This allows Qt to close the Android resources before the buffer is full.
In recent versions of Qt, Qt catches this exception itself (see https:// bugreports.qt.io/browse/QTBUG-116526) by restarting the camera, but frequent restarts may degrade performance.
On non-Android platforms, this fix has the advantage that the GUI remains responsive even if the barcode processing is slow, and that always the most recently captured frame is processed.
Related to #743