| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2004 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2004 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 #endif | 745 #endif |
| 746 | 746 |
| 747 if (offer->crypto_required() == CT_SDES && offer->cryptos().empty()) { | 747 if (offer->crypto_required() == CT_SDES && offer->cryptos().empty()) { |
| 748 return false; | 748 return false; |
| 749 } | 749 } |
| 750 return true; | 750 return true; |
| 751 } | 751 } |
| 752 | 752 |
| 753 template <class C> | 753 template <class C> |
| 754 static bool ReferencedCodecsMatch(const std::vector<C>& codecs1, | 754 static bool ReferencedCodecsMatch(const std::vector<C>& codecs1, |
| 755 const std::string& codec1_id_str, | 755 const int codec1_id, |
| 756 const std::vector<C>& codecs2, | 756 const std::vector<C>& codecs2, |
| 757 const std::string& codec2_id_str) { | 757 const int codec2_id) { |
| 758 int codec1_id; | 758 const C* codec1 = FindCodecById(codecs1, codec1_id); |
| 759 int codec2_id; | 759 const C* codec2 = FindCodecById(codecs2, codec2_id); |
| 760 C codec1; | 760 return codec1 != nullptr && codec2 != nullptr && codec1->Matches(*codec2); |
| 761 C codec2; | |
| 762 if (!rtc::FromString(codec1_id_str, &codec1_id) || | |
| 763 !rtc::FromString(codec2_id_str, &codec2_id) || | |
| 764 !FindCodecById(codecs1, codec1_id, &codec1) || | |
| 765 !FindCodecById(codecs2, codec2_id, &codec2)) { | |
| 766 return false; | |
| 767 } | |
| 768 return codec1.Matches(codec2); | |
| 769 } | 761 } |
| 770 | 762 |
| 771 template <class C> | 763 template <class C> |
| 772 static void NegotiateCodecs(const std::vector<C>& local_codecs, | 764 static void NegotiateCodecs(const std::vector<C>& local_codecs, |
| 773 const std::vector<C>& offered_codecs, | 765 const std::vector<C>& offered_codecs, |
| 774 std::vector<C>* negotiated_codecs) { | 766 std::vector<C>* negotiated_codecs) { |
| 775 for (const C& ours : local_codecs) { | 767 for (const C& ours : local_codecs) { |
| 776 C theirs; | 768 C theirs; |
| 777 // Note that we intentionally only find one matching codec for each of our | 769 // Note that we intentionally only find one matching codec for each of our |
| 778 // local codecs, in case the remote offer contains duplicate codecs. | 770 // local codecs, in case the remote offer contains duplicate codecs. |
| 779 if (FindMatchingCodec(local_codecs, offered_codecs, ours, &theirs)) { | 771 if (FindMatchingCodec(local_codecs, offered_codecs, ours, &theirs)) { |
| 780 C negotiated = ours; | 772 C negotiated = ours; |
| 781 negotiated.IntersectFeedbackParams(theirs); | 773 negotiated.IntersectFeedbackParams(theirs); |
| 782 if (IsRtxCodec(negotiated)) { | 774 if (IsRtxCodec(negotiated)) { |
| 783 std::string offered_apt_value; | 775 const auto apt_it = |
| 784 theirs.GetParam(kCodecParamAssociatedPayloadType, &offered_apt_value); | 776 theirs.params.find(kCodecParamAssociatedPayloadType); |
| 785 // FindMatchingCodec shouldn't return something with no apt value. | 777 // FindMatchingCodec shouldn't return something with no apt value. |
| 786 RTC_DCHECK(!offered_apt_value.empty()); | 778 RTC_DCHECK(apt_it != theirs.params.end()); |
| 787 negotiated.SetParam(kCodecParamAssociatedPayloadType, | 779 negotiated.SetParam(kCodecParamAssociatedPayloadType, apt_it->second); |
| 788 offered_apt_value); | |
| 789 } | 780 } |
| 790 negotiated.id = theirs.id; | 781 negotiated.id = theirs.id; |
| 791 negotiated.name = theirs.name; | 782 negotiated.name = theirs.name; |
| 792 negotiated_codecs->push_back(negotiated); | 783 negotiated_codecs->push_back(std::move(negotiated)); |
| 793 } | 784 } |
| 794 } | 785 } |
| 795 // RFC3264: Although the answerer MAY list the formats in their desired | 786 // RFC3264: Although the answerer MAY list the formats in their desired |
| 796 // order of preference, it is RECOMMENDED that unless there is a | 787 // order of preference, it is RECOMMENDED that unless there is a |
| 797 // specific reason, the answerer list formats in the same relative order | 788 // specific reason, the answerer list formats in the same relative order |
| 798 // they were present in the offer. | 789 // they were present in the offer. |
| 799 std::unordered_map<int, int> payload_type_preferences; | 790 std::unordered_map<int, int> payload_type_preferences; |
| 800 int preference = static_cast<int>(offered_codecs.size() + 1); | 791 int preference = static_cast<int>(offered_codecs.size() + 1); |
| 801 for (const C& codec : offered_codecs) { | 792 for (const C& codec : offered_codecs) { |
| 802 payload_type_preferences[codec.id] = preference--; | 793 payload_type_preferences[codec.id] = preference--; |
| 803 } | 794 } |
| 804 std::sort(negotiated_codecs->begin(), negotiated_codecs->end(), | 795 std::sort(negotiated_codecs->begin(), negotiated_codecs->end(), |
| 805 [&payload_type_preferences](const C& a, const C& b) { | 796 [&payload_type_preferences](const C& a, const C& b) { |
| 806 return payload_type_preferences[a.id] > | 797 return payload_type_preferences[a.id] > |
| 807 payload_type_preferences[b.id]; | 798 payload_type_preferences[b.id]; |
| 808 }); | 799 }); |
| 809 } | 800 } |
| 810 | 801 |
| 811 // Finds a codec in |codecs2| that matches |codec_to_match|, which is | 802 // Finds a codec in |codecs2| that matches |codec_to_match|, which is |
| 812 // a member of |codecs1|. If |codec_to_match| is an RTX codec, both | 803 // a member of |codecs1|. If |codec_to_match| is an RTX codec, both |
| 813 // the codecs themselves and their associated codecs must match. | 804 // the codecs themselves and their associated codecs must match. |
| 814 template <class C> | 805 template <class C> |
| 815 static bool FindMatchingCodec(const std::vector<C>& codecs1, | 806 static bool FindMatchingCodec(const std::vector<C>& codecs1, |
| 816 const std::vector<C>& codecs2, | 807 const std::vector<C>& codecs2, |
| 817 const C& codec_to_match, | 808 const C& codec_to_match, |
| 818 C* found_codec) { | 809 C* found_codec) { |
| 819 for (const C& potential_match : codecs2) { | 810 for (const C& potential_match : codecs2) { |
| 820 if (potential_match.Matches(codec_to_match)) { | 811 if (potential_match.Matches(codec_to_match)) { |
| 821 if (IsRtxCodec(codec_to_match)) { | 812 if (IsRtxCodec(codec_to_match)) { |
| 822 std::string apt_value_1; | 813 int apt_value_1 = 0; |
| 823 std::string apt_value_2; | 814 int apt_value_2 = 0; |
| 824 if (!codec_to_match.GetParam(kCodecParamAssociatedPayloadType, | 815 if (!codec_to_match.GetParam(kCodecParamAssociatedPayloadType, |
| 825 &apt_value_1) || | 816 &apt_value_1) || |
| 826 !potential_match.GetParam(kCodecParamAssociatedPayloadType, | 817 !potential_match.GetParam(kCodecParamAssociatedPayloadType, |
| 827 &apt_value_2)) { | 818 &apt_value_2)) { |
| 828 LOG(LS_WARNING) << "RTX missing associated payload type."; | 819 LOG(LS_WARNING) << "RTX missing associated payload type."; |
| 829 continue; | 820 continue; |
| 830 } | 821 } |
| 831 if (!ReferencedCodecsMatch(codecs1, apt_value_1, codecs2, | 822 if (!ReferencedCodecsMatch(codecs1, apt_value_1, codecs2, |
| 832 apt_value_2)) { | 823 apt_value_2)) { |
| 833 continue; | 824 continue; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 879 | 870 |
| 880 int associated_pt; | 871 int associated_pt; |
| 881 if (!rtc::FromString(associated_pt_str, &associated_pt)) { | 872 if (!rtc::FromString(associated_pt_str, &associated_pt)) { |
| 882 LOG(LS_WARNING) << "Couldn't convert payload type " << associated_pt_str | 873 LOG(LS_WARNING) << "Couldn't convert payload type " << associated_pt_str |
| 883 << " of RTX codec " << rtx_codec.name | 874 << " of RTX codec " << rtx_codec.name |
| 884 << " to an integer."; | 875 << " to an integer."; |
| 885 continue; | 876 continue; |
| 886 } | 877 } |
| 887 | 878 |
| 888 // Find the associated reference codec for the reference RTX codec. | 879 // Find the associated reference codec for the reference RTX codec. |
| 889 C associated_codec; | 880 const C* associated_codec = |
| 890 if (!FindCodecById(reference_codecs, associated_pt, &associated_codec)) { | 881 FindCodecById(reference_codecs, associated_pt); |
| 882 if (!associated_codec) { |
| 891 LOG(LS_WARNING) << "Couldn't find associated codec with payload type " | 883 LOG(LS_WARNING) << "Couldn't find associated codec with payload type " |
| 892 << associated_pt << " for RTX codec " << rtx_codec.name | 884 << associated_pt << " for RTX codec " << rtx_codec.name |
| 893 << "."; | 885 << "."; |
| 894 continue; | 886 continue; |
| 895 } | 887 } |
| 896 | 888 |
| 897 // Find a codec in the offered list that matches the reference codec. | 889 // Find a codec in the offered list that matches the reference codec. |
| 898 // Its payload type may be different than the reference codec. | 890 // Its payload type may be different than the reference codec. |
| 899 C matching_codec; | 891 C matching_codec; |
| 900 if (!FindMatchingCodec<C>(reference_codecs, *offered_codecs, | 892 if (!FindMatchingCodec<C>(reference_codecs, *offered_codecs, |
| 901 associated_codec, &matching_codec)) { | 893 *associated_codec, &matching_codec)) { |
| 902 LOG(LS_WARNING) << "Couldn't find matching " << associated_codec.name | 894 LOG(LS_WARNING) << "Couldn't find matching " << associated_codec->name |
| 903 << " codec."; | 895 << " codec."; |
| 904 continue; | 896 continue; |
| 905 } | 897 } |
| 906 | 898 |
| 907 rtx_codec.params[kCodecParamAssociatedPayloadType] = | 899 rtx_codec.params[kCodecParamAssociatedPayloadType] = |
| 908 rtc::ToString(matching_codec.id); | 900 rtc::ToString(matching_codec.id); |
| 909 used_pltypes->FindAndSetIdUsed(&rtx_codec); | 901 used_pltypes->FindAndSetIdUsed(&rtx_codec); |
| 910 offered_codecs->push_back(rtx_codec); | 902 offered_codecs->push_back(rtx_codec); |
| 911 } | 903 } |
| 912 } | 904 } |
| (...skipping 1248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2161 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); | 2153 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); |
| 2162 } | 2154 } |
| 2163 | 2155 |
| 2164 DataContentDescription* GetFirstDataContentDescription( | 2156 DataContentDescription* GetFirstDataContentDescription( |
| 2165 SessionDescription* sdesc) { | 2157 SessionDescription* sdesc) { |
| 2166 return static_cast<DataContentDescription*>( | 2158 return static_cast<DataContentDescription*>( |
| 2167 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); | 2159 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); |
| 2168 } | 2160 } |
| 2169 | 2161 |
| 2170 } // namespace cricket | 2162 } // namespace cricket |
| OLD | NEW |