From 7c327ef6ccb722f8458a170d58d7eef7a8aa8681 Mon Sep 17 00:00:00 2001 From: axxel Date: Mon, 23 Sep 2024 17:50:23 +0200 Subject: [PATCH] make camera_trigger_canon_eos_capture "synchronous" This is a draft of a change along the lines of the discussion in https://github.com/gphoto/libgphoto2/issues/968#issuecomment-2337742476 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. --- camlibs/ptp2/library.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/camlibs/ptp2/library.c b/camlibs/ptp2/library.c index 99dae394d..aaebca777 100644 --- a/camlibs/ptp2/library.c +++ b/camlibs/ptp2/library.c @@ -5995,9 +5995,14 @@ camera_trigger_canon_eos_capture (Camera *camera, GPContext *context) uint32_t result; struct timeval focus_start; PTPDevicePropDesc dpd; + int full_press_wait = 0; GP_LOG_D ("camera_trigger_canon_eos_capture"); + for (unsigned i = 0; i < params->nrofcanon_props; i++) + if (params->canon_props[i].proptype == PTP_DPC_CANON_EOS_Owner) + full_press_wait = atoi(params->canon_props[i].dpd.CurrentValue.str); + if (!params->eos_captureenabled) camera_prepare_capture (camera, context); else @@ -6107,6 +6112,12 @@ camera_trigger_canon_eos_capture (Camera *camera, GPContext *context) return GP_ERROR; } /* no event check between */ + + if (full_press_wait) { + GP_LOG_D ("waiting %dms", full_press_wait); + usleep (full_press_wait * 1000); + } + /* full release now */ C_PTP_REP_MSG (ptp_canon_eos_remotereleaseoff (params, 2), _("Canon EOS Full-Release failed")); ptp_check_eos_events (params); @@ -6182,6 +6193,23 @@ camera_trigger_canon_eos_capture (Camera *camera, GPContext *context) return GP_ERROR; } } + + if (full_press_wait) + { + struct timeval event_start = time_now(); + PTPPropertyValue propval = { 0 }; + for (unsigned i = 0; i < params->nrofcanon_props; i++) + if (params->canon_props[i].proptype == PTP_DPC_CANON_EOS_ISOSpeed) + propval.u16 = params->canon_props[i].dpd.CurrentValue.u16; + + do { + // if setting iso does not return busy, the camera is ready to take new commands or is lost -> exit + ret = ptp_canon_eos_setdevicepropvalue (params, PTP_DPC_CANON_EOS_ISOSpeed, &propval, PTP_DTC_UINT16); + back_off_wait = 0; + } while (ret == PTP_RC_DeviceBusy && waiting_for_timeout (&back_off_wait, event_start, 30*1000)); + params->eos_camerastatus = 0; /* manually set it to 'done' */ + } + return GP_OK; }