Add NetEq API to get info about the current decoder.

This is currenly tracked in both AcmReceiver and NetEq. Adding this API
enables us to have it in just one place.

Bug: None
Change-Id: Ia537f87f36b0aedf19c00a57bd6cec4425a49df1
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/360743
Commit-Queue: Jakob Ivarsson‎ <jakobi@webrtc.org>
Reviewed-by: Tomas Lundqvist <tomasl@google.com>
Cr-Commit-Position: refs/heads/main@{#42872}
This commit is contained in:
Jakob Ivarsson 2024-08-27 14:31:41 +00:00 committed by WebRTC LUCI CQ
parent c22a1ae9a1
commit b6046aece2
4 changed files with 46 additions and 10 deletions

View File

@ -176,6 +176,7 @@ class NetEq {
// Return type for GetDecoderFormat.
struct DecoderFormat {
int payload_type;
int sample_rate_hz;
int num_channels;
SdpAudioFormat sdp_format;
@ -300,6 +301,11 @@ class NetEq {
virtual absl::optional<DecoderFormat> GetDecoderFormat(
int payload_type) const = 0;
// Returns info for the most recently used decoder.
virtual absl::optional<DecoderFormat> GetCurrentDecoderFormat() const {
return absl::nullopt;
}
// Flushes both the packet buffer and the sync buffer.
virtual void FlushBuffers() = 0;

View File

@ -377,20 +377,34 @@ int NetEqImpl::last_output_sample_rate_hz() const {
absl::optional<NetEq::DecoderFormat> NetEqImpl::GetDecoderFormat(
int payload_type) const {
MutexLock lock(&mutex_);
return GetDecoderFormatInternal(payload_type);
}
absl::optional<NetEq::DecoderFormat> NetEqImpl::GetDecoderFormatInternal(
int payload_type) const {
const DecoderDatabase::DecoderInfo* const di =
decoder_database_->GetDecoderInfo(payload_type);
if (di) {
const AudioDecoder* const decoder = di->GetDecoder();
// TODO(kwiberg): Why the special case for RED?
return DecoderFormat{
/*sample_rate_hz=*/di->IsRed() ? 8000 : di->SampleRateHz(),
/*num_channels=*/
decoder ? rtc::dchecked_cast<int>(decoder->Channels()) : 1,
/*sdp_format=*/di->GetFormat()};
} else {
if (di == nullptr) {
// Payload type not registered.
return absl::nullopt;
}
const AudioDecoder* const decoder = di->GetDecoder();
// TODO(kwiberg): Why the special case for RED?
return DecoderFormat{
/*payload_type=*/payload_type,
/*sample_rate_hz=*/di->IsRed() ? 8000 : di->SampleRateHz(),
/*num_channels=*/
decoder ? rtc::dchecked_cast<int>(decoder->Channels()) : 1,
/*sdp_format=*/di->GetFormat()};
}
absl::optional<NetEq::DecoderFormat> NetEqImpl::GetCurrentDecoderFormat()
const {
MutexLock lock(&mutex_);
if (!current_rtp_payload_type_.has_value()) {
return absl::nullopt;
}
return GetDecoderFormatInternal(*current_rtp_payload_type_);
}
void NetEqImpl::FlushBuffers() {

View File

@ -180,6 +180,8 @@ class NetEqImpl : public webrtc::NetEq {
absl::optional<DecoderFormat> GetDecoderFormat(
int payload_type) const override;
absl::optional<DecoderFormat> GetCurrentDecoderFormat() const override;
// Flushes both the packet buffer and the sync buffer.
void FlushBuffers() override;
@ -340,6 +342,9 @@ class NetEqImpl : public webrtc::NetEq {
NetEqController::PacketArrivedInfo ToPacketArrivedInfo(
const Packet& packet) const RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
absl::optional<DecoderFormat> GetDecoderFormatInternal(int payload_type) const
RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
const Environment env_;
mutable Mutex mutex_;

View File

@ -1734,16 +1734,28 @@ TEST_F(NetEqImplTest, InsertPacketChangePayloadType) {
header.timestamp = 1234;
uint8_t payload[160] = {0};
absl::optional<NetEq::DecoderFormat> decoder =
neteq_->GetCurrentDecoderFormat();
EXPECT_FALSE(decoder.has_value());
EXPECT_EQ(neteq_->InsertPacket(header, payload,
/*receive_time=*/clock_.CurrentTime()),
NetEq::kOK);
EXPECT_EQ(neteq_->GetLifetimeStatistics().packets_discarded, 0u);
decoder = neteq_->GetCurrentDecoderFormat();
ASSERT_TRUE(decoder.has_value());
EXPECT_EQ(decoder->payload_type, kPcmuPayloadType);
EXPECT_EQ(decoder->sdp_format.name, "pcmu");
header.payloadType = kPcmaPayloadType;
header.timestamp += 80;
EXPECT_EQ(neteq_->InsertPacket(header, payload,
/*receive_time=*/clock_.CurrentTime()),
NetEq::kOK);
decoder = neteq_->GetCurrentDecoderFormat();
ASSERT_TRUE(decoder.has_value());
EXPECT_EQ(decoder->payload_type, kPcmaPayloadType);
EXPECT_EQ(decoder->sdp_format.name, "pcma");
// The previous packet should be discarded since the codec changed.
EXPECT_EQ(neteq_->GetLifetimeStatistics().packets_discarded, 1u);
@ -1753,7 +1765,6 @@ TEST_F(NetEqImplTest, InsertPacketChangePayloadType) {
EXPECT_EQ(neteq_->GetAudio(&audio_frame, &muted), NetEq::kOK);
EXPECT_EQ(audio_frame.sample_rate_hz(), 8000);
EXPECT_EQ(audio_frame.speech_type_, AudioFrame::SpeechType::kNormalSpeech);
// TODO(jakobi): check active decoder.
}
class Decoder120ms : public AudioDecoder {