]> git.sesse.net Git - nageru/blobdiff - nageru/mixer.cpp
When reconnecting an SRT input, try to use the same slot as last time.
[nageru] / nageru / mixer.cpp
index 212041bd1b0f5c69ecab7e6116e5e1844015ad8e..a773d6c60db99cb59530301f95f21b0f6f299120 100644 (file)
@@ -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);
        }
        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;
        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
 #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) {
        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);
 
                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";
                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);
                        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();
                        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();