In ChannelReceive, use AcmReceiver directly, not AudioCodingModule

Bug: webrtc:9801
Change-Id: I02d76bc89c363247c8dc782db316a9f87a2b93ec
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/111504
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Henrik Lundin <henrik.lundin@webrtc.org>
Commit-Queue: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28766}
This commit is contained in:
Niels Möller 2019-07-30 15:15:59 +02:00 committed by Commit Bot
parent e80885a89c
commit ed44f5464a
5 changed files with 69 additions and 62 deletions

View File

@ -59,6 +59,7 @@ rtc_static_library("audio") {
"../logging:rtc_event_log_api", "../logging:rtc_event_log_api",
"../logging:rtc_stream_config", "../logging:rtc_stream_config",
"../modules/audio_coding", "../modules/audio_coding",
"../modules/audio_coding:audio_coding_module_typedefs",
"../modules/audio_coding:audio_encoder_cng", "../modules/audio_coding:audio_encoder_cng",
"../modules/audio_coding:audio_network_adaptor_config", "../modules/audio_coding:audio_network_adaptor_config",
"../modules/audio_device", "../modules/audio_device",

View File

@ -23,8 +23,8 @@
#include "audio/utility/audio_frame_operations.h" #include "audio/utility/audio_frame_operations.h"
#include "logging/rtc_event_log/events/rtc_event_audio_playout.h" #include "logging/rtc_event_log/events/rtc_event_audio_playout.h"
#include "logging/rtc_event_log/rtc_event_log.h" #include "logging/rtc_event_log/rtc_event_log.h"
#include "modules/audio_coding/acm2/acm_receiver.h"
#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h" #include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
#include "modules/audio_coding/include/audio_coding_module.h"
#include "modules/audio_device/include/audio_device.h" #include "modules/audio_device/include/audio_device.h"
#include "modules/pacing/packet_router.h" #include "modules/pacing/packet_router.h"
#include "modules/rtp_rtcp/include/receive_statistics.h" #include "modules/rtp_rtcp/include/receive_statistics.h"
@ -77,6 +77,21 @@ RTPHeader CreateRTPHeaderForMediaTransportFrame(
return rtp_header; return rtp_header;
} }
AudioCodingModule::Config AcmConfig(
rtc::scoped_refptr<AudioDecoderFactory> decoder_factory,
absl::optional<AudioCodecPairId> codec_pair_id,
size_t jitter_buffer_max_packets,
bool jitter_buffer_fast_playout) {
AudioCodingModule::Config acm_config;
acm_config.decoder_factory = decoder_factory;
acm_config.neteq_config.codec_pair_id = codec_pair_id;
acm_config.neteq_config.max_packets_in_buffer = jitter_buffer_max_packets;
acm_config.neteq_config.enable_fast_accelerate = jitter_buffer_fast_playout;
acm_config.neteq_config.enable_muted_state = true;
return acm_config;
}
class ChannelReceive : public ChannelReceiveInterface, class ChannelReceive : public ChannelReceiveInterface,
public MediaTransportAudioSinkInterface { public MediaTransportAudioSinkInterface {
public: public:
@ -167,7 +182,7 @@ class ChannelReceive : public ChannelReceiveInterface,
} }
private: private:
bool ReceivePacket(const uint8_t* packet, void ReceivePacket(const uint8_t* packet,
size_t packet_length, size_t packet_length,
const RTPHeader& header); const RTPHeader& header);
int ResendPackets(const uint16_t* sequence_numbers, int length); int ResendPackets(const uint16_t* sequence_numbers, int length);
@ -180,9 +195,8 @@ class ChannelReceive : public ChannelReceiveInterface,
void OnData(uint64_t channel_id, void OnData(uint64_t channel_id,
MediaTransportEncodedAudioFrame frame) override; MediaTransportEncodedAudioFrame frame) override;
int32_t OnReceivedPayloadData(const uint8_t* payloadData, void OnReceivedPayloadData(rtc::ArrayView<const uint8_t> payload,
size_t payloadSize, const RTPHeader& rtpHeader);
const RTPHeader& rtpHeader);
bool Playing() const { bool Playing() const {
rtc::CritScope lock(&playing_lock_); rtc::CritScope lock(&playing_lock_);
@ -224,7 +238,8 @@ class ChannelReceive : public ChannelReceiveInterface,
absl::optional<int64_t> last_received_rtp_system_time_ms_ absl::optional<int64_t> last_received_rtp_system_time_ms_
RTC_GUARDED_BY(&sync_info_lock_); RTC_GUARDED_BY(&sync_info_lock_);
std::unique_ptr<AudioCodingModule> audio_coding_; // The AcmReceiver is thread safe, using its own lock.
acm2::AcmReceiver acm_receiver_;
AudioSinkInterface* audio_sink_ = nullptr; AudioSinkInterface* audio_sink_ = nullptr;
AudioLevel _outputAudioLevel; AudioLevel _outputAudioLevel;
@ -269,36 +284,34 @@ class ChannelReceive : public ChannelReceiveInterface,
const bool use_standard_bytes_stats_; const bool use_standard_bytes_stats_;
}; };
int32_t ChannelReceive::OnReceivedPayloadData(const uint8_t* payloadData, void ChannelReceive::OnReceivedPayloadData(
size_t payloadSize, rtc::ArrayView<const uint8_t> payload,
const RTPHeader& rtp_header) { const RTPHeader& rtpHeader) {
// We should not be receiving any RTP packets if media_transport is set. // We should not be receiving any RTP packets if media_transport is set.
RTC_CHECK(!media_transport()); RTC_CHECK(!media_transport());
if (!Playing()) { if (!Playing()) {
// Avoid inserting into NetEQ when we are not playing. Count the // Avoid inserting into NetEQ when we are not playing. Count the
// packet as discarded. // packet as discarded.
return 0; return;
} }
// Push the incoming payload (parsed and ready for decoding) into the ACM // Push the incoming payload (parsed and ready for decoding) into the ACM
if (audio_coding_->IncomingPacket(payloadData, payloadSize, rtp_header) != if (acm_receiver_.InsertPacket(rtpHeader, payload) != 0) {
0) {
RTC_DLOG(LS_ERROR) << "ChannelReceive::OnReceivedPayloadData() unable to " RTC_DLOG(LS_ERROR) << "ChannelReceive::OnReceivedPayloadData() unable to "
"push data to the ACM"; "push data to the ACM";
return -1; return;
} }
int64_t round_trip_time = 0; int64_t round_trip_time = 0;
_rtpRtcpModule->RTT(remote_ssrc_, &round_trip_time, NULL, NULL, NULL); _rtpRtcpModule->RTT(remote_ssrc_, &round_trip_time, NULL, NULL, NULL);
std::vector<uint16_t> nack_list = audio_coding_->GetNackList(round_trip_time); std::vector<uint16_t> nack_list = acm_receiver_.GetNackList(round_trip_time);
if (!nack_list.empty()) { if (!nack_list.empty()) {
// Can't use nack_list.data() since it's not supported by all // Can't use nack_list.data() since it's not supported by all
// compilers. // compilers.
ResendPackets(&(nack_list[0]), static_cast<int>(nack_list.size())); ResendPackets(&(nack_list[0]), static_cast<int>(nack_list.size()));
} }
return 0;
} }
// MediaTransportAudioSinkInterface override. // MediaTransportAudioSinkInterface override.
@ -313,9 +326,9 @@ void ChannelReceive::OnData(uint64_t channel_id,
} }
// Send encoded audio frame to Decoder / NetEq. // Send encoded audio frame to Decoder / NetEq.
if (audio_coding_->IncomingPacket( if (acm_receiver_.InsertPacket(
frame.encoded_data().data(), frame.encoded_data().size(), CreateRTPHeaderForMediaTransportFrame(frame, channel_id),
CreateRTPHeaderForMediaTransportFrame(frame, channel_id)) != 0) { frame.encoded_data()) != 0) {
RTC_DLOG(LS_ERROR) << "ChannelReceive::OnData: unable to " RTC_DLOG(LS_ERROR) << "ChannelReceive::OnData: unable to "
"push data to the ACM"; "push data to the ACM";
} }
@ -331,8 +344,8 @@ AudioMixer::Source::AudioFrameInfo ChannelReceive::GetAudioFrameWithInfo(
// Get 10ms raw PCM data from the ACM (mixer limits output frequency) // Get 10ms raw PCM data from the ACM (mixer limits output frequency)
bool muted; bool muted;
if (audio_coding_->PlayoutData10Ms(audio_frame->sample_rate_hz_, audio_frame, if (acm_receiver_.GetAudio(audio_frame->sample_rate_hz_, audio_frame,
&muted) == -1) { &muted) == -1) {
RTC_DLOG(LS_ERROR) RTC_DLOG(LS_ERROR)
<< "ChannelReceive::GetAudioFrame() PlayoutData10Ms() failed!"; << "ChannelReceive::GetAudioFrame() PlayoutData10Ms() failed!";
// In all likelihood, the audio in this frame is garbage. We return an // In all likelihood, the audio in this frame is garbage. We return an
@ -414,8 +427,8 @@ AudioMixer::Source::AudioFrameInfo ChannelReceive::GetAudioFrameWithInfo(
{ {
RTC_HISTOGRAM_COUNTS_1000("WebRTC.Audio.TargetJitterBufferDelayMs", RTC_HISTOGRAM_COUNTS_1000("WebRTC.Audio.TargetJitterBufferDelayMs",
audio_coding_->TargetDelayMs()); acm_receiver_.TargetDelayMs());
const int jitter_buffer_delay = audio_coding_->FilteredCurrentDelayMs(); const int jitter_buffer_delay = acm_receiver_.FilteredCurrentDelayMs();
rtc::CritScope lock(&video_sync_lock_); rtc::CritScope lock(&video_sync_lock_);
RTC_HISTOGRAM_COUNTS_1000("WebRTC.Audio.ReceiverDelayEstimateMs", RTC_HISTOGRAM_COUNTS_1000("WebRTC.Audio.ReceiverDelayEstimateMs",
jitter_buffer_delay + playout_delay_ms_); jitter_buffer_delay + playout_delay_ms_);
@ -432,8 +445,8 @@ AudioMixer::Source::AudioFrameInfo ChannelReceive::GetAudioFrameWithInfo(
int ChannelReceive::PreferredSampleRate() const { int ChannelReceive::PreferredSampleRate() const {
RTC_DCHECK_RUNS_SERIALIZED(&audio_thread_race_checker_); RTC_DCHECK_RUNS_SERIALIZED(&audio_thread_race_checker_);
// Return the bigger of playout and receive frequency in the ACM. // Return the bigger of playout and receive frequency in the ACM.
return std::max(audio_coding_->ReceiveFrequency(), return std::max(acm_receiver_.last_packet_sample_rate_hz().value_or(0),
audio_coding_->PlayoutFrequency()); acm_receiver_.last_output_sample_rate_hz());
} }
ChannelReceive::ChannelReceive( ChannelReceive::ChannelReceive(
@ -455,6 +468,10 @@ ChannelReceive::ChannelReceive(
: event_log_(rtc_event_log), : event_log_(rtc_event_log),
rtp_receive_statistics_(ReceiveStatistics::Create(clock)), rtp_receive_statistics_(ReceiveStatistics::Create(clock)),
remote_ssrc_(remote_ssrc), remote_ssrc_(remote_ssrc),
acm_receiver_(AcmConfig(decoder_factory,
codec_pair_id,
jitter_buffer_max_packets,
jitter_buffer_fast_playout)),
_outputAudioLevel(), _outputAudioLevel(),
ntp_estimator_(clock), ntp_estimator_(clock),
playout_timestamp_rtp_(0), playout_timestamp_rtp_(0),
@ -476,16 +493,11 @@ ChannelReceive::ChannelReceive(
RTC_DCHECK(module_process_thread); RTC_DCHECK(module_process_thread);
RTC_DCHECK(audio_device_module); RTC_DCHECK(audio_device_module);
AudioCodingModule::Config acm_config;
acm_config.decoder_factory = decoder_factory; acm_receiver_.ResetInitialDelay();
acm_config.neteq_config.codec_pair_id = codec_pair_id; acm_receiver_.SetMinimumDelay(0);
acm_config.neteq_config.max_packets_in_buffer = jitter_buffer_max_packets; acm_receiver_.SetMaximumDelay(0);
acm_config.neteq_config.enable_fast_accelerate = jitter_buffer_fast_playout; acm_receiver_.FlushBuffers();
acm_config.neteq_config.min_delay_ms = jitter_buffer_min_delay_ms;
acm_config.neteq_config.enable_muted_state = true;
acm_config.neteq_config.enable_rtx_handling =
jitter_buffer_enable_rtx_handling;
audio_coding_.reset(AudioCodingModule::Create(acm_config));
_outputAudioLevel.ResetLevelFullRange(); _outputAudioLevel.ResetLevelFullRange();
@ -527,9 +539,6 @@ ChannelReceive::~ChannelReceive() {
StopPlayout(); StopPlayout();
int error = audio_coding_->RegisterTransportCallback(NULL);
RTC_DCHECK_EQ(0, error);
if (_moduleProcessThreadPtr) if (_moduleProcessThreadPtr)
_moduleProcessThreadPtr->DeRegisterModule(_rtpRtcpModule.get()); _moduleProcessThreadPtr->DeRegisterModule(_rtpRtcpModule.get());
} }
@ -556,7 +565,7 @@ void ChannelReceive::StopPlayout() {
absl::optional<std::pair<int, SdpAudioFormat>> ChannelReceive::GetReceiveCodec() absl::optional<std::pair<int, SdpAudioFormat>> ChannelReceive::GetReceiveCodec()
const { const {
RTC_DCHECK(worker_thread_checker_.IsCurrent()); RTC_DCHECK(worker_thread_checker_.IsCurrent());
return audio_coding_->ReceiveCodec(); return acm_receiver_.LastDecoder();
} }
void ChannelReceive::SetReceiveCodecs( void ChannelReceive::SetReceiveCodecs(
@ -566,7 +575,7 @@ void ChannelReceive::SetReceiveCodecs(
RTC_DCHECK_GE(kv.second.clockrate_hz, 1000); RTC_DCHECK_GE(kv.second.clockrate_hz, 1000);
payload_type_frequencies_[kv.first] = kv.second.clockrate_hz; payload_type_frequencies_[kv.first] = kv.second.clockrate_hz;
} }
audio_coding_->SetReceiveCodecs(codecs); acm_receiver_.SetCodecs(codecs);
} }
// May be called on either worker thread or network thread. // May be called on either worker thread or network thread.
@ -597,7 +606,7 @@ void ChannelReceive::OnRtpPacket(const RtpPacketReceived& packet) {
ReceivePacket(packet_copy.data(), packet_copy.size(), header); ReceivePacket(packet_copy.data(), packet_copy.size(), header);
} }
bool ChannelReceive::ReceivePacket(const uint8_t* packet, void ChannelReceive::ReceivePacket(const uint8_t* packet,
size_t packet_length, size_t packet_length,
const RTPHeader& header) { const RTPHeader& header) {
const uint8_t* payload = packet + header.headerLength; const uint8_t* payload = packet + header.headerLength;
@ -638,10 +647,8 @@ bool ChannelReceive::ReceivePacket(const uint8_t* packet,
payload_data_length = 0; payload_data_length = 0;
} }
if (payload_data_length == 0) { OnReceivedPayloadData(
return OnReceivedPayloadData(nullptr, 0, header); rtc::ArrayView<const uint8_t>(payload, payload_data_length), header);
}
return OnReceivedPayloadData(payload, payload_data_length, header);
} }
// May be called on either worker thread or network thread. // May be called on either worker thread or network thread.
@ -770,13 +777,12 @@ void ChannelReceive::SetNACKStatus(bool enable, int max_packets) {
RTC_DCHECK(worker_thread_checker_.IsCurrent()); RTC_DCHECK(worker_thread_checker_.IsCurrent());
// None of these functions can fail. // None of these functions can fail.
if (enable) { if (enable) {
rtp_receive_statistics_->SetMaxReorderingThreshold(remote_ssrc_, rtp_receive_statistics_->SetMaxReorderingThreshold(max_packets);
max_packets); acm_receiver_.EnableNack(max_packets);
audio_coding_->EnableNack(max_packets);
} else { } else {
rtp_receive_statistics_->SetMaxReorderingThreshold( rtp_receive_statistics_->SetMaxReorderingThreshold(
remote_ssrc_, kDefaultMaxReorderingThreshold); kDefaultMaxReorderingThreshold);
audio_coding_->DisableNack(); acm_receiver_.DisableNack();
} }
} }
@ -796,15 +802,14 @@ void ChannelReceive::SetAssociatedSendChannel(
NetworkStatistics ChannelReceive::GetNetworkStatistics() const { NetworkStatistics ChannelReceive::GetNetworkStatistics() const {
RTC_DCHECK(worker_thread_checker_.IsCurrent()); RTC_DCHECK(worker_thread_checker_.IsCurrent());
NetworkStatistics stats; NetworkStatistics stats;
int error = audio_coding_->GetNetworkStatistics(&stats); acm_receiver_.GetNetworkStatistics(&stats);
RTC_DCHECK_EQ(0, error);
return stats; return stats;
} }
AudioDecodingCallStats ChannelReceive::GetDecodingCallStatistics() const { AudioDecodingCallStats ChannelReceive::GetDecodingCallStatistics() const {
RTC_DCHECK(worker_thread_checker_.IsCurrent()); RTC_DCHECK(worker_thread_checker_.IsCurrent());
AudioDecodingCallStats stats; AudioDecodingCallStats stats;
audio_coding_->GetDecodingCallStatistics(&stats); acm_receiver_.GetDecodingCallStatistics(&stats);
return stats; return stats;
} }
@ -812,7 +817,7 @@ uint32_t ChannelReceive::GetDelayEstimate() const {
RTC_DCHECK(worker_thread_checker_.IsCurrent() || RTC_DCHECK(worker_thread_checker_.IsCurrent() ||
module_process_thread_checker_.IsCurrent()); module_process_thread_checker_.IsCurrent());
rtc::CritScope lock(&video_sync_lock_); rtc::CritScope lock(&video_sync_lock_);
return audio_coding_->FilteredCurrentDelayMs() + playout_delay_ms_; return acm_receiver_.FilteredCurrentDelayMs() + playout_delay_ms_;
} }
void ChannelReceive::SetMinimumPlayoutDelay(int delay_ms) { void ChannelReceive::SetMinimumPlayoutDelay(int delay_ms) {
@ -821,7 +826,7 @@ void ChannelReceive::SetMinimumPlayoutDelay(int delay_ms) {
// close as possible, instead of failing. // close as possible, instead of failing.
delay_ms = rtc::SafeClamp(delay_ms, kVoiceEngineMinMinPlayoutDelayMs, delay_ms = rtc::SafeClamp(delay_ms, kVoiceEngineMinMinPlayoutDelayMs,
kVoiceEngineMaxMinPlayoutDelayMs); kVoiceEngineMaxMinPlayoutDelayMs);
if (audio_coding_->SetMinimumPlayoutDelay(delay_ms) != 0) { if (acm_receiver_.SetMinimumDelay(delay_ms) != 0) {
RTC_DLOG(LS_ERROR) RTC_DLOG(LS_ERROR)
<< "SetMinimumPlayoutDelay() failed to set min playout delay"; << "SetMinimumPlayoutDelay() failed to set min playout delay";
} }
@ -836,11 +841,11 @@ uint32_t ChannelReceive::GetPlayoutTimestamp() const {
} }
bool ChannelReceive::SetBaseMinimumPlayoutDelayMs(int delay_ms) { bool ChannelReceive::SetBaseMinimumPlayoutDelayMs(int delay_ms) {
return audio_coding_->SetBaseMinimumPlayoutDelayMs(delay_ms); return acm_receiver_.SetBaseMinimumDelayMs(delay_ms);
} }
int ChannelReceive::GetBaseMinimumPlayoutDelayMs() const { int ChannelReceive::GetBaseMinimumPlayoutDelayMs() const {
return audio_coding_->GetBaseMinimumPlayoutDelayMs(); return acm_receiver_.GetBaseMinimumDelayMs();
} }
absl::optional<Syncable::Info> ChannelReceive::GetSyncInfo() const { absl::optional<Syncable::Info> ChannelReceive::GetSyncInfo() const {
@ -863,7 +868,7 @@ absl::optional<Syncable::Info> ChannelReceive::GetSyncInfo() const {
} }
void ChannelReceive::UpdatePlayoutTimestamp(bool rtcp) { void ChannelReceive::UpdatePlayoutTimestamp(bool rtcp) {
jitter_buffer_playout_timestamp_ = audio_coding_->PlayoutTimestamp(); jitter_buffer_playout_timestamp_ = acm_receiver_.GetPlayoutTimestamp();
if (!jitter_buffer_playout_timestamp_) { if (!jitter_buffer_playout_timestamp_) {
// This can happen if this channel has not received any RTP packets. In // This can happen if this channel has not received any RTP packets. In
@ -895,14 +900,14 @@ void ChannelReceive::UpdatePlayoutTimestamp(bool rtcp) {
} }
int ChannelReceive::GetRtpTimestampRateHz() const { int ChannelReceive::GetRtpTimestampRateHz() const {
const auto decoder = audio_coding_->ReceiveCodec(); const auto decoder = acm_receiver_.LastDecoder();
// Default to the playout frequency if we've not gotten any packets yet. // Default to the playout frequency if we've not gotten any packets yet.
// TODO(ossu): Zero clockrate can only happen if we've added an external // TODO(ossu): Zero clockrate can only happen if we've added an external
// decoder for a format we don't support internally. Remove once that way of // decoder for a format we don't support internally. Remove once that way of
// adding decoders is gone! // adding decoders is gone!
return (decoder && decoder->second.clockrate_hz != 0) return (decoder && decoder->second.clockrate_hz != 0)
? decoder->second.clockrate_hz ? decoder->second.clockrate_hz
: audio_coding_->PlayoutFrequency(); : acm_receiver_.last_output_sample_rate_hz();
} }
int64_t ChannelReceive::GetRTT() const { int64_t ChannelReceive::GetRTT() const {

View File

@ -27,7 +27,8 @@
#include "api/rtp_receiver_interface.h" #include "api/rtp_receiver_interface.h"
#include "call/rtp_packet_sink_interface.h" #include "call/rtp_packet_sink_interface.h"
#include "call/syncable.h" #include "call/syncable.h"
#include "modules/audio_coding/include/audio_coding_module.h" #include "modules/audio_coding/include/audio_coding_module_typedefs.h"
#include "system_wrappers/include/clock.h"
// TODO(solenberg, nisse): This file contains a few NOLINT marks, to silence // TODO(solenberg, nisse): This file contains a few NOLINT marks, to silence
// warnings about use of unsigned short. // warnings about use of unsigned short.

View File

@ -228,7 +228,7 @@ absl::optional<std::pair<int, SdpAudioFormat>> AcmReceiver::LastDecoder()
return last_decoder_; return last_decoder_;
} }
void AcmReceiver::GetNetworkStatistics(NetworkStatistics* acm_stat) { void AcmReceiver::GetNetworkStatistics(NetworkStatistics* acm_stat) const {
NetEqNetworkStatistics neteq_stat; NetEqNetworkStatistics neteq_stat;
// NetEq function always returns zero, so we don't check the return value. // NetEq function always returns zero, so we don't check the return value.
neteq_->NetworkStatistics(&neteq_stat); neteq_->NetworkStatistics(&neteq_stat);

View File

@ -138,7 +138,7 @@ class AcmReceiver {
// Output: // Output:
// - statistics : The current network statistics. // - statistics : The current network statistics.
// //
void GetNetworkStatistics(NetworkStatistics* statistics); void GetNetworkStatistics(NetworkStatistics* statistics) const;
// //
// Flushes the NetEq packet and speech buffers. // Flushes the NetEq packet and speech buffers.