Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: talk/session/media/mediasession.cc

Issue 1616033002: Fixing some issues with payload type mappings. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Log a warning if we can't find the associated codec for an RTX codec. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | talk/session/media/mediasession_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2004 Google Inc. 3 * Copyright 2004 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation 11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution. 12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products 13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28 #include "talk/session/media/mediasession.h" 28 #include "talk/session/media/mediasession.h"
29 29
30 #include <algorithm> // For std::find_if.
30 #include <functional> 31 #include <functional>
31 #include <map> 32 #include <map>
32 #include <set> 33 #include <set>
33 #include <utility> 34 #include <utility>
34 35
35 #include "talk/media/base/constants.h" 36 #include "talk/media/base/constants.h"
36 #include "talk/media/base/cryptoparams.h" 37 #include "talk/media/base/cryptoparams.h"
37 #include "talk/session/media/channelmanager.h" 38 #include "talk/session/media/channelmanager.h"
38 #include "talk/session/media/srtpfilter.h" 39 #include "talk/session/media/srtpfilter.h"
39 #include "webrtc/base/helpers.h" 40 #include "webrtc/base/helpers.h"
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 !FindCodecById(codecs2, codec2_id, &codec2)) { 812 !FindCodecById(codecs2, codec2_id, &codec2)) {
812 return false; 813 return false;
813 } 814 }
814 return codec1.Matches(codec2); 815 return codec1.Matches(codec2);
815 } 816 }
816 817
817 template <class C> 818 template <class C>
818 static void NegotiateCodecs(const std::vector<C>& local_codecs, 819 static void NegotiateCodecs(const std::vector<C>& local_codecs,
819 const std::vector<C>& offered_codecs, 820 const std::vector<C>& offered_codecs,
820 std::vector<C>* negotiated_codecs) { 821 std::vector<C>* negotiated_codecs) {
821 typename std::vector<C>::const_iterator ours; 822 for (const C& ours : local_codecs) {
822 for (ours = local_codecs.begin(); 823 C theirs;
823 ours != local_codecs.end(); ++ours) { 824 if (FindMatchingCodec(local_codecs, offered_codecs, ours, &theirs)) {
824 typename std::vector<C>::const_iterator theirs; 825 C negotiated = ours;
825 for (theirs = offered_codecs.begin(); 826 negotiated.IntersectFeedbackParams(theirs);
826 theirs != offered_codecs.end(); ++theirs) { 827 if (IsRtxCodec(negotiated)) {
827 if (ours->Matches(*theirs)) { 828 std::string offered_apt_value;
828 C negotiated = *ours; 829 theirs.GetParam(kCodecParamAssociatedPayloadType, &offered_apt_value);
829 negotiated.IntersectFeedbackParams(*theirs); 830 // FindMatchingCodec shouldn't return something with no apt value.
830 if (IsRtxCodec(negotiated)) { 831 RTC_DCHECK(!offered_apt_value.empty());
831 std::string offered_apt_value; 832 negotiated.SetParam(kCodecParamAssociatedPayloadType,
832 std::string local_apt_value; 833 offered_apt_value);
833 if (!ours->GetParam(kCodecParamAssociatedPayloadType,
834 &local_apt_value) ||
835 !theirs->GetParam(kCodecParamAssociatedPayloadType,
836 &offered_apt_value)) {
837 LOG(LS_WARNING) << "RTX missing associated payload type.";
838 continue;
839 }
840 // Only negotiate RTX if kCodecParamAssociatedPayloadType has been
841 // set in local and remote codecs, and they match.
842 if (!ReferencedCodecsMatch(local_codecs, local_apt_value,
843 offered_codecs, offered_apt_value)) {
844 LOG(LS_WARNING) << "RTX associated codecs don't match.";
845 continue;
846 }
847 negotiated.SetParam(kCodecParamAssociatedPayloadType,
848 offered_apt_value);
849 }
850
851 negotiated.id = theirs->id;
852 // RFC3264: Although the answerer MAY list the formats in their desired
853 // order of preference, it is RECOMMENDED that unless there is a
854 // specific reason, the answerer list formats in the same relative order
855 // they were present in the offer.
856 negotiated.preference = theirs->preference;
857 negotiated_codecs->push_back(negotiated);
858 } 834 }
835 negotiated.id = theirs.id;
836 // RFC3264: Although the answerer MAY list the formats in their desired
837 // order of preference, it is RECOMMENDED that unless there is a
838 // specific reason, the answerer list formats in the same relative order
839 // they were present in the offer.
840 negotiated.preference = theirs.preference;
841 negotiated_codecs->push_back(negotiated);
859 } 842 }
860 } 843 }
861 } 844 }
862 845
846 // Finds a codec in |codecs2| that matches |codec_to_match|, which is
847 // a member of |codecs1|. If |codec_to_match| is an RTX codec, both
848 // the codecs themselves and their associated codecs must match.
863 template <class C> 849 template <class C>
864 static bool FindMatchingCodec(const std::vector<C>& codecs, 850 static bool FindMatchingCodec(const std::vector<C>& codecs1,
851 const std::vector<C>& codecs2,
865 const C& codec_to_match, 852 const C& codec_to_match,
866 C* found_codec) { 853 C* found_codec) {
867 for (typename std::vector<C>::const_iterator it = codecs.begin(); 854 for (const C& potential_match : codecs2) {
868 it != codecs.end(); ++it) { 855 if (potential_match.Matches(codec_to_match)) {
869 if (it->Matches(codec_to_match)) { 856 if (IsRtxCodec(codec_to_match)) {
870 if (found_codec != NULL) { 857 std::string apt_value_1;
871 *found_codec= *it; 858 std::string apt_value_2;
859 if (!codec_to_match.GetParam(kCodecParamAssociatedPayloadType,
860 &apt_value_1) ||
861 !potential_match.GetParam(kCodecParamAssociatedPayloadType,
862 &apt_value_2)) {
863 LOG(LS_WARNING) << "RTX missing associated payload type.";
864 continue;
865 }
866 if (!ReferencedCodecsMatch(codecs1, apt_value_1, codecs2,
867 apt_value_2)) {
868 LOG(LS_INFO) << "RTX associated codecs don't match.";
pthatcher1 2016/02/26 21:30:14 Since this is FindMatchingCodec, LS_INFO here seem
Taylor Brandstetter 2016/03/04 16:12:23 It was strong even before (in fact I changed it fr
869 continue;
870 }
871 }
872 if (found_codec) {
873 *found_codec = potential_match;
872 } 874 }
873 return true; 875 return true;
874 } 876 }
875 } 877 }
876 return false; 878 return false;
877 } 879 }
878 880
879 // Adds all codecs from |reference_codecs| to |offered_codecs| that dont' 881 // Adds all codecs from |reference_codecs| to |offered_codecs| that dont'
880 // already exist in |offered_codecs| and ensure the payload types don't 882 // already exist in |offered_codecs| and ensure the payload types don't
881 // collide. 883 // collide.
882 template <class C> 884 template <class C>
883 static void FindCodecsToOffer( 885 static void FindCodecsToOffer(
884 const std::vector<C>& reference_codecs, 886 const std::vector<C>& reference_codecs,
885 std::vector<C>* offered_codecs, 887 std::vector<C>* offered_codecs,
886 UsedPayloadTypes* used_pltypes) { 888 UsedPayloadTypes* used_pltypes) {
887 889
888 typedef std::map<int, C> RtxCodecReferences;
889 RtxCodecReferences new_rtx_codecs;
890
891 // Find all new RTX codecs.
892 for (typename std::vector<C>::const_iterator it = reference_codecs.begin();
893 it != reference_codecs.end(); ++it) {
894 if (!FindMatchingCodec<C>(*offered_codecs, *it, NULL) && IsRtxCodec(*it)) {
895 C rtx_codec = *it;
896 int referenced_pl_type =
897 rtc::FromString<int>(0,
898 rtx_codec.params[kCodecParamAssociatedPayloadType]);
899 new_rtx_codecs.insert(std::pair<int, C>(referenced_pl_type,
900 rtx_codec));
901 }
902 }
903
904 // Add all new codecs that are not RTX codecs. 890 // Add all new codecs that are not RTX codecs.
905 for (typename std::vector<C>::const_iterator it = reference_codecs.begin(); 891 for (const C& reference_codec : reference_codecs) {
906 it != reference_codecs.end(); ++it) { 892 if (!IsRtxCodec(reference_codec) &&
907 if (!FindMatchingCodec<C>(*offered_codecs, *it, NULL) && !IsRtxCodec(*it)) { 893 !FindMatchingCodec<C>(reference_codecs, *offered_codecs,
908 C codec = *it; 894 reference_codec, nullptr)) {
909 int original_payload_id = codec.id; 895 C codec = reference_codec;
910 used_pltypes->FindAndSetIdUsed(&codec); 896 used_pltypes->FindAndSetIdUsed(&codec);
911 offered_codecs->push_back(codec); 897 offered_codecs->push_back(codec);
912
913 // If this codec is referenced by a new RTX codec, update the reference
914 // in the RTX codec with the new payload type.
915 typename RtxCodecReferences::iterator rtx_it =
916 new_rtx_codecs.find(original_payload_id);
917 if (rtx_it != new_rtx_codecs.end()) {
918 C& rtx_codec = rtx_it->second;
919 rtx_codec.params[kCodecParamAssociatedPayloadType] =
920 rtc::ToString(codec.id);
921 }
922 } 898 }
923 } 899 }
924 900
925 // Add all new RTX codecs. 901 // Add all new RTX codecs.
926 for (typename RtxCodecReferences::iterator it = new_rtx_codecs.begin(); 902 for (const C& reference_codec : reference_codecs) {
927 it != new_rtx_codecs.end(); ++it) { 903 if (IsRtxCodec(reference_codec) &&
928 C& rtx_codec = it->second; 904 !FindMatchingCodec<C>(reference_codecs, *offered_codecs,
929 used_pltypes->FindAndSetIdUsed(&rtx_codec); 905 reference_codec, nullptr)) {
930 offered_codecs->push_back(rtx_codec); 906 C rtx_codec = reference_codec;
907
908 std::string associated_pt_str;
909 if (!rtx_codec.GetParam(kCodecParamAssociatedPayloadType,
910 &associated_pt_str)) {
911 LOG(LS_WARNING) << "RTX codec " << rtx_codec.name
912 << " is missing an associated payload type.";
913 continue;
914 }
915
916 int associated_pt;
917 if (!rtc::FromString(associated_pt_str, &associated_pt)) {
918 LOG(LS_WARNING) << "Couldn't convert payload type " << associated_pt_str
919 << " of RTX codec " << rtx_codec.name
920 << " to an integer.";
921 continue;
922 }
923
924 // Find the associated reference codec for the reference RTX codec.
925 C associated_codec;
926 if (!FindCodecById(reference_codecs, associated_pt, &associated_codec)) {
927 LOG(LS_WARNING) << "Couldn't find associated codec with payload type "
928 << associated_pt << " for RTX codec " << rtx_codec.name
929 << ".";
930 continue;
931 }
932
933 // Find a codec in the offered list that matches the reference codec.
934 // Its payload type may be different than the reference codec.
935 C matching_codec;
936 if (!FindMatchingCodec<C>(reference_codecs, *offered_codecs,
937 associated_codec, &matching_codec)) {
938 LOG(LS_WARNING) << "Couldn't find matching " << associated_codec.name
939 << " codec.";
940 continue;
941 }
942
943 rtx_codec.params[kCodecParamAssociatedPayloadType] =
944 rtc::ToString(matching_codec.id);
945 used_pltypes->FindAndSetIdUsed(&rtx_codec);
946 offered_codecs->push_back(rtx_codec);
947 }
931 } 948 }
932 } 949 }
933 950
934 951
935 static bool FindByUri(const RtpHeaderExtensions& extensions, 952 static bool FindByUri(const RtpHeaderExtensions& extensions,
936 const RtpHeaderExtension& ext_to_match, 953 const RtpHeaderExtension& ext_to_match,
937 RtpHeaderExtension* found_extension) { 954 RtpHeaderExtension* found_extension) {
938 for (RtpHeaderExtensions::const_iterator it = extensions.begin(); 955 for (RtpHeaderExtensions::const_iterator it = extensions.begin();
939 it != extensions.end(); ++it) { 956 it != extensions.end(); ++it) {
940 // We assume that all URIs are given in a canonical format. 957 // We assume that all URIs are given in a canonical format.
(...skipping 1046 matching lines...) Expand 10 before | Expand all | Expand 10 after
1987 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO)); 2004 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_VIDEO));
1988 } 2005 }
1989 2006
1990 const DataContentDescription* GetFirstDataContentDescription( 2007 const DataContentDescription* GetFirstDataContentDescription(
1991 const SessionDescription* sdesc) { 2008 const SessionDescription* sdesc) {
1992 return static_cast<const DataContentDescription*>( 2009 return static_cast<const DataContentDescription*>(
1993 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA)); 2010 GetFirstMediaContentDescription(sdesc, MEDIA_TYPE_DATA));
1994 } 2011 }
1995 2012
1996 } // namespace cricket 2013 } // namespace cricket
OLDNEW
« no previous file with comments | « no previous file | talk/session/media/mediasession_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698