blob: fcfb3ef7ae3f72aa84bf208ed8d8108d53fe7363 [file] [log] [blame]
brandtr76648da2016-10-20 04:54:48 -07001/*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
brandtr7250b392016-12-19 01:13:46 -080011#include "webrtc/call/flexfec_receive_stream_impl.h"
brandtr76648da2016-10-20 04:54:48 -070012
brandtrfa5a3682017-01-17 01:33:54 -080013#include <string>
brandtrb29e6522016-12-21 06:37:18 -080014
brandtr76648da2016-10-20 04:54:48 -070015#include "webrtc/base/checks.h"
tommidea489f2017-03-03 03:20:24 -080016#include "webrtc/base/location.h"
brandtr76648da2016-10-20 04:54:48 -070017#include "webrtc/base/logging.h"
brandtrfa5a3682017-01-17 01:33:54 -080018#include "webrtc/modules/rtp_rtcp/include/flexfec_receiver.h"
19#include "webrtc/modules/rtp_rtcp/include/receive_statistics.h"
20#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
21#include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h"
22#include "webrtc/modules/utility/include/process_thread.h"
23#include "webrtc/system_wrappers/include/clock.h"
brandtr76648da2016-10-20 04:54:48 -070024
25namespace webrtc {
26
27std::string FlexfecReceiveStream::Stats::ToString(int64_t time_ms) const {
28 std::stringstream ss;
29 ss << "FlexfecReceiveStream stats: " << time_ms
30 << ", {flexfec_bitrate_bps: " << flexfec_bitrate_bps << "}";
31 return ss.str();
32}
33
brandtr1cfbd602016-12-08 04:17:53 -080034std::string FlexfecReceiveStream::Config::ToString() const {
35 std::stringstream ss;
36 ss << "{payload_type: " << payload_type;
37 ss << ", remote_ssrc: " << remote_ssrc;
38 ss << ", local_ssrc: " << local_ssrc;
39 ss << ", protected_media_ssrcs: [";
40 size_t i = 0;
41 for (; i + 1 < protected_media_ssrcs.size(); ++i)
42 ss << protected_media_ssrcs[i] << ", ";
43 if (!protected_media_ssrcs.empty())
44 ss << protected_media_ssrcs[i];
45 ss << "], transport_cc: " << (transport_cc ? "on" : "off");
brandtrb29e6522016-12-21 06:37:18 -080046 ss << ", rtp_header_extensions: [";
brandtr1cfbd602016-12-08 04:17:53 -080047 i = 0;
brandtrb29e6522016-12-21 06:37:18 -080048 for (; i + 1 < rtp_header_extensions.size(); ++i)
49 ss << rtp_header_extensions[i].ToString() << ", ";
50 if (!rtp_header_extensions.empty())
51 ss << rtp_header_extensions[i].ToString();
brandtr1cfbd602016-12-08 04:17:53 -080052 ss << "]}";
53 return ss.str();
54}
55
brandtr8313a6f2017-01-13 07:41:19 -080056bool FlexfecReceiveStream::Config::IsCompleteAndEnabled() const {
57 // Check if FlexFEC is enabled.
58 if (payload_type < 0)
59 return false;
60 // Do we have the necessary SSRC information?
61 if (remote_ssrc == 0)
62 return false;
63 // TODO(brandtr): Update this check when we support multistream protection.
64 if (protected_media_ssrcs.size() != 1u)
65 return false;
66 return true;
67}
68
brandtr76648da2016-10-20 04:54:48 -070069namespace {
70
71// TODO(brandtr): Update this function when we support multistream protection.
brandtr43c31e72016-11-15 05:26:45 -080072std::unique_ptr<FlexfecReceiver> MaybeCreateFlexfecReceiver(
73 const FlexfecReceiveStream::Config& config,
brandtrb29e6522016-12-21 06:37:18 -080074 RecoveredPacketReceiver* recovered_packet_receiver) {
brandtr1cfbd602016-12-08 04:17:53 -080075 if (config.payload_type < 0) {
brandtr43c31e72016-11-15 05:26:45 -080076 LOG(LS_WARNING) << "Invalid FlexFEC payload type given. "
77 << "This FlexfecReceiveStream will therefore be useless.";
brandtr76648da2016-10-20 04:54:48 -070078 return nullptr;
brandtr43c31e72016-11-15 05:26:45 -080079 }
brandtr1cfbd602016-12-08 04:17:53 -080080 RTC_DCHECK_GE(config.payload_type, 0);
81 RTC_DCHECK_LE(config.payload_type, 127);
82 if (config.remote_ssrc == 0) {
brandtr43c31e72016-11-15 05:26:45 -080083 LOG(LS_WARNING) << "Invalid FlexFEC SSRC given. "
84 << "This FlexfecReceiveStream will therefore be useless.";
85 return nullptr;
86 }
87 if (config.protected_media_ssrcs.empty()) {
88 LOG(LS_WARNING) << "No protected media SSRC supplied. "
89 << "This FlexfecReceiveStream will therefore be useless.";
90 return nullptr;
91 }
92
93 if (config.protected_media_ssrcs.size() > 1) {
brandtr76648da2016-10-20 04:54:48 -070094 LOG(LS_WARNING)
95 << "The supplied FlexfecConfig contained multiple protected "
96 "media streams, but our implementation currently only "
brandtr43c31e72016-11-15 05:26:45 -080097 "supports protecting a single media stream. "
98 "To avoid confusion, disabling FlexFEC completely.";
99 return nullptr;
brandtr76648da2016-10-20 04:54:48 -0700100 }
brandtr43c31e72016-11-15 05:26:45 -0800101 RTC_DCHECK_EQ(1U, config.protected_media_ssrcs.size());
102 return std::unique_ptr<FlexfecReceiver>(
brandtr1cfbd602016-12-08 04:17:53 -0800103 new FlexfecReceiver(config.remote_ssrc, config.protected_media_ssrcs[0],
brandtrb29e6522016-12-21 06:37:18 -0800104 recovered_packet_receiver));
brandtr76648da2016-10-20 04:54:48 -0700105}
106
brandtrfa5a3682017-01-17 01:33:54 -0800107std::unique_ptr<RtpRtcp> CreateRtpRtcpModule(
108 ReceiveStatistics* receive_statistics,
109 Transport* rtcp_send_transport,
110 RtcpRttStats* rtt_stats) {
111 RtpRtcp::Configuration configuration;
112 configuration.audio = false;
113 configuration.receiver_only = true;
114 configuration.clock = Clock::GetRealTimeClock();
115 configuration.receive_statistics = receive_statistics;
116 configuration.outgoing_transport = rtcp_send_transport;
117 configuration.rtt_stats = rtt_stats;
118 std::unique_ptr<RtpRtcp> rtp_rtcp(RtpRtcp::CreateRtpRtcp(configuration));
119 return rtp_rtcp;
120}
121
brandtr76648da2016-10-20 04:54:48 -0700122} // namespace
123
brandtr7250b392016-12-19 01:13:46 -0800124FlexfecReceiveStreamImpl::FlexfecReceiveStreamImpl(
brandtr446fcb62016-12-08 04:14:24 -0800125 const Config& config,
brandtrfa5a3682017-01-17 01:33:54 -0800126 RecoveredPacketReceiver* recovered_packet_receiver,
127 RtcpRttStats* rtt_stats,
128 ProcessThread* process_thread)
129 : config_(config),
130 started_(false),
131 receiver_(MaybeCreateFlexfecReceiver(config_, recovered_packet_receiver)),
132 rtp_receive_statistics_(
133 ReceiveStatistics::Create(Clock::GetRealTimeClock())),
134 rtp_rtcp_(CreateRtpRtcpModule(rtp_receive_statistics_.get(),
135 config_.rtcp_send_transport,
136 rtt_stats)),
137 process_thread_(process_thread) {
brandtr7250b392016-12-19 01:13:46 -0800138 LOG(LS_INFO) << "FlexfecReceiveStreamImpl: " << config_.ToString();
brandtrfa5a3682017-01-17 01:33:54 -0800139
140 // RTCP reporting.
141 rtp_rtcp_->SetSendingMediaStatus(false);
142 rtp_rtcp_->SetRTCPStatus(config_.rtcp_mode);
143 rtp_rtcp_->SetSSRC(config_.local_ssrc);
tommidea489f2017-03-03 03:20:24 -0800144 process_thread_->RegisterModule(rtp_rtcp_.get(), RTC_FROM_HERE);
brandtr76648da2016-10-20 04:54:48 -0700145}
146
brandtr7250b392016-12-19 01:13:46 -0800147FlexfecReceiveStreamImpl::~FlexfecReceiveStreamImpl() {
148 LOG(LS_INFO) << "~FlexfecReceiveStreamImpl: " << config_.ToString();
brandtr76648da2016-10-20 04:54:48 -0700149 Stop();
brandtrfa5a3682017-01-17 01:33:54 -0800150 process_thread_->DeRegisterModule(rtp_rtcp_.get());
brandtr76648da2016-10-20 04:54:48 -0700151}
152
nisse5c29a7a2017-02-16 06:52:32 -0800153void FlexfecReceiveStreamImpl::OnRtpPacket(const RtpPacketReceived& packet) {
brandtr76648da2016-10-20 04:54:48 -0700154 {
155 rtc::CritScope cs(&crit_);
156 if (!started_)
nisse5c29a7a2017-02-16 06:52:32 -0800157 return;
brandtr76648da2016-10-20 04:54:48 -0700158 }
brandtrfa5a3682017-01-17 01:33:54 -0800159
brandtr76648da2016-10-20 04:54:48 -0700160 if (!receiver_)
nisse5c29a7a2017-02-16 06:52:32 -0800161 return;
brandtrfa5a3682017-01-17 01:33:54 -0800162
nisse5c29a7a2017-02-16 06:52:32 -0800163 receiver_->OnRtpPacket(packet);
brandtrfa5a3682017-01-17 01:33:54 -0800164
165 // Do not report media packets in the RTCP RRs generated by |rtp_rtcp_|.
166 if (packet.Ssrc() == config_.remote_ssrc) {
167 RTPHeader header;
168 packet.GetHeader(&header);
169 // FlexFEC packets are never retransmitted.
170 const bool kNotRetransmitted = false;
171 rtp_receive_statistics_->IncomingPacket(header, packet.size(),
172 kNotRetransmitted);
173 }
brandtr76648da2016-10-20 04:54:48 -0700174}
175
brandtr7250b392016-12-19 01:13:46 -0800176void FlexfecReceiveStreamImpl::Start() {
brandtr76648da2016-10-20 04:54:48 -0700177 rtc::CritScope cs(&crit_);
178 started_ = true;
179}
180
brandtr7250b392016-12-19 01:13:46 -0800181void FlexfecReceiveStreamImpl::Stop() {
brandtr76648da2016-10-20 04:54:48 -0700182 rtc::CritScope cs(&crit_);
183 started_ = false;
184}
185
186// TODO(brandtr): Implement this member function when we have designed the
187// stats for FlexFEC.
brandtr7250b392016-12-19 01:13:46 -0800188FlexfecReceiveStreamImpl::Stats FlexfecReceiveStreamImpl::GetStats() const {
189 return FlexfecReceiveStream::Stats();
brandtr76648da2016-10-20 04:54:48 -0700190}
191
brandtr76648da2016-10-20 04:54:48 -0700192} // namespace webrtc