Optimize FindCodecById and ReferencedCodecsMatch

These functions currently copy cricket::Codec classes by value which is
expensive since they contain e.g. std::map<std::string, std::string>
containers with parameters. This CL avoids copying them altogether.

BUG=webrtc:6337

Review-Url: https://codereview.webrtc.org/2493733003
Cr-Commit-Position: refs/heads/master@{#15040}
diff --git a/webrtc/api/webrtcsdp.cc b/webrtc/api/webrtcsdp.cc
index b7ef28e..d78112c 100644
--- a/webrtc/api/webrtcsdp.cc
+++ b/webrtc/api/webrtcsdp.cc
@@ -2438,10 +2438,12 @@
 // with that payload type.
 template <class T>
 T GetCodecWithPayloadType(const std::vector<T>& codecs, int payload_type) {
+  const T* codec = FindCodecById(codecs, payload_type);
+  if (codec)
+    return *codec;
+  // Return empty codec with |payload_type|.
   T ret_val;
-  if (!FindCodecById(codecs, payload_type, &ret_val)) {
-    ret_val.id = payload_type;
-  }
+  ret_val.id = payload_type;
   return ret_val;
 }
 
diff --git a/webrtc/media/base/codec.h b/webrtc/media/base/codec.h
index bfbff23..3bd93a9 100644
--- a/webrtc/media/base/codec.h
+++ b/webrtc/media/base/codec.h
@@ -197,18 +197,14 @@
 };
 
 // Get the codec setting associated with |payload_type|. If there
-// is no codec associated with that payload type it returns false.
+// is no codec associated with that payload type it returns nullptr.
 template <class Codec>
-bool FindCodecById(const std::vector<Codec>& codecs,
-                   int payload_type,
-                   Codec* codec_out) {
+const Codec* FindCodecById(const std::vector<Codec>& codecs, int payload_type) {
   for (const auto& codec : codecs) {
-    if (codec.id == payload_type) {
-      *codec_out = codec;
-      return true;
-    }
+    if (codec.id == payload_type)
+      return &codec;
   }
-  return false;
+  return nullptr;
 }
 
 bool CodecNamesEq(const std::string& name1, const std::string& name2);
diff --git a/webrtc/media/base/rtpdataengine.cc b/webrtc/media/base/rtpdataengine.cc
index 6c3837d..e21aa00 100644
--- a/webrtc/media/base/rtpdataengine.cc
+++ b/webrtc/media/base/rtpdataengine.cc
@@ -225,8 +225,7 @@
     return;
   }
 
-  DataCodec codec;
-  if (!FindCodecById(recv_codecs_, header.payload_type, &codec)) {
+  if (!FindCodecById(recv_codecs_, header.payload_type)) {
     // For bundling, this will be logged for every message.
     // So disable this logging.
     // LOG(LS_WARNING) << "Not receiving packet "
diff --git a/webrtc/pc/mediasession.cc b/webrtc/pc/mediasession.cc
index ebba9ac..cc93a8b 100644
--- a/webrtc/pc/mediasession.cc
+++ b/webrtc/pc/mediasession.cc
@@ -752,20 +752,12 @@
 
 template <class C>
 static bool ReferencedCodecsMatch(const std::vector<C>& codecs1,
-                                  const std::string& codec1_id_str,
+                                  const int codec1_id,
                                   const std::vector<C>& codecs2,
-                                  const std::string& codec2_id_str) {
-  int codec1_id;
-  int codec2_id;
-  C codec1;
-  C codec2;
-  if (!rtc::FromString(codec1_id_str, &codec1_id) ||
-      !rtc::FromString(codec2_id_str, &codec2_id) ||
-      !FindCodecById(codecs1, codec1_id, &codec1) ||
-      !FindCodecById(codecs2, codec2_id, &codec2)) {
-    return false;
-  }
-  return codec1.Matches(codec2);
+                                  const int codec2_id) {
+  const C* codec1 = FindCodecById(codecs1, codec1_id);
+  const C* codec2 = FindCodecById(codecs2, codec2_id);
+  return codec1 != nullptr && codec2 != nullptr && codec1->Matches(*codec2);
 }
 
 template <class C>
@@ -780,16 +772,15 @@
       C negotiated = ours;
       negotiated.IntersectFeedbackParams(theirs);
       if (IsRtxCodec(negotiated)) {
-        std::string offered_apt_value;
-        theirs.GetParam(kCodecParamAssociatedPayloadType, &offered_apt_value);
+        const auto apt_it =
+            theirs.params.find(kCodecParamAssociatedPayloadType);
         // FindMatchingCodec shouldn't return something with no apt value.
-        RTC_DCHECK(!offered_apt_value.empty());
-        negotiated.SetParam(kCodecParamAssociatedPayloadType,
-                            offered_apt_value);
+        RTC_DCHECK(apt_it != theirs.params.end());
+        negotiated.SetParam(kCodecParamAssociatedPayloadType, apt_it->second);
       }
       negotiated.id = theirs.id;
       negotiated.name = theirs.name;
-      negotiated_codecs->push_back(negotiated);
+      negotiated_codecs->push_back(std::move(negotiated));
     }
   }
   // RFC3264: Although the answerer MAY list the formats in their desired
@@ -819,8 +810,8 @@
   for (const C& potential_match : codecs2) {
     if (potential_match.Matches(codec_to_match)) {
       if (IsRtxCodec(codec_to_match)) {
-        std::string apt_value_1;
-        std::string apt_value_2;
+        int apt_value_1 = 0;
+        int apt_value_2 = 0;
         if (!codec_to_match.GetParam(kCodecParamAssociatedPayloadType,
                                      &apt_value_1) ||
             !potential_match.GetParam(kCodecParamAssociatedPayloadType,
@@ -886,8 +877,9 @@
       }
 
       // Find the associated reference codec for the reference RTX codec.
-      C associated_codec;
-      if (!FindCodecById(reference_codecs, associated_pt, &associated_codec)) {
+      const C* associated_codec =
+          FindCodecById(reference_codecs, associated_pt);
+      if (!associated_codec) {
         LOG(LS_WARNING) << "Couldn't find associated codec with payload type "
                         << associated_pt << " for RTX codec " << rtx_codec.name
                         << ".";
@@ -898,8 +890,8 @@
       // Its payload type may be different than the reference codec.
       C matching_codec;
       if (!FindMatchingCodec<C>(reference_codecs, *offered_codecs,
-                               associated_codec, &matching_codec)) {
-        LOG(LS_WARNING) << "Couldn't find matching " << associated_codec.name
+                                *associated_codec, &matching_codec)) {
+        LOG(LS_WARNING) << "Couldn't find matching " << associated_codec->name
                         << " codec.";
         continue;
       }
diff --git a/webrtc/pc/mediasession_unittest.cc b/webrtc/pc/mediasession_unittest.cc
index f23e070..ca1e4b39 100644
--- a/webrtc/pc/mediasession_unittest.cc
+++ b/webrtc/pc/mediasession_unittest.cc
@@ -192,8 +192,7 @@
 
 static void AddRtxCodec(const VideoCodec& rtx_codec,
                         std::vector<VideoCodec>* codecs) {
-  VideoCodec rtx;
-  ASSERT_FALSE(cricket::FindCodecById(*codecs, rtx_codec.id, &rtx));
+  ASSERT_FALSE(cricket::FindCodecById(*codecs, rtx_codec.id));
   codecs->push_back(rtx_codec);
 }