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

Burst capture #968

Open
davidedelvento opened this issue Mar 24, 2024 · 13 comments
Open

Burst capture #968

davidedelvento opened this issue Mar 24, 2024 · 13 comments
Assignees

Comments

@davidedelvento
Copy link

Prologue

I am not sure if this is operator error, PTP limitation, or using the wrong tool for the job.

I have a number of different DSLR and mirrorless Nikon cameras which all can take extremely fast bursts with several shoots per second in either identical exposure or bracketing conditions.

It looks like whatever I do, with either gphoto2 CLI (from the latest Ubuntu's snap, which brings v2.5.15) or libgphoto2 (gotten from Pip's python-gphoto2, which brings libgphoto.so.6.3.0) I can never achieve more than 1 shot per second which is absolutely insufficient for my needs.

There is a large number of people with similar complaints spread out in time since the project started, so maybe this is not supported? For just two examples jim-easterbrook/python-gphoto2#123 and #317 but there are many more maybe mentioning terms like slow or fast or bracketing etc.

Describe the bug

Is this something that is supposed to work or not? If yes, how? Just repeating the capture slows to a crawl and is totally inadequate. Maybe it works only with some protocols? Only with some cameras (obviously not expecting to go faster than the camera can go on its on)?
To keep it simple let's say without downloading the images, just saving them on the SD cards (yes, these are indeed top-notch speed and work perfectly at the speed the camera is capable on -- when using it standalone rather than connected to the computer).

To avoid frustrating people, it would be greatly appreciated if there could be an authoritative section in the docs or README.md saying:

  • this is not supported ever because no protocol supports it, it's 1 second max cadence
  • this works only with cameras X, Y, Z
  • this works only with gphoto2 versions newer than v
  • any other information that would help people understand if they are dumb, if their hardware is broken or not up to specs (e.g. USB2 vs USB3 -- don't think it's relevant to me since none of my cameras uses USB3), or whatever
  • and if it does work, this is how to do it

Thanks!!!

@msmeissn
Copy link
Contributor

This is hard to specify, and I would say it is camera and hardware dependent.

Also a bit API challenge:

The original capture_image API waits until the image is fully available, which usually takes longer.

There is the trigger capture API and gphoto2 --trigger-capture command, which does not wait until the camera has the image ready, so can queue off more shots while the camera is processing the previous ones still.

So if you specify multiple --trigger-capture (or trigger capture api calls), you should get speeds higher than 1/second.

You will however only get the filename additions later on when the cameras has processed the images (and you can get them via wait-event).

For testing, I just did with my Nikon Z6:

gphoto2 --trigger-capture --trigger-capture --trigger-capture --trigger-capture --trigger-capture --trigger-capture --trigger-capture --trigger-capture --wait-event-and-download=20s

first shot - a 0.x second delay somehow - further shots with definitely less than a second distnace.

only after around 10 seconds it starts downloading images.

@msmeissn msmeissn self-assigned this Mar 24, 2024
@davidedelvento
Copy link
Author

Thank you @msmeissn this helps. I will try it today and report back with exact setup.

Yesterday I tried examples/sample-trigger-capture.c, even removing the wait_event_and_download was a far cry from what the cameras can do on their own.

You will however only get the filename additions later on when the cameras has processed the images (and you can get them via wait-event).

I suspect this is part of the problem. For this use case, I think one has to forgo the filenames and downloads and that is exactly what I am trying to do.

@davidedelvento
Copy link
Author

With my Nikon D5500, D5300 and Z50, a single --trigger-capture gives an error but works. Using more than one trigger, only errors (of the PTP device is busy kind). So it seems that gphoto2 is able to put out the request, but it does so too fast for these cameras to parse, which is quite unfortunate (especially because they can parse equivalently fast or continuous pressure of their physical shutter button).

Thanks again

@msmeissn
Copy link
Contributor

msmeissn commented Apr 7, 2024

There is also on Nikon a "BurstNumber" setting, here for us "burstnumber" configuration.

if you set this, and either do capture_image or trigger_image it will ttake the burstnumber images as fast as the camera can.

seems aavailable on all Nikon D and Z

@davidedelvento
Copy link
Author

Oh, fantastic!! Thanks so much for mentioning it!
I confirm it works with my cameras. Perhaps it just needs some advertising... Speaking of which, is there a place where a list of all these settings are specified, hopefully with their syntax? Every time I try to change something differently from what I've done in the past it feels like I'm reverse engineering the camera....

As far as I am concerned, this issue can be closed.

@axxel
Copy link
Contributor

axxel commented Sep 9, 2024

Lucky Nikon users who have this burstnumber feature... ;). I'm interested in bursting captures on a Canon EOS camera. I have two distinct use cases:

  1. "manual AEB": set exposure time, trigger capture (store on memory card), wait the shortest amount of time required for the camera to complete, repeat.
  2. "in camera AEB": enable AEB, set exposure time, trigger 3 (or 5) captures as fast as possible, wait the shortest amount of time required for the camera to complete, repeat.

For theses two use cases, I came up with a solution around 10 years ago that I have not really touched ever since. For the first use case, I introduced 2 things:

  • poll the camera's 'busy' state by continuously trying to change the ISO setting until that succeeded
  • then simply return from the camera_canon_eos_capture function.

