Remove references to AudioCodec and VideoCodec constructors

The preferred method to create codecs is to use the function
cricket::CreateAudioCodec or cricketCreateVideoCodec.
Empty codec objects are deprecated and should be replaced
with alternatives such as methods returning an
absl::optional object instead.

Bug: webrtc:15214
Change-Id: I7fe40f64673cd407830dbbb0e541b85a3aee93aa
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/307521
Commit-Queue: Florent Castelli <orphis@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40226}
diff --git a/api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h b/api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h
index c10fda4..b16989c 100644
--- a/api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h
+++ b/api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h
@@ -24,7 +24,7 @@
 
   static std::unique_ptr<VideoEncoder> CreateEncoder(
       const SdpVideoFormat& format) {
-    return VP9Encoder::Create(cricket::VideoCodec(format));
+    return VP9Encoder::Create(cricket::CreateVideoCodec(format));
   }
 
   static bool IsScalabilityModeSupported(ScalabilityMode scalability_mode) {
diff --git a/api/video_codecs/video_encoder_factory_template_open_h264_adapter.h b/api/video_codecs/video_encoder_factory_template_open_h264_adapter.h
index 0830460c..6995b27 100644
--- a/api/video_codecs/video_encoder_factory_template_open_h264_adapter.h
+++ b/api/video_codecs/video_encoder_factory_template_open_h264_adapter.h
@@ -31,7 +31,7 @@
   static std::unique_ptr<VideoEncoder> CreateEncoder(
       const SdpVideoFormat& format) {
 #if defined(WEBRTC_USE_H264)
-    return H264Encoder::Create(cricket::VideoCodec(format));
+    return H264Encoder::Create(cricket::CreateVideoCodec(format));
 #else
     return nullptr;
 #endif
diff --git a/media/base/codec.cc b/media/base/codec.cc
index 73b93c6..a707a48 100644
--- a/media/base/codec.cc
+++ b/media/base/codec.cc
@@ -396,7 +396,10 @@
 
 VideoCodec CreateVideoRtxCodec(int rtx_payload_type,
                                int associated_payload_type) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
   VideoCodec rtx_codec(rtx_payload_type, kRtxCodecName);
+#pragma clang diagnostic pop
   rtx_codec.SetParam(kCodecParamAssociatedPayloadType, associated_payload_type);
   return rtx_codec;
 }
@@ -500,15 +503,31 @@
                             const std::string& name,
                             int clockrate,
                             size_t channels) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
   return AudioCodec(id, name, clockrate, 0, channels);
+#pragma clang diagnostic pop
 }
 
 VideoCodec CreateVideoCodec(const std::string& name) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
   return VideoCodec(name);
+#pragma clang diagnostic pop
 }
 
 VideoCodec CreateVideoCodec(int id, const std::string& name) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
   return VideoCodec(id, name);
+#pragma clang diagnostic pop
+}
+
+VideoCodec CreateVideoCodec(const webrtc::SdpVideoFormat& c) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+  return VideoCodec(c);
+#pragma clang diagnostic pop
 }
 
 }  // namespace cricket
diff --git a/media/base/codec.h b/media/base/codec.h
index 29ebef7..34f4506 100644
--- a/media/base/codec.h
+++ b/media/base/codec.h
@@ -168,13 +168,14 @@
 
 struct AudioCodec : public Codec {
   // Creates a codec with the given parameters.
-  AudioCodec(int id,
-             const std::string& name,
-             int clockrate,
-             int unused_bitrate,
-             size_t channels);
+  [[deprecated("Use cricket::CreateAudioCodec")]] AudioCodec(
+      int id,
+      const std::string& name,
+      int clockrate,
+      int unused_bitrate,
+      size_t channels);
   // Creates an empty codec.
-  AudioCodec();
+  [[deprecated("Do not create empty AudioCodec")]] AudioCodec();
   AudioCodec(const AudioCodec& c);
   AudioCodec(AudioCodec&& c);
   ~AudioCodec() override = default;
@@ -185,13 +186,16 @@
 
 struct RTC_EXPORT VideoCodec : public Codec {
   // Creates a codec with the given parameters.
-  VideoCodec(int id, const std::string& name);
+  [[deprecated("Use cricket::CreateVideoCodec")]] VideoCodec(
+      int id,
+      const std::string& name);
   // Creates a codec with the given name and empty id.
-  explicit VideoCodec(const std::string& name);
+  [[deprecated("Use cricket::CreateVideoCodec")]] explicit VideoCodec(
+      const std::string& name);
   // Creates an empty codec.
-  VideoCodec();
+  [[deprecated("Do not create empty VideoCodec")]] VideoCodec();
   VideoCodec(const VideoCodec& c);
-  explicit VideoCodec(const webrtc::SdpVideoFormat& c);
+  [[deprecated]] explicit VideoCodec(const webrtc::SdpVideoFormat& c);
   VideoCodec(VideoCodec&& c);
   ~VideoCodec() override = default;
 
@@ -221,6 +225,7 @@
                             size_t channels);
 VideoCodec CreateVideoCodec(const std::string& name);
 VideoCodec CreateVideoCodec(int id, const std::string& name);
+VideoCodec CreateVideoCodec(const webrtc::SdpVideoFormat& c);
 VideoCodec CreateVideoRtxCodec(int rtx_payload_type,
                                int associated_payload_type);
 
diff --git a/media/base/codec_unittest.cc b/media/base/codec_unittest.cc
index e6205cc..0d405be 100644
--- a/media/base/codec_unittest.cc
+++ b/media/base/codec_unittest.cc
@@ -69,21 +69,24 @@
 }
 
 TEST(CodecTest, TestAudioCodecOperators) {
-  AudioCodec c0(96, "A", 44100, 20000, 2);
-  AudioCodec c1(95, "A", 44100, 20000, 2);
-  AudioCodec c2(96, "x", 44100, 20000, 2);
-  AudioCodec c3(96, "A", 48000, 20000, 2);
-  AudioCodec c4(96, "A", 44100, 10000, 2);
+  AudioCodec c0 = cricket::CreateAudioCodec(96, "A", 44100, 2);
+  AudioCodec c1 = cricket::CreateAudioCodec(95, "A", 44100, 2);
+  AudioCodec c2 = cricket::CreateAudioCodec(96, "x", 44100, 2);
+  AudioCodec c3 = cricket::CreateAudioCodec(96, "A", 48000, 2);
+  AudioCodec c4 = cricket::CreateAudioCodec(96, "A", 44100, 2);
   c4.bitrate = 10000;
-  AudioCodec c5(96, "A", 44100, 20000, 1);
+  AudioCodec c5 = cricket::CreateAudioCodec(96, "A", 44100, 1);
   EXPECT_NE(c0, c1);
   EXPECT_NE(c0, c2);
   EXPECT_NE(c0, c3);
   EXPECT_NE(c0, c4);
   EXPECT_NE(c0, c5);
 
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
   AudioCodec c7;
-  AudioCodec c8(0, "", 0, 0, 0);
+#pragma clang diagnostic pop
+  AudioCodec c8 = cricket::CreateAudioCodec(0, "", 0, 0);
   AudioCodec c9 = c0;
   EXPECT_EQ(c8, c7);
   EXPECT_NE(c9, c7);
@@ -108,59 +111,62 @@
 
 TEST(CodecTest, TestAudioCodecMatches) {
   // Test a codec with a static payload type.
-  AudioCodec c0(34, "A", 44100, 20000, 1);
-  EXPECT_TRUE(c0.Matches(AudioCodec(34, "", 44100, 20000, 1)));
-  EXPECT_TRUE(c0.Matches(AudioCodec(34, "", 44100, 20000, 0)));
-  EXPECT_TRUE(c0.Matches(AudioCodec(34, "", 44100, 0, 0)));
-  EXPECT_TRUE(c0.Matches(AudioCodec(34, "", 0, 0, 0)));
-  EXPECT_FALSE(c0.Matches(AudioCodec(96, "A", 44100, 20000, 1)));
-  EXPECT_FALSE(c0.Matches(AudioCodec(96, "", 44100, 20000, 1)));
-  EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 55100, 20000, 1)));
-  EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 44100, 30000, 1)));
-  EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 44100, 20000, 2)));
-  EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 55100, 30000, 2)));
+  AudioCodec c0 = cricket::CreateAudioCodec(34, "A", 44100, 1);
+  EXPECT_TRUE(c0.Matches(cricket::CreateAudioCodec(34, "", 44100, 1)));
+  EXPECT_TRUE(c0.Matches(cricket::CreateAudioCodec(34, "", 44100, 0)));
+  EXPECT_TRUE(c0.Matches(cricket::CreateAudioCodec(34, "", 44100, 0)));
+  EXPECT_TRUE(c0.Matches(cricket::CreateAudioCodec(34, "", 0, 0)));
+  EXPECT_FALSE(c0.Matches(cricket::CreateAudioCodec(96, "A", 44100, 1)));
+  EXPECT_FALSE(c0.Matches(cricket::CreateAudioCodec(96, "", 44100, 1)));
+  EXPECT_FALSE(c0.Matches(cricket::CreateAudioCodec(95, "", 55100, 1)));
+  EXPECT_FALSE(c0.Matches(cricket::CreateAudioCodec(95, "", 44100, 1)));
+  EXPECT_FALSE(c0.Matches(cricket::CreateAudioCodec(95, "", 44100, 2)));
+  EXPECT_FALSE(c0.Matches(cricket::CreateAudioCodec(95, "", 55100, 2)));
 
   // Test a codec with a dynamic payload type.
-  AudioCodec c1(96, "A", 44100, 20000, 1);
-  EXPECT_TRUE(c1.Matches(AudioCodec(96, "A", 0, 0, 0)));
-  EXPECT_TRUE(c1.Matches(AudioCodec(97, "A", 0, 0, 0)));
-  EXPECT_TRUE(c1.Matches(AudioCodec(96, "a", 0, 0, 0)));
-  EXPECT_TRUE(c1.Matches(AudioCodec(97, "a", 0, 0, 0)));
-  EXPECT_TRUE(c1.Matches(AudioCodec(35, "a", 0, 0, 0)));
-  EXPECT_TRUE(c1.Matches(AudioCodec(42, "a", 0, 0, 0)));
-  EXPECT_TRUE(c1.Matches(AudioCodec(65, "a", 0, 0, 0)));
-  EXPECT_FALSE(c1.Matches(AudioCodec(95, "A", 0, 0, 0)));
-  EXPECT_FALSE(c1.Matches(AudioCodec(34, "A", 0, 0, 0)));
-  EXPECT_FALSE(c1.Matches(AudioCodec(96, "", 44100, 20000, 2)));
-  EXPECT_FALSE(c1.Matches(AudioCodec(96, "A", 55100, 30000, 1)));
+  AudioCodec c1 = cricket::CreateAudioCodec(96, "A", 44100, 1);
+  EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(96, "A", 0, 0)));
+  EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(97, "A", 0, 0)));
+  EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(96, "a", 0, 0)));
+  EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(97, "a", 0, 0)));
+  EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(35, "a", 0, 0)));
+  EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(42, "a", 0, 0)));
+  EXPECT_TRUE(c1.Matches(cricket::CreateAudioCodec(65, "a", 0, 0)));
+  EXPECT_FALSE(c1.Matches(cricket::CreateAudioCodec(95, "A", 0, 0)));
+  EXPECT_FALSE(c1.Matches(cricket::CreateAudioCodec(34, "A", 0, 0)));
+  EXPECT_FALSE(c1.Matches(cricket::CreateAudioCodec(96, "", 44100, 2)));
+  EXPECT_FALSE(c1.Matches(cricket::CreateAudioCodec(96, "A", 55100, 1)));
 
   // Test a codec with a dynamic payload type, and auto bitrate.
-  AudioCodec c2(97, "A", 16000, 0, 1);
+  AudioCodec c2 = cricket::CreateAudioCodec(97, "A", 16000, 1);
   // Use default bitrate.
-  EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, 0, 1)));
-  EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, 0, 0)));
+  EXPECT_TRUE(c2.Matches(cricket::CreateAudioCodec(97, "A", 16000, 1)));
+  EXPECT_TRUE(c2.Matches(cricket::CreateAudioCodec(97, "A", 16000, 0)));
   // Use explicit bitrate.
-  EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, 32000, 1)));
+  EXPECT_TRUE(c2.Matches(cricket::CreateAudioCodec(97, "A", 16000, 1)));
   // Backward compatibility with clients that might send "-1" (for default).
-  EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, -1, 1)));
+  EXPECT_TRUE(c2.Matches(cricket::CreateAudioCodec(97, "A", 16000, 1)));
 
   // Stereo doesn't match channels = 0.
-  AudioCodec c3(96, "A", 44100, 20000, 2);
-  EXPECT_TRUE(c3.Matches(AudioCodec(96, "A", 44100, 20000, 2)));
-  EXPECT_FALSE(c3.Matches(AudioCodec(96, "A", 44100, 20000, 1)));
-  EXPECT_FALSE(c3.Matches(AudioCodec(96, "A", 44100, 20000, 0)));
+  AudioCodec c3 = cricket::CreateAudioCodec(96, "A", 44100, 2);
+  EXPECT_TRUE(c3.Matches(cricket::CreateAudioCodec(96, "A", 44100, 2)));
+  EXPECT_FALSE(c3.Matches(cricket::CreateAudioCodec(96, "A", 44100, 1)));
+  EXPECT_FALSE(c3.Matches(cricket::CreateAudioCodec(96, "A", 44100, 0)));
 }
 
 TEST(CodecTest, TestVideoCodecOperators) {
-  VideoCodec c0(96, "V");
-  VideoCodec c1(95, "V");
-  VideoCodec c2(96, "x");
+  VideoCodec c0 = cricket::CreateVideoCodec(96, "V");
+  VideoCodec c1 = cricket::CreateVideoCodec(95, "V");
+  VideoCodec c2 = cricket::CreateVideoCodec(96, "x");
 
   EXPECT_TRUE(c0 != c1);
   EXPECT_TRUE(c0 != c2);
 
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
   VideoCodec c7;
-  VideoCodec c8(0, "");
+#pragma clang diagnostic pop
+  VideoCodec c8 = cricket::CreateVideoCodec(0, "");
   VideoCodec c9 = c0;
   EXPECT_TRUE(c8 == c7);
   EXPECT_TRUE(c9 != c7);
@@ -184,9 +190,9 @@
 }
 
 TEST(CodecTest, TestVideoCodecEqualsWithDifferentPacketization) {
-  VideoCodec c0(100, cricket::kVp8CodecName);
-  VideoCodec c1(100, cricket::kVp8CodecName);
-  VideoCodec c2(100, cricket::kVp8CodecName);
+  VideoCodec c0 = cricket::CreateVideoCodec(100, cricket::kVp8CodecName);
+  VideoCodec c1 = cricket::CreateVideoCodec(100, cricket::kVp8CodecName);
+  VideoCodec c2 = cricket::CreateVideoCodec(100, cricket::kVp8CodecName);
   c2.packetization = "raw";
 
   EXPECT_EQ(c0, c1);
@@ -197,28 +203,28 @@
 
 TEST(CodecTest, TestVideoCodecMatches) {
   // Test a codec with a static payload type.
-  VideoCodec c0(34, "V");
-  EXPECT_TRUE(c0.Matches(VideoCodec(34, "")));
-  EXPECT_FALSE(c0.Matches(VideoCodec(96, "")));
-  EXPECT_FALSE(c0.Matches(VideoCodec(96, "V")));
+  VideoCodec c0 = cricket::CreateVideoCodec(34, "V");
+  EXPECT_TRUE(c0.Matches(cricket::CreateVideoCodec(34, "")));
+  EXPECT_FALSE(c0.Matches(cricket::CreateVideoCodec(96, "")));
+  EXPECT_FALSE(c0.Matches(cricket::CreateVideoCodec(96, "V")));
 
   // Test a codec with a dynamic payload type.
-  VideoCodec c1(96, "V");
-  EXPECT_TRUE(c1.Matches(VideoCodec(96, "V")));
-  EXPECT_TRUE(c1.Matches(VideoCodec(97, "V")));
-  EXPECT_TRUE(c1.Matches(VideoCodec(96, "v")));
-  EXPECT_TRUE(c1.Matches(VideoCodec(97, "v")));
-  EXPECT_TRUE(c1.Matches(VideoCodec(35, "v")));
-  EXPECT_TRUE(c1.Matches(VideoCodec(42, "v")));
-  EXPECT_TRUE(c1.Matches(VideoCodec(65, "v")));
-  EXPECT_FALSE(c1.Matches(VideoCodec(96, "")));
-  EXPECT_FALSE(c1.Matches(VideoCodec(95, "V")));
-  EXPECT_FALSE(c1.Matches(VideoCodec(34, "V")));
+  VideoCodec c1 = cricket::CreateVideoCodec(96, "V");
+  EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(96, "V")));
+  EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(97, "V")));
+  EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(96, "v")));
+  EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(97, "v")));
+  EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(35, "v")));
+  EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(42, "v")));
+  EXPECT_TRUE(c1.Matches(cricket::CreateVideoCodec(65, "v")));
+  EXPECT_FALSE(c1.Matches(cricket::CreateVideoCodec(96, "")));
+  EXPECT_FALSE(c1.Matches(cricket::CreateVideoCodec(95, "V")));
+  EXPECT_FALSE(c1.Matches(cricket::CreateVideoCodec(34, "V")));
 }
 
 TEST(CodecTest, TestVideoCodecMatchesWithDifferentPacketization) {
-  VideoCodec c0(100, cricket::kVp8CodecName);
-  VideoCodec c1(101, cricket::kVp8CodecName);
+  VideoCodec c0 = cricket::CreateVideoCodec(100, cricket::kVp8CodecName);
+  VideoCodec c1 = cricket::CreateVideoCodec(101, cricket::kVp8CodecName);
   c1.packetization = "raw";
 
   EXPECT_TRUE(c0.Matches(c1));
@@ -231,12 +237,13 @@
   const char kProfile1[] = "1";
   const char kProfile2[] = "2";
 
-  VideoCodec c_no_profile(95, cricket::kAv1CodecName);
-  VideoCodec c_profile0(95, cricket::kAv1CodecName);
+  VideoCodec c_no_profile =
+      cricket::CreateVideoCodec(95, cricket::kAv1CodecName);
+  VideoCodec c_profile0 = cricket::CreateVideoCodec(95, cricket::kAv1CodecName);
   c_profile0.params[webrtc::kAV1FmtpProfile] = kProfile0;
-  VideoCodec c_profile1(95, cricket::kAv1CodecName);
+  VideoCodec c_profile1 = cricket::CreateVideoCodec(95, cricket::kAv1CodecName);
   c_profile1.params[webrtc::kAV1FmtpProfile] = kProfile1;
-  VideoCodec c_profile2(95, cricket::kAv1CodecName);
+  VideoCodec c_profile2 = cricket::CreateVideoCodec(95, cricket::kAv1CodecName);
   c_profile2.params[webrtc::kAV1FmtpProfile] = kProfile2;
 
   // An AV1 entry with no profile specified should be treated as profile-0.
@@ -244,20 +251,23 @@
 
   {
     // Two AV1 entries without a profile specified are treated as duplicates.
-    VideoCodec c_no_profile_eq(95, cricket::kAv1CodecName);
+    VideoCodec c_no_profile_eq =
+        cricket::CreateVideoCodec(95, cricket::kAv1CodecName);
     EXPECT_TRUE(c_no_profile.Matches(c_no_profile_eq));
   }
 
   {
     // Two AV1 entries with profile 0 specified are treated as duplicates.
-    VideoCodec c_profile0_eq(95, cricket::kAv1CodecName);
+    VideoCodec c_profile0_eq =
+        cricket::CreateVideoCodec(95, cricket::kAv1CodecName);
     c_profile0_eq.params[webrtc::kAV1FmtpProfile] = kProfile0;
     EXPECT_TRUE(c_profile0.Matches(c_profile0_eq));
   }
 
   {
     // Two AV1 entries with profile 1 specified are treated as duplicates.
-    VideoCodec c_profile1_eq(95, cricket::kAv1CodecName);
+    VideoCodec c_profile1_eq =
+        cricket::CreateVideoCodec(95, cricket::kAv1CodecName);
     c_profile1_eq.params[webrtc::kAV1FmtpProfile] = kProfile1;
     EXPECT_TRUE(c_profile1.Matches(c_profile1_eq));
   }
@@ -276,27 +286,31 @@
   const char kProfile0[] = "0";
   const char kProfile2[] = "2";
 
-  VideoCodec c_no_profile(95, cricket::kVp9CodecName);
-  VideoCodec c_profile0(95, cricket::kVp9CodecName);
+  VideoCodec c_no_profile =
+      cricket::CreateVideoCodec(95, cricket::kVp9CodecName);
+  VideoCodec c_profile0 = cricket::CreateVideoCodec(95, cricket::kVp9CodecName);
   c_profile0.params[webrtc::kVP9FmtpProfileId] = kProfile0;
 
   EXPECT_TRUE(c_profile0.Matches(c_no_profile));
 
   {
-    VideoCodec c_profile0_eq(95, cricket::kVp9CodecName);
+    VideoCodec c_profile0_eq =
+        cricket::CreateVideoCodec(95, cricket::kVp9CodecName);
     c_profile0_eq.params[webrtc::kVP9FmtpProfileId] = kProfile0;
     EXPECT_TRUE(c_profile0.Matches(c_profile0_eq));
   }
 
   {
-    VideoCodec c_profile2(95, cricket::kVp9CodecName);
+    VideoCodec c_profile2 =
+        cricket::CreateVideoCodec(95, cricket::kVp9CodecName);
     c_profile2.params[webrtc::kVP9FmtpProfileId] = kProfile2;
     EXPECT_FALSE(c_profile0.Matches(c_profile2));
     EXPECT_FALSE(c_no_profile.Matches(c_profile2));
   }
 
   {
-    VideoCodec c_no_profile_eq(95, cricket::kVp9CodecName);
+    VideoCodec c_no_profile_eq =
+        cricket::CreateVideoCodec(95, cricket::kVp9CodecName);
     EXPECT_TRUE(c_no_profile.Matches(c_no_profile_eq));
   }
 }
