gphoto / libgphoto2

The libgphoto2 camera access and control library.
GNU Lesser General Public License v2.1
1.03k stars 324 forks source link

Sony A7 II+ Cameras #981

Open tmandys opened 3 months ago

tmandys commented 3 months ago

I use libgphoto2 (2.5.31) from python-ghoto2 on RPI3/4/5 running Bullseye and Bookworm. I use more Sony fullframe mirrorless cameras Sony A7I, II, III, IV. My application uses USB preview or grabbed HDMI input to get live preview. HDMI works rather reliably but USB preview is pain on all Sony models supporting it i.e. Sony A7 II +.

Bug

Without USB preview I can take series of pictures but when USB preview is started then I could take one picture and next one freezes/reboots camera (sequence preview-capture-preview-capture(=shutter)-frozen. Also preview alone stopped working in 30secs or so.

I investigated and found that USB channel corrupted and caused preview crash (getting typically error code "-1 Bad parameter"). I made fix when automatically reinitializing camera (in 10 cycle loop with n*200ms delay) and opening new session, I see usb address always increments. This algorithm improved preview stability (but still I can see sometimes unresurectable state).

But when I combine with capture and download, then cca every other capture ends with "-7 I/O error" which can be reinitilized often to -1 or minor to OK. Sometimes the camera is frozen that I must remove battery to reboot, looks like is frozen during shutdown (display is already off).

Tested with Sony Edge @ MAC, W11 and it works well. Note: The same USB cable as it is often a pain as well

I made Wireshark PTP dumps but no progress yet.

Camera

Do you mean is the bug related to PTP protocol or might be issue on USB level ? Note: tested on more RPIs, USB2/3, no difference.

msmeissn commented 3 months ago

its likely some form of sony specific protocol issue.

do you have a debuglog?

tmandys commented 3 months ago

I found that sequence opensession-preview-capture-preview-capture always fails. As temporary workaround is possible probably after capture close and open session. The first caoture in preview session always passes. But seems the reason is waiting to image availability polling _ptp_sony_getalldevicepropdesc vs. event. gphoto get PTP event too early when data are not availble in camera. Strange I cannot see event in pcap itself. Is not it related to code below ? Maybe unrelated event or a pending event in queue.

#if 1
                /* needed on older cameras like the a58, check for events ... */
                /* This would be unsafe if we get an out-of-order event with no objects present, but
                 * we drained all events above */
                C_PTP (ptp_check_event_queue (params));
                if (ptp_get_one_event(params, &event)) {
                        GP_LOG_D ("during wait for image event.code=%04x Param1=%08x", event.Code, event.Param1);
                        if (event.Code == PTP_EC_Sony_ObjectAdded) {
                                newobject = event.Param1;
                                GP_LOG_D ("SONY ObjectAdded received, ending wait");
                                break;
                        }
                }
#endif
2024-06-25 20:32:38,198: gphoto2: MainThread: DEBUG: (camera_sony_capture) DEBUG== 0xd215 after capture = 0
2024-06-25 20:32:38,198: gphoto2: MainThread: DEBUG: (gp_port_get_timeout) Current port timeout is 20000 milliseconds.
2024-06-25 20:32:38,198: gphoto2: MainThread: DEBUG: (gp_port_set_timeout) Setting port timeout to 0 milliseconds.
2024-06-25 20:32:38,198: gphoto2: MainThread: DEBUG: (gp_port_set_timeout) Setting port timeout to 20000 milliseconds.
2024-06-25 20:32:38,198: gphoto2: MainThread: DEBUG: (ptp) event: nparams=0x1, code=0xC203, trans_id=0xFFFFFFFF, p1=0xD21D, p2=0x0, p3=0x0
2024-06-25 20:32:38,198: gphoto2: MainThread: DEBUG: (camera_sony_capture) during event.code=c203 Param1=0000d21d
[logs.zip](https://github.com/user-attachments/files/15977343/logs.zip)

[logs.zip](https://github.com/user-attachments/files/15977357/logs.zip)
[logs.zip](https://github.com/user-attachments/files/15977398/logs.zip)

Passes

2024-06-25 20:32:54,217: gphoto2: MainThread: DEBUG: (ptp) event: nparams=0x1, code=0xC201, trans_id=0xFFFFFFFF, p1=0xFFFFC001, p2=0x0, p3=0x0
2024-06-25 20:32:54,217: gphoto2: MainThread: DEBUG: (camera_sony_capture) during event.code=c201 Param1=ffffc001
2024-06-25 20:32:54,217: gphoto2: MainThread: DEBUG: (camera_sony_capture) SONY ObjectAdded received, ending wait
2024-06-25 20:32:54,217: gphoto2: MainThread: DEBUG: (camera_sony_capture) ending image availability
2024-06-25 20:32:54,217: gphoto2: MainThread: DEBUG: (ptp_usb_sendreq) Sending PTP_OC 0x1008 (Get object info) (0xffffc001) request...
2024-06-25 20:32:54,218: gphoto2: MainThread: DEBUG: (ptp_usb_getdata) Reading PTP_OC 0x1008 (Get object info) data...
2024-06-25 20:32:54,773: gphoto2: MainThread: WARNING: (gp_libusb1_read [libusb1.c:599]) 'libusb_bulk_transfer (port->pl->dh, port->settings.usb.inep, (unsigned char*)bytes, size, &curread, port->timeout)' failed: Input/Output error (-1)
2024-06-25 20:32:54,773: gphoto2: MainThread: WARNING: (gp_port_read [gphoto2-port.c:427]) Reading 1024 = 0x400 bytes from port failed: Error reading from the port (-34)
2024-06-25 20:32:54,773: gphoto2: MainThread: DEBUG: (ptp_usb_getpacket) Clearing halt on IN EP and retrying once.
2024-06-25 20:32:54,773: gphoto2: MainThread: DEBUG: (gp_port_usb_clear_halt) Clear USB halt...
2024-06-25 20:32:54,773: gphoto2: MainThread: WARNING: (gp_libusb1_clear_halt_lib [libusb1.c:573]) 'libusb_clear_halt(port->pl->dh, internal_ep)' failed: Other error (-99)
2024-06-25 20:32:54,774: gphoto2: MainThread: WARNING: (gp_libusb1_read [libusb1.c:599]) 'libusb_bulk_transfer (port->pl->dh, port->settings.usb.inep, (unsigned char*)bytes, size, &curread, port->timeout)' failed: Input/Output error (-1)

Fails

I tested low level code provided by lightweight Sony Camera Remote SDK tools. It works well in both Linux and Windows (completely different code). There are no events in pcap at all. I wonder who setup events on/off. Seems it must be in very early USB connection stage.

Is somehow possible proceed further without recompilation of whole gphoto tool chain? I have not setup it, it is not trivial.

Now I cannot reproduce USB reinitiation during USB preview, maybe again USB cable issue.

Sony-linux-bash-control.pcapng.gz ... no events here

gphoto_simul.sh.txt ... leightweight Sony Capture Tool script

gphoto2.log.gz ... full program+gphoto log

gphoto2.pcapng.gz ... related pcap

tmandys commented 3 months ago

I can prove the issue is race event vs. polled state. When I skip event then Sony camera capture works with preview. I skipping event for ILCE-7 cameras in patch:

diff --git a/camlibs/ptp2/library.c b/camlibs/ptp2/library.c
index 590ff7ace..93a87fe93 100644
--- a/camlibs/ptp2/library.c
+++ b/camlibs/ptp2/library.c
@@ -5026,9 +5026,13 @@ camera_sony_capture (Camera *camera, CameraCaptureType type, CameraFilePath *pat
                if (ptp_get_one_event(params, &event)) {
                        GP_LOG_D ("during wait for image event.code=%04x Param1=%08x", event.Code, event.Param1);
                        if (event.Code == PTP_EC_Sony_ObjectAdded) {
-                               newobject = event.Param1;
-                               GP_LOG_D ("SONY ObjectAdded received, ending wait");
-                               break;
+                               if (params->deviceinfo.Model && !strncmp(params->deviceinfo.Model, "ILCE-7", 6)) {
+                                       GP_LOG_D ("SONY ObjectAdded received, waiting for poll flag");
+                               } else {
+                                       newobject = event.Param1;
+                                       GP_LOG_D ("SONY ObjectAdded received, ending wait");
+                                       break;
+                               }
                        }
                }
 #endif

Seems there is potentially similar issue with Nikon Z9 but I did not tested it personally and have no logs.

Note I have another issue with symbols python-gphoto2 in cython. Likely a build problem in python-gphoto2

ImportError: /home/pi/.local/lib/python3.11/site-packages/gphoto2/_context.cpython-311-aarch64-linux-gnu.so: undefined symbol: gp_context_set_status_func

I have to force loading libphoto2.so

LD_PRELOAD=/home/pi/.local/lib/python3.11/site-packages/gphoto2/libgphoto2/libgphoto2.so.6 python3 -m gphoto2