| 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;
|
|
|