2015-04-29 15:24:01 +02:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* Use of this source code is governed by a BSD-style license
|
|
|
|
|
* that can be found in the LICENSE file in the root of the source
|
|
|
|
|
* tree. An additional intellectual property rights grant can be found
|
|
|
|
|
* in the file PATENTS. All contributing project authors may
|
|
|
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
|
|
|
*/
|
|
|
|
|
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "audio/audio_receive_stream.h"
|
2015-04-29 15:24:01 +02:00
|
|
|
|
|
|
|
|
#include <string>
|
2015-12-12 01:37:01 +01:00
|
|
|
#include <utility>
|
2015-04-29 15:24:01 +02:00
|
|
|
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "api/call/audio_sink.h"
|
|
|
|
|
#include "audio/audio_send_stream.h"
|
|
|
|
|
#include "audio/audio_state.h"
|
2018-01-17 11:18:31 +01:00
|
|
|
#include "audio/channel_proxy.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "audio/conversion.h"
|
|
|
|
|
#include "call/rtp_stream_receiver_controller_interface.h"
|
|
|
|
|
#include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
|
|
|
|
#include "modules/rtp_rtcp/include/rtp_receiver.h"
|
|
|
|
|
#include "modules/rtp_rtcp/include/rtp_rtcp.h"
|
|
|
|
|
#include "rtc_base/checks.h"
|
|
|
|
|
#include "rtc_base/logging.h"
|
Adding a new string utility class: SimpleStringBuilder.
This is a fairly minimalistic string building class that
can be used instead of stringstream, which is discouraged
but tempting to use due to its convenient interface and
familiarity for anyone using our logging macros.
As a starter, I'm changing the string building code in
ReceiveStatisticsProxy and SendStatisticsProxy from using
stringstream and using SimpleStringBuilder instead.
In the case of SimpleStringBuilder, there's a single allocation,
it's done on the stack (fast), and minimal code is required for
each concatenation. The developer is responsible for ensuring
that the buffer size is adequate but the class won't overflow
the buffer. In dcheck-enabled builds, a check will go off if
we run out of buffer space.
As part of using SimpleStringBuilder for a small part of
rtc::LogMessage, a few more changes were made:
- SimpleStringBuilder is used for formatting errors instead of ostringstream.
- A new 'noop' state has been introduced for log messages that will be dropped.
- Use a static (singleton) noop ostream object for noop logging messages
instead of building up an actual ostringstream object that will be dropped.
- Add a LogMessageForTest class for better state inspection/testing.
- Fix benign bug in LogTest.Perf, change the test to not use File IO and
always enable it.
- Ensure that minimal work is done for noop messages.
- Remove dependency on rtc::Thread.
- Add tests for the extra_ field, correctly parsed paths and noop handling.
Bug: webrtc:8529, webrtc:4364, webrtc:8933
Change-Id: Ifa258c135135945e4560d9e24315f7d96f784acb
Reviewed-on: https://webrtc-review.googlesource.com/55520
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Jonas Olsson <jonasolsson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22203}
2018-02-27 13:51:08 +01:00
|
|
|
#include "rtc_base/strings/string_builder.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "rtc_base/timeutils.h"
|
2015-04-29 15:24:01 +02:00
|
|
|
|
|
|
|
|
namespace webrtc {
|
2016-01-12 13:55:00 +01:00
|
|
|
|
2015-04-29 15:24:01 +02:00
|
|
|
std::string AudioReceiveStream::Config::Rtp::ToString() const {
|
2018-03-08 15:03:23 +01:00
|
|
|
char ss_buf[1024];
|
|
|
|
|
rtc::SimpleStringBuilder ss(ss_buf);
|
2015-04-29 15:24:01 +02:00
|
|
|
ss << "{remote_ssrc: " << remote_ssrc;
|
2015-10-27 03:35:21 -07:00
|
|
|
ss << ", local_ssrc: " << local_ssrc;
|
2016-06-14 12:13:00 -07:00
|
|
|
ss << ", transport_cc: " << (transport_cc ? "on" : "off");
|
|
|
|
|
ss << ", nack: " << nack.ToString();
|
2015-04-29 15:24:01 +02:00
|
|
|
ss << ", extensions: [";
|
|
|
|
|
for (size_t i = 0; i < extensions.size(); ++i) {
|
|
|
|
|
ss << extensions[i].ToString();
|
2015-10-22 10:49:27 +02:00
|
|
|
if (i != extensions.size() - 1) {
|
2015-04-29 15:24:01 +02:00
|
|
|
ss << ", ";
|
2015-10-22 10:49:27 +02:00
|
|
|
}
|
2015-04-29 15:24:01 +02:00
|
|
|
}
|
|
|
|
|
ss << ']';
|
|
|
|
|
ss << '}';
|
|
|
|
|
return ss.str();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string AudioReceiveStream::Config::ToString() const {
|
2018-03-08 15:03:23 +01:00
|
|
|
char ss_buf[1024];
|
|
|
|
|
rtc::SimpleStringBuilder ss(ss_buf);
|
2015-04-29 15:24:01 +02:00
|
|
|
ss << "{rtp: " << rtp.ToString();
|
2015-10-27 03:35:21 -07:00
|
|
|
ss << ", rtcp_send_transport: "
|
2017-02-26 04:18:12 -08:00
|
|
|
<< (rtcp_send_transport ? "(Transport)" : "null");
|
2015-10-22 10:49:27 +02:00
|
|
|
if (!sync_group.empty()) {
|
2015-07-15 08:02:58 -07:00
|
|
|
ss << ", sync_group: " << sync_group;
|
2015-10-22 10:49:27 +02:00
|
|
|
}
|
2015-04-29 15:24:01 +02:00
|
|
|
ss << '}';
|
|
|
|
|
return ss.str();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace internal {
|
2018-01-11 13:52:30 +01:00
|
|
|
namespace {
|
|
|
|
|
std::unique_ptr<voe::ChannelProxy> CreateChannelAndProxy(
|
|
|
|
|
webrtc::AudioState* audio_state,
|
|
|
|
|
ProcessThread* module_process_thread,
|
|
|
|
|
const webrtc::AudioReceiveStream::Config& config) {
|
|
|
|
|
RTC_DCHECK(audio_state);
|
|
|
|
|
internal::AudioState* internal_audio_state =
|
|
|
|
|
static_cast<internal::AudioState*>(audio_state);
|
2018-03-20 19:18:55 +01:00
|
|
|
return std::unique_ptr<voe::ChannelProxy>(
|
|
|
|
|
new voe::ChannelProxy(std::unique_ptr<voe::Channel>(new voe::Channel(
|
|
|
|
|
module_process_thread, internal_audio_state->audio_device_module(),
|
2018-03-26 13:28:26 +02:00
|
|
|
nullptr /* RtcpRttStats */, config.jitter_buffer_max_packets,
|
2018-03-20 19:18:55 +01:00
|
|
|
config.jitter_buffer_fast_accelerate, config.decoder_factory,
|
|
|
|
|
config.codec_pair_id))));
|
2018-01-11 13:52:30 +01:00
|
|
|
}
|
|
|
|
|
} // namespace
|
|
|
|
|
|
2015-04-29 15:24:01 +02:00
|
|
|
AudioReceiveStream::AudioReceiveStream(
|
2017-06-21 01:05:22 -07:00
|
|
|
RtpStreamReceiverControllerInterface* receiver_controller,
|
2016-11-30 03:35:20 -08:00
|
|
|
PacketRouter* packet_router,
|
2018-01-11 13:52:30 +01:00
|
|
|
ProcessThread* module_process_thread,
|
2015-11-06 15:34:49 -08:00
|
|
|
const webrtc::AudioReceiveStream::Config& config,
|
2016-07-04 07:06:55 -07:00
|
|
|
const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
|
|
|
|
|
webrtc::RtcEventLog* event_log)
|
2018-01-11 13:52:30 +01:00
|
|
|
: AudioReceiveStream(receiver_controller,
|
|
|
|
|
packet_router,
|
|
|
|
|
config,
|
|
|
|
|
audio_state,
|
|
|
|
|
event_log,
|
|
|
|
|
CreateChannelAndProxy(audio_state.get(),
|
|
|
|
|
module_process_thread,
|
|
|
|
|
config)) {}
|
|
|
|
|
|
|
|
|
|
AudioReceiveStream::AudioReceiveStream(
|
|
|
|
|
RtpStreamReceiverControllerInterface* receiver_controller,
|
|
|
|
|
PacketRouter* packet_router,
|
|
|
|
|
const webrtc::AudioReceiveStream::Config& config,
|
|
|
|
|
const rtc::scoped_refptr<webrtc::AudioState>& audio_state,
|
|
|
|
|
webrtc::RtcEventLog* event_log,
|
|
|
|
|
std::unique_ptr<voe::ChannelProxy> channel_proxy)
|
|
|
|
|
: audio_state_(audio_state), channel_proxy_(std::move(channel_proxy)) {
|
2018-01-25 10:14:29 +01:00
|
|
|
RTC_LOG(LS_INFO) << "AudioReceiveStream: " << config.rtp.remote_ssrc;
|
2018-01-11 13:52:30 +01:00
|
|
|
RTC_DCHECK(receiver_controller);
|
2016-11-30 03:35:20 -08:00
|
|
|
RTC_DCHECK(packet_router);
|
2018-01-11 13:52:30 +01:00
|
|
|
RTC_DCHECK(config.decoder_factory);
|
|
|
|
|
RTC_DCHECK(audio_state_);
|
|
|
|
|
RTC_DCHECK(channel_proxy_);
|
2015-11-20 09:59:34 -08:00
|
|
|
|
2017-01-31 03:58:40 -08:00
|
|
|
module_process_thread_checker_.DetachFromThread();
|
|
|
|
|
|
2018-01-10 15:17:10 +01:00
|
|
|
channel_proxy_->SetRtcEventLog(event_log);
|
2017-09-29 06:00:28 -07:00
|
|
|
channel_proxy_->RegisterTransport(config.rtcp_send_transport);
|
2017-01-19 07:03:59 -08:00
|
|
|
|
2016-01-12 13:55:00 +01:00
|
|
|
// Configure bandwidth estimation.
|
2016-11-30 03:35:20 -08:00
|
|
|
channel_proxy_->RegisterReceiverCongestionControlObjects(packet_router);
|
2017-06-21 01:05:22 -07:00
|
|
|
|
|
|
|
|
// Register with transport.
|
2018-01-10 15:17:10 +01:00
|
|
|
rtp_stream_receiver_ = receiver_controller->CreateReceiver(
|
2017-06-21 01:05:22 -07:00
|
|
|
config.rtp.remote_ssrc, channel_proxy_.get());
|
2018-01-10 15:17:10 +01:00
|
|
|
|
|
|
|
|
ConfigureStream(this, config, true);
|
2015-04-29 15:24:01 +02:00
|
|
|
}
|
|
|
|
|
|
2015-10-15 05:22:13 -07:00
|
|
|
AudioReceiveStream::~AudioReceiveStream() {
|
2017-01-31 03:58:40 -08:00
|
|
|
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
|
2018-01-25 10:14:29 +01:00
|
|
|
RTC_LOG(LS_INFO) << "~AudioReceiveStream: " << config_.rtp.remote_ssrc;
|
2017-12-18 22:41:03 +01:00
|
|
|
Stop();
|
2016-11-14 11:30:07 -08:00
|
|
|
channel_proxy_->DisassociateSendChannel();
|
2017-09-29 06:00:28 -07:00
|
|
|
channel_proxy_->RegisterTransport(nullptr);
|
2017-03-31 05:44:52 -07:00
|
|
|
channel_proxy_->ResetReceiverCongestionControlObjects();
|
2016-07-04 07:06:55 -07:00
|
|
|
channel_proxy_->SetRtcEventLog(nullptr);
|
2015-10-15 05:22:13 -07:00
|
|
|
}
|
|
|
|
|
|
2018-01-10 15:17:10 +01:00
|
|
|
void AudioReceiveStream::Reconfigure(
|
|
|
|
|
const webrtc::AudioReceiveStream::Config& config) {
|
|
|
|
|
RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
|
|
|
|
|
ConfigureStream(this, config, false);
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-20 09:59:34 -08:00
|
|
|
void AudioReceiveStream::Start() {
|
2017-01-31 03:58:40 -08:00
|
|
|
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
|
2016-11-22 06:42:53 -08:00
|
|
|
if (playing_) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-12-18 22:41:03 +01:00
|
|
|
channel_proxy_->StartPlayout();
|
2016-11-22 06:42:53 -08:00
|
|
|
playing_ = true;
|
2017-12-18 22:41:03 +01:00
|
|
|
audio_state()->AddReceivingStream(this);
|
2015-11-20 09:59:34 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AudioReceiveStream::Stop() {
|
2017-01-31 03:58:40 -08:00
|
|
|
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
|
2016-11-22 06:42:53 -08:00
|
|
|
if (!playing_) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-12-18 22:41:03 +01:00
|
|
|
channel_proxy_->StopPlayout();
|
2016-11-22 06:42:53 -08:00
|
|
|
playing_ = false;
|
2017-12-18 22:41:03 +01:00
|
|
|
audio_state()->RemoveReceivingStream(this);
|
2015-11-20 09:59:34 -08:00
|
|
|
}
|
|
|
|
|
|
2015-06-08 13:04:56 +02:00
|
|
|
webrtc::AudioReceiveStream::Stats AudioReceiveStream::GetStats() const {
|
2017-01-31 03:58:40 -08:00
|
|
|
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
|
2015-10-22 10:49:27 +02:00
|
|
|
webrtc::AudioReceiveStream::Stats stats;
|
|
|
|
|
stats.remote_ssrc = config_.rtp.remote_ssrc;
|
2015-11-27 10:46:42 -08:00
|
|
|
|
|
|
|
|
webrtc::CallStatistics call_stats = channel_proxy_->GetRTCPStatistics();
|
2017-02-06 12:53:57 -08:00
|
|
|
// TODO(solenberg): Don't return here if we can't get the codec - return the
|
|
|
|
|
// stats we *can* get.
|
2015-10-27 03:35:21 -07:00
|
|
|
webrtc::CodecInst codec_inst = {0};
|
2017-02-06 12:53:57 -08:00
|
|
|
if (!channel_proxy_->GetRecCodec(&codec_inst)) {
|
2015-10-22 10:49:27 +02:00
|
|
|
return stats;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-27 03:35:21 -07:00
|
|
|
stats.bytes_rcvd = call_stats.bytesReceived;
|
|
|
|
|
stats.packets_rcvd = call_stats.packetsReceived;
|
|
|
|
|
stats.packets_lost = call_stats.cumulativeLost;
|
|
|
|
|
stats.fraction_lost = Q8ToFloat(call_stats.fractionLost);
|
2015-11-16 09:48:04 -08:00
|
|
|
stats.capture_start_ntp_time_ms = call_stats.capture_start_ntp_time_ms_;
|
2015-10-27 03:35:21 -07:00
|
|
|
if (codec_inst.pltype != -1) {
|
|
|
|
|
stats.codec_name = codec_inst.plname;
|
2017-11-16 10:57:35 +01:00
|
|
|
stats.codec_payload_type = codec_inst.pltype;
|
2015-10-22 10:49:27 +02:00
|
|
|
}
|
2015-10-27 03:35:21 -07:00
|
|
|
stats.ext_seqnum = call_stats.extendedMax;
|
|
|
|
|
if (codec_inst.plfreq / 1000 > 0) {
|
|
|
|
|
stats.jitter_ms = call_stats.jitterSamples / (codec_inst.plfreq / 1000);
|
2015-10-22 10:49:27 +02:00
|
|
|
}
|
2015-11-27 10:46:42 -08:00
|
|
|
stats.delay_estimate_ms = channel_proxy_->GetDelayEstimate();
|
|
|
|
|
stats.audio_level = channel_proxy_->GetSpeechOutputLevelFullRange();
|
2017-07-14 12:17:49 -07:00
|
|
|
stats.total_output_energy = channel_proxy_->GetTotalOutputEnergy();
|
|
|
|
|
stats.total_output_duration = channel_proxy_->GetTotalOutputDuration();
|
2015-10-22 10:49:27 +02:00
|
|
|
|
2015-11-16 09:48:04 -08:00
|
|
|
// Get jitter buffer and total delay (alg + jitter + playout) stats.
|
2015-11-27 10:46:42 -08:00
|
|
|
auto ns = channel_proxy_->GetNetworkStatistics();
|
2015-11-16 09:48:04 -08:00
|
|
|
stats.jitter_buffer_ms = ns.currentBufferSize;
|
|
|
|
|
stats.jitter_buffer_preferred_ms = ns.preferredBufferSize;
|
2017-08-24 17:15:13 -07:00
|
|
|
stats.total_samples_received = ns.totalSamplesReceived;
|
|
|
|
|
stats.concealed_samples = ns.concealedSamples;
|
2017-09-18 09:28:20 +02:00
|
|
|
stats.concealment_events = ns.concealmentEvents;
|
2017-10-02 12:00:34 +02:00
|
|
|
stats.jitter_buffer_delay_seconds =
|
|
|
|
|
static_cast<double>(ns.jitterBufferDelayMs) /
|
|
|
|
|
static_cast<double>(rtc::kNumMillisecsPerSec);
|
2015-11-16 09:48:04 -08:00
|
|
|
stats.expand_rate = Q14ToFloat(ns.currentExpandRate);
|
|
|
|
|
stats.speech_expand_rate = Q14ToFloat(ns.currentSpeechExpandRate);
|
|
|
|
|
stats.secondary_decoded_rate = Q14ToFloat(ns.currentSecondaryDecodedRate);
|
2017-08-28 13:51:27 +02:00
|
|
|
stats.secondary_discarded_rate = Q14ToFloat(ns.currentSecondaryDiscardedRate);
|
2015-11-16 09:48:04 -08:00
|
|
|
stats.accelerate_rate = Q14ToFloat(ns.currentAccelerateRate);
|
|
|
|
|
stats.preemptive_expand_rate = Q14ToFloat(ns.currentPreemptiveRate);
|
2015-10-22 10:49:27 +02:00
|
|
|
|
2015-11-27 10:46:42 -08:00
|
|
|
auto ds = channel_proxy_->GetDecodingCallStatistics();
|
2015-11-16 09:48:04 -08:00
|
|
|
stats.decoding_calls_to_silence_generator = ds.calls_to_silence_generator;
|
|
|
|
|
stats.decoding_calls_to_neteq = ds.calls_to_neteq;
|
|
|
|
|
stats.decoding_normal = ds.decoded_normal;
|
|
|
|
|
stats.decoding_plc = ds.decoded_plc;
|
|
|
|
|
stats.decoding_cng = ds.decoded_cng;
|
|
|
|
|
stats.decoding_plc_cng = ds.decoded_plc_cng;
|
2016-09-20 01:47:12 -07:00
|
|
|
stats.decoding_muted_output = ds.decoded_muted_output;
|
2015-10-22 10:49:27 +02:00
|
|
|
|
|
|
|
|
return stats;
|
2015-06-08 13:04:56 +02:00
|
|
|
}
|
|
|
|
|
|
2018-01-11 13:52:30 +01:00
|
|
|
void AudioReceiveStream::SetSink(AudioSinkInterface* sink) {
|
2017-01-31 03:58:40 -08:00
|
|
|
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
|
2018-01-11 13:52:30 +01:00
|
|
|
channel_proxy_->SetSink(sink);
|
2015-12-12 01:37:01 +01:00
|
|
|
}
|
|
|
|
|
|
2016-06-17 08:30:54 -07:00
|
|
|
void AudioReceiveStream::SetGain(float gain) {
|
2017-01-31 03:58:40 -08:00
|
|
|
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
|
2016-06-17 08:30:54 -07:00
|
|
|
channel_proxy_->SetChannelOutputVolumeScaling(gain);
|
|
|
|
|
}
|
|
|
|
|
|
Reland of Implemented the GetSources() in native code. (patchset #1 id:1 of https://codereview.webrtc.org/2809613002/ )
Reason for revert:
Re-land, reverting did not fix bug.
https://bugs.chromium.org/p/webrtc/issues/detail?id=7465
Original issue's description:
> Revert of Implemented the GetSources() in native code. (patchset #11 id:510001 of https://codereview.webrtc.org/2770233003/ )
>
> Reason for revert:
> Suspected of WebRtcApprtcBrowserTest.MANUAL_WorksOnApprtc breakage, see
>
> https://bugs.chromium.org/p/webrtc/issues/detail?id=7465
>
> Original issue's description:
> > Added the GetSources() to the RtpReceiverInterface and implemented
> > it for the AudioRtpReceiver.
> >
> > This method returns a vector of RtpSource(both CSRC source and SSRC
> > source) which contains the ID of a source, the timestamp, the source
> > type (SSRC or CSRC) and the audio level.
> >
> > The RtpSource objects are buffered and maintained by the
> > RtpReceiver in webrtc/modules/rtp_rtcp/. When the method is called,
> > the info of the contributing source will be pulled along the object
> > chain:
> > AudioRtpReceiver -> VoiceChannel -> WebRtcVoiceMediaChannel ->
> > AudioReceiveStream -> voe::Channel -> RtpRtcp module
> >
> > Spec:https://w3c.github.io/webrtc-pc/archives/20151006/webrtc.html#widl-RTCRtpReceiver-getContributingSources-sequence-RTCRtpContributingSource
> >
> > BUG=chromium:703122
> > TBR=stefan@webrtc.org, danilchap@webrtc.org
> >
> > Review-Url: https://codereview.webrtc.org/2770233003
> > Cr-Commit-Position: refs/heads/master@{#17591}
> > Committed: https://chromium.googlesource.com/external/webrtc/+/292084c3765d9f3ee406ca2ec86eae206b540053
>
> TBR=deadbeef@webrtc.org,solenberg@webrtc.org,hbos@webrtc.org,philipel@webrtc.org,stefan@webrtc.org,danilchap@webrtc.org,zhihuang@webrtc.org
> # Not skipping CQ checks because original CL landed more than 1 days ago.
> BUG=chromium:703122
>
> Review-Url: https://codereview.webrtc.org/2809613002
> Cr-Commit-Position: refs/heads/master@{#17616}
> Committed: https://chromium.googlesource.com/external/webrtc/+/fbcc5cb3869d1370008e40f24fc03ac8fb69c675
TBR=deadbeef@webrtc.org,solenberg@webrtc.org,philipel@webrtc.org,stefan@webrtc.org,danilchap@webrtc.org,zhihuang@webrtc.org,olka@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=chromium:703122
Review-Url: https://codereview.webrtc.org/2810623003
Cr-Commit-Position: refs/heads/master@{#17621}
2017-04-10 07:39:05 -07:00
|
|
|
std::vector<RtpSource> AudioReceiveStream::GetSources() const {
|
|
|
|
|
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
|
|
|
|
|
return channel_proxy_->GetSources();
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-31 03:58:40 -08:00
|
|
|
AudioMixer::Source::AudioFrameInfo AudioReceiveStream::GetAudioFrameWithInfo(
|
|
|
|
|
int sample_rate_hz,
|
|
|
|
|
AudioFrame* audio_frame) {
|
|
|
|
|
return channel_proxy_->GetAudioFrameWithInfo(sample_rate_hz, audio_frame);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int AudioReceiveStream::Ssrc() const {
|
|
|
|
|
return config_.rtp.remote_ssrc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int AudioReceiveStream::PreferredSampleRate() const {
|
2017-09-22 06:48:10 -07:00
|
|
|
return channel_proxy_->PreferredSampleRate();
|
2017-01-31 03:58:40 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int AudioReceiveStream::id() const {
|
|
|
|
|
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
|
|
|
|
|
return config_.rtp.remote_ssrc;
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-15 12:28:07 +02:00
|
|
|
absl::optional<Syncable::Info> AudioReceiveStream::GetInfo() const {
|
2017-01-31 03:58:40 -08:00
|
|
|
RTC_DCHECK_RUN_ON(&module_process_thread_checker_);
|
2018-08-08 10:49:16 +02:00
|
|
|
absl::optional<Syncable::Info> info = channel_proxy_->GetSyncInfo();
|
2017-01-31 03:58:40 -08:00
|
|
|
|
2018-08-08 10:49:16 +02:00
|
|
|
if (!info)
|
2018-06-15 12:28:07 +02:00
|
|
|
return absl::nullopt;
|
2017-01-31 03:58:40 -08:00
|
|
|
|
2018-08-08 10:49:16 +02:00
|
|
|
info->current_delay_ms = channel_proxy_->GetDelayEstimate();
|
2017-11-16 10:57:35 +01:00
|
|
|
return info;
|
2017-01-31 03:58:40 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t AudioReceiveStream::GetPlayoutTimestamp() const {
|
|
|
|
|
// Called on video capture thread.
|
|
|
|
|
return channel_proxy_->GetPlayoutTimestamp();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void AudioReceiveStream::SetMinimumPlayoutDelay(int delay_ms) {
|
|
|
|
|
RTC_DCHECK_RUN_ON(&module_process_thread_checker_);
|
|
|
|
|
return channel_proxy_->SetMinimumPlayoutDelay(delay_ms);
|
2015-10-15 05:22:13 -07:00
|
|
|
}
|
|
|
|
|
|
2016-11-14 11:30:07 -08:00
|
|
|
void AudioReceiveStream::AssociateSendStream(AudioSendStream* send_stream) {
|
2017-01-31 03:58:40 -08:00
|
|
|
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
|
2016-11-14 11:30:07 -08:00
|
|
|
if (send_stream) {
|
2018-01-11 13:52:30 +01:00
|
|
|
channel_proxy_->AssociateSendChannel(send_stream->GetChannelProxy());
|
2016-11-14 11:30:07 -08:00
|
|
|
} else {
|
|
|
|
|
channel_proxy_->DisassociateSendChannel();
|
|
|
|
|
}
|
2018-01-11 13:52:30 +01:00
|
|
|
associated_send_stream_ = send_stream;
|
2016-11-14 11:30:07 -08:00
|
|
|
}
|
|
|
|
|
|
2016-05-01 20:18:34 -07:00
|
|
|
void AudioReceiveStream::SignalNetworkState(NetworkState state) {
|
2017-01-31 03:58:40 -08:00
|
|
|
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
|
2016-05-01 20:18:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool AudioReceiveStream::DeliverRtcp(const uint8_t* packet, size_t length) {
|
|
|
|
|
// TODO(solenberg): Tests call this function on a network thread, libjingle
|
|
|
|
|
// calls on the worker thread. We should move towards always using a network
|
|
|
|
|
// thread. Then this check can be enabled.
|
|
|
|
|
// RTC_DCHECK(!thread_checker_.CalledOnValidThread());
|
|
|
|
|
return channel_proxy_->ReceivedRTCPPacket(packet, length);
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-21 06:28:10 -08:00
|
|
|
void AudioReceiveStream::OnRtpPacket(const RtpPacketReceived& packet) {
|
2016-05-01 20:18:34 -07:00
|
|
|
// TODO(solenberg): Tests call this function on a network thread, libjingle
|
|
|
|
|
// calls on the worker thread. We should move towards always using a network
|
|
|
|
|
// thread. Then this check can be enabled.
|
|
|
|
|
// RTC_DCHECK(!thread_checker_.CalledOnValidThread());
|
2017-02-21 06:28:10 -08:00
|
|
|
channel_proxy_->OnRtpPacket(packet);
|
2016-05-01 20:18:34 -07:00
|
|
|
}
|
|
|
|
|
|
2017-01-31 03:58:40 -08:00
|
|
|
const webrtc::AudioReceiveStream::Config& AudioReceiveStream::config() const {
|
|
|
|
|
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
|
|
|
|
|
return config_;
|
2016-10-31 03:26:40 -07:00
|
|
|
}
|
|
|
|
|
|
2018-01-11 13:52:30 +01:00
|
|
|
const AudioSendStream* AudioReceiveStream::GetAssociatedSendStreamForTesting()
|
|
|
|
|
const {
|
|
|
|
|
RTC_DCHECK_RUN_ON(&worker_thread_checker_);
|
|
|
|
|
return associated_send_stream_;
|
2016-10-20 06:32:39 -07:00
|
|
|
}
|
|
|
|
|
|
2016-11-22 06:42:53 -08:00
|
|
|
internal::AudioState* AudioReceiveStream::audio_state() const {
|
|
|
|
|
auto* audio_state = static_cast<internal::AudioState*>(audio_state_.get());
|
|
|
|
|
RTC_DCHECK(audio_state);
|
|
|
|
|
return audio_state;
|
|
|
|
|
}
|
2018-01-10 15:17:10 +01:00
|
|
|
|
|
|
|
|
void AudioReceiveStream::ConfigureStream(AudioReceiveStream* stream,
|
|
|
|
|
const Config& new_config,
|
|
|
|
|
bool first_time) {
|
2018-01-25 10:14:29 +01:00
|
|
|
RTC_LOG(LS_INFO) << "AudioReceiveStream::ConfigureStream: "
|
|
|
|
|
<< new_config.ToString();
|
2018-01-10 15:17:10 +01:00
|
|
|
RTC_DCHECK(stream);
|
|
|
|
|
const auto& channel_proxy = stream->channel_proxy_;
|
|
|
|
|
const auto& old_config = stream->config_;
|
|
|
|
|
|
|
|
|
|
// Configuration parameters which cannot be changed.
|
|
|
|
|
RTC_DCHECK(first_time ||
|
|
|
|
|
old_config.rtp.remote_ssrc == new_config.rtp.remote_ssrc);
|
|
|
|
|
RTC_DCHECK(first_time ||
|
|
|
|
|
old_config.rtcp_send_transport == new_config.rtcp_send_transport);
|
|
|
|
|
// Decoder factory cannot be changed because it is configured at
|
|
|
|
|
// voe::Channel construction time.
|
|
|
|
|
RTC_DCHECK(first_time ||
|
|
|
|
|
old_config.decoder_factory == new_config.decoder_factory);
|
|
|
|
|
|
|
|
|
|
if (first_time || old_config.rtp.local_ssrc != new_config.rtp.local_ssrc) {
|
|
|
|
|
channel_proxy->SetLocalSSRC(new_config.rtp.local_ssrc);
|
|
|
|
|
}
|
2018-05-25 13:41:10 +02:00
|
|
|
|
|
|
|
|
if (first_time) {
|
|
|
|
|
channel_proxy->SetRemoteSSRC(new_config.rtp.remote_ssrc);
|
|
|
|
|
} else {
|
|
|
|
|
// Remote ssrc can't be changed mid-stream.
|
|
|
|
|
RTC_DCHECK_EQ(old_config.rtp.remote_ssrc, new_config.rtp.remote_ssrc);
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-10 15:17:10 +01:00
|
|
|
// TODO(solenberg): Config NACK history window (which is a packet count),
|
|
|
|
|
// using the actual packet size for the configured codec.
|
|
|
|
|
if (first_time || old_config.rtp.nack.rtp_history_ms !=
|
|
|
|
|
new_config.rtp.nack.rtp_history_ms) {
|
|
|
|
|
channel_proxy->SetNACKStatus(new_config.rtp.nack.rtp_history_ms != 0,
|
|
|
|
|
new_config.rtp.nack.rtp_history_ms / 20);
|
|
|
|
|
}
|
|
|
|
|
if (first_time || old_config.decoder_map != new_config.decoder_map) {
|
|
|
|
|
channel_proxy->SetReceiveCodecs(new_config.decoder_map);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stream->config_ = new_config;
|
|
|
|
|
}
|
2015-04-29 15:24:01 +02:00
|
|
|
} // namespace internal
|
|
|
|
|
} // namespace webrtc
|