| 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..0576ae2e891c3537a0db6f8b0140db512820f1f4
|
| --- /dev/null
|
| +++ b/webrtc/call/rtp_transport_controller_receive.cc
|
| @@ -0,0 +1,171 @@
|
| +/*
|
| + * 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/rtp_rtcp/source/rtp_packet_received.h"
|
| +
|
| +namespace webrtc {
|
| +
|
| +class RtpTransportControllerReceive
|
| + : public RtpTransportControllerReceiveInterface {
|
| + public:
|
| + RtpTransportControllerReceive(RtpPacketObserverInterface* observer);
|
| +
|
| + // ImplementRtpTransportControllerReceiveInterface
|
| + bool AddReceiver(uint32_t ssrc,
|
| + MediaType media_type,
|
| + const Config& config,
|
| + RtpPacketReceiverInterface* receiver) override;
|
| + bool RemoveReceiver(const RtpPacketReceiverInterface* receiver) override;
|
| +
|
| + bool AddSink(uint32_t ssrc,
|
| + MediaType media_type,
|
| + 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(
|
| + MediaType media_type,
|
| + int64_t arrival_time_ms,
|
| + rtc::ArrayView<const uint8_t> packet) override;
|
| +
|
| + ~RtpTransportControllerReceive() override;
|
| +
|
| + private:
|
| + struct Stream {
|
| + MediaType media_type = MediaType::ANY;
|
| + Config config;
|
| + RtpPacketReceiverInterface* receiver = nullptr;
|
| + std::vector<RtpPacketSinkInterface*> auxillary_sinks;
|
| +
|
| + Stream(MediaType media_type,
|
| + Config config,
|
| + RtpPacketReceiverInterface* receiver)
|
| + : media_type(media_type), config(config), receiver(receiver) {}
|
| + };
|
| +
|
| + Stream* LookupStream(uint32_t ssrc, MediaType media_type);
|
| +
|
| + // Indexed by ssrc. We could use a map indexed by pairs (media_type, ssrc),
|
| + // except that we want special handling of MediaType:ANY specially.
|
| + std::multimap<uint32_t, Stream> streams_;
|
| + RtpPacketObserverInterface* observer_;
|
| +};
|
| +
|
| +RtpTransportControllerReceive::RtpTransportControllerReceive(
|
| + RtpPacketObserverInterface* observer)
|
| + : observer_(observer) {}
|
| +
|
| +RtpTransportControllerReceive::~RtpTransportControllerReceive() {
|
| + RTC_DCHECK(streams_.empty());
|
| +}
|
| +
|
| +RtpTransportControllerReceive::Stream*
|
| +RtpTransportControllerReceive::LookupStream(uint32_t ssrc,
|
| + MediaType media_type) {
|
| + auto range = streams_.equal_range(ssrc);
|
| + for (auto it = range.first; it != range.second; ++it) {
|
| + if (media_type == MediaType::ANY || media_type == it->second.media_type)
|
| + return &it->second;
|
| + }
|
| + return nullptr;
|
| +}
|
| +
|
| +bool RtpTransportControllerReceive::AddReceiver(
|
| + uint32_t ssrc,
|
| + MediaType media_type,
|
| + const Config& config,
|
| + RtpPacketReceiverInterface* receiver) {
|
| + if (LookupStream(ssrc, media_type)) {
|
| + return false;
|
| + }
|
| + streams_.insert(
|
| + std::pair<uint32_t, Stream>(ssrc, Stream(media_type, config, receiver)));
|
| + return true;
|
| +}
|
| +
|
| +bool RtpTransportControllerReceive::RemoveReceiver(
|
| + const RtpPacketReceiverInterface* receiver) {
|
| + for (auto it = streams_.begin(); it != streams_.end(); ++it) {
|
| + if (it->second.receiver == receiver) {
|
| + streams_.erase(it);
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +bool RtpTransportControllerReceive::AddSink(uint32_t ssrc,
|
| + MediaType media_type,
|
| + RtpPacketSinkInterface* sink) {
|
| + Stream* stream = LookupStream(ssrc, media_type);
|
| + 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(
|
| + MediaType media_type,
|
| + 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(), media_type);
|
| + 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 (observer_)
|
| + observer_->OnRtpPacket(media_type, stream->config, parsed_packet);
|
| + return PacketReceiver::DELIVERY_OK;
|
| +}
|
| +
|
| +// static
|
| +std::unique_ptr<RtpTransportControllerReceiveInterface>
|
| +RtpTransportControllerReceiveInterface::Create(
|
| + RtpPacketObserverInterface* observer) {
|
| + return std::unique_ptr<RtpTransportControllerReceiveInterface>(
|
| + new RtpTransportControllerReceive(observer));
|
| +}
|
| +
|
| +} // namespace webrtc
|
|
|