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

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

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

Powered by Google App Engine
This is Rietveld 408576698