@@ -307,12 +321,12 @@
   const char kProfileLevelId1[] = "42e01f";
   const char kProfileLevelId2[] = "42a01e";
 
-  VideoCodec pli_1_pm_0(95, "H264");
+  VideoCodec pli_1_pm_0 = cricket::CreateVideoCodec(95, "H264");
   pli_1_pm_0.params[cricket::kH264FmtpProfileLevelId] = kProfileLevelId1;
   pli_1_pm_0.params[cricket::kH264FmtpPacketizationMode] = "0";
 
   {
-    VideoCodec pli_1_pm_blank(95, "H264");
+    VideoCodec pli_1_pm_blank = cricket::CreateVideoCodec(95, "H264");
     pli_1_pm_blank.params[cricket::kH264FmtpProfileLevelId] = kProfileLevelId1;
     pli_1_pm_blank.params.erase(
         pli_1_pm_blank.params.find(cricket::kH264FmtpPacketizationMode));
@@ -322,7 +336,7 @@
   }
 
   {
-    VideoCodec pli_1_pm_1(95, "H264");
+    VideoCodec pli_1_pm_1 = cricket::CreateVideoCodec(95, "H264");
     pli_1_pm_1.params[cricket::kH264FmtpProfileLevelId] = kProfileLevelId1;
     pli_1_pm_1.params[cricket::kH264FmtpPacketizationMode] = "1";
 
@@ -331,7 +345,7 @@
   }
 
   {
-    VideoCodec pli_2_pm_0(95, "H264");
+    VideoCodec pli_2_pm_0 = cricket::CreateVideoCodec(95, "H264");
     pli_2_pm_0.params[cricket::kH264FmtpProfileLevelId] = kProfileLevelId2;
     pli_2_pm_0.params[cricket::kH264FmtpPacketizationMode] = "0";
 
@@ -382,11 +396,11 @@
 
 TEST(CodecTest, TestGetCodecType) {
   // Codec type comparison should be case insenstive on names.
-  const VideoCodec codec(96, "V");
-  const VideoCodec rtx_codec(96, "rTx");
-  const VideoCodec ulpfec_codec(96, "ulpFeC");
-  const VideoCodec flexfec_codec(96, "FlExFeC-03");
-  const VideoCodec red_codec(96, "ReD");
+  const VideoCodec codec = cricket::CreateVideoCodec(96, "V");
+  const VideoCodec rtx_codec = cricket::CreateVideoCodec(96, "rTx");
+  const VideoCodec ulpfec_codec = cricket::CreateVideoCodec(96, "ulpFeC");
+  const VideoCodec flexfec_codec = cricket::CreateVideoCodec(96, "FlExFeC-03");
+  const VideoCodec red_codec = cricket::CreateVideoCodec(96, "ReD");
   EXPECT_TRUE(codec.IsMediaCodec());
   EXPECT_EQ(codec.GetResiliencyType(), Codec::ResiliencyType::kNone);
   EXPECT_EQ(rtx_codec.GetResiliencyType(), Codec::ResiliencyType::kRtx);
@@ -406,7 +420,7 @@
 }
 
 TEST(CodecTest, TestValidateCodecFormat) {
-  const VideoCodec codec(96, "V");
+  const VideoCodec codec = cricket::CreateVideoCodec(96, "V");
   ASSERT_TRUE(codec.ValidateCodecFormat());
 
   // Accept 0-127 as payload types.
@@ -447,7 +461,7 @@
 }
 
 TEST(CodecTest, TestToCodecParameters) {
-  VideoCodec v(96, "V");
+  VideoCodec v = cricket::CreateVideoCodec(96, "V");
   v.SetParam("p1", "v1");
   webrtc::RtpCodecParameters codec_params_1 = v.ToCodecParameters();
   EXPECT_EQ(96, codec_params_1.payload_type);
@@ -459,7 +473,7 @@
   EXPECT_EQ("p1", codec_params_1.parameters.begin()->first);
   EXPECT_EQ("v1", codec_params_1.parameters.begin()->second);
 
-  AudioCodec a(97, "A", 44100, 20000, 2);
+  AudioCodec a = cricket::CreateAudioCodec(97, "A", 44100, 2);
   a.SetParam("p1", "a1");
   webrtc::RtpCodecParameters codec_params_2 = a.ToCodecParameters();
   EXPECT_EQ(97, codec_params_2.payload_type);
diff --git a/media/base/fake_media_engine.cc b/media/base/fake_media_engine.cc
index 3e8a29b..5e4ecd3 100644
--- a/media/base/fake_media_engine.cc
+++ b/media/base/fake_media_engine.cc
@@ -317,12 +317,11 @@
 bool FakeVideoMediaChannel::RemoveSendStream(uint32_t ssrc) {
   return RtpHelper<VideoMediaChannel>::RemoveSendStream(ssrc);
 }
-bool FakeVideoMediaChannel::GetSendCodec(VideoCodec* send_codec) {
+absl::optional<VideoCodec> FakeVideoMediaChannel::GetSendCodec() {
   if (send_codecs_.empty()) {
-    return false;
+    return absl::nullopt;
   }
-  *send_codec = send_codecs_[0];
-  return true;
+  return send_codecs_[0];
 }
 bool FakeVideoMediaChannel::SetSink(
     uint32_t ssrc,
@@ -444,7 +443,7 @@
 FakeVoiceEngine::FakeVoiceEngine() : fail_create_channel_(false) {
   // Add a fake audio codec. Note that the name must not be "" as there are
   // sanity checks against that.
-  SetCodecs({AudioCodec(101, "fake_audio_codec", 8000, 0, 1)});
+  SetCodecs({cricket::CreateAudioCodec(101, "fake_audio_codec", 8000, 1)});
 }
 void FakeVoiceEngine::Init() {}
 rtc::scoped_refptr<webrtc::AudioState> FakeVoiceEngine::GetAudioState() const {
@@ -544,8 +543,8 @@
     : capture_(false), fail_create_channel_(false) {
   // Add a fake video codec. Note that the name must not be "" as there are
   // sanity checks against that.
-  send_codecs_.push_back(VideoCodec(111, "fake_video_codec"));
-  recv_codecs_.push_back(VideoCodec(111, "fake_video_codec"));
+  send_codecs_.push_back(cricket::CreateVideoCodec(111, "fake_video_codec"));
+  recv_codecs_.push_back(cricket::CreateVideoCodec(111, "fake_video_codec"));
 }
 bool FakeVideoEngine::SetOptions(const VideoOptions& options) {
   options_ = options;
diff --git a/media/base/fake_media_engine.h b/media/base/fake_media_engine.h
index 74128cb..26fe276 100644
--- a/media/base/fake_media_engine.h
+++ b/media/base/fake_media_engine.h
@@ -489,7 +489,7 @@
   bool AddSendStream(const StreamParams& sp) override;
   bool RemoveSendStream(uint32_t ssrc) override;
 
-  bool GetSendCodec(VideoCodec* send_codec) override;
+  absl::optional<VideoCodec> GetSendCodec() override;
   bool SetSink(uint32_t ssrc,
                rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) override;
   void SetDefaultSink(
diff --git a/media/base/media_channel.h b/media/base/media_channel.h
index 58e35f3..f23df8b 100644
--- a/media/base/media_channel.h
+++ b/media/base/media_channel.h
@@ -939,7 +939,7 @@
  public:
   virtual bool SetSendParameters(const VideoSendParameters& params) = 0;
   // Gets the currently set codecs/payload types to be used for outgoing media.
-  virtual bool GetSendCodec(VideoCodec* send_codec) = 0;
+  virtual absl::optional<VideoCodec> GetSendCodec() = 0;
   // Starts or stops transmission (and potentially capture) of local video.
   virtual bool SetSend(bool send) = 0;
   // Configure stream for sending and register a source.
diff --git a/media/base/media_channel_impl.h b/media/base/media_channel_impl.h
index 411576a..5a76708 100644
--- a/media/base/media_channel_impl.h
+++ b/media/base/media_channel_impl.h
@@ -669,8 +669,8 @@
   bool SetSendParameters(const VideoSendParameters& params) override {
     return impl()->SetSendParameters(params);
   }
-  bool GetSendCodec(VideoCodec* send_codec) override {
-    return impl()->GetSendCodec(send_codec);
+  absl::optional<VideoCodec> GetSendCodec() override {
+    return impl()->GetSendCodec();
   }
   bool SetSend(bool send) override { return impl()->SetSend(send); }
   bool SetVideoSend(
diff --git a/media/base/media_channel_shim.h b/media/base/media_channel_shim.h
index 679e15c..4c5e9da 100644
--- a/media/base/media_channel_shim.h
+++ b/media/base/media_channel_shim.h
@@ -397,8 +397,8 @@
   bool SetSendParameters(const VideoSendParameters& params) override {
     return send_impl()->SetSendParameters(params);
   }
-  bool GetSendCodec(VideoCodec* send_codec) override {
-    return send_impl()->GetSendCodec(send_codec);
+  absl::optional<VideoCodec> GetSendCodec() override {
+    return send_impl()->GetSendCodec();
   }
   bool SetSend(bool send) override { return send_impl()->SetSend(send); }
   bool SetVideoSend(
diff --git a/media/engine/fake_webrtc_video_engine.cc b/media/engine/fake_webrtc_video_engine.cc
index d10e618..77d92d7 100644
--- a/media/engine/fake_webrtc_video_engine.cc
+++ b/media/engine/fake_webrtc_video_engine.cc
@@ -119,7 +119,7 @@
 void FakeWebRtcVideoDecoderFactory::AddSupportedVideoCodecType(
     const std::string& name) {
   // This is to match the default H264 params of cricket::VideoCodec.
-  cricket::VideoCodec video_codec(name);
+  cricket::VideoCodec video_codec = cricket::CreateVideoCodec(name);
   supported_codec_formats_.push_back(
       webrtc::SdpVideoFormat(video_codec.name, video_codec.params));
 }
@@ -284,7 +284,7 @@
 void FakeWebRtcVideoEncoderFactory::AddSupportedVideoCodecType(
     const std::string& name) {
   // This is to match the default H264 params of cricket::VideoCodec.
-  cricket::VideoCodec video_codec(name);
+  cricket::VideoCodec video_codec = cricket::CreateVideoCodec(name);
   formats_.push_back(
       webrtc::SdpVideoFormat(video_codec.name, video_codec.params));
 }
diff --git a/media/engine/multiplex_codec_factory.cc b/media/engine/multiplex_codec_factory.cc
index 660c359..90df02a 100644
--- a/media/engine/multiplex_codec_factory.cc
+++ b/media/engine/multiplex_codec_factory.cc
@@ -59,7 +59,7 @@
 
 std::unique_ptr<VideoEncoder> MultiplexEncoderFactory::CreateVideoEncoder(
     const SdpVideoFormat& format) {
-  if (!IsMultiplexCodec(cricket::VideoCodec(format)))
+  if (!IsMultiplexCodec(cricket::CreateVideoCodec(format)))
     return factory_->CreateVideoEncoder(format);
   const auto& it =
       format.parameters.find(cricket::kCodecParamAssociatedCodecName);
@@ -97,7 +97,7 @@
 
 std::unique_ptr<VideoDecoder> MultiplexDecoderFactory::CreateVideoDecoder(
     const SdpVideoFormat& format) {
-  if (!IsMultiplexCodec(cricket::VideoCodec(format)))
+  if (!IsMultiplexCodec(cricket::CreateVideoCodec(format)))
     return factory_->CreateVideoDecoder(format);
   const auto& it =
       format.parameters.find(cricket::kCodecParamAssociatedCodecName);
diff --git a/media/engine/payload_type_mapper.cc b/media/engine/payload_type_mapper.cc
index 66c48a7..bd86453 100644
--- a/media/engine/payload_type_mapper.cc
+++ b/media/engine/payload_type_mapper.cc
@@ -14,6 +14,7 @@
 
 #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 {
@@ -130,8 +131,9 @@
   // ACM or NetEq.
   auto opt_payload_type = GetMappingFor(format);
   if (opt_payload_type) {
-    AudioCodec codec(*opt_payload_type, format.name, format.clockrate_hz, 0,
-                     format.num_channels);
+    AudioCodec codec =
+        cricket::CreateAudioCodec(*opt_payload_type, format.name,
+                                  format.clockrate_hz, format.num_channels);
     codec.params = format.parameters;
     return std::move(codec);
   }
diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc
index 825b2aa..971cee3 100644
--- a/media/engine/webrtc_video_engine.cc
+++ b/media/engine/webrtc_video_engine.cc
@@ -220,7 +220,7 @@
 
   std::vector<VideoCodec> output_codecs;
   for (const webrtc::SdpVideoFormat& format : supported_formats) {
-    VideoCodec codec(format);
+    VideoCodec codec = cricket::CreateVideoCodec(format);
     bool isFecCodec = absl::EqualsIgnoreCase(codec.name, kUlpfecCodecName) ||
                       absl::EqualsIgnoreCase(codec.name, kFlexfecCodecName);
 
@@ -597,8 +597,7 @@
       }
 
       case Codec::ResiliencyType::kNone: {
-        video_codecs.emplace_back();
-        video_codecs.back().codec = in_codec;
+        video_codecs.emplace_back(in_codec);
         break;
       }
     }
@@ -1513,14 +1512,13 @@
   SetReceiverReportSsrc(*choices.begin());
 }
 
-bool WebRtcVideoSendChannel::GetSendCodec(VideoCodec* codec) {
+absl::optional<VideoCodec> WebRtcVideoSendChannel::GetSendCodec() {
   RTC_DCHECK_RUN_ON(&thread_checker_);
   if (!send_codec()) {
     RTC_LOG(LS_VERBOSE) << "GetSendCodec: No send codec set.";
-    return false;
+    return absl::nullopt;
   }
-  *codec = send_codec()->codec;
-  return true;
+  return send_codec()->codec;
 }
 
 void WebRtcVideoReceiveChannel::SetReceive(bool receive) {
@@ -3692,8 +3690,8 @@
   stream_->UpdateRtxSsrc(ssrc);
 }
 
-VideoCodecSettings::VideoCodecSettings()
-    : flexfec_payload_type(-1), rtx_payload_type(-1) {}
+VideoCodecSettings::VideoCodecSettings(const VideoCodec& codec)
+    : codec(codec), flexfec_payload_type(-1), rtx_payload_type(-1) {}
 
 bool VideoCodecSettings::operator==(const VideoCodecSettings& other) const {
   return codec == other.codec && ulpfec == other.ulpfec &&
diff --git a/media/engine/webrtc_video_engine.h b/media/engine/webrtc_video_engine.h
index 3e22604..3635c21 100644
--- a/media/engine/webrtc_video_engine.h
+++ b/media/engine/webrtc_video_engine.h
@@ -146,7 +146,7 @@
 };
 
 struct VideoCodecSettings {
-  VideoCodecSettings();
+  explicit VideoCodecSettings(const VideoCodec& codec);
 
   // Checks if all members of |*this| are equal to the corresponding members
   // of `other`.
@@ -207,7 +207,7 @@
       const webrtc::RtpParameters& parameters,
       webrtc::SetParametersCallback callback) override;
   webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const override;
-  bool GetSendCodec(VideoCodec* send_codec) override;
+  absl::optional<VideoCodec> GetSendCodec() override;
   bool SetSend(bool send) override;
   bool SetVideoSend(
       uint32_t ssrc,
diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc
index ec9de84..97ed730 100644
--- a/media/engine/webrtc_video_engine_unittest.cc
+++ b/media/engine/webrtc_video_engine_unittest.cc
@@ -401,7 +401,7 @@
   std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
       video_bitrate_allocator_factory_;
   WebRtcVideoEngine engine_;
-  VideoCodec default_codec_;
+  absl::optional<VideoCodec> default_codec_;
   std::map<int, int> default_apt_rtx_types_;
 };
 
@@ -416,7 +416,7 @@
     int associated_payload_type;
     EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
                                           &associated_payload_type));
-    EXPECT_EQ(default_codec_.id, associated_payload_type);
+    EXPECT_EQ(default_codec_->id, associated_payload_type);
     return;
   }
   FAIL() << "No RTX codec found among default codecs.";
@@ -722,15 +722,16 @@
   // Now search for RTX codecs for them. Expect that they all have associated
   // RTX codecs.
   EXPECT_TRUE(HasRtxCodec(
-      codecs,
-      FindMatchingCodec(codecs, cricket::VideoCodec(h264_constrained_baseline))
-          ->id));
+      codecs, FindMatchingCodec(
+                  codecs, cricket::CreateVideoCodec(h264_constrained_baseline))
+                  ->id));
+  EXPECT_TRUE(HasRtxCodec(
+      codecs, FindMatchingCodec(
+                  codecs, cricket::CreateVideoCodec(h264_constrained_high))
+                  ->id));
   EXPECT_TRUE(HasRtxCodec(
       codecs,
-      FindMatchingCodec(codecs, cricket::VideoCodec(h264_constrained_high))
-          ->id));
-  EXPECT_TRUE(HasRtxCodec(
-      codecs, FindMatchingCodec(codecs, cricket::VideoCodec(h264_high))->id));
+      FindMatchingCodec(codecs, cricket::CreateVideoCodec(h264_high))->id));
 }
 
 #if defined(RTC_ENABLE_VP9)
@@ -1975,7 +1976,7 @@
     }
     // This point should never be reached.
     ADD_FAILURE() << "Unrecognized codec name: " << name;
-    return cricket::VideoCodec();
+    return cricket::CreateVideoCodec(0, "");
   }
 
   cricket::VideoCodec DefaultCodec() { return GetEngineCodec("VP8"); }
@@ -2546,22 +2547,24 @@
   parameters.codecs.push_back(GetEngineCodec("VP8"));
   EXPECT_TRUE(channel_->SetSendParameters(parameters));
 
-  VideoCodec codec;
-  ASSERT_TRUE(channel_->GetSendCodec(&codec));
-  EXPECT_EQ("VP9", codec.name);
+  absl::optional<VideoCodec> codec = channel_->GetSendCodec();
+  ASSERT_TRUE(codec);
+  EXPECT_EQ("VP9", codec->name);
 
   // RequestEncoderFallback will post a task to the worker thread (which is also
   // the current thread), hence the ProcessMessages call.
   SendImpl()->RequestEncoderFallback();
   time_controller_.AdvanceTime(kFrameDuration);
-  ASSERT_TRUE(channel_->GetSendCodec(&codec));
-  EXPECT_EQ("VP8", codec.name);
+  codec = channel_->GetSendCodec();
+  ASSERT_TRUE(codec);
+  EXPECT_EQ("VP8", codec->name);
 
   // No other codec to fall back to, keep using VP8.
   SendImpl()->RequestEncoderFallback();
   time_controller_.AdvanceTime(kFrameDuration);
-  ASSERT_TRUE(channel_->GetSendCodec(&codec));
-  EXPECT_EQ("VP8", codec.name);
+  codec = channel_->GetSendCodec();
+  ASSERT_TRUE(codec);
+  EXPECT_EQ("VP8", codec->name);
 }
 
 TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderSwitchDefaultFallback) {
@@ -2570,9 +2573,9 @@
   parameters.codecs.push_back(GetEngineCodec("VP8"));
   EXPECT_TRUE(channel_->SetSendParameters(parameters));
 
-  VideoCodec codec;
-  ASSERT_TRUE(channel_->GetSendCodec(&codec));
-  EXPECT_EQ("VP9", codec.name);
+  absl::optional<VideoCodec> codec = channel_->GetSendCodec();
+  ASSERT_TRUE(codec);
+  EXPECT_EQ("VP9", codec->name);
 
   // RequestEncoderSwitch will post a task to the worker thread (which is also
   // the current thread), hence the ProcessMessages call.
@@ -2582,8 +2585,9 @@
 
   // Requested encoder is not available. Default fallback is allowed. Switch to
   // the next negotiated codec, VP8.
-  ASSERT_TRUE(channel_->GetSendCodec(&codec));
-  EXPECT_EQ("VP8", codec.name);
+  codec = channel_->GetSendCodec();
+  ASSERT_TRUE(codec);
+  EXPECT_EQ("VP8", codec->name);
 }
 
 TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderSwitchStrictPreference) {
@@ -2595,9 +2599,9 @@
   parameters.codecs.push_back(vp9);
   EXPECT_TRUE(channel_->SetSendParameters(parameters));
 
-  VideoCodec codec;
-  ASSERT_TRUE(channel_->GetSendCodec(&codec));
-  EXPECT_EQ("VP8", codec.name);
+  absl::optional<VideoCodec> codec = channel_->GetSendCodec();
+  ASSERT_TRUE(codec);
+  EXPECT_EQ("VP8", codec->name);
 
   SendImpl()->RequestEncoderSwitch(
       webrtc::SdpVideoFormat("VP9", {{"profile-id", "1"}}),
@@ -2606,8 +2610,9 @@
 
   // VP9 profile_id=1 is not available. Default fallback is not allowed. Switch
   // is not performed.
-  ASSERT_TRUE(channel_->GetSendCodec(&codec));
-  EXPECT_EQ("VP8", codec.name);
+  codec = channel_->GetSendCodec();
+  ASSERT_TRUE(codec);
+  EXPECT_EQ("VP8", codec->name);
 
   SendImpl()->RequestEncoderSwitch(
       webrtc::SdpVideoFormat("VP9", {{"profile-id", "0"}}),
@@ -2615,8 +2620,9 @@
   time_controller_.AdvanceTime(kFrameDuration);
 
   // VP9 profile_id=0 is available. Switch encoder.
-  ASSERT_TRUE(channel_->GetSendCodec(&codec));
-  EXPECT_EQ("VP9", codec.name);
+  codec = channel_->GetSendCodec();
+  ASSERT_TRUE(codec);
+  EXPECT_EQ("VP9", codec->name);
 }
 
 TEST_F(WebRtcVideoChannelBaseTest, SendCodecIsMovedToFrontInRtpParameters) {
@@ -2708,7 +2714,7 @@
     }
     // This point should never be reached.
     ADD_FAILURE() << "Unrecognized codec name: " << name;
-    return cricket::VideoCodec();
+    return cricket::CreateVideoCodec(0, "");
   }
 
   cricket::VideoCodec DefaultCodec() { return GetEngineCodec("VP8"); }
@@ -2875,7 +2881,7 @@
 
   void TestLossNotificationState(bool expect_lntf_enabled) {
     AssignDefaultCodec();
-    VerifyCodecHasDefaultFeedbackParams(default_codec_, expect_lntf_enabled);
+    VerifyCodecHasDefaultFeedbackParams(*default_codec_, expect_lntf_enabled);
 
     cricket::VideoSendParameters parameters;
     parameters.codecs = engine_.send_codecs();
@@ -3328,7 +3334,7 @@
   ResetTest();
 
   AssignDefaultCodec();
-  VerifyCodecHasDefaultFeedbackParams(default_codec_, true);
+  VerifyCodecHasDefaultFeedbackParams(*default_codec_, true);
 
   {
     cricket::VideoSendParameters parameters;
@@ -3366,7 +3372,7 @@
 
 TEST_F(WebRtcVideoChannelTest, NackIsEnabledByDefault) {
   AssignDefaultCodec();
-  VerifyCodecHasDefaultFeedbackParams(default_codec_, false);
+  VerifyCodecHasDefaultFeedbackParams(*default_codec_, false);
 
   cricket::VideoSendParameters parameters;
   parameters.codecs = engine_.send_codecs();
@@ -4290,9 +4296,9 @@
   AssignDefaultAptRtxTypes();
   ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
 
-  VideoCodec codec;
-  EXPECT_TRUE(channel_->GetSendCodec(&codec));
-  EXPECT_TRUE(codec.Matches(engine_.send_codecs()[0], &field_trials_));
+  absl::optional<VideoCodec> codec = channel_->GetSendCodec();
+  ASSERT_TRUE(codec);
+  EXPECT_TRUE(codec->Matches(engine_.send_codecs()[0], &field_trials_));
 
   // Using a RTX setup to verify that the default RTX payload type is good.
   const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
@@ -4662,7 +4668,8 @@
   EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType));
 
   cricket::VideoSendParameters parameters;
-  cricket::VideoCodec rtx_codec(kUnusedPayloadType, "rtx");
+  cricket::VideoCodec rtx_codec =
+      cricket::CreateVideoCodec(kUnusedPayloadType, "rtx");
   parameters.codecs.push_back(rtx_codec);
   EXPECT_FALSE(channel_->SetSendParameters(parameters))
       << "RTX codec without associated payload type should be rejected.";
@@ -4708,7 +4715,8 @@
   // Original payload type for RTX.
   cricket::VideoSendParameters parameters;
   parameters.codecs.push_back(GetEngineCodec("VP8"));
-  cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
+  cricket::VideoCodec rtx_codec =
+      cricket::CreateVideoCodec(kUnusedPayloadType1, "rtx");
   rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
   parameters.codecs.push_back(rtx_codec);
   EXPECT_TRUE(channel_->SetSendParameters(parameters));
@@ -4777,7 +4785,7 @@
 
 TEST_F(WebRtcVideoChannelTest, SetSendCodecsChangesExistingStreams) {
   cricket::VideoSendParameters parameters;
-  cricket::VideoCodec codec(100, "VP8");
+  cricket::VideoCodec codec = cricket::CreateVideoCodec(100, "VP8");
   codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax);
   parameters.codecs.push_back(codec);
 
@@ -5043,9 +5051,9 @@
   EXPECT_EQ(atoi(kMaxQuantization),
             AddSendStream()->GetVideoStreams().back().max_qp);
 
-  VideoCodec codec;
-  EXPECT_TRUE(channel_->GetSendCodec(&codec));
-  EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]);
+  absl::optional<VideoCodec> codec = channel_->GetSendCodec();
+  ASSERT_TRUE(codec);
+  EXPECT_EQ(kMaxQuantization, codec->params[kCodecParamMaxQuantization]);
 }
 
 TEST_F(WebRtcVideoChannelTest, SetSendCodecsRejectBadPayloadTypes) {
@@ -5105,7 +5113,8 @@
 
   cricket::VideoRecvParameters parameters;
   parameters.codecs.push_back(GetEngineCodec("VP8"));
-  cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
+  cricket::VideoCodec rtx_codec =
+      cricket::CreateVideoCodec(kUnusedPayloadType1, "rtx");
   parameters.codecs.push_back(rtx_codec);
   EXPECT_FALSE(channel_->SetRecvParameters(parameters))
       << "RTX codec without associated payload should be rejected.";
@@ -5117,7 +5126,8 @@
   parameters.codecs[1].SetParam("apt", GetEngineCodec("VP8").id);
   EXPECT_TRUE(channel_->SetRecvParameters(parameters));
 
-  cricket::VideoCodec rtx_codec2(kUnusedPayloadType2, "rtx");
+  cricket::VideoCodec rtx_codec2 =
+      cricket::CreateVideoCodec(kUnusedPayloadType2, "rtx");
   rtx_codec2.SetParam("apt", rtx_codec.id);
   parameters.codecs.push_back(rtx_codec2);
 
@@ -5168,10 +5178,10 @@
 
   cricket::VideoRecvParameters parameters;
   parameters.codecs.push_back(GetEngineCodec("VP8"));
-  parameters.codecs.push_back(
-      cricket::VideoCodec(kFirstUlpfecPayloadType, cricket::kUlpfecCodecName));
-  parameters.codecs.push_back(
-      cricket::VideoCodec(kSecondUlpfecPayloadType, cricket::kUlpfecCodecName));
+  parameters.codecs.push_back(cricket::CreateVideoCodec(
+      kFirstUlpfecPayloadType, cricket::kUlpfecCodecName));
+  parameters.codecs.push_back(cricket::CreateVideoCodec(
+      kSecondUlpfecPayloadType, cricket::kUlpfecCodecName));
   ASSERT_TRUE(channel_->SetRecvParameters(parameters));
 
   FakeVideoReceiveStream* recv_stream = AddRecvStream();
@@ -5186,9 +5196,9 @@
   cricket::VideoRecvParameters parameters;
   parameters.codecs.push_back(GetEngineCodec("VP8"));
   parameters.codecs.push_back(
-      cricket::VideoCodec(kFirstRedPayloadType, cricket::kRedCodecName));
+      cricket::CreateVideoCodec(kFirstRedPayloadType, cricket::kRedCodecName));
   parameters.codecs.push_back(
-      cricket::VideoCodec(kSecondRedPayloadType, cricket::kRedCodecName));
+      cricket::CreateVideoCodec(kSecondRedPayloadType, cricket::kRedCodecName));
   ASSERT_TRUE(channel_->SetRecvParameters(parameters));
 
   FakeVideoReceiveStream* recv_stream = AddRecvStream();
