diff --git a/call/BUILD.gn b/call/BUILD.gn index a74e8ac4bf..f53d0bdbf6 100644 --- a/call/BUILD.gn +++ b/call/BUILD.gn @@ -39,7 +39,6 @@ rtc_library("call_interfaces") { deps = [ ":audio_sender_interface", ":payload_type", - ":payload_type", ":receive_stream_interface", ":rtp_interfaces", ":video_stream_api", diff --git a/call/call.cc b/call/call.cc index cf94cb8910..2b7751742f 100644 --- a/call/call.cc +++ b/call/call.cc @@ -114,6 +114,11 @@ class PayloadTypeSuggesterForTests : public PayloadTypeSuggester { cricket::Codec codec) override { return payload_type_picker_.SuggestMapping(codec, nullptr); } + RTCError AddLocalMapping(const std::string& mid, + PayloadType payload_type, + const cricket::Codec& codec) override { + return RTCError::OK(); + } private: PayloadTypePicker payload_type_picker_; diff --git a/call/payload_type.h b/call/payload_type.h index 428096b023..c0520e8f4c 100644 --- a/call/payload_type.h +++ b/call/payload_type.h @@ -37,6 +37,11 @@ class PayloadTypeSuggester { // or a newly suggested one. virtual RTCErrorOr SuggestPayloadType(const std::string& mid, cricket::Codec codec) = 0; + // Register a payload type as mapped to a specific codec for this MID + // at this time. + virtual RTCError AddLocalMapping(const std::string& mid, + PayloadType payload_type, + const cricket::Codec& codec) = 0; }; } // namespace webrtc diff --git a/call/payload_type_picker.cc b/call/payload_type_picker.cc index 4c5936b46d..765d716cd6 100644 --- a/call/payload_type_picker.cc +++ b/call/payload_type_picker.cc @@ -136,6 +136,14 @@ PayloadTypePicker::PayloadTypePicker() { RTCErrorOr PayloadTypePicker::SuggestMapping( cricket::Codec codec, const PayloadTypeRecorder* excluder) { + // Test compatibility: If the codec contains a PT, and it is free, use it. + // This saves having to rewrite tests that set the codec ID themselves. + // Codecs with unassigned IDs should have -1 as their id. + if (codec.id >= 0 && codec.id <= kLastDynamicPayloadTypeUpperRange && + seen_payload_types_.count(PayloadType(codec.id)) == 0) { + AddMapping(PayloadType(codec.id), codec); + return PayloadType(codec.id); + } // The first matching entry is returned, unless excluder // maps it to something different. for (auto entry : entries_) { @@ -149,6 +157,7 @@ RTCErrorOr PayloadTypePicker::SuggestMapping( return entry.payload_type(); } } + // Assign the first free payload type. RTCErrorOr found_pt = FindFreePayloadType(seen_payload_types_); if (found_pt.ok()) { AddMapping(found_pt.value(), codec); diff --git a/media/BUILD.gn b/media/BUILD.gn index 32af2321d2..74d935db83 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn @@ -344,6 +344,8 @@ rtc_source_set("media_channel") { "../rtc_base:stringutils", "../rtc_base/network:sent_packet", "../video/config:encoder_config", + "//third_party/abseil-cpp/absl/functional:any_invocable", + "//third_party/abseil-cpp/absl/strings:string_view", ] } @@ -592,6 +594,8 @@ rtc_library("rtc_audio_video") { "../api/video_codecs:video_codecs_api", "../call", "../call:call_interfaces", + "../call:payload_type", + "../call:payload_type_picker", "../call:receive_stream_interface", "../call:rtp_interfaces", "../call:video_stream_api", @@ -652,8 +656,6 @@ rtc_library("rtc_audio_video") { sources = [ "engine/adm_helpers.cc", "engine/adm_helpers.h", - "engine/payload_type_mapper.cc", - "engine/payload_type_mapper.h", "engine/webrtc_media_engine.cc", "engine/webrtc_media_engine.h", "engine/webrtc_video_engine.cc", @@ -786,12 +788,23 @@ if (rtc_include_tests) { ":video_common", "../api:call_api", "../api:fec_controller_api", + "../api:frame_transformer_interface", + "../api:rtc_error", + "../api:rtp_headers", "../api:rtp_parameters", + "../api:rtp_sender_interface", "../api:scoped_refptr", + "../api/adaptation:resource_adaptation_api", + "../api/audio:audio_frame_api", "../api/audio:audio_processing", + "../api/audio_codecs:audio_codecs_api", + "../api/crypto:frame_decryptor_interface", "../api/environment", "../api/task_queue", "../api/task_queue:pending_task_safety_flag", + "../api/transport:bitrate_settings", + "../api/transport/rtp:rtp_source", + "../api/units:time_delta", "../api/units:timestamp", "../api/video:encoded_image", "../api/video:video_bitrate_allocation", @@ -800,9 +813,13 @@ if (rtc_include_tests) { "../api/video_codecs:video_codecs_api", "../call:call_interfaces", "../call:mock_rtp_interfaces", + "../call:payload_type", + "../call:payload_type_picker", + "../call:rtp_interfaces", "../call:video_stream_api", "../common_video", "../modules/audio_processing", + "../modules/rtp_rtcp", "../modules/rtp_rtcp:rtp_rtcp_format", "../modules/video_coding:video_codec_interface", "../modules/video_coding:video_coding_utility", @@ -820,11 +837,13 @@ if (rtc_include_tests) { "../rtc_base:stringutils", "../rtc_base:threading", "../rtc_base:timeutils", + "../rtc_base/network:sent_packet", "../rtc_base/synchronization:mutex", "../rtc_base/third_party/sigslot", "../test:explicit_key_value_config", "../test:scoped_key_value_config", "../test:test_support", + "../video/config:encoder_config", "../video/config:streams_config", "//testing/gtest", "//third_party/abseil-cpp/absl/algorithm:container", @@ -882,6 +901,7 @@ if (rtc_include_tests) { ":rtc_audio_video", ":rtc_internal_video_codecs", ":rtc_media", + ":rtc_media_config", ":rtc_media_tests_utils", ":rtc_sdp_video_format_utils", ":rtc_simulcast_encoder_adapter", @@ -891,27 +911,38 @@ if (rtc_include_tests) { ":video_adapter", ":video_broadcaster", ":video_common", + "../api:audio_options_api", + "../api:call_api", "../api:create_simulcast_test_fixture_api", "../api:field_trials_view", "../api:libjingle_peerconnection_api", + "../api:make_ref_counted", "../api:mock_encoder_selector", "../api:mock_video_bitrate_allocator", "../api:mock_video_bitrate_allocator_factory", "../api:mock_video_codec_factory", "../api:mock_video_encoder", "../api:priority", + "../api:ref_count", + "../api:rtc_error", + "../api:rtp_headers", "../api:rtp_parameters", "../api:scoped_refptr", "../api:simulcast_test_fixture_api", + "../api/audio:audio_processing", + "../api/audio_codecs:audio_codecs_api", "../api/audio_codecs:builtin_audio_decoder_factory", "../api/audio_codecs:builtin_audio_encoder_factory", + "../api/crypto:options", "../api/environment", "../api/environment:environment_factory", "../api/rtc_event_log", "../api/task_queue", "../api/task_queue:default_task_queue_factory", "../api/test/video:function_video_factory", + "../api/transport:bitrate_settings", "../api/transport:field_trial_based_config", + "../api/transport/rtp:rtp_source", "../api/units:time_delta", "../api/units:timestamp", "../api/video:builtin_video_bitrate_allocator_factory", @@ -950,6 +981,8 @@ if (rtc_include_tests) { "../rtc_base:async_packet_socket", "../rtc_base:byte_order", "../rtc_base:checks", + "../rtc_base:copy_on_write_buffer", + "../rtc_base:dscp", "../rtc_base:gunit_helpers", "../rtc_base:logging", "../rtc_base:macromagic", @@ -995,7 +1028,6 @@ if (rtc_include_tests) { "base/video_common_unittest.cc", "engine/internal_decoder_factory_unittest.cc", "engine/internal_encoder_factory_unittest.cc", - "engine/payload_type_mapper_unittest.cc", "engine/simulcast_encoder_adapter_unittest.cc", "engine/webrtc_media_engine_unittest.cc", "engine/webrtc_video_engine_unittest.cc", diff --git a/media/DEPS b/media/DEPS index bcdbcac20c..ffa3c11a9a 100644 --- a/media/DEPS +++ b/media/DEPS @@ -34,8 +34,7 @@ specific_include_rules = { ".*fake_webrtc_call\.cc": [ "+video/config", ], - # temporary - ".*webrtc_voice_engine\.cc": [ - "+pc/payload_type_picker.h", + ".*fake_webrtc_call\.h": [ + "+video/config", ], } diff --git a/media/base/media_channel.h b/media/base/media_channel.h index b7f5987f6e..73d2b2585a 100644 --- a/media/base/media_channel.h +++ b/media/base/media_channel.h @@ -11,6 +11,9 @@ #ifndef MEDIA_BASE_MEDIA_CHANNEL_H_ #define MEDIA_BASE_MEDIA_CHANNEL_H_ +#include +#include +#include #include #include #include @@ -19,6 +22,8 @@ #include #include +#include "absl/functional/any_invocable.h" +#include "absl/strings/string_view.h" #include "api/audio/audio_processing_statistics.h" #include "api/audio_codecs/audio_encoder.h" #include "api/audio_options.h" @@ -27,37 +32,34 @@ #include "api/crypto/frame_encryptor_interface.h" #include "api/frame_transformer_interface.h" #include "api/media_stream_interface.h" +#include "api/media_types.h" #include "api/rtc_error.h" +#include "api/rtp_headers.h" #include "api/rtp_parameters.h" #include "api/rtp_sender_interface.h" -#include "api/task_queue/pending_task_safety_flag.h" -#include "api/transport/data_channel_transport_interface.h" +#include "api/scoped_refptr.h" #include "api/transport/rtp/rtp_source.h" #include "api/units/time_delta.h" #include "api/units/timestamp.h" +#include "api/video/recordable_encoded_frame.h" #include "api/video/video_content_type.h" #include "api/video/video_sink_interface.h" #include "api/video/video_source_interface.h" #include "api/video/video_timing.h" #include "api/video_codecs/scalability_mode.h" #include "api/video_codecs/video_encoder_factory.h" -#include "call/video_receive_stream.h" #include "common_video/include/quality_limitation_reason.h" #include "media/base/codec.h" -#include "media/base/media_constants.h" #include "media/base/stream_params.h" #include "modules/rtp_rtcp/include/report_block_data.h" #include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "rtc_base/async_packet_socket.h" -#include "rtc_base/buffer.h" #include "rtc_base/copy_on_write_buffer.h" -#include "rtc_base/dscp.h" -#include "rtc_base/logging.h" +#include "rtc_base/network/sent_packet.h" #include "rtc_base/network_route.h" #include "rtc_base/socket.h" #include "rtc_base/string_encode.h" #include "rtc_base/strings/string_builder.h" -#include "video/config/video_encoder_config.h" namespace rtc { class Timing; diff --git a/media/engine/fake_webrtc_call.h b/media/engine/fake_webrtc_call.h index 64baab771a..c4e5f615a2 100644 --- a/media/engine/fake_webrtc_call.h +++ b/media/engine/fake_webrtc_call.h @@ -20,24 +20,56 @@ #ifndef MEDIA_ENGINE_FAKE_WEBRTC_CALL_H_ #define MEDIA_ENGINE_FAKE_WEBRTC_CALL_H_ +#include +#include #include #include +#include #include #include #include #include "absl/strings/string_view.h" +#include "api/adaptation/resource.h" +#include "api/audio/audio_frame.h" +#include "api/audio_codecs/audio_format.h" +#include "api/crypto/frame_decryptor_interface.h" #include "api/environment/environment.h" +#include "api/frame_transformer_interface.h" +#include "api/media_types.h" +#include "api/rtc_error.h" +#include "api/rtp_headers.h" +#include "api/rtp_parameters.h" +#include "api/rtp_sender_interface.h" +#include "api/scoped_refptr.h" +#include "api/task_queue/task_queue_base.h" +#include "api/transport/bitrate_settings.h" +#include "api/transport/rtp/rtp_source.h" +#include "api/units/time_delta.h" +#include "api/units/timestamp.h" #include "api/video/video_frame.h" +#include "api/video/video_sink_interface.h" +#include "api/video/video_source_interface.h" +#include "api/video_codecs/video_codec.h" #include "call/audio_receive_stream.h" #include "call/audio_send_stream.h" #include "call/call.h" #include "call/flexfec_receive_stream.h" +#include "call/packet_receiver.h" +#include "call/payload_type.h" +#include "call/payload_type_picker.h" +#include "call/rtp_transport_controller_send_interface.h" #include "call/test/mock_rtp_transport_controller_send.h" #include "call/video_receive_stream.h" #include "call/video_send_stream.h" +#include "media/base/codec.h" +#include "modules/rtp_rtcp/include/receive_statistics.h" #include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "rtc_base/buffer.h" +#include "rtc_base/copy_on_write_buffer.h" +#include "rtc_base/network/sent_packet.h" +#include "test/gmock.h" +#include "video/config/video_encoder_config.h" namespace cricket { class FakeAudioSendStream final : public webrtc::AudioSendStream { @@ -363,6 +395,26 @@ class FakeFlexfecReceiveStream final : public webrtc::FlexfecReceiveStream { webrtc::FlexfecReceiveStream::Config config_; }; +// Fake payload type suggester. +// This is injected into FakeCall at initialization. +class FakePayloadTypeSuggester : public webrtc::PayloadTypeSuggester { + public: + webrtc::RTCErrorOr SuggestPayloadType( + const std::string& mid, + cricket::Codec codec) override { + // Ignores mid argument. + return pt_picker_.SuggestMapping(codec, nullptr); + } + webrtc::RTCError AddLocalMapping(const std::string& mid, + webrtc::PayloadType payload_type, + const cricket::Codec& codec) override { + return webrtc::RTCError::OK(); + } + + private: + webrtc::PayloadTypePicker pt_picker_; +}; + class FakeCall final : public webrtc::Call, public webrtc::PacketReceiver { public: explicit FakeCall(const webrtc::Environment& env); @@ -371,6 +423,10 @@ class FakeCall final : public webrtc::Call, public webrtc::PacketReceiver { webrtc::TaskQueueBase* network_thread); ~FakeCall() override; + webrtc::PayloadTypeSuggester* GetPayloadTypeSuggester() { + return &pt_suggester_; + } + webrtc::MockRtpTransportControllerSend* GetMockTransportControllerSend() { return &transport_controller_send_; } @@ -501,6 +557,8 @@ class FakeCall final : public webrtc::Call, public webrtc::PacketReceiver { int num_created_send_streams_; int num_created_receive_streams_; + + FakePayloadTypeSuggester pt_suggester_; }; } // namespace cricket diff --git a/media/engine/payload_type_mapper.cc b/media/engine/payload_type_mapper.cc deleted file mode 100644 index 9db2281a2a..0000000000 --- a/media/engine/payload_type_mapper.cc +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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 "media/engine/payload_type_mapper.h" - -#include - -#include "absl/strings/ascii.h" -#include "api/audio_codecs/audio_format.h" -#include "media/base/codec.h" -#include "media/base/media_constants.h" - -namespace cricket { - -webrtc::SdpAudioFormat AudioCodecToSdpAudioFormat(const Codec& ac) { - return webrtc::SdpAudioFormat(ac.name, ac.clockrate, ac.channels, ac.params); -} - -PayloadTypeMapper::PayloadTypeMapper() - // RFC 3551 reserves payload type numbers in the range 96-127 exclusively - // for dynamic assignment. Once those are used up, it is recommended that - // payload types unassigned by the RFC are used for dynamic payload type - // mapping, before any static payload ids. At this point, we only support - // mapping within the exclusive range. - : next_unused_payload_type_(96), - max_payload_type_(127), - mappings_( - {// Static payload type assignments according to RFC 3551. - {{kPcmuCodecName, 8000, 1}, 0}, - {{"GSM", 8000, 1}, 3}, - {{"G723", 8000, 1}, 4}, - {{"DVI4", 8000, 1}, 5}, - {{"DVI4", 16000, 1}, 6}, - {{"LPC", 8000, 1}, 7}, - {{kPcmaCodecName, 8000, 1}, 8}, - {{kG722CodecName, 8000, 1}, 9}, - {{kL16CodecName, 44100, 2}, 10}, - {{kL16CodecName, 44100, 1}, 11}, - {{"QCELP", 8000, 1}, 12}, - {{kCnCodecName, 8000, 1}, 13}, - // RFC 4566 is a bit ambiguous on the contents of the "encoding - // parameters" field, which, for audio, encodes the number of - // channels. It is "optional and may be omitted if the number of - // channels is one". Does that necessarily imply that an omitted - // encoding parameter means one channel? Since RFC 3551 doesn't - // specify a value for this parameter for MPA, I've included both 0 - // and 1 here, to increase the chances it will be correctly used if - // someone implements an MPEG audio encoder/decoder. - {{"MPA", 90000, 0}, 14}, - {{"MPA", 90000, 1}, 14}, - {{"G728", 8000, 1}, 15}, - {{"DVI4", 11025, 1}, 16}, - {{"DVI4", 22050, 1}, 17}, - {{"G729", 8000, 1}, 18}, - - // Payload type assignments currently used by WebRTC. - // Includes data to reduce collisions (and thus reassignments) - {{kIlbcCodecName, 8000, 1}, 102}, - {{kCnCodecName, 16000, 1}, 105}, - {{kCnCodecName, 32000, 1}, 106}, - {{kOpusCodecName, - 48000, - 2, - {{kCodecParamMinPTime, "10"}, - {kCodecParamUseInbandFec, kParamValueTrue}}}, - 111}, - // RED for opus is assigned in the lower range, starting at the top. - // Note that the FMTP refers to the opus payload type. - {{kRedCodecName, - 48000, - 2, - {{kCodecParamNotInNameValueFormat, "111/111"}}}, - 63}, - // TODO(solenberg): Remove the hard coded 16k,32k,48k DTMF once we - // assign payload types dynamically for send side as well. - {{kDtmfCodecName, 48000, 1}, 110}, - {{kDtmfCodecName, 32000, 1}, 112}, - {{kDtmfCodecName, 16000, 1}, 113}, - {{kDtmfCodecName, 8000, 1}, 126}}) { - // TODO(ossu): Try to keep this as change-proof as possible until we're able - // to remove the payload type constants from everywhere in the code. - for (const auto& mapping : mappings_) { - used_payload_types_.insert(mapping.second); - } -} - -PayloadTypeMapper::~PayloadTypeMapper() = default; - -std::optional PayloadTypeMapper::GetMappingFor( - const webrtc::SdpAudioFormat& format) { - auto iter = mappings_.find(format); - if (iter != mappings_.end()) - return iter->second; - - for (; next_unused_payload_type_ <= max_payload_type_; - ++next_unused_payload_type_) { - int payload_type = next_unused_payload_type_; - if (used_payload_types_.find(payload_type) == used_payload_types_.end()) { - used_payload_types_.insert(payload_type); - mappings_[format] = payload_type; - ++next_unused_payload_type_; - return payload_type; - } - } - - return std::nullopt; -} - -std::optional PayloadTypeMapper::FindMappingFor( - const webrtc::SdpAudioFormat& format) const { - auto iter = mappings_.find(format); - if (iter != mappings_.end()) - return iter->second; - - return std::nullopt; -} - -std::optional PayloadTypeMapper::ToAudioCodec( - const webrtc::SdpAudioFormat& format) { - // TODO(ossu): We can safely set bitrate to zero here, since that field is - // not presented in the SDP. It is used to ferry around some target bitrate - // values for certain codecs (ISAC and Opus) and in ways it really - // shouldn't. It should be removed once we no longer use CodecInsts in the - // ACM or NetEq. - auto opt_payload_type = GetMappingFor(format); - if (opt_payload_type) { - Codec codec = - cricket::CreateAudioCodec(*opt_payload_type, format.name, - format.clockrate_hz, format.num_channels); - codec.params = format.parameters; - return std::move(codec); - } - - return std::nullopt; -} - -bool PayloadTypeMapper::SdpAudioFormatOrdering::operator()( - const webrtc::SdpAudioFormat& a, - const webrtc::SdpAudioFormat& b) const { - if (a.clockrate_hz == b.clockrate_hz) { - if (a.num_channels == b.num_channels) { - int name_cmp = - absl::AsciiStrToLower(a.name).compare(absl::AsciiStrToLower(b.name)); - if (name_cmp == 0) - return a.parameters < b.parameters; - return name_cmp < 0; - } - return a.num_channels < b.num_channels; - } - return a.clockrate_hz < b.clockrate_hz; -} - -} // namespace cricket diff --git a/media/engine/payload_type_mapper.h b/media/engine/payload_type_mapper.h deleted file mode 100644 index 246b04e306..0000000000 --- a/media/engine/payload_type_mapper.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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. - */ - -#ifndef MEDIA_ENGINE_PAYLOAD_TYPE_MAPPER_H_ -#define MEDIA_ENGINE_PAYLOAD_TYPE_MAPPER_H_ - -#include -#include -#include - -#include "api/audio_codecs/audio_format.h" -#include "media/base/codec.h" - -namespace cricket { - -webrtc::SdpAudioFormat AudioCodecToSdpAudioFormat(const Codec& ac); - -class PayloadTypeMapper { - public: - PayloadTypeMapper(); - ~PayloadTypeMapper(); - - // Finds the current payload type for `format` or assigns a new one, if no - // current mapping exists. Will return an empty value if it was unable to - // create a mapping, i.e. if all dynamic payload type ids have been used up. - std::optional GetMappingFor(const webrtc::SdpAudioFormat& format); - - // Finds the current payload type for `format`, if any. Returns an empty value - // if no payload type mapping exists for the format. - std::optional FindMappingFor(const webrtc::SdpAudioFormat& format) const; - - // Like GetMappingFor, but fills in an AudioCodec structure with the necessary - // information instead. - std::optional ToAudioCodec(const webrtc::SdpAudioFormat& format); - - private: - struct SdpAudioFormatOrdering { - bool operator()(const webrtc::SdpAudioFormat& a, - const webrtc::SdpAudioFormat& b) const; - }; - - int next_unused_payload_type_; - int max_payload_type_; - std::map mappings_; - std::set used_payload_types_; -}; - -} // namespace cricket -#endif // MEDIA_ENGINE_PAYLOAD_TYPE_MAPPER_H_ diff --git a/media/engine/payload_type_mapper_unittest.cc b/media/engine/payload_type_mapper_unittest.cc deleted file mode 100644 index 62cca1e47e..0000000000 --- a/media/engine/payload_type_mapper_unittest.cc +++ /dev/null @@ -1,139 +0,0 @@ -/* - * 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 "media/engine/payload_type_mapper.h" - -#include -#include - -#include "absl/strings/string_view.h" -#include "media/base/media_constants.h" -#include "test/gmock.h" -#include "test/gtest.h" - -namespace cricket { - -class PayloadTypeMapperTest : public ::testing::Test { - protected: - PayloadTypeMapper mapper_; -}; - -TEST_F(PayloadTypeMapperTest, StaticPayloadTypes) { - EXPECT_EQ(0, mapper_.FindMappingFor({"pcmu", 8000, 1})); - EXPECT_EQ(3, mapper_.FindMappingFor({"gsm", 8000, 1})); - EXPECT_EQ(4, mapper_.FindMappingFor({"g723", 8000, 1})); - EXPECT_EQ(5, mapper_.FindMappingFor({"dvi4", 8000, 1})); - EXPECT_EQ(6, mapper_.FindMappingFor({"dvi4", 16000, 1})); - EXPECT_EQ(7, mapper_.FindMappingFor({"lpc", 8000, 1})); - EXPECT_EQ(8, mapper_.FindMappingFor({"pcma", 8000, 1})); - EXPECT_EQ(9, mapper_.FindMappingFor({"g722", 8000, 1})); - EXPECT_EQ(10, mapper_.FindMappingFor({"l16", 44100, 2})); - EXPECT_EQ(11, mapper_.FindMappingFor({"l16", 44100, 1})); - EXPECT_EQ(12, mapper_.FindMappingFor({"qcelp", 8000, 1})); - EXPECT_EQ(13, mapper_.FindMappingFor({"cn", 8000, 1})); - EXPECT_EQ(14, mapper_.FindMappingFor({"mpa", 90000, 0})); - EXPECT_EQ(14, mapper_.FindMappingFor({"mpa", 90000, 1})); - EXPECT_EQ(15, mapper_.FindMappingFor({"g728", 8000, 1})); - EXPECT_EQ(16, mapper_.FindMappingFor({"dvi4", 11025, 1})); - EXPECT_EQ(17, mapper_.FindMappingFor({"dvi4", 22050, 1})); - EXPECT_EQ(18, mapper_.FindMappingFor({"g729", 8000, 1})); -} - -TEST_F(PayloadTypeMapperTest, WebRTCPayloadTypes) { - // Tests that the payload mapper knows about the audio formats we've - // been using in WebRTC, with their hard coded values. - EXPECT_EQ(102, mapper_.FindMappingFor({kIlbcCodecName, 8000, 1})); - EXPECT_EQ(105, mapper_.FindMappingFor({kCnCodecName, 16000, 1})); - EXPECT_EQ(106, mapper_.FindMappingFor({kCnCodecName, 32000, 1})); - EXPECT_EQ(111, mapper_.FindMappingFor( - {kOpusCodecName, - 48000, - 2, - {{"minptime", "10"}, {"useinbandfec", "1"}}})); - EXPECT_EQ( - 63, mapper_.FindMappingFor({kRedCodecName, 48000, 2, {{"", "111/111"}}})); - // TODO(solenberg): Remove 16k, 32k, 48k DTMF checks once these payload types - // are dynamically assigned. - EXPECT_EQ(110, mapper_.FindMappingFor({kDtmfCodecName, 48000, 1})); - EXPECT_EQ(112, mapper_.FindMappingFor({kDtmfCodecName, 32000, 1})); - EXPECT_EQ(113, mapper_.FindMappingFor({kDtmfCodecName, 16000, 1})); - EXPECT_EQ(126, mapper_.FindMappingFor({kDtmfCodecName, 8000, 1})); -} - -TEST_F(PayloadTypeMapperTest, ValidDynamicPayloadTypes) { - // RFC 3551 says: - // "This profile reserves payload type numbers in the range 96-127 - // exclusively for dynamic assignment. Applications SHOULD first use - // values in this range for dynamic payload types. Those applications - // which need to define more than 32 dynamic payload types MAY bind - // codes below 96, in which case it is RECOMMENDED that unassigned - // payload type numbers be used first. However, the statically assigned - // payload types are default bindings and MAY be dynamically bound to - // new encodings if needed." - - // Tests that the payload mapper uses values in the dynamic payload type range - // (96 - 127) before any others and that the values returned are all valid. - bool has_been_below_96 = false; - std::set used_payload_types; - for (int i = 0; i != 256; ++i) { - std::string format_name = "unknown_format_" + std::to_string(i); - webrtc::SdpAudioFormat format(format_name.c_str(), i * 100, (i % 2) + 1); - auto opt_payload_type = mapper_.GetMappingFor(format); - bool mapper_is_full = false; - - // There's a limited number of slots for payload types. We're fine with not - // being able to map them all. - if (opt_payload_type) { - int payload_type = *opt_payload_type; - EXPECT_FALSE(mapper_is_full) << "Mapping should not fail sporadically"; - EXPECT_EQ(used_payload_types.find(payload_type), used_payload_types.end()) - << "Payload types must not be reused"; - used_payload_types.insert(payload_type); - EXPECT_GE(payload_type, 0) << "Negative payload types are invalid"; - EXPECT_LE(payload_type, 127) << "Payload types above 127 are invalid"; - EXPECT_FALSE(payload_type >= 96 && has_been_below_96); - if (payload_type < 96) - has_been_below_96 = true; - - EXPECT_EQ(payload_type, mapper_.FindMappingFor(format)) - << "Mapping must be permanent after successful call to " - "GetMappingFor"; - EXPECT_EQ(payload_type, mapper_.GetMappingFor(format)) - << "Subsequent calls to GetMappingFor must return the same value"; - } else { - mapper_is_full = true; - } - } - - // Also, we must've been able to map at least one dynamic payload type. - EXPECT_FALSE(used_payload_types.empty()) - << "Mapper must support at least one user-defined payload type"; -} - -TEST_F(PayloadTypeMapperTest, ToAudioCodec) { - webrtc::SdpAudioFormat format("unknown_format", 4711, 17); - auto opt_payload_type = mapper_.GetMappingFor(format); - EXPECT_TRUE(opt_payload_type); - auto opt_audio_codec = mapper_.ToAudioCodec(format); - EXPECT_TRUE(opt_audio_codec); - - if (opt_payload_type && opt_audio_codec) { - int payload_type = *opt_payload_type; - const Codec& codec = *opt_audio_codec; - - EXPECT_EQ(codec.id, payload_type); - EXPECT_EQ(codec.name, format.name); - EXPECT_EQ(codec.clockrate, format.clockrate_hz); - EXPECT_EQ(codec.channels, format.num_channels); - EXPECT_THAT(codec.params, ::testing::ContainerEq(format.parameters)); - } -} - -} // namespace cricket diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc index e65d0eb734..93533dad58 100644 --- a/media/engine/webrtc_voice_engine.cc +++ b/media/engine/webrtc_voice_engine.cc @@ -12,54 +12,77 @@ #include #include +#include #include #include #include #include +#include #include #include +#include #include -#include #include #include #include "absl/algorithm/algorithm.h" #include "absl/algorithm/container.h" +#include "absl/functional/any_invocable.h" #include "absl/functional/bind_front.h" #include "absl/strings/match.h" +#include "absl/strings/string_view.h" #include "api/audio/audio_frame.h" #include "api/audio/audio_frame_processor.h" +#include "api/audio/audio_mixer.h" #include "api/audio/audio_processing.h" #include "api/audio/audio_processing_statistics.h" #include "api/audio_codecs/audio_codec_pair_id.h" +#include "api/audio_codecs/audio_decoder_factory.h" #include "api/audio_codecs/audio_encoder.h" +#include "api/audio_codecs/audio_encoder_factory.h" +#include "api/audio_codecs/audio_format.h" +#include "api/audio_options.h" #include "api/call/audio_sink.h" +#include "api/crypto/crypto_options.h" +#include "api/crypto/frame_decryptor_interface.h" #include "api/field_trials_view.h" +#include "api/frame_transformer_interface.h" #include "api/make_ref_counted.h" #include "api/media_types.h" #include "api/priority.h" +#include "api/rtc_error.h" #include "api/rtp_headers.h" #include "api/rtp_parameters.h" +#include "api/rtp_sender_interface.h" #include "api/rtp_transceiver_direction.h" +#include "api/scoped_refptr.h" +#include "api/sequence_checker.h" #include "api/task_queue/pending_task_safety_flag.h" #include "api/transport/bitrate_settings.h" +#include "api/transport/rtp/rtp_source.h" #include "api/units/data_rate.h" #include "api/units/time_delta.h" #include "api/units/timestamp.h" #include "call/audio_receive_stream.h" +#include "call/audio_send_stream.h" +#include "call/audio_state.h" +#include "call/call.h" #include "call/packet_receiver.h" +#include "call/payload_type_picker.h" #include "call/rtp_config.h" #include "call/rtp_transport_controller_send_interface.h" #include "media/base/audio_source.h" #include "media/base/codec.h" +#include "media/base/media_channel.h" +#include "media/base/media_channel_impl.h" +#include "media/base/media_config.h" #include "media/base/media_constants.h" +#include "media/base/media_engine.h" #include "media/base/stream_params.h" #include "media/engine/adm_helpers.h" -#include "media/engine/payload_type_mapper.h" #include "media/engine/webrtc_media_engine.h" #include "modules/async_audio_processing/async_audio_processing.h" #include "modules/audio_mixer/audio_mixer_impl.h" -#include "modules/rtp_rtcp/include/report_block_data.h" #include "modules/rtp_rtcp/include/rtp_header_extension_map.h" #include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "modules/rtp_rtcp/source/rtp_util.h" @@ -72,6 +95,7 @@ #include "rtc_base/strings/audio_format_to_string.h" #include "rtc_base/strings/string_builder.h" #include "rtc_base/strings/string_format.h" +#include "rtc_base/system/file_wrapper.h" #include "rtc_base/thread_annotations.h" #include "rtc_base/time_utils.h" #include "rtc_base/trace_event.h" @@ -332,6 +356,91 @@ bool CheckRedParameters( return true; } +webrtc::SdpAudioFormat AudioCodecToSdpAudioFormat(const Codec& ac) { + return webrtc::SdpAudioFormat(ac.name, ac.clockrate, ac.channels, ac.params); +} + +// Assign the payload types for the codecs of this voice engine. +// This is a "preliminary" pass, done to prime the +// payload type picker with a normal set of PTs. +// TODO: https://issues.webrtc.org/360058654 - remove. +std::vector LegacyCollectCodecs( + const std::vector& specs) { + // Once payload assignment is done in the channel not in the factory, + // this needs to be a variable. But then this function should go away. + webrtc::PayloadTypePicker pt_mapper; + std::vector out; + + // Only generate CN payload types for these clockrates: + std::map> generate_cn = { + {8000, false}, {16000, false}, {32000, false}}; + // Only generate telephone-event payload types for these clockrates: + std::map> generate_dtmf = { + {8000, false}, {16000, false}, {32000, false}, {48000, false}}; + + for (const auto& spec : specs) { + cricket::Codec codec = CreateAudioCodec(spec.format); + auto pt_or_error = pt_mapper.SuggestMapping(codec, nullptr); + // We need to do some extra stuff before adding the main codecs to out. + if (pt_or_error.ok()) { + codec.id = pt_or_error.value(); + if (spec.info.supports_network_adaption) { + codec.AddFeedbackParam( + FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty)); + } + + if (spec.info.allow_comfort_noise) { + // Generate a CN entry if the decoder allows it and we support the + // clockrate. + auto cn = generate_cn.find(spec.format.clockrate_hz); + if (cn != generate_cn.end()) { + cn->second = true; + } + } + + // Generate a telephone-event entry if we support the clockrate. + auto dtmf = generate_dtmf.find(spec.format.clockrate_hz); + if (dtmf != generate_dtmf.end()) { + dtmf->second = true; + } + + out.push_back(codec); + + // TODO(hta): Don't assign RED codecs until we know that the PT for Opus + // is final + if (codec.name == kOpusCodecName) { + std::string red_fmtp = + rtc::ToString(codec.id) + "/" + rtc::ToString(codec.id); + cricket::Codec red_codec = + CreateAudioCodec({kRedCodecName, 48000, 2, {{"", red_fmtp}}}); + red_codec.id = pt_mapper.SuggestMapping(red_codec, nullptr).value(); + out.push_back(red_codec); + } + } + } + + // Add CN codecs after "proper" audio codecs. + for (const auto& cn : generate_cn) { + if (cn.second) { + cricket::Codec cn_codec = CreateAudioCodec({kCnCodecName, cn.first, 1}); + cn_codec.id = pt_mapper.SuggestMapping(cn_codec, nullptr).value(); + out.push_back(cn_codec); + } + } + + // Add telephone-event codecs last. + for (const auto& dtmf : generate_dtmf) { + if (dtmf.second) { + cricket::Codec dtmf_codec = + CreateAudioCodec({kDtmfCodecName, dtmf.first, 1}); + dtmf_codec.id = pt_mapper.SuggestMapping(dtmf_codec, nullptr).value(); + out.push_back(dtmf_codec); + } + } + + return out; +} + } // namespace WebRtcVoiceEngine::WebRtcVoiceEngine( @@ -383,13 +492,13 @@ void WebRtcVoiceEngine::Init() { // Load our audio codec lists. RTC_LOG(LS_VERBOSE) << "Supported send codecs in order of preference:"; - send_codecs_ = CollectCodecs(encoder_factory_->GetSupportedEncoders()); + send_codecs_ = LegacyCollectCodecs(encoder_factory_->GetSupportedEncoders()); for (const Codec& codec : send_codecs_) { RTC_LOG(LS_VERBOSE) << ToString(codec); } RTC_LOG(LS_VERBOSE) << "Supported recv codecs in order of preference:"; - recv_codecs_ = CollectCodecs(decoder_factory_->GetSupportedDecoders()); + recv_codecs_ = LegacyCollectCodecs(decoder_factory_->GetSupportedDecoders()); for (const Codec& codec : recv_codecs_) { RTC_LOG(LS_VERBOSE) << ToString(codec); } @@ -708,84 +817,6 @@ webrtc::AudioState* WebRtcVoiceEngine::audio_state() { return audio_state_.get(); } -std::vector WebRtcVoiceEngine::CollectCodecs( - const std::vector& specs) const { - PayloadTypeMapper mapper; - std::vector out; - - // Only generate CN payload types for these clockrates: - std::map> generate_cn = { - {8000, false}, {16000, false}, {32000, false}}; - // Only generate telephone-event payload types for these clockrates: - std::map> generate_dtmf = { - {8000, false}, {16000, false}, {32000, false}, {48000, false}}; - - auto map_format = [&mapper](const webrtc::SdpAudioFormat& format, - std::vector* out) { - std::optional opt_codec = mapper.ToAudioCodec(format); - if (opt_codec) { - if (out) { - out->push_back(*opt_codec); - } - } else { - RTC_LOG(LS_ERROR) << "Unable to assign payload type to format: " - << rtc::ToString(format); - } - - return opt_codec; - }; - - for (const auto& spec : specs) { - // We need to do some extra stuff before adding the main codecs to out. - std::optional opt_codec = map_format(spec.format, nullptr); - if (opt_codec) { - Codec& codec = *opt_codec; - if (spec.info.supports_network_adaption) { - codec.AddFeedbackParam( - FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty)); - } - - if (spec.info.allow_comfort_noise) { - // Generate a CN entry if the decoder allows it and we support the - // clockrate. - auto cn = generate_cn.find(spec.format.clockrate_hz); - if (cn != generate_cn.end()) { - cn->second = true; - } - } - - // Generate a telephone-event entry if we support the clockrate. - auto dtmf = generate_dtmf.find(spec.format.clockrate_hz); - if (dtmf != generate_dtmf.end()) { - dtmf->second = true; - } - - out.push_back(codec); - - if (codec.name == kOpusCodecName) { - std::string red_fmtp = - rtc::ToString(codec.id) + "/" + rtc::ToString(codec.id); - map_format({kRedCodecName, 48000, 2, {{"", red_fmtp}}}, &out); - } - } - } - - // Add CN codecs after "proper" audio codecs. - for (const auto& cn : generate_cn) { - if (cn.second) { - map_format({kCnCodecName, cn.first, 1}, &out); - } - } - - // Add telephone-event codecs last. - for (const auto& dtmf : generate_dtmf) { - if (dtmf.second) { - map_format({kDtmfCodecName, dtmf.first, 1}, &out); - } - } - - return out; -} // --------------------------------- WebRtcVoiceSendChannel ------------------ @@ -2151,11 +2182,20 @@ bool WebRtcVoiceReceiveChannel::SetOptions(const AudioOptions& options) { } bool WebRtcVoiceReceiveChannel::SetRecvCodecs( - const std::vector& codecs) { + const std::vector& codecs_in) { RTC_DCHECK_RUN_ON(worker_thread_); - // Set the payload types to be used for incoming media. - RTC_LOG(LS_INFO) << "Setting receive voice codecs."; + auto codecs = codecs_in; + // Record the payload types used in the payload type suggester. + RTC_LOG(LS_INFO) << "Setting receive voice codecs. Mid is " << mid_; + for (auto& codec : codecs) { + auto error = call_->GetPayloadTypeSuggester()->AddLocalMapping( + mid_, codec.id, codec); + if (!error.ok()) { + RTC_LOG(LS_ERROR) << "Failed to register PT for " << codec.ToString(); + return false; + } + } if (!VerifyUniquePayloadTypes(codecs)) { RTC_LOG(LS_ERROR) << "Codec payload types overlap."; diff --git a/media/engine/webrtc_voice_engine.h b/media/engine/webrtc_voice_engine.h index 942c56903b..dd5b84b4d0 100644 --- a/media/engine/webrtc_voice_engine.h +++ b/media/engine/webrtc_voice_engine.h @@ -34,13 +34,14 @@ #include "api/audio_codecs/audio_format.h" #include "api/audio_options.h" #include "api/call/audio_sink.h" -#include "api/call/transport.h" #include "api/crypto/crypto_options.h" #include "api/crypto/frame_decryptor_interface.h" #include "api/crypto/frame_encryptor_interface.h" #include "api/field_trials_view.h" #include "api/frame_transformer_interface.h" +#include "api/media_types.h" #include "api/rtc_error.h" +#include "api/rtp_headers.h" #include "api/rtp_parameters.h" #include "api/rtp_sender_interface.h" #include "api/scoped_refptr.h" @@ -57,12 +58,11 @@ #include "media/base/media_channel_impl.h" #include "media/base/media_config.h" #include "media/base/media_engine.h" -#include "media/base/rtp_utils.h" #include "media/base/stream_params.h" #include "modules/async_audio_processing/async_audio_processing.h" #include "modules/rtp_rtcp/include/rtp_header_extension_map.h" #include "modules/rtp_rtcp/source/rtp_packet_received.h" -#include "rtc_base/buffer.h" +#include "rtc_base/checks.h" #include "rtc_base/network/sent_packet.h" #include "rtc_base/network_route.h" #include "rtc_base/system/file_wrapper.h" @@ -147,9 +147,6 @@ class WebRtcVoiceEngine final : public VoiceEngineInterface { webrtc::AudioProcessing* apm() const; webrtc::AudioState* audio_state(); - std::vector CollectCodecs( - const std::vector& specs) const; - webrtc::SequenceChecker signal_thread_checker_{ webrtc::SequenceChecker::kDetached}; webrtc::SequenceChecker worker_thread_checker_{ diff --git a/pc/BUILD.gn b/pc/BUILD.gn index 5e11f04398..f21f407fbf 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -79,6 +79,7 @@ rtc_source_set("channel") { "../api:scoped_refptr", "../api:sequence_checker", "../api/crypto:options", + "../api/task_queue", "../api/task_queue:pending_task_safety_flag", "../api/units:timestamp", "../call:rtp_interfaces", @@ -1105,6 +1106,7 @@ rtc_source_set("peer_connection") { "../api:ice_transport_interface", "../api:libjingle_logging_api", "../api:libjingle_peerconnection_api", + "../api:make_ref_counted", "../api:media_stream_interface", "../api:rtc_error", "../api:rtc_stats_api", @@ -1115,16 +1117,20 @@ rtc_source_set("peer_connection") { "../api:sequence_checker", "../api:turn_customizer", "../api/adaptation:resource_adaptation_api", + "../api/audio:audio_device", "../api/crypto:options", "../api/environment", "../api/rtc_event_log", "../api/task_queue:pending_task_safety_flag", + "../api/transport:bandwidth_estimation_settings", "../api/transport:bitrate_settings", "../api/transport:datagram_transport_interface", "../api/transport:enums", + "../api/units:time_delta", "../api/video:video_codec_constants", "../call:call_interfaces", "../call:payload_type_picker", + "../media:codec", "../media:media_channel", "../media:media_engine", "../media:rid_description", diff --git a/pc/channel.cc b/pc/channel.cc index 45c6e74f64..6e4a80be3c 100644 --- a/pc/channel.cc +++ b/pc/channel.cc @@ -12,28 +12,44 @@ #include #include +#include +#include +#include #include -#include #include +#include #include "absl/algorithm/container.h" #include "absl/strings/string_view.h" +#include "api/crypto/crypto_options.h" +#include "api/jsep.h" +#include "api/media_types.h" #include "api/rtp_parameters.h" #include "api/sequence_checker.h" #include "api/task_queue/pending_task_safety_flag.h" -#include "api/units/timestamp.h" +#include "api/task_queue/task_queue_base.h" #include "media/base/codec.h" +#include "media/base/media_channel.h" #include "media/base/rid_description.h" #include "media/base/rtp_utils.h" +#include "media/base/stream_params.h" #include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "p2p/base/dtls_transport_internal.h" #include "pc/rtp_media_utils.h" +#include "pc/rtp_transport_internal.h" +#include "pc/session_description.h" +#include "rtc_base/async_packet_socket.h" #include "rtc_base/checks.h" +#include "rtc_base/containers/flat_set.h" #include "rtc_base/copy_on_write_buffer.h" #include "rtc_base/logging.h" +#include "rtc_base/network/sent_packet.h" #include "rtc_base/network_route.h" +#include "rtc_base/socket.h" #include "rtc_base/strings/string_format.h" +#include "rtc_base/thread.h" #include "rtc_base/trace_event.h" +#include "rtc_base/unique_id_generator.h" namespace cricket { namespace { @@ -907,7 +923,9 @@ bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content, set_local_content_direction(content->direction()); UpdateMediaSendRecvState_w(); - RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(0); + // Disabled because suggeting PTs takes thread jumps. + // TODO: https://issues.webrtc.org/360058654 - reenable after cleanup + // RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(0); bool success = MaybeUpdateDemuxerAndRtpExtensions_w( criteria_modified, @@ -916,7 +934,7 @@ bool VoiceChannel::SetLocalContent_w(const MediaContentDescription* content, : std::nullopt, error_desc); - RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(1); + // RTC_DCHECK_BLOCK_COUNT_NO_MORE_THAN(1); return success; } diff --git a/pc/jsep_transport.h b/pc/jsep_transport.h index 56840a3146..4839ea7796 100644 --- a/pc/jsep_transport.h +++ b/pc/jsep_transport.h @@ -17,7 +17,6 @@ #include #include -#include "api/candidate.h" #include "api/ice_transport_interface.h" #include "api/jsep.h" #include "api/rtc_error.h" @@ -243,6 +242,9 @@ class JsepTransport { const webrtc::PayloadTypeRecorder& local_payload_types() const { return local_payload_types_; } + webrtc::PayloadTypeRecorder& local_payload_types() { + return local_payload_types_; + } void CommitPayloadTypes() { RTC_DCHECK_RUN_ON(network_thread_); local_payload_types_.Commit(); diff --git a/pc/jsep_transport_controller.cc b/pc/jsep_transport_controller.cc index 27801966d3..cb79860889 100644 --- a/pc/jsep_transport_controller.cc +++ b/pc/jsep_transport_controller.cc @@ -12,25 +12,58 @@ #include +#include #include +#include #include +#include #include -#include #include +#include #include "absl/algorithm/container.h" +#include "absl/strings/string_view.h" +#include "api/async_dns_resolver.h" +#include "api/candidate.h" #include "api/dtls_transport_interface.h" #include "api/environment/environment.h" +#include "api/ice_transport_interface.h" +#include "api/jsep.h" +#include "api/peer_connection_interface.h" +#include "api/rtc_error.h" #include "api/rtp_parameters.h" +#include "api/scoped_refptr.h" #include "api/sequence_checker.h" +#include "api/transport/data_channel_transport_interface.h" #include "api/transport/enums.h" +#include "call/payload_type.h" +#include "call/payload_type_picker.h" +#include "media/base/codec.h" #include "media/sctp/sctp_transport_internal.h" +#include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "p2p/base/dtls_transport.h" +#include "p2p/base/dtls_transport_internal.h" #include "p2p/base/ice_transport_internal.h" #include "p2p/base/p2p_constants.h" #include "p2p/base/port.h" +#include "p2p/base/port_allocator.h" +#include "p2p/base/transport_description.h" +#include "p2p/base/transport_info.h" +#include "pc/dtls_srtp_transport.h" +#include "pc/dtls_transport.h" +#include "pc/jsep_transport.h" +#include "pc/rtp_transport.h" +#include "pc/rtp_transport_internal.h" +#include "pc/sctp_transport.h" +#include "pc/session_description.h" +#include "pc/srtp_transport.h" +#include "pc/transport_stats.h" #include "rtc_base/checks.h" +#include "rtc_base/copy_on_write_buffer.h" #include "rtc_base/logging.h" +#include "rtc_base/rtc_certificate.h" +#include "rtc_base/ssl_certificate.h" +#include "rtc_base/ssl_stream_adapter.h" #include "rtc_base/thread.h" #include "rtc_base/trace_event.h" @@ -225,6 +258,15 @@ std::optional JsepTransportController::GetDtlsRole( RTCErrorOr JsepTransportController::SuggestPayloadType( const std::string& mid, cricket::Codec codec) { + // Because SDP processing runs on the signal thread and Call processing + // runs on the worker thread, we allow cross thread invocation until we + // can clean up the thread work. + if (!network_thread_->IsCurrent()) { + return network_thread_->BlockingCall([&] { + RTC_DCHECK_RUN_ON(network_thread_); + return SuggestPayloadType(mid, codec); + }); + } RTC_DCHECK_RUN_ON(network_thread_); const cricket::JsepTransport* transport = GetJsepTransportForMid(mid); if (transport) { @@ -245,6 +287,27 @@ RTCErrorOr JsepTransportController::SuggestPayloadType( return payload_type_picker_.SuggestMapping(codec, nullptr); } +RTCError JsepTransportController::AddLocalMapping(const std::string& mid, + PayloadType payload_type, + const cricket::Codec& codec) { + // Because SDP processing runs on the signal thread and Call processing + // runs on the worker thread, we allow cross thread invocation until we + // can clean up the thread work. + if (!network_thread_->IsCurrent()) { + return network_thread_->BlockingCall([&] { + RTC_DCHECK_RUN_ON(network_thread_); + return AddLocalMapping(mid, payload_type, codec); + }); + } + RTC_DCHECK_RUN_ON(network_thread_); + cricket::JsepTransport* transport = GetJsepTransportForMid(mid); + if (!transport) { + return RTCError(RTCErrorType::INVALID_PARAMETER, + "AddLocalMapping: no transport for mid"); + } + return transport->local_payload_types().AddMapping(payload_type, codec); +} + bool JsepTransportController::SetLocalCertificate( const rtc::scoped_refptr& certificate) { if (!network_thread_->IsCurrent()) { diff --git a/pc/jsep_transport_controller.h b/pc/jsep_transport_controller.h index 2846dab115..b5e3ebf1f3 100644 --- a/pc/jsep_transport_controller.h +++ b/pc/jsep_transport_controller.h @@ -243,6 +243,9 @@ class JsepTransportController : public PayloadTypeSuggester, // or a newly suggested one. RTCErrorOr SuggestPayloadType(const std::string& mid, cricket::Codec codec) override; + RTCError AddLocalMapping(const std::string& mid, + PayloadType payload_type, + const cricket::Codec& codec) override; // TODO(deadbeef): GetStats isn't const because all the way down to // OpenSSLStreamAdapter, GetSslCipherSuite and GetDtlsSrtpCryptoSuite are not diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc index 32f21cfaea..b125f9e4fe 100644 --- a/pc/peer_connection.cc +++ b/pc/peer_connection.cc @@ -13,54 +13,110 @@ #include #include -#include +#include +#include +#include #include #include #include #include #include +#include #include "absl/algorithm/container.h" #include "absl/strings/match.h" #include "absl/strings/string_view.h" +#include "api/adaptation/resource.h" +#include "api/audio/audio_device.h" +#include "api/candidate.h" +#include "api/crypto/crypto_options.h" +#include "api/data_channel_interface.h" +#include "api/dtls_transport_interface.h" #include "api/environment/environment.h" +#include "api/jsep.h" #include "api/jsep_ice_candidate.h" +#include "api/make_ref_counted.h" +#include "api/media_stream_interface.h" #include "api/media_types.h" +#include "api/peer_connection_interface.h" +#include "api/rtc_error.h" +#include "api/rtc_event_log_output.h" #include "api/rtp_parameters.h" +#include "api/rtp_receiver_interface.h" +#include "api/rtp_sender_interface.h" #include "api/rtp_transceiver_direction.h" +#include "api/rtp_transceiver_interface.h" +#include "api/scoped_refptr.h" +#include "api/sctp_transport_interface.h" +#include "api/sequence_checker.h" +#include "api/set_local_description_observer_interface.h" +#include "api/set_remote_description_observer_interface.h" +#include "api/stats/rtc_stats_collector_callback.h" +#include "api/task_queue/pending_task_safety_flag.h" +#include "api/transport/bandwidth_estimation_settings.h" +#include "api/transport/bitrate_settings.h" +#include "api/transport/data_channel_transport_interface.h" +#include "api/transport/enums.h" +#include "api/turn_customizer.h" #include "api/uma_metrics.h" +#include "api/units/time_delta.h" #include "api/video/video_codec_constants.h" #include "call/audio_state.h" #include "call/packet_receiver.h" -#include "media/base/media_channel.h" +#include "media/base/codec.h" #include "media/base/media_config.h" #include "media/base/media_engine.h" #include "media/base/rid_description.h" #include "media/base/stream_params.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" +#include "modules/rtp_rtcp/source/rtp_packet_received.h" #include "p2p/base/basic_async_resolver_factory.h" -#include "p2p/base/connection.h" #include "p2p/base/connection_info.h" #include "p2p/base/dtls_transport_internal.h" +#include "p2p/base/ice_transport_internal.h" #include "p2p/base/p2p_constants.h" #include "p2p/base/p2p_transport_channel.h" +#include "p2p/base/port.h" +#include "p2p/base/port_allocator.h" +#include "p2p/base/transport_description.h" #include "p2p/base/transport_info.h" +#include "pc/channel_interface.h" +#include "pc/connection_context.h" +#include "pc/data_channel_utils.h" +#include "pc/dtls_transport.h" #include "pc/ice_server_parsing.h" +#include "pc/jsep_transport_controller.h" +#include "pc/legacy_stats_collector.h" +#include "pc/rtc_stats_collector.h" #include "pc/rtp_receiver.h" #include "pc/rtp_receiver_proxy.h" #include "pc/rtp_sender.h" #include "pc/rtp_sender_proxy.h" +#include "pc/rtp_transceiver.h" +#include "pc/rtp_transmission_manager.h" +#include "pc/rtp_transport_internal.h" +#include "pc/sctp_data_channel.h" #include "pc/sctp_transport.h" +#include "pc/sdp_offer_answer.h" +#include "pc/session_description.h" #include "pc/simulcast_description.h" -#include "pc/webrtc_session_description_factory.h" +#include "pc/transceiver_list.h" +#include "pc/transport_stats.h" +#include "pc/usage_pattern.h" +#include "rtc_base/checks.h" +#include "rtc_base/copy_on_write_buffer.h" #include "rtc_base/crypto_random.h" #include "rtc_base/ip_address.h" #include "rtc_base/logging.h" #include "rtc_base/net_helper.h" #include "rtc_base/network.h" #include "rtc_base/network_constants.h" +#include "rtc_base/rtc_certificate.h" #include "rtc_base/socket_address.h" +#include "rtc_base/ssl_certificate.h" +#include "rtc_base/ssl_stream_adapter.h" #include "rtc_base/string_encode.h" +#include "rtc_base/thread.h" #include "rtc_base/trace_event.h" #include "rtc_base/unique_id_generator.h" #include "system_wrappers/include/metrics.h" @@ -695,6 +751,12 @@ RTCError PeerConnection::Initialize( kPeerConnectionAddressFamilyCounter_Max); return InitializeTransportController_n(configuration, dependencies); }); + if (call_ptr_) { + worker_thread()->BlockingCall([this, tc = transport_controller_copy_] { + RTC_DCHECK_RUN_ON(worker_thread()); + call_->SetPayloadTypeSuggester(tc); + }); + } configuration_ = configuration;