From cda479a414b0f0b0c2cefa25969fa2b59681d652 Mon Sep 17 00:00:00 2001 From: Marcus Meissner Date: Wed, 15 Apr 2015 15:30:33 +0000 Subject: [PATCH] EOS capture ... on newer with eosremoterelease on/off switch, use that one and check if we are acquiring focus before doing a full press. This can avoid "busy" locking the camera when we get no focus. (partially done, trigger capture needs it too) git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@15423 67ed7778-7388-44ab-90cf-0a291f65f57c --- camlibs/ptp2/library.c | 101 +++++++++++++++++++++++++++++++--------- camlibs/ptp2/ptp-pack.c | 12 ++--- camlibs/ptp2/ptp.h | 3 ++ 3 files changed, 88 insertions(+), 28 deletions(-) diff --git a/camlibs/ptp2/library.c b/camlibs/ptp2/library.c index 59b5ac0c1..b1d95d7db 100644 --- a/camlibs/ptp2/library.c +++ b/camlibs/ptp2/library.c @@ -2865,29 +2865,75 @@ camera_canon_eos_capture (Camera *camera, CameraCaptureType type, CameraFilePath /* Get the initial bulk set of event data, otherwise * capture might return busy. */ ptp_check_eos_events (params); + while (ptp_get_one_eos_event (params, &entry)) + GP_LOG_D("discarding event type %d", entry.type); - C_PTP_REP_MSG (ptp_canon_eos_capture (params, &result), - _("Canon EOS Capture failed")); + if (ptp_operation_issupported(params, PTP_OC_CANON_EOS_RemoteReleaseOn)) { + int oneloop; - if ((result & 0x7000) == 0x2000) { /* also happened */ - gp_context_error (context, _("Canon EOS Capture failed: %x"), result); - return translate_ptp_result (result); - } - GP_LOG_D ("result is %d", result); - switch (result) { - case 0: /* OK */ - break; - case 1: gp_context_error (context, _("Canon EOS Capture failed to release: Perhaps no focus?")); - return GP_ERROR; - case 3: gp_context_error (context, _("Canon EOS Capture failed to release: Perhaps mirror up?")); - return GP_ERROR; - case 7: gp_context_error (context, _("Canon EOS Capture failed to release: Perhaps no more memory on card?")); - return GP_ERROR_NO_MEMORY; - case 8: gp_context_error (context, _("Canon EOS Capture failed to release: Card read-only?")); - return GP_ERROR_NO_MEMORY; - default: - gp_context_error (context, _("Canon EOS Capture failed to release: Unknown error %d, please report."), result); - return GP_ERROR; + ret = GP_OK; + /* half press now - initiate focusing and wait for result */ + C_PTP_REP_MSG (ptp_canon_eos_remotereleaseon (params, 1, 0), _("Canon EOS Half-Press failed")); + + do { + int foundfocusinfo = 0; + C_PTP_REP_MSG (ptp_check_eos_events (params), + _("Canon EOS Get Changes failed")); + oneloop = 0; + while (ptp_get_one_eos_event (params, &entry)) { + oneloop = 1; + GP_LOG_D("focusing - read event type %d", entry.type); + if (entry.type == PTP_CANON_EOS_CHANGES_TYPE_FOCUSINFO) { + GP_LOG_D("focusinfo content: %s", entry.u.info); + foundfocusinfo = 1; + if (strstr(entry.u.info,"0000200")) { + gp_context_error (context, _("Canon EOS Capture failed to release: Perhaps no focus?")); + ret = GP_ERROR; + } + } + } + if (foundfocusinfo) + break; + } while (oneloop); + + if (ret != GP_OK) { + C_PTP_REP_MSG (ptp_canon_eos_remotereleaseoff (params, 1), _("Canon EOS Half-Release failed")); + return ret; + } + /* full press now */ + + C_PTP_REP_MSG (ptp_canon_eos_remotereleaseon (params, 2, 0), _("Canon EOS Full-Press failed")); + /* no event check between */ + /* full release now */ + C_PTP_REP_MSG (ptp_canon_eos_remotereleaseoff (params, 2), _("Canon EOS Full-Release failed")); + ptp_check_eos_events (params); + + /* half release now */ + C_PTP_REP_MSG (ptp_canon_eos_remotereleaseoff (params, 1), _("Canon EOS Half-Release failed")); + } else { + C_PTP_REP_MSG (ptp_canon_eos_capture (params, &result), + _("Canon EOS Capture failed")); + + if ((result & 0x7000) == 0x2000) { /* also happened */ + gp_context_error (context, _("Canon EOS Capture failed: %x"), result); + return translate_ptp_result (result); + } + GP_LOG_D ("result is %d", result); + switch (result) { + case 0: /* OK */ + break; + case 1: gp_context_error (context, _("Canon EOS Capture failed to release: Perhaps no focus?")); + return GP_ERROR; + case 3: gp_context_error (context, _("Canon EOS Capture failed to release: Perhaps mirror up?")); + return GP_ERROR; + case 7: gp_context_error (context, _("Canon EOS Capture failed to release: Perhaps no more memory on card?")); + return GP_ERROR_NO_MEMORY; + case 8: gp_context_error (context, _("Canon EOS Capture failed to release: Card read-only?")); + return GP_ERROR_NO_MEMORY; + default: + gp_context_error (context, _("Canon EOS Capture failed to release: Unknown error %d, please report."), result); + return GP_ERROR; + } } newobject = 0; @@ -2899,11 +2945,12 @@ camera_canon_eos_capture (Camera *camera, CameraCaptureType type, CameraFilePath _("Canon EOS Get Changes failed")); while (ptp_get_one_eos_event (params, &entry)) { sleepcnt = 1; - GP_LOG_D ("entry type %04x", entry.type); if (entry.type == PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN) { + GP_LOG_D ("entry unknown: %s", entry.u.info); free (entry.u.info); continue; /* in loop ... do not poll while draining the queue */ } + GP_LOG_D ("entry type %04x", entry.type); if (entry.type == PTP_CANON_EOS_CHANGES_TYPE_OBJECTTRANSFER) { GP_LOG_D ("Found new object! OID 0x%x, name %s", (unsigned int)entry.u.object.oid, entry.u.object.oi.Filename); newobject = entry.u.object.oid; @@ -3966,6 +4013,16 @@ camera_wait_for_event (Camera *camera, int timeout, C_MEM (*eventdata = malloc(strlen("Camera Status 123456789012345")+1)); sprintf (*eventdata, "Camera Status %d", entry.u.status); return GP_OK; + case PTP_CANON_EOS_CHANGES_TYPE_FOCUSINFO: + *eventtype = GP_EVENT_UNKNOWN; + C_MEM (*eventdata = malloc(strlen("Focus Info 12345678901234567890123456789")+1)); + sprintf (*eventdata, "Focus Info %s", entry.u.info); + break; + case PTP_CANON_EOS_CHANGES_TYPE_FOCUSMASK: + *eventtype = GP_EVENT_UNKNOWN; + C_MEM (*eventdata = malloc(strlen("Focus Mask 12345678901234567890123456789")+1)); + sprintf (*eventdata, "Focus Mask %s", entry.u.info); + break; case PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN: /* only return if interesting stuff happened */ if (entry.u.info) { diff --git a/camlibs/ptp2/ptp-pack.c b/camlibs/ptp2/ptp-pack.c index 834027f35..f8206454a 100644 --- a/camlibs/ptp2/ptp-pack.c +++ b/camlibs/ptp2/ptp-pack.c @@ -2258,9 +2258,9 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize, } if (mask & 0x0100) { /* mask 0x0100: 6 bytes, 00 00 00 00 00 00 (before focus) and 00 00 00 00 01 00 (on focus) observed */ - ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; - ce[i].u.info = malloc(strlen("OLCInfo event 0x0100 content 0123456789ab")+1); - sprintf(ce[i].u.info,"OLCInfo event 0x0100 content %02x%02x%02x%02x%02x%02x", + ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_FOCUSINFO; + ce[i].u.info = malloc(strlen("0123456789ab")+1); + sprintf(ce[i].u.info,"%02x%02x%02x%02x%02x%02x", curdata[curoff], curdata[curoff+1], curdata[curoff+2], @@ -2273,9 +2273,9 @@ ptp_unpack_CANON_changes (PTPParams *params, unsigned char* data, int datasize, } if (mask & 0x0200) { /* mask 0x0200: 7 bytes, 00 00 00 00 00 00 00 observed */ - ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_UNKNOWN; - ce[i].u.info = malloc(strlen("OLCInfo event 0x0200 content 0123456789abcd")+1); - sprintf(ce[i].u.info,"OLCInfo event 0x0200 content %02x%02x%02x%02x%02x%02x%02x", + ce[i].type = PTP_CANON_EOS_CHANGES_TYPE_FOCUSMASK; + ce[i].u.info = malloc(strlen("0123456789abcd0123456789abcdef")+1); + sprintf(ce[i].u.info,"%02x%02x%02x%02x%02x%02x%02x", curdata[curoff], curdata[curoff+1], curdata[curoff+2], diff --git a/camlibs/ptp2/ptp.h b/camlibs/ptp2/ptp.h index db10cd8b1..1dbd11e29 100644 --- a/camlibs/ptp2/ptp.h +++ b/camlibs/ptp2/ptp.h @@ -278,6 +278,7 @@ typedef struct _PTPIPHeader PTPIPHeader; /* 902c: no parms, read 3 uint32 in data, no response parms */ #define PTP_OC_CANON_902C 0x902C #define PTP_OC_CANON_GetDirectory 0x902D +#define PTP_OC_CANON_902E 0x902E #define PTP_OC_CANON_SetPairingInfo 0x9030 #define PTP_OC_CANON_GetPairingInfo 0x9031 @@ -1264,6 +1265,8 @@ typedef struct _PTPNIKONWifiProfile PTPNIKONWifiProfile; #define PTP_CANON_EOS_CHANGES_TYPE_OBJECTTRANSFER 2 #define PTP_CANON_EOS_CHANGES_TYPE_PROPERTY 3 #define PTP_CANON_EOS_CHANGES_TYPE_CAMERASTATUS 4 +#define PTP_CANON_EOS_CHANGES_TYPE_FOCUSINFO 5 +#define PTP_CANON_EOS_CHANGES_TYPE_FOCUSMASK 6 struct _PTPCanon_New_Object { uint32_t oid;