gphoto2 icon indicating copy to clipboard operation
gphoto2 copied to clipboard

Valid images returned from invalid USB ports

Open kentavv opened this issue 5 years ago • 9 comments

If an invalid USB port name, one that is not listed by 'gphoto2 --auto-detect', is used to perform a capture and download, no error is encountered and an image is retrieved from some camera. This is confusing, especially in the case where one has multiple cameras, and after obtaining the USB port IDs, one of the cameras is detached, using the USB port of the removed camera still returns a valid from one of the still attached cameras. Glad to provide more information or perform tests. Thank you

Name the camera If this is camera specific, include the camera name as shown by gphoto2 --auto-detect or USB IDs [wildcat ~]$ gphoto2 --auto-detect Model Port

Canon EOS 70D usb:001,074 Canon EOS 70D usb:001,075 Canon EOS 70D usb:001,076

libgphoto2 and gphoto2 version output of: gphoto2 --version [wildcat ~]$ gphoto2 --version gphoto2 2.5.20

Copyright (c) 2000-2018 Lutz Mueller and others

gphoto2 comes with NO WARRANTY, to the extent permitted by law. You may redistribute copies of gphoto2 under the terms of the GNU General Public License. For more information about these matters, see the files named COPYING.

This version of gphoto2 is using the following software versions and options: gphoto2 2.5.20 gcc, popt(m), exif, no cdk, no aa, jpeg, readline libgphoto2 2.5.21 all camlibs, gcc, ltdl, EXIF libgphoto2_port 0.12.0 iolibs: disk ptpip serial usb1 usbdiskdirect usbscsi, gcc, ltdl, USB, serial lockdev locking

To Reproduce Steps to reproduce the behavior:

  1. List the USB ports
  2. Capture and download an image from one valid port
  3. Capture and download an image from an invalid port
  4. See both 2 and 3 left a valid image.

[wildcat ~]$ gphoto2 --auto-detect Model Port

Canon EOS 70D usb:001,074 Canon EOS 70D usb:001,075 Canon EOS 70D usb:001,076 [wildcat ~]$ /usr/bin/gphoto2 --capture-image-and-download --port="usb:001,075" --stdout > a.jpg [wildcat ~]$ ls -l a.jpg; file a.jpg -rw-rw-r--. 1 wildcat wildcat 5263489 May 12 12:10 a.jpg a.jpg: JPEG image data, Exif standard: [TIFF image data, little-endian, direntries=12, manufacturer=Canon, model=Canon EOS 70D, orientation=upper-right, xresolution=196, yresolution=204, resolutionunit=2, datetime=2019:05:12 12:14:23], baseline, precision 8, 5472x3648, frames 3 [wildcat ~]$ /usr/bin/gphoto2 --capture-image-and-download --port="usb:001,077" --stdout > a.jpg [wildcat ~]$ ls -l a.jpg; file a.jpg -rw-rw-r--. 1 wildcat wildcat 5293154 May 12 12:10 a.jpg a.jpg: JPEG image data, Exif standard: [TIFF image data, little-endian, direntries=12, manufacturer=Canon, model=Canon EOS 70D, orientation=upper-right, xresolution=196, yresolution=204, resolutionunit=2, datetime=2019:05:12 12:14:39], baseline, precision 8, 5472x3648, frames 3

If its a camera misbehavior, attach debug output using --debug --debug-logfile=debug.log (if considered useful).

kentavv avatar May 12 '19 17:05 kentavv

I was encountering this here: https://github.com/gphoto/gphoto2/issues/43

I recall digging into the code and there is some weirdness with the if/else branching where you have to specify the --camera otherwise it won't work despite them all being the same type of camera.

It's definitely annoying and non-intuitive to have it use whatever port it can if you specify an invalid port. Probably more user friendly for people who only have one camera plugged in but breaks behavior if you are trying to maintain control over multiple cameras of same model as you (and I) are doing.

wtgee avatar Sep 08 '19 23:09 wtgee

Yes, any way to make --camera and --port fail if the selection fails? Or is there another command to force an actual check if it exists without doing a separate --auto-detect call? Perhaps a --force-camera-exists parameter to have the entire call fail.

