Skip to content

Commit

Permalink
LayerDetectorHandler reads also resolution and framerate (#1026)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcague authored Sep 14, 2017
1 parent b1cadf7 commit 3ce30d8
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 21 deletions.
91 changes: 72 additions & 19 deletions erizo/src/erizo/rtp/LayerDetectorHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,21 @@

namespace erizo {

static constexpr uint32_t kMaxTemporalLayers = 4;
static constexpr uint32_t kMaxSpatialLayers = 4;
static constexpr erizo::duration kMinNotifyLayerInfoInterval = std::chrono::seconds(5);

DEFINE_LOGGER(LayerDetectorHandler, "rtp.LayerDetectorHandler");

LayerDetectorHandler::LayerDetectorHandler() : connection_{nullptr}, enabled_{true}, initialized_{false} {}
LayerDetectorHandler::LayerDetectorHandler(std::shared_ptr<erizo::Clock> the_clock)
: clock_{the_clock}, connection_{nullptr}, enabled_{true}, initialized_{false},
last_event_sent_{clock_->now()} {
for (uint32_t temporal_layer = 0; temporal_layer <= kMaxTemporalLayers; temporal_layer++) {
video_frame_rate_list_.push_back(MovingIntervalRateStat{std::chrono::milliseconds(500), 10, .5, clock_});
}
video_frame_width_list_ = std::vector<uint32_t>(kMaxSpatialLayers);
video_frame_height_list_ = std::vector<uint32_t>(kMaxSpatialLayers);
}

void LayerDetectorHandler::enable() {
enabled_ = true;
Expand All @@ -35,6 +47,28 @@ void LayerDetectorHandler::read(Context *ctx, std::shared_ptr<DataPacket> packet
ctx->fireRead(std::move(packet));
}

void LayerDetectorHandler::notifyLayerInfoChangedEvent() {
ELOG_DEBUG("LAYER INFO CHANGED");
for (uint32_t spatial_layer = 0; spatial_layer < video_frame_width_list_.size(); spatial_layer++) {
ELOG_DEBUG(" SPATIAL LAYER (%u): %u %u",
spatial_layer, video_frame_width_list_[spatial_layer], video_frame_height_list_[spatial_layer]);
}
for (uint32_t temporal_layer = 0; temporal_layer < video_frame_rate_list_.size(); temporal_layer++) {
ELOG_DEBUG(" TEMPORAL LAYER (%u): %lu",
temporal_layer, video_frame_rate_list_[temporal_layer].value());
}

// TODO(javier): send an event to subscribers with the new info

last_event_sent_ = clock_->now();
}

void LayerDetectorHandler::notifyLayerInfoChangedEventMaybe() {
if (clock_->now() - last_event_sent_ > kMinNotifyLayerInfoInterval) {
notifyLayerInfoChangedEvent();
}
}

int LayerDetectorHandler::getSsrcPosition(uint32_t ssrc) {
std::vector<uint32_t>::iterator item = std::find(video_ssrc_list_.begin(), video_ssrc_list_.end(), ssrc);
size_t index = std::distance(video_ssrc_list_.begin(), item);
Expand All @@ -55,17 +89,13 @@ void LayerDetectorHandler::parseLayerInfoFromVP8(std::shared_ptr<DataPacket> pac
}
packet->compatible_temporal_layers = {};
switch (payload->tID) {
case 0:
packet->compatible_temporal_layers.push_back(0);
case 2:
packet->compatible_temporal_layers.push_back(1);
case 1:
packet->compatible_temporal_layers.push_back(2);
case 0: addTemporalLayerAndCalculateRate(packet, 0, payload->beginningOfPartition);
case 2: addTemporalLayerAndCalculateRate(packet, 1, payload->beginningOfPartition);
case 1: addTemporalLayerAndCalculateRate(packet, 2, payload->beginningOfPartition);
// case 3 and beyond are not handled because Chrome only
// supports 3 temporal scalability today (03/15/17)
break;
default:
packet->compatible_temporal_layers.push_back(0);
default: addTemporalLayerAndCalculateRate(packet, 0, payload->beginningOfPartition);
break;
}

Expand All @@ -76,9 +106,24 @@ void LayerDetectorHandler::parseLayerInfoFromVP8(std::shared_ptr<DataPacket> pac
} else {
packet->is_keyframe = false;
}

if (payload->frameWidth != -1 && static_cast<uint>(payload->frameWidth) != video_frame_width_list_[position]) {
video_frame_width_list_[position] = payload->frameWidth;
video_frame_height_list_[position] = payload->frameHeight;
notifyLayerInfoChangedEvent();
}
notifyLayerInfoChangedEventMaybe();
delete payload;
}

void LayerDetectorHandler::addTemporalLayerAndCalculateRate(const std::shared_ptr<DataPacket> &packet,
int temporal_layer, bool new_frame) {
if (new_frame) {
video_frame_rate_list_[temporal_layer]++;
}
packet->compatible_temporal_layers.push_back(temporal_layer);
}

void LayerDetectorHandler::parseLayerInfoFromVP9(std::shared_ptr<DataPacket> packet) {
RtpHeader *rtp_header = reinterpret_cast<RtpHeader*>(packet->data);
unsigned char* start_buffer = reinterpret_cast<unsigned char*> (packet->data);
Expand All @@ -95,17 +140,12 @@ void LayerDetectorHandler::parseLayerInfoFromVP9(std::shared_ptr<DataPacket> pac

packet->compatible_temporal_layers = {};
switch (payload->temporalID) {
case 0:
packet->compatible_temporal_layers.push_back(0);
case 2:
packet->compatible_temporal_layers.push_back(1);
case 1:
packet->compatible_temporal_layers.push_back(2);
case 3:
packet->compatible_temporal_layers.push_back(3);
case 0: addTemporalLayerAndCalculateRate(packet, 0, payload->beginningOfLayerFrame);
case 2: addTemporalLayerAndCalculateRate(packet, 1, payload->beginningOfLayerFrame);
case 1: addTemporalLayerAndCalculateRate(packet, 2, payload->beginningOfLayerFrame);
case 3: addTemporalLayerAndCalculateRate(packet, 3, payload->beginningOfLayerFrame);
break;
default:
packet->compatible_temporal_layers.push_back(0);
default: addTemporalLayerAndCalculateRate(packet, 0, payload->beginningOfLayerFrame);
break;
}

Expand All @@ -114,6 +154,19 @@ void LayerDetectorHandler::parseLayerInfoFromVP9(std::shared_ptr<DataPacket> pac
} else {
packet->is_keyframe = false;
}
bool resolution_changed = false;
if (payload->resolutions.size() > 0) {
for (uint position = 0; position < payload->resolutions.size(); position++) {
resolution_changed = true;
video_frame_width_list_[position] = payload->resolutions[position].width;
video_frame_height_list_[position] = payload->resolutions[position].height;
}
}
if (resolution_changed) {
notifyLayerInfoChangedEvent();
}

notifyLayerInfoChangedEventMaybe();

packet->ending_of_layer_frame = payload->endingOfLayerFrame;
delete payload;
Expand Down
12 changes: 10 additions & 2 deletions erizo/src/erizo/rtp/LayerDetectorHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@
#include "pipeline/Handler.h"
#include "rtp/RtpVP8Parser.h"
#include "rtp/RtpVP9Parser.h"
#include "./Stats.h"

#define MAX_DELAY 450000

namespace erizo {

class WebRtcConnection;


class LayerDetectorHandler: public InboundHandler, public std::enable_shared_from_this<LayerDetectorHandler> {
DECLARE_LOGGER();


public:
LayerDetectorHandler();
explicit LayerDetectorHandler(std::shared_ptr<erizo::Clock> the_clock = std::make_shared<erizo::SteadyClock>());

void enable() override;
void disable() override;
Expand All @@ -39,14 +39,22 @@ class LayerDetectorHandler: public InboundHandler, public std::enable_shared_fro
void parseLayerInfoFromVP8(std::shared_ptr<DataPacket> packet);
void parseLayerInfoFromVP9(std::shared_ptr<DataPacket> packet);
int getSsrcPosition(uint32_t ssrc);
void addTemporalLayerAndCalculateRate(const std::shared_ptr<DataPacket> &packet, int temporal_layer, bool new_frame);
void notifyLayerInfoChangedEvent();
void notifyLayerInfoChangedEventMaybe();

private:
std::shared_ptr<erizo::Clock> clock_;
WebRtcConnection *connection_;
bool enabled_;
bool initialized_;
RtpVP8Parser vp8_parser_;
RtpVP9Parser vp9_parser_;
std::vector<uint32_t> video_ssrc_list_;
std::vector<uint32_t> video_frame_height_list_;
std::vector<uint32_t> video_frame_width_list_;
std::vector<MovingIntervalRateStat> video_frame_rate_list_;
std::chrono::steady_clock::time_point last_event_sent_;
};
} // namespace erizo

Expand Down

0 comments on commit 3ce30d8

Please sign in to comment.