MOQT: Ignore OnSubgroupAbandoned for groups before first_active_group_.

If a subgroup is abandoned after its group has already been abandoned, group < first_active_group_. Instead of hitting a DCHECK, return early from OnSubgroupAbandoned.

PiperOrigin-RevId: 986778151
diff --git a/quiche/quic/moqt/moqt_live_publisher.cc b/quiche/quic/moqt/moqt_live_publisher.cc
index 49630dc..0bdfb64 100644
--- a/quiche/quic/moqt/moqt_live_publisher.cc
+++ b/quiche/quic/moqt/moqt_live_publisher.cc
@@ -285,7 +285,7 @@
 void LivePublisher::OnSubgroupAbandoned(
     uint64_t group, uint64_t subgroup,
     webtransport::StreamErrorCode error_code) {
-  if (!InWindow(group)) {
+  if (!InWindow(group) || group < first_active_group_) {
     return;
   }
   DataStreamIndex index(group, subgroup);
@@ -294,7 +294,6 @@
     return;
   }
   reset_subgroups_.insert(index);
-  QUICHE_DCHECK_GE(group, first_active_group_);
   std::optional<webtransport::StreamId> stream_id =
       stream_map_.GetStreamFor(index);
   if (!stream_id.has_value()) {
diff --git a/quiche/quic/moqt/moqt_live_publisher_test.cc b/quiche/quic/moqt/moqt_live_publisher_test.cc
index 0360d4c..d70fd0d 100644
--- a/quiche/quic/moqt/moqt_live_publisher_test.cc
+++ b/quiche/quic/moqt/moqt_live_publisher_test.cc
@@ -722,6 +722,16 @@
   publisher_->OnSubgroupAbandoned(1, 0, 1234);
 }
 
+// Repro for b/564069875. A relay could abandon a group and then receive a reset
+// for a stream in that group.
+TEST_F(LivePublisherTest, OnSubgroupAbandonedAfterGroupAbandoned) {
+  CreateStream(Location(1, 0), 0, 128);
+  EXPECT_CALL(mock_uni_stream_, ResetWithUserCode(kResetCodeDeliveryTimeout))
+      .WillOnce([&](webtransport::StreamErrorCode) { uni_stream_.reset(); });
+  publisher_->OnGroupAbandoned(1);
+  publisher_->OnSubgroupAbandoned(1, 0, 1234);
+}
+
 }  // namespace
 
 }  // namespace moqt::test