webrtc_m130/modules/video_coding/video_codec_initializer.cc

358 lines
15 KiB
C++
Raw Normal View History

Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
/*
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/video_coding/include/video_codec_initializer.h"
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
#include <stdint.h>
#include <string.h>
#include <algorithm>
#include "absl/types/optional.h"
#include "api/array_view.h"
#include "api/field_trials_view.h"
#include "api/scoped_refptr.h"
#include "api/units/data_rate.h"
#include "api/video_codecs/video_encoder.h"
#include "modules/video_coding/codecs/av1/av1_svc_config.h"
#include "modules/video_coding/codecs/vp8/vp8_scalability.h"
#include "modules/video_coding/codecs/vp9/svc_config.h"
#include "modules/video_coding/include/video_coding_defines.h"
#include "modules/video_coding/svc/scalability_mode_util.h"
#include "rtc_base/checks.h"
#include "rtc_base/experiments/min_video_bitrate_experiment.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_conversions.h"
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
namespace webrtc {
// TODO(sprang): Split this up and separate the codec specific parts.
VideoCodec VideoCodecInitializer::SetupCodec(
const FieldTrialsView& field_trials,
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
const VideoEncoderConfig& config,
const std::vector<VideoStream>& streams) {
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
static const int kEncoderMinBitrateKbps = 30;
RTC_DCHECK(!streams.empty());
RTC_DCHECK_GE(config.min_transmit_bitrate_bps, 0);
VideoCodec video_codec;
Reland "Reland "Move rtp-specific config out of EncoderSettings."" This reverts commit 6c2c13af06b32778b86950681758a7970d1c5d9e. Reason for revert: Intend to investigate and fix perf problems. Original change's description: > Revert "Reland "Move rtp-specific config out of EncoderSettings."" > > This reverts commit 04dd1768625eb2241d1fb97fd0137897e703e266. > > Reason for revert: Regression in ramp up perf tests. > > Original change's description: > > Reland "Move rtp-specific config out of EncoderSettings." > > > > This is a reland of bc900cb1d1810fcf678fe41cf1e3966daa39c88c > > > > Original change's description: > > > Move rtp-specific config out of EncoderSettings. > > > > > > In VideoSendStream::Config, move payload_name and payload_type from > > > EncoderSettings to Rtp. > > > > > > EncoderSettings now contains configuration for VideoStreamEncoder only, > > > and should perhaps be renamed in a follow up cl. It's no longer > > > passed as an argument to VideoCodecInitializer::SetupCodec. > > > > > > The latter then needs a different way to know the codec type, > > > which is provided by a new codec_type member in VideoEncoderConfig. > > > > > > Bug: webrtc:8830 > > > Change-Id: Ifcc691aef1ee6a95e43c0452c5e630d92a511cd6 > > > Reviewed-on: https://webrtc-review.googlesource.com/62062 > > > Commit-Queue: Niels Moller <nisse@webrtc.org> > > > Reviewed-by: Magnus Jedvert <magjed@webrtc.org> > > > Reviewed-by: Stefan Holmer <stefan@webrtc.org> > > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> > > > Cr-Commit-Position: refs/heads/master@{#22532} > > > > Bug: webrtc:8830 > > Change-Id: If88ef7d57cdaa4fae3c7b2a97ea5a6e1b833e019 > > Reviewed-on: https://webrtc-review.googlesource.com/63721 > > Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org> > > Commit-Queue: Niels Moller <nisse@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#22595} > > TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org > > Bug: webrtc:8830,chromium:827080 > Change-Id: Iaaf146de91ec5c0d741b8efdf143f7e173084fef > Reviewed-on: https://webrtc-review.googlesource.com/65520 > Commit-Queue: Niels Moller <nisse@webrtc.org> > Reviewed-by: Niels Moller <nisse@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#22677} TBR=brandtr@webrtc.org,magjed@webrtc.org,nisse@webrtc.org,stefan@webrtc.org # Not skipping CQ checks because original CL landed > 1 day ago. Bug: webrtc:8830, chromium:827080 Change-Id: I9b62987bf5daced90dfeb3ebb6739c80117c487f Reviewed-on: https://webrtc-review.googlesource.com/66862 Commit-Queue: Niels Moller <nisse@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#22751}
2018-04-05 15:36:51 +02:00
video_codec.codecType = config.codec_type;
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
switch (config.content_type) {
case VideoEncoderConfig::ContentType::kRealtimeVideo:
video_codec.mode = VideoCodecMode::kRealtimeVideo;
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
break;
case VideoEncoderConfig::ContentType::kScreen:
video_codec.mode = VideoCodecMode::kScreensharing;
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
break;
}
video_codec.legacy_conference_mode =
config.content_type == VideoEncoderConfig::ContentType::kScreen &&
config.legacy_conference_mode;
video_codec.SetFrameDropEnabled(config.frame_drop_enabled);
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
video_codec.numberOfSimulcastStreams =
static_cast<unsigned char>(streams.size());
video_codec.minBitrate = streams[0].min_bitrate_bps / 1000;
bool codec_active = false;
// Active configuration might not be fully copied to `streams` for SVC yet.
// Therefore the `config` is checked here.
for (const VideoStream& stream : config.simulcast_layers) {
if (stream.active) {
codec_active = true;
break;
}
}
// Set active for the entire video codec for the non simulcast case.
video_codec.active = codec_active;
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
if (video_codec.minBitrate < kEncoderMinBitrateKbps)
video_codec.minBitrate = kEncoderMinBitrateKbps;
video_codec.timing_frame_thresholds = {kDefaultTimingFramesDelayMs,
kDefaultOutlierFrameSizePercent};
RTC_DCHECK_LE(streams.size(), kMaxSimulcastStreams);
int max_framerate = 0;
absl::optional<ScalabilityMode> scalability_mode =
streams[0].scalability_mode;
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
for (size_t i = 0; i < streams.size(); ++i) {
SimulcastStream* sim_stream = &video_codec.simulcastStream[i];
RTC_DCHECK_GT(streams[i].width, 0);
RTC_DCHECK_GT(streams[i].height, 0);
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
RTC_DCHECK_GT(streams[i].max_framerate, 0);
RTC_DCHECK_GE(streams[i].min_bitrate_bps, 0);
RTC_DCHECK_GE(streams[i].target_bitrate_bps, streams[i].min_bitrate_bps);
RTC_DCHECK_GE(streams[i].max_bitrate_bps, streams[i].target_bitrate_bps);
RTC_DCHECK_GE(streams[i].max_qp, 0);
sim_stream->width = static_cast<uint16_t>(streams[i].width);
sim_stream->height = static_cast<uint16_t>(streams[i].height);
sim_stream->maxFramerate = streams[i].max_framerate;
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
sim_stream->minBitrate = streams[i].min_bitrate_bps / 1000;
sim_stream->targetBitrate = streams[i].target_bitrate_bps / 1000;
sim_stream->maxBitrate = streams[i].max_bitrate_bps / 1000;
sim_stream->qpMax = streams[i].max_qp;
int num_temporal_layers =
streams[i].scalability_mode.has_value()
? ScalabilityModeToNumTemporalLayers(*streams[i].scalability_mode)
: streams[i].num_temporal_layers.value_or(1);
Reland "Replaced temporal_layer_thresholds_bps[] field with num_temporal_layers." This reverts commit e27e0aca9411b6990fcdf56d8a3475569ee5fd2f. Reason for revert: <INSERT REASONING HERE> Original change's description: > Revert "Replaced temporal_layer_thresholds_bps[] field with num_temporal_layers." > > This reverts commit d2ed0a4c9e7f04060d8e3358eb0006c31579bb86. > > Reason for revert: Breaks downstream projects. > > Original change's description: > > Replaced temporal_layer_thresholds_bps[] field with num_temporal_layers. > > > > temporal_layer_thresholds_bps served only one purpose: its size was used > > to infer number of temporal layers. I replaced it with num_temporal_layers, > > which does what is says. > > > > The practical reason for this change is the need to have possibility to > > distinguish between cases when VP9 SVC temporal layering was/not set > > through field trial. That was not possible with > > temporal_layer_thresholds_bps[] because empty vector means 1 temporal > > layer. > > > > Bug: webrtc:8518 > > Change-Id: I275ec3a8c74e8ba409eb049878199f132a20ec51 > > Reviewed-on: https://webrtc-review.googlesource.com/58084 > > Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> > > Reviewed-by: Erik Språng <sprang@webrtc.org> > > Reviewed-by: Stefan Holmer <stefan@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#22230} > > TBR=sprang@webrtc.org,stefan@webrtc.org,ssilkin@webrtc.org > > Change-Id: Ic2940f7f78a74312170940d51ad8967cde8ad42f > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: webrtc:8518 > Reviewed-on: https://webrtc-review.googlesource.com/58902 > Reviewed-by: Philip Eliasson <philipel@webrtc.org> > Commit-Queue: Philip Eliasson <philipel@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#22234} TBR=sprang@webrtc.org,stefan@webrtc.org,philipel@webrtc.org,ssilkin@webrtc.org Change-Id: I1900c6b845b9baa9430fb72c3f4e7f2a44b3a8b1 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: webrtc:8518 Reviewed-on: https://webrtc-review.googlesource.com/59160 Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> Reviewed-by: Sergey Silkin <ssilkin@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/master@{#22256}
2018-03-01 15:11:29 +01:00
sim_stream->numberOfTemporalLayers =
static_cast<unsigned char>(num_temporal_layers);
sim_stream->active = streams[i].active;
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
video_codec.width =
std::max(video_codec.width, static_cast<uint16_t>(streams[i].width));
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
video_codec.height =
std::max(video_codec.height, static_cast<uint16_t>(streams[i].height));
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
video_codec.minBitrate =
std::min(static_cast<uint16_t>(video_codec.minBitrate),
static_cast<uint16_t>(streams[i].min_bitrate_bps / 1000));
video_codec.maxBitrate += streams[i].max_bitrate_bps / 1000;
video_codec.qpMax = std::max(video_codec.qpMax,
static_cast<unsigned int>(streams[i].max_qp));
max_framerate = std::max(max_framerate, streams[i].max_framerate);
// TODO(bugs.webrtc.org/11607): Since scalability mode is a top-level
// setting on VideoCodec, setting it makes sense only if it is the same for
Fix crash happening when changing from legacy to standard VP9. Attempting to ship "WebRTC-AllowDisablingLegacyScalability" revealed a DCHECK that happens when negotiating 3 VP9 streams prior to the setParameters() call: 1. By default, `scalability_mode` is missing, so those 3 streams defaulted to legacy SVC, meaning only a single stream is used. 2. Then, setParameters() was called to make `encodings[0].scalability_mode = "L2T2_KEY"` and `encodings[1-2].active = false`. The inactive streams were just dummies and never expected to exist. Without simulcast support this is OK, because both 1) and 2) are interpreted to have a single stream. But with simulcast support, 1) is interpreted as single stream and 2) as three streams (1 active, 2 inactive). This should be roughly the same setup, but our code treats them differently. The DCHECK crash was a mismatch in number of streams in one of the layers. The fix is to re-create the streams when the number of streams change for this reason. The new test revealed other issues and fixes too: - Support for multiple spatial layers (e.g. "L2T2_KEY") when multiple encodings exist but only one encoding is active. - Allow inactive layers not to have a scalability mode set. A laundry list (https://crbug.com/webrtc/15028) has been created to update known places doing "if streams == 1" that need to do "if active streams == 1" instead. Credit: The RecreateWebRtcStream() fix is based on eshr@'s POC from https://webrtc-review.googlesource.com/c/src/+/298565. Bug: webrtc:15016 Change-Id: I909a3f83a4ef53562894549ade0a870b208cec7e Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/298443 Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Reviewed-by: Evan Shrubsole <eshr@google.com> Cr-Commit-Position: refs/heads/main@{#39651}
2023-03-22 18:08:00 +01:00
// all active simulcast streams.
if (streams[i].active &&
streams[0].scalability_mode != streams[i].scalability_mode) {
scalability_mode.reset();
// For VP8, top-level scalability mode doesn't matter, since configuration
// is based on the per-simulcast stream configuration of temporal layers.
if (video_codec.codecType != kVideoCodecVP8) {
RTC_LOG(LS_WARNING) << "Inconsistent scalability modes configured.";
}
}
}
if (scalability_mode.has_value()) {
video_codec.SetScalabilityMode(*scalability_mode);
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
}
if (video_codec.maxBitrate == 0) {
// Unset max bitrate -> cap to one bit per pixel.
video_codec.maxBitrate =
(video_codec.width * video_codec.height * video_codec.maxFramerate) /
1000;
}
if (video_codec.maxBitrate < kEncoderMinBitrateKbps)
video_codec.maxBitrate = kEncoderMinBitrateKbps;
video_codec.maxFramerate = max_framerate;
video_codec.spatialLayers[0] = {0};
video_codec.spatialLayers[0].width = video_codec.width;
video_codec.spatialLayers[0].height = video_codec.height;
video_codec.spatialLayers[0].maxFramerate = max_framerate;
video_codec.spatialLayers[0].numberOfTemporalLayers =
streams[0].scalability_mode.has_value()
? ScalabilityModeToNumTemporalLayers(*streams[0].scalability_mode)
: streams[0].num_temporal_layers.value_or(1);
// Set codec specific options
if (config.encoder_specific_settings)
config.encoder_specific_settings->FillEncoderSpecificSettings(&video_codec);
switch (video_codec.codecType) {
case kVideoCodecVP8: {
if (!config.encoder_specific_settings) {
*video_codec.VP8() = VideoEncoder::GetDefaultVp8Settings();
}
// Validate specified scalability modes. If some layer has an unsupported
// mode, store it as the top-level scalability mode, which will make
// InitEncode fail with an appropriate error.
for (const auto& stream : streams) {
if (stream.scalability_mode.has_value() &&
!VP8SupportsScalabilityMode(*stream.scalability_mode)) {
RTC_LOG(LS_WARNING)
<< "Invalid scalability mode for VP8: "
<< ScalabilityModeToString(*stream.scalability_mode);
video_codec.SetScalabilityMode(*stream.scalability_mode);
break;
}
}
video_codec.VP8()->numberOfTemporalLayers =
streams.back().scalability_mode.has_value()
? ScalabilityModeToNumTemporalLayers(
*streams.back().scalability_mode)
: streams.back().num_temporal_layers.value_or(
video_codec.VP8()->numberOfTemporalLayers);
RTC_DCHECK_GE(video_codec.VP8()->numberOfTemporalLayers, 1);
RTC_DCHECK_LE(video_codec.VP8()->numberOfTemporalLayers,
kMaxTemporalStreams);
break;
}
case kVideoCodecVP9: {
// When the SvcRateAllocator is used, "active" is controlled by
// `SpatialLayer::active` instead.
if (video_codec.numberOfSimulcastStreams <= 1) {
video_codec.simulcastStream[0].active = codec_active;
}
if (!config.encoder_specific_settings) {
*video_codec.VP9() = VideoEncoder::GetDefaultVp9Settings();
}
video_codec.VP9()->numberOfTemporalLayers = static_cast<unsigned char>(
streams.back().num_temporal_layers.value_or(
video_codec.VP9()->numberOfTemporalLayers));
RTC_DCHECK_GE(video_codec.VP9()->numberOfTemporalLayers, 1);
RTC_DCHECK_LE(video_codec.VP9()->numberOfTemporalLayers,
kMaxTemporalStreams);
RTC_DCHECK(config.spatial_layers.empty() ||
config.spatial_layers.size() ==
video_codec.VP9()->numberOfSpatialLayers);
std::vector<SpatialLayer> spatial_layers;
if (!config.spatial_layers.empty()) {
// Layering is set explicitly.
spatial_layers = config.spatial_layers;
} else if (video_codec.GetScalabilityMode().has_value()) {
// Layering is set via scalability mode.
spatial_layers = GetVp9SvcConfig(video_codec);
} else {
size_t first_active_layer = 0;
for (size_t spatial_idx = 0;
spatial_idx < config.simulcast_layers.size(); ++spatial_idx) {
if (config.simulcast_layers[spatial_idx].active) {
first_active_layer = spatial_idx;
break;
}
}
spatial_layers = GetSvcConfig(
video_codec.width, video_codec.height, video_codec.maxFramerate,
first_active_layer, video_codec.VP9()->numberOfSpatialLayers,
video_codec.VP9()->numberOfTemporalLayers,
video_codec.mode == VideoCodecMode::kScreensharing);
// If there was no request for spatial layering, don't limit bitrate
// of single spatial layer.
const bool no_spatial_layering =
video_codec.VP9()->numberOfSpatialLayers <= 1;
if (no_spatial_layering) {
// Use codec's bitrate limits.
spatial_layers.back().minBitrate = video_codec.minBitrate;
spatial_layers.back().targetBitrate = video_codec.maxBitrate;
spatial_layers.back().maxBitrate = video_codec.maxBitrate;
}
for (size_t spatial_idx = first_active_layer;
spatial_idx < config.simulcast_layers.size() &&
spatial_idx < spatial_layers.size() + first_active_layer;
++spatial_idx) {
spatial_layers[spatial_idx - first_active_layer].active =
config.simulcast_layers[spatial_idx].active;
}
}
RTC_DCHECK(!spatial_layers.empty());
for (size_t i = 0; i < spatial_layers.size(); ++i) {
video_codec.spatialLayers[i] = spatial_layers[i];
}
// The top spatial layer dimensions may not be equal to the input
// resolution because of the rounding or explicit configuration.
// This difference must be propagated to the stream configuration.
video_codec.width = spatial_layers.back().width;
video_codec.height = spatial_layers.back().height;
// Only propagate if we're not doing simulcast. Simulcast is assumed not
// to have multiple spatial layers, if we wanted to support simulcast+SVC
// combos we would need to calculate unique spatial layers per simulcast
// layer, but VideoCodec is not capable of expressing per-simulcastStream
// spatialLayers.
if (video_codec.numberOfSimulcastStreams == 1) {
video_codec.simulcastStream[0].width = spatial_layers.back().width;
video_codec.simulcastStream[0].height = spatial_layers.back().height;
}
// Update layering settings.
video_codec.VP9()->numberOfSpatialLayers =
static_cast<unsigned char>(spatial_layers.size());
RTC_DCHECK_GE(video_codec.VP9()->numberOfSpatialLayers, 1);
RTC_DCHECK_LE(video_codec.VP9()->numberOfSpatialLayers,
kMaxSpatialLayers);
video_codec.VP9()->numberOfTemporalLayers = static_cast<unsigned char>(
spatial_layers.back().numberOfTemporalLayers);
RTC_DCHECK_GE(video_codec.VP9()->numberOfTemporalLayers, 1);
RTC_DCHECK_LE(video_codec.VP9()->numberOfTemporalLayers,
kMaxTemporalStreams);
break;
}
case kVideoCodecAV1:
if (SetAv1SvcConfig(video_codec,
/*num_temporal_layers=*/
streams.back().num_temporal_layers.value_or(1),
/*num_spatial_layers=*/
std::max<int>(config.spatial_layers.size(), 1))) {
// If min bitrate is set via RtpEncodingParameters, use this value on
// lowest spatial layer.
if (!config.simulcast_layers.empty() &&
config.simulcast_layers[0].min_bitrate_bps > 0) {
video_codec.spatialLayers[0].minBitrate = std::min(
config.simulcast_layers[0].min_bitrate_bps / 1000,
static_cast<int>(video_codec.spatialLayers[0].targetBitrate));
}
for (size_t i = 0; i < config.spatial_layers.size(); ++i) {
video_codec.spatialLayers[i].active = config.spatial_layers[i].active;
}
} else {
RTC_LOG(LS_WARNING) << "Failed to configure svc bitrates for av1.";
}
break;
case kVideoCodecH264: {
RTC_CHECK(!config.encoder_specific_settings);
*video_codec.H264() = VideoEncoder::GetDefaultH264Settings();
video_codec.H264()->numberOfTemporalLayers = static_cast<unsigned char>(
streams.back().num_temporal_layers.value_or(
video_codec.H264()->numberOfTemporalLayers));
RTC_DCHECK_GE(video_codec.H264()->numberOfTemporalLayers, 1);
RTC_DCHECK_LE(video_codec.H264()->numberOfTemporalLayers,
kMaxTemporalStreams);
break;
}
case kVideoCodecH265:
// TODO(bugs.webrtc.org/13485)
break;
default:
// TODO(pbos): Support encoder_settings codec-agnostically.
RTC_DCHECK(!config.encoder_specific_settings)
<< "Encoder-specific settings for codec type not wired up.";
break;
}
const absl::optional<DataRate> experimental_min_bitrate =
GetExperimentalMinVideoBitrate(field_trials, video_codec.codecType);
if (experimental_min_bitrate) {
const int experimental_min_bitrate_kbps =
rtc::saturated_cast<int>(experimental_min_bitrate->kbps());
video_codec.minBitrate = experimental_min_bitrate_kbps;
video_codec.simulcastStream[0].minBitrate = experimental_min_bitrate_kbps;
if (video_codec.codecType == kVideoCodecVP9 ||
video_codec.codecType == kVideoCodecAV1) {
video_codec.spatialLayers[0].minBitrate = experimental_min_bitrate_kbps;
}
}
Reland #2 of Issue 2434073003: Extract bitrate allocation ... This is yet another reland of https://codereview.webrtc.org/2434073003/ including two fixes: 1. SimulcastRateAllocator did not handle the screenshare settings properly for numSimulcastStreams = 1. Additional test case was added for that. 2. In VideoSender, when rate allocation is updated after setting a new VideoCodec config, only update the state of the EncoderParameters, but don't actually run SetRateAllocation on the encoder itself. This caused some problems upstreams. Please review only the changes after patch set 1. Original description: Extract bitrate allocation of spatial/temporal layers out of codec impl. This CL makes a number of intervowen changes: * Add BitrateAllocation struct, that contains a codec independent view of how the target bitrate is distributed over spatial and temporal layers. * Adds the BitrateAllocator interface, which takes a bitrate and frame rate and produces a BitrateAllocation. * A default (non layered) implementation is added, and SimulcastRateAllocator is extended to fully handle VP8 allocation. This includes capturing TemporalLayer instances created by the encoder. * ViEEncoder now owns both the bitrate allocator and the temporal layer factories for VP8. This allows allocation to happen fully outside of the encoder implementation. This refactoring will make it possible for ViEEncoder to signal the full picture of target bitrates to the RTCP module. BUG=webrtc:6301 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2510583002 . Cr-Commit-Position: refs/heads/master@{#15105}
2016-11-16 16:41:30 +01:00
return video_codec;
}
} // namespace webrtc