Skip to content

Commit e483800

Browse files
authored
Fix padding removal handler (#868)
1 parent 9668b17 commit e483800

File tree

8 files changed

+78
-17
lines changed

8 files changed

+78
-17
lines changed

erizo/src/erizo/WebRtcConnection.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,8 @@ void WebRtcConnection::initializePipeline() {
277277
pipeline_->addFront(RtpPaddingGeneratorHandler());
278278
pipeline_->addFront(PliPacerHandler());
279279
pipeline_->addFront(BandwidthEstimationHandler());
280-
pipeline_->addFront(RtcpFeedbackGenerationHandler());
281280
pipeline_->addFront(RtpPaddingRemovalHandler());
281+
pipeline_->addFront(RtcpFeedbackGenerationHandler());
282282
pipeline_->addFront(RtpRetransmissionHandler());
283283
pipeline_->addFront(SRPacketHandler());
284284
pipeline_->addFront(SenderBandwidthEstimationHandler());

erizo/src/erizo/rtp/RtpPaddingRemovalHandler.cpp

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,30 +22,67 @@ void RtpPaddingRemovalHandler::read(Context *ctx, std::shared_ptr<dataPacket> pa
2222

2323
if (!chead->isRtcp() && enabled_ && packet->type == VIDEO_PACKET) {
2424
uint32_t ssrc = rtp_header->getSSRC();
25-
auto translator_it = translator_map_.find(ssrc);
26-
std::shared_ptr<SequenceNumberTranslator> translator;
27-
if (translator_it != translator_map_.end()) {
28-
translator = translator_it->second;
29-
} else {
30-
ELOG_DEBUG("message: no Translator found creating a new one, ssrc: %u", ssrc);
31-
translator = std::make_shared<SequenceNumberTranslator>();
32-
translator_map_[ssrc] = translator;
33-
}
25+
std::shared_ptr<SequenceNumberTranslator> translator = getTranslatorForSsrc(ssrc, true);
3426
if (!removePaddingBytes(packet, translator)) {
3527
return;
3628
}
3729
uint16_t sequence_number = rtp_header->getSeqNumber();
3830
SequenceNumber sequence_number_info = translator->get(sequence_number, false);
3931

4032
if (sequence_number_info.type != SequenceNumberType::Valid) {
33+
ELOG_DEBUG("Invalid translation %u, ssrc: %u", sequence_number, ssrc);
4134
return;
4235
}
36+
ELOG_DEBUG("Changing seq_number from %u to %u, ssrc %u", sequence_number, sequence_number_info.output,
37+
ssrc);
4338
rtp_header->setSeqNumber(sequence_number_info.output);
4439
}
4540
ctx->fireRead(packet);
4641
}
4742

4843
void RtpPaddingRemovalHandler::write(Context *ctx, std::shared_ptr<dataPacket> packet) {
44+
RtcpHeader* rtcp_head = reinterpret_cast<RtcpHeader*>(packet->data);
45+
if (!enabled_ || packet->type != VIDEO_PACKET || !rtcp_head->isFeedback()) {
46+
ctx->fireWrite(packet);
47+
return;
48+
}
49+
uint32_t ssrc = rtcp_head->getSourceSSRC();
50+
std::shared_ptr<SequenceNumberTranslator> translator = getTranslatorForSsrc(ssrc, false);
51+
if (!translator) {
52+
ELOG_DEBUG("No translator for ssrc %u, %s", ssrc, connection_->toLog());
53+
ctx->fireWrite(packet);
54+
return;
55+
}
56+
RtpUtils::forEachRRBlock(packet, [this, translator, ssrc](RtcpHeader *chead) {
57+
if (chead->packettype == RTCP_RTP_Feedback_PT) {
58+
RtpUtils::forEachNack(chead, [this, chead, translator, ssrc](uint16_t new_seq_num, uint16_t new_plb,
59+
RtcpHeader* nack_header) {
60+
uint16_t initial_seq_num = new_seq_num;
61+
std::vector<uint16_t> seq_nums;
62+
for (int i = -1; i <= 15; i++) {
63+
uint16_t seq_num = initial_seq_num + i + 1;
64+
SequenceNumber input_seq_num = translator->reverse(seq_num);
65+
if (input_seq_num.type == SequenceNumberType::Valid) {
66+
seq_nums.push_back(input_seq_num.input);
67+
} else {
68+
ELOG_DEBUG("Input is not valid for %u, ssrc %u, %s", seq_num, ssrc, connection_->toLog());
69+
}
70+
ELOG_DEBUG("Lost packet %u, input %u, ssrc %u", seq_num, input_seq_num.input, ssrc);
71+
}
72+
if (seq_nums.size() > 0) {
73+
uint16_t pid = seq_nums[0];
74+
uint16_t blp = 0;
75+
for (uint16_t index = 1; index < seq_nums.size() ; index++) {
76+
uint16_t distance = seq_nums[index] - pid - 1;
77+
blp |= (1 << distance);
78+
}
79+
nack_header->setNackPid(pid);
80+
nack_header->setNackBlp(blp);
81+
ELOG_DEBUG("Translated pid %u, translated blp %u, ssrc %u, %s", pid, blp, ssrc, connection_->toLog());
82+
}
83+
});
84+
}
85+
});
4986
ctx->fireWrite(packet);
5087
}
5188

@@ -58,22 +95,39 @@ bool RtpPaddingRemovalHandler::removePaddingBytes(std::shared_ptr<dataPacket> pa
5895
if (padding_length + header_length == packet->length) {
5996
uint16_t sequence_number = rtp_header->getSeqNumber();
6097
translator->get(sequence_number, true);
98+
ELOG_DEBUG("Dropping packet %u, %s", sequence_number, connection_->toLog());
6199
return false;
62100
}
63101
packet->length -= padding_length;
64102
rtp_header->padding = 0;
65103
return true;
66104
}
67105

106+
std::shared_ptr<SequenceNumberTranslator> RtpPaddingRemovalHandler::getTranslatorForSsrc(uint32_t ssrc,
107+
bool should_create) {
108+
auto translator_it = translator_map_.find(ssrc);
109+
std::shared_ptr<SequenceNumberTranslator> translator;
110+
if (translator_it != translator_map_.end()) {
111+
ELOG_DEBUG("Found Translator for %u, %s", ssrc, connection_->toLog());
112+
translator = translator_it->second;
113+
} else if (should_create) {
114+
ELOG_DEBUG("message: no Translator found creating a new one, ssrc: %u, %s", ssrc,
115+
connection_->toLog());
116+
translator = std::make_shared<SequenceNumberTranslator>();
117+
translator_map_[ssrc] = translator;
118+
}
119+
return translator;
120+
}
121+
68122
void RtpPaddingRemovalHandler::notifyUpdate() {
69123
auto pipeline = getContext()->getPipelineShared();
70124
if (!pipeline) {
71125
return;
72126
}
73-
74127
if (initialized_) {
75128
return;
76129
}
130+
connection_ = pipeline->getService<WebRtcConnection>().get();
77131
initialized_ = true;
78132
}
79133
} // namespace erizo

erizo/src/erizo/rtp/RtpPaddingRemovalHandler.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
#ifndef ERIZO_SRC_ERIZO_RTP_RTPPADDINGREMOVALHANDLER_H_
23
#define ERIZO_SRC_ERIZO_RTP_RTPPADDINGREMOVALHANDLER_H_
34

@@ -6,6 +7,7 @@
67
#include "./logger.h"
78
#include "pipeline/Handler.h"
89
#include "rtp/SequenceNumberTranslator.h"
10+
#include "WebRtcConnection.h"
911

1012
namespace erizo {
1113

@@ -32,11 +34,14 @@ class RtpPaddingRemovalHandler: public Handler, public std::enable_shared_from_t
3234
private:
3335
bool removePaddingBytes(std::shared_ptr<dataPacket> packet,
3436
std::shared_ptr<SequenceNumberTranslator> translator);
37+
std::shared_ptr<SequenceNumberTranslator> getTranslatorForSsrc(uint32_t ssrc,
38+
bool should_create);
3539

3640
private:
3741
bool enabled_;
3842
bool initialized_;
3943
std::map<uint32_t, std::shared_ptr<SequenceNumberTranslator>> translator_map_;
44+
WebRtcConnection* connection_;
4045
};
4146
} // namespace erizo
4247

