audio: fix handling of RED packets where the primary encoding is too large
by falling back to the primary encoding. This can happen with
opus stereo packets at the maximum bitrate which results in
1276 encoded bytes.
BUG=chromium:1470261
Change-Id: I3fd9bb30773963a519bbb5da44fe71db5dec2bd7
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/315141
Commit-Queue: Henrik Lundin <henrik.lundin@webrtc.org>
Commit-Queue: Philipp Hancke <phancke@microsoft.com>
Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40524}
diff --git a/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc b/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc
index 724bba5..634f14d 100644
--- a/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc
+++ b/modules/audio_coding/codecs/red/audio_encoder_copy_red.cc
@@ -104,7 +104,14 @@
RTC_CHECK(info.redundant.empty()) << "Cannot use nested redundant encoders.";
RTC_DCHECK_EQ(primary_encoded_.size(), info.encoded_bytes);
- if (info.encoded_bytes == 0 || info.encoded_bytes >= kRedMaxPacketSize) {
+ if (info.encoded_bytes == 0) {
+ return info;
+ }
+ if (info.encoded_bytes >= kRedMaxPacketSize) {
+ // Fallback to the primary encoding if the encoded size is more than
+ // what RED can encode as redundancy (1024 bytes). This can happen with
+ // Opus stereo at the highest bitrate which consumes up to 1276 bytes.
+ encoded->AppendData(primary_encoded_);
return info;
}
RTC_DCHECK_GT(max_packet_length_, info.encoded_bytes);
diff --git a/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc b/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc
index 8161931..20d85a1 100644
--- a/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc
+++ b/modules/audio_coding/codecs/red/audio_encoder_copy_red_unittest.cc
@@ -315,6 +315,23 @@
}
}
+// Checks that packets encoded larger than REDs 1024 maximum are returned as-is.
+TEST_F(AudioEncoderCopyRedTest, VeryLargePacket) {
+ AudioEncoder::EncodedInfo info;
+ info.payload_type = 63;
+ info.encoded_bytes =
+ 1111; // Must be > 1024 which is the maximum size encodable by RED.
+ info.encoded_timestamp = timestamp_;
+
+ EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
+ .WillOnce(Invoke(MockAudioEncoder::FakeEncoding(info)));
+
+ Encode();
+ ASSERT_EQ(0u, encoded_info_.redundant.size());
+ ASSERT_EQ(info.encoded_bytes, encoded_info_.encoded_bytes);
+ ASSERT_EQ(info.payload_type, encoded_info_.payload_type);
+}
+
// Checks that the correct timestamps are returned.
TEST_F(AudioEncoderCopyRedTest, CheckTimestamps) {
uint32_t primary_timestamp = timestamp_;