Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(794)

Unified Diff: webrtc/call/rtp_transport_controller_receive.cc

Issue 2709723003: Initial implementation of RtpTransportControllerReceive and related interfaces.
Patch Set: Fix audio. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..22fe6a2810fed0d5f2fbafcf9292ef1af3f079dc
--- /dev/null
+++ b/webrtc/call/rtp_transport_controller_receive.cc
@@ -0,0 +1,190 @@
+/*
+ * 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/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 {
+
+class RtpTransportControllerReceive
+ : public RtpTransportControllerReceiveInterface {
+ public:
+ explicit RtpTransportControllerReceive(
+ ReceiveSideCongestionController* receive_side_cc,
+ bool enable_receive_side_bwe);
+
+ // ImplementRtpTransportControllerReceiveInterface
+ bool AddReceiver(uint32_t ssrc,
+ const Config& config,
+ RtpPacketReceiverInterface* receiver) override;
+ bool RemoveReceiver(const RtpPacketReceiverInterface* receiver) override;
+
+ bool AddSink(uint32_t ssrc, RtpPacketSinkInterface* sink) override;
+ bool RemoveSink(const RtpPacketSinkInterface* sink) override;
+
+#if 0
+ bool RegisterPayload(uint8_t payload_type, MediaType media_type,
+ RtpPacketReceiverInterface *receiver) override;
+#endif
+ PacketReceiver::DeliveryStatus OnRtpPacket(
+ int64_t arrival_time_ms,
+ rtc::ArrayView<const uint8_t> packet) override;
+
+ ~RtpTransportControllerReceive() 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;
+}
+
+bool RtpTransportControllerReceive::AddReceiver(
+ uint32_t ssrc,
+ const Config& config,
+ RtpPacketReceiverInterface* receiver) {
+ if (LookupStream(ssrc)) {
+ return false;
+ }
+ streams_.insert(std::pair<uint32_t, Stream>(ssrc, Stream(config, receiver)));
+ return true;
+}
+
+bool RtpTransportControllerReceive::RemoveReceiver(
+ const RtpPacketReceiverInterface* receiver) {
+ bool found = false;
+ 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);
+ found = true;
+ } else {
+ ++it;
+ }
+ }
+ return found;
+}
+
+bool RtpTransportControllerReceive::AddSink(uint32_t ssrc,
+ RtpPacketSinkInterface* sink) {
+ Stream* stream = LookupStream(ssrc);
+ if (stream) {
+ stream->auxillary_sinks.push_back(sink);
+ return true;
+ }
+ return false;
+}
+
+bool RtpTransportControllerReceive::RemoveSink(
+ const RtpPacketSinkInterface* sink) {
+ bool found = false;
+ 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);
+ if (sinks_it != sinks_end) {
+ it.second.auxillary_sinks.erase(sinks_it, sinks_end);
+ found = true;
+ }
+ }
+ return found;
+}
+
+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.data(), raw_packet.size()))
+ return PacketReceiver::DELIVERY_PACKET_ERROR;
+ parsed_packet.set_arrival_time_ms(arrival_time_ms);
+
+ Stream* stream = LookupStream(parsed_packet.Ssrc());
+ if (!stream) {
+ // TODO(nisse): Lookup payload, for unsignalled streams.
+ 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;
+}
+
+// static
+std::unique_ptr<RtpTransportControllerReceiveInterface>
+RtpTransportControllerReceiveInterface::Create(
+ ReceiveSideCongestionController* receive_side_cc,
+ bool enable_receive_side_bwe) {
+ return std::unique_ptr<RtpTransportControllerReceiveInterface>(
+ new RtpTransportControllerReceive(receive_side_cc,
+ enable_receive_side_bwe));
+}
+
+} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698