diff --git a/api/video_codecs/video_codec.h b/api/video_codecs/video_codec.h index 48e72edb67..e1a8d06b21 100644 --- a/api/video_codecs/video_codec.h +++ b/api/video_codecs/video_codec.h @@ -16,6 +16,7 @@ #include +#include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/video/video_bitrate_allocation.h" #include "api/video/video_codec_type.h" @@ -101,6 +102,14 @@ class RTC_EXPORT VideoCodec { public: VideoCodec(); + // Scalability mode as described in + // https://www.w3.org/TR/webrtc-svc/#scalabilitymodes* + // or value 'NONE' to indicate no scalability. + absl::string_view ScalabilityMode() const { return scalability_mode_; } + void SetScalabilityMode(absl::string_view scalability_mode) { + scalability_mode_ = std::string(scalability_mode); + } + // Public variables. TODO(hta): Make them private with accessors. VideoCodecType codecType; @@ -166,6 +175,7 @@ class RTC_EXPORT VideoCodec { // TODO(hta): Consider replacing the union with a pointer type. // This will allow removing the VideoCodec* types from this file. VideoCodecUnion codec_specific_; + std::string scalability_mode_; }; } // namespace webrtc diff --git a/media/engine/simulcast_encoder_adapter.cc b/media/engine/simulcast_encoder_adapter.cc index 961de15c27..36163c82d0 100644 --- a/media/engine/simulcast_encoder_adapter.cc +++ b/media/engine/simulcast_encoder_adapter.cc @@ -156,8 +156,6 @@ SimulcastEncoderAdapter::SimulcastEncoderAdapter( // The adapter is typically created on the worker thread, but operated on // the encoder task queue. encoder_queue_.Detach(); - - memset(&codec_, 0, sizeof(webrtc::VideoCodec)); } SimulcastEncoderAdapter::~SimulcastEncoderAdapter() { diff --git a/modules/video_coding/codecs/av1/BUILD.gn b/modules/video_coding/codecs/av1/BUILD.gn index b88bdef7e4..27b22a0a59 100644 --- a/modules/video_coding/codecs/av1/BUILD.gn +++ b/modules/video_coding/codecs/av1/BUILD.gn @@ -40,6 +40,7 @@ rtc_library("libaom_av1_encoder") { public = [ "libaom_av1_encoder.h" ] deps = [ "../../../../api/video_codecs:video_codecs_api", + "../../svc:scalability_structures", "../../svc:scalable_video_controller", ] absl_deps = [ diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc index 435761baf2..6216b9bd50 100644 --- a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc +++ b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc @@ -27,6 +27,7 @@ #include "api/video_codecs/video_encoder.h" #include "modules/video_coding/include/video_codec_interface.h" #include "modules/video_coding/include/video_error_codes.h" +#include "modules/video_coding/svc/create_scalability_structure.h" #include "modules/video_coding/svc/scalable_video_controller.h" #include "modules/video_coding/svc/scalable_video_controller_no_layering.h" #include "rtc_base/checks.h" @@ -93,7 +94,7 @@ class LibaomAv1Encoder final : public VideoEncoder { void SetSvcRefFrameConfig( const ScalableVideoController::LayerFrameConfig& layer_frame); - const std::unique_ptr svc_controller_; + std::unique_ptr svc_controller_; bool inited_; absl::optional svc_params_; VideoCodec encoder_settings_; @@ -164,6 +165,21 @@ int LibaomAv1Encoder::InitEncode(const VideoCodec* codec_settings, "LibaomAv1Encoder."; return result; } + if (encoder_settings_.numberOfSimulcastStreams > 1) { + RTC_LOG(LS_WARNING) << "Simulcast is not implemented by LibaomAv1Encoder."; + return result; + } + absl::string_view scalability_mode = encoder_settings_.ScalabilityMode(); + // When scalability_mode is not set, keep using svc_controller_ created + // at construction of the encoder. + if (!scalability_mode.empty()) { + svc_controller_ = CreateScalabilityStructure(scalability_mode); + } + if (svc_controller_ == nullptr) { + RTC_LOG(LS_WARNING) << "Failed to set scalability mode " + << scalability_mode; + return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; + } if (!SetSvcParams(svc_controller_->StreamConfig())) { return WEBRTC_VIDEO_CODEC_ERROR; diff --git a/modules/video_coding/codecs/av1/libaom_av1_unittest.cc b/modules/video_coding/codecs/av1/libaom_av1_unittest.cc index dd3d163410..78725ab626 100644 --- a/modules/video_coding/codecs/av1/libaom_av1_unittest.cc +++ b/modules/video_coding/codecs/av1/libaom_av1_unittest.cc @@ -179,14 +179,13 @@ struct SvcTestParam { class LibaomAv1SvcTest : public ::testing::TestWithParam {}; TEST_P(LibaomAv1SvcTest, EncodeAndDecodeAllDecodeTargets) { - std::unique_ptr svc_controller = - CreateScalabilityStructure(GetParam().name); - size_t num_decode_targets = - svc_controller->DependencyStructure().num_decode_targets; + size_t num_decode_targets = CreateScalabilityStructure(GetParam().name) + ->DependencyStructure() + .num_decode_targets; - std::unique_ptr encoder = - CreateLibaomAv1Encoder(std::move(svc_controller)); + std::unique_ptr encoder = CreateLibaomAv1Encoder(); VideoCodec codec_settings = DefaultCodecSettings(); + codec_settings.SetScalabilityMode(GetParam().name); ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()), WEBRTC_VIDEO_CODEC_OK); std::vector encoded_frames = diff --git a/modules/video_coding/decoder_database.cc b/modules/video_coding/decoder_database.cc index 32be39bcb4..a7a4b8f75d 100644 --- a/modules/video_coding/decoder_database.cc +++ b/modules/video_coding/decoder_database.cc @@ -96,7 +96,7 @@ bool VCMDecoderDataBase::DeregisterReceiveCodec(uint8_t payload_type) { dec_map_.erase(it); if (payload_type == current_payload_type_) { // This codec is currently in use. - memset(&receive_codec_, 0, sizeof(VideoCodec)); + receive_codec_ = {}; current_payload_type_ = 0; } return true; @@ -113,7 +113,7 @@ VCMGenericDecoder* VCMDecoderDataBase::GetDecoder( // If decoder exists - delete. if (ptr_decoder_) { ptr_decoder_.reset(); - memset(&receive_codec_, 0, sizeof(VideoCodec)); + receive_codec_ = {}; current_payload_type_ = 0; } ptr_decoder_ = CreateAndInitDecoder(frame, &receive_codec_); @@ -126,7 +126,7 @@ VCMGenericDecoder* VCMDecoderDataBase::GetDecoder( if (ptr_decoder_->RegisterDecodeCompleteCallback(decoded_frame_callback) < 0) { ptr_decoder_.reset(); - memset(&receive_codec_, 0, sizeof(VideoCodec)); + receive_codec_ = {}; current_payload_type_ = 0; return nullptr; } @@ -178,7 +178,7 @@ std::unique_ptr VCMDecoderDataBase::CreateAndInitDecoder( RTC_LOG(LS_ERROR) << "Failed to initialize decoder. Error code: " << err; return nullptr; } - memcpy(new_codec, decoder_item->settings.get(), sizeof(VideoCodec)); + *new_codec = *decoder_item->settings.get(); return ptr_decoder; } diff --git a/modules/video_coding/utility/simulcast_rate_allocator_unittest.cc b/modules/video_coding/utility/simulcast_rate_allocator_unittest.cc index 69c14ff78e..259524f181 100644 --- a/modules/video_coding/utility/simulcast_rate_allocator_unittest.cc +++ b/modules/video_coding/utility/simulcast_rate_allocator_unittest.cc @@ -54,7 +54,6 @@ class MockTemporalLayers : public Vp8FrameBufferController { class SimulcastRateAllocatorTest : public ::testing::TestWithParam { public: SimulcastRateAllocatorTest() { - memset(&codec_, 0, sizeof(VideoCodec)); codec_.codecType = kVideoCodecVP8; codec_.minBitrate = kMinBitrateKbps; codec_.maxBitrate = kLegacyScreenshareMaxBitrateKbps; diff --git a/modules/video_coding/utility/simulcast_test_fixture_impl.cc b/modules/video_coding/utility/simulcast_test_fixture_impl.cc index 981454e9ec..e262d0f54b 100644 --- a/modules/video_coding/utility/simulcast_test_fixture_impl.cc +++ b/modules/video_coding/utility/simulcast_test_fixture_impl.cc @@ -213,7 +213,7 @@ void SimulcastTestFixtureImpl::DefaultSettings( VideoCodecType codec_type, bool reverse_layer_order) { RTC_CHECK(settings); - memset(settings, 0, sizeof(VideoCodec)); + *settings = {}; settings->codecType = codec_type; settings->startBitrate = 300; settings->minBitrate = 30; diff --git a/test/video_codec_settings.h b/test/video_codec_settings.h index 8e565351d3..82c82cd7e1 100644 --- a/test/video_codec_settings.h +++ b/test/video_codec_settings.h @@ -25,7 +25,7 @@ const int64_t kTestTimingFramesDelayMs = 200; const uint16_t kTestOutlierFrameSizePercent = 250; static void CodecSettings(VideoCodecType codec_type, VideoCodec* settings) { - memset(settings, 0, sizeof(VideoCodec)); + *settings = {}; settings->width = kTestWidth; settings->height = kTestHeight; diff --git a/video/video_receive_stream.cc b/video/video_receive_stream.cc index 02eb9034fc..fbd32e4d44 100644 --- a/video/video_receive_stream.cc +++ b/video/video_receive_stream.cc @@ -115,8 +115,6 @@ class WebRtcRecordableEncodedFrame : public RecordableEncodedFrame { VideoCodec CreateDecoderVideoCodec(const VideoReceiveStream::Decoder& decoder) { VideoCodec codec; - memset(&codec, 0, sizeof(codec)); - codec.codecType = PayloadStringToCodecType(decoder.video_format.name); if (codec.codecType == kVideoCodecVP8) { diff --git a/video/video_receive_stream2.cc b/video/video_receive_stream2.cc index 21c188fe7c..c2440f8e1c 100644 --- a/video/video_receive_stream2.cc +++ b/video/video_receive_stream2.cc @@ -113,8 +113,6 @@ class WebRtcRecordableEncodedFrame : public RecordableEncodedFrame { VideoCodec CreateDecoderVideoCodec(const VideoReceiveStream::Decoder& decoder) { VideoCodec codec; - memset(&codec, 0, sizeof(codec)); - codec.codecType = PayloadStringToCodecType(decoder.video_format.name); if (codec.codecType == kVideoCodecVP8) {