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

Side by Side Diff: webrtc/modules/rtp_rtcp/source/flexfec_sender_impl.cc

Issue 2441613002: Add FlexfecSender. (Closed)
Patch Set: DCHECK on unprotected media SSRC added instead. Created 4 years, 1 month 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 unified diff | Download patch
OLDNEW
(Empty)
1 /*
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
11 #include "webrtc/modules/rtp_rtcp/source/flexfec_sender_impl.h"
12
13 #include <utility>
14
15 #include "webrtc/base/logging.h"
16 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
17 #include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
18 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h"
19
20 namespace webrtc {
21
22 namespace {
23
24 // Let first sequence number be in the first half of the interval.
25 constexpr uint16_t kMaxInitRtpSeqNumber = 0x7fff;
26
27 // See breakdown in flexfec_header_reader_writer.cc.
28 constexpr size_t kFlexfecMaxHeaderSize = 32;
29
30 // Since we will mainly use FlexFEC to protect video streams, we use a 90 kHz
31 // clock for the RTP timestamps. (This is according to the RFC, which states
32 // that it is RECOMMENDED to use the same clock frequency for FlexFEC as for
33 // the protected media stream.)
34 // The constant converts from clock millisecond timestamps to the 90 kHz
35 // RTP timestamp.
36 const int kMsToRtpTimestamp = kVideoPayloadTypeFrequency / 1000;
37
38 // How often to log the generated FEC packets to the text log.
39 constexpr int64_t kPacketLogIntervalMs = 10000;
40
41 } // namespace
42
43 std::unique_ptr<FlexfecSender> FlexfecSender::Create(
44 int flexfec_payload_type,
45 uint32_t flexfec_ssrc,
46 uint32_t protected_media_ssrc,
47 const std::vector<RtpExtension>& rtp_header_extensions,
48 Clock* clock) {
49 // This object should not have been instantiated if FlexFEC is disabled.
50 RTC_DCHECK_GE(flexfec_payload_type, 0);
51 RTC_DCHECK_LE(flexfec_payload_type, 127);
52 return std::unique_ptr<FlexfecSender>(new FlexfecSenderImpl(
53 flexfec_payload_type, flexfec_ssrc, protected_media_ssrc,
54 rtp_header_extensions, clock));
55 }
56
57 FlexfecSenderImpl::FlexfecSenderImpl(
58 int flexfec_payload_type,
59 uint32_t flexfec_ssrc,
60 uint32_t protected_media_ssrc,
61 const std::vector<RtpExtension>& rtp_header_extensions,
62 Clock* clock)
63 : clock_(clock),
64 random_(clock_->TimeInMicroseconds()),
65 last_generated_packet_ms_(-1),
66 flexfec_payload_type_(flexfec_payload_type),
67 // Initialize the timestamp offset and RTP sequence numbers and randomly.
68 // (This is not intended to be cryptographically strong.)
69 timestamp_offset_(random_.Rand<uint32_t>()),
70 flexfec_ssrc_(flexfec_ssrc),
71 protected_media_ssrc_(protected_media_ssrc),
72 seq_num_(random_.Rand(1, kMaxInitRtpSeqNumber)),
73 ulpfec_generator_(ForwardErrorCorrection::CreateFlexfec()),
74 rtp_header_extension_map_() {
75 // It's OK to create this object on a different thread/task queue than
76 // the one used during main operation.
77 sequence_checker_.Detach();
78
79 // Register RTP header extensions for BWE.
80 for (const auto& extension : rtp_header_extensions) {
81 if (extension.uri == RtpExtension::kTransportSequenceNumberUri) {
82 rtp_header_extension_map_.Register(kRtpExtensionTransportSequenceNumber,
83 extension.id);
84 } else if (extension.uri == RtpExtension::kAbsSendTimeUri) {
85 rtp_header_extension_map_.Register(kRtpExtensionAbsoluteSendTime,
86 extension.id);
87 } else if (extension.uri == RtpExtension::kTimestampOffsetUri) {
88 rtp_header_extension_map_.Register(kRtpExtensionTransmissionTimeOffset,
89 extension.id);
90 } else {
91 LOG(LS_WARNING) << "RTP header extension with id: " << extension.id
92 << ", uri: " << extension.uri
93 << ", is unsupported by FlexfecSender.";
94 }
95 }
96 }
97
98 FlexfecSenderImpl::~FlexfecSenderImpl() = default;
99
100 // We are reusing the implementation from ProducerFec for SetFecParameters,
101 // AddRtpPacketAndGenerateFec, and FecAvailable.
102 void FlexfecSenderImpl::SetFecParameters(const FecProtectionParams& params) {
103 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
104 ulpfec_generator_.SetFecParameters(&params);
105 }
106
107 bool FlexfecSenderImpl::AddRtpPacketAndGenerateFec(
108 const RtpPacketToSend& packet) {
109 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
110 // TODO(brandtr): Generalize this SSRC check when we support multistream
111 // protection.
112 RTC_DCHECK(packet.Ssrc() == protected_media_ssrc_);
danilchap 2016/10/26 12:08:41 RTC_DCHECK_EQ
brandtr 2016/10/26 12:20:53 Done.
113 return ulpfec_generator_.AddRtpPacketAndGenerateFec(
114 packet.data(), packet.payload_size(), packet.headers_size()) == 0;
115 }
116
117 bool FlexfecSenderImpl::FecAvailable() const {
118 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
119 return ulpfec_generator_.FecAvailable();
120 }
121
122 std::vector<std::unique_ptr<RtpPacketToSend>>
123 FlexfecSenderImpl::GetFecPackets() {
124 RTC_DCHECK_CALLED_SEQUENTIALLY(&sequence_checker_);
125
126 std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets_to_send;
127 fec_packets_to_send.reserve(ulpfec_generator_.generated_fec_packets_.size());
128 for (const auto& fec_packet : ulpfec_generator_.generated_fec_packets_) {
129 std::unique_ptr<RtpPacketToSend> fec_packet_to_send(
130 new RtpPacketToSend(&rtp_header_extension_map_));
131
132 // RTP header.
133 fec_packet_to_send->SetMarker(false);
134 fec_packet_to_send->SetPayloadType(flexfec_payload_type_);
135 fec_packet_to_send->SetSequenceNumber(seq_num_++);
136 fec_packet_to_send->SetTimestamp(
137 timestamp_offset_ +
138 static_cast<uint32_t>(kMsToRtpTimestamp *
139 clock_->TimeInMilliseconds()));
140 // Set "capture time" so that the TransmissionOffset header extension
141 // can be set by the RTPSender.
142 fec_packet_to_send->set_capture_time_ms(clock_->TimeInMilliseconds());
143 fec_packet_to_send->SetSsrc(flexfec_ssrc_);
144 // Reserve extensions, if registered. These will be set by the RTPSender.
145 fec_packet_to_send->ReserveExtension<AbsoluteSendTime>();
146 fec_packet_to_send->ReserveExtension<TransmissionOffset>();
147 fec_packet_to_send->ReserveExtension<TransportSequenceNumber>();
148
149 // RTP payload.
150 uint8_t* payload = fec_packet_to_send->AllocatePayload(fec_packet->length);
151 memcpy(payload, fec_packet->data, fec_packet->length);
152
153 fec_packets_to_send.push_back(std::move(fec_packet_to_send));
154 }
155 ulpfec_generator_.ResetState();
156
157 // Periodically log generated FEC packets.
158 int64_t now_ms = clock_->TimeInMilliseconds();
159 if (!fec_packets_to_send.empty() &&
160 now_ms - last_generated_packet_ms_ > kPacketLogIntervalMs) {
161 LOG(LS_INFO) << "Generated " << fec_packets_to_send.size()
162 << " FlexFEC packets with payload type: "
163 << flexfec_payload_type_ << " and SSRC: " << flexfec_ssrc_
164 << ".";
165 last_generated_packet_ms_ = now_ms;
166 }
167
168 return fec_packets_to_send;
169 }
170
171 size_t FlexfecSenderImpl::MaxPacketOverhead() const {
172 return kFlexfecMaxHeaderSize;
173 }
174
175 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698