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

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

Issue 2553863003: Parse FlexFEC RTP headers in Call and add integration with BWE. (Closed)
Patch Set: Work in progress. Created 4 years 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
1 /* 1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/rtp_rtcp/include/flexfec_receiver.h" 11 #include "webrtc/modules/rtp_rtcp/include/flexfec_receiver.h"
12 12
13 #include <utility> 13 #include <utility>
14 14
15 #include "webrtc/base/logging.h" 15 #include "webrtc/base/logging.h"
16 #include "webrtc/base/scoped_ref_ptr.h" 16 #include "webrtc/base/scoped_ref_ptr.h"
17 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimat or.h"
18 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h"
17 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h" 19 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h"
18 20
19 namespace webrtc { 21 namespace webrtc {
20 22
21 namespace { 23 namespace {
22 24
23 using Packet = ForwardErrorCorrection::Packet; 25 using Packet = ForwardErrorCorrection::Packet;
24 using ReceivedPacket = ForwardErrorCorrection::ReceivedPacket; 26 using ReceivedPacket = ForwardErrorCorrection::ReceivedPacket;
25 27
26 // Minimum header size (in bytes) of a well-formed non-singular FlexFEC packet. 28 // Minimum header size (in bytes) of a well-formed non-singular FlexFEC packet.
27 constexpr size_t kMinFlexfecHeaderSize = 20; 29 constexpr size_t kMinFlexfecHeaderSize = 20;
28 30
29 // How often to log the recovered packets to the text log. 31 // How often to log the recovered packets to the text log.
30 constexpr int kPacketLogIntervalMs = 10000; 32 constexpr int kPacketLogIntervalMs = 10000;
31 33
34 bool HasBweExtension(const RtpPacketReceived& packet) {
35 if (packet.HasExtension<TransportSequenceNumber>()) {
danilchap 2016/12/06 15:04:30 may be return packet.HasExtension<TransportSequenc
brandtr 2016/12/12 13:51:08 Done.
36 return true;
37 } else if (packet.HasExtension<AbsoluteSendTime>()) {
38 return true;
39 } else if (packet.HasExtension<TransmissionOffset>()) {
40 return true;
41 }
42 return false;
43 }
44
32 } // namespace 45 } // namespace
33 46
34 FlexfecReceiver::FlexfecReceiver(uint32_t ssrc, 47 FlexfecReceiver::FlexfecReceiver(
35 uint32_t protected_media_ssrc, 48 uint32_t ssrc,
36 RecoveredPacketReceiver* callback) 49 uint32_t protected_media_ssrc,
50 RecoveredPacketReceiver* recovered_packet_receiver,
51 RemoteBitrateEstimator* remote_bitrate_estimator)
37 : ssrc_(ssrc), 52 : ssrc_(ssrc),
38 protected_media_ssrc_(protected_media_ssrc), 53 protected_media_ssrc_(protected_media_ssrc),
39 erasure_code_(ForwardErrorCorrection::CreateFlexfec()), 54 erasure_code_(ForwardErrorCorrection::CreateFlexfec()),
40 callback_(callback), 55 recovered_packet_receiver_(recovered_packet_receiver),
56 remote_bitrate_estimator_(remote_bitrate_estimator),
41 clock_(Clock::GetRealTimeClock()), 57 clock_(Clock::GetRealTimeClock()),
42 last_recovered_packet_ms_(-1) { 58 last_recovered_packet_ms_(-1) {
43 // It's OK to create this object on a different thread/task queue than 59 // It's OK to create this object on a different thread/task queue than
44 // the one used during main operation. 60 // the one used during main operation.
45 sequence_checker_.Detach(); 61 sequence_checker_.Detach();
46 } 62 }
47 63
48 FlexfecReceiver::~FlexfecReceiver() = default; 64 FlexfecReceiver::~FlexfecReceiver() = default;
49 65
50 bool FlexfecReceiver::AddAndProcessReceivedPacket(const uint8_t* packet, 66 bool FlexfecReceiver::AddAndProcessReceivedPacket(RtpPacketReceived packet) {
51 size_t packet_length) {
52 RTC_DCHECK(sequence_checker_.CalledSequentially()); 67 RTC_DCHECK(sequence_checker_.CalledSequentially());
53 68
54 if (!AddReceivedPacket(packet, packet_length)) { 69 if (!AddReceivedPacket(std::move(packet))) {
55 return false; 70 return false;
56 } 71 }
57 return ProcessReceivedPackets(); 72 return ProcessReceivedPackets();
58 } 73 }
59 74
60 FecPacketCounter FlexfecReceiver::GetPacketCounter() const { 75 FecPacketCounter FlexfecReceiver::GetPacketCounter() const {
61 RTC_DCHECK(sequence_checker_.CalledSequentially()); 76 RTC_DCHECK(sequence_checker_.CalledSequentially());
62 return packet_counter_; 77 return packet_counter_;
63 } 78 }
64 79
65 bool FlexfecReceiver::AddReceivedPacket(const uint8_t* packet, 80 bool FlexfecReceiver::AddReceivedPacket(RtpPacketReceived packet) {
66 size_t packet_length) {
67 RTC_DCHECK(sequence_checker_.CalledSequentially()); 81 RTC_DCHECK(sequence_checker_.CalledSequentially());
68 82
69 // RTP packets with a full base header (12 bytes), but without payload, 83 // RTP packets with a full base header (12 bytes), but without payload,
70 // could conceivably be useful in the decoding. Therefore we check 84 // could conceivably be useful in the decoding. Therefore we check
71 // with a strict inequality here. 85 // with a strict inequality here.
72 if (packet_length < kRtpHeaderSize) { 86 if (packet.size() < kRtpHeaderSize) {
danilchap 2016/12/06 15:04:30 feel free to DCHECK now instead: RtpPacket should
brandtr 2016/12/12 13:51:07 Done.
73 LOG(LS_WARNING) << "Truncated packet, discarding."; 87 LOG(LS_WARNING) << "Truncated packet, discarding.";
74 return false; 88 return false;
75 } 89 }
76 90
77 // TODO(brandtr): Consider how to handle received FlexFEC packets and
78 // the bandwidth estimator.
79 RtpPacketReceived parsed_packet;
80 if (!parsed_packet.Parse(packet, packet_length)) {
81 return false;
82 }
83
84 // Demultiplex based on SSRC, and insert into erasure code decoder. 91 // Demultiplex based on SSRC, and insert into erasure code decoder.
85 std::unique_ptr<ReceivedPacket> received_packet(new ReceivedPacket()); 92 std::unique_ptr<ReceivedPacket> received_packet(new ReceivedPacket());
86 received_packet->seq_num = parsed_packet.SequenceNumber(); 93 received_packet->seq_num = packet.SequenceNumber();
87 received_packet->ssrc = parsed_packet.Ssrc(); 94 received_packet->ssrc = packet.Ssrc();
88 if (received_packet->ssrc == ssrc_) { 95 if (received_packet->ssrc == ssrc_) {
89 // This is a FEC packet belonging to this FlexFEC stream. 96 // This is a FlexFEC packet.
90 if (parsed_packet.payload_size() < kMinFlexfecHeaderSize) { 97 if (packet.payload_size() < kMinFlexfecHeaderSize) {
91 LOG(LS_WARNING) << "Truncated FlexFEC packet, discarding."; 98 LOG(LS_WARNING) << "Truncated FlexFEC packet, discarding.";
92 return false; 99 return false;
93 } 100 }
94 received_packet->is_fec = true; 101 received_packet->is_fec = true;
95 ++packet_counter_.num_fec_packets; 102 ++packet_counter_.num_fec_packets;
103
104 // Notify BWE.
105 if (HasBweExtension(packet)) {
106 RTPHeader header;
107 packet.GetHeader(&header);
108 remote_bitrate_estimator_->IncomingPacket(packet.arrival_time_ms(),
109 packet.payload_size(), header);
110 }
111
96 // Insert packet payload into erasure code. 112 // Insert packet payload into erasure code.
97 // TODO(brandtr): Remove this memcpy when the FEC packet classes 113 // TODO(brandtr): Remove this memcpy when the FEC packet classes
98 // are using COW buffers internally. 114 // are using COW buffers internally.
99 received_packet->pkt = rtc::scoped_refptr<Packet>(new Packet()); 115 received_packet->pkt = rtc::scoped_refptr<Packet>(new Packet());
100 auto payload = parsed_packet.payload(); 116 auto payload = packet.payload();
101 memcpy(received_packet->pkt->data, payload.data(), payload.size()); 117 memcpy(received_packet->pkt->data, payload.data(), payload.size());
102 received_packet->pkt->length = payload.size(); 118 received_packet->pkt->length = payload.size();
103 } else { 119 } else {
104 // This is a media packet, or a FlexFEC packet belonging to some 120 // This is a media packet, or a FlexFEC packet belonging to some
105 // other FlexFEC stream. 121 // other FlexFEC stream.
106 if (received_packet->ssrc != protected_media_ssrc_) { 122 if (received_packet->ssrc != protected_media_ssrc_) {
107 return false; 123 return false;
108 } 124 }
109 received_packet->is_fec = false; 125 received_packet->is_fec = false;
126
110 // Insert entire packet into erasure code. 127 // Insert entire packet into erasure code.
111 // TODO(brandtr): Remove this memcpy too. 128 // TODO(brandtr): Remove this memcpy too.
112 received_packet->pkt = rtc::scoped_refptr<Packet>(new Packet()); 129 received_packet->pkt = rtc::scoped_refptr<Packet>(new Packet());
113 memcpy(received_packet->pkt->data, parsed_packet.data(), 130 memcpy(received_packet->pkt->data, packet.data(), packet.size());
114 parsed_packet.size()); 131 received_packet->pkt->length = packet.size();
115 received_packet->pkt->length = parsed_packet.size();
116 } 132 }
133
117 received_packets_.push_back(std::move(received_packet)); 134 received_packets_.push_back(std::move(received_packet));
118 ++packet_counter_.num_packets; 135 ++packet_counter_.num_packets;
119 136
120 return true; 137 return true;
121 } 138 }
122 139
123 // Note that the implementation of this member function and the implementation 140 // Note that the implementation of this member function and the implementation
124 // in UlpfecReceiver::ProcessReceivedFec() are slightly different. 141 // in UlpfecReceiver::ProcessReceivedFec() are slightly different.
125 // This implementation only returns _recovered_ media packets through the 142 // This implementation only returns _recovered_ media packets through the
126 // callback, whereas the implementation in UlpfecReceiver returns _all inserted_ 143 // callback, whereas the implementation in UlpfecReceiver returns _all inserted_
(...skipping 11 matching lines...) Expand all
138 0) { 155 0) {
139 return false; 156 return false;
140 } 157 }
141 } 158 }
142 // Return recovered packets through callback. 159 // Return recovered packets through callback.
143 for (const auto& recovered_packet : recovered_packets_) { 160 for (const auto& recovered_packet : recovered_packets_) {
144 if (recovered_packet->returned) { 161 if (recovered_packet->returned) {
145 continue; 162 continue;
146 } 163 }
147 ++packet_counter_.num_recovered_packets; 164 ++packet_counter_.num_recovered_packets;
148 if (!callback_->OnRecoveredPacket(recovered_packet->pkt->data, 165 if (!recovered_packet_receiver_->OnRecoveredPacket(
149 recovered_packet->pkt->length)) { 166 recovered_packet->pkt->data, recovered_packet->pkt->length)) {
150 return false; 167 return false;
151 } 168 }
152 recovered_packet->returned = true; 169 recovered_packet->returned = true;
153 // Periodically log the incoming packets. 170 // Periodically log the incoming packets.
154 int64_t now_ms = clock_->TimeInMilliseconds(); 171 int64_t now_ms = clock_->TimeInMilliseconds();
155 if (now_ms - last_recovered_packet_ms_ > kPacketLogIntervalMs) { 172 if (now_ms - last_recovered_packet_ms_ > kPacketLogIntervalMs) {
156 uint32_t media_ssrc = 173 uint32_t media_ssrc =
157 ForwardErrorCorrection::ParseSsrc(recovered_packet->pkt->data); 174 ForwardErrorCorrection::ParseSsrc(recovered_packet->pkt->data);
158 LOG(LS_INFO) << "Recovered media packet with SSRC: " << media_ssrc 175 LOG(LS_INFO) << "Recovered media packet with SSRC: " << media_ssrc
159 << " from FlexFEC stream with SSRC: " << ssrc_ << "."; 176 << " from FlexFEC stream with SSRC: " << ssrc_ << ".";
160 last_recovered_packet_ms_ = now_ms; 177 last_recovered_packet_ms_ = now_ms;
161 } 178 }
162 } 179 }
163 return true; 180 return true;
164 } 181 }
165 182
166 } // namespace webrtc 183 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698