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

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

Issue 2510583002: Reland #2 of Issue 2434073003: Extract bitrate allocation ... (Closed)
Patch Set: Addressed comments Created 4 years, 1 month 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 880f45fa7e4ca7f0ffa55ccd67251e3e5f986eec..32472750f5f0fc21df8512431ece44af806377d7 100644
--- a/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc
+++ b/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc
@@ -83,17 +83,6 @@ int VerifyCodec(const webrtc::VideoCodec* inst) {
return WEBRTC_VIDEO_CODEC_OK;
}
-struct ScreenshareTemporalLayersFactory : webrtc::TemporalLayersFactory {
- ScreenshareTemporalLayersFactory() {}
- virtual ~ScreenshareTemporalLayersFactory() {}
-
- virtual webrtc::TemporalLayers* Create(int num_temporal_layers,
- uint8_t initial_tl0_pic_idx) const {
- return new webrtc::ScreenshareLayers(num_temporal_layers, rand(),
- webrtc::Clock::GetRealTimeClock());
- }
-};
-
// An EncodedImageCallback implementation that forwards on calls to a
// SimulcastEncoderAdapter, but with the stream index it's registered with as
// the first parameter to Encoded.
@@ -116,6 +105,25 @@ class AdapterEncodedImageCallback : public webrtc::EncodedImageCallback {
const size_t stream_idx_;
};
+// Utility class used to adapt the simulcast id as reported by the temporal
+// layers factory, since each sub-encoder will report stream 0.
+class TemporalLayersFactoryAdapter : public webrtc::TemporalLayersFactory {
+ public:
+ TemporalLayersFactoryAdapter(int adapted_simulcast_id,
+ const TemporalLayersFactory& tl_factory)
+ : adapted_simulcast_id_(adapted_simulcast_id), tl_factory_(tl_factory) {}
+ ~TemporalLayersFactoryAdapter() override {}
+ webrtc::TemporalLayers* Create(int simulcast_id,
+ int temporal_layers,
+ uint8_t initial_tl0_pic_idx) const override {
+ return tl_factory_.Create(adapted_simulcast_id_, temporal_layers,
+ initial_tl0_pic_idx);
+ }
+
+ const int adapted_simulcast_id_;
+ const TemporalLayersFactory& tl_factory_;
+};
+
} // namespace
namespace webrtc {
@@ -125,7 +133,6 @@ SimulcastEncoderAdapter::SimulcastEncoderAdapter(VideoEncoderFactory* factory)
encoded_complete_callback_(nullptr),
implementation_name_("SimulcastEncoderAdapter") {
memset(&codec_, 0, sizeof(webrtc::VideoCodec));
- rate_allocator_.reset(new SimulcastRateAllocator(codec_));
}
SimulcastEncoderAdapter::~SimulcastEncoderAdapter() {
@@ -173,14 +180,13 @@ 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) {
- screensharing_tl_factory_.reset(new ScreenshareTemporalLayersFactory());
- codec_.VP8()->tl_factory = screensharing_tl_factory_.get();
+ SimulcastRateAllocator rate_allocator(codec_, nullptr);
+ BitrateAllocation allocation = rate_allocator.GetAllocation(
+ codec_.startBitrate * 1000, codec_.maxFramerate);
+ std::vector<uint32_t> start_bitrates;
+ for (int i = 0; i < kMaxSimulcastStreams; ++i) {
+ uint32_t stream_bitrate = allocation.GetSpatialLayerSum(i) / 1000;
+ start_bitrates.push_back(stream_bitrate);
}
std::string implementation_name;
@@ -200,6 +206,9 @@ int SimulcastEncoderAdapter::InitEncode(const VideoCodec* inst,
PopulateStreamCodec(&codec_, i, start_bitrate_kbps,
highest_resolution_stream, &stream_codec);
}
+ TemporalLayersFactoryAdapter tl_factory_adapter(i,
+ *codec_.VP8()->tl_factory);
+ stream_codec.VP8()->tl_factory = &tl_factory_adapter;
// TODO(ronghuawu): Remove once this is handled in VP8EncoderImpl.
if (stream_codec.qpMax < kDefaultMinQp) {
@@ -340,61 +349,48 @@ int SimulcastEncoderAdapter::SetChannelParameters(uint32_t packet_loss,
return WEBRTC_VIDEO_CODEC_OK;
}
-int SimulcastEncoderAdapter::SetRates(uint32_t new_bitrate_kbit,
- uint32_t new_framerate) {
- if (!Initialized()) {
+int SimulcastEncoderAdapter::SetRateAllocation(const BitrateAllocation& bitrate,
+ uint32_t new_framerate) {
+ if (!Initialized())
return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
- }
- if (new_framerate < 1) {
+
+ if (new_framerate < 1)
+ return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+
+ if (codec_.maxBitrate > 0 && bitrate.get_sum_kbps() > codec_.maxBitrate)
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
- }
- 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) {
+ if (bitrate.get_sum_bps() > 0) {
// Make sure the bitrate fits the configured min bitrates. 0 is a special
// value that means paused, though, so leave it alone.
- if (new_bitrate_kbit < codec_.minBitrate) {
- new_bitrate_kbit = codec_.minBitrate;
- }
+ if (bitrate.get_sum_kbps() < codec_.minBitrate)
+ return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
+
if (codec_.numberOfSimulcastStreams > 0 &&
- new_bitrate_kbit < codec_.simulcastStream[0].minBitrate) {
- new_bitrate_kbit = codec_.simulcastStream[0].minBitrate;
+ bitrate.get_sum_kbps() < codec_.simulcastStream[0].minBitrate) {
+ return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
}
- stream_bitrates = rate_allocator_->GetAllocation(new_bitrate_kbit);
}
- codec_.maxFramerate = new_framerate;
- // Disable any stream not in the current allocation.
- stream_bitrates.resize(streaminfos_.size(), 0U);
+ codec_.maxFramerate = new_framerate;
for (size_t stream_idx = 0; stream_idx < streaminfos_.size(); ++stream_idx) {
- uint32_t stream_bitrate_kbps = stream_bitrates[stream_idx];
+ uint32_t stream_bitrate_kbps =
+ bitrate.GetSpatialLayerSum(stream_idx) / 1000;
+
// Need a key frame if we have not sent this stream before.
if (stream_bitrate_kbps > 0 && !streaminfos_[stream_idx].send_stream) {
streaminfos_[stream_idx].key_frame_request = true;
}
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
- // to allow for a different max bitrate, so if the codec can't meet
- // the target we still allow it to overshoot up to the max before dropping
- // frames. This hack should be improved.
- if (codec_.targetBitrate > 0 &&
- (codec_.VP8()->numberOfTemporalLayers == 2 ||
- codec_.simulcastStream[0].numberOfTemporalLayers == 2)) {
- 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_kbps);
- // new_framerate = -1;
- }
-
- streaminfos_[stream_idx].encoder->SetRates(stream_bitrate_kbps,
- new_framerate);
+ // Slice the temporal layers out of the full allocation and pass it on to
+ // the encoder handling the current simulcast stream.
+ BitrateAllocation stream_allocation;
+ for (int i = 0; i < kMaxTemporalStreams; ++i)
+ stream_allocation.SetBitrate(0, i, bitrate.GetBitrate(stream_idx, i));
+ streaminfos_[stream_idx].encoder->SetRateAllocation(stream_allocation,
+ new_framerate);
}
return WEBRTC_VIDEO_CODEC_OK;

Powered by Google App Engine
This is Rietveld 408576698