@@ -5211,7 +5221,8 @@
   // Original payload type for RTX.
   cricket::VideoRecvParameters parameters;
   parameters.codecs.push_back(GetEngineCodec("VP8"));
-  cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
+  cricket::VideoCodec rtx_codec =
+      cricket::CreateVideoCodec(kUnusedPayloadType1, "rtx");
   rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
   parameters.codecs.push_back(rtx_codec);
   EXPECT_TRUE(channel_->SetRecvParameters(parameters));
@@ -5254,7 +5265,8 @@
   // Payload type for RTX.
   cricket::VideoRecvParameters parameters;
   parameters.codecs.push_back(GetEngineCodec("VP8"));
-  cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
+  cricket::VideoCodec rtx_codec =
+      cricket::CreateVideoCodec(kUnusedPayloadType1, "rtx");
   rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
   parameters.codecs.push_back(rtx_codec);
   EXPECT_TRUE(channel_->SetRecvParameters(parameters));
@@ -5332,7 +5344,7 @@
 TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectUnsupportedCodec) {
   cricket::VideoRecvParameters parameters;
   parameters.codecs.push_back(GetEngineCodec("VP8"));
-  parameters.codecs.push_back(VideoCodec(101, "WTF3"));
+  parameters.codecs.push_back(cricket::CreateVideoCodec(101, "WTF3"));
   EXPECT_FALSE(channel_->SetRecvParameters(parameters));
 }
 
@@ -7467,7 +7479,7 @@
   parameters.codecs.push_back(GetEngineCodec("VP9"));
 
 #if defined(WEBRTC_USE_H264)
-  cricket::VideoCodec H264codec(126, "H264");
+  cricket::VideoCodec H264codec = cricket::CreateVideoCodec(126, "H264");
   parameters.codecs.push_back(H264codec);
 #endif
 
