X-Git-Url: https://git.sesse.net/?p=nageru;a=blobdiff_plain;f=nageru%2Fmixer.cpp;fp=nageru%2Fmixer.cpp;h=a773d6c60db99cb59530301f95f21b0f6f299120;hp=212041bd1b0f5c69ecab7e6116e5e1844015ad8e;hb=c9af508251685ef34a1d2cf42330ae6795dd91eb;hpb=0478d360a9aa0f816b21b0c6b1df91c1426c35d6 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();