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

Unified Diff: webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc

Issue 2288223002: Extract simulcast rate allocation outside of video encoder. (Closed)
Patch Set: Rebase, handle pause case in simulcast wrapper Created 4 years, 3 months 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 side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc
diff --git a/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc b/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc
index 586a6491fa027642c95b46b1601ff429eda128d1..766e517484671a4e1cfa7ac0c7f9621a91f7ea6e 100644
--- a/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc
+++ b/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc
@@ -17,6 +17,7 @@
#include "webrtc/base/checks.h"
#include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h"
+#include "webrtc/modules/video_coding/utility/simulcast_rate_allocator.h"
#include "webrtc/system_wrappers/include/clock.h"
namespace {
@@ -26,14 +27,6 @@ const unsigned int kDefaultMaxQp = 56;
// Max qp for lowest spatial resolution when doing simulcast.
const unsigned int kLowestResMaxQp = 45;
-uint32_t SumStreamTargetBitrate(int streams, const webrtc::VideoCodec& codec) {
- uint32_t bitrate_sum = 0;
- for (int i = 0; i < streams; ++i) {
- bitrate_sum += codec.simulcastStream[i].targetBitrate;
- }
- return bitrate_sum;
-}
-
uint32_t SumStreamMaxBitrate(int streams, const webrtc::VideoCodec& codec) {
uint32_t bitrate_sum = 0;
for (int i = 0; i < streams; ++i) {
@@ -92,13 +85,8 @@ int VerifyCodec(const webrtc::VideoCodec* inst) {
return WEBRTC_VIDEO_CODEC_OK;
}
-// TL1 FrameDropper's max time to drop frames.
-const float kTl1MaxTimeToDropFrames = 20.0f;
-
struct ScreenshareTemporalLayersFactory : webrtc::TemporalLayersFactory {
- ScreenshareTemporalLayersFactory()
- : tl1_frame_dropper_(kTl1MaxTimeToDropFrames) {}
-
+ ScreenshareTemporalLayersFactory() {}
virtual ~ScreenshareTemporalLayersFactory() {}
virtual webrtc::TemporalLayers* Create(int num_temporal_layers,
@@ -106,9 +94,6 @@ struct ScreenshareTemporalLayersFactory : webrtc::TemporalLayersFactory {
return new webrtc::ScreenshareLayers(num_temporal_layers, rand(),
webrtc::Clock::GetRealTimeClock());
}
-
- mutable webrtc::FrameDropper tl0_frame_dropper_;
- mutable webrtc::FrameDropper tl1_frame_dropper_;
};
// An EncodedImageCallback implementation that forwards on calls to a
@@ -139,9 +124,10 @@ namespace webrtc {
SimulcastEncoderAdapter::SimulcastEncoderAdapter(VideoEncoderFactory* factory)
: factory_(factory),
- encoded_complete_callback_(NULL),
+ encoded_complete_callback_(nullptr),
implementation_name_("SimulcastEncoderAdapter") {
memset(&codec_, 0, sizeof(webrtc::VideoCodec));
+ rate_allocator_.reset(new SimulcastRateAllocator(codec_));
}
SimulcastEncoderAdapter::~SimulcastEncoderAdapter() {
@@ -189,6 +175,9 @@ int SimulcastEncoderAdapter::InitEncode(const VideoCodec* inst,
}
codec_ = *inst;
+ rate_allocator_.reset(new SimulcastRateAllocator(codec_));
+ std::vector<uint32_t> start_bitrates =
+ rate_allocator_->GetAllocation(codec_.startBitrate);
// Special mode when screensharing on a single stream.
if (number_of_streams == 1 && inst->mode == kScreensharing) {
@@ -200,15 +189,18 @@ int SimulcastEncoderAdapter::InitEncode(const VideoCodec* inst,
// Create |number_of_streams| of encoder instances and init them.
for (int i = 0; i < number_of_streams; ++i) {
VideoCodec stream_codec;
- bool send_stream = true;
+ uint32_t start_bitrate_kbps = start_bitrates[i];
if (!doing_simulcast) {
stream_codec = codec_;
stream_codec.numberOfSimulcastStreams = 1;
} else {
+ // Cap start bitrate to the min bitrate in order to avoid strange codec
+ // behavior. Since sending sending will be false, this should not matter.
+ start_bitrate_kbps =
+ std::max(codec_.simulcastStream[i].minBitrate, start_bitrate_kbps);
bool highest_resolution_stream = (i == (number_of_streams - 1));
- PopulateStreamCodec(&codec_, i, number_of_streams,
- highest_resolution_stream, &stream_codec,
- &send_stream);
+ PopulateStreamCodec(&codec_, i, start_bitrate_kbps,
+ highest_resolution_stream, &stream_codec);
}
// TODO(ronghuawu): Remove once this is handled in VP8EncoderImpl.
@@ -225,7 +217,8 @@ int SimulcastEncoderAdapter::InitEncode(const VideoCodec* inst,
EncodedImageCallback* callback = new AdapterEncodedImageCallback(this, i);
encoder->RegisterEncodeCompleteCallback(callback);
streaminfos_.push_back(StreamInfo(encoder, callback, stream_codec.width,
- stream_codec.height, send_stream));
+ stream_codec.height,
+ start_bitrate_kbps > 0));
if (i != 0)
implementation_name += ", ";
implementation_name += streaminfos_[i].encoder->ImplementationName();
@@ -363,6 +356,8 @@ int SimulcastEncoderAdapter::SetRates(uint32_t new_bitrate_kbit,
if (codec_.maxBitrate > 0 && new_bitrate_kbit > codec_.maxBitrate) {
new_bitrate_kbit = codec_.maxBitrate;
}
+
+ std::vector<uint32_t> stream_bitrates;
if (new_bitrate_kbit > 0) {
// Make sure the bitrate fits the configured min bitrates. 0 is a special
// value that means paused, though, so leave it alone.
@@ -373,19 +368,20 @@ int SimulcastEncoderAdapter::SetRates(uint32_t new_bitrate_kbit,
new_bitrate_kbit < codec_.simulcastStream[0].minBitrate) {
new_bitrate_kbit = codec_.simulcastStream[0].minBitrate;
}
+ stream_bitrates = rate_allocator_->GetAllocation(new_bitrate_kbit);
}
codec_.maxFramerate = new_framerate;
- bool send_stream = true;
- uint32_t stream_bitrate = 0;
+ // Disable any stream not in the current allocation.
+ stream_bitrates.resize(streaminfos_.size(), 0U);
+
for (size_t stream_idx = 0; stream_idx < streaminfos_.size(); ++stream_idx) {
- stream_bitrate = GetStreamBitrate(stream_idx, streaminfos_.size(),
- new_bitrate_kbit, &send_stream);
+ uint32_t stream_bitrate_kbps = stream_bitrates[stream_idx];
// Need a key frame if we have not sent this stream before.
- if (send_stream && !streaminfos_[stream_idx].send_stream) {
+ if (stream_bitrate_kbps > 0 && !streaminfos_[stream_idx].send_stream) {
streaminfos_[stream_idx].key_frame_request = true;
}
- streaminfos_[stream_idx].send_stream = send_stream;
+ streaminfos_[stream_idx].send_stream = stream_bitrate_kbps > 0;
// TODO(holmer): This is a temporary hack for screensharing, where we
// interpret the startBitrate as the encoder target bitrate. This is
@@ -395,14 +391,15 @@ int SimulcastEncoderAdapter::SetRates(uint32_t new_bitrate_kbit,
if (codec_.targetBitrate > 0 &&
(codec_.codecSpecific.VP8.numberOfTemporalLayers == 2 ||
codec_.simulcastStream[0].numberOfTemporalLayers == 2)) {
- stream_bitrate = std::min(codec_.maxBitrate, stream_bitrate);
+ stream_bitrate_kbps = std::min(codec_.maxBitrate, stream_bitrate_kbps);
// TODO(ronghuawu): Can't change max bitrate via the VideoEncoder
// interface. And VP8EncoderImpl doesn't take negative framerate.
- // max_bitrate = std::min(codec_.maxBitrate, stream_bitrate);
+ // max_bitrate = std::min(codec_.maxBitrate, stream_bitrate_kbps);
// new_framerate = -1;
}
- streaminfos_[stream_idx].encoder->SetRates(stream_bitrate, new_framerate);
+ streaminfos_[stream_idx].encoder->SetRates(stream_bitrate_kbps,
+ new_framerate);
}
return WEBRTC_VIDEO_CODEC_OK;
@@ -422,61 +419,12 @@ EncodedImageCallback::Result SimulcastEncoderAdapter::OnEncodedImage(
encodedImage, &stream_codec_specific, fragmentation);
}
-uint32_t SimulcastEncoderAdapter::GetStreamBitrate(
- int stream_idx,
- size_t total_number_of_streams,
- uint32_t new_bitrate_kbit,
- bool* send_stream) const {
- if (total_number_of_streams == 1) {
- *send_stream = true;
- return new_bitrate_kbit;
- }
-
- // The bitrate needed to start sending this stream is given by the
- // minimum bitrate allowed for encoding this stream, plus the sum target
- // rates of all lower streams.
- uint32_t sum_target_lower_streams =
- SumStreamTargetBitrate(stream_idx, codec_);
- uint32_t bitrate_to_send_this_layer =
- codec_.simulcastStream[stream_idx].minBitrate + sum_target_lower_streams;
- if (new_bitrate_kbit >= bitrate_to_send_this_layer) {
- // We have enough bandwidth to send this stream.
- *send_stream = true;
- // Bitrate for this stream is the new bitrate (|new_bitrate_kbit|) minus the
- // sum target rates of the lower streams, and capped to a maximum bitrate.
- // The maximum cap depends on whether we send the next higher stream.
- // If we will be sending the next higher stream, |max_rate| is given by
- // current stream's |targetBitrate|, otherwise it's capped by |maxBitrate|.
- if (stream_idx < codec_.numberOfSimulcastStreams - 1) {
- unsigned int max_rate = codec_.simulcastStream[stream_idx].maxBitrate;
- if (new_bitrate_kbit >=
- SumStreamTargetBitrate(stream_idx + 1, codec_) +
- codec_.simulcastStream[stream_idx + 1].minBitrate) {
- max_rate = codec_.simulcastStream[stream_idx].targetBitrate;
- }
- return std::min(new_bitrate_kbit - sum_target_lower_streams, max_rate);
- } else {
- // For the highest stream (highest resolution), the |targetBitRate| and
- // |maxBitrate| are not used. Any excess bitrate (above the targets of
- // all lower streams) is given to this (highest resolution) stream.
- return new_bitrate_kbit - sum_target_lower_streams;
- }
- } else {
- // Not enough bitrate for this stream.
- // Return our max bitrate of |stream_idx| - 1, but we don't send it. We need
- // to keep this resolution coding in order for the multi-encoder to work.
- *send_stream = false;
- return codec_.simulcastStream[stream_idx - 1].maxBitrate;
- }
-}
-
void SimulcastEncoderAdapter::PopulateStreamCodec(
const webrtc::VideoCodec* inst,
int stream_index,
- size_t total_number_of_streams,
+ uint32_t start_bitrate_kbps,
bool highest_resolution_stream,
- webrtc::VideoCodec* stream_codec,
- bool* send_stream) {
+ webrtc::VideoCodec* stream_codec) {
*stream_codec = *inst;
// Stream specific settings.
@@ -505,9 +453,7 @@ void SimulcastEncoderAdapter::PopulateStreamCodec(
}
// TODO(ronghuawu): what to do with targetBitrate.
- int stream_bitrate = GetStreamBitrate(stream_index, total_number_of_streams,
- inst->startBitrate, send_stream);
- stream_codec->startBitrate = stream_bitrate;
+ stream_codec->startBitrate = start_bitrate_kbps;
}
bool SimulcastEncoderAdapter::Initialized() const {
« no previous file with comments | « webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.h ('k') | webrtc/modules/video_coding/codecs/vp8/vp8_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698