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

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

Issue 2441613002: Add FlexfecSender. (Closed)
Patch Set: Created 4 years, 2 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 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 constexpr uint16_t kMaxInitRtpSeqNumber = 32767; // 2^15 -1.
25
26 // Conversion between NTP millisecond time and RTP timestamp.
27 constexpr int kMsToRtpTimestamp = 90;
danilchap 2016/10/20 15:12:57 does the frequency has to be same as for video str
brandtr 2016/10/24 12:52:08 It doesn't have to be, but it's "RECOMMENDED" that
danilchap 2016/10/24 13:40:31 Sorry used too strong wording, I meant 'is there a
28
29 // How often to log the generated FEC packets to the text log.
30 constexpr int kPacketLogIntervalMs = 10000;
31
32 } // namespace
33
34 std::unique_ptr<FlexfecSender> FlexfecSender::Create(
35 int flexfec_payload_type,
36 uint32_t flexfec_ssrc,
37 uint32_t protected_media_ssrc,
38 std::vector<RtpExtension> rtp_header_extensions,
39 Clock* clock) {
40 // Don't instantiate this object if FlexFEC is disabled.
41 RTC_DCHECK_GE(flexfec_payload_type, 0);
42 RTC_DCHECK_LE(flexfec_payload_type, 127);
43 return std::unique_ptr<FlexfecSender>(new FlexfecSenderImpl(
44 flexfec_payload_type, flexfec_ssrc, protected_media_ssrc,
45 rtp_header_extensions, clock));
danilchap 2016/10/20 15:12:57 std::move(rtp_header_extensions) (otherwise vector
brandtr 2016/10/24 12:52:07 Yep, this should be const&. Thanks!
46 }
47
48 FlexfecSenderImpl::FlexfecSenderImpl(
49 int flexfec_payload_type,
50 uint32_t flexfec_ssrc,
51 uint32_t protected_media_ssrc,
52 std::vector<RtpExtension> rtp_header_extensions,
53 Clock* clock)
54 : clock_(clock),
55 random_(clock_->TimeInMicroseconds()),
56 last_generated_packet_ms_(-1),
57 flexfec_payload_type_(flexfec_payload_type),
58 // Initialize the RTP sequence numbers and timestamp offset randomly.
59 // (This is not intended to be cryptographically strong.)
60 seq_num_(random_.Rand(1, kMaxInitRtpSeqNumber)),
61 timestamp_offset_(random_.Rand<uint32_t>()),
62 flexfec_ssrc_(flexfec_ssrc),
63 protected_media_ssrc_(protected_media_ssrc),
64 ulpfec_sender_(ForwardErrorCorrection::CreateFlexfec()),
65 rtp_header_extension_map_() {
66 // It's OK to create this object on a different thread/task queue than
67 // the one used during main operation.
68 sequence_checker_.Detach();
69
70 // Register RTP header extensions.
danilchap 2016/10/20 15:12:57 Does FlexfecSender has to know full list of bwe ex
brandtr 2016/10/24 12:52:07 Yes, it needs to know about all BWE extensions, si
71 for (const auto& extension : rtp_header_extensions) {
72 if (extension.uri == RtpExtension::kTransportSequenceNumberUri) {
73 rtp_header_extension_map_.Register(kRtpExtensionTransportSequenceNumber,
74 extension.id);
75 } else if (extension.uri == RtpExtension::kAbsSendTimeUri) {
76 rtp_header_extension_map_.Register(kRtpExtensionAbsoluteSendTime,
77 extension.id);
78 } else if (extension.uri == RtpExtension::kTimestampOffsetUri) {
79 rtp_header_extension_map_.Register(kRtpExtensionTransmissionTimeOffset,
80 extension.id);
81 } else {
82 LOG(LS_WARNING) << "RTP header extension with id: " << extension.id
83 << ", uri: " << extension.uri
84 << ", is unsupported by FlexfecSender.";
85 }
86 }
87 }
88
89 FlexfecSenderImpl::~FlexfecSenderImpl() = default;
90
91 // We are reusing the implementation from ProducerFec for SetFecParameters,
92 // AddRtpPacketAndGenerateFec, and FecAvailable.
93 void FlexfecSenderImpl::SetFecParameters(const FecProtectionParams* params) {
94 RTC_DCHECK(sequence_checker_.CalledSequentially());
95 ulpfec_sender_.SetFecParameters(params);
96 }
97
98 int FlexfecSenderImpl::AddRtpPacketAndGenerateFec(RtpPacketToSend* packet) {
danilchap 2016/10/20 15:12:57 does parameter need to be non-const? May be it can
brandtr 2016/10/24 12:52:07 Good idea, done!
99 RTC_DCHECK(sequence_checker_.CalledSequentially());
100 if (packet->Ssrc() != protected_media_ssrc_) {
101 return 0;
102 }
103 return ulpfec_sender_.AddRtpPacketAndGenerateFec(
104 packet->data(), packet->payload_size(), packet->headers_size());
105 }
106
107 bool FlexfecSenderImpl::FecAvailable() const {
108 RTC_DCHECK(sequence_checker_.CalledSequentially());
109 return ulpfec_sender_.FecAvailable();
110 }
111
112 std::vector<std::unique_ptr<RtpPacketToSend>>
113 FlexfecSenderImpl::GetFecPackets() {
114 RTC_DCHECK(sequence_checker_.CalledSequentially());
115
116 std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets_to_send;
117 fec_packets_to_send.reserve(ulpfec_sender_.generated_fec_packets_.size());
118 for (const auto& fec_packet : ulpfec_sender_.generated_fec_packets_) {
119 std::unique_ptr<RtpPacketToSend> fec_packet_to_send(
120 new RtpPacketToSend(&rtp_header_extension_map_));
121
122 // RTP header.
123 fec_packet_to_send->SetMarker(false);
124 fec_packet_to_send->SetPayloadType(flexfec_payload_type_);
125 fec_packet_to_send->SetSequenceNumber(seq_num_++);
126 fec_packet_to_send->SetTimestamp(
127 timestamp_offset_ +
128 kMsToRtpTimestamp *
129 static_cast<uint32_t>(clock_->CurrentNtpInMilliseconds()));
danilchap 2016/10/20 15:12:57 Does it have to be based on ntp? may be base it on
brandtr 2016/10/24 12:52:08 Cool, didn't think about the monotonicity. It can
130 fec_packet_to_send->SetSsrc(flexfec_ssrc_);
131 // Reserve extensions, if registered. These will be set by the RtpSender.
danilchap 2016/10/20 15:12:57 fec_packet_to_send->set_capture_time_ms(...) other
brandtr 2016/10/24 12:52:07 Done.
132 fec_packet_to_send->ReserveExtension<AbsoluteSendTime>();
133 fec_packet_to_send->ReserveExtension<TransmissionOffset>();
134 fec_packet_to_send->ReserveExtension<TransportSequenceNumber>();
135
136 // RTP payload.
137 uint8_t* payload = fec_packet_to_send->AllocatePayload(fec_packet->length);
138 memcpy(payload, fec_packet->data, fec_packet->length);
139
140 fec_packets_to_send.push_back(std::move(fec_packet_to_send));
141 }
142 ulpfec_sender_.ResetState();
143
144 // Periodically log generated FEC packets.
145 int64_t now_ms = clock_->TimeInMilliseconds();
146 if (!fec_packets_to_send.empty() &&
147 now_ms - last_generated_packet_ms_ > kPacketLogIntervalMs) {
148 std::stringstream ss;
danilchap 2016/10/20 15:12:57 probably better to avoid stringstream: Currently s
brandtr 2016/10/24 12:52:08 Done.
149 ss << "Generated " << fec_packets_to_send.size() << " FlexFEC packets with "
150 << "payload type: " << flexfec_payload_type_
151 << " and SSRC: " << flexfec_ssrc_ << ".";
152 LOG(LS_INFO) << ss.str();
153 last_generated_packet_ms_ = now_ms;
154 }
155
156 return fec_packets_to_send;
157 }
158
159 // This member function is called from the pacer thread sometimes. No need
160 // for synchronization however, since it always returns the same constant.
161 // TODO(brandtr): Remove the underlying call and make the packet overhead
162 // explicit here.
163 size_t FlexfecSenderImpl::MaxPacketOverhead() const {
164 return ulpfec_sender_.MaxPacketOverhead();
165 }
166
167 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698