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

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: nisse comments 1. 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/rtp_rtcp/source/rtp_packet_received.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"
18 19
19 namespace webrtc { 20 namespace webrtc {
20 21
21 namespace { 22 namespace {
22 23
23 using Packet = ForwardErrorCorrection::Packet; 24 using Packet = ForwardErrorCorrection::Packet;
24 using ReceivedPacket = ForwardErrorCorrection::ReceivedPacket; 25 using ReceivedPacket = ForwardErrorCorrection::ReceivedPacket;
25 26
26 // Minimum header size (in bytes) of a well-formed non-singular FlexFEC packet. 27 // Minimum header size (in bytes) of a well-formed non-singular FlexFEC packet.
27 constexpr size_t kMinFlexfecHeaderSize = 20; 28 constexpr size_t kMinFlexfecHeaderSize = 20;
28 29
29 // How often to log the recovered packets to the text log. 30 // How often to log the recovered packets to the text log.
30 constexpr int kPacketLogIntervalMs = 10000; 31 constexpr int kPacketLogIntervalMs = 10000;
31 32
33 bool HasBweExtension(const RtpPacketReceived& packet) {
34 return packet.HasExtension<TransportSequenceNumber>() ||
35 packet.HasExtension<AbsoluteSendTime>() ||
36 packet.HasExtension<TransmissionOffset>();
37 }
38
32 } // namespace 39 } // namespace
33 40
34 FlexfecReceiver::FlexfecReceiver(uint32_t ssrc, 41 FlexfecReceiver::FlexfecReceiver(
35 uint32_t protected_media_ssrc, 42 uint32_t ssrc,
36 RecoveredPacketReceiver* callback) 43 uint32_t protected_media_ssrc,
44 RecoveredPacketReceiver* recovered_packet_receiver,
45 RemoteBitrateEstimator* remote_bitrate_estimator)
37 : ssrc_(ssrc), 46 : ssrc_(ssrc),
38 protected_media_ssrc_(protected_media_ssrc), 47 protected_media_ssrc_(protected_media_ssrc),
39 erasure_code_(ForwardErrorCorrection::CreateFlexfec()), 48 erasure_code_(ForwardErrorCorrection::CreateFlexfec()),
40 callback_(callback), 49 recovered_packet_receiver_(recovered_packet_receiver),
50 remote_bitrate_estimator_(remote_bitrate_estimator),
41 clock_(Clock::GetRealTimeClock()), 51 clock_(Clock::GetRealTimeClock()),
42 last_recovered_packet_ms_(-1) { 52 last_recovered_packet_ms_(-1) {
43 // It's OK to create this object on a different thread/task queue than 53 // It's OK to create this object on a different thread/task queue than
44 // the one used during main operation. 54 // the one used during main operation.
45 sequence_checker_.Detach(); 55 sequence_checker_.Detach();
46 } 56 }
47 57
48 FlexfecReceiver::~FlexfecReceiver() = default; 58 FlexfecReceiver::~FlexfecReceiver() = default;
49 59
50 bool FlexfecReceiver::AddAndProcessReceivedPacket(const uint8_t* packet, 60 bool FlexfecReceiver::AddAndProcessReceivedPacket(RtpPacketReceived packet) {
51 size_t packet_length) {
52 RTC_DCHECK(sequence_checker_.CalledSequentially()); 61 RTC_DCHECK(sequence_checker_.CalledSequentially());
53 62
54 if (!AddReceivedPacket(packet, packet_length)) { 63 if (!AddReceivedPacket(std::move(packet))) {
55 return false; 64 return false;
56 } 65 }
57 return ProcessReceivedPackets(); 66 return ProcessReceivedPackets();
58 } 67 }
59 68
60 FecPacketCounter FlexfecReceiver::GetPacketCounter() const { 69 FecPacketCounter FlexfecReceiver::GetPacketCounter() const {
61 RTC_DCHECK(sequence_checker_.CalledSequentially()); 70 RTC_DCHECK(sequence_checker_.CalledSequentially());
62 return packet_counter_; 71 return packet_counter_;
63 } 72 }
64 73
65 bool FlexfecReceiver::AddReceivedPacket(const uint8_t* packet, 74 bool FlexfecReceiver::AddReceivedPacket(RtpPacketReceived packet) {
66 size_t packet_length) {
67 RTC_DCHECK(sequence_checker_.CalledSequentially()); 75 RTC_DCHECK(sequence_checker_.CalledSequentially());
68 76
69 // RTP packets with a full base header (12 bytes), but without payload, 77 // RTP packets with a full base header (12 bytes), but without payload,
70 // could conceivably be useful in the decoding. Therefore we check 78 // could conceivably be useful in the decoding. Therefore we check
71 // with a strict inequality here. 79 // with a non-strict inequality here.
72 if (packet_length < kRtpHeaderSize) { 80 RTC_DCHECK_GE(packet.size(), kRtpHeaderSize);
73 LOG(LS_WARNING) << "Truncated packet, discarding.";
74 return false;
75 }
76
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 81
84 // Demultiplex based on SSRC, and insert into erasure code decoder. 82 // Demultiplex based on SSRC, and insert into erasure code decoder.
85 std::unique_ptr<ReceivedPacket> received_packet(new ReceivedPacket()); 83 std::unique_ptr<ReceivedPacket> received_packet(new ReceivedPacket());
86 received_packet->seq_num = parsed_packet.SequenceNumber(); 84 received_packet->seq_num = packet.SequenceNumber();
87 received_packet->ssrc = parsed_packet.Ssrc(); 85 received_packet->ssrc = packet.Ssrc();
88 if (received_packet->ssrc == ssrc_) { 86 if (received_packet->ssrc == ssrc_) {
89 // This is a FEC packet belonging to this FlexFEC stream. 87 // This is a FlexFEC packet.
90 if (parsed_packet.payload_size() < kMinFlexfecHeaderSize) { 88 if (packet.payload_size() < kMinFlexfecHeaderSize) {
91 LOG(LS_WARNING) << "Truncated FlexFEC packet, discarding."; 89 LOG(LS_WARNING) << "Truncated FlexFEC packet, discarding.";
92 return false; 90 return false;
93 } 91 }
94 received_packet->is_fec = true; 92 received_packet->is_fec = true;
95 ++packet_counter_.num_fec_packets; 93 ++packet_counter_.num_fec_packets;
94
95 // Notify BWE.
danilchap 2016/12/13 14:11:24 why is it done all the way down here rather than i
brandtr 2016/12/14 12:55:49 I forgot that Call demuxes based on SSRC, so we co
96 if (HasBweExtension(packet)) {
97 RTPHeader header;
98 packet.GetHeader(&header);
99 remote_bitrate_estimator_->IncomingPacket(packet.arrival_time_ms(),
100 packet.payload_size(), header);
101 }
102
96 // Insert packet payload into erasure code. 103 // Insert packet payload into erasure code.
97 // TODO(brandtr): Remove this memcpy when the FEC packet classes 104 // TODO(brandtr): Remove this memcpy when the FEC packet classes
98 // are using COW buffers internally. 105 // are using COW buffers internally.
99 received_packet->pkt = rtc::scoped_refptr<Packet>(new Packet()); 106 received_packet->pkt = rtc::scoped_refptr<Packet>(new Packet());
100 auto payload = parsed_packet.payload(); 107 auto payload = packet.payload();
101 memcpy(received_packet->pkt->data, payload.data(), payload.size()); 108 memcpy(received_packet->pkt->data, payload.data(), payload.size());
102 received_packet->pkt->length = payload.size(); 109 received_packet->pkt->length = payload.size();
103 } else { 110 } else {
104 // This is a media packet, or a FlexFEC packet belonging to some 111 // This is a media packet, or a FlexFEC packet belonging to some
105 // other FlexFEC stream. 112 // other FlexFEC stream.
106 if (received_packet->ssrc != protected_media_ssrc_) { 113 if (received_packet->ssrc != protected_media_ssrc_) {
107 return false; 114 return false;
108 } 115 }
109 received_packet->is_fec = false; 116 received_packet->is_fec = false;
117
110 // Insert entire packet into erasure code. 118 // Insert entire packet into erasure code.
111 // TODO(brandtr): Remove this memcpy too. 119 // TODO(brandtr): Remove this memcpy too.
112 received_packet->pkt = rtc::scoped_refptr<Packet>(new Packet()); 120 received_packet->pkt = rtc::scoped_refptr<Packet>(new Packet());
113 memcpy(received_packet->pkt->data, parsed_packet.data(), 121 memcpy(received_packet->pkt->data, packet.data(), packet.size());
114 parsed_packet.size()); 122 received_packet->pkt->length = packet.size();
115 received_packet->pkt->length = parsed_packet.size();
116 } 123 }
124
117 received_packets_.push_back(std::move(received_packet)); 125 received_packets_.push_back(std::move(received_packet));
118 ++packet_counter_.num_packets; 126 ++packet_counter_.num_packets;
119 127
120 return true; 128 return true;
121 } 129 }
122 130
123 // Note that the implementation of this member function and the implementation 131 // Note that the implementation of this member function and the implementation
124 // in UlpfecReceiver::ProcessReceivedFec() are slightly different. 132 // in UlpfecReceiver::ProcessReceivedFec() are slightly different.
125 // This implementation only returns _recovered_ media packets through the 133 // This implementation only returns _recovered_ media packets through the
126 // callback, whereas the implementation in UlpfecReceiver returns _all inserted_ 134 // callback, whereas the implementation in UlpfecReceiver returns _all inserted_
(...skipping 11 matching lines...) Expand all
138 0) { 146 0) {
139 return false; 147 return false;
140 } 148 }
141 } 149 }
142 // Return recovered packets through callback. 150 // Return recovered packets through callback.
143 for (const auto& recovered_packet : recovered_packets_) { 151 for (const auto& recovered_packet : recovered_packets_) {
144 if (recovered_packet->returned) { 152 if (recovered_packet->returned) {
145 continue; 153 continue;
146 } 154 }
147 ++packet_counter_.num_recovered_packets; 155 ++packet_counter_.num_recovered_packets;
148 if (!callback_->OnRecoveredPacket(recovered_packet->pkt->data, 156 if (!recovered_packet_receiver_->OnRecoveredPacket(
149 recovered_packet->pkt->length)) { 157 recovered_packet->pkt->data, recovered_packet->pkt->length)) {
150 return false; 158 return false;
151 } 159 }
152 recovered_packet->returned = true; 160 recovered_packet->returned = true;
153 // Periodically log the incoming packets. 161 // Periodically log the incoming packets.
154 int64_t now_ms = clock_->TimeInMilliseconds(); 162 int64_t now_ms = clock_->TimeInMilliseconds();
155 if (now_ms - last_recovered_packet_ms_ > kPacketLogIntervalMs) { 163 if (now_ms - last_recovered_packet_ms_ > kPacketLogIntervalMs) {
156 uint32_t media_ssrc = 164 uint32_t media_ssrc =
157 ForwardErrorCorrection::ParseSsrc(recovered_packet->pkt->data); 165 ForwardErrorCorrection::ParseSsrc(recovered_packet->pkt->data);
158 LOG(LS_INFO) << "Recovered media packet with SSRC: " << media_ssrc 166 LOG(LS_INFO) << "Recovered media packet with SSRC: " << media_ssrc
159 << " from FlexFEC stream with SSRC: " << ssrc_ << "."; 167 << " from FlexFEC stream with SSRC: " << ssrc_ << ".";
160 last_recovered_packet_ms_ = now_ms; 168 last_recovered_packet_ms_ = now_ms;
161 } 169 }
162 } 170 }
163 return true; 171 return true;
164 } 172 }
165 173
166 } // namespace webrtc 174 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698