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 1c8037a60e9ce4657a146cd0ba888798e416ac40..5d005d95d3443e4d17b7ee0966ec9b9451a81335 100644 |
--- a/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc |
+++ b/webrtc/modules/video_coding/codecs/vp8/simulcast_encoder_adapter.cc |
@@ -85,17 +85,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. |
@@ -127,7 +116,7 @@ SimulcastEncoderAdapter::SimulcastEncoderAdapter(VideoEncoderFactory* factory) |
encoded_complete_callback_(nullptr), |
implementation_name_("SimulcastEncoderAdapter") { |
memset(&codec_, 0, sizeof(webrtc::VideoCodec)); |
- rate_allocator_.reset(new SimulcastRateAllocator(codec_)); |
+ fallback_rate_allocator_.reset(new SimulcastRateAllocator(codec_)); |
} |
SimulcastEncoderAdapter::~SimulcastEncoderAdapter() { |
@@ -175,14 +164,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_.codecSpecific.VP8.tl_factory = screensharing_tl_factory_.get(); |
+ fallback_rate_allocator_.reset(new SimulcastRateAllocator(codec_)); |
+ std::vector<uint32_t> start_bitrates; |
+ BitrateAllocation allocation = fallback_rate_allocator_->GetAllocation( |
+ codec_.startBitrate * 1000, codec_.maxFramerate); |
+ for (int i = 0; i < kMaxSimulcastStreams; ++i) { |
+ uint32_t stream_bitrate = allocation.get_spatial_layer_sum(i) / 1000; |
+ start_bitrates.push_back(stream_bitrate); |
} |
std::string implementation_name; |
@@ -344,36 +332,44 @@ int SimulcastEncoderAdapter::SetChannelParameters(uint32_t packet_loss, |
int SimulcastEncoderAdapter::SetRates(uint32_t new_bitrate_kbit, |
uint32_t new_framerate) { |
- if (!Initialized()) { |
- return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
+ BitrateAllocation allocation; |
+ if (new_bitrate_kbit != 0) { |
+ allocation = fallback_rate_allocator_->GetAllocation( |
+ new_bitrate_kbit * 1000, new_framerate); |
} |
- if (new_framerate < 1) { |
+ |
+ return SetRateAllocation(allocation, new_framerate); |
+} |
+ |
+int SimulcastEncoderAdapter::SetRateAllocation(const BitrateAllocation& bitrate, |
+ uint32_t new_framerate) { |
+ if (!Initialized()) |
+ return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
+ |
+ 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.get_spatial_layer_sum(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; |
@@ -389,14 +385,21 @@ int SimulcastEncoderAdapter::SetRates(uint32_t new_bitrate_kbit, |
(codec_.codecSpecific.VP8.numberOfTemporalLayers == 2 || |
codec_.simulcastStream[0].numberOfTemporalLayers == 2)) { |
stream_bitrate_kbps = std::min(codec_.maxBitrate, stream_bitrate_kbps); |
+ streaminfos_[stream_idx].encoder->SetRates(stream_bitrate_kbps, |
+ new_framerate); |
// 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; |
+ } else { |
+ // 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.set_bitrate(0, i, bitrate.get_bitrate(stream_idx, i)); |
+ streaminfos_[stream_idx].encoder->SetRateAllocation(stream_allocation, |
+ new_framerate); |
} |
- |
- streaminfos_[stream_idx].encoder->SetRates(stream_bitrate_kbps, |
- new_framerate); |
} |
return WEBRTC_VIDEO_CODEC_OK; |