erizo/src/erizo/rtp/RtpRetransmissionHandler.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ void RtpRetransmissionHandler::read(Context *ctx, std::shared_ptr<dataPacket> pa
7474
if (chead->packettype == RTCP_RTP_Feedback_PT) {
7575
contains_nack = true;
7676

77-
RtpUtils::forEachNack(chead, [this, chead, &is_fully_recovered](uint16_t new_seq_num, uint16_t new_plb) {
77+
RtpUtils::forEachNack(chead, [this, chead, &is_fully_recovered](uint16_t new_seq_num,
78+
uint16_t new_plb, RtcpHeader* nack_head) {
7879
uint16_t initial_seq_num = new_seq_num;
7980
uint16_t plb = new_plb;
8081

erizo/src/erizo/rtp/RtpUtils.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ void RtpUtils::updateREMB(RtcpHeader *chead, uint bitrate) {
2121
}
2222
}
2323

24-
void RtpUtils::forEachNack(RtcpHeader *chead, std::function<void(uint16_t, uint16_t)> f) {
24+
void RtpUtils::forEachNack(RtcpHeader *chead, std::function<void(uint16_t, uint16_t, RtcpHeader*)> f) {
2525
if (chead->packettype == RTCP_RTP_Feedback_PT) {
2626
int length = (chead->getLength() + 1)*4;
2727
int current_position = kNackCommonHeaderLengthBytes;
@@ -31,7 +31,7 @@ void RtpUtils::forEachNack(RtcpHeader *chead, std::function<void(uint16_t, uint1
3131
aux_chead = reinterpret_cast<RtcpHeader*>(aux_pointer);
3232
uint16_t initial_seq_num = aux_chead->getNackPid();
3333
uint16_t plb = aux_chead->getNackBlp();
34-
f(initial_seq_num, plb);
34+
f(initial_seq_num, plb, aux_chead);
3535
current_position += 4;
3636
aux_pointer += 4;
3737
}

erizo/src/erizo/rtp/RtpUtils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class RtpUtils {
2323

2424
static bool isFIR(std::shared_ptr<dataPacket> packet);
2525

26-
static void forEachNack(RtcpHeader *chead, std::function<void(uint16_t, uint16_t)> f);
26+
static void forEachNack(RtcpHeader *chead, std::function<void(uint16_t, uint16_t, RtcpHeader*)> f);
2727

2828
static std::shared_ptr<dataPacket> createPLI(uint32_t source_ssrc, uint32_t sink_ssrc);
2929

erizo/src/test/log4cxx.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ log4j.logger.rtp.RtpAudioMuteHandler=ERROR
5353
log4j.logger.rtp.RtpSink=ERROR
5454
log4j.logger.rtp.RtpSource=ERROR
5555
log4j.logger.rtp.RtcpFeedbackGenerationHandler=ERROR
56+
log4j.logger.rtp.RtpPaddingRemovalHandler=ERROR
5657
log4j.logger.rtp.RtcpRrGenerator=ERROR
5758
log4j.logger.rtp.RtcpNackGenerator=ERROR
5859
log4j.logger.rtp.SRPacketHandler=ERROR

erizo/src/test/rtp/RtcpNackGeneratorTest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ class RtcpNackGeneratorTest :public ::testing::Test {
5858
total_length += rtcp_length;
5959

6060
if (chead->packettype == RTCP_RTP_Feedback_PT) {
61-
erizo::RtpUtils::forEachNack(chead, [chead, lost_seq_num, &found_nack](uint16_t seq_num, uint16_t plb) {
61+
erizo::RtpUtils::forEachNack(chead, [chead, lost_seq_num, &found_nack](uint16_t seq_num,
62+
uint16_t plb, RtcpHeader* nack_head) {
6263
uint16_t initial_seq_num = seq_num;
6364
if (initial_seq_num == lost_seq_num) {
6465
found_nack = true;
@@ -201,4 +202,3 @@ TEST_F(RtcpNackGeneratorTest, shouldNotRetransmitNacksMoreThanTwice) {
201202
receiver_report = generateRrWithNack();
202203
EXPECT_FALSE(RtcpPacketContainsNackSeqNum(receiver_report, erizo::kArbitrarySeqNumber + 1));
203204
}
204-

0 commit comments

Comments
 (0)