blob: f5272c9029dd48f2e8ba77866a0df0c81fe81b1c [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"
16#include "webrtc/base/logging.h"
brandtrfa5a3682017-01-17 01:33:54 -080017#include "webrtc/modules/rtp_rtcp/include/flexfec_receiver.h"
18#include "webrtc/modules/rtp_rtcp/include/receive_statistics.h"
19#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
20#include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h"
21#include "webrtc/modules/utility/include/process_thread.h"
22#include "webrtc/system_wrappers/include/clock.h"
brandtr76648da2016-10-20 04:54:48 -070023
24namespace webrtc {
25
26std::string FlexfecReceiveStream::Stats::ToString(int64_t time_ms) const {
27 std::stringstream ss;
28 ss << "FlexfecReceiveStream stats: " << time_ms
29 << ", {flexfec_bitrate_bps: " << flexfec_bitrate_bps << "}";
30 return ss.str();
31}
32
brandtr1cfbd602016-12-08 04:17:53 -080033std::string FlexfecReceiveStream::Config::ToString() const {
34 std::stringstream ss;
35 ss << "{payload_type: " << payload_type;
36 ss << ", remote_ssrc: " << remote_ssrc;
37 ss << ", local_ssrc: " << local_ssrc;
38 ss << ", protected_media_ssrcs: [";
39 size_t i = 0;
40 for (; i + 1 < protected_media_ssrcs.size(); ++i)
41 ss << protected_media_ssrcs[i] << ", ";
42 if (!protected_media_ssrcs.empty())
43 ss << protected_media_ssrcs[i];
44 ss << "], transport_cc: " << (transport_cc ? "on" : "off");
brandtrb29e6522016-12-21 06:37:18 -080045 ss << ", rtp_header_extensions: [";
brandtr1cfbd602016-12-08 04:17:53 -080046 i = 0;
brandtrb29e6522016-12-21 06:37:18 -080047 for (; i + 1 < rtp_header_extensions.size(); ++i)
48 ss << rtp_header_extensions[i].ToString() << ", ";
49 if (!rtp_header_extensions.empty())
50 ss << rtp_header_extensions[i].ToString();
brandtr1cfbd602016-12-08 04:17:53 -080051 ss << "]}";
52 return ss.str();
53}
54
brandtr8313a6f2017-01-13 07:41:19 -080055bool FlexfecReceiveStream::Config::IsCompleteAndEnabled() const {
56 // Check if FlexFEC is enabled.
57 if (payload_type < 0)
58 return false;
59 // Do we have the necessary SSRC information?
60 if (remote_ssrc == 0)
61 return false;
62 // TODO(brandtr): Update this check when we support multistream protection.
63 if (protected_media_ssrcs.size() != 1u)
64 return false;
65 return true;
66}
67
brandtr76648da2016-10-20 04:54:48 -070068namespace {
69
70// TODO(brandtr): Update this function when we support multistream protection.
brandtr43c31e72016-11-15 05:26:45 -080071std::unique_ptr<FlexfecReceiver> MaybeCreateFlexfecReceiver(
72 const FlexfecReceiveStream::Config& config,
brandtrb29e6522016-12-21 06:37:18 -080073 RecoveredPacketReceiver* recovered_packet_receiver) {
brandtr1cfbd602016-12-08 04:17:53 -080074 if (config.payload_type < 0) {
brandtr43c31e72016-11-15 05:26:45 -080075 LOG(LS_WARNING) << "Invalid FlexFEC payload type given. "
76 << "This FlexfecReceiveStream will therefore be useless.";
brandtr76648da2016-10-20 04:54:48 -070077 return nullptr;
brandtr43c31e72016-11-15 05:26:45 -080078 }
brandtr1cfbd602016-12-08 04:17:53 -080079 RTC_DCHECK_GE(config.payload_type, 0);
80 RTC_DCHECK_LE(config.payload_type, 127);
81 if (config.remote_ssrc == 0) {
brandtr43c31e72016-11-15 05:26:45 -080082 LOG(LS_WARNING) << "Invalid FlexFEC SSRC given. "
83 << "This FlexfecReceiveStream will therefore be useless.";
84 return nullptr;
85 }
86 if (config.protected_media_ssrcs.empty()) {
87 LOG(LS_WARNING) << "No protected media SSRC supplied. "
88 << "This FlexfecReceiveStream will therefore be useless.";
89 return nullptr;
90 }
91
92 if (config.protected_media_ssrcs.size() > 1) {
brandtr76648da2016-10-20 04:54:48 -070093 LOG(LS_WARNING)
94 << "The supplied FlexfecConfig contained multiple protected "
95 "media streams, but our implementation currently only "
brandtr43c31e72016-11-15 05:26:45 -080096 "supports protecting a single media stream. "
97 "To avoid confusion, disabling FlexFEC completely.";
98 return nullptr;
brandtr76648da2016-10-20 04:54:48 -070099 }
brandtr43c31e72016-11-15 05:26:45 -0800100 RTC_DCHECK_EQ(1U, config.protected_media_ssrcs.size());
101 return std::unique_ptr<FlexfecReceiver>(
brandtr1cfbd602016-12-08 04:17:53 -0800102 new FlexfecReceiver(config.remote_ssrc, config.protected_media_ssrcs[0],
brandtrb29e6522016-12-21 06:37:18 -0800103 recovered_packet_receiver));
brandtr76648da2016-10-20 04:54:48 -0700104}
105
brandtrfa5a3682017-01-17 01:33:54 -0800106std::unique_ptr<RtpRtcp> CreateRtpRtcpModule(
107 ReceiveStatistics* receive_statistics,
108 Transport* rtcp_send_transport,
109 RtcpRttStats* rtt_stats) {
110 RtpRtcp::Configuration configuration;
111 configuration.audio = false;
112 configuration.receiver_only = true;
113 configuration.clock = Clock::GetRealTimeClock();
114 configuration.receive_statistics = receive_statistics;
115 configuration.outgoing_transport = rtcp_send_transport;
116 configuration.rtt_stats = rtt_stats;
117 std::unique_ptr<RtpRtcp> rtp_rtcp(RtpRtcp::CreateRtpRtcp(configuration));
118 return rtp_rtcp;
119}
120
brandtr76648da2016-10-20 04:54:48 -0700121} // namespace
122
brandtr7250b392016-12-19 01:13:46 -0800123FlexfecReceiveStreamImpl::FlexfecReceiveStreamImpl(
brandtr446fcb62016-12-08 04:14:24 -0800124 const Config& config,
brandtrfa5a3682017-01-17 01:33:54 -0800125 RecoveredPacketReceiver* recovered_packet_receiver,
126 RtcpRttStats* rtt_stats,
127 ProcessThread* process_thread)
128 : config_(config),
129 started_(false),
130 receiver_(MaybeCreateFlexfecReceiver(config_, recovered_packet_receiver)),
131 rtp_receive_statistics_(
132 ReceiveStatistics::Create(Clock::GetRealTimeClock())),
133 rtp_rtcp_(CreateRtpRtcpModule(rtp_receive_statistics_.get(),
134 config_.rtcp_send_transport,
135 rtt_stats)),
136 process_thread_(process_thread) {
brandtr7250b392016-12-19 01:13:46 -0800137 LOG(LS_INFO) << "FlexfecReceiveStreamImpl: " << config_.ToString();
brandtrfa5a3682017-01-17 01:33:54 -0800138
139 // RTCP reporting.
140 rtp_rtcp_->SetSendingMediaStatus(false);
141 rtp_rtcp_->SetRTCPStatus(config_.rtcp_mode);
142 rtp_rtcp_->SetSSRC(config_.local_ssrc);
143 process_thread_->RegisterModule(rtp_rtcp_.get());
brandtr76648da2016-10-20 04:54:48 -0700144}
145
brandtr7250b392016-12-19 01:13:46 -0800146FlexfecReceiveStreamImpl::~FlexfecReceiveStreamImpl() {
147 LOG(LS_INFO) << "~FlexfecReceiveStreamImpl: " << config_.ToString();
brandtr76648da2016-10-20 04:54:48 -0700148 Stop();
brandtrfa5a3682017-01-17 01:33:54 -0800149 process_thread_->DeRegisterModule(rtp_rtcp_.get());
brandtr76648da2016-10-20 04:54:48 -0700150}
151
brandtr7250b392016-12-19 01:13:46 -0800152bool FlexfecReceiveStreamImpl::AddAndProcessReceivedPacket(
brandtrfa5a3682017-01-17 01:33:54 -0800153 const RtpPacketReceived& packet) {
brandtr76648da2016-10-20 04:54:48 -0700154 {
155 rtc::CritScope cs(&crit_);
156 if (!started_)
157 return false;
158 }
brandtrfa5a3682017-01-17 01:33:54 -0800159
brandtr76648da2016-10-20 04:54:48 -0700160 if (!receiver_)
161 return false;
brandtrfa5a3682017-01-17 01:33:54 -0800162
163 if (!receiver_->AddAndProcessReceivedPacket(packet))
164 return false;
165
166 // Do not report media packets in the RTCP RRs generated by |rtp_rtcp_|.
167 if (packet.Ssrc() == config_.remote_ssrc) {
168 RTPHeader header;
169 packet.GetHeader(&header);
170 // FlexFEC packets are never retransmitted.
171 const bool kNotRetransmitted = false;
172 rtp_receive_statistics_->IncomingPacket(header, packet.size(),
173 kNotRetransmitted);
174 }
175
176 return true;
brandtr76648da2016-10-20 04:54:48 -0700177}
178
brandtr7250b392016-12-19 01:13:46 -0800179void FlexfecReceiveStreamImpl::Start() {
brandtr76648da2016-10-20 04:54:48 -0700180 rtc::CritScope cs(&crit_);
181 started_ = true;
182}
183
brandtr7250b392016-12-19 01:13:46 -0800184void FlexfecReceiveStreamImpl::Stop() {
brandtr76648da2016-10-20 04:54:48 -0700185 rtc::CritScope cs(&crit_);
186 started_ = false;
187}
188
189// TODO(brandtr): Implement this member function when we have designed the
190// stats for FlexFEC.
brandtr7250b392016-12-19 01:13:46 -0800191FlexfecReceiveStreamImpl::Stats FlexfecReceiveStreamImpl::GetStats() const {
192 return FlexfecReceiveStream::Stats();
brandtr76648da2016-10-20 04:54:48 -0700193}
194
brandtr76648da2016-10-20 04:54:48 -0700195} // namespace webrtc