Without a failure we have no way of knowing which camera a given image actually came from! Any suggestions?

mms- avatar Mar 20 '21 08:03 mms-

I am encountering the same issue, multiple Nikon D5300s, if I turn off the cameras, invalid ports or old ports get assigned to the camera that is still on despite the port number being invalid!

BeebBenjamin avatar May 08 '21 23:05 BeebBenjamin

When you specify --camera even though they are all the same, it is able to detect that the port is no longer valid. I am going to implement something which watches for changes to the original port assignments, and then hopefully recover from it. It might mess up the order of my images though which is annoying, unless there is some way to reset the incremental count on the USB devices.

BeebBenjamin avatar May 08 '21 23:05 BeebBenjamin

I wrote shell script that runs auto detect and writes the port to files for each port and compares the port to a known serial number list.

#!/bin/bash

camera1_ser='' camera2_ser=''

for line in $(gphoto2 --list-ports | grep usb | awk '{print$1}') ; do

if [ $(gphoto2 --port="$line" --get-config serialnumber | grep Current | awk '{print $2}') ==  "$camera1_ser" ]
then
	CAMERA1=$line
fi
if [ $(gphoto2 --port="$line" --get-config serialnumber | grep Current | awk '{print $2}') == "$camera2_ser" ]
then
	CAMERA2=$line
fi

done echo "Camera1 port = $CAMERA1" echo "Camera2 port = $CAMERA2" echo "$CAMERA1" > camera1.conf echo "$CAMERA2" > camera2.conf Then wrote a python script to take pics at same time.


#!/usr/bin/python3

from multiprocessing import Process import sys import os

with open('camera1.conf','r') as f: camera1 = f.read() with open('camera2.conf','r') as f: camera2 = f.read()

def camera1(): os.system('gphoto2 --quiet --port="{}" --capture-image-and-download --force-overwrite --filename "camera1.jpeg"'.format(camera1))

def camera2(): os.system('gphoto2 --quiet --port="{}" --capture-image-and-download --force-overwrite --filename "camera2.jpeg"'.format(camera2))

if name=='main': p1 = Process(target=camera1) p1.start() p2 = Process(target=camera2) p2.start()

demiurge28 avatar May 13 '21 20:05 demiurge28

I think it needs some codefix in gphoto2, that disregards at least --port usb:X,Y where X,Y is no longer valid ... yes :/

msmeissn avatar May 16 '21 12:05 msmeissn

I've found that the problem goes away if I specify camera and port, but only when the cameras are triggered in sequence i.e. distinctly after each other. If one tries to run it in parallel using subprocess.popen, eventually the cameras go into a state where they cannot recover. I queried one of the cameras in this state and it had reverted to using camera RAM, and was running out of PTP storage space, which shouldn't be the case because they were all set to capture to SD card.

BeebBenjamin avatar Jul 09 '21 15:07 BeebBenjamin

Update: Using a desktop PC with Ubuntu it fails. However, using a RaspberryPi 4 with Raspbian (Buster) with a camera on three individual USB ports, parallel triggering works for longer before failure.

cmds = [['gphoto2', '--camera=Nikon DSC D5300','--port=usb:001,004','trigger-capture'],
['gphoto2', '--camera=Nikon DSC D5300','--port=usb:001,005','--trigger-capture'],
['gphoto2', '--camera=Nikon DSC D5300','--port=usb:001,006','--trigger-capture']]

def parallel_capture(cmds):
    procs = [Popen(i) for i in cmds]
    for p in procs:
       p.wait()




BeebBenjamin avatar Jul 09 '21 16:07 BeebBenjamin

I have just tried again with the Raspberry Pi but this time escaping the camera param in the cmds list, and it works a lot better.

cmds = [['gphoto2', '--camera=\"Nikon DSC D5300\"','--port=usb:001,004','--trigger-capture'],
['gphoto2', '--camera=\"Nikon DSC D5300\"','--port=usb:001,005','--trigger-capture'],
['gphoto2', '--camera=\"Nikon DSC D5300\"','--port=usb:001,007','--trigger-capture']]

BeebBenjamin avatar Jul 09 '21 16:07 BeebBenjamin