diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:33 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:33 +0000 |
commit | 086c044dc34dfc0f74fbe41f4ecb402b2cd34884 (patch) | |
tree | a4f824bd33cb075dd5aa3eb5a0a94af221bbe83a /third_party/libwebrtc/pc/media_session.cc | |
parent | Adding debian version 124.0.1-1. (diff) | |
download | firefox-086c044dc34dfc0f74fbe41f4ecb402b2cd34884.tar.xz firefox-086c044dc34dfc0f74fbe41f4ecb402b2cd34884.zip |
Merging upstream version 125.0.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/pc/media_session.cc')
-rw-r--r-- | third_party/libwebrtc/pc/media_session.cc | 865 |
1 files changed, 326 insertions, 539 deletions
diff --git a/third_party/libwebrtc/pc/media_session.cc b/third_party/libwebrtc/pc/media_session.cc index a763919c16..573e35225e 100644 --- a/third_party/libwebrtc/pc/media_session.cc +++ b/third_party/libwebrtc/pc/media_session.cc @@ -117,52 +117,38 @@ namespace cricket { namespace { -bool IsRtxCodec(const Codec& codec) { - return absl::EqualsIgnoreCase(codec.name, kRtxCodecName); -} - bool IsRtxCodec(const webrtc::RtpCodecCapability& capability) { return absl::EqualsIgnoreCase(capability.name, kRtxCodecName); } bool ContainsRtxCodec(const std::vector<Codec>& codecs) { - for (const auto& codec : codecs) { - if (IsRtxCodec(codec)) { - return true; - } - } - return false; -} - -bool IsRedCodec(const Codec& codec) { - return absl::EqualsIgnoreCase(codec.name, kRedCodecName); + return absl::c_find_if(codecs, [](const Codec& c) { + return c.GetResiliencyType() == Codec::ResiliencyType::kRtx; + }) != codecs.end(); } bool IsRedCodec(const webrtc::RtpCodecCapability& capability) { return absl::EqualsIgnoreCase(capability.name, kRedCodecName); } -bool IsFlexfecCodec(const Codec& codec) { - return absl::EqualsIgnoreCase(codec.name, kFlexfecCodecName); -} - bool ContainsFlexfecCodec(const std::vector<Codec>& codecs) { - for (const auto& codec : codecs) { - if (IsFlexfecCodec(codec)) { - return true; - } - } - return false; -} - -bool IsUlpfecCodec(const Codec& codec) { - return absl::EqualsIgnoreCase(codec.name, kUlpfecCodecName); + return absl::c_find_if(codecs, [](const Codec& c) { + return c.GetResiliencyType() == Codec::ResiliencyType::kFlexfec; + }) != codecs.end(); } bool IsComfortNoiseCodec(const Codec& codec) { return absl::EqualsIgnoreCase(codec.name, kComfortNoiseCodecName); } +void StripCNCodecs(AudioCodecs* audio_codecs) { + audio_codecs->erase(std::remove_if(audio_codecs->begin(), audio_codecs->end(), + [](const AudioCodec& codec) { + return IsComfortNoiseCodec(codec); + }), + audio_codecs->end()); +} + RtpTransceiverDirection NegotiateRtpTransceiverDirection( RtpTransceiverDirection offer, RtpTransceiverDirection wants) { @@ -727,12 +713,10 @@ RTCError CreateMediaContentOffer( bool ReferencedCodecsMatch(const std::vector<Codec>& codecs1, const int codec1_id, const std::vector<Codec>& codecs2, - const int codec2_id, - const webrtc::FieldTrialsView* field_trials) { + const int codec2_id) { const Codec* codec1 = FindCodecById(codecs1, codec1_id); const Codec* codec2 = FindCodecById(codecs2, codec2_id); - return codec1 != nullptr && codec2 != nullptr && - codec1->Matches(*codec2, field_trials); + return codec1 != nullptr && codec2 != nullptr && codec1->Matches(*codec2); } void NegotiatePacketization(const Codec& local_codec, @@ -747,11 +731,9 @@ void NegotiatePacketization(const Codec& local_codec, // Finds a codec in `codecs2` that matches `codec_to_match`, which is // a member of `codecs1`. If `codec_to_match` is an RED or RTX codec, both // the codecs themselves and their associated codecs must match. -absl::optional<Codec> FindMatchingCodec( - const std::vector<Codec>& codecs1, - const std::vector<Codec>& codecs2, - const Codec& codec_to_match, - const webrtc::FieldTrialsView* field_trials) { +absl::optional<Codec> FindMatchingCodec(const std::vector<Codec>& codecs1, + const std::vector<Codec>& codecs2, + const Codec& codec_to_match) { // `codec_to_match` should be a member of `codecs1`, in order to look up // RED/RTX codecs' associated codecs correctly. If not, that's a programming // error. @@ -759,8 +741,8 @@ absl::optional<Codec> FindMatchingCodec( return &codec == &codec_to_match; })); for (const Codec& potential_match : codecs2) { - if (potential_match.Matches(codec_to_match, field_trials)) { - if (IsRtxCodec(codec_to_match)) { + if (potential_match.Matches(codec_to_match)) { + if (codec_to_match.GetResiliencyType() == Codec::ResiliencyType::kRtx) { int apt_value_1 = 0; int apt_value_2 = 0; if (!codec_to_match.GetParam(kCodecParamAssociatedPayloadType, @@ -770,11 +752,12 @@ absl::optional<Codec> FindMatchingCodec( RTC_LOG(LS_WARNING) << "RTX missing associated payload type."; continue; } - if (!ReferencedCodecsMatch(codecs1, apt_value_1, codecs2, apt_value_2, - field_trials)) { + if (!ReferencedCodecsMatch(codecs1, apt_value_1, codecs2, + apt_value_2)) { continue; } - } else if (IsRedCodec(codec_to_match)) { + } else if (codec_to_match.GetResiliencyType() == + Codec::ResiliencyType::kRed) { auto red_parameters_1 = codec_to_match.params.find(kCodecParamNotInNameValueFormat); auto red_parameters_2 = @@ -814,7 +797,7 @@ absl::optional<Codec> FindMatchingCodec( if (rtc::FromString(redundant_payloads_1[0], &red_value_1) && rtc::FromString(redundant_payloads_2[0], &red_value_2)) { if (!ReferencedCodecsMatch(codecs1, red_value_1, codecs2, - red_value_2, field_trials)) { + red_value_2)) { continue; } } @@ -832,18 +815,17 @@ absl::optional<Codec> FindMatchingCodec( void NegotiateCodecs(const std::vector<Codec>& local_codecs, const std::vector<Codec>& offered_codecs, std::vector<Codec>* negotiated_codecs, - bool keep_offer_order, - const webrtc::FieldTrialsView* field_trials) { + bool keep_offer_order) { for (const Codec& ours : local_codecs) { absl::optional<Codec> theirs = - FindMatchingCodec(local_codecs, offered_codecs, ours, field_trials); + FindMatchingCodec(local_codecs, offered_codecs, ours); // Note that we intentionally only find one matching codec for each of our // local codecs, in case the remote offer contains duplicate codecs. if (theirs) { Codec negotiated = ours; NegotiatePacketization(ours, *theirs, &negotiated); negotiated.IntersectFeedbackParams(*theirs); - if (IsRtxCodec(negotiated)) { + if (negotiated.GetResiliencyType() == Codec::ResiliencyType::kRtx) { const auto apt_it = theirs->params.find(kCodecParamAssociatedPayloadType); // FindMatchingCodec shouldn't return something with no apt value. @@ -855,7 +837,8 @@ void NegotiateCodecs(const std::vector<Codec>& local_codecs, if (rtx_time_it != theirs->params.end()) { negotiated.SetParam(kCodecParamRtxTime, rtx_time_it->second); } - } else if (IsRedCodec(negotiated)) { + } else if (negotiated.GetResiliencyType() == + Codec::ResiliencyType::kRed) { const auto red_it = theirs->params.find(kCodecParamNotInNameValueFormat); if (red_it != theirs->params.end()) { @@ -960,15 +943,15 @@ const Codec* GetAssociatedCodecForRed(const std::vector<Codec>& codec_list, // collide. void MergeCodecs(const std::vector<Codec>& reference_codecs, std::vector<Codec>* offered_codecs, - UsedPayloadTypes* used_pltypes, - const webrtc::FieldTrialsView* field_trials) { + UsedPayloadTypes* used_pltypes) { // Add all new codecs that are not RTX/RED codecs. // The two-pass splitting of the loops means preferring payload types // of actual codecs with respect to collisions. for (const Codec& reference_codec : reference_codecs) { - if (!IsRtxCodec(reference_codec) && !IsRedCodec(reference_codec) && - !FindMatchingCodec(reference_codecs, *offered_codecs, reference_codec, - field_trials)) { + if (reference_codec.GetResiliencyType() != Codec::ResiliencyType::kRtx && + reference_codec.GetResiliencyType() != Codec::ResiliencyType::kRed && + !FindMatchingCodec(reference_codecs, *offered_codecs, + reference_codec)) { Codec codec = reference_codec; used_pltypes->FindAndSetIdUsed(&codec); offered_codecs->push_back(codec); @@ -977,9 +960,9 @@ void MergeCodecs(const std::vector<Codec>& reference_codecs, // Add all new RTX or RED codecs. for (const Codec& reference_codec : reference_codecs) { - if (IsRtxCodec(reference_codec) && - !FindMatchingCodec(reference_codecs, *offered_codecs, reference_codec, - field_trials)) { + if (reference_codec.GetResiliencyType() == Codec::ResiliencyType::kRtx && + !FindMatchingCodec(reference_codecs, *offered_codecs, + reference_codec)) { Codec rtx_codec = reference_codec; const Codec* associated_codec = GetAssociatedCodecForRtx(reference_codecs, rtx_codec); @@ -989,7 +972,7 @@ void MergeCodecs(const std::vector<Codec>& reference_codecs, // Find a codec in the offered list that matches the reference codec. // Its payload type may be different than the reference codec. absl::optional<Codec> matching_codec = FindMatchingCodec( - reference_codecs, *offered_codecs, *associated_codec, field_trials); + reference_codecs, *offered_codecs, *associated_codec); if (!matching_codec) { RTC_LOG(LS_WARNING) << "Couldn't find matching " << associated_codec->name << " codec."; @@ -1000,15 +983,16 @@ void MergeCodecs(const std::vector<Codec>& reference_codecs, rtc::ToString(matching_codec->id); used_pltypes->FindAndSetIdUsed(&rtx_codec); offered_codecs->push_back(rtx_codec); - } else if (IsRedCodec(reference_codec) && + } else if (reference_codec.GetResiliencyType() == + Codec::ResiliencyType::kRed && !FindMatchingCodec(reference_codecs, *offered_codecs, - reference_codec, field_trials)) { + reference_codec)) { Codec red_codec = reference_codec; const Codec* associated_codec = GetAssociatedCodecForRed(reference_codecs, red_codec); if (associated_codec) { absl::optional<Codec> matching_codec = FindMatchingCodec( - reference_codecs, *offered_codecs, *associated_codec, field_trials); + reference_codecs, *offered_codecs, *associated_codec); if (!matching_codec) { RTC_LOG(LS_WARNING) << "Couldn't find matching " << associated_codec->name << " codec."; @@ -1032,8 +1016,7 @@ void MergeCodecs(const std::vector<Codec>& reference_codecs, std::vector<Codec> MatchCodecPreference( const std::vector<webrtc::RtpCodecCapability>& codec_preferences, const std::vector<Codec>& codecs, - const std::vector<Codec>& supported_codecs, - const webrtc::FieldTrialsView* field_trials) { + const std::vector<Codec>& supported_codecs) { std::vector<Codec> filtered_codecs; bool want_rtx = false; bool want_red = false; @@ -1060,12 +1043,13 @@ std::vector<Codec> MatchCodecPreference( }); if (found_codec != supported_codecs.end()) { - absl::optional<Codec> found_codec_with_correct_pt = FindMatchingCodec( - supported_codecs, codecs, *found_codec, field_trials); + absl::optional<Codec> found_codec_with_correct_pt = + FindMatchingCodec(supported_codecs, codecs, *found_codec); if (found_codec_with_correct_pt) { // RED may already have been added if its primary codec is before RED // in the codec list. - bool is_red_codec = IsRedCodec(*found_codec_with_correct_pt); + bool is_red_codec = found_codec_with_correct_pt->GetResiliencyType() == + Codec::ResiliencyType::kRed; if (!is_red_codec || !red_was_added) { filtered_codecs.push_back(*found_codec_with_correct_pt); red_was_added = is_red_codec ? true : red_was_added; @@ -1074,14 +1058,15 @@ std::vector<Codec> MatchCodecPreference( // Search for the matching rtx or red codec. if (want_red || want_rtx) { for (const auto& codec : codecs) { - if (IsRtxCodec(codec)) { + if (codec.GetResiliencyType() == Codec::ResiliencyType::kRtx) { const auto apt = codec.params.find(cricket::kCodecParamAssociatedPayloadType); if (apt != codec.params.end() && apt->second == id) { filtered_codecs.push_back(codec); break; } - } else if (IsRedCodec(codec)) { + } else if (codec.GetResiliencyType() == + Codec::ResiliencyType::kRed) { // For RED, do not insert the codec again if it was already // inserted. audio/red for opus gets enabled by having RED before // the primary codec. @@ -1110,10 +1095,8 @@ std::vector<Codec> MatchCodecPreference( } // Compute the union of `codecs1` and `codecs2`. -std::vector<Codec> ComputeCodecsUnion( - const std::vector<Codec>& codecs1, - const std::vector<Codec>& codecs2, - const webrtc::FieldTrialsView* field_trials) { +std::vector<Codec> ComputeCodecsUnion(const std::vector<Codec>& codecs1, + const std::vector<Codec>& codecs2) { std::vector<Codec> all_codecs; UsedPayloadTypes used_payload_types; for (const Codec& codec : codecs1) { @@ -1124,7 +1107,7 @@ std::vector<Codec> ComputeCodecsUnion( // Use MergeCodecs to merge the second half of our list as it already checks // and fixes problems with duplicate payload types. - MergeCodecs(codecs2, &all_codecs, &used_payload_types, field_trials); + MergeCodecs(codecs2, &all_codecs, &used_payload_types); return all_codecs; } @@ -1333,14 +1316,6 @@ void NegotiateRtpHeaderExtensions(const RtpHeaderExtensions& local_extensions, } } -void StripCNCodecs(AudioCodecs* audio_codecs) { - audio_codecs->erase(std::remove_if(audio_codecs->begin(), audio_codecs->end(), - [](const AudioCodec& codec) { - return IsComfortNoiseCodec(codec); - }), - audio_codecs->end()); -} - bool SetCodecsInAnswer(const MediaContentDescription* offer, const std::vector<Codec>& local_codecs, const MediaDescriptionOptions& media_description_options, @@ -1353,8 +1328,7 @@ bool SetCodecsInAnswer(const MediaContentDescription* offer, offer->type() == MEDIA_TYPE_VIDEO); std::vector<Codec> negotiated_codecs; NegotiateCodecs(local_codecs, offer->codecs(), &negotiated_codecs, - media_description_options.codec_preferences.empty(), - &field_trials); + media_description_options.codec_preferences.empty()); answer->AddCodecs(negotiated_codecs); answer->set_protocol(offer->protocol()); if (!AddStreamParams(media_description_options.sender_options, @@ -1512,6 +1486,145 @@ bool IsDtlsActive(const ContentInfo* content, .description.secure(); } +webrtc::RTCErrorOr<AudioCodecs> GetNegotiatedCodecsForOffer( + const MediaDescriptionOptions& media_description_options, + const MediaSessionOptions& session_options, + const ContentInfo* current_content, + const std::vector<Codec>& codecs, + const std::vector<Codec>& supported_codecs) { + std::vector<Codec> filtered_codecs; + if (!media_description_options.codec_preferences.empty()) { + // Add the codecs from the current transceiver's codec preferences. + // They override any existing codecs from previous negotiations. + filtered_codecs = MatchCodecPreference( + media_description_options.codec_preferences, codecs, supported_codecs); + } else { + // Add the codecs from current content if it exists and is not rejected nor + // recycled. + if (current_content && !current_content->rejected && + current_content->name == media_description_options.mid) { + if (!IsMediaContentOfType(current_content, + media_description_options.type)) { + // Can happen if the remote side re-uses a MID while recycling. + LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, + "Media type for content with mid='" + + current_content->name + + "' does not match previous type."); + } + const MediaContentDescription* mcd = current_content->media_description(); + for (const Codec& codec : mcd->codecs()) { + if (FindMatchingCodec(mcd->codecs(), codecs, codec)) { + filtered_codecs.push_back(codec); + } + } + } + // Add other supported codecs. + for (const Codec& codec : supported_codecs) { + absl::optional<Codec> found_codec = + FindMatchingCodec(supported_codecs, codecs, codec); + if (found_codec && + !FindMatchingCodec(supported_codecs, filtered_codecs, codec)) { + // Use the `found_codec` from `codecs` because it has the + // correctly mapped payload type. + // This is only done for video since we do not yet have rtx for audio. + if (media_description_options.type == MEDIA_TYPE_VIDEO && + found_codec->GetResiliencyType() == Codec::ResiliencyType::kRtx) { + // For RTX we might need to adjust the apt parameter if we got a + // remote offer without RTX for a codec for which we support RTX. + auto referenced_codec = + GetAssociatedCodecForRtx(supported_codecs, codec); + RTC_DCHECK(referenced_codec); + + // Find the codec we should be referencing and point to it. + absl::optional<Codec> changed_referenced_codec = FindMatchingCodec( + supported_codecs, filtered_codecs, *referenced_codec); + if (changed_referenced_codec) { + found_codec->SetParam(kCodecParamAssociatedPayloadType, + changed_referenced_codec->id); + } + } + filtered_codecs.push_back(*found_codec); + } + } + } + + if (media_description_options.type == MEDIA_TYPE_AUDIO && + !session_options.vad_enabled) { + // If application doesn't want CN codecs in offer. + StripCNCodecs(&filtered_codecs); + } else if (media_description_options.type == MEDIA_TYPE_VIDEO && + session_options.raw_packetization_for_video) { + for (Codec& codec : filtered_codecs) { + if (codec.IsMediaCodec()) { + codec.packetization = kPacketizationParamRaw; + } + } + } + return filtered_codecs; +} + +webrtc::RTCErrorOr<AudioCodecs> GetNegotiatedCodecsForAnswer( + const MediaDescriptionOptions& media_description_options, + const MediaSessionOptions& session_options, + const ContentInfo* current_content, + const std::vector<Codec>& codecs, + const std::vector<Codec>& supported_codecs) { + std::vector<Codec> filtered_codecs; + + if (!media_description_options.codec_preferences.empty()) { + filtered_codecs = MatchCodecPreference( + media_description_options.codec_preferences, codecs, supported_codecs); + } else { + // Add the codecs from current content if it exists and is not rejected nor + // recycled. + if (current_content && !current_content->rejected && + current_content->name == media_description_options.mid) { + if (!IsMediaContentOfType(current_content, + media_description_options.type)) { + // Can happen if the remote side re-uses a MID while recycling. + LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, + "Media type for content with mid='" + + current_content->name + + "' does not match previous type."); + } + const MediaContentDescription* mcd = current_content->media_description(); + for (const Codec& codec : mcd->codecs()) { + if (FindMatchingCodec(mcd->codecs(), codecs, codec)) { + filtered_codecs.push_back(codec); + } + } + } + // Add other supported video codecs. + std::vector<Codec> other_codecs; + for (const Codec& codec : supported_codecs) { + if (FindMatchingCodec(supported_codecs, codecs, codec) && + !FindMatchingCodec(supported_codecs, filtered_codecs, codec)) { + // We should use the local codec with local parameters and the codec id + // would be correctly mapped in `NegotiateCodecs`. + other_codecs.push_back(codec); + } + } + + // Use ComputeCodecsUnion to avoid having duplicate payload IDs. + // This is a no-op for audio until RTX is added. + filtered_codecs = ComputeCodecsUnion(filtered_codecs, other_codecs); + } + + if (media_description_options.type == MEDIA_TYPE_AUDIO && + !session_options.vad_enabled) { + // If application doesn't want CN codecs in offer. + StripCNCodecs(&filtered_codecs); + } else if (media_description_options.type == MEDIA_TYPE_VIDEO && + session_options.raw_packetization_for_video) { + for (Codec& codec : filtered_codecs) { + if (codec.IsMediaCodec()) { + codec.packetization = kPacketizationParamRaw; + } + } + } + return filtered_codecs; +} + } // namespace void MediaDescriptionOptions::AddAudioSender( @@ -1683,15 +1796,16 @@ MediaSessionDescriptionFactory::CreateOfferOrError( RTCError error; switch (media_description_options.type) { case MEDIA_TYPE_AUDIO: - error = AddAudioContentForOffer( - media_description_options, session_options, current_content, - current_description, extensions_with_ids.audio, offer_audio_codecs, - ¤t_streams, offer.get(), &ice_credentials); - break; case MEDIA_TYPE_VIDEO: - error = AddVideoContentForOffer( + error = AddRtpContentForOffer( media_description_options, session_options, current_content, - current_description, extensions_with_ids.video, offer_video_codecs, + current_description, + media_description_options.type == MEDIA_TYPE_AUDIO + ? extensions_with_ids.audio + : extensions_with_ids.video, + media_description_options.type == MEDIA_TYPE_AUDIO + ? offer_audio_codecs + : offer_video_codecs, ¤t_streams, offer.get(), &ice_credentials); break; case MEDIA_TYPE_DATA: @@ -1852,18 +1966,15 @@ MediaSessionDescriptionFactory::CreateAnswerOrError( RTCError error; switch (media_description_options.type) { case MEDIA_TYPE_AUDIO: - error = AddAudioContentForAnswer( - media_description_options, session_options, offer_content, offer, - current_content, current_description, bundle_transport, - answer_audio_codecs, header_extensions, ¤t_streams, - answer.get(), &ice_credentials); - break; case MEDIA_TYPE_VIDEO: - error = AddVideoContentForAnswer( + error = AddRtpContentForAnswer( media_description_options, session_options, offer_content, offer, current_content, current_description, bundle_transport, - answer_video_codecs, header_extensions, ¤t_streams, - answer.get(), &ice_credentials); + media_description_options.type == MEDIA_TYPE_AUDIO + ? answer_audio_codecs + : answer_video_codecs, + header_extensions, ¤t_streams, answer.get(), + &ice_credentials); break; case MEDIA_TYPE_DATA: error = AddDataContentForAnswer( @@ -2035,15 +2146,14 @@ void MergeCodecsFromDescription( const std::vector<const ContentInfo*>& current_active_contents, AudioCodecs* audio_codecs, VideoCodecs* video_codecs, - UsedPayloadTypes* used_pltypes, - const webrtc::FieldTrialsView* field_trials) { + UsedPayloadTypes* used_pltypes) { for (const ContentInfo* content : current_active_contents) { if (IsMediaContentOfType(content, MEDIA_TYPE_AUDIO)) { MergeCodecs(content->media_description()->codecs(), audio_codecs, - used_pltypes, field_trials); + used_pltypes); } else if (IsMediaContentOfType(content, MEDIA_TYPE_VIDEO)) { MergeCodecs(content->media_description()->codecs(), video_codecs, - used_pltypes, field_trials); + used_pltypes); } } } @@ -2058,18 +2168,16 @@ void MediaSessionDescriptionFactory::GetCodecsForOffer( const std::vector<const ContentInfo*>& current_active_contents, AudioCodecs* audio_codecs, VideoCodecs* video_codecs) const { - const webrtc::FieldTrialsView* field_trials = - &transport_desc_factory_->trials(); // First - get all codecs from the current description if the media type // is used. Add them to `used_pltypes` so the payload type is not reused if a // new media type is added. UsedPayloadTypes used_pltypes; MergeCodecsFromDescription(current_active_contents, audio_codecs, - video_codecs, &used_pltypes, field_trials); + video_codecs, &used_pltypes); // Add our codecs that are not in the current description. - MergeCodecs(all_audio_codecs_, audio_codecs, &used_pltypes, field_trials); - MergeCodecs(all_video_codecs_, video_codecs, &used_pltypes, field_trials); + MergeCodecs(all_audio_codecs_, audio_codecs, &used_pltypes); + MergeCodecs(all_video_codecs_, video_codecs, &used_pltypes); } // Getting codecs for an answer involves these steps: @@ -2084,14 +2192,12 @@ void MediaSessionDescriptionFactory::GetCodecsForAnswer( const SessionDescription& remote_offer, AudioCodecs* audio_codecs, VideoCodecs* video_codecs) const { - const webrtc::FieldTrialsView* field_trials = - &transport_desc_factory_->trials(); // First - get all codecs from the current description if the media type // is used. Add them to `used_pltypes` so the payload type is not reused if a // new media type is added. UsedPayloadTypes used_pltypes; MergeCodecsFromDescription(current_active_contents, audio_codecs, - video_codecs, &used_pltypes, field_trials); + video_codecs, &used_pltypes); // Second - filter out codecs that we don't support at all and should ignore. AudioCodecs filtered_offered_audio_codecs; @@ -2101,9 +2207,9 @@ void MediaSessionDescriptionFactory::GetCodecsForAnswer( std::vector<Codec> offered_codecs = content.media_description()->codecs(); for (const Codec& offered_audio_codec : offered_codecs) { if (!FindMatchingCodec(offered_codecs, filtered_offered_audio_codecs, - offered_audio_codec, field_trials) && + offered_audio_codec) && FindMatchingCodec(offered_codecs, all_audio_codecs_, - offered_audio_codec, field_trials)) { + offered_audio_codec)) { filtered_offered_audio_codecs.push_back(offered_audio_codec); } } @@ -2111,9 +2217,9 @@ void MediaSessionDescriptionFactory::GetCodecsForAnswer( std::vector<Codec> offered_codecs = content.media_description()->codecs(); for (const Codec& offered_video_codec : offered_codecs) { if (!FindMatchingCodec(offered_codecs, filtered_offered_video_codecs, - offered_video_codec, field_trials) && + offered_video_codec) && FindMatchingCodec(offered_codecs, all_video_codecs_, - offered_video_codec, field_trials)) { + offered_video_codec)) { filtered_offered_video_codecs.push_back(offered_video_codec); } } @@ -2122,10 +2228,8 @@ void MediaSessionDescriptionFactory::GetCodecsForAnswer( // Add codecs that are not in the current description but were in // `remote_offer`. - MergeCodecs(filtered_offered_audio_codecs, audio_codecs, &used_pltypes, - field_trials); - MergeCodecs(filtered_offered_video_codecs, video_codecs, &used_pltypes, - field_trials); + MergeCodecs(filtered_offered_audio_codecs, audio_codecs, &used_pltypes); + MergeCodecs(filtered_offered_video_codecs, video_codecs, &used_pltypes); } MediaSessionDescriptionFactory::AudioVideoRtpHeaderExtensions @@ -2237,228 +2341,85 @@ RTCError MediaSessionDescriptionFactory::AddTransportAnswer( return RTCError::OK(); } -// `audio_codecs` = set of all possible codecs that can be used, with correct +// `codecs` = set of all possible codecs that can be used, with correct // payload type mappings // -// `supported_audio_codecs` = set of codecs that are supported for the direction +// `supported_codecs` = set of codecs that are supported for the direction // of this m= section +// `current_content` = current description, may be null. +// current_content->codecs() = set of previously negotiated codecs for this m= +// section // -// mcd->codecs() = set of previously negotiated codecs for this m= section -// -// The payload types should come from audio_codecs, but the order should come -// from mcd->codecs() and then supported_codecs, to ensure that re-offers don't -// change existing codec priority, and that new codecs are added with the right -// priority. -RTCError MediaSessionDescriptionFactory::AddAudioContentForOffer( +// The payload types should come from codecs, but the order should come +// from current_content->codecs() and then supported_codecs, to ensure that +// re-offers don't change existing codec priority, and that new codecs are added +// with the right priority. +RTCError MediaSessionDescriptionFactory::AddRtpContentForOffer( const MediaDescriptionOptions& media_description_options, const MediaSessionOptions& session_options, const ContentInfo* current_content, const SessionDescription* current_description, - const RtpHeaderExtensions& audio_rtp_extensions, - const AudioCodecs& audio_codecs, + const RtpHeaderExtensions& header_extensions, + const std::vector<Codec>& codecs, StreamParamsVec* current_streams, - SessionDescription* desc, + SessionDescription* session_description, IceCredentialsIterator* ice_credentials) const { - const webrtc::FieldTrialsView* field_trials = - &transport_desc_factory_->trials(); - // Filter audio_codecs (which includes all codecs, with correctly remapped - // payload types) based on transceiver direction. - const AudioCodecs& supported_audio_codecs = - GetAudioCodecsForOffer(media_description_options.direction); - - AudioCodecs filtered_codecs; + RTC_DCHECK(media_description_options.type == MEDIA_TYPE_AUDIO || + media_description_options.type == MEDIA_TYPE_VIDEO); - if (!media_description_options.codec_preferences.empty()) { - // Add the codecs from the current transceiver's codec preferences. - // They override any existing codecs from previous negotiations. - filtered_codecs = MatchCodecPreference( - media_description_options.codec_preferences, audio_codecs, - supported_audio_codecs, field_trials); - } else { - // Add the codecs from current content if it exists and is not rejected nor - // recycled. - if (current_content && !current_content->rejected && - current_content->name == media_description_options.mid) { - if (!IsMediaContentOfType(current_content, MEDIA_TYPE_AUDIO)) { - // Can happen if the remote side re-uses a MID while recycling. - LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, - "Media type for content with mid='" + - current_content->name + - "' does not match previous type."); - } - const MediaContentDescription* mcd = current_content->media_description(); - for (const Codec& codec : mcd->codecs()) { - if (FindMatchingCodec(mcd->codecs(), audio_codecs, codec, - field_trials)) { - filtered_codecs.push_back(codec); - } - } - } - // Add other supported audio codecs. - for (const Codec& codec : supported_audio_codecs) { - absl::optional<Codec> found_codec = FindMatchingCodec( - supported_audio_codecs, audio_codecs, codec, field_trials); - if (found_codec && - !FindMatchingCodec(supported_audio_codecs, filtered_codecs, codec, - field_trials)) { - // Use the `found_codec` from `audio_codecs` because it has the - // correctly mapped payload type. - filtered_codecs.push_back(*found_codec); - } - } - } - if (!session_options.vad_enabled) { - // If application doesn't want CN codecs in offer. - StripCNCodecs(&filtered_codecs); + const std::vector<Codec>& supported_codecs = + media_description_options.type == MEDIA_TYPE_AUDIO + ? GetAudioCodecsForOffer(media_description_options.direction) + : GetVideoCodecsForOffer(media_description_options.direction); + webrtc::RTCErrorOr<std::vector<Codec>> error_or_filtered_codecs = + GetNegotiatedCodecsForOffer(media_description_options, session_options, + current_content, codecs, supported_codecs); + if (!error_or_filtered_codecs.ok()) { + return error_or_filtered_codecs.MoveError(); } cricket::SecurePolicy sdes_policy = IsDtlsActive(current_content, current_description) ? cricket::SEC_DISABLED : secure(); - auto audio = std::make_unique<AudioContentDescription>(); std::vector<std::string> crypto_suites; - GetSupportedAudioSdesCryptoSuiteNames(session_options.crypto_options, - &crypto_suites); - auto error = CreateMediaContentOffer( - media_description_options, session_options, filtered_codecs, sdes_policy, - GetCryptos(current_content), crypto_suites, audio_rtp_extensions, - ssrc_generator(), current_streams, audio.get(), - transport_desc_factory_->trials()); - if (!error.ok()) { - return error; - } - - bool secure_transport = (transport_desc_factory_->secure() != SEC_DISABLED); - SetMediaProtocol(secure_transport, audio.get()); - - audio->set_direction(media_description_options.direction); - - desc->AddContent(media_description_options.mid, MediaProtocolType::kRtp, - media_description_options.stopped, std::move(audio)); - error = AddTransportOffer(media_description_options.mid, - media_description_options.transport_options, - current_description, desc, ice_credentials); - if (!error.ok()) { - return error; - } - - return RTCError::OK(); -} - -// TODO(kron): This function is very similar to AddAudioContentForOffer. -// Refactor to reuse shared code. -RTCError MediaSessionDescriptionFactory::AddVideoContentForOffer( - const MediaDescriptionOptions& media_description_options, - const MediaSessionOptions& session_options, - const ContentInfo* current_content, - const SessionDescription* current_description, - const RtpHeaderExtensions& video_rtp_extensions, - const VideoCodecs& video_codecs, - StreamParamsVec* current_streams, - SessionDescription* desc, - IceCredentialsIterator* ice_credentials) const { - const webrtc::FieldTrialsView* field_trials = - &transport_desc_factory_->trials(); - // Filter video_codecs (which includes all codecs, with correctly remapped - // payload types) based on transceiver direction. - const VideoCodecs& supported_video_codecs = - GetVideoCodecsForOffer(media_description_options.direction); - - VideoCodecs filtered_codecs; - - if (!media_description_options.codec_preferences.empty()) { - // Add the codecs from the current transceiver's codec preferences. - // They override any existing codecs from previous negotiations. - filtered_codecs = MatchCodecPreference( - media_description_options.codec_preferences, video_codecs, - supported_video_codecs, field_trials); + if (media_description_options.type == MEDIA_TYPE_AUDIO) { + GetSupportedAudioSdesCryptoSuiteNames(session_options.crypto_options, + &crypto_suites); } else { - // Add the codecs from current content if it exists and is not rejected nor - // recycled. - if (current_content && !current_content->rejected && - current_content->name == media_description_options.mid) { - if (!IsMediaContentOfType(current_content, MEDIA_TYPE_VIDEO)) { - // Can happen if the remote side re-uses a MID while recycling. - LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, - "Media type for content with mid='" + - current_content->name + - "' does not match previous type."); - } - const MediaContentDescription* mcd = current_content->media_description(); - for (const Codec& codec : mcd->codecs()) { - if (FindMatchingCodec(mcd->codecs(), video_codecs, codec, - field_trials)) { - filtered_codecs.push_back(codec); - } - } - } - // Add other supported video codecs. - for (const Codec& codec : supported_video_codecs) { - absl::optional<Codec> found_codec = FindMatchingCodec( - supported_video_codecs, video_codecs, codec, field_trials); - if (found_codec && - !FindMatchingCodec(supported_video_codecs, filtered_codecs, codec, - field_trials)) { - // Use the `found_codec` from `video_codecs` because it has the - // correctly mapped payload type. - if (IsRtxCodec(codec)) { - // For RTX we might need to adjust the apt parameter if we got a - // remote offer without RTX for a codec for which we support RTX. - auto referenced_codec = - GetAssociatedCodecForRtx(supported_video_codecs, codec); - RTC_DCHECK(referenced_codec); - - // Find the codec we should be referencing and point to it. - absl::optional<Codec> changed_referenced_codec = - FindMatchingCodec(supported_video_codecs, filtered_codecs, - *referenced_codec, field_trials); - if (changed_referenced_codec) { - found_codec->SetParam(kCodecParamAssociatedPayloadType, - changed_referenced_codec->id); - } - } - filtered_codecs.push_back(*found_codec); - } - } + GetSupportedVideoSdesCryptoSuiteNames(session_options.crypto_options, + &crypto_suites); } - if (session_options.raw_packetization_for_video) { - for (Codec& codec : filtered_codecs) { - if (codec.IsMediaCodec()) { - codec.packetization = kPacketizationParamRaw; - } - } + std::unique_ptr<MediaContentDescription> content_description; + if (media_description_options.type == MEDIA_TYPE_AUDIO) { + content_description = std::make_unique<AudioContentDescription>(); + } else { + content_description = std::make_unique<VideoContentDescription>(); } - cricket::SecurePolicy sdes_policy = - IsDtlsActive(current_content, current_description) ? cricket::SEC_DISABLED - : secure(); - auto video = std::make_unique<VideoContentDescription>(); - std::vector<std::string> crypto_suites; - GetSupportedVideoSdesCryptoSuiteNames(session_options.crypto_options, - &crypto_suites); auto error = CreateMediaContentOffer( - media_description_options, session_options, filtered_codecs, sdes_policy, - GetCryptos(current_content), crypto_suites, video_rtp_extensions, - ssrc_generator(), current_streams, video.get(), + media_description_options, session_options, + error_or_filtered_codecs.MoveValue(), sdes_policy, + GetCryptos(current_content), crypto_suites, header_extensions, + ssrc_generator(), current_streams, content_description.get(), transport_desc_factory_->trials()); if (!error.ok()) { return error; } - video->set_bandwidth(kAutoBandwidth); - - bool secure_transport = (transport_desc_factory_->secure() != SEC_DISABLED); - SetMediaProtocol(secure_transport, video.get()); + bool secure_transport = transport_desc_factory_->secure() != SEC_DISABLED; + SetMediaProtocol(secure_transport, content_description.get()); - video->set_direction(media_description_options.direction); + content_description->set_direction(media_description_options.direction); - desc->AddContent(media_description_options.mid, MediaProtocolType::kRtp, - media_description_options.stopped, std::move(video)); + session_description->AddContent( + media_description_options.mid, MediaProtocolType::kRtp, + media_description_options.stopped, std::move(content_description)); return AddTransportOffer(media_description_options.mid, media_description_options.transport_options, - current_description, desc, ice_credentials); + current_description, session_description, + ice_credentials); } RTCError MediaSessionDescriptionFactory::AddDataContentForOffer( @@ -2526,19 +2487,19 @@ RTCError MediaSessionDescriptionFactory::AddUnsupportedContentForOffer( current_description, desc, ice_credentials); } -// `audio_codecs` = set of all possible codecs that can be used, with correct +// `codecs` = set of all possible codecs that can be used, with correct // payload type mappings // -// `supported_audio_codecs` = set of codecs that are supported for the direction +// `supported_codecs` = set of codecs that are supported for the direction // of this m= section // // mcd->codecs() = set of previously negotiated codecs for this m= section // -// The payload types should come from audio_codecs, but the order should come +// The payload types should come from codecs, but the order should come // from mcd->codecs() and then supported_codecs, to ensure that re-offers don't // change existing codec priority, and that new codecs are added with the right // priority. -RTCError MediaSessionDescriptionFactory::AddAudioContentForAnswer( +RTCError MediaSessionDescriptionFactory::AddRtpContentForAnswer( const MediaDescriptionOptions& media_description_options, const MediaSessionOptions& session_options, const ContentInfo* offer_content, @@ -2546,272 +2507,104 @@ RTCError MediaSessionDescriptionFactory::AddAudioContentForAnswer( const ContentInfo* current_content, const SessionDescription* current_description, const TransportInfo* bundle_transport, - const AudioCodecs& audio_codecs, - const RtpHeaderExtensions& rtp_header_extensions, + const std::vector<Codec>& codecs, + const RtpHeaderExtensions& header_extensions, StreamParamsVec* current_streams, SessionDescription* answer, IceCredentialsIterator* ice_credentials) const { - const webrtc::FieldTrialsView* field_trials = - &transport_desc_factory_->trials(); - RTC_CHECK(IsMediaContentOfType(offer_content, MEDIA_TYPE_AUDIO)); - const AudioContentDescription* offer_audio_description = - offer_content->media_description()->as_audio(); - - std::unique_ptr<TransportDescription> audio_transport = CreateTransportAnswer( + RTC_DCHECK(media_description_options.type == MEDIA_TYPE_AUDIO || + media_description_options.type == MEDIA_TYPE_VIDEO); + RTC_CHECK( + IsMediaContentOfType(offer_content, media_description_options.type)); + const RtpMediaContentDescription* offer_content_description; + if (media_description_options.type == MEDIA_TYPE_AUDIO) { + offer_content_description = offer_content->media_description()->as_audio(); + } else { + offer_content_description = offer_content->media_description()->as_video(); + } + std::unique_ptr<TransportDescription> transport = CreateTransportAnswer( media_description_options.mid, offer_description, media_description_options.transport_options, current_description, bundle_transport != nullptr, ice_credentials); - if (!audio_transport) { + if (!transport) { LOG_AND_RETURN_ERROR( RTCErrorType::INTERNAL_ERROR, - "Failed to create transport answer, audio transport is missing"); + "Failed to create transport answer, transport is missing"); } // Pick codecs based on the requested communications direction in the offer // and the selected direction in the answer. // Note these will be filtered one final time in CreateMediaContentAnswer. auto wants_rtd = media_description_options.direction; - auto offer_rtd = offer_audio_description->direction(); + auto offer_rtd = offer_content_description->direction(); auto answer_rtd = NegotiateRtpTransceiverDirection(offer_rtd, wants_rtd); - AudioCodecs supported_audio_codecs = - GetAudioCodecsForAnswer(offer_rtd, answer_rtd); - AudioCodecs filtered_codecs; - - if (!media_description_options.codec_preferences.empty()) { - filtered_codecs = MatchCodecPreference( - media_description_options.codec_preferences, audio_codecs, - supported_audio_codecs, field_trials); - } else { - // Add the codecs from current content if it exists and is not rejected nor - // recycled. - if (current_content && !current_content->rejected && - current_content->name == media_description_options.mid) { - if (!IsMediaContentOfType(current_content, MEDIA_TYPE_AUDIO)) { - // Can happen if the remote side re-uses a MID while recycling. - LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, - "Media type for content with mid='" + - current_content->name + - "' does not match previous type."); - } - const MediaContentDescription* mcd = current_content->media_description(); - for (const Codec& codec : mcd->codecs()) { - if (FindMatchingCodec(mcd->codecs(), audio_codecs, codec, - field_trials)) { - filtered_codecs.push_back(codec); - } - } - } - // Add other supported audio codecs. - for (const Codec& codec : supported_audio_codecs) { - if (FindMatchingCodec(supported_audio_codecs, audio_codecs, codec, - field_trials) && - !FindMatchingCodec(supported_audio_codecs, filtered_codecs, codec, - field_trials)) { - // We should use the local codec with local parameters and the codec id - // would be correctly mapped in `NegotiateCodecs`. - filtered_codecs.push_back(codec); - } - } - } - if (!session_options.vad_enabled) { - // If application doesn't want CN codecs in answer. - StripCNCodecs(&filtered_codecs); + const std::vector<Codec>& supported_codecs = + media_description_options.type == MEDIA_TYPE_AUDIO + ? GetAudioCodecsForAnswer(offer_rtd, answer_rtd) + : GetVideoCodecsForAnswer(offer_rtd, answer_rtd); + webrtc::RTCErrorOr<std::vector<Codec>> error_or_filtered_codecs = + GetNegotiatedCodecsForAnswer(media_description_options, session_options, + current_content, codecs, supported_codecs); + if (!error_or_filtered_codecs.ok()) { + return error_or_filtered_codecs.MoveError(); } + auto filtered_codecs = error_or_filtered_codecs.MoveValue(); // Determine if we have media codecs in common. bool has_common_media_codecs = std::find_if(filtered_codecs.begin(), filtered_codecs.end(), - [](const AudioCodec& c) { - return !(IsRedCodec(c) || IsComfortNoiseCodec(c)); + [](const Codec& c) { + return c.IsMediaCodec() && !IsComfortNoiseCodec(c); }) != filtered_codecs.end(); bool bundle_enabled = offer_description->HasGroup(GROUP_TYPE_BUNDLE) && session_options.bundle_enabled; - auto audio_answer = std::make_unique<AudioContentDescription>(); + std::unique_ptr<MediaContentDescription> answer_content; + if (media_description_options.type == MEDIA_TYPE_AUDIO) { + answer_content = std::make_unique<AudioContentDescription>(); + } else { + answer_content = std::make_unique<VideoContentDescription>(); + } // Do not require or create SDES cryptos if DTLS is used. cricket::SecurePolicy sdes_policy = - audio_transport->secure() ? cricket::SEC_DISABLED : secure(); - if (!SetCodecsInAnswer(offer_audio_description, filtered_codecs, - media_description_options, session_options, - ssrc_generator(), current_streams, audio_answer.get(), - transport_desc_factory_->trials())) { + transport->secure() ? cricket::SEC_DISABLED : secure(); + if (!SetCodecsInAnswer( + offer_content_description, filtered_codecs, media_description_options, + session_options, ssrc_generator(), current_streams, + answer_content.get(), transport_desc_factory_->trials())) { LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, "Failed to set codecs in answer"); } if (!CreateMediaContentAnswer( - offer_audio_description, media_description_options, session_options, + offer_content_description, media_description_options, session_options, sdes_policy, GetCryptos(current_content), - filtered_rtp_header_extensions(rtp_header_extensions), - ssrc_generator(), enable_encrypted_rtp_header_extensions_, - current_streams, bundle_enabled, audio_answer.get())) { + filtered_rtp_header_extensions(header_extensions), ssrc_generator(), + enable_encrypted_rtp_header_extensions_, current_streams, + bundle_enabled, answer_content.get())) { LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, "Failed to create answer"); } bool secure = bundle_transport ? bundle_transport->description.secure() - : audio_transport->secure(); + : transport->secure(); bool rejected = media_description_options.stopped || offer_content->rejected || !has_common_media_codecs || !IsMediaProtocolSupported(MEDIA_TYPE_AUDIO, - audio_answer->protocol(), secure); - auto error = AddTransportAnswer(media_description_options.mid, - *(audio_transport.get()), answer); - if (!error.ok()) { - return error; - } - + answer_content->protocol(), secure); if (rejected) { - RTC_LOG(LS_INFO) << "Audio m= section '" << media_description_options.mid + RTC_LOG(LS_INFO) << "m= section '" << media_description_options.mid << "' being rejected in answer."; } - answer->AddContent(media_description_options.mid, offer_content->type, - rejected, std::move(audio_answer)); - return RTCError::OK(); -} - -// TODO(kron): This function is very similar to AddAudioContentForAnswer. -// Refactor to reuse shared code. -RTCError MediaSessionDescriptionFactory::AddVideoContentForAnswer( - const MediaDescriptionOptions& media_description_options, - const MediaSessionOptions& session_options, - const ContentInfo* offer_content, - const SessionDescription* offer_description, - const ContentInfo* current_content, - const SessionDescription* current_description, - const TransportInfo* bundle_transport, - const VideoCodecs& video_codecs, - const RtpHeaderExtensions& default_video_rtp_header_extensions, - StreamParamsVec* current_streams, - SessionDescription* answer, - IceCredentialsIterator* ice_credentials) const { - const webrtc::FieldTrialsView* field_trials = - &transport_desc_factory_->trials(); - RTC_CHECK(IsMediaContentOfType(offer_content, MEDIA_TYPE_VIDEO)); - const VideoContentDescription* offer_video_description = - offer_content->media_description()->as_video(); - - std::unique_ptr<TransportDescription> video_transport = CreateTransportAnswer( - media_description_options.mid, offer_description, - media_description_options.transport_options, current_description, - bundle_transport != nullptr, ice_credentials); - if (!video_transport) { - LOG_AND_RETURN_ERROR( - RTCErrorType::INTERNAL_ERROR, - "Failed to create transport answer, video transport is missing"); - } - - // Pick codecs based on the requested communications direction in the offer - // and the selected direction in the answer. - // Note these will be filtered one final time in CreateMediaContentAnswer. - auto wants_rtd = media_description_options.direction; - auto offer_rtd = offer_video_description->direction(); - auto answer_rtd = NegotiateRtpTransceiverDirection(offer_rtd, wants_rtd); - VideoCodecs supported_video_codecs = - GetVideoCodecsForAnswer(offer_rtd, answer_rtd); - - VideoCodecs filtered_codecs; - - if (!media_description_options.codec_preferences.empty()) { - filtered_codecs = MatchCodecPreference( - media_description_options.codec_preferences, video_codecs, - supported_video_codecs, field_trials); - } else { - // Add the codecs from current content if it exists and is not rejected nor - // recycled. - if (current_content && !current_content->rejected && - current_content->name == media_description_options.mid) { - if (!IsMediaContentOfType(current_content, MEDIA_TYPE_VIDEO)) { - // Can happen if the remote side re-uses a MID while recycling. - LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, - "Media type for content with mid='" + - current_content->name + - "' does not match previous type."); - } - const MediaContentDescription* mcd = current_content->media_description(); - for (const Codec& codec : mcd->codecs()) { - if (FindMatchingCodec(mcd->codecs(), video_codecs, codec, - field_trials)) { - filtered_codecs.push_back(codec); - } - } - } - - // Add other supported video codecs. - VideoCodecs other_video_codecs; - for (const Codec& codec : supported_video_codecs) { - if (FindMatchingCodec(supported_video_codecs, video_codecs, codec, - field_trials) && - !FindMatchingCodec(supported_video_codecs, filtered_codecs, codec, - field_trials)) { - // We should use the local codec with local parameters and the codec id - // would be correctly mapped in `NegotiateCodecs`. - other_video_codecs.push_back(codec); - } - } - - // Use ComputeCodecsUnion to avoid having duplicate payload IDs - filtered_codecs = - ComputeCodecsUnion(filtered_codecs, other_video_codecs, field_trials); - } - // Determine if we have media codecs in common. - bool has_common_media_codecs = - std::find_if( - filtered_codecs.begin(), filtered_codecs.end(), [](const Codec& c) { - return !(IsRedCodec(c) || IsUlpfecCodec(c) || IsFlexfecCodec(c)); - }) != filtered_codecs.end(); - - if (session_options.raw_packetization_for_video) { - for (Codec& codec : filtered_codecs) { - if (codec.IsMediaCodec()) { - codec.packetization = kPacketizationParamRaw; - } - } - } - - bool bundle_enabled = offer_description->HasGroup(GROUP_TYPE_BUNDLE) && - session_options.bundle_enabled; - auto video_answer = std::make_unique<VideoContentDescription>(); - // Do not require or create SDES cryptos if DTLS is used. - cricket::SecurePolicy sdes_policy = - video_transport->secure() ? cricket::SEC_DISABLED : secure(); - if (!SetCodecsInAnswer(offer_video_description, filtered_codecs, - media_description_options, session_options, - ssrc_generator(), current_streams, video_answer.get(), - transport_desc_factory_->trials())) { - LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, - "Failed to set codecs in answer"); - } - if (!CreateMediaContentAnswer( - offer_video_description, media_description_options, session_options, - sdes_policy, GetCryptos(current_content), - filtered_rtp_header_extensions(default_video_rtp_header_extensions), - ssrc_generator(), enable_encrypted_rtp_header_extensions_, - current_streams, bundle_enabled, video_answer.get())) { - LOG_AND_RETURN_ERROR(RTCErrorType::INTERNAL_ERROR, - "Failed to create answer"); - } - bool secure = bundle_transport ? bundle_transport->description.secure() - : video_transport->secure(); - bool rejected = media_description_options.stopped || - offer_content->rejected || !has_common_media_codecs || - !IsMediaProtocolSupported(MEDIA_TYPE_VIDEO, - video_answer->protocol(), secure); auto error = AddTransportAnswer(media_description_options.mid, - *(video_transport.get()), answer); + *(transport.get()), answer); if (!error.ok()) { return error; } - if (!rejected) { - video_answer->set_bandwidth(kAutoBandwidth); - } else { - RTC_LOG(LS_INFO) << "Video m= section '" << media_description_options.mid - << "' being rejected in answer."; - } answer->AddContent(media_description_options.mid, offer_content->type, - rejected, std::move(video_answer)); + rejected, std::move(answer_content)); return RTCError::OK(); } @@ -2934,23 +2727,19 @@ RTCError MediaSessionDescriptionFactory::AddUnsupportedContentForAnswer( } void MediaSessionDescriptionFactory::ComputeAudioCodecsIntersectionAndUnion() { - const webrtc::FieldTrialsView* field_trials = - &transport_desc_factory_->trials(); audio_sendrecv_codecs_.clear(); all_audio_codecs_.clear(); // Compute the audio codecs union. for (const Codec& send : audio_send_codecs_) { all_audio_codecs_.push_back(send); - if (!FindMatchingCodec(audio_send_codecs_, audio_recv_codecs_, send, - field_trials)) { + if (!FindMatchingCodec(audio_send_codecs_, audio_recv_codecs_, send)) { // It doesn't make sense to have an RTX codec we support sending but not // receiving. - RTC_DCHECK(!IsRtxCodec(send)); + RTC_DCHECK(send.GetResiliencyType() != Codec::ResiliencyType::kRtx); } } for (const Codec& recv : audio_recv_codecs_) { - if (!FindMatchingCodec(audio_recv_codecs_, audio_send_codecs_, recv, - field_trials)) { + if (!FindMatchingCodec(audio_recv_codecs_, audio_send_codecs_, recv)) { all_audio_codecs_.push_back(recv); } } @@ -2960,17 +2749,15 @@ void MediaSessionDescriptionFactory::ComputeAudioCodecsIntersectionAndUnion() { // expensive than decoding, and prioritizing a codec in the send list probably // means it's a codec we can handle efficiently. NegotiateCodecs(audio_recv_codecs_, audio_send_codecs_, - &audio_sendrecv_codecs_, true, field_trials); + &audio_sendrecv_codecs_, true); } void MediaSessionDescriptionFactory::ComputeVideoCodecsIntersectionAndUnion() { - const webrtc::FieldTrialsView* field_trials = - &transport_desc_factory_->trials(); video_sendrecv_codecs_.clear(); // Use ComputeCodecsUnion to avoid having duplicate payload IDs all_video_codecs_ = - ComputeCodecsUnion(video_recv_codecs_, video_send_codecs_, field_trials); + ComputeCodecsUnion(video_recv_codecs_, video_send_codecs_); // Use NegotiateCodecs to merge our codec lists, since the operation is // essentially the same. Put send_codecs as the offered_codecs, which is the @@ -2978,7 +2765,7 @@ void MediaSessionDescriptionFactory::ComputeVideoCodecsIntersectionAndUnion() { // expensive than decoding, and prioritizing a codec in the send list probably // means it's a codec we can handle efficiently. NegotiateCodecs(video_recv_codecs_, video_send_codecs_, - &video_sendrecv_codecs_, true, field_trials); + &video_sendrecv_codecs_, true); } bool IsMediaContent(const ContentInfo* content) { |