| Index: webrtc/call/rtp_transport_controller_receive.cc
|
| diff --git a/webrtc/call/rtp_transport_controller_receive.cc b/webrtc/call/rtp_transport_controller_receive.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6ac4b1a91deadcb66fa453bf009b74e8886765ef
|
| --- /dev/null
|
| +++ b/webrtc/call/rtp_transport_controller_receive.cc
|
| @@ -0,0 +1,180 @@
|
| +/*
|
| + * Copyright (c) 2017 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.
|
| + */
|
| +
|
| +#include <map>
|
| +#include <utility>
|
| +#include <vector>
|
| +
|
| +#include "webrtc/base/ptr_util.h"
|
| +#include "webrtc/call/rtp_transport_controller_receive.h"
|
| +#include "webrtc/modules/congestion_controller/include/receive_side_congestion_controller.h"
|
| +#include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h"
|
| +#include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h"
|
| +
|
| +namespace webrtc {
|
| +namespace {
|
| +
|
| +class RtpTransportControllerReceive
|
| + : public RtpTransportControllerReceiveInterface {
|
| + public:
|
| + RtpTransportControllerReceive(
|
| + ReceiveSideCongestionController* receive_side_cc,
|
| + bool enable_receive_side_bwe);
|
| +
|
| + ~RtpTransportControllerReceive() override;
|
| +
|
| + // ImplementRtpTransportControllerReceiveInterface
|
| + void AddReceiver(uint32_t ssrc,
|
| + const Config& config,
|
| + RtpPacketReceiverInterface* receiver) override;
|
| + void RemoveReceiver(const RtpPacketReceiverInterface* receiver) override;
|
| +
|
| + void AddSink(uint32_t ssrc, RtpPacketSinkInterface* sink) override;
|
| + void RemoveSink(const RtpPacketSinkInterface* sink) override;
|
| +
|
| + PacketReceiver::DeliveryStatus OnRtpPacket(
|
| + int64_t arrival_time_ms,
|
| + rtc::ArrayView<const uint8_t> packet) override;
|
| +
|
| + private:
|
| + struct Stream {
|
| + Config config;
|
| + RtpPacketReceiverInterface* receiver;
|
| + std::vector<RtpPacketSinkInterface*> auxillary_sinks;
|
| +
|
| + Stream(Config config, RtpPacketReceiverInterface* receiver)
|
| + : config(config), receiver(receiver) {}
|
| + };
|
| +
|
| + Stream* LookupStream(uint32_t ssrc);
|
| +
|
| + // Indexed by ssrc.
|
| + std::map<uint32_t, Stream> streams_;
|
| + ReceiveSideCongestionController* const receive_side_cc_;
|
| + const bool enable_receive_side_bwe_;
|
| +};
|
| +
|
| +RtpTransportControllerReceive::RtpTransportControllerReceive(
|
| + ReceiveSideCongestionController* receive_side_cc,
|
| + bool enable_receive_side_bwe)
|
| + : receive_side_cc_(receive_side_cc),
|
| + enable_receive_side_bwe_(enable_receive_side_bwe) {}
|
| +
|
| +RtpTransportControllerReceive::~RtpTransportControllerReceive() {
|
| + RTC_DCHECK(streams_.empty());
|
| +}
|
| +
|
| +RtpTransportControllerReceive::Stream*
|
| +RtpTransportControllerReceive::LookupStream(uint32_t ssrc) {
|
| + const auto it = streams_.find(ssrc);
|
| + return (it != streams_.end()) ? &it->second : nullptr;
|
| +}
|
| +
|
| +void RtpTransportControllerReceive::AddReceiver(
|
| + uint32_t ssrc,
|
| + const Config& config,
|
| + RtpPacketReceiverInterface* receiver) {
|
| + bool inserted = streams_.emplace(ssrc, Stream(config, receiver)).second;
|
| + RTC_DCHECK(inserted);
|
| +}
|
| +
|
| +void RtpTransportControllerReceive::RemoveReceiver(
|
| + const RtpPacketReceiverInterface* receiver) {
|
| + for (auto it = streams_.begin(); it != streams_.end();) {
|
| + if (it->second.receiver == receiver) {
|
| + receive_side_cc_
|
| + ->GetRemoteBitrateEstimator(it->second.config.use_send_side_bwe)
|
| + ->RemoveStream(it->first);
|
| + it = streams_.erase(it);
|
| + } else {
|
| + ++it;
|
| + }
|
| + }
|
| +}
|
| +
|
| +void RtpTransportControllerReceive::AddSink(uint32_t ssrc,
|
| + RtpPacketSinkInterface* sink) {
|
| + Stream* stream = LookupStream(ssrc);
|
| + // Can't DCHECK this, since flexfec tests create flexfec streams
|
| + // without creating the streams they are protecting.
|
| + if (!stream) {
|
| + return;
|
| + }
|
| + stream->auxillary_sinks.push_back(sink);
|
| +}
|
| +
|
| +void RtpTransportControllerReceive::RemoveSink(
|
| + const RtpPacketSinkInterface* sink) {
|
| + for (auto& it : streams_) {
|
| + auto sinks_end = it.second.auxillary_sinks.end();
|
| + auto sinks_it =
|
| + std::remove(it.second.auxillary_sinks.begin(), sinks_end, sink);
|
| + it.second.auxillary_sinks.erase(sinks_it, sinks_end);
|
| + }
|
| +}
|
| +
|
| +PacketReceiver::DeliveryStatus RtpTransportControllerReceive::OnRtpPacket(
|
| + int64_t arrival_time_ms,
|
| + rtc::ArrayView<const uint8_t> raw_packet) {
|
| + RtpPacketReceived parsed_packet;
|
| + if (!parsed_packet.Parse(raw_packet)) {
|
| + return PacketReceiver::DELIVERY_PACKET_ERROR;
|
| + }
|
| + parsed_packet.set_arrival_time_ms(arrival_time_ms);
|
| +
|
| + Stream* stream = LookupStream(parsed_packet.Ssrc());
|
| + if (!stream) {
|
| + return PacketReceiver::DELIVERY_UNKNOWN_SSRC;
|
| + }
|
| + if (!stream->receiver->OnRtpPacketReceive(&parsed_packet)) {
|
| + return PacketReceiver::DELIVERY_PACKET_ERROR;
|
| + }
|
| + for (auto* it : stream->auxillary_sinks) {
|
| + it->OnRtpPacket(parsed_packet);
|
| + }
|
| + if (receive_side_cc_) {
|
| + if (!stream->config.use_send_side_bwe &&
|
| + parsed_packet.HasExtension<TransportSequenceNumber>()) {
|
| + // Inconsistent configuration of send side BWE. Do nothing.
|
| + // TODO(nisse): Without this check, we may produce RTCP feedback
|
| + // packets even when not negotiated. But it would be cleaner to
|
| + // move the check down to RTCPSender::SendFeedbackPacket, which
|
| + // would also help the PacketRouter to select an appropriate rtp
|
| + // module in the case that some, but not all, have RTCP feedback
|
| + // enabled.
|
| + return PacketReceiver::DELIVERY_OK;
|
| + }
|
| + // Receive side bwe is not used for audio.
|
| + if (enable_receive_side_bwe_ ||
|
| + (stream->config.use_send_side_bwe &&
|
| + parsed_packet.HasExtension<TransportSequenceNumber>())) {
|
| + RTPHeader header;
|
| + parsed_packet.GetHeader(&header);
|
| +
|
| + receive_side_cc_->OnReceivedPacket(
|
| + parsed_packet.arrival_time_ms(),
|
| + parsed_packet.payload_size() + parsed_packet.padding_size(), header);
|
| + }
|
| + }
|
| + return PacketReceiver::DELIVERY_OK;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// static
|
| +std::unique_ptr<RtpTransportControllerReceiveInterface>
|
| +RtpTransportControllerReceiveInterface::Create(
|
| + ReceiveSideCongestionController* receive_side_cc,
|
| + bool enable_receive_side_bwe) {
|
| + return rtc::MakeUnique<RtpTransportControllerReceive>(
|
| + receive_side_cc, enable_receive_side_bwe);
|
| +}
|
| +
|
| +} // namespace webrtc
|
|
|