The second was basically introducing the trigger_capture function, which didn't exist at the time, so this part can be dropped. But the first part still needs to be addressed. If I call gphoto2 --trigger-capture --trigger-capture, the second one will always fail with PTP_RC_DeviceBusy.

So, first question to @msmeissn: I wonder whether changing that to only return from camera_trigger_capture after the camera is ready to accept a new command (like another trigger-capture) would not be a general improvement for everyone?

For the second use case, I came up with something that is based on ptp_canon_eos_remotereleaseon and very close to the current version of camera_trigger_canon_eos_capture, only that I

  • added a sleep between the Full press and its release command, simulating the user pressing the button longer. The time to sleep is calculated on the client side and depends obviously on the current exposure time but also on the camera model because of different FPS speeds.
  • added a mechanism based on trying an ISO change again and also trying an remotereleaseon to determine whether or not the current AEB sequence has completed. And if not, I started another burst. And if that still failed, I canceled the current AEB sequence, so that the camera gets back to a defined default state.

What I'm basically trying to achieve here is, telling the Canon to fire a full AEB sequence as fast as possible and let me know, once it is done. Second question @msmeissn: Do you have any suggestion for how to that better with the current state of the library? Ideally, we could come up with something that is generic enough to be put inside libgphoto2, so I don't have to maintain my external patches anymore.

@msmeissn
Copy link
Contributor

I tried to change trigger_capture, but it still was not pushing fast enough.

In the end I think the best way is:

  • switch the camera to continuous release mode
  • set-config eosremoterelease="Press Half"
  • set-config eosrermoterelease="Press Full"
  • ... wait X seconds ... or pioll events and check how many pictures are taken
  • set-config eosremoterelease="Release Full"
  • set-config eosremoterelease="Release Half"
    or something along those lines.

@axxel
Copy link
Contributor

axxel commented Sep 15, 2024

I tried to change trigger_capture, but it still was not pushing fast enough.

What do you mean "pushing fast enough"? Can you explain what you tried to do?

@msmeissn
Copy link
Contributor

I tried to change trigger_capture, but it still was not pushing fast enough.

What do you mean "pushing fast enough"? Can you explain what you tried to do?

  • tried trigger-capture in a loop until it not returned busy/ok ... this still took 3 - 5 seconds for one cycle on the EOS 2000D.

Basically I think because it waits for the full press and releasing of the shutter button.

@axxel
Copy link
Contributor

axxel commented Sep 16, 2024

I did a little experiment with the 3 bodies I currently have available. The table below shows the timestamp in the debug log when the 4 "events" took place:

  • release: Sending PTP_OC 0x9128 (EOS_RemoteReleaseOn) (0x2,0x0) request...
  • not-busy: a 'polling' EOS_SetDevicePropValueEx for ISO first succeeded
  • OLC: an OLCInfoChanged event was received
  • oi-added: the objectinfo added event was received
        release     not-busy    OLC     oi-added

5DM2:   0.3         1.0         -       1.4
5Ds:    0.2         1.2         1.2     1.8
R8:     0.4         0.9         0.9     1.0

As you can see, the two older EOS have a substantial delay between the not-busy moment and the oi-added moment. That is the reason I came up with the ISO-polling approach 12 years ago. The R8 is now substantially faster with processing the data with only about 100ms delay.

The event I found that seems to correlate with this moment where the camera starts responding again is the OLC one (but the 5DM2 does not emit those at all, it seems). So for newer models it seems I could use that as an indicator. The R8 sent the OLCInfo event 0x0010 content 04020631, while the 5Ds sent a Button 1 event. No idea what other models might do here...

The ptp-pack.c files contains the comment still unclear what OLC stands for. Is this still up-to-date?

@msmeissn
Copy link
Contributor

i still do not know what the abbreviation of OLC stands for ... but it does not really matter, it works well.

axxel added a commit to axxel/libgphoto2 that referenced this issue Sep 23, 2024
This is a draft of a change along the lines of the discussion in
gphoto#968 (comment)
meant to be able to discuss something like that further.

After realizing that there is no event sent from the camera to reliably
detect the moment the camera is ready again, I went back to the approach
that I successfully used for the last 10 years in production.

This allows me to execute the following command on my R8 to capture a
total of 4 images in under 2s.

gphoto2 --set-config capturetarget=1
  --set-config aeb="+/- 3"
  --set-config-index drivemode=1
  --set-config shutterspeed=1/500
  --set-config ownername=400
  --trigger-capture
  --set-config aeb=off
  --set-config-index drivemode=0
  --set-config ownername=1
  --trigger-capture

The use of "ownername" is obviously not meant to stay, it was just a quick
hack to enable me to pass an sleep_ms parameter into
camera_trigger_capture from the command line.
@axxel
Copy link
Contributor

axxel commented Sep 23, 2024

Further experiments revealed that OLCInfo event 0x0010 timing is actually not correlated with the not-busy moment, it seems to work for the first capture after power-on but already changes for the second capture. After close inspection I could indeed not find any suitable event that marks this moment in time. Hence the draft PR with the "busy-loop" approach to see if we can find something that is useful for the general user-base.

@andrewyguo
Copy link

@msmeissn Is this available for Sony? I am using a A7M4.

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

4 participants