Skip to content

Commit

Permalink
Add Black keyframes in mute video (#1421)
Browse files Browse the repository at this point in the history
  • Loading branch information
lodoyun authored Jun 10, 2019
1 parent 9ebf7f5 commit d7507f2
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 17 deletions.
1 change: 1 addition & 0 deletions erizo/src/erizo/rtp/FakeKeyframeGeneratorHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ std::shared_ptr<DataPacket> FakeKeyframeGeneratorHandler::transformIntoKeyframeP
(std::shared_ptr<DataPacket> packet) {
if (packet->codec == "VP8") {
auto keyframe_packet = RtpUtils::makeVP8BlackKeyframePacket(packet);
packet->is_keyframe = true;
return keyframe_packet;
} else {
ELOG_DEBUG("Generate keyframe packet is not available for codec %s", packet->codec);
Expand Down
61 changes: 48 additions & 13 deletions erizo/src/erizo/rtp/RtpTrackMuteHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,37 @@ void RtpTrackMuteHandler::write(Context *ctx, std::shared_ptr<DataPacket> packet

void RtpTrackMuteHandler::handlePacket(Context *ctx, TrackMuteInfo *info, std::shared_ptr<DataPacket> packet) {
RtpHeader *rtp_header = reinterpret_cast<RtpHeader*>(packet->data);
uint16_t offset = info->seq_num_offset;
info->last_original_seq_num = rtp_header->getSeqNumber();
if (!info->mute_is_active) {
info->last_sent_seq_num = info->last_original_seq_num - offset;
if (offset > 0) {
setPacketSeqNumber(packet, info->last_sent_seq_num);
if (info->last_sent_seq_num == -1) {
info->last_sent_seq_num = info->last_original_seq_num;
}
if (info->mute_is_active) {
if (packet->is_keyframe) {
if (info->unmute_requested) {
ELOG_DEBUG("%s message: Keyframe arrived - unmuting video", stream_->toLog());
info->mute_is_active = false;
info->unmute_requested = false;
} else {
ELOG_DEBUG("%s message: video muted - maybe transforming into black keyframe", stream_->toLog());
if (packet->codec == "VP8") {
packet = transformIntoBlackKeyframePacket(packet);
} else {
ELOG_WARN("%s cannot generate keyframe packet is not available for codec %s",
stream_->toLog(), packet->codec);
return;
}
}
updateOffset(info);
} else {
return;
}
ctx->fireWrite(std::move(packet));
}
uint16_t offset = info->seq_num_offset;
info->last_sent_seq_num = info->last_original_seq_num - offset;
if (offset > 0) {
setPacketSeqNumber(packet, info->last_sent_seq_num);
}
ctx->fireWrite(std::move(packet));
}

void RtpTrackMuteHandler::muteAudio(bool active) {
Expand All @@ -106,16 +128,19 @@ void RtpTrackMuteHandler::muteTrack(TrackMuteInfo *info, bool active) {
if (info->mute_is_active == active) {
return;
}
info->mute_is_active = active;
ELOG_INFO("%s message: Mute %s, active: %d", info->label.c_str(), stream_->toLog(), active);
if (!info->mute_is_active) {
info->seq_num_offset = info->last_original_seq_num - info->last_sent_seq_num;
ELOG_DEBUG("%s message: Deactivated, original_seq_num: %u, last_sent_seq_num: %u, offset: %u",
stream_->toLog(), info->last_original_seq_num, info->last_sent_seq_num, info->seq_num_offset);
} else {
ELOG_INFO("%s message: muteTrack, label:%s, active: %d", stream_->toLog(), info->label.c_str(), active);
if (!active) {
if (info->label == "video") {
info->unmute_requested = true;
getContext()->fireRead(RtpUtils::createPLI(stream_->getVideoSinkSSRC(), stream_->getVideoSourceSSRC()));
ELOG_DEBUG("%s message: Unmute requested for video, original_seq_num: %u, last_sent_seq_num: %u, offset: %u",
stream_->toLog(), info->last_original_seq_num, info->last_sent_seq_num, info->seq_num_offset);
} else {
info->mute_is_active = active;
updateOffset(info);
}
} else {
info->mute_is_active = active;
}
}

Expand All @@ -128,4 +153,14 @@ inline void RtpTrackMuteHandler::setPacketSeqNumber(std::shared_ptr<DataPacket>
head->setSeqNumber(seq_number);
}

void RtpTrackMuteHandler::updateOffset(TrackMuteInfo *info) {
info->seq_num_offset = info->last_original_seq_num - info->last_sent_seq_num;
}


std::shared_ptr<DataPacket> RtpTrackMuteHandler::transformIntoBlackKeyframePacket
(std::shared_ptr<DataPacket> packet) {
auto keyframe_packet = RtpUtils::makeVP8BlackKeyframePacket(packet);
return keyframe_packet;
}
} // namespace erizo
7 changes: 5 additions & 2 deletions erizo/src/erizo/rtp/RtpTrackMuteHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ class TrackMuteInfo {
public:
explicit TrackMuteInfo(std::string label_)
: label{label_}, last_original_seq_num{-1}, seq_num_offset{0},
last_sent_seq_num{0}, mute_is_active{false} {}
last_sent_seq_num{-1}, mute_is_active{false}, unmute_requested{false} {}
std::string label;
int32_t last_original_seq_num;
uint16_t seq_num_offset;
uint16_t last_sent_seq_num;
int32_t last_sent_seq_num;
bool mute_is_active;
bool unmute_requested;
};

class RtpTrackMuteHandler: public Handler {
Expand All @@ -46,6 +47,8 @@ class RtpTrackMuteHandler: public Handler {
void handleFeedback(const TrackMuteInfo &info, const std::shared_ptr<DataPacket> &packet);
void handlePacket(Context *ctx, TrackMuteInfo *info, std::shared_ptr<DataPacket> packet);
inline void setPacketSeqNumber(std::shared_ptr<DataPacket> packet, uint16_t seq_number);
std::shared_ptr<DataPacket> transformIntoBlackKeyframePacket(std::shared_ptr<DataPacket> packet);
void updateOffset(TrackMuteInfo *info);

private:
TrackMuteInfo audio_info_;
Expand Down
4 changes: 2 additions & 2 deletions erizo/src/test/rtp/RtpTrackMuteHandlerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,11 @@ TEST_F(RtpTrackMuteHandlerTest, shouldNotWriteAnyPacketsIfAllIsActive) {
}

TEST_F(RtpTrackMuteHandlerTest, shouldSendPLIsWhenVideoIsActivated) {
track_mute_handler->muteVideo(false);
track_mute_handler->muteVideo(true);

EXPECT_CALL(*reader.get(), read(_, _)).With(Args<1>(erizo::IsPLI())).Times(1);

track_mute_handler->muteVideo(true);
track_mute_handler->muteVideo(false);
}

TEST_F(RtpTrackMuteHandlerTest, shouldAdjustSequenceNumbers) {
Expand Down

0 comments on commit d7507f2

Please sign in to comment.