@@ -632,50 +632,86 @@ Freenect2Device *Freenect2::openDevice(int idx)
632
632
}
633
633
634
634
Freenect2Device *Freenect2::openDevice (int idx, const PacketPipeline *pipeline)
635
+ {
636
+ return openDevice (idx, pipeline, true );
637
+ }
638
+
639
+ Freenect2Device *Freenect2::openDevice (int idx, const PacketPipeline *pipeline, bool attempting_reset)
635
640
{
636
641
int num_devices = impl_->getNumDevices ();
637
642
Freenect2DeviceImpl *device = 0 ;
638
643
639
- if (idx < num_devices)
644
+ if (idx >= num_devices)
640
645
{
641
- Freenect2Impl::UsbDeviceWithSerial &dev = impl_->enumerated_devices_ [idx];
642
- libusb_device_handle *dev_handle;
646
+ std::cout << " [Freenect2Impl] requested device " << idx << " is not connected!" << std::endl;
647
+ return device;
648
+ }
643
649
644
- if (!impl_->tryGetDevice (dev.dev , &device))
645
- {
646
- int r = libusb_open (dev.dev , &dev_handle);
650
+ Freenect2Impl::UsbDeviceWithSerial &dev = impl_->enumerated_devices_ [idx];
651
+ libusb_device_handle *dev_handle;
647
652
648
- if (r == LIBUSB_SUCCESS)
649
- {
650
- r = libusb_reset_device (dev_handle);
653
+ if (impl_->tryGetDevice (dev.dev , &device))
654
+ {
655
+ std::cout << " [Freenect2Impl] failed to get device " << PrintBusAndDevice (dev.dev )
656
+ << " (the device may already be open)" << std::endl;
657
+ return device;
658
+ }
651
659
652
- if (r == LIBUSB_SUCCESS)
653
- {
654
- device = new Freenect2DeviceImpl (impl_, pipeline, dev.dev , dev_handle, dev.serial );
655
- impl_->addDevice (device);
660
+ int r = libusb_open (dev.dev , &dev_handle);
656
661
657
- if (!device->open ())
658
- {
659
- delete device;
660
- device = 0 ;
662
+ if (r != LIBUSB_SUCCESS)
663
+ {
664
+ std::cout << " [Freenect2Impl] failed to open Kinect v2 " << PrintBusAndDevice (dev.dev ) << " !" << std::endl;
665
+ return device;
666
+ }
661
667
662
- std::cout << " [Freenect2DeviceImpl] failed to open Kinect v2 " << PrintBusAndDevice (dev.dev ) << " !" << std::endl;
663
- }
664
- }
665
- else
666
- {
667
- std::cout << " [Freenect2Impl] failed to reset Kinect v2 " << PrintBusAndDevice (dev.dev ) << " !" << std::endl;
668
- }
669
- }
670
- else
671
- {
672
- std::cout << " [Freenect2Impl] failed to open Kinect v2 " << PrintBusAndDevice (dev.dev ) << " !" << std::endl;
673
- }
668
+ if (attempting_reset)
669
+ {
670
+ r = libusb_reset_device (dev_handle);
671
+
672
+ if (r == LIBUSB_ERROR_NOT_FOUND)
673
+ {
674
+ // From libusb documentation:
675
+ // "If the reset fails, the descriptors change, or the previous state
676
+ // cannot be restored, the device will appear to be disconnected and
677
+ // reconnected. This means that the device handle is no longer valid (you
678
+ // should close it) and rediscover the device. A return code of
679
+ // LIBUSB_ERROR_NOT_FOUND indicates when this is the case."
680
+
681
+ // be a good citizen
682
+ libusb_close (dev_handle);
683
+
684
+ // HACK: wait for the planets to align... (When the reset fails it may
685
+ // take a short while for the device to show up on the bus again. In the
686
+ // absence of hotplug support, we just wait a little. If this code path
687
+ // is followed there will already be a delay opening the device fully so
688
+ // adding a little more is tolerable.)
689
+ libfreenect2::this_thread::sleep_for (libfreenect2::chrono::milliseconds (1000 ));
690
+
691
+ // reenumerate devices
692
+ std::cout << " [Freenect2Impl] re-enumerating devices after reset" << std::endl;
693
+ impl_->clearDeviceEnumeration ();
694
+ impl_->enumerateDevices ();
695
+
696
+ // re-open without reset
697
+ return openDevice (idx, pipeline, false );
698
+ }
699
+ else if (r != LIBUSB_SUCCESS)
700
+ {
701
+ std::cout << " [Freenect2Impl] failed to reset Kinect v2 " << PrintBusAndDevice (dev.dev ) << " !" << std::endl;
702
+ return device;
674
703
}
675
704
}
676
- else
705
+
706
+ device = new Freenect2DeviceImpl (impl_, pipeline, dev.dev , dev_handle, dev.serial );
707
+ impl_->addDevice (device);
708
+
709
+ if (!device->open ())
677
710
{
678
- std::cout << " [Freenect2Impl] requested device " << idx << " is not connected!" << std::endl;
711
+ delete device;
712
+ device = 0 ;
713
+
714
+ std::cout << " [Freenect2DeviceImpl] failed to open Kinect v2 " << PrintBusAndDevice (dev.dev ) << " !" << std::endl;
679
715
}
680
716
681
717
return device;
0 commit comments