@@ -149,9 +149,13 @@ namespace webrtc {
149
149
150
150
SimulcastEncoderAdapter::EncoderContext::EncoderContext (
151
151
std::unique_ptr<VideoEncoder> encoder,
152
- bool prefer_temporal_support)
152
+ bool prefer_temporal_support,
153
+ VideoEncoder::EncoderInfo primary_info,
154
+ VideoEncoder::EncoderInfo fallback_info)
153
155
: encoder_(std::move(encoder)),
154
- prefer_temporal_support_ (prefer_temporal_support) {}
156
+ prefer_temporal_support_ (prefer_temporal_support),
157
+ primary_info_(std::move(primary_info)),
158
+ fallback_info_(std::move(fallback_info)) {}
155
159
156
160
void SimulcastEncoderAdapter::EncoderContext::Release () {
157
161
if (encoder_) {
@@ -690,7 +694,7 @@ void SimulcastEncoderAdapter::DestroyStoredEncoders() {
690
694
691
695
std::unique_ptr<SimulcastEncoderAdapter::EncoderContext>
692
696
SimulcastEncoderAdapter::FetchOrCreateEncoderContext (
693
- bool is_lowest_quality_stream) {
697
+ bool is_lowest_quality_stream) const {
694
698
bool prefer_temporal_support = fallback_encoder_factory_ != nullptr &&
695
699
is_lowest_quality_stream &&
696
700
prefer_temporal_support_on_base_layer_;
@@ -712,14 +716,20 @@ SimulcastEncoderAdapter::FetchOrCreateEncoderContext(
712
716
} else {
713
717
std::unique_ptr<VideoEncoder> encoder =
714
718
primary_encoder_factory_->CreateVideoEncoder (video_format_);
719
+ VideoEncoder::EncoderInfo primary_info = encoder->GetEncoderInfo ();
720
+ VideoEncoder::EncoderInfo fallback_info = primary_info;
715
721
if (fallback_encoder_factory_ != nullptr ) {
722
+ std::unique_ptr<VideoEncoder> fallback_encoder =
723
+ fallback_encoder_factory_->CreateVideoEncoder (video_format_);
724
+ fallback_info = fallback_encoder->GetEncoderInfo ();
716
725
encoder = CreateVideoEncoderSoftwareFallbackWrapper (
717
- fallback_encoder_factory_-> CreateVideoEncoder (video_format_ ),
718
- std::move (encoder), prefer_temporal_support);
726
+ std::move (fallback_encoder), std::move (encoder ),
727
+ prefer_temporal_support);
719
728
}
720
729
721
730
encoder_context = std::make_unique<SimulcastEncoderAdapter::EncoderContext>(
722
- std::move (encoder), prefer_temporal_support);
731
+ std::move (encoder), prefer_temporal_support, primary_info,
732
+ fallback_info);
723
733
}
724
734
725
735
encoder_context->encoder ().RegisterEncodeCompleteCallback (
@@ -789,9 +799,11 @@ webrtc::VideoCodec SimulcastEncoderAdapter::MakeStreamCodec(
789
799
void SimulcastEncoderAdapter::OverrideFromFieldTrial (
790
800
VideoEncoder::EncoderInfo* info) const {
791
801
if (encoder_info_override_.requested_resolution_alignment ()) {
792
- info->requested_resolution_alignment =
793
- *encoder_info_override_.requested_resolution_alignment ();
802
+ info->requested_resolution_alignment = cricket::LeastCommonMultiple (
803
+ info->requested_resolution_alignment ,
804
+ *encoder_info_override_.requested_resolution_alignment ());
794
805
info->apply_alignment_to_all_simulcast_layers =
806
+ info->apply_alignment_to_all_simulcast_layers ||
795
807
encoder_info_override_.apply_alignment_to_all_simulcast_layers ();
796
808
}
797
809
if (!encoder_info_override_.resolution_bitrate_limits ().empty ()) {
@@ -815,7 +827,34 @@ VideoEncoder::EncoderInfo SimulcastEncoderAdapter::GetEncoderInfo() const {
815
827
encoder_info.apply_alignment_to_all_simulcast_layers = false ;
816
828
encoder_info.supports_native_handle = true ;
817
829
encoder_info.scaling_settings .thresholds = absl::nullopt;
830
+
818
831
if (stream_contexts_.empty ()) {
832
+ // GetEncoderInfo queried before InitEncode. Only alignment info is needed
833
+ // to be filled.
834
+ // Create one encoder and query it.
835
+
836
+ std::unique_ptr<SimulcastEncoderAdapter::EncoderContext> encoder_context =
837
+ FetchOrCreateEncoderContext (true );
838
+
839
+ const VideoEncoder::EncoderInfo& primary_info =
840
+ encoder_context->PrimaryInfo ();
841
+ const VideoEncoder::EncoderInfo& fallback_info =
842
+ encoder_context->FallbackInfo ();
843
+
844
+ encoder_info.requested_resolution_alignment = cricket::LeastCommonMultiple (
845
+ primary_info.requested_resolution_alignment ,
846
+ fallback_info.requested_resolution_alignment );
847
+
848
+ encoder_info.apply_alignment_to_all_simulcast_layers =
849
+ primary_info.apply_alignment_to_all_simulcast_layers ||
850
+ fallback_info.apply_alignment_to_all_simulcast_layers ;
851
+
852
+ if (!primary_info.supports_simulcast || !fallback_info.supports_simulcast ) {
853
+ encoder_info.apply_alignment_to_all_simulcast_layers = true ;
854
+ }
855
+
856
+ cached_encoder_contexts_.emplace_back (std::move (encoder_context));
857
+
819
858
OverrideFromFieldTrial (&encoder_info);
820
859
return encoder_info;
821
860
}
@@ -825,7 +864,6 @@ VideoEncoder::EncoderInfo SimulcastEncoderAdapter::GetEncoderInfo() const {
825
864
for (size_t i = 0 ; i < stream_contexts_.size (); ++i) {
826
865
VideoEncoder::EncoderInfo encoder_impl_info =
827
866
stream_contexts_[i].encoder ().GetEncoderInfo ();
828
-
829
867
if (i == 0 ) {
830
868
// Encoder name indicates names of all sub-encoders.
831
869
encoder_info.implementation_name += " (" ;
@@ -864,7 +902,12 @@ VideoEncoder::EncoderInfo SimulcastEncoderAdapter::GetEncoderInfo() const {
864
902
encoder_info.requested_resolution_alignment = cricket::LeastCommonMultiple (
865
903
encoder_info.requested_resolution_alignment ,
866
904
encoder_impl_info.requested_resolution_alignment );
867
- if (encoder_impl_info.apply_alignment_to_all_simulcast_layers ) {
905
+ // request alignment on all layers if any of the encoders may need it, or
906
+ // if any non-top layer encoder requests a non-trivial alignment.
907
+ if (encoder_impl_info.apply_alignment_to_all_simulcast_layers ||
908
+ (encoder_impl_info.requested_resolution_alignment > 1 &&
909
+ (codec_.simulcastStream [i].height < codec_.height ||
910
+ codec_.simulcastStream [i].width < codec_.width ))) {
868
911
encoder_info.apply_alignment_to_all_simulcast_layers = true ;
869
912
}
870
913
}
0 commit comments