@@ -7916,7 +7928,7 @@
 TEST_F(WebRtcVideoChannelTest,
        GetAndSetRtpSendParametersScaleResolutionDownByVP8) {
   VideoSendParameters parameters;
-  parameters.codecs.push_back(VideoCodec(kVp8CodecName));
+  parameters.codecs.push_back(cricket::CreateVideoCodec(kVp8CodecName));
   ASSERT_TRUE(channel_->SetSendParameters(parameters));
   FakeVideoSendStream* stream = SetUpSimulcast(true, /*with_rtx=*/false);
 
@@ -8033,7 +8045,7 @@
 
   // Set up WebRtcVideoChannel for 3-layer VP8 simulcast.
   VideoSendParameters parameters;
-  parameters.codecs.push_back(VideoCodec(kVp8CodecName));
+  parameters.codecs.push_back(cricket::CreateVideoCodec(kVp8CodecName));
   ASSERT_TRUE(channel_->SetSendParameters(parameters));
   FakeVideoSendStream* stream = SetUpSimulcast(true, /*with_rtx=*/false);
   webrtc::test::FrameForwarder frame_forwarder;
@@ -8076,7 +8088,7 @@
        GetAndSetRtpSendParametersScaleResolutionDownByH264) {
   encoder_factory_->AddSupportedVideoCodecType(kH264CodecName);
   VideoSendParameters parameters;
-  parameters.codecs.push_back(VideoCodec(kH264CodecName));
+  parameters.codecs.push_back(cricket::CreateVideoCodec(kH264CodecName));
   ASSERT_TRUE(channel_->SetSendParameters(parameters));
   FakeVideoSendStream* stream = SetUpSimulcast(true, /*with_rtx=*/false);
 
@@ -8193,7 +8205,7 @@
   // Set up WebRtcVideoChannel for 3-layer H264 simulcast.
   encoder_factory_->AddSupportedVideoCodecType(kH264CodecName);
   VideoSendParameters parameters;
-  parameters.codecs.push_back(VideoCodec(kH264CodecName));
+  parameters.codecs.push_back(cricket::CreateVideoCodec(kH264CodecName));
   ASSERT_TRUE(channel_->SetSendParameters(parameters));
   FakeVideoSendStream* stream = SetUpSimulcast(true, /*with_rtx=*/false);
   webrtc::test::FrameForwarder frame_forwarder;
@@ -9268,10 +9280,10 @@
 TEST_F(WebRtcVideoChannelTest, DISABLED_GetRtpReceiveFmtpSprop) {
 #endif
   cricket::VideoRecvParameters parameters;
-  cricket::VideoCodec kH264sprop1(101, "H264");
+  cricket::VideoCodec kH264sprop1 = cricket::CreateVideoCodec(101, "H264");
   kH264sprop1.SetParam(kH264FmtpSpropParameterSets, "uvw");
   parameters.codecs.push_back(kH264sprop1);
-  cricket::VideoCodec kH264sprop2(102, "H264");
+  cricket::VideoCodec kH264sprop2 = cricket::CreateVideoCodec(102, "H264");
   kH264sprop2.SetParam(kH264FmtpSpropParameterSets, "xyz");
   parameters.codecs.push_back(kH264sprop2);
   EXPECT_TRUE(channel_->SetRecvParameters(parameters));
@@ -9657,34 +9669,34 @@
 };
 
 TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWith2SimulcastStreams) {
-  VerifySimulcastSettings(cricket::VideoCodec("VP8"), 640, 360, 2, 2, false,
-                          true);
+  VerifySimulcastSettings(cricket::CreateVideoCodec("VP8"), 640, 360, 2, 2,
+                          false, true);
 }
 
 TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWith3SimulcastStreams) {
-  VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3, false,
-                          true);
+  VerifySimulcastSettings(cricket::CreateVideoCodec("VP8"), 1280, 720, 3, 3,
+                          false, true);
 }
 
 // Test that we normalize send codec format size in simulcast.
 TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWithOddSizeInSimulcast) {
-  VerifySimulcastSettings(cricket::VideoCodec("VP8"), 541, 271, 2, 2, false,
-                          true);
+  VerifySimulcastSettings(cricket::CreateVideoCodec("VP8"), 541, 271, 2, 2,
+                          false, true);
 }
 
 TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsForScreenshare) {
-  VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3, true,
-                          false);
+  VerifySimulcastSettings(cricket::CreateVideoCodec("VP8"), 1280, 720, 3, 3,
+                          true, false);
 }
 
 TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsForSimulcastScreenshare) {
-  VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 2, true,
-                          true);
+  VerifySimulcastSettings(cricket::CreateVideoCodec("VP8"), 1280, 720, 3, 2,
+                          true, true);
 }
 
 TEST_F(WebRtcVideoChannelSimulcastTest, SimulcastScreenshareWithoutConference) {
-  VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3, true,
-                          false);
+  VerifySimulcastSettings(cricket::CreateVideoCodec("VP8"), 1280, 720, 3, 3,
+                          true, false);
 }
 
 TEST_F(WebRtcVideoChannelBaseTest, GetSources) {
@@ -9755,9 +9767,9 @@
   EXPECT_TRUE(channel_->SetSendParameters(parameters));
   channel_->SetSend(true);
 
-  VideoCodec codec;
-  ASSERT_TRUE(channel_->GetSendCodec(&codec));
-  EXPECT_EQ("VP8", codec.name);
+  absl::optional<VideoCodec> codec = channel_->GetSendCodec();
+  ASSERT_TRUE(codec);
+  EXPECT_EQ("VP8", codec->name);
 
   webrtc::MockEncoderSelector encoder_selector;
   EXPECT_CALL(encoder_selector, OnAvailableBitrate)
@@ -9766,8 +9778,9 @@
   channel_->SetEncoderSelector(kSsrc, &encoder_selector);
   time_controller_.AdvanceTime(kFrameDuration);
 
-  ASSERT_TRUE(channel_->GetSendCodec(&codec));
-  EXPECT_EQ("VP9", codec.name);
+  codec = channel_->GetSendCodec();
+  ASSERT_TRUE(codec);
+  EXPECT_EQ("VP9", codec->name);
 
   // Deregister the encoder selector in case it's called during test tear-down.
   channel_->SetEncoderSelector(kSsrc, nullptr);
diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc
index 0dc4b7a..79e285d 100644
--- a/media/engine/webrtc_voice_engine.cc
+++ b/media/engine/webrtc_voice_engine.cc
@@ -26,6 +26,7 @@
 #include "absl/algorithm/container.h"
 #include "absl/functional/bind_front.h"
 #include "absl/strings/match.h"
+#include "absl/types/optional.h"
 #include "api/audio/audio_frame.h"
 #include "api/audio/audio_frame_processor.h"
 #include "api/audio_codecs/audio_codec_pair_id.h"
@@ -144,19 +145,16 @@
   return absl::EqualsIgnoreCase(codec.name, ref_name);
 }
 
