fec: Skip traversal the list of recovered packets if possible

Do not traverse the list of recovered media packets
if none of them was recovered through FEC recovery procedure.

Bug: None
Change-Id: Ib3aa59c946919fab08f0e20fcf279b1b8032d0e3
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/315320
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Auto-Submit: Andrei Volykhin <andrey.volykhin@lge.com>
Cr-Commit-Position: refs/heads/main@{#40546}
diff --git a/modules/rtp_rtcp/source/flexfec_receiver.cc b/modules/rtp_rtcp/source/flexfec_receiver.cc
index 9f30a72..7f2cc0c 100644
--- a/modules/rtp_rtcp/source/flexfec_receiver.cc
+++ b/modules/rtp_rtcp/source/flexfec_receiver.cc
@@ -149,7 +149,12 @@
   RTC_DCHECK_RUN_ON(&sequence_checker_);
 
   // Decode.
-  erasure_code_->DecodeFec(received_packet, &recovered_packets_);
+  ForwardErrorCorrection::DecodeFecResult decode_result =
+      erasure_code_->DecodeFec(received_packet, &recovered_packets_);
+
+  if (decode_result.num_recovered_packets == 0) {
+    return;
+  }
 
   // Return recovered packets through callback.
   for (const auto& recovered_packet : recovered_packets_) {
diff --git a/modules/rtp_rtcp/source/forward_error_correction.cc b/modules/rtp_rtcp/source/forward_error_correction.cc
index ee99bb9..15a0801 100644
--- a/modules/rtp_rtcp/source/forward_error_correction.cc
+++ b/modules/rtp_rtcp/source/forward_error_correction.cc
@@ -665,8 +665,10 @@
   return true;
 }
 
-void ForwardErrorCorrection::AttemptRecovery(
+size_t ForwardErrorCorrection::AttemptRecovery(
     RecoveredPacketList* recovered_packets) {
+  size_t num_recovered_packets = 0;
+
   auto fec_packet_it = received_fec_packets_.begin();
   while (fec_packet_it != received_fec_packets_.end()) {
     // Search for each FEC packet's protected media packets.
@@ -683,6 +685,8 @@
         continue;
       }
 
+      ++num_recovered_packets;
+
       auto* recovered_packet_ptr = recovered_packet.get();
       // Add recovered packet to the list of recovered packets and update any
       // FEC packets covering this packet with a pointer to the data.
@@ -708,6 +712,8 @@
       fec_packet_it++;
     }
   }
+
+  return num_recovered_packets;
 }
 
 int ForwardErrorCorrection::NumCoveredPacketsMissing(
@@ -758,8 +764,9 @@
   return (packet[8] << 24) + (packet[9] << 16) + (packet[10] << 8) + packet[11];
 }
 
-void ForwardErrorCorrection::DecodeFec(const ReceivedPacket& received_packet,
-                                       RecoveredPacketList* recovered_packets) {
+ForwardErrorCorrection::DecodeFecResult ForwardErrorCorrection::DecodeFec(
+    const ReceivedPacket& received_packet,
+    RecoveredPacketList* recovered_packets) {
   RTC_DCHECK(recovered_packets);
 
   const size_t max_media_packets = fec_header_reader_->MaxMediaPackets();
@@ -782,7 +789,10 @@
   }
 
   InsertPacket(received_packet, recovered_packets);
-  AttemptRecovery(recovered_packets);
+
+  DecodeFecResult decode_result;
+  decode_result.num_recovered_packets = AttemptRecovery(recovered_packets);
+  return decode_result;
 }
 
 size_t ForwardErrorCorrection::MaxPacketOverhead() const {
diff --git a/modules/rtp_rtcp/source/forward_error_correction.h b/modules/rtp_rtcp/source/forward_error_correction.h
index ff6c459..84278a8 100644
--- a/modules/rtp_rtcp/source/forward_error_correction.h
+++ b/modules/rtp_rtcp/source/forward_error_correction.h
@@ -229,8 +229,13 @@
   //                            list will be valid until the next call to
   //                            DecodeFec().
   //
-  void DecodeFec(const ReceivedPacket& received_packet,
-                 RecoveredPacketList* recovered_packets);
+  struct DecodeFecResult {
+    // Number of recovered media packets using FEC.
+    size_t num_recovered_packets = 0;
+  };
+
+  DecodeFecResult DecodeFec(const ReceivedPacket& received_packet,
+                            RecoveredPacketList* recovered_packets);
 
   // Get the number of generated FEC packets, given the number of media packets
   // and the protection factor.
@@ -302,7 +307,7 @@
 
   // Attempt to recover missing packets, using the internally stored
   // received FEC packets.
-  void AttemptRecovery(RecoveredPacketList* recovered_packets);
+  size_t AttemptRecovery(RecoveredPacketList* recovered_packets);
 
   // Initializes headers and payload before the XOR operation
   // that recovers a packet.
diff --git a/modules/rtp_rtcp/source/ulpfec_receiver.cc b/modules/rtp_rtcp/source/ulpfec_receiver.cc
index 4452bdb..7f74a18 100644
--- a/modules/rtp_rtcp/source/ulpfec_receiver.cc
+++ b/modules/rtp_rtcp/source/ulpfec_receiver.cc
@@ -192,6 +192,7 @@
       received_packets;
   received_packets.swap(received_packets_);
   RtpHeaderExtensionMap* last_recovered_extension_map = nullptr;
+  size_t num_recovered_packets = 0;
 
   for (const auto& received_packet : received_packets) {
     // Send received media packet to VCM.
@@ -217,11 +218,17 @@
       // different set of the RTP header extensions and thus different byte
       // representation than the original packet, That will corrupt
       // FEC calculation.
-      fec_->DecodeFec(*received_packet, &recovered_packets_);
+      ForwardErrorCorrection::DecodeFecResult decode_result =
+          fec_->DecodeFec(*received_packet, &recovered_packets_);
       last_recovered_extension_map = &received_packet->extensions;
+      num_recovered_packets += decode_result.num_recovered_packets;
     }
   }
 
+  if (num_recovered_packets == 0) {
+    return;
+  }
+
   // Send any recovered media packets to VCM.
   for (const auto& recovered_packet : recovered_packets_) {
     if (recovered_packet->returned) {