NetEq: Flush and reset if the speech and cng sample rates mismatch
If a CNG packet is received first, followed by a speech packet with
another sample rate, NetEq should treat this as a change of codec, flush
out the CNG packet and reset the sample rate to that of the speech
packet.
BUG=webrtc:5447
NOTRY=True
Review-Url: https://codereview.webrtc.org/2307493002
Cr-Commit-Position: refs/heads/master@{#14032}
diff --git a/webrtc/modules/audio_coding/neteq/packet_buffer.cc b/webrtc/modules/audio_coding/neteq/packet_buffer.cc
index 0e512b6..ba469a6 100644
--- a/webrtc/modules/audio_coding/neteq/packet_buffer.cc
+++ b/webrtc/modules/audio_coding/neteq/packet_buffer.cc
@@ -22,7 +22,7 @@
#include "webrtc/modules/audio_coding/neteq/tick_timer.h"
namespace webrtc {
-
+namespace {
// Predicate used when inserting packets in the buffer list.
// Operator() returns true when |packet| goes before |new_packet|.
class NewTimestampIsLarger {
@@ -38,6 +38,17 @@
const Packet* new_packet_;
};
+// Returns true if both payload types are known to the decoder database, and
+// have the same sample rate.
+bool EqualSampleRates(uint8_t pt1,
+ uint8_t pt2,
+ const DecoderDatabase& decoder_database) {
+ auto di1 = decoder_database.GetDecoderInfo(pt1);
+ auto di2 = decoder_database.GetDecoderInfo(pt2);
+ return di1 && di2 && di1->SampleRateHz() == di2->SampleRateHz();
+}
+} // namespace
+
PacketBuffer::PacketBuffer(size_t max_number_of_packets,
const TickTimer* tick_timer)
: max_number_of_packets_(max_number_of_packets), tick_timer_(tick_timer) {}
@@ -126,8 +137,12 @@
rtc::Optional<uint8_t>(packet->header.payloadType);
} else if (!decoder_database.IsDtmf(packet->header.payloadType)) {
// This must be speech.
- if (*current_rtp_payload_type &&
- **current_rtp_payload_type != packet->header.payloadType) {
+ if ((*current_rtp_payload_type &&
+ **current_rtp_payload_type != packet->header.payloadType) ||
+ (*current_cng_rtp_payload_type &&
+ !EqualSampleRates(packet->header.payloadType,
+ **current_cng_rtp_payload_type,
+ decoder_database))) {
*current_cng_rtp_payload_type = rtc::Optional<uint8_t>();
Flush();
flushed = true;