SEA: Only spawn multi-layered encoders if active layers > 1.
With this CL, SimulcastEncoderAdapter no longer configures its encoder as multi-layered if we only have a single active layer. Instead we create a single single-layered encoder for that one and only active layer. When using VP8 SW encoder this means that LibvpxVp8Encoder is configured to only prepare a single video frame which avoids the cost of scaling down to layers that we do not send. (A multi-layered LibvpxVp8Encoder is required to scale even layers we don't encode.) When profiling this CL I found very small but measurable gains for representative downscale factors of 20.1 ms of 60 s profile. This is just 0.0335% CPU so it's not much, but skipping a downscale might be worth a lot more if we have to map/unmap buffers or do GPU round-trips in the future (which I have not measured). When downscaling to factors 4 and 2 due to libyuv having a "fast-path" for these (i.e. no adaptation active), zero difference was found for NV12. For I420 there was small regression of 16.1 ms (0.026% CPU) for this one edge-case. It's possible to work around this, but considering the tiny changes we're talking about, I really don't think it's worth the additional complexity. I'll file a bug on libyuv about scaling factors 2+2 vs 4 and leave it at that. Bug: webrtc:12603 Change-Id: Id462140c6a829cf6b460baae868e94243f477db3 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/219683 Commit-Queue: Henrik Boström <hbos@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#34092}
This commit is contained in:

committed by
WebRTC LUCI CQ

parent
bcadacdb0f
commit
70cd086644
@ -344,20 +344,24 @@ int SimulcastEncoderAdapter::InitEncode(
|
||||
|
||||
// Two distinct scenarios:
|
||||
// * Singlecast (total_streams_count == 1) or simulcast with simulcast-capable
|
||||
// underlaying encoder implementation. SEA operates in bypass mode: original
|
||||
// settings are passed to the underlaying encoder, frame encode complete
|
||||
// callback is not intercepted.
|
||||
// underlaying encoder implementation if active_streams_count > 1. SEA
|
||||
// operates in bypass mode: original settings are passed to the underlaying
|
||||
// encoder, frame encode complete callback is not intercepted.
|
||||
// * Multi-encoder simulcast or singlecast if layers are deactivated
|
||||
// (total_streams_count > 1 and active_streams_count >= 1). SEA creates
|
||||
// N=active_streams_count encoders and configures each to produce a single
|
||||
// stream.
|
||||
// (active_streams_count >= 1). SEA creates N=active_streams_count encoders
|
||||
// and configures each to produce a single stream.
|
||||
|
||||
int active_streams_count = CountActiveStreams(*inst);
|
||||
// If we only have a single active layer it is better to create an encoder
|
||||
// with only one configured layer than creating it with all-but-one disabled
|
||||
// layers because that way we control scaling.
|
||||
bool separate_encoders_needed =
|
||||
!encoder_context->encoder().GetEncoderInfo().supports_simulcast ||
|
||||
active_streams_count == 1;
|
||||
// Singlecast or simulcast with simulcast-capable underlaying encoder.
|
||||
if (total_streams_count_ == 1 ||
|
||||
encoder_context->encoder().GetEncoderInfo().supports_simulcast) {
|
||||
if (total_streams_count_ == 1 || !separate_encoders_needed) {
|
||||
int ret = encoder_context->encoder().InitEncode(&codec_, settings);
|
||||
if (ret >= 0) {
|
||||
int active_streams_count = CountActiveStreams(*inst);
|
||||
stream_contexts_.emplace_back(
|
||||
/*parent=*/nullptr, std::move(encoder_context),
|
||||
/*framerate_controller=*/nullptr, /*stream_idx=*/0, codec_.width,
|
||||
|
Reference in New Issue
Block a user