Skip to content

Commit

Permalink
Add new Padding Manager in WebRtcConnection (#1476)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcague authored Oct 17, 2019
1 parent 15c6180 commit 458edbc
Show file tree
Hide file tree
Showing 24 changed files with 652 additions and 181 deletions.
8 changes: 5 additions & 3 deletions erizo/src/erizo/MediaDefinitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "lib/Clock.h"
#include "lib/ClockUtils.h"
#include "rtp/RtpHeaders.h"

namespace erizo {

Expand All @@ -25,19 +26,19 @@ struct DataPacket {

DataPacket(int comp_, const char *data_, int length_, packetType type_, uint64_t received_time_ms_) :
comp{comp_}, length{length_}, type{type_}, received_time_ms{received_time_ms_}, is_keyframe{false},
ending_of_layer_frame{false}, picture_id{-1}, tl0_pic_idx{-1} {
ending_of_layer_frame{false}, picture_id{-1}, tl0_pic_idx{-1}, is_padding{false} {
memcpy(data, data_, length_);
}

DataPacket(int comp_, const char *data_, int length_, packetType type_) :
comp{comp_}, length{length_}, type{type_}, received_time_ms{ClockUtils::timePointToMs(clock::now())},
is_keyframe{false}, ending_of_layer_frame{false}, picture_id{-1}, tl0_pic_idx{-1} {
is_keyframe{false}, ending_of_layer_frame{false}, picture_id{-1}, tl0_pic_idx{-1}, is_padding{false} {
memcpy(data, data_, length_);
}

DataPacket(int comp_, const unsigned char *data_, int length_) :
comp{comp_}, length{length_}, type{VIDEO_PACKET}, received_time_ms{ClockUtils::timePointToMs(clock::now())},
is_keyframe{false}, ending_of_layer_frame{false}, picture_id{-1}, tl0_pic_idx{-1} {
is_keyframe{false}, ending_of_layer_frame{false}, picture_id{-1}, tl0_pic_idx{-1}, is_padding{false} {
memcpy(data, data_, length_);
}

Expand Down Expand Up @@ -70,6 +71,7 @@ struct DataPacket {
int tl0_pic_idx;
std::string codec;
unsigned int clock_rate = 0;
bool is_padding;
};

class Monitor {
Expand Down
29 changes: 28 additions & 1 deletion erizo/src/erizo/MediaStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ DEFINE_LOGGER(MediaStream, "MediaStream");
log4cxx::LoggerPtr MediaStream::statsLogger = log4cxx::Logger::getLogger("StreamStats");

static constexpr auto kStreamStatsPeriod = std::chrono::seconds(120);
static constexpr uint64_t kInitialBitrate = 300000;

MediaStream::MediaStream(std::shared_ptr<Worker> worker,
std::shared_ptr<WebRtcConnection> connection,
Expand All @@ -64,7 +65,8 @@ MediaStream::MediaStream(std::shared_ptr<Worker> worker,
simulcast_{false},
bitrate_from_max_quality_layer_{0},
video_bitrate_{0},
random_generator_{random_device_()} {
random_generator_{random_device_()},
target_padding_bitrate_{0} {
if (is_publisher) {
setVideoSinkSSRC(kDefaultVideoSinkSSRC);
setAudioSinkSSRC(kDefaultAudioSinkSSRC);
Expand Down Expand Up @@ -637,6 +639,31 @@ void MediaStream::setSlideShowMode(bool state) {
notifyUpdateToHandlers();
}

void MediaStream::setTargetPaddingBitrate(uint64_t target_padding_bitrate) {
target_padding_bitrate_ = target_padding_bitrate;
notifyUpdateToHandlers();
}

uint32_t MediaStream::getTargetVideoBitrate() {
bool slide_show_mode = isSlideShowModeEnabled();
bool is_simulcast = isSimulcast();
uint32_t bitrate_sent = getVideoBitrate();
uint32_t max_bitrate = getMaxVideoBW();
uint32_t bitrate_from_max_quality_layer = getBitrateFromMaxQualityLayer();

uint32_t target_bitrate = max_bitrate;
if (is_simulcast) {
target_bitrate = std::min(bitrate_from_max_quality_layer, max_bitrate);
}
if (slide_show_mode || !is_simulcast) {
target_bitrate = std::min(bitrate_sent, max_bitrate);
}
if (target_bitrate == 0) {
target_bitrate = kInitialBitrate;
}
return target_bitrate;
}

void MediaStream::muteStream(bool mute_video, bool mute_audio) {
asyncTask([mute_audio, mute_video] (std::shared_ptr<MediaStream> media_stream) {
ELOG_DEBUG("%s message: muteStream, mute_video: %u, mute_audio: %u", media_stream->toLog(), mute_video, mute_audio);
Expand Down
7 changes: 7 additions & 0 deletions erizo/src/erizo/MediaStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ class MediaStream: public MediaSink, public MediaSource, public FeedbackSink,
bool isSinkSSRC(uint32_t ssrc);
void parseIncomingPayloadType(char *buf, int len, packetType type);
void parseIncomingExtensionId(char *buf, int len, packetType type);
virtual void setTargetPaddingBitrate(uint64_t bitrate);
virtual uint64_t getTargetPaddingBitrate() {
return target_padding_bitrate_;
}

virtual uint32_t getTargetVideoBitrate();

bool isPipelineInitialized() { return pipeline_initialized_; }
bool isRunning() { return pipeline_initialized_ && sending_; }
Expand Down Expand Up @@ -223,6 +229,7 @@ class MediaStream: public MediaSink, public MediaSource, public FeedbackSink,
std::atomic<uint32_t> video_bitrate_;
std::random_device random_device_;
std::mt19937 random_generator_;
uint64_t target_padding_bitrate_;
protected:
std::shared_ptr<SdpInfo> remote_sdp_;
};
Expand Down
15 changes: 12 additions & 3 deletions erizo/src/erizo/WebRtcConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "rtp/QualityManager.h"
#include "rtp/PliPacerHandler.h"
#include "rtp/RtpPaddingGeneratorHandler.h"
#include "rtp/RtpPaddingManagerHandler.h"
#include "rtp/RtpUtils.h"

namespace erizo {
Expand Down Expand Up @@ -121,13 +122,19 @@ void WebRtcConnection::initializePipeline() {
pipeline_->addFront(std::make_shared<ConnectionPacketReader>(this));

pipeline_->addFront(std::make_shared<SenderBandwidthEstimationHandler>());
pipeline_->addFront(std::make_shared<RtpPaddingManagerHandler>());

pipeline_->addFront(std::make_shared<ConnectionPacketWriter>(this));
pipeline_->finalize();
pipeline_initialized_ = true;
}

void WebRtcConnection::notifyUpdateToHandlers() {
asyncTask([] (std::shared_ptr<WebRtcConnection> conn) {
if (conn && conn->pipeline_ && conn->pipeline_initialized_) {
conn->pipeline_->notifyUpdate();
}
});
}

boost::future<void> WebRtcConnection::createOffer(bool video_enabled, bool audio_enabled, bool bundle) {
Expand Down Expand Up @@ -209,6 +216,10 @@ ConnectionQualityLevel WebRtcConnection::getConnectionQualityLevel() {
return connection_quality_check_.getLevel();
}

bool WebRtcConnection::werePacketLossesRecently() {
return connection_quality_check_.werePacketLossesRecently();
}

boost::future<void> WebRtcConnection::addMediaStream(std::shared_ptr<MediaStream> media_stream) {
return asyncTask([media_stream] (std::shared_ptr<WebRtcConnection> connection) {
boost::mutex::scoped_lock lock(connection->update_state_mutex_);
Expand Down Expand Up @@ -281,9 +292,7 @@ boost::future<void> WebRtcConnection::setRemoteSdpInfo(
return;
}
connection->remote_sdp_ = sdp;
if (connection->pipeline_initialized_ && connection->pipeline_) {
connection->pipeline_->notifyUpdate();
}
connection->notifyUpdateToHandlers();
boost::future<void> future = connection->processRemoteSdp().then(
[task_promise] (boost::future<void>) {
task_promise->set_value();
Expand Down
1 change: 1 addition & 0 deletions erizo/src/erizo/WebRtcConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ class WebRtcConnection: public TransportListener, public LogContext, public Hand
void write(std::shared_ptr<DataPacket> packet);
void notifyUpdateToHandlers() override;
ConnectionQualityLevel getConnectionQualityLevel();
bool werePacketLossesRecently();
void getJSONStats(std::function<void(std::string)> callback);

private:
Expand Down
13 changes: 12 additions & 1 deletion erizo/src/erizo/bandwidth/ConnectionQualityCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ constexpr uint8_t ConnectionQualityCheck::kLowVideoFractionLostThreshold;
constexpr size_t ConnectionQualityCheck::kNumberOfPacketsPerStream;

ConnectionQualityCheck::ConnectionQualityCheck()
: quality_level_{ConnectionQualityLevel::GOOD}, audio_buffer_{1}, video_buffer_{1} {
: quality_level_{ConnectionQualityLevel::GOOD}, audio_buffer_{1}, video_buffer_{1}, recent_packet_losses_{false} {
}

void ConnectionQualityCheck::onFeedback(std::shared_ptr<DataPacket> packet,
Expand Down Expand Up @@ -59,6 +59,10 @@ void ConnectionQualityCheck::onFeedback(std::shared_ptr<DataPacket> packet,
}
}

bool ConnectionQualityCheck::werePacketLossesRecently() {
return recent_packet_losses_;
}

void ConnectionQualityCheck::maybeNotifyMediaStreamsAboutConnectionQualityLevel(
const std::vector<std::shared_ptr<MediaStream>> &streams) {
if (!audio_buffer_.full() || !video_buffer_.full()) {
Expand All @@ -76,6 +80,13 @@ void ConnectionQualityCheck::maybeNotifyMediaStreamsAboutConnectionQualityLevel(
}
uint8_t audio_fraction_lost = audio_buffer_size > 0 ? total_audio_fraction_lost / audio_buffer_size : 0;
uint8_t video_fraction_lost = video_buffer_size > 0 ? total_video_fraction_lost / video_buffer_size : 0;

if (audio_fraction_lost == 0 && video_fraction_lost == 0) {
recent_packet_losses_ = false;
} else {
recent_packet_losses_ = true;
}

ConnectionQualityLevel level = ConnectionQualityLevel::GOOD;
if (audio_fraction_lost >= kHighAudioFractionLostThreshold) {
level = ConnectionQualityLevel::HIGH_LOSSES;
Expand Down
2 changes: 2 additions & 0 deletions erizo/src/erizo/bandwidth/ConnectionQualityCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,14 @@ class ConnectionQualityCheck {
virtual ~ConnectionQualityCheck() {}
void onFeedback(std::shared_ptr<DataPacket> packet, const std::vector<std::shared_ptr<MediaStream>> &streams);
ConnectionQualityLevel getLevel() { return quality_level_; }
bool werePacketLossesRecently();
private:
void maybeNotifyMediaStreamsAboutConnectionQualityLevel(const std::vector<std::shared_ptr<MediaStream>> &streams);
private:
ConnectionQualityLevel quality_level_;
circular_buffer audio_buffer_;
circular_buffer video_buffer_;
bool recent_packet_losses_;
};

} // namespace erizo
Expand Down
27 changes: 6 additions & 21 deletions erizo/src/erizo/bandwidth/TargetVideoBWDistributor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,21 @@ void TargetVideoBWDistributor::distribute(uint32_t remb, uint32_t ssrc,
stream->isSlideShowModeEnabled(),
stream->getVideoBitrate(),
stream->getMaxVideoBW(),
stream->getBitrateFromMaxQualityLayer()});
stream->getBitrateFromMaxQualityLayer(),
stream->getTargetVideoBitrate()});
});

std::sort(stream_infos.begin(), stream_infos.end(),
[this](const MediaStreamInfo &i, const MediaStreamInfo &j) {
return getTargetVideoBW(i) < getTargetVideoBW(j);
[](const MediaStreamInfo &i, const MediaStreamInfo &j) {
return i.target_video_bitrate < j.target_video_bitrate;
});
uint8_t remaining_streams = streams.size();
uint32_t remaining_bitrate = remb;
std::for_each(stream_infos.begin(), stream_infos.end(),
[&remaining_bitrate, &remaining_streams, transport, ssrc, this](const MediaStreamInfo &stream) {
[&remaining_bitrate, &remaining_streams, transport, ssrc](const MediaStreamInfo &stream) {
uint32_t max_bitrate = stream.max_video_bw;

uint32_t target_bitrate = getTargetVideoBW(stream);
uint32_t target_bitrate = stream.target_video_bitrate;

uint32_t remaining_avg_bitrate = remaining_bitrate / remaining_streams;
uint32_t bitrate = std::min(target_bitrate, remaining_avg_bitrate);
Expand All @@ -48,20 +49,4 @@ void TargetVideoBWDistributor::distribute(uint32_t remb, uint32_t ssrc,
});
}

uint32_t TargetVideoBWDistributor::getTargetVideoBW(const MediaStreamInfo &stream) {
bool slide_show_mode = stream.is_slideshow;
bool is_simulcast = stream.is_simulcast;
uint32_t bitrate_sent = stream.bitrate_sent;
uint32_t max_bitrate = stream.max_video_bw;

uint32_t target_bitrate = max_bitrate;
if (is_simulcast) {
target_bitrate = std::min(stream.bitrate_from_max_quality_layer, max_bitrate);
}
if (slide_show_mode) {
target_bitrate = std::min(bitrate_sent, max_bitrate);
}
return target_bitrate;
}

} // namespace erizo
3 changes: 1 addition & 2 deletions erizo/src/erizo/bandwidth/TargetVideoBWDistributor.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ struct MediaStreamInfo {
uint32_t bitrate_sent;
uint32_t max_video_bw;
uint32_t bitrate_from_max_quality_layer;
uint32_t target_video_bitrate;
};

class TargetVideoBWDistributor : public BandwidthDistributionAlgorithm {
Expand All @@ -23,8 +24,6 @@ class TargetVideoBWDistributor : public BandwidthDistributionAlgorithm {
virtual ~TargetVideoBWDistributor() {}
void distribute(uint32_t remb, uint32_t ssrc, std::vector<std::shared_ptr<MediaStream>> streams,
Transport *transport) override;
private:
uint32_t getTargetVideoBW(const MediaStreamInfo &stream);
};

} // namespace erizo
Expand Down
Loading

0 comments on commit 458edbc

Please sign in to comment.