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

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

Powered by Google App Engine
This is Rietveld 408576698