From: Steinar H. Gunderson Date: Fri, 15 May 2020 17:41:46 +0000 (+0200) Subject: When reconnecting an SRT input, try to use the same slot as last time. X-Git-Tag: 2.0.0~34 X-Git-Url: https://git.sesse.net/?p=nageru;a=commitdiff_plain;h=c9af508251685ef34a1d2cf42330ae6795dd91eb When reconnecting an SRT input, try to use the same slot as last time. --- diff --git a/nageru/mixer.cpp b/nageru/mixer.cpp index 212041b..a773d6c 100644 --- a/nageru/mixer.cpp +++ b/nageru/mixer.cpp @@ -559,6 +559,9 @@ void Mixer::configure_card(unsigned card_index, CaptureInterface *capture, CardT } card->capture.reset(capture); card->is_fake_capture = (card_type == CardType::FAKE_CAPTURE); + if (card->is_fake_capture) { + card->fake_capture_counter = fake_capture_counter++; + } card->is_cef_capture = (card_type == CardType::CEF_INPUT); card->may_have_dropped_last_frame = false; card->type = card_type; @@ -1428,22 +1431,35 @@ void Mixer::handle_hotplugged_cards() #ifdef HAVE_SRT // Same, for SRT inputs. // TODO: On disconnect and reconnect, we might want to use the stream ID - // to find the slot it used to go into? for (SRTSOCKET sock : hotplugged_srt_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 = card_index; - break; - } - } - char name[256]; int namelen = sizeof(name); srt_getsockopt(sock, /*ignored=*/0, SRTO_STREAMID, name, &namelen); string stream_id(name, namelen); + // Look for a fake capture card where we can stick this in. + // Prioritize ones that previously held SRT streams with the + // same stream ID, if any exist -- and it multiple exist, + // take the one that disconnected the last. + int first_free_card_index = -1, last_matching_free_card_index = -1; + for (unsigned card_index = 0; card_index < num_cards; ++card_index) { + CaptureCard *card = &cards[card_index]; + if (!card->is_fake_capture) { + continue; + } + if (first_free_card_index == -1) { + first_free_card_index = card_index; + } + if (card->last_srt_stream_id == stream_id && + (last_matching_free_card_index == -1 || + card->fake_capture_counter > + cards[last_matching_free_card_index].fake_capture_counter)) { + last_matching_free_card_index = card_index; + } + } + + const int free_card_index = (last_matching_free_card_index != -1) + ? last_matching_free_card_index : first_free_card_index; if (free_card_index == -1) { if (stream_id.empty()) { stream_id = "no name"; @@ -1461,6 +1477,7 @@ void Mixer::handle_hotplugged_cards() FFmpegCapture *capture = new FFmpegCapture(sock, stream_id); capture->set_card_index(free_card_index); configure_card(free_card_index, capture, CardType::FFMPEG_INPUT, /*output=*/nullptr, /*override_card_as_live=*/true); + card->last_srt_stream_id = stream_id; 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(); diff --git a/nageru/mixer.h b/nageru/mixer.h index ff8a197..235dd8d 100644 --- a/nageru/mixer.h +++ b/nageru/mixer.h @@ -510,11 +510,19 @@ private: // frame rate is integer, will always stay zero. unsigned fractional_samples = 0; + // Monotonic counter that lets us know which slot was last turned into + // a fake capture. Used for SRT re-plugging. + unsigned fake_capture_counter = 0; + mutable std::mutex card_mutex; bool has_bmusb_thread = false; struct CaptureCard { std::unique_ptr capture; bool is_fake_capture; + // If is_fake_capture is true, contains a monotonic timer value for when + // it was last changed. Otherwise undefined. Used for SRT re-plugging. + int fake_capture_counter; + std::string last_srt_stream_id = ""; // Used for SRT re-plugging. CardType type; std::unique_ptr output;