Enable initial frame drop for SVC 'singlecast'
Bug: none Change-Id: Ideda726f4f7df5e92556048a199cda06261e76b4 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/195542 Reviewed-by: Åsa Persson <asapersson@webrtc.org> Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#32714}
This commit is contained in:
parent
4005e5abb8
commit
cde4a9f669
@ -62,22 +62,39 @@ std::string ToString(VideoAdaptationReason reason) {
|
||||
absl::optional<uint32_t> GetSingleActiveStreamPixels(const VideoCodec& codec) {
|
||||
int num_active = 0;
|
||||
absl::optional<uint32_t> pixels;
|
||||
for (int i = 0; i < codec.numberOfSimulcastStreams; ++i) {
|
||||
if (codec.simulcastStream[i].active) {
|
||||
++num_active;
|
||||
pixels = codec.simulcastStream[i].width * codec.simulcastStream[i].height;
|
||||
if (codec.codecType == VideoCodecType::kVideoCodecVP9) {
|
||||
for (int i = 0; i < codec.VP9().numberOfSpatialLayers; ++i) {
|
||||
if (codec.spatialLayers[i].active) {
|
||||
++num_active;
|
||||
pixels = codec.spatialLayers[i].width * codec.spatialLayers[i].height;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < codec.numberOfSimulcastStreams; ++i) {
|
||||
if (codec.simulcastStream[i].active) {
|
||||
++num_active;
|
||||
pixels =
|
||||
codec.simulcastStream[i].width * codec.simulcastStream[i].height;
|
||||
}
|
||||
}
|
||||
if (num_active > 1)
|
||||
return absl::nullopt;
|
||||
}
|
||||
if (num_active > 1)
|
||||
return absl::nullopt;
|
||||
return pixels;
|
||||
}
|
||||
|
||||
std::vector<bool> GetActiveLayersFlags(const VideoCodec& codec) {
|
||||
const int num_streams = codec.numberOfSimulcastStreams;
|
||||
std::vector<bool> flags(num_streams);
|
||||
for (int i = 0; i < codec.numberOfSimulcastStreams; ++i) {
|
||||
flags[i] = codec.simulcastStream[i].active;
|
||||
std::vector<bool> flags;
|
||||
if (codec.codecType == VideoCodecType::kVideoCodecVP9) {
|
||||
flags.resize(codec.VP9().numberOfSpatialLayers);
|
||||
for (size_t i = 0; i < flags.size(); ++i) {
|
||||
flags[i] = codec.spatialLayers[i].active;
|
||||
}
|
||||
} else {
|
||||
flags.resize(codec.numberOfSimulcastStreams);
|
||||
for (size_t i = 0; i < flags.size(); ++i) {
|
||||
flags[i] = codec.simulcastStream[i].active;
|
||||
}
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
@ -1847,21 +1847,23 @@ void VideoStreamEncoder::OnBitrateUpdated(DataRate target_bitrate,
|
||||
}
|
||||
|
||||
bool VideoStreamEncoder::DropDueToSize(uint32_t pixel_count) const {
|
||||
bool simulcast_or_svc =
|
||||
(send_codec_.codecType == VideoCodecType::kVideoCodecVP9 &&
|
||||
send_codec_.VP9().numberOfSpatialLayers > 1) ||
|
||||
((send_codec_.numberOfSimulcastStreams > 1 ||
|
||||
encoder_config_.simulcast_layers.size() > 1) &&
|
||||
!stream_resource_manager_.SingleActiveStreamPixels());
|
||||
|
||||
if (simulcast_or_svc || !stream_resource_manager_.DropInitialFrames() ||
|
||||
if (!stream_resource_manager_.DropInitialFrames() ||
|
||||
!encoder_target_bitrate_bps_.has_value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (send_codec_.numberOfSimulcastStreams > 1 &&
|
||||
stream_resource_manager_.SingleActiveStreamPixels()) {
|
||||
pixel_count = stream_resource_manager_.SingleActiveStreamPixels().value();
|
||||
bool simulcast_or_svc =
|
||||
(send_codec_.codecType == VideoCodecType::kVideoCodecVP9 &&
|
||||
send_codec_.VP9().numberOfSpatialLayers > 1) ||
|
||||
(send_codec_.numberOfSimulcastStreams > 1 ||
|
||||
encoder_config_.simulcast_layers.size() > 1);
|
||||
|
||||
if (simulcast_or_svc) {
|
||||
if (stream_resource_manager_.SingleActiveStreamPixels()) {
|
||||
pixel_count = stream_resource_manager_.SingleActiveStreamPixels().value();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
absl::optional<VideoEncoder::ResolutionBitrateLimits> encoder_bitrate_limits =
|
||||
|
||||
@ -4619,6 +4619,71 @@ TEST_F(VideoStreamEncoderTest, InitialFrameDropActivatesWhenLayersChange) {
|
||||
video_stream_encoder_->Stop();
|
||||
}
|
||||
|
||||
TEST_F(VideoStreamEncoderTest, InitialFrameDropActivatesWhenSVCLayersChange) {
|
||||
const int kLowTargetBitrateBps = 400000;
|
||||
// Set simulcast.
|
||||
ResetEncoder("VP9", 1, 1, 3, false);
|
||||
fake_encoder_.SetQualityScaling(true);
|
||||
const int kWidth = 1280;
|
||||
const int kHeight = 720;
|
||||
video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
|
||||
DataRate::BitsPerSec(kLowTargetBitrateBps),
|
||||
DataRate::BitsPerSec(kLowTargetBitrateBps),
|
||||
DataRate::BitsPerSec(kLowTargetBitrateBps), 0, 0, 0);
|
||||
video_source_.IncomingCapturedFrame(CreateFrame(1, kWidth, kHeight));
|
||||
// Frame should not be dropped.
|
||||
WaitForEncodedFrame(1);
|
||||
|
||||
// Trigger QVGA "singlecast"
|
||||
// Update the config.
|
||||
VideoEncoderConfig video_encoder_config;
|
||||
test::FillEncoderConfiguration(PayloadStringToCodecType("VP9"), 1,
|
||||
&video_encoder_config);
|
||||
VideoCodecVP9 vp9_settings = VideoEncoder::GetDefaultVp9Settings();
|
||||
vp9_settings.numberOfSpatialLayers = 3;
|
||||
// Since only one layer is active - automatic resize should be enabled.
|
||||
vp9_settings.automaticResizeOn = true;
|
||||
video_encoder_config.encoder_specific_settings =
|
||||
new rtc::RefCountedObject<VideoEncoderConfig::Vp9EncoderSpecificSettings>(
|
||||
vp9_settings);
|
||||
video_encoder_config.max_bitrate_bps = kSimulcastTargetBitrateBps;
|
||||
video_encoder_config.content_type =
|
||||
VideoEncoderConfig::ContentType::kRealtimeVideo;
|
||||
// Currently simulcast layers |active| flags are used to inidicate
|
||||
// which SVC layers are active.
|
||||
video_encoder_config.simulcast_layers.resize(3);
|
||||
|
||||
video_encoder_config.simulcast_layers[0].active = true;
|
||||
video_encoder_config.simulcast_layers[1].active = false;
|
||||
video_encoder_config.simulcast_layers[2].active = false;
|
||||
|
||||
video_stream_encoder_->ConfigureEncoder(video_encoder_config.Copy(),
|
||||
kMaxPayloadLength);
|
||||
video_stream_encoder_->WaitUntilTaskQueueIsIdle();
|
||||
|
||||
video_source_.IncomingCapturedFrame(CreateFrame(2, kWidth, kHeight));
|
||||
// Frame should not be dropped.
|
||||
WaitForEncodedFrame(2);
|
||||
|
||||
// Trigger HD "singlecast"
|
||||
video_encoder_config.simulcast_layers[0].active = false;
|
||||
video_encoder_config.simulcast_layers[1].active = false;
|
||||
video_encoder_config.simulcast_layers[2].active = true;
|
||||
|
||||
video_stream_encoder_->ConfigureEncoder(video_encoder_config.Copy(),
|
||||
kMaxPayloadLength);
|
||||
video_stream_encoder_->WaitUntilTaskQueueIsIdle();
|
||||
|
||||
video_source_.IncomingCapturedFrame(CreateFrame(3, kWidth, kHeight));
|
||||
// Frame should be dropped because of initial frame drop.
|
||||
ExpectDroppedFrame();
|
||||
|
||||
// Expect the sink_wants to specify a scaled frame.
|
||||
EXPECT_TRUE_WAIT(
|
||||
video_source_.sink_wants().max_pixel_count < kWidth * kHeight, 5000);
|
||||
video_stream_encoder_->Stop();
|
||||
}
|
||||
|
||||
TEST_F(VideoStreamEncoderTest,
|
||||
InitialFrameDropActivatesWhenResolutionIncreases) {
|
||||
const int kWidth = 640;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user