-bool FindCodec(const std::vector<AudioCodec>& codecs,
-               const AudioCodec& codec,
-               AudioCodec* found_codec,
-               const webrtc::FieldTrialsView* field_trials) {
+absl::optional<AudioCodec> FindCodec(
+    const std::vector<AudioCodec>& codecs,
+    const AudioCodec& codec,
+    const webrtc::FieldTrialsView* field_trials) {
   for (const AudioCodec& c : codecs) {
     if (c.Matches(codec, field_trials)) {
-      if (found_codec != NULL) {
-        *found_codec = c;
-      }
-      return true;
+      return c;
     }
   }
-  return false;
+  return absl::nullopt;
 }
 
 bool VerifyUniquePayloadTypes(const std::vector<AudioCodec>& codecs) {
@@ -1615,12 +1613,12 @@
   for (const AudioCodec& codec : codecs) {
     // Log a warning if a codec's payload type is changing. This used to be
     // treated as an error. It's abnormal, but not really illegal.
-    AudioCodec old_codec;
-    if (FindCodec(recv_codecs_, codec, &old_codec, &call_->trials()) &&
-        old_codec.id != codec.id) {
+    absl::optional<AudioCodec> old_codec =
+        FindCodec(recv_codecs_, codec, &call_->trials());
+    if (old_codec && old_codec->id != codec.id) {
       RTC_LOG(LS_WARNING) << codec.name << " mapped to a second payload type ("
                           << codec.id << ", was already mapped to "
-                          << old_codec.id << ")";
+                          << old_codec->id << ")";
     }
     auto format = AudioCodecToSdpAudioFormat(codec);
     if (!IsCodec(codec, kCnCodecName) && !IsCodec(codec, kDtmfCodecName) &&
diff --git a/media/engine/webrtc_voice_engine_unittest.cc b/media/engine/webrtc_voice_engine_unittest.cc
index 86dc95e..ff6429d 100644
--- a/media/engine/webrtc_voice_engine_unittest.cc
+++ b/media/engine/webrtc_voice_engine_unittest.cc
@@ -23,6 +23,7 @@
 #include "api/task_queue/default_task_queue_factory.h"
 #include "api/transport/field_trial_based_config.h"
 #include "call/call.h"
+#include "media/base/codec.h"
 #include "media/base/fake_media_engine.h"
 #include "media/base/fake_network_interface.h"
 #include "media/base/fake_rtp.h"
@@ -58,23 +59,24 @@
 
 constexpr uint32_t kMaxUnsignaledRecvStreams = 4;
 
-const cricket::AudioCodec kPcmuCodec(0, "PCMU", 8000, 64000, 1);
-const cricket::AudioCodec kOpusCodec(111, "opus", 48000, 32000, 2);
-const cricket::AudioCodec kG722CodecVoE(9, "G722", 16000, 64000, 1);
-const cricket::AudioCodec kG722CodecSdp(9, "G722", 8000, 64000, 1);
-const cricket::AudioCodec kCn8000Codec(13, "CN", 8000, 0, 1);
-const cricket::AudioCodec kCn16000Codec(105, "CN", 16000, 0, 1);
-const cricket::AudioCodec kRed48000Codec(112, "RED", 48000, 32000, 2);
-const cricket::AudioCodec kTelephoneEventCodec1(106,
-                                                "telephone-event",
-                                                8000,
-                                                0,
-                                                1);
-const cricket::AudioCodec kTelephoneEventCodec2(107,
-                                                "telephone-event",
-                                                32000,
-                                                0,
-                                                1);
+const cricket::AudioCodec kPcmuCodec =
+    cricket::CreateAudioCodec(0, "PCMU", 8000, 1);
+const cricket::AudioCodec kOpusCodec =
+    cricket::CreateAudioCodec(111, "opus", 48000, 2);
+const cricket::AudioCodec kG722CodecVoE =
+    cricket::CreateAudioCodec(9, "G722", 16000, 1);
+const cricket::AudioCodec kG722CodecSdp =
+    cricket::CreateAudioCodec(9, "G722", 8000, 1);
+const cricket::AudioCodec kCn8000Codec =
+    cricket::CreateAudioCodec(13, "CN", 8000, 1);
+const cricket::AudioCodec kCn16000Codec =
+    cricket::CreateAudioCodec(105, "CN", 16000, 1);
+const cricket::AudioCodec kRed48000Codec =
+    cricket::CreateAudioCodec(112, "RED", 48000, 2);
+const cricket::AudioCodec kTelephoneEventCodec1 =
+    cricket::CreateAudioCodec(106, "telephone-event", 8000, 1);
+const cricket::AudioCodec kTelephoneEventCodec2 =
+    cricket::CreateAudioCodec(107, "telephone-event", 32000, 1);
 
 const uint32_t kSsrc0 = 0;
 const uint32_t kSsrc1 = 1;
@@ -908,7 +910,7 @@
   EXPECT_TRUE(SetupChannel());
   cricket::AudioRecvParameters parameters;
   parameters.codecs.push_back(kOpusCodec);
-  parameters.codecs.push_back(cricket::AudioCodec(127, "XYZ", 32000, 0, 1));
+  parameters.codecs.push_back(cricket::CreateAudioCodec(127, "XYZ", 32000, 1));
   EXPECT_FALSE(channel_->SetRecvParameters(parameters));
 }
 
@@ -3869,7 +3871,7 @@
       webrtc::CryptoOptions(), call.get(), webrtc::AudioCodecPairId::Create());
   {
     cricket::AudioSendParameters params;
-    params.codecs.push_back(cricket::AudioCodec(1, "opus", 48000, 32000, 2));
+    params.codecs.push_back(cricket::CreateAudioCodec(1, "opus", 48000, 2));
     params.extensions.push_back(webrtc::RtpExtension(
         webrtc::RtpExtension::kTransportSequenceNumberUri, 1));
     EXPECT_TRUE(channel.SetSendParameters(params));
@@ -3933,7 +3935,8 @@
     // Rather than just ASSERTing that there are enough codecs, ensure that we
     // can check the actual values safely, to provide better test results.
     auto get_codec = [&codecs](size_t index) -> const cricket::AudioCodec& {
-      static const cricket::AudioCodec missing_codec(0, "<missing>", 0, 0, 0);
+      static const cricket::AudioCodec missing_codec =
+          cricket::CreateAudioCodec(0, "<missing>", 0, 0);
       if (codecs.size() > index)
         return codecs[index];
       return missing_codec;
diff --git a/modules/video_coding/codecs/h264/h264_encoder_impl_unittest.cc b/modules/video_coding/codecs/h264/h264_encoder_impl_unittest.cc
index 52d2695..3a139ab 100644
--- a/modules/video_coding/codecs/h264/h264_encoder_impl_unittest.cc
+++ b/modules/video_coding/codecs/h264/h264_encoder_impl_unittest.cc
@@ -39,7 +39,7 @@
 }
 
 TEST(H264EncoderImplTest, CanInitializeWithDefaultParameters) {
-  H264EncoderImpl encoder(cricket::VideoCodec("H264"));
+  H264EncoderImpl encoder(cricket::CreateVideoCodec("H264"));
   VideoCodec codec_settings;
   SetDefaultSettings(&codec_settings);
   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
@@ -49,7 +49,7 @@
 }
 
 TEST(H264EncoderImplTest, CanInitializeWithNonInterleavedModeExplicitly) {
-  cricket::VideoCodec codec("H264");
+  cricket::VideoCodec codec = cricket::CreateVideoCodec("H264");
   codec.SetParam(cricket::kH264FmtpPacketizationMode, "1");
   H264EncoderImpl encoder(codec);
   VideoCodec codec_settings;
@@ -61,7 +61,7 @@
 }
 
 TEST(H264EncoderImplTest, CanInitializeWithSingleNalUnitModeExplicitly) {
-  cricket::VideoCodec codec("H264");
+  cricket::VideoCodec codec = cricket::CreateVideoCodec("H264");
   codec.SetParam(cricket::kH264FmtpPacketizationMode, "0");
   H264EncoderImpl encoder(codec);
   VideoCodec codec_settings;
@@ -73,7 +73,7 @@
 }
 
 TEST(H264EncoderImplTest, CanInitializeWithRemovedParameter) {
-  cricket::VideoCodec codec("H264");
+  cricket::VideoCodec codec = cricket::CreateVideoCodec("H264");
   codec.RemoveParam(cricket::kH264FmtpPacketizationMode);
   H264EncoderImpl encoder(codec);
   VideoCodec codec_settings;
diff --git a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
index a74dfa4..3bf165f 100644
--- a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
+++ b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc
@@ -17,6 +17,8 @@
 #include "api/video_codecs/video_encoder.h"
 #include "api/video_codecs/vp9_profile.h"
 #include "common_video/libyuv/include/webrtc_libyuv.h"
+#include "media/base/codec.h"
+#include "media/base/media_constants.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "modules/video_coding/codecs/interface/libvpx_interface.h"
 #include "modules/video_coding/codecs/interface/mock_libvpx_interface.h"
@@ -2038,7 +2040,8 @@
   }
 
   std::unique_ptr<VideoEncoder> CreateEncoder() override {
-    cricket::VideoCodec profile2_codec;
+    cricket::VideoCodec profile2_codec =
+        cricket::CreateVideoCodec(cricket::kVp9CodecName);
     profile2_codec.SetParam(kVP9FmtpProfileId,
                             VP9ProfileToString(VP9Profile::kProfile2));
     return VP9Encoder::Create(profile2_codec);
@@ -2219,7 +2222,7 @@
   // Keep a raw pointer for EXPECT calls and the like. Ownership is otherwise
   // passed on to LibvpxVp9Encoder.
   auto* const vpx = new NiceMock<MockLibvpxInterface>();
-  LibvpxVp9Encoder encoder(cricket::VideoCodec(),
+  LibvpxVp9Encoder encoder(cricket::CreateVideoCodec(cricket::kVp9CodecName),
                            absl::WrapUnique<LibvpxInterface>(vpx), trials);
 
   VideoCodec settings = DefaultCodecSettings();
@@ -2263,7 +2266,7 @@
   // Keep a raw pointer for EXPECT calls and the like. Ownership is otherwise
   // passed on to LibvpxVp9Encoder.
   auto* const vpx = new NiceMock<MockLibvpxInterface>();
-  LibvpxVp9Encoder encoder(cricket::VideoCodec(),
+  LibvpxVp9Encoder encoder(cricket::CreateVideoCodec(cricket::kVp9CodecName),
                            absl::WrapUnique<LibvpxInterface>(vpx), trials);
 
   VideoCodec settings = DefaultCodecSettings();
@@ -2321,7 +2324,7 @@
   // Keep a raw pointer for EXPECT calls and the like. Ownership is otherwise
   // passed on to LibvpxVp9Encoder.
   auto* const vpx = new NiceMock<MockLibvpxInterface>();
-  LibvpxVp9Encoder encoder(cricket::VideoCodec(),
+  LibvpxVp9Encoder encoder(cricket::CreateVideoCodec(cricket::kVp9CodecName),
                            absl::WrapUnique<LibvpxInterface>(vpx), trials);
 
   VideoCodec settings = DefaultCodecSettings();
diff --git a/pc/channel_unittest.cc b/pc/channel_unittest.cc
index e50f954..06da2f0 100644
--- a/pc/channel_unittest.cc
+++ b/pc/channel_unittest.cc
@@ -57,11 +57,15 @@
 using webrtc::SdpType;
 
 namespace {
-const cricket::AudioCodec kPcmuCodec(0, "PCMU", 64000, 8000, 1);
-const cricket::AudioCodec kPcmaCodec(8, "PCMA", 64000, 8000, 1);
-const cricket::AudioCodec kIsacCodec(103, "ISAC", 40000, 16000, 1);
-const cricket::VideoCodec kH264Codec(97, "H264");
-const cricket::VideoCodec kH264SvcCodec(99, "H264-SVC");
+const cricket::AudioCodec kPcmuCodec =
+    cricket::CreateAudioCodec(0, "PCMU", 64000, 1);
+const cricket::AudioCodec kPcmaCodec =
+    cricket::CreateAudioCodec(8, "PCMA", 64000, 1);
+const cricket::AudioCodec kIsacCodec =
+    cricket::CreateAudioCodec(103, "ISAC", 40000, 1);
+const cricket::VideoCodec kH264Codec = cricket::CreateVideoCodec(97, "H264");
+const cricket::VideoCodec kH264SvcCodec =
+    cricket::CreateVideoCodec(99, "H264-SVC");
 const uint32_t kSsrc1 = 0x1111;
 const uint32_t kSsrc2 = 0x2222;
 const uint32_t kSsrc3 = 0x3333;
@@ -2096,8 +2100,8 @@
 }
 
 TEST_F(VideoChannelSingleThreadTest, TestSetLocalOfferWithPacketization) {
-  const cricket::VideoCodec kVp8Codec(97, "VP8");
-  cricket::VideoCodec vp9_codec(98, "VP9");
+  const cricket::VideoCodec kVp8Codec = cricket::CreateVideoCodec(97, "VP8");
+  cricket::VideoCodec vp9_codec = cricket::CreateVideoCodec(98, "VP9");
   vp9_codec.packetization = cricket::kPacketizationParamRaw;
   cricket::VideoContentDescription video;
   video.set_codecs({kVp8Codec, vp9_codec});
@@ -2119,8 +2123,8 @@
 }
 
 TEST_F(VideoChannelSingleThreadTest, TestSetRemoteOfferWithPacketization) {
-  const cricket::VideoCodec kVp8Codec(97, "VP8");
-  cricket::VideoCodec vp9_codec(98, "VP9");
+  const cricket::VideoCodec kVp8Codec = cricket::CreateVideoCodec(97, "VP8");
+  cricket::VideoCodec vp9_codec = cricket::CreateVideoCodec(98, "VP9");
   vp9_codec.packetization = cricket::kPacketizationParamRaw;
   cricket::VideoContentDescription video;
   video.set_codecs({kVp8Codec, vp9_codec});
@@ -2143,8 +2147,8 @@
 }
 
 TEST_F(VideoChannelSingleThreadTest, TestSetAnswerWithPacketization) {
-  const cricket::VideoCodec kVp8Codec(97, "VP8");
-  cricket::VideoCodec vp9_codec(98, "VP9");
+  const cricket::VideoCodec kVp8Codec = cricket::CreateVideoCodec(97, "VP8");
+  cricket::VideoCodec vp9_codec = cricket::CreateVideoCodec(98, "VP9");
   vp9_codec.packetization = cricket::kPacketizationParamRaw;
   cricket::VideoContentDescription video;
   video.set_codecs({kVp8Codec, vp9_codec});
@@ -2177,8 +2181,8 @@
 }
 
 TEST_F(VideoChannelSingleThreadTest, TestSetLocalAnswerWithoutPacketization) {
-  const cricket::VideoCodec kLocalCodec(98, "VP8");
-  cricket::VideoCodec remote_codec(99, "VP8");
+  const cricket::VideoCodec kLocalCodec = cricket::CreateVideoCodec(98, "VP8");
+  cricket::VideoCodec remote_codec = cricket::CreateVideoCodec(99, "VP8");
   remote_codec.packetization = cricket::kPacketizationParamRaw;
   cricket::VideoContentDescription local_video;
   local_video.set_codecs({kLocalCodec});
@@ -2199,9 +2203,9 @@
 }
 
 TEST_F(VideoChannelSingleThreadTest, TestSetRemoteAnswerWithoutPacketization) {
-  cricket::VideoCodec local_codec(98, "VP8");
+  cricket::VideoCodec local_codec = cricket::CreateVideoCodec(98, "VP8");
   local_codec.packetization = cricket::kPacketizationParamRaw;
-  const cricket::VideoCodec kRemoteCodec(99, "VP8");
+  const cricket::VideoCodec kRemoteCodec = cricket::CreateVideoCodec(99, "VP8");
   cricket::VideoContentDescription local_video;
   local_video.set_codecs({local_codec});
   cricket::VideoContentDescription remote_video;
@@ -2223,9 +2227,9 @@
 
 TEST_F(VideoChannelSingleThreadTest,
        TestSetRemoteAnswerWithInvalidPacketization) {
-  cricket::VideoCodec local_codec(98, "VP8");
+  cricket::VideoCodec local_codec = cricket::CreateVideoCodec(98, "VP8");
   local_codec.packetization = cricket::kPacketizationParamRaw;
-  cricket::VideoCodec remote_codec(99, "VP8");
+  cricket::VideoCodec remote_codec = cricket::CreateVideoCodec(99, "VP8");
   remote_codec.packetization = "unknownpacketizationattributevalue";
   cricket::VideoContentDescription local_video;
   local_video.set_codecs({local_codec});
@@ -2248,9 +2252,9 @@
 
 TEST_F(VideoChannelSingleThreadTest,
        TestSetLocalAnswerWithInvalidPacketization) {
-  cricket::VideoCodec local_codec(98, "VP8");
+  cricket::VideoCodec local_codec = cricket::CreateVideoCodec(98, "VP8");
   local_codec.packetization = cricket::kPacketizationParamRaw;
-  const cricket::VideoCodec kRemoteCodec(99, "VP8");
+  const cricket::VideoCodec kRemoteCodec = cricket::CreateVideoCodec(99, "VP8");
   cricket::VideoContentDescription local_video;
   local_video.set_codecs({local_codec});
   cricket::VideoContentDescription remote_video;
diff --git a/pc/jsep_session_description_unittest.cc b/pc/jsep_session_description_unittest.cc
index ee446cb..c4b993d 100644
--- a/pc/jsep_session_description_unittest.cc
+++ b/pc/jsep_session_description_unittest.cc
@@ -62,11 +62,11 @@
   // VideoContentDescription
   auto video = std::make_unique<cricket::VideoContentDescription>();
 
-  audio->AddCodec(cricket::AudioCodec(103, "ISAC", 16000, 0, 0));
+  audio->AddCodec(cricket::CreateAudioCodec(103, "ISAC", 16000, 0));
   desc->AddContent(cricket::CN_AUDIO, MediaProtocolType::kRtp,
                    std::move(audio));
 
-  video->AddCodec(cricket::VideoCodec(120, "VP8"));
+  video->AddCodec(cricket::CreateVideoCodec(120, "VP8"));
   desc->AddContent(cricket::CN_VIDEO, MediaProtocolType::kRtp,
                    std::move(video));
 
diff --git a/pc/media_session.cc b/pc/media_session.cc
index 5b387f2..f911723 100644
--- a/pc/media_session.cc
+++ b/pc/media_session.cc
@@ -771,38 +771,39 @@
                             bool keep_offer_order,
                             const webrtc::FieldTrialsView* field_trials) {
   for (const C& ours : local_codecs) {
-    C theirs;
+    absl::optional<C> theirs =
+        FindMatchingCodec(local_codecs, offered_codecs, ours, field_trials);
     // Note that we intentionally only find one matching codec for each of our
     // local codecs, in case the remote offer contains duplicate codecs.
-    if (FindMatchingCodec(local_codecs, offered_codecs, ours, &theirs,
-                          field_trials)) {
+    if (theirs) {
       C negotiated = ours;
-      NegotiatePacketization(ours, theirs, &negotiated);
-      negotiated.IntersectFeedbackParams(theirs);
+      NegotiatePacketization(ours, *theirs, &negotiated);
+      negotiated.IntersectFeedbackParams(*theirs);
       if (IsRtxCodec(negotiated)) {
         const auto apt_it =
-            theirs.params.find(kCodecParamAssociatedPayloadType);
+            theirs->params.find(kCodecParamAssociatedPayloadType);
         // FindMatchingCodec shouldn't return something with no apt value.
-        RTC_DCHECK(apt_it != theirs.params.end());
+        RTC_DCHECK(apt_it != theirs->params.end());
         negotiated.SetParam(kCodecParamAssociatedPayloadType, apt_it->second);
 
         // We support parsing the declarative rtx-time parameter.
-        const auto rtx_time_it = theirs.params.find(kCodecParamRtxTime);
-        if (rtx_time_it != theirs.params.end()) {
+        const auto rtx_time_it = theirs->params.find(kCodecParamRtxTime);
+        if (rtx_time_it != theirs->params.end()) {
           negotiated.SetParam(kCodecParamRtxTime, rtx_time_it->second);
         }
       } else if (IsRedCodec(negotiated)) {
-        const auto red_it = theirs.params.find(kCodecParamNotInNameValueFormat);
-        if (red_it != theirs.params.end()) {
+        const auto red_it =
+            theirs->params.find(kCodecParamNotInNameValueFormat);
+        if (red_it != theirs->params.end()) {
           negotiated.SetParam(kCodecParamNotInNameValueFormat, red_it->second);
         }
       }
       if (absl::EqualsIgnoreCase(ours.name, kH264CodecName)) {
-        webrtc::H264GenerateProfileLevelIdForAnswer(ours.params, theirs.params,
+        webrtc::H264GenerateProfileLevelIdForAnswer(ours.params, theirs->params,
                                                     &negotiated.params);
       }
-      negotiated.id = theirs.id;
-      negotiated.name = theirs.name;
+      negotiated.id = theirs->id;
+      negotiated.name = theirs->name;
       negotiated_codecs->push_back(std::move(negotiated));
     }
   }
@@ -828,11 +829,11 @@
 // a member of `codecs1`. If `codec_to_match` is an RED or RTX codec, both
 // the codecs themselves and their associated codecs must match.
 template <class C>
-static bool FindMatchingCodec(const std::vector<C>& codecs1,
-                              const std::vector<C>& codecs2,
-                              const C& codec_to_match,
-                              C* found_codec,
-                              const webrtc::FieldTrialsView* field_trials) {
+static absl::optional<C> FindMatchingCodec(
+    const std::vector<C>& codecs1,
+    const std::vector<C>& codecs2,
+    const C& codec_to_match,
+    const webrtc::FieldTrialsView* field_trials) {
   // `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.
@@ -904,13 +905,10 @@
           continue;
         }
       }
-      if (found_codec) {
-        *found_codec = potential_match;
-      }
-      return true;
+      return potential_match;
     }
   }
-  return false;
+  return absl::nullopt;
 }
 
 // Find the codec in `codec_list` that `rtx_codec` is associated with.
@@ -995,7 +993,7 @@
   for (const C& reference_codec : reference_codecs) {
     if (!IsRtxCodec(reference_codec) && !IsRedCodec(reference_codec) &&
         !FindMatchingCodec<C>(reference_codecs, *offered_codecs,
-                              reference_codec, nullptr, field_trials)) {
+                              reference_codec, field_trials)) {
       C codec = reference_codec;
       used_pltypes->FindAndSetIdUsed(&codec);
       offered_codecs->push_back(codec);
@@ -1006,7 +1004,7 @@
   for (const C& reference_codec : reference_codecs) {
     if (IsRtxCodec(reference_codec) &&
         !FindMatchingCodec<C>(reference_codecs, *offered_codecs,
-                              reference_codec, nullptr, field_trials)) {
+                              reference_codec, field_trials)) {
       C rtx_codec = reference_codec;
       const C* associated_codec =
           GetAssociatedCodecForRtx(reference_codecs, rtx_codec);
@@ -1015,38 +1013,36 @@
       }
       // Find a codec in the offered list that matches the reference codec.
       // Its payload type may be different than the reference codec.
-      C matching_codec;
-      if (!FindMatchingCodec<C>(reference_codecs, *offered_codecs,
-                                *associated_codec, &matching_codec,
-                                field_trials)) {
+      absl::optional<C> matching_codec = FindMatchingCodec<C>(
+          reference_codecs, *offered_codecs, *associated_codec, field_trials);
+      if (!matching_codec) {
         RTC_LOG(LS_WARNING)
             << "Couldn't find matching " << associated_codec->name << " codec.";
         continue;
       }
 
       rtx_codec.params[kCodecParamAssociatedPayloadType] =
-          rtc::ToString(matching_codec.id);
+          rtc::ToString(matching_codec->id);
       used_pltypes->FindAndSetIdUsed(&rtx_codec);
       offered_codecs->push_back(rtx_codec);
     } else if (IsRedCodec(reference_codec) &&
                !FindMatchingCodec<C>(reference_codecs, *offered_codecs,
-                                     reference_codec, nullptr, field_trials)) {
+                                     reference_codec, field_trials)) {
       C red_codec = reference_codec;
       const C* associated_codec =
           GetAssociatedCodecForRed(reference_codecs, red_codec);
       if (associated_codec) {
-        C matching_codec;
-        if (!FindMatchingCodec<C>(reference_codecs, *offered_codecs,
-                                  *associated_codec, &matching_codec,
-                                  field_trials)) {
+        absl::optional<C> matching_codec = FindMatchingCodec<C>(
+            reference_codecs, *offered_codecs, *associated_codec, field_trials);
+        if (!matching_codec) {
           RTC_LOG(LS_WARNING) << "Couldn't find matching "
                               << associated_codec->name << " codec.";
           continue;
         }
 
         red_codec.params[kCodecParamNotInNameValueFormat] =
-            rtc::ToString(matching_codec.id) + "/" +
-            rtc::ToString(matching_codec.id);
+            rtc::ToString(matching_codec->id) + "/" +
+            rtc::ToString(matching_codec->id);
       }
       used_pltypes->FindAndSetIdUsed(&red_codec);
       offered_codecs->push_back(red_codec);
@@ -1090,11 +1086,12 @@
         });
 
     if (found_codec != supported_codecs.end()) {
-      typename Codecs::value_type found_codec_with_correct_pt;
-      if (FindMatchingCodec(supported_codecs, codecs, *found_codec,
-                            &found_codec_with_correct_pt, field_trials)) {
-        filtered_codecs.push_back(found_codec_with_correct_pt);
-        std::string id = rtc::ToString(found_codec_with_correct_pt.id);
+      absl::optional<typename Codecs::value_type> found_codec_with_correct_pt =
+          FindMatchingCodec(supported_codecs, codecs, *found_codec,
+                            field_trials);
+      if (found_codec_with_correct_pt) {
+        filtered_codecs.push_back(*found_codec_with_correct_pt);
+        std::string id = rtc::ToString(found_codec_with_correct_pt->id);
         // Search for the matching rtx or red codec.
         if (want_red || want_rtx) {
           for (const auto& codec : codecs) {
@@ -2153,12 +2150,11 @@
       const AudioContentDescription* audio =
           content.media_description()->as_audio();
       for (const AudioCodec& offered_audio_codec : audio->codecs()) {
-        if (!FindMatchingCodec<AudioCodec>(
-                audio->codecs(), filtered_offered_audio_codecs,
-                offered_audio_codec, nullptr, field_trials) &&
+        if (!FindMatchingCodec<AudioCodec>(audio->codecs(),
+                                           filtered_offered_audio_codecs,
+                                           offered_audio_codec, field_trials) &&
             FindMatchingCodec<AudioCodec>(audio->codecs(), all_audio_codecs_,
-                                          offered_audio_codec, nullptr,
-                                          field_trials)) {
+                                          offered_audio_codec, field_trials)) {
           filtered_offered_audio_codecs.push_back(offered_audio_codec);
         }
       }
@@ -2166,12 +2162,11 @@
       const VideoContentDescription* video =
           content.media_description()->as_video();
       for (const VideoCodec& offered_video_codec : video->codecs()) {
-        if (!FindMatchingCodec<VideoCodec>(
-                video->codecs(), filtered_offered_video_codecs,
-                offered_video_codec, nullptr, field_trials) &&
+        if (!FindMatchingCodec<VideoCodec>(video->codecs(),
+                                           filtered_offered_video_codecs,
+                                           offered_video_codec, field_trials) &&
             FindMatchingCodec<VideoCodec>(video->codecs(), all_video_codecs_,
-                                          offered_video_codec, nullptr,
-                                          field_trials)) {
+                                          offered_video_codec, field_trials)) {
           filtered_offered_video_codecs.push_back(offered_video_codec);
         }
       }
@@ -2350,22 +2345,22 @@
           current_content->media_description()->as_audio();
       for (const AudioCodec& codec : acd->codecs()) {
         if (FindMatchingCodec<AudioCodec>(acd->codecs(), audio_codecs, codec,
-                                          nullptr, field_trials)) {
+                                          field_trials)) {
           filtered_codecs.push_back(codec);
         }
       }
     }
     // Add other supported audio codecs.
-    AudioCodec found_codec;
+
     for (const AudioCodec& codec : supported_audio_codecs) {
-      if (FindMatchingCodec<AudioCodec>(supported_audio_codecs, audio_codecs,
-                                        codec, &found_codec, field_trials) &&
-          !FindMatchingCodec<AudioCodec>(supported_audio_codecs,
-                                         filtered_codecs, codec, nullptr,
-                                         field_trials)) {
+      absl::optional<AudioCodec> found_codec = FindMatchingCodec<AudioCodec>(
+          supported_audio_codecs, audio_codecs, codec, field_trials);
+      if (found_codec &&
+          !FindMatchingCodec<AudioCodec>(
+              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);
+        filtered_codecs.push_back(*found_codec);
       }
     }
   }
@@ -2443,19 +2438,18 @@
           current_content->media_description()->as_video();
       for (const VideoCodec& codec : vcd->codecs()) {
         if (FindMatchingCodec<VideoCodec>(vcd->codecs(), video_codecs, codec,
-                                          nullptr, field_trials)) {
+                                          field_trials)) {
           filtered_codecs.push_back(codec);
         }
       }
     }
     // Add other supported video codecs.
-    VideoCodec found_codec;
     for (const VideoCodec& codec : supported_video_codecs) {
-      if (FindMatchingCodec<VideoCodec>(supported_video_codecs, video_codecs,
-                                        codec, &found_codec, field_trials) &&
-          !FindMatchingCodec<VideoCodec>(supported_video_codecs,
-                                         filtered_codecs, codec, nullptr,
-                                         field_trials)) {
+      absl::optional<VideoCodec> found_codec = FindMatchingCodec<VideoCodec>(
+          supported_video_codecs, video_codecs, codec, field_trials);
+      if (found_codec &&
+          !FindMatchingCodec<VideoCodec>(
+              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)) {
@@ -2466,15 +2460,16 @@
           RTC_DCHECK(referenced_codec);
 
           // Find the codec we should be referencing and point to it.
-          VideoCodec changed_referenced_codec;
-          if (FindMatchingCodec<VideoCodec>(
-                  supported_video_codecs, filtered_codecs, *referenced_codec,
-                  &changed_referenced_codec, field_trials)) {
-            found_codec.SetParam(kCodecParamAssociatedPayloadType,
-                                 changed_referenced_codec.id);
+          absl::optional<VideoCodec> changed_referenced_codec =
+              FindMatchingCodec<VideoCodec>(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);
+        filtered_codecs.push_back(*found_codec);
       }
     }
   }
@@ -2654,7 +2649,7 @@
           current_content->media_description()->as_audio();
       for (const AudioCodec& codec : acd->codecs()) {
         if (FindMatchingCodec<AudioCodec>(acd->codecs(), audio_codecs, codec,
-                                          nullptr, field_trials)) {
+                                          field_trials)) {
           filtered_codecs.push_back(codec);
         }
       }
@@ -2662,10 +2657,9 @@
     // Add other supported audio codecs.
     for (const AudioCodec& codec : supported_audio_codecs) {
       if (FindMatchingCodec<AudioCodec>(supported_audio_codecs, audio_codecs,
-                                        codec, nullptr, field_trials) &&
-          !FindMatchingCodec<AudioCodec>(supported_audio_codecs,
-                                         filtered_codecs, codec, nullptr,
-                                         field_trials)) {
+                                        codec, field_trials) &&
+          !FindMatchingCodec<AudioCodec>(
+              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);
@@ -2780,7 +2774,7 @@
           current_content->media_description()->as_video();
       for (const VideoCodec& codec : vcd->codecs()) {
         if (FindMatchingCodec<VideoCodec>(vcd->codecs(), video_codecs, codec,
-                                          nullptr, field_trials)) {
+                                          field_trials)) {
           filtered_codecs.push_back(codec);
         }
       }
@@ -2790,10 +2784,9 @@
     VideoCodecs other_video_codecs;
     for (const VideoCodec& codec : supported_video_codecs) {
       if (FindMatchingCodec<VideoCodec>(supported_video_codecs, video_codecs,
-                                        codec, nullptr, field_trials) &&
-          !FindMatchingCodec<VideoCodec>(supported_video_codecs,
-                                         filtered_codecs, codec, nullptr,
-                                         field_trials)) {
+                                        codec, field_trials) &&
+          !FindMatchingCodec<VideoCodec>(
+              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);
@@ -2982,7 +2975,7 @@
   for (const AudioCodec& send : audio_send_codecs_) {
     all_audio_codecs_.push_back(send);
     if (!FindMatchingCodec<AudioCodec>(audio_send_codecs_, audio_recv_codecs_,
-                                       send, nullptr, field_trials)) {
+                                       send, field_trials)) {
       // It doesn't make sense to have an RTX codec we support sending but not
       // receiving.
       RTC_DCHECK(!IsRtxCodec(send));
@@ -2990,7 +2983,7 @@
   }
   for (const AudioCodec& recv : audio_recv_codecs_) {
     if (!FindMatchingCodec<AudioCodec>(audio_recv_codecs_, audio_send_codecs_,
-                                       recv, nullptr, field_trials)) {
+                                       recv, field_trials)) {
       all_audio_codecs_.push_back(recv);
     }
   }
diff --git a/pc/media_session_unittest.cc b/pc/media_session_unittest.cc
index c209dbd..8a6c8f6 100644
--- a/pc/media_session_unittest.cc
+++ b/pc/media_session_unittest.cc
@@ -112,34 +112,38 @@
 using webrtc::RtpTransceiverDirection;
 
 static const AudioCodec kAudioCodecs1[] = {
-    AudioCodec(103, "ISAC", 16000, -1, 1),
-    AudioCodec(102, "iLBC", 8000, 13300, 1),
-    AudioCodec(0, "PCMU", 8000, 64000, 1),
-    AudioCodec(8, "PCMA", 8000, 64000, 1),
-    AudioCodec(117, "red", 8000, 0, 1),
-    AudioCodec(107, "CN", 48000, 0, 1)};
+    cricket::CreateAudioCodec(103, "ISAC", 16000, 1),
+    cricket::CreateAudioCodec(102, "iLBC", 8000, 1),
+    cricket::CreateAudioCodec(0, "PCMU", 8000, 1),
+    cricket::CreateAudioCodec(8, "PCMA", 8000, 1),
+    cricket::CreateAudioCodec(117, "red", 8000, 1),
+    cricket::CreateAudioCodec(107, "CN", 48000, 1)};
 
 static const AudioCodec kAudioCodecs2[] = {
-    AudioCodec(126, "foo", 16000, 22000, 1),
-    AudioCodec(0, "PCMU", 8000, 64000, 1),
-    AudioCodec(127, "iLBC", 8000, 13300, 1),
+    cricket::CreateAudioCodec(126, "foo", 16000, 1),
+    cricket::CreateAudioCodec(0, "PCMU", 8000, 1),
+    cricket::CreateAudioCodec(127, "iLBC", 8000, 1),
 };
 
 static const AudioCodec kAudioCodecsAnswer[] = {
-    AudioCodec(102, "iLBC", 8000, 13300, 1),
-    AudioCodec(0, "PCMU", 8000, 64000, 1),
+    cricket::CreateAudioCodec(102, "iLBC", 8000, 1),
+    cricket::CreateAudioCodec(0, "PCMU", 8000, 1),
 };
 
-static const VideoCodec kVideoCodecs1[] = {VideoCodec(96, "H264-SVC"),
-                                           VideoCodec(97, "H264")};
+static const VideoCodec kVideoCodecs1[] = {
+    cricket::CreateVideoCodec(96, "H264-SVC"),
+    cricket::CreateVideoCodec(97, "H264")};
 
-static const VideoCodec kVideoCodecs1Reverse[] = {VideoCodec(97, "H264"),
-                                                  VideoCodec(96, "H264-SVC")};
+static const VideoCodec kVideoCodecs1Reverse[] = {
+    cricket::CreateVideoCodec(97, "H264"),
+    cricket::CreateVideoCodec(96, "H264-SVC")};
 
-static const VideoCodec kVideoCodecs2[] = {VideoCodec(126, "H264"),
-                                           VideoCodec(127, "H263")};
+static const VideoCodec kVideoCodecs2[] = {
+    cricket::CreateVideoCodec(126, "H264"),
+    cricket::CreateVideoCodec(127, "H263")};
 
-static const VideoCodec kVideoCodecsAnswer[] = {VideoCodec(97, "H264")};
+static const VideoCodec kVideoCodecsAnswer[] = {
+    cricket::CreateVideoCodec(97, "H264")};
 
 static const RtpExtension kAudioRtpExtension1[] = {
     RtpExtension("urn:ietf:params:rtp-hdrext:ssrc-audio-level", 8),
@@ -1313,10 +1317,10 @@
   AddMediaDescriptionOptions(MEDIA_TYPE_AUDIO, "audio",
                              RtpTransceiverDirection::kSendRecv, kActive,
                              &opts);
-  std::vector f1_codecs = {AudioCodec(96, "opus", 48000, -1, 1)};
+  std::vector f1_codecs = {cricket::CreateAudioCodec(96, "opus", 48000, 1)};
   f1_.set_audio_codecs(f1_codecs, f1_codecs);
 
-  std::vector f2_codecs = {AudioCodec(0, "PCMU", 8000, -1, 1)};
+  std::vector f2_codecs = {cricket::CreateAudioCodec(0, "PCMU", 8000, 1)};
   f2_.set_audio_codecs(f2_codecs, f2_codecs);
 
   std::unique_ptr<SessionDescription> offer = f1_.CreateOffer(opts, nullptr);
@@ -1384,10 +1388,10 @@
   AddMediaDescriptionOptions(MEDIA_TYPE_VIDEO, "video",
                              RtpTransceiverDirection::kSendRecv, kActive,
                              &opts);
-  std::vector f1_codecs = {VideoCodec(96, "H264")};
+  std::vector f1_codecs = {cricket::CreateVideoCodec(96, "H264")};
   f1_.set_video_codecs(f1_codecs, f1_codecs);
 
-  std::vector f2_codecs = {VideoCodec(97, "VP8")};
+  std::vector f2_codecs = {cricket::CreateVideoCodec(97, "VP8")};
   f2_.set_video_codecs(f2_codecs, f2_codecs);
 
   std::unique_ptr<SessionDescription> offer = f1_.CreateOffer(opts, nullptr);
@@ -1406,12 +1410,12 @@
   AddMediaDescriptionOptions(MEDIA_TYPE_VIDEO, "video",
                              RtpTransceiverDirection::kSendRecv, kActive,
                              &opts);
-  std::vector f1_codecs = {VideoCodec(96, "H264"),
-                           VideoCodec(118, "flexfec-03")};
+  std::vector f1_codecs = {cricket::CreateVideoCodec(96, "H264"),
+                           cricket::CreateVideoCodec(118, "flexfec-03")};
   f1_.set_video_codecs(f1_codecs, f1_codecs);
 
-  std::vector f2_codecs = {VideoCodec(97, "VP8"),
-                           VideoCodec(118, "flexfec-03")};
+  std::vector f2_codecs = {cricket::CreateVideoCodec(97, "VP8"),
+                           cricket::CreateVideoCodec(118, "flexfec-03")};
   f2_.set_video_codecs(f2_codecs, f2_codecs);
 
   std::unique_ptr<SessionDescription> offer = f1_.CreateOffer(opts, nullptr);
@@ -3001,13 +3005,13 @@
                              &opts);
   // We specifically choose different preferred payload types for VP8 to
   // trigger the issue.
-  cricket::VideoCodec vp8_offerer(100, "VP8");
+  cricket::VideoCodec vp8_offerer = cricket::CreateVideoCodec(100, "VP8");
   cricket::VideoCodec vp8_offerer_rtx =
       cricket::CreateVideoRtxCodec(101, vp8_offerer.id);
-  cricket::VideoCodec vp8_answerer(110, "VP8");
+  cricket::VideoCodec vp8_answerer = cricket::CreateVideoCodec(110, "VP8");
   cricket::VideoCodec vp8_answerer_rtx =
       cricket::CreateVideoRtxCodec(111, vp8_answerer.id);
-  cricket::VideoCodec vp9(120, "VP9");
+  cricket::VideoCodec vp9 = cricket::CreateVideoCodec(120, "VP9");
   cricket::VideoCodec vp9_rtx = cricket::CreateVideoRtxCodec(121, vp9.id);
 
   std::vector<VideoCodec> f1_codecs = {vp8_offerer, vp8_offerer_rtx};
@@ -3153,7 +3157,8 @@
                              &opts);
   std::vector<VideoCodec> f1_codecs = MAKE_VECTOR(kVideoCodecs1);
   // This creates RTX without associated payload type parameter.
-  AddRtxCodec(VideoCodec(126, cricket::kRtxCodecName), &f1_codecs);
+  AddRtxCodec(cricket::CreateVideoCodec(126, cricket::kRtxCodecName),
+              &f1_codecs);
   f1_.set_video_codecs(f1_codecs, f1_codecs);
 
   std::vector<VideoCodec> f2_codecs = MAKE_VECTOR(kVideoCodecs2);
@@ -3310,7 +3315,7 @@
 
   // Use a single real codec, and then add RTX for it.
   std::vector<VideoCodec> f1_codecs;
-  f1_codecs.push_back(VideoCodec(97, "H264"));
+  f1_codecs.push_back(cricket::CreateVideoCodec(97, "H264"));
   AddRtxCodec(cricket::CreateVideoRtxCodec(125, 97), &f1_codecs);
   f1_.set_video_codecs(f1_codecs, f1_codecs);
 
@@ -3354,8 +3359,8 @@
 
   // Use a single real codec, and then add FlexFEC for it.
   std::vector<VideoCodec> f1_codecs;
-  f1_codecs.push_back(VideoCodec(97, "H264"));
-  f1_codecs.push_back(VideoCodec(118, "flexfec-03"));
+  f1_codecs.push_back(cricket::CreateVideoCodec(97, "H264"));
+  f1_codecs.push_back(cricket::CreateVideoCodec(118, "flexfec-03"));
   f1_.set_video_codecs(f1_codecs, f1_codecs);
 
   // Ensure that the offer has a single FlexFEC ssrc and that
@@ -3397,8 +3402,8 @@
 
   // Use a single real codec, and then add FlexFEC for it.
   std::vector<VideoCodec> f1_codecs;
-  f1_codecs.push_back(VideoCodec(97, "H264"));
-  f1_codecs.push_back(VideoCodec(118, "flexfec-03"));
+  f1_codecs.push_back(cricket::CreateVideoCodec(97, "H264"));
+  f1_codecs.push_back(cricket::CreateVideoCodec(118, "flexfec-03"));
   f1_.set_video_codecs(f1_codecs, f1_codecs);
 
   // Ensure that the offer has no FlexFEC ssrcs for each regular ssrc, and that
@@ -4446,10 +4451,10 @@
        H264MatchCriteriaIncludesPacketizationMode) {
   // Create two H264 codecs with the same profile level ID and different
   // packetization modes.
-  VideoCodec h264_pm0(96, "H264");
+  VideoCodec h264_pm0 = cricket::CreateVideoCodec(96, "H264");
   h264_pm0.params[cricket::kH264FmtpProfileLevelId] = "42c01f";
   h264_pm0.params[cricket::kH264FmtpPacketizationMode] = "0";
-  VideoCodec h264_pm1(97, "H264");
+  VideoCodec h264_pm1 = cricket::CreateVideoCodec(97, "H264");
   h264_pm1.params[cricket::kH264FmtpProfileLevelId] = "42c01f";
   h264_pm1.params[cricket::kH264FmtpPacketizationMode] = "1";
 
@@ -4665,13 +4670,13 @@
 }
 
 static const AudioCodec kOfferAnswerCodecs[] = {
-    AudioCodec(0, "codec0", 16000, -1, 1),
-    AudioCodec(1, "codec1", 8000, 13300, 1),
-    AudioCodec(2, "codec2", 8000, 64000, 1),
-    AudioCodec(3, "codec3", 8000, 64000, 1),
-    AudioCodec(4, "codec4", 8000, 0, 2),
-    AudioCodec(5, "codec5", 32000, 0, 1),
-    AudioCodec(6, "codec6", 48000, 0, 1)};
+    cricket::CreateAudioCodec(0, "codec0", 16000, 1),
+    cricket::CreateAudioCodec(1, "codec1", 8000, 1),
+    cricket::CreateAudioCodec(2, "codec2", 8000, 1),
+    cricket::CreateAudioCodec(3, "codec3", 8000, 1),
+    cricket::CreateAudioCodec(4, "codec4", 8000, 2),
+    cricket::CreateAudioCodec(5, "codec5", 32000, 1),
+    cricket::CreateAudioCodec(6, "codec6", 48000, 1)};
 
 /* The codecs groups below are chosen as per the matrix below. The objective
  * is to have different sets of codecs in the inputs, to get unique sets of
diff --git a/pc/peer_connection_integrationtest.cc b/pc/peer_connection_integrationtest.cc
index 7fbfb7f..43e307e 100644
--- a/pc/peer_connection_integrationtest.cc
+++ b/pc/peer_connection_integrationtest.cc
@@ -1087,7 +1087,8 @@
     media->set_rtp_header_extensions(extensions);
     cricket::VideoContentDescription* video = media->as_video();
     ASSERT_TRUE(video != nullptr);
-    std::vector<cricket::VideoCodec> codecs = {{pt++, "VP8"}};
+    std::vector<cricket::VideoCodec> codecs = {
+        cricket::CreateVideoCodec(pt++, "VP8")};
     video->set_codecs(codecs);
   }
 }
diff --git a/pc/peer_connection_media_unittest.cc b/pc/peer_connection_media_unittest.cc
index c454536..dd497ba 100644
--- a/pc/peer_connection_media_unittest.cc
+++ b/pc/peer_connection_media_unittest.cc
@@ -572,12 +572,13 @@
 // Test that raw packetization is not set in the offer by default.
 TEST_P(PeerConnectionMediaTest, RawPacketizationNotSetInOffer) {
   std::vector<cricket::VideoCodec> fake_codecs;
-  fake_codecs.push_back(cricket::VideoCodec(111, cricket::kVp8CodecName));
-  fake_codecs.push_back(cricket::VideoCodec(112, cricket::kRtxCodecName));
+  fake_codecs.push_back(cricket::CreateVideoCodec(111, cricket::kVp8CodecName));
+  fake_codecs.push_back(cricket::CreateVideoCodec(112, cricket::kRtxCodecName));
   fake_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] = "111";
-  fake_codecs.push_back(cricket::VideoCodec(113, cricket::kVp9CodecName));
-  fake_codecs.push_back(cricket::VideoCodec(114, cricket::kH264CodecName));
-  fake_codecs.push_back(cricket::VideoCodec(115, "HEVC"));
+  fake_codecs.push_back(cricket::CreateVideoCodec(113, cricket::kVp9CodecName));
+  fake_codecs.push_back(
+      cricket::CreateVideoCodec(114, cricket::kH264CodecName));
+  fake_codecs.push_back(cricket::CreateVideoCodec(115, "HEVC"));
   auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
   caller_fake_engine->SetVideoCodecs(fake_codecs);
 
@@ -594,12 +595,13 @@
 // video payload when raw_packetization_for_video is true.
 TEST_P(PeerConnectionMediaTest, RawPacketizationSetInOfferAndAnswer) {
   std::vector<cricket::VideoCodec> fake_codecs;
-  fake_codecs.push_back(cricket::VideoCodec(111, cricket::kVp8CodecName));
-  fake_codecs.push_back(cricket::VideoCodec(112, cricket::kRtxCodecName));
+  fake_codecs.push_back(cricket::CreateVideoCodec(111, cricket::kVp8CodecName));
+  fake_codecs.push_back(cricket::CreateVideoCodec(112, cricket::kRtxCodecName));
   fake_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] = "111";
-  fake_codecs.push_back(cricket::VideoCodec(113, cricket::kVp9CodecName));
-  fake_codecs.push_back(cricket::VideoCodec(114, cricket::kH264CodecName));
-  fake_codecs.push_back(cricket::VideoCodec(115, "HEVC"));
+  fake_codecs.push_back(cricket::CreateVideoCodec(113, cricket::kVp9CodecName));
+  fake_codecs.push_back(
+      cricket::CreateVideoCodec(114, cricket::kH264CodecName));
+  fake_codecs.push_back(cricket::CreateVideoCodec(115, "HEVC"));
   auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
   caller_fake_engine->SetVideoCodecs(fake_codecs);
   auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
@@ -637,12 +639,13 @@
 TEST_P(PeerConnectionMediaTest,
        RawPacketizationNotSetInAnswerWhenNotSetInOffer) {
   std::vector<cricket::VideoCodec> fake_codecs;
-  fake_codecs.push_back(cricket::VideoCodec(111, cricket::kVp8CodecName));
-  fake_codecs.push_back(cricket::VideoCodec(112, cricket::kRtxCodecName));
+  fake_codecs.push_back(cricket::CreateVideoCodec(111, cricket::kVp8CodecName));
+  fake_codecs.push_back(cricket::CreateVideoCodec(112, cricket::kRtxCodecName));
   fake_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] = "111";
-  fake_codecs.push_back(cricket::VideoCodec(113, cricket::kVp9CodecName));
-  fake_codecs.push_back(cricket::VideoCodec(114, cricket::kH264CodecName));
-  fake_codecs.push_back(cricket::VideoCodec(115, "HEVC"));
+  fake_codecs.push_back(cricket::CreateVideoCodec(113, cricket::kVp9CodecName));
+  fake_codecs.push_back(
+      cricket::CreateVideoCodec(114, cricket::kH264CodecName));
+  fake_codecs.push_back(cricket::CreateVideoCodec(115, "HEVC"));
   auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
   caller_fake_engine->SetVideoCodecs(fake_codecs);
   auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
@@ -878,10 +881,10 @@
 }
 
 void AddComfortNoiseCodecsToSend(cricket::FakeMediaEngine* media_engine) {
-  const cricket::AudioCodec kComfortNoiseCodec8k(102, cricket::kCnCodecName,
-                                                 8000, 0, 1);
-  const cricket::AudioCodec kComfortNoiseCodec16k(103, cricket::kCnCodecName,
-                                                  16000, 0, 1);
+  const cricket::AudioCodec kComfortNoiseCodec8k =
+      cricket::CreateAudioCodec(102, cricket::kCnCodecName, 8000, 1);
+  const cricket::AudioCodec kComfortNoiseCodec16k =
+      cricket::CreateAudioCodec(103, cricket::kCnCodecName, 16000, 1);
 
   auto codecs = media_engine->voice().send_codecs();
   codecs.push_back(kComfortNoiseCodec8k);
@@ -1358,15 +1361,15 @@
 // fmtp line is modified to refer to the correct payload type.
 TEST_P(PeerConnectionMediaTest, RedFmtpPayloadTypeReassigned) {
   std::vector<cricket::AudioCodec> caller_fake_codecs;
-  caller_fake_codecs.push_back(cricket::AudioCodec(100, "foo", 0, 0, 1));
+  caller_fake_codecs.push_back(cricket::CreateAudioCodec(100, "foo", 0, 1));
   auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
   caller_fake_engine->SetAudioCodecs(caller_fake_codecs);
   auto caller = CreatePeerConnectionWithAudio(std::move(caller_fake_engine));
 
   std::vector<cricket::AudioCodec> callee_fake_codecs;
-  callee_fake_codecs.push_back(cricket::AudioCodec(120, "foo", 0, 0, 1));
+  callee_fake_codecs.push_back(cricket::CreateAudioCodec(120, "foo", 0, 1));
   callee_fake_codecs.push_back(
-      cricket::AudioCodec(121, cricket::kRedCodecName, 0, 0, 1));
+      cricket::CreateAudioCodec(121, cricket::kRedCodecName, 0, 1));
   callee_fake_codecs.back().SetParam(cricket::kCodecParamNotInNameValueFormat,
                                      "120/120");
   auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
@@ -1401,17 +1404,17 @@
 // Test that RED without fmtp does match RED without fmtp.
 TEST_P(PeerConnectionMediaTest, RedFmtpPayloadTypeNoFmtpMatchNoFmtp) {
   std::vector<cricket::AudioCodec> caller_fake_codecs;
-  caller_fake_codecs.push_back(cricket::AudioCodec(100, "foo", 0, 0, 1));
+  caller_fake_codecs.push_back(cricket::CreateAudioCodec(100, "foo", 0, 1));
   caller_fake_codecs.push_back(
-      cricket::AudioCodec(101, cricket::kRedCodecName, 0, 0, 1));
+      cricket::CreateAudioCodec(101, cricket::kRedCodecName, 0, 1));
   auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
   caller_fake_engine->SetAudioCodecs(caller_fake_codecs);
   auto caller = CreatePeerConnectionWithAudio(std::move(caller_fake_engine));
 
   std::vector<cricket::AudioCodec> callee_fake_codecs;
-  callee_fake_codecs.push_back(cricket::AudioCodec(120, "foo", 0, 0, 1));
+  callee_fake_codecs.push_back(cricket::CreateAudioCodec(120, "foo", 0, 1));
   callee_fake_codecs.push_back(
-      cricket::AudioCodec(121, cricket::kRedCodecName, 0, 0, 1));
+      cricket::CreateAudioCodec(121, cricket::kRedCodecName, 0, 1));
   auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
   callee_fake_engine->SetAudioCodecs(callee_fake_codecs);
   auto callee = CreatePeerConnectionWithAudio(std::move(callee_fake_engine));
@@ -1443,17 +1446,17 @@
 // Test that RED without fmtp does not match RED with fmtp.
 TEST_P(PeerConnectionMediaTest, RedFmtpPayloadTypeNoFmtpNoMatchFmtp) {
   std::vector<cricket::AudioCodec> caller_fake_codecs;
-  caller_fake_codecs.push_back(cricket::AudioCodec(100, "foo", 0, 0, 1));
+  caller_fake_codecs.push_back(cricket::CreateAudioCodec(100, "foo", 0, 1));
   caller_fake_codecs.push_back(
-      cricket::AudioCodec(101, cricket::kRedCodecName, 0, 0, 1));
+      cricket::CreateAudioCodec(101, cricket::kRedCodecName, 0, 1));
   auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
   caller_fake_engine->SetAudioCodecs(caller_fake_codecs);
   auto caller = CreatePeerConnectionWithAudio(std::move(caller_fake_engine));
 
   std::vector<cricket::AudioCodec> callee_fake_codecs;
-  callee_fake_codecs.push_back(cricket::AudioCodec(120, "foo", 0, 0, 1));
+  callee_fake_codecs.push_back(cricket::CreateAudioCodec(120, "foo", 0, 1));
   callee_fake_codecs.push_back(
-      cricket::AudioCodec(121, cricket::kRedCodecName, 0, 0, 1));
+      cricket::CreateAudioCodec(121, cricket::kRedCodecName, 0, 1));
   callee_fake_codecs.back().SetParam(cricket::kCodecParamNotInNameValueFormat,
                                      "120/120");
   auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
@@ -1490,9 +1493,9 @@
 // Test that RED with fmtp must match base codecs.
 TEST_P(PeerConnectionMediaTest, RedFmtpPayloadTypeMustMatchBaseCodecs) {
   std::vector<cricket::AudioCodec> caller_fake_codecs;
-  caller_fake_codecs.push_back(cricket::AudioCodec(100, "foo", 0, 0, 1));
+  caller_fake_codecs.push_back(cricket::CreateAudioCodec(100, "foo", 0, 1));
   caller_fake_codecs.push_back(
-      cricket::AudioCodec(101, cricket::kRedCodecName, 0, 0, 1));
+      cricket::CreateAudioCodec(101, cricket::kRedCodecName, 0, 1));
   caller_fake_codecs.back().SetParam(cricket::kCodecParamNotInNameValueFormat,
                                      "100/100");
   auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
@@ -1500,10 +1503,10 @@
   auto caller = CreatePeerConnectionWithAudio(std::move(caller_fake_engine));
 
   std::vector<cricket::AudioCodec> callee_fake_codecs;
-  callee_fake_codecs.push_back(cricket::AudioCodec(120, "foo", 0, 0, 1));
+  callee_fake_codecs.push_back(cricket::CreateAudioCodec(120, "foo", 0, 1));
   callee_fake_codecs.push_back(
-      cricket::AudioCodec(121, cricket::kRedCodecName, 0, 0, 1));
-  callee_fake_codecs.push_back(cricket::AudioCodec(122, "bar", 0, 0, 1));
+      cricket::CreateAudioCodec(121, cricket::kRedCodecName, 0, 1));
+  callee_fake_codecs.push_back(cricket::CreateAudioCodec(122, "bar", 0, 1));
   callee_fake_codecs.back().SetParam(cricket::kCodecParamNotInNameValueFormat,
                                      "122/122");
   auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
@@ -1524,10 +1527,10 @@
 // which is not supported.
 TEST_P(PeerConnectionMediaTest, RedFmtpPayloadMixed) {
   std::vector<cricket::AudioCodec> caller_fake_codecs;
-  caller_fake_codecs.push_back(cricket::AudioCodec(100, "foo", 0, 0, 1));
-  caller_fake_codecs.push_back(cricket::AudioCodec(102, "bar", 0, 0, 1));
+  caller_fake_codecs.push_back(cricket::CreateAudioCodec(100, "foo", 0, 1));
+  caller_fake_codecs.push_back(cricket::CreateAudioCodec(102, "bar", 0, 1));
   caller_fake_codecs.push_back(
-      cricket::AudioCodec(101, cricket::kRedCodecName, 0, 0, 1));
+      cricket::CreateAudioCodec(101, cricket::kRedCodecName, 0, 1));
   caller_fake_codecs.back().SetParam(cricket::kCodecParamNotInNameValueFormat,
                                      "100/102");
   auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
@@ -1535,9 +1538,9 @@
   auto caller = CreatePeerConnectionWithAudio(std::move(caller_fake_engine));
 
   std::vector<cricket::AudioCodec> callee_fake_codecs;
-  callee_fake_codecs.push_back(cricket::AudioCodec(120, "foo", 0, 0, 1));
+  callee_fake_codecs.push_back(cricket::CreateAudioCodec(120, "foo", 0, 1));
   callee_fake_codecs.push_back(
-      cricket::AudioCodec(121, cricket::kRedCodecName, 0, 0, 1));
+      cricket::CreateAudioCodec(121, cricket::kRedCodecName, 0, 1));
   callee_fake_codecs.back().SetParam(cricket::kCodecParamNotInNameValueFormat,
                                      "120/120");
   auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
@@ -1558,9 +1561,9 @@
 // redundancy.
 TEST_P(PeerConnectionMediaTest, RedFmtpPayloadDifferentRedundancy) {
   std::vector<cricket::AudioCodec> caller_fake_codecs;
-  caller_fake_codecs.push_back(cricket::AudioCodec(100, "foo", 0, 0, 1));
+  caller_fake_codecs.push_back(cricket::CreateAudioCodec(100, "foo", 0, 1));
   caller_fake_codecs.push_back(
-      cricket::AudioCodec(101, cricket::kRedCodecName, 0, 0, 1));
+      cricket::CreateAudioCodec(101, cricket::kRedCodecName, 0, 1));
   caller_fake_codecs.back().SetParam(cricket::kCodecParamNotInNameValueFormat,
                                      "100/100");
   auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
@@ -1568,9 +1571,9 @@
   auto caller = CreatePeerConnectionWithAudio(std::move(caller_fake_engine));
 
   std::vector<cricket::AudioCodec> callee_fake_codecs;
-  callee_fake_codecs.push_back(cricket::AudioCodec(120, "foo", 0, 0, 1));
+  callee_fake_codecs.push_back(cricket::CreateAudioCodec(120, "foo", 0, 1));
   callee_fake_codecs.push_back(
-      cricket::AudioCodec(121, cricket::kRedCodecName, 0, 0, 1));
+      cricket::CreateAudioCodec(121, cricket::kRedCodecName, 0, 1));
   callee_fake_codecs.back().SetParam(cricket::kCodecParamNotInNameValueFormat,
                                      "120/120/120");
   auto callee_fake_engine = std::make_unique<FakeMediaEngine>();
@@ -1638,8 +1641,8 @@
        SetCodecPreferencesAudioMissingRecvCodec) {
   auto fake_engine = std::make_unique<FakeMediaEngine>();
   auto send_codecs = fake_engine->voice().send_codecs();
-  send_codecs.push_back(cricket::AudioCodec(send_codecs.back().id + 1,
-                                            "send_only_codec", 0, 0, 1));
+  send_codecs.push_back(cricket::CreateAudioCodec(send_codecs.back().id + 1,
+                                                  "send_only_codec", 0, 1));
   fake_engine->SetAudioSendCodecs(send_codecs);
 
   auto caller = CreatePeerConnectionWithAudio(std::move(fake_engine));
@@ -1662,8 +1665,8 @@
        SetCodecPreferencesAudioMissingSendCodec) {
   auto fake_engine = std::make_unique<FakeMediaEngine>();
   auto recv_codecs = fake_engine->voice().recv_codecs();
-  recv_codecs.push_back(cricket::AudioCodec(recv_codecs.back().id + 1,
-                                            "recv_only_codec", 0, 0, 1));
+  recv_codecs.push_back(cricket::CreateAudioCodec(recv_codecs.back().id + 1,
+                                                  "recv_only_codec", 0, 1));
   fake_engine->SetAudioRecvCodecs(recv_codecs);
   auto caller = CreatePeerConnectionWithAudio(std::move(fake_engine));
 
@@ -1703,14 +1706,14 @@
        SetCodecPreferencesAudioRejectsOnlyRtxRedFec) {
   auto fake_engine = std::make_unique<FakeMediaEngine>();
   auto audio_codecs = fake_engine->voice().send_codecs();
-  audio_codecs.push_back(cricket::AudioCodec(audio_codecs.back().id + 1,
-                                             cricket::kRtxCodecName, 0, 0, 1));
+  audio_codecs.push_back(cricket::CreateAudioCodec(
+      audio_codecs.back().id + 1, cricket::kRtxCodecName, 0, 1));
   audio_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] =
       std::to_string(audio_codecs.back().id - 1);
-  audio_codecs.push_back(cricket::AudioCodec(audio_codecs.back().id + 1,
-                                             cricket::kRedCodecName, 0, 0, 1));
-  audio_codecs.push_back(cricket::AudioCodec(
-      audio_codecs.back().id + 1, cricket::kUlpfecCodecName, 0, 0, 1));
+  audio_codecs.push_back(cricket::CreateAudioCodec(
+      audio_codecs.back().id + 1, cricket::kRedCodecName, 0, 1));
+  audio_codecs.push_back(cricket::CreateAudioCodec(
+      audio_codecs.back().id + 1, cricket::kUlpfecCodecName, 0, 1));
   fake_engine->SetAudioCodecs(audio_codecs);
 
   auto caller = CreatePeerConnectionWithAudio(std::move(fake_engine));
@@ -1800,14 +1803,14 @@
        SetCodecPreferencesVideoRejectsOnlyRtxRedFec) {
   auto fake_engine = std::make_unique<FakeMediaEngine>();
   auto video_codecs = fake_engine->video().send_codecs();
-  video_codecs.push_back(
-      cricket::VideoCodec(video_codecs.back().id + 1, cricket::kRtxCodecName));
+  video_codecs.push_back(cricket::CreateVideoCodec(video_codecs.back().id + 1,
+                                                   cricket::kRtxCodecName));
   video_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] =
       std::to_string(video_codecs.back().id - 1);
-  video_codecs.push_back(
-      cricket::VideoCodec(video_codecs.back().id + 1, cricket::kRedCodecName));
-  video_codecs.push_back(cricket::VideoCodec(video_codecs.back().id + 1,
-                                             cricket::kUlpfecCodecName));
+  video_codecs.push_back(cricket::CreateVideoCodec(video_codecs.back().id + 1,
+                                                   cricket::kRedCodecName));
+  video_codecs.push_back(cricket::CreateVideoCodec(video_codecs.back().id + 1,
+                                                   cricket::kUlpfecCodecName));
   fake_engine->SetVideoCodecs(video_codecs);
 
   auto caller = CreatePeerConnectionWithVideo(std::move(fake_engine));
@@ -1908,15 +1911,15 @@
 TEST_F(PeerConnectionMediaTestUnifiedPlan, SetCodecPreferencesVideoWithRtx) {
   auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
   auto caller_video_codecs = caller_fake_engine->video().send_codecs();
-  caller_video_codecs.push_back(cricket::VideoCodec(
+  caller_video_codecs.push_back(cricket::CreateVideoCodec(
       caller_video_codecs.back().id + 1, cricket::kVp8CodecName));
-  caller_video_codecs.push_back(cricket::VideoCodec(
+  caller_video_codecs.push_back(cricket::CreateVideoCodec(
       caller_video_codecs.back().id + 1, cricket::kRtxCodecName));
   caller_video_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] =
       std::to_string(caller_video_codecs.back().id - 1);
-  caller_video_codecs.push_back(cricket::VideoCodec(
+  caller_video_codecs.push_back(cricket::CreateVideoCodec(
       caller_video_codecs.back().id + 1, cricket::kVp9CodecName));
-  caller_video_codecs.push_back(cricket::VideoCodec(
+  caller_video_codecs.push_back(cricket::CreateVideoCodec(
       caller_video_codecs.back().id + 1, cricket::kRtxCodecName));
   caller_video_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] =
       std::to_string(caller_video_codecs.back().id - 1);
@@ -1960,15 +1963,15 @@
        SetCodecPreferencesVideoCodecsNegotiation) {
   auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
   auto caller_video_codecs = caller_fake_engine->video().send_codecs();
-  caller_video_codecs.push_back(cricket::VideoCodec(
+  caller_video_codecs.push_back(cricket::CreateVideoCodec(
       caller_video_codecs.back().id + 1, cricket::kVp8CodecName));
-  caller_video_codecs.push_back(cricket::VideoCodec(
+  caller_video_codecs.push_back(cricket::CreateVideoCodec(
       caller_video_codecs.back().id + 1, cricket::kRtxCodecName));
   caller_video_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] =
       std::to_string(caller_video_codecs.back().id - 1);
-  caller_video_codecs.push_back(cricket::VideoCodec(
+  caller_video_codecs.push_back(cricket::CreateVideoCodec(
       caller_video_codecs.back().id + 1, cricket::kVp9CodecName));
-  caller_video_codecs.push_back(cricket::VideoCodec(
+  caller_video_codecs.push_back(cricket::CreateVideoCodec(
       caller_video_codecs.back().id + 1, cricket::kRtxCodecName));
   caller_video_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] =
       std::to_string(caller_video_codecs.back().id - 1);
@@ -2034,15 +2037,15 @@
        SetCodecPreferencesVideoCodecsNegotiationReverseOrder) {
   auto caller_fake_engine = std::make_unique<FakeMediaEngine>();
   auto caller_video_codecs = caller_fake_engine->video().send_codecs();
-  caller_video_codecs.push_back(cricket::VideoCodec(
+  caller_video_codecs.push_back(cricket::CreateVideoCodec(
       caller_video_codecs.back().id + 1, cricket::kVp8CodecName));
-  caller_video_codecs.push_back(cricket::VideoCodec(
+  caller_video_codecs.push_back(cricket::CreateVideoCodec(
       caller_video_codecs.back().id + 1, cricket::kRtxCodecName));
   caller_video_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] =
       std::to_string(caller_video_codecs.back().id - 1);
-  caller_video_codecs.push_back(cricket::VideoCodec(
+  caller_video_codecs.push_back(cricket::CreateVideoCodec(
       caller_video_codecs.back().id + 1, cricket::kVp9CodecName));
-  caller_video_codecs.push_back(cricket::VideoCodec(
+  caller_video_codecs.push_back(cricket::CreateVideoCodec(
       caller_video_codecs.back().id + 1, cricket::kRtxCodecName));
   caller_video_codecs.back().params[cricket::kCodecParamAssociatedPayloadType] =
       std::to_string(caller_video_codecs.back().id - 1);
diff --git a/pc/rtp_parameters_conversion.cc b/pc/rtp_parameters_conversion.cc
index 196cb79..fa8599c 100644
--- a/pc/rtp_parameters_conversion.cc
+++ b/pc/rtp_parameters_conversion.cc
@@ -18,6 +18,7 @@
 
 #include "api/array_view.h"
 #include "api/media_types.h"
+#include "media/base/codec.h"
 #include "media/base/media_constants.h"
 #include "media/base/rtp_utils.h"
 #include "rtc_base/checks.h"
@@ -80,13 +81,12 @@
 }
 
 template <typename C>
-static RTCError ToCricketCodecTypeSpecific(const RtpCodecParameters& codec,
-                                           C* cricket_codec);
+static RTCErrorOr<C> ToCricketCodecTypeSpecific(
+    const RtpCodecParameters& codec);
 
 template <>
-RTCError ToCricketCodecTypeSpecific<cricket::AudioCodec>(
-    const RtpCodecParameters& codec,
-    cricket::AudioCodec* cricket_codec) {
+RTCErrorOr<cricket::AudioCodec> ToCricketCodecTypeSpecific<cricket::AudioCodec>(
+    const RtpCodecParameters& codec) {
   if (codec.kind != cricket::MEDIA_TYPE_AUDIO) {
     LOG_AND_RETURN_ERROR(
         RTCErrorType::INVALID_PARAMETER,
@@ -100,7 +100,6 @@
     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_RANGE,
                          "Number of channels must be positive.");
   }
-  cricket_codec->channels = *codec.num_channels;
   if (!codec.clock_rate) {
     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
                          "Missing codec clock rate.");
@@ -109,17 +108,16 @@
     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_RANGE,
                          "Clock rate must be positive.");
   }
-  cricket_codec->clockrate = *codec.clock_rate;
-  return RTCError::OK();
+  return cricket::CreateAudioCodec(0, codec.name, *codec.clock_rate,
+                                   *codec.num_channels);
 }
 
 // Video codecs don't use num_channels or clock_rate, but they should at least
 // be validated to ensure the application isn't trying to do something it
 // doesn't intend to.
 template <>
-RTCError ToCricketCodecTypeSpecific<cricket::VideoCodec>(
-    const RtpCodecParameters& codec,
-    cricket::VideoCodec*) {
+RTCErrorOr<cricket::VideoCodec> ToCricketCodecTypeSpecific<cricket::VideoCodec>(
+    const RtpCodecParameters& codec) {
   if (codec.kind != cricket::MEDIA_TYPE_VIDEO) {
     LOG_AND_RETURN_ERROR(
         RTCErrorType::INVALID_PARAMETER,
@@ -137,18 +135,17 @@
     LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
                          "Video clock rate must be 90000.");
   }
-  return RTCError::OK();
+  return cricket::CreateVideoCodec(0, codec.name);
 }
 
 template <typename C>
 RTCErrorOr<C> ToCricketCodec(const RtpCodecParameters& codec) {
-  C cricket_codec;
   // Start with audio/video specific conversion.
-  RTCError err = ToCricketCodecTypeSpecific(codec, &cricket_codec);
-  if (!err.ok()) {
-    return std::move(err);
+  RTCErrorOr<C> result = ToCricketCodecTypeSpecific<C>(codec);
+  if (!result.ok()) {
+    return result.MoveError();
   }
-  cricket_codec.name = codec.name;
+  C cricket_codec = result.MoveValue();
   if (!cricket::IsValidRtpPayloadType(codec.payload_type)) {
     char buf[40];
     rtc::SimpleStringBuilder sb(buf);
diff --git a/pc/rtp_parameters_conversion_unittest.cc b/pc/rtp_parameters_conversion_unittest.cc
index 250743b..b1e6323 100644
--- a/pc/rtp_parameters_conversion_unittest.cc
+++ b/pc/rtp_parameters_conversion_unittest.cc
@@ -416,9 +416,7 @@
 }
 
 TEST(RtpParametersConversionTest, ToVideoRtpCodecCapability) {
-  cricket::VideoCodec cricket_codec;
-  cricket_codec.name = "VID";
-  cricket_codec.id = 101;
+  cricket::VideoCodec cricket_codec = cricket::CreateVideoCodec(101, "VID");
   cricket_codec.clockrate = 80000;
   cricket_codec.params["foo"] = "bar";
   cricket_codec.params["ANOTHER"] = "param";
@@ -485,9 +483,7 @@
 }
 
 TEST(RtpParametersConversionTest, ToVideoRtpCodecParameters) {
-  cricket::VideoCodec cricket_codec;
-  cricket_codec.name = "VID";
-  cricket_codec.id = 101;
+  cricket::VideoCodec cricket_codec = cricket::CreateVideoCodec(101, "VID");
   cricket_codec.clockrate = 80000;
   cricket_codec.params["foo"] = "bar";
   cricket_codec.params["ANOTHER"] = "param";
@@ -529,35 +525,21 @@
 // test that the result of ToRtpCodecCapability ends up in the result, and that
 // the "fec" list is assembled correctly.
 TEST(RtpParametersConversionTest, ToRtpCapabilities) {
-  cricket::VideoCodec vp8;
-  vp8.name = "VP8";
-  vp8.id = 101;
+  cricket::VideoCodec vp8 = cricket::CreateVideoCodec(101, "VP8");
   vp8.clockrate = 90000;
 
-  cricket::VideoCodec red;
-  red.name = "red";
-  red.id = 102;
+  cricket::VideoCodec red = cricket::CreateVideoCodec(102, "red");
   red.clockrate = 90000;
 
-  cricket::VideoCodec ulpfec;
-  ulpfec.name = "ulpfec";
-  ulpfec.id = 103;
+  cricket::VideoCodec ulpfec = cricket::CreateVideoCodec(103, "ulpfec");
   ulpfec.clockrate = 90000;
 
-  cricket::VideoCodec flexfec;
-  flexfec.name = "flexfec-03";
-  flexfec.id = 102;
+  cricket::VideoCodec flexfec = cricket::CreateVideoCodec(102, "flexfec-03");
   flexfec.clockrate = 90000;
 
-  cricket::VideoCodec rtx;
-  rtx.name = "rtx";
-  rtx.id = 104;
-  rtx.params.insert({"apt", "101"});
+  cricket::VideoCodec rtx = cricket::CreateVideoRtxCodec(014, 101);
 
-  cricket::VideoCodec rtx2;
-  rtx2.name = "rtx";
-  rtx2.id = 105;
-  rtx2.params.insert({"apt", "109"});
+  cricket::VideoCodec rtx2 = cricket::CreateVideoRtxCodec(105, 109);
 
   RtpCapabilities capabilities = ToRtpCapabilities<cricket::VideoCodec>(
       {vp8, ulpfec, rtx, rtx2}, {{"uri", 1}, {"uri2", 3}});
@@ -588,19 +570,13 @@
 }
 
 TEST(RtpParametersConversionTest, ToRtpParameters) {
-  cricket::VideoCodec vp8;
-  vp8.name = "VP8";
-  vp8.id = 101;
+  cricket::VideoCodec vp8 = cricket::CreateVideoCodec(101, "VP8");
   vp8.clockrate = 90000;
 
-  cricket::VideoCodec red;
-  red.name = "red";
-  red.id = 102;
+  cricket::VideoCodec red = cricket::CreateVideoCodec(102, "red");
   red.clockrate = 90000;
 
-  cricket::VideoCodec ulpfec;
-  ulpfec.name = "ulpfec";
-  ulpfec.id = 103;
+  cricket::VideoCodec ulpfec = cricket::CreateVideoCodec(103, "ulpfec");
   ulpfec.clockrate = 90000;
 
   cricket::StreamParamsVec streams;
diff --git a/pc/rtp_sender.cc b/pc/rtp_sender.cc
index fe3b3b1..6c5acac 100644
--- a/pc/rtp_sender.cc
+++ b/pc/rtp_sender.cc
@@ -20,6 +20,7 @@
 #include "api/audio_options.h"
 #include "api/media_stream_interface.h"
 #include "api/priority.h"
+#include "api/rtc_error.h"
 #include "media/base/media_engine.h"
 #include "pc/legacy_stats_collector_interface.h"
 #include "rtc_base/checks.h"
@@ -876,15 +877,18 @@
 }
 
 RTCError VideoRtpSender::CheckSVCParameters(const RtpParameters& parameters) {
-  cricket::VideoCodec codec;
-  video_media_channel()->GetSendCodec(&codec);
+  absl::optional<cricket::VideoCodec> send_codec =
+      video_media_channel()->GetSendCodec();
 
   // Match the currently used codec against the codec preferences to gather
   // the SVC capabilities.
   std::vector<cricket::VideoCodec> codecs;
-  for (const auto& codec_preference : video_codec_preferences_) {
-    if (codec.Matches(codec_preference)) {
-      codecs.push_back(codec_preference);
+  if (send_codec) {
+    for (const auto& codec_preference : video_codec_preferences_) {
+      if (send_codec->Matches(codec_preference)) {
+        codecs.push_back(codec_preference);
+        break;
+      }
     }
   }
 
diff --git a/pc/rtp_sender_receiver_unittest.cc b/pc/rtp_sender_receiver_unittest.cc
index 8be3a0a..2d8a1e8 100644
--- a/pc/rtp_sender_receiver_unittest.cc
+++ b/pc/rtp_sender_receiver_unittest.cc
@@ -197,8 +197,8 @@
   // Needed to use DTMF sender.
   void AddDtmfCodec() {
     cricket::AudioSendParameters params;
-    const cricket::AudioCodec kTelephoneEventCodec(106, "telephone-event", 8000,
-                                                   0, 1);
+    const cricket::AudioCodec kTelephoneEventCodec =
+        cricket::CreateAudioCodec(106, "telephone-event", 8000, 1);
     params.codecs.push_back(kTelephoneEventCodec);
     voice_media_send_channel()->SetSendParameters(params);
   }
diff --git a/pc/webrtc_sdp.cc b/pc/webrtc_sdp.cc
index 6d041ff..467b8c2 100644
--- a/pc/webrtc_sdp.cc
+++ b/pc/webrtc_sdp.cc
@@ -20,6 +20,7 @@
 #include <memory>
 #include <set>
 #include <string>
+#include <type_traits>
 #include <unordered_map>
 #include <utility>
 #include <vector>
@@ -2617,8 +2618,8 @@
       std::string encoding_name = kStaticPayloadAudioCodecs[payload_type].name;
       int clock_rate = kStaticPayloadAudioCodecs[payload_type].clockrate;
       size_t channels = kStaticPayloadAudioCodecs[payload_type].channels;
-      media_desc->AddCodec(cricket::AudioCodec(payload_type, encoding_name,
-                                               clock_rate, 0, channels));
+      media_desc->AddCodec(cricket::CreateAudioCodec(
+          payload_type, encoding_name, clock_rate, channels));
     }
   }
 }
@@ -2901,9 +2902,11 @@
   if (codec)
     return *codec;
   // Return empty codec with `payload_type`.
-  T ret_val;
-  ret_val.id = payload_type;
-  return ret_val;
+  if constexpr (std::is_same<T, cricket::AudioCodec>::value) {
+    return cricket::CreateAudioCodec(payload_type, "", 0, 0);
+  } else if constexpr (std::is_same<T, cricket::VideoCodec>::value) {
+    return cricket::CreateVideoCodec(payload_type, "");
+  }
 }
 
 // Updates or creates a new codec entry in the media description.
@@ -2972,26 +2975,26 @@
 }
 
 template <class T>
-bool PopWildcardCodec(std::vector<T>* codecs, T* wildcard_codec) {
+absl::optional<T> PopWildcardCodec(std::vector<T>* codecs) {
   for (auto iter = codecs->begin(); iter != codecs->end(); ++iter) {
     if (iter->id == kWildcardPayloadType) {
-      *wildcard_codec = *iter;
+      T wildcard_codec = *iter;
       codecs->erase(iter);
-      return true;
+      return wildcard_codec;
     }
   }
-  return false;
+  return absl::nullopt;
 }
 
 template <class T>
 void UpdateFromWildcardCodecs(cricket::MediaContentDescriptionImpl<T>* desc) {
   auto codecs = desc->codecs();
-  T wildcard_codec;
-  if (!PopWildcardCodec(&codecs, &wildcard_codec)) {
+  absl::optional<T> wildcard_codec = PopWildcardCodec(&codecs);
+  if (!wildcard_codec) {
     return;
   }
   for (auto& codec : codecs) {
-    AddFeedbackParameters(wildcard_codec.feedback_params, &codec);
+    AddFeedbackParameters(wildcard_codec->feedback_params, &codec);
   }
   desc->set_codecs(codecs);
 }
diff --git a/pc/webrtc_sdp_unittest.cc b/pc/webrtc_sdp_unittest.cc
index 0e1e62e..e680514 100644
--- a/pc/webrtc_sdp_unittest.cc
+++ b/pc/webrtc_sdp_unittest.cc
@@ -1241,9 +1241,9 @@
         "inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj|2^20|1:32",
         "dummy_session_params"));
     audio->set_protocol(cricket::kMediaProtocolSavpf);
-    audio->AddCodec(AudioCodec(111, "opus", 48000, 0, 2));
-    audio->AddCodec(AudioCodec(103, "ISAC", 16000, 0, 1));
-    audio->AddCodec(AudioCodec(104, "ISAC", 32000, 0, 1));
+    audio->AddCodec(cricket::CreateAudioCodec(111, "opus", 48000, 2));
+    audio->AddCodec(cricket::CreateAudioCodec(103, "ISAC", 16000, 1));
+    audio->AddCodec(cricket::CreateAudioCodec(104, "ISAC", 32000, 1));
     return audio;
   }
 
@@ -1317,7 +1317,7 @@
         1, "AES_CM_128_HMAC_SHA1_80",
         "inline:d0RmdmcmVCspeEc3QGZiNWpVLFJhQX1cfHAwJSoj|2^20|1:32", ""));
     video->set_protocol(cricket::kMediaProtocolSavpf);
-    video->AddCodec(VideoCodec(120, "VP8"));
+    video->AddCodec(cricket::CreateVideoCodec(120, "VP8"));
     return video;
   }
 
@@ -2344,7 +2344,7 @@
 }
 
 TEST_F(WebRtcSdpTest, SerializeSessionDescriptionWithH264) {
-  cricket::VideoCodec h264_codec("H264");
+  cricket::VideoCodec h264_codec = cricket::CreateVideoCodec("H264");
   h264_codec.SetParam("profile-level-id", "42e01f");
   h264_codec.SetParam("level-asymmetry-allowed", "1");
   h264_codec.SetParam("packetization-mode", "1");
@@ -2435,9 +2435,9 @@
   AudioCodecs ref_codecs;
   // The codecs in the AudioContentDescription should be in the same order as
   // the payload types (<fmt>s) on the m= line.
-  ref_codecs.push_back(AudioCodec(0, "PCMU", 8000, 0, 1));
-  ref_codecs.push_back(AudioCodec(18, "G729", 8000, 0, 1));
-  ref_codecs.push_back(AudioCodec(103, "ISAC", 16000, 0, 1));
+  ref_codecs.push_back(cricket::CreateAudioCodec(0, "PCMU", 8000, 1));
+  ref_codecs.push_back(cricket::CreateAudioCodec(18, "G729", 8000, 1));
+  ref_codecs.push_back(cricket::CreateAudioCodec(103, "ISAC", 16000, 1));
   EXPECT_EQ(ref_codecs, audio->codecs());
 }
 
@@ -3483,7 +3483,8 @@
   AudioContentDescription* acd = GetFirstAudioContentDescription(&desc_);
 
   cricket::AudioCodecs codecs = acd->codecs();
-  cricket::AudioCodec dtmf(105, "telephone-event", 8000, 0, 1);
+  cricket::AudioCodec dtmf =
+      cricket::CreateAudioCodec(105, "telephone-event", 8000, 1);
   dtmf.params[""] = "0-15";
   codecs.push_back(dtmf);
   acd->set_codecs(codecs);