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 724bba52d6..634f14d370 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 @@ AudioEncoder::EncodedInfo AudioEncoderCopyRed::EncodeImpl( 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 8161931a7a..20d85a1d15 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 @@ TEST_F(AudioEncoderCopyRedTest, CheckPayloadSizes3) { } } +// 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_;