}
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;
#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";
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();