+void Mixer::handle_hotplugged_cards()
+{
+ // Check for cards that have been disconnected since last frame.
+ for (unsigned card_index = 0; card_index < num_cards; ++card_index) {
+ CaptureCard *card = &cards[card_index];
+ if (card->capture->get_disconnected()) {
+ fprintf(stderr, "Card %u went away, replacing with a fake card.\n", card_index);
+ FakeCapture *capture = new FakeCapture(WIDTH, HEIGHT, FAKE_FPS, OUTPUT_FREQUENCY, card_index, global_flags.fake_cards_audio);
+ configure_card(card_index, capture, /*is_fake_capture=*/true);
+ card->queue_length_policy.reset(card_index);
+ card->capture->start_bm_capture();
+ }
+ }
+
+ // Check for cards that have been connected since last frame.
+ vector<libusb_device *> hotplugged_cards_copy;
+ {
+ lock_guard<mutex> lock(hotplug_mutex);
+ swap(hotplugged_cards, hotplugged_cards_copy);
+ }
+ for (libusb_device *new_dev : hotplugged_cards_copy) {
+ // Look for a fake capture card where we can stick this in.
+ int free_card_index = -1;
+ for (unsigned card_index = 0; card_index < num_cards; ++card_index) {
+ if (cards[card_index].is_fake_capture) {
+ free_card_index = int(card_index);
+ break;
+ }
+ }
+
+ if (free_card_index == -1) {
+ fprintf(stderr, "New card plugged in, but no free slots -- ignoring.\n");
+ libusb_unref_device(new_dev);
+ } else {
+ // BMUSBCapture takes ownership.
+ fprintf(stderr, "New card plugged in, choosing slot %d.\n", free_card_index);
+ CaptureCard *card = &cards[free_card_index];
+ BMUSBCapture *capture = new BMUSBCapture(free_card_index, new_dev);
+ configure_card(free_card_index, capture, /*is_fake_capture=*/false);
+ card->queue_length_policy.reset(free_card_index);
+ capture->set_card_disconnected_callback(bind(&Mixer::bm_hotplug_remove, this, free_card_index));
+ capture->start_bm_capture();
+ }
+ }
+}
+
+