Skip to content
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

gp_camera_wait_for_event ignores timeout, blocks for a long time #29

Closed
Ruuttu opened this issue Mar 24, 2017 · 8 comments
Closed

gp_camera_wait_for_event ignores timeout, blocks for a long time #29

Ruuttu opened this issue Mar 24, 2017 · 8 comments

Comments

@Ruuttu
Copy link

Ruuttu commented Mar 24, 2017

With the Canon EOS 600D, I'm polling gp_camera_wait_for_event in an endless loop with a timeout of 1 (ms). After physically triggering a shot on the camera, the function produces a GP_EVENT_FILE_ADDED event, but not before blocking for about 1.2 seconds. The duration is reduced when taking smaller pictures, so this might be the time it takes to download the image.

My goal is to download images in small chunks while keeping the loop interactive. Seems like this should be doable.

@jim-easterbrook
Copy link
Owner

jim-easterbrook commented Mar 25, 2017

Do you get the same behaviour with a C program? I'm not aware of anything in the Python interface that would add a delay, so your problem may be with libgphoto2 itself.

I don't think the image is being downloaded during your 1.2 second delay, I think the camera is busy saving it to its SD card (and so not responding to USB). If you don't need to store the image on the SD card you could try capturing to memory instead. (It might also be worth trying a faster SD card.)

PS. Rather than using a loop with a short timeout I'd prefer to use a separate thread to wait for the camera to have an image. I do this with any sort of blocking operation in an interactive program.

@mangodan2003
Copy link

mangodan2003 commented Jun 22, 2017

I'm also using a Canon EOS 600D and seeing unexpected behaviour trying to use gp_camera_wait_for_event.

It seems to just return right away. i.e. it never waits!

Python 3.4.5 (default, Feb 21 2017, 16:14:02) 
[GCC 4.9.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import gphoto2 as gp
>>> context = gp.Context()
>>> camera = gp.Camera()
>>> camera.wait_for_event(1000,context)
[0, None]
>>> gp.gp_camera_wait_for_event(camera,1000,context)
[0, 0, None]
>>> gp.version.gp_library_version(1)
['2.5.14', 'all camlibs', 'gcc (C compiler used)', 'ltdl (for portable loading of camlibs)', 'EXIF (for special handling of EXIF files)']

Any pointers?

@jim-easterbrook
Copy link
Owner

How soon is "right away"? You're specifying a timeout of only 1 second.

@mangodan2003
Copy link

mangodan2003 commented Jun 22, 2017

much less than 1sec. fwiw specifying much longer makes no difference.

Python 3.4.2 (default, Oct 19 2014, 13:31:11) 
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import gphoto2 as gp, time
>>> context = gp.Context()
>>> camera = gp.Camera()
>>> start = time.time()
>>> camera.wait_for_event(10000,context)
[0, None]
>>> time.time()  - start
0.2146010398864746

subsequent calls return much quicker - assume the first call has to do a bit more work initiinlaising the "connection"

>>> start = time.time()
>>> camera.wait_for_event(10000,context)
[0, None]
>>> time.time()  - start
0.014323234558105469

@jim-easterbrook
Copy link
Owner

I don't know then. The return value of 0 is GP_EVENT_UNKNOWN - the documentation says "unknown and unhandled event. argument is a char* or NULL" so maybe there's a string there that the Python interface is currently ignoring.
It would appear that you need to poll camera.wait_for_event in a loop until you get an event of interest. It might be worth asking for clarification on the libgphoto mailing list though.

@mangodan2003
Copy link

ok thanks, I remember finding that 0 meant gp.GP_EVENT_UNKNOWN come to think of it and wondered similar..

@mangodan2003
Copy link

mangodan2003 commented Jun 22, 2017

>>> while True:
...  foo = camera.wait_for_event(10000,context)
...  if foo[0] != 0:
...    print(foo)
...    break
... 
[2, <Swig Object of type 'CameraFilePath *' at 0x767ac7c0>]

:)

@jim-easterbrook
Copy link
Owner

jim-easterbrook commented Jun 22, 2017

I've just added code to handle any string when GP_EVENT_UNKNOWN is returned. Trying it on my EOS 100D I get the following

Type "help", "copyright", "credits" or "license" for more information.
>>> import gphoto2 as gp
>>> ctx = gp.Context()
>>> cam = gp.Camera()
>>> cam.init(ctx)
>>> cam.wait_for_event(1000, ctx)
[0, 'PTP Property d105 changed']
>>> cam.wait_for_event(1000, ctx)
[0, 'PTP Property d108 changed']
>>> cam.wait_for_event(1000, ctx)
[0, 'PTP Property d106 changed']
>>> cam.wait_for_event(1000, ctx)
[0, 'PTP Property d107 changed']
>>> cam.wait_for_event(1000, ctx)
[0, 'PTP Property d109 changed']
>>> cam.wait_for_event(1000, ctx)
[0, 'PTP Property d10a changed']
>>> cam.wait_for_event(1000, ctx)
[0, 'PTP Property d10b changed']
>>> cam.wait_for_event(1000, ctx)
[0, 'PTP Property d10c changed']
>>>

I suspect I might run out of such events eventually.
[Edit - yes, I did. After which it was blocking